@aloudata/aloudata-design 3.0.7 → 3.0.9
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/dist/Alert/index.js +2 -2
- package/dist/Alert/index.js.map +1 -1
- package/dist/Avatar/component/Avatar/index.js +7 -1
- package/dist/Avatar/component/Avatar/index.js.map +1 -1
- package/dist/Button/index.d.ts +2 -0
- package/dist/Button/index.js +2 -1
- package/dist/Button/index.js.map +1 -1
- package/dist/Card/index.js +2 -2
- package/dist/Card/index.js.map +1 -1
- package/dist/Checkbox/index.js +3 -1
- package/dist/Checkbox/index.js.map +1 -1
- package/dist/Checkbox/type.d.ts +4 -0
- package/dist/Collapse/index.js +18 -8
- package/dist/Collapse/index.js.map +1 -1
- package/dist/ConfigProvider/index.d.ts +5 -2
- package/dist/ConfigProvider/index.js +25 -3
- package/dist/ConfigProvider/index.js.map +1 -1
- package/dist/DataPreviewTable/components/Body/Error.d.ts +2 -0
- package/dist/DataPreviewTable/components/Body/Error.js +7 -3
- package/dist/DataPreviewTable/components/Body/Error.js.map +1 -1
- package/dist/DataPreviewTable/index.js +3 -1
- package/dist/DataPreviewTable/index.js.map +1 -1
- package/dist/DatePicker/index.js +12 -1
- package/dist/DatePicker/index.js.map +1 -1
- package/dist/Dropdown/index.js +7 -9
- package/dist/Dropdown/index.js.map +1 -1
- package/dist/Empty/index.js +1 -2
- package/dist/Empty/index.js.map +1 -1
- package/dist/IconButton/index.d.ts +4 -0
- package/dist/IconButton/index.js +8 -2
- package/dist/IconButton/index.js.map +1 -1
- package/dist/Input/components/Input/index.d.ts +4 -0
- package/dist/Input/components/Input/index.js +10 -4
- package/dist/Input/components/Input/index.js.map +1 -1
- package/dist/InputNumber/index.js +5 -1
- package/dist/InputNumber/index.js.map +1 -1
- package/dist/InputNumber/type.d.ts +4 -0
- package/dist/InputSearch/index.d.ts +4 -0
- package/dist/InputSearch/index.js +3 -1
- package/dist/InputSearch/index.js.map +1 -1
- package/dist/MemberPicker/index.js +3 -1
- package/dist/MemberPicker/index.js.map +1 -1
- package/dist/Modal/index.d.ts +4 -0
- package/dist/Modal/index.js +3 -1
- package/dist/Modal/index.js.map +1 -1
- package/dist/Popconfirm/index.js +3 -2
- package/dist/Popconfirm/index.js.map +1 -1
- package/dist/Radio/components/Group/index.js +3 -1
- package/dist/Radio/components/Group/index.js.map +1 -1
- package/dist/Radio/components/Radio/index.js +8 -2
- package/dist/Radio/components/Radio/index.js.map +1 -1
- package/dist/Radio/interface/radioGroup.d.ts +4 -0
- package/dist/Select/BaseSelect.js +5 -1
- package/dist/Select/BaseSelect.js.map +1 -1
- package/dist/Select/components/Suffix.d.ts +2 -1
- package/dist/Select/components/Suffix.js +14 -5
- package/dist/Select/components/Suffix.js.map +1 -1
- package/dist/Select/interface.d.ts +4 -0
- package/dist/Slider/index.js +2 -2
- package/dist/Slider/index.js.map +1 -1
- package/dist/Steps/components/Step/index.d.ts +1 -0
- package/dist/Steps/components/Step/index.js.map +1 -1
- package/dist/Steps/index.d.ts +1 -1
- package/dist/Steps/index.js +4 -2
- package/dist/Steps/index.js.map +1 -1
- package/dist/Switch/index.d.ts +4 -0
- package/dist/Switch/index.js +3 -1
- package/dist/Switch/index.js.map +1 -1
- package/dist/Tabs/index.d.ts +4 -0
- package/dist/Tabs/index.js +3 -1
- package/dist/Tabs/index.js.map +1 -1
- package/dist/Tooltip/index.js +5 -4
- package/dist/Tooltip/index.js.map +1 -1
- package/dist/aloudata-design.css +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/ConfigProvider/index.tsx"],"sourcesContent":["import React, { createContext } from 'react';\nimport { LocaleContext, defaultLocale } from '../locale/default';\nimport getUserListContext, {\n IUser,\n IUserGroup,\n getUsersByIdsType,\n getUsersByKeywordsType,\n} from './getUserList';\nimport useGetUserList from './hooks/useGetUserList';\nimport SizeContext from './sizeContext';\n\nexport const ConfigContext = createContext<{\n getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string;\n direction?: 'ltr' | 'rtl';\n virtual?: boolean;\n}>({\n getPrefixCls: (suffixCls, customizePrefixCls) => {\n if (customizePrefixCls) return customizePrefixCls;\n return suffixCls ? `ald-${suffixCls}` : 'ald';\n },\n});\n\nexport const ConfigConsumer = ConfigContext.Consumer;\n\nexport type CSPConfig = { nonce?: string };\nexport type DirectionType = 'ltr' | 'rtl';\nexport type RenderEmptyHandler = (componentName?: string) => React.ReactNode;\nexport type ConfigConsumerProps = {\n getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string;\n direction?: DirectionType;\n};\n\nexport type configConsumerProps = any;\n\nexport type globalConfig = any;\n\ninterface AldCustomConfigProviderProps {\n children?: React.ReactNode;\n getUsersByIds?: getUsersByIdsType;\n getUsersByKeywords?: getUsersByKeywordsType;\n getMemberPickerItemMoreInfoKey?: (user: IUser) => string;\n getNextLevelGroup?: (params: {\n parentGroupId?: string;\n keyword: string;\n }) => Promise<IUserGroup[]>;\n locale?: any;\n theme?: any;\n componentSize?:
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/ConfigProvider/index.tsx"],"sourcesContent":["import React, { createContext } from 'react';\nimport { LocaleContext, defaultLocale } from '../locale/default';\nimport DisabledContext from './DisabledContext';\nimport getUserListContext, {\n IUser,\n IUserGroup,\n getUsersByIdsType,\n getUsersByKeywordsType,\n} from './getUserList';\nimport useGetUserList from './hooks/useGetUserList';\nimport SizeContext, { type SizeType } from './sizeContext';\n\nexport const ConfigContext = createContext<{\n getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string;\n direction?: 'ltr' | 'rtl';\n virtual?: boolean;\n}>({\n getPrefixCls: (suffixCls, customizePrefixCls) => {\n if (customizePrefixCls) return customizePrefixCls;\n return suffixCls ? `ald-${suffixCls}` : 'ald';\n },\n});\n\nexport const ConfigConsumer = ConfigContext.Consumer;\n\nexport type CSPConfig = { nonce?: string };\nexport type DirectionType = 'ltr' | 'rtl';\nexport type RenderEmptyHandler = (componentName?: string) => React.ReactNode;\nexport type ConfigConsumerProps = {\n getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string;\n direction?: DirectionType;\n};\n\nexport type configConsumerProps = any;\n\nexport type globalConfig = any;\n\ninterface AldCustomConfigProviderProps {\n children?: React.ReactNode;\n getUsersByIds?: getUsersByIdsType;\n getUsersByKeywords?: getUsersByKeywordsType;\n getMemberPickerItemMoreInfoKey?: (user: IUser) => string;\n getNextLevelGroup?: (params: {\n parentGroupId?: string;\n keyword: string;\n }) => Promise<IUserGroup[]>;\n locale?: any;\n theme?: any;\n componentSize?: SizeType;\n componentDisabled?: boolean;\n prefixCls?: string;\n direction?: DirectionType;\n virtual?: boolean;\n}\n\nconst AldCustomConfigProvider: React.FC<AldCustomConfigProviderProps> & {\n ConfigContext: typeof ConfigContext;\n SizeContext: typeof SizeContext;\n useConfig: () => { componentSize: string };\n useGetUserList: typeof useGetUserList;\n} = (props) => {\n const {\n children,\n getUsersByIds,\n getUsersByKeywords,\n getMemberPickerItemMoreInfoKey,\n getNextLevelGroup,\n componentSize,\n componentDisabled,\n prefixCls = 'ald',\n direction,\n virtual,\n } = props;\n\n const config = React.useMemo(\n () => ({\n getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {\n if (customizePrefixCls) return customizePrefixCls;\n return suffixCls ? `${prefixCls}-${suffixCls}` : prefixCls;\n },\n direction,\n virtual,\n }),\n [direction, prefixCls, virtual],\n );\n\n let childNode = children;\n if (getUsersByIds || getUsersByKeywords) {\n childNode = (\n <getUserListContext.Provider\n value={{\n getUsersByIds,\n getUsersByKeywords,\n getMemberPickerItemMoreInfoKey,\n getNextLevelGroup,\n }}\n >\n {children}\n </getUserListContext.Provider>\n );\n }\n\n return (\n <LocaleContext.Provider value={props.locale || defaultLocale}>\n <ConfigContext.Provider value={config}>\n <SizeContext.Provider value={componentSize}>\n <DisabledContext.Provider value={componentDisabled}>\n {childNode}\n </DisabledContext.Provider>\n </SizeContext.Provider>\n </ConfigContext.Provider>\n </LocaleContext.Provider>\n );\n};\n\nAldCustomConfigProvider.ConfigContext = ConfigContext;\nAldCustomConfigProvider.SizeContext = SizeContext;\nAldCustomConfigProvider.useConfig = () => ({ componentSize: 'middle' });\nAldCustomConfigProvider.useGetUserList = useGetUserList;\n\nexport default AldCustomConfigProvider;\n"],"mappings":";;;;;;;;AAYA,IAAa,gBAAgB,cAI1B,EACD,eAAe,WAAW,uBAAuB;AAC/C,KAAI,mBAAoB,QAAO;AAC/B,QAAO,YAAY,OAAO,cAAc;GAE3C,CAAC;AAE4B,cAAc;AAgC5C,IAAM,2BAKD,UAAU;CACb,MAAM,EACJ,UACA,eACA,oBACA,gCACA,mBACA,eACA,mBACA,YAAY,OACZ,WACA,YACE;CAEJ,MAAM,SAAS,MAAM,eACZ;EACL,eAAe,WAAoB,uBAAgC;AACjE,OAAI,mBAAoB,QAAO;AAC/B,UAAO,YAAY,GAAG,UAAU,GAAG,cAAc;;EAEnD;EACA;EACD,GACD;EAAC;EAAW;EAAW;EAAQ,CAChC;CAED,IAAI,YAAY;AAChB,KAAI,iBAAiB,mBACnB,aACE,oBAAC,mBAAmB,UAApB;EACE,OAAO;GACL;GACA;GACA;GACA;GACD;EAEA;EAC2B,CAAA;AAIlC,QACE,oBAAC,cAAc,UAAf;EAAwB,OAAO,MAAM,UAAU;YAC7C,oBAAC,cAAc,UAAf;GAAwB,OAAO;aAC7B,oBAAC,YAAY,UAAb;IAAsB,OAAO;cAC3B,oBAAC,gBAAgB,UAAjB;KAA0B,OAAO;eAC9B;KACwB,CAAA;IACN,CAAA;GACA,CAAA;EACF,CAAA;;AAI7B,wBAAwB,gBAAgB;AACxC,wBAAwB,cAAc;AACtC,wBAAwB,mBAAmB,EAAE,eAAe,UAAU;AACtE,wBAAwB,iBAAiB"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
interface IErrorProps {
|
|
3
3
|
wrapWidth: number;
|
|
4
|
+
wrapHeight: number;
|
|
5
|
+
headerHeight: number;
|
|
4
6
|
errorMsg?: string | React.ReactNode;
|
|
5
7
|
}
|
|
6
8
|
declare function ErrorBody(props: IErrorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -6,10 +6,14 @@ import { jsx } from "react/jsx-runtime";
|
|
|
6
6
|
function ErrorBody(props) {
|
|
7
7
|
const { locale } = useContext(LocaleContext);
|
|
8
8
|
const t = getTranslator(locale);
|
|
9
|
-
const { wrapWidth, errorMsg = t.DataPreviewTable.loadFailed } = props;
|
|
9
|
+
const { wrapWidth, wrapHeight, headerHeight, errorMsg = t.DataPreviewTable.loadFailed } = props;
|
|
10
10
|
return /* @__PURE__ */ jsx("div", {
|
|
11
|
-
className: "ald-data-preview-table-error tw-
|
|
12
|
-
style: {
|
|
11
|
+
className: "ald-data-preview-table-error tw-absolute tw-left-0 tw-flex tw-items-center tw-justify-center",
|
|
12
|
+
style: {
|
|
13
|
+
width: wrapWidth,
|
|
14
|
+
height: Math.max(wrapHeight - headerHeight, 0),
|
|
15
|
+
top: headerHeight
|
|
16
|
+
},
|
|
13
17
|
children: typeof errorMsg === "string" ? /* @__PURE__ */ jsx(Result, {
|
|
14
18
|
status: "warning",
|
|
15
19
|
subTitle: errorMsg
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Error.js","names":[],"sources":["../../../../src/DataPreviewTable/components/Body/Error.tsx"],"sourcesContent":["import React, { memo, useContext } from 'react';\nimport Result from '../../../Result';\nimport { LocaleContext, getTranslator } from '../../../locale/default';\n\ninterface IErrorProps {\n wrapWidth: number;\n errorMsg?: string | React.ReactNode;\n}\nfunction ErrorBody(props: IErrorProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const {
|
|
1
|
+
{"version":3,"file":"Error.js","names":[],"sources":["../../../../src/DataPreviewTable/components/Body/Error.tsx"],"sourcesContent":["import React, { memo, useContext } from 'react';\nimport Result from '../../../Result';\nimport { LocaleContext, getTranslator } from '../../../locale/default';\n\ninterface IErrorProps {\n wrapWidth: number;\n wrapHeight: number;\n headerHeight: number;\n errorMsg?: string | React.ReactNode;\n}\nfunction ErrorBody(props: IErrorProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const {\n wrapWidth,\n wrapHeight,\n headerHeight,\n errorMsg = t.DataPreviewTable.loadFailed,\n } = props;\n return (\n <div\n className=\"ald-data-preview-table-error tw-absolute tw-left-0 tw-flex tw-items-center tw-justify-center\"\n style={{\n width: wrapWidth,\n height: Math.max(wrapHeight - headerHeight, 0),\n top: headerHeight,\n }}\n >\n {typeof errorMsg === 'string' ? (\n <Result status=\"warning\" subTitle={errorMsg} />\n ) : (\n errorMsg\n )}\n </div>\n );\n}\nexport default memo(ErrorBody);\n"],"mappings":";;;;;AAUA,SAAS,UAAU,OAAoB;CACrC,MAAM,EAAE,WAAW,WAAW,cAAc;CAC5C,MAAM,IAAI,cAAc,OAAO;CAE/B,MAAM,EACJ,WACA,YACA,cACA,WAAW,EAAE,iBAAiB,eAC5B;AACJ,QACE,oBAAC,OAAD;EACE,WAAU;EACV,OAAO;GACL,OAAO;GACP,QAAQ,KAAK,IAAI,aAAa,cAAc,EAAE;GAC9C,KAAK;GACN;YAEA,OAAO,aAAa,WACnB,oBAAC,QAAD;GAAQ,QAAO;GAAU,UAAU;GAAY,CAAA,GAE/C;EAEE,CAAA;;AAGV,IAAA,gBAAe,KAAK,UAAU"}
|
|
@@ -92,7 +92,9 @@ var DataPreviewTable_default = memo(forwardRef(function(props, ref) {
|
|
|
92
92
|
}),
|
|
93
93
|
dataStatus === "error" && /* @__PURE__ */ jsx(Error_default, {
|
|
94
94
|
errorMsg,
|
|
95
|
-
wrapWidth: wrapRef.current?.clientWidth || 0
|
|
95
|
+
wrapWidth: wrapRef.current?.clientWidth || 0,
|
|
96
|
+
wrapHeight: wrapRef.current?.clientHeight || 0,
|
|
97
|
+
headerHeight: realHeaderHeight
|
|
96
98
|
})
|
|
97
99
|
]
|
|
98
100
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/DataPreviewTable/index.tsx"],"sourcesContent":["import { cn } from '../lib/utils';\nimport React, {\n forwardRef,\n memo,\n useContext,\n useImperativeHandle,\n useMemo,\n useRef,\n} from 'react';\nimport Progress, { IProgressRef } from '../Progress';\nimport ScrollArea from '../ScrollArea';\nimport Spin from '../Spin';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport Body from './components/Body';\nimport Error from './components/Body/Error';\nimport Header from './components/Header';\nimport { CELL_HEIGHT, DEFAULT_HEADER_HEIGHT } from './constant';\nimport useDirection from './hooks/useDirection';\nimport { DataPreviewTableRef, ITableProps } from './interface';\n\nconst DataPreviewTable = forwardRef(function (\n props: ITableProps,\n ref: React.Ref<DataPreviewTableRef>,\n) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const {\n columns = [],\n datasource = [],\n width,\n height,\n headerHeight = 0,\n loading,\n dataStatus,\n errorMsg = t.DataPreviewTable.dataLoadFailed,\n } = props;\n\n const realHeaderHeight = Math.max(headerHeight, DEFAULT_HEADER_HEIGHT);\n const contentHeight = useMemo(() => {\n return datasource.length * CELL_HEIGHT + realHeaderHeight;\n }, [datasource, realHeaderHeight]);\n const wrapRef = useRef<HTMLDivElement>(null);\n const progressRef = useRef<IProgressRef>(null);\n const {\n columnRange,\n rowRange,\n onScroll,\n columnLayout,\n setColumnsWidth,\n tableColumns,\n contentWidth,\n } = useDirection(columns, wrapRef);\n\n useImperativeHandle(ref, () => ({\n scrollToColumnInView: (columnId: string) => {\n // 实现scrollTo方法\n const columnPos = columnLayout[columnId];\n if (!columnPos) return;\n // 根据容器的宽度,容器的scrollLeft,columnPos,判断当前列是否在可视区域内\n const { scrollLeft } = wrapRef.current as HTMLDivElement;\n const { left, width } = columnPos;\n const containerWidth = wrapRef.current?.clientWidth || 0;\n if (left < scrollLeft) {\n // 左边不可见\n wrapRef.current?.scrollTo({\n left,\n behavior: 'smooth',\n });\n } else if (left + width > scrollLeft + containerWidth) {\n // 右边不可见\n wrapRef.current?.scrollTo({\n left: left + width - containerWidth,\n behavior: 'smooth',\n });\n }\n },\n progressRestart: () => {\n progressRef.current?.restart();\n },\n }));\n\n const skeletonRows = useMemo(() => {\n if (!wrapRef.current) return 0;\n const rows = Math.ceil(\n ((wrapRef.current?.clientHeight || 0) - realHeaderHeight) / CELL_HEIGHT,\n );\n return rows - 1 < 0 ? 0 : rows - 1;\n }, [realHeaderHeight]);\n\n return (\n <ScrollArea\n ref={wrapRef}\n style={{ width, height, willChange: 'transform' }}\n onViewportScroll={() => {\n // const { scrollTop, scrollLeft } = e.target as HTMLDivElement;\n onScroll();\n }}\n className={cn(\n props.className,\n 'ald-data-preview-table tw-box-border tw-border tw-border-solid tw-border-[var(--alias-colors-border-default)] tw-text-xs tw-tabular-nums [&_*]:tw-box-border',\n {\n 'ald-data-preview-table-show-skeleton': dataStatus === 'pending',\n },\n )}\n >\n <div\n style={{\n height:\n dataStatus === 'pending'\n ? skeletonRows * CELL_HEIGHT + realHeaderHeight\n : contentHeight,\n position: 'relative',\n width: 'fit-content',\n }}\n >\n <div className=\"ald-data-preview-sticky tw-sticky tw-top-0 tw-z-[1]\">\n <Progress\n className=\"ald-data-preview-progress tw-fixed tw-left-0 tw-top-0 tw-z-[3] tw-w-full\"\n loading={!!loading}\n ref={progressRef}\n />\n <Header\n contentWidth={contentWidth}\n headerHeight={realHeaderHeight}\n columns={tableColumns}\n columnLayout={columnLayout}\n setWidth={setColumnsWidth}\n columnRange={columnRange}\n />\n </div>\n {dataStatus === 'pending' && tableColumns.length > 0 && (\n <div className=\"ald-data-preview-loading tw-fixed tw-flex tw-size-full tw-items-center tw-justify-center\">\n <Spin />\n </div>\n )}\n {dataStatus === 'success' && (\n <Body\n columns={tableColumns}\n columnRange={columnRange}\n columnLayout={columnLayout}\n datasource={datasource}\n rowRange={rowRange}\n headerHeight={realHeaderHeight}\n />\n )}\n {dataStatus === 'error' && (\n <Error\n errorMsg={errorMsg}\n wrapWidth={wrapRef.current?.clientWidth || 0}\n />\n )}\n </div>\n </ScrollArea>\n );\n});\n\nexport default memo(DataPreviewTable);\n"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/DataPreviewTable/index.tsx"],"sourcesContent":["import { cn } from '../lib/utils';\nimport React, {\n forwardRef,\n memo,\n useContext,\n useImperativeHandle,\n useMemo,\n useRef,\n} from 'react';\nimport Progress, { IProgressRef } from '../Progress';\nimport ScrollArea from '../ScrollArea';\nimport Spin from '../Spin';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport Body from './components/Body';\nimport Error from './components/Body/Error';\nimport Header from './components/Header';\nimport { CELL_HEIGHT, DEFAULT_HEADER_HEIGHT } from './constant';\nimport useDirection from './hooks/useDirection';\nimport { DataPreviewTableRef, ITableProps } from './interface';\n\nconst DataPreviewTable = forwardRef(function (\n props: ITableProps,\n ref: React.Ref<DataPreviewTableRef>,\n) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const {\n columns = [],\n datasource = [],\n width,\n height,\n headerHeight = 0,\n loading,\n dataStatus,\n errorMsg = t.DataPreviewTable.dataLoadFailed,\n } = props;\n\n const realHeaderHeight = Math.max(headerHeight, DEFAULT_HEADER_HEIGHT);\n const contentHeight = useMemo(() => {\n return datasource.length * CELL_HEIGHT + realHeaderHeight;\n }, [datasource, realHeaderHeight]);\n const wrapRef = useRef<HTMLDivElement>(null);\n const progressRef = useRef<IProgressRef>(null);\n const {\n columnRange,\n rowRange,\n onScroll,\n columnLayout,\n setColumnsWidth,\n tableColumns,\n contentWidth,\n } = useDirection(columns, wrapRef);\n\n useImperativeHandle(ref, () => ({\n scrollToColumnInView: (columnId: string) => {\n // 实现scrollTo方法\n const columnPos = columnLayout[columnId];\n if (!columnPos) return;\n // 根据容器的宽度,容器的scrollLeft,columnPos,判断当前列是否在可视区域内\n const { scrollLeft } = wrapRef.current as HTMLDivElement;\n const { left, width } = columnPos;\n const containerWidth = wrapRef.current?.clientWidth || 0;\n if (left < scrollLeft) {\n // 左边不可见\n wrapRef.current?.scrollTo({\n left,\n behavior: 'smooth',\n });\n } else if (left + width > scrollLeft + containerWidth) {\n // 右边不可见\n wrapRef.current?.scrollTo({\n left: left + width - containerWidth,\n behavior: 'smooth',\n });\n }\n },\n progressRestart: () => {\n progressRef.current?.restart();\n },\n }));\n\n const skeletonRows = useMemo(() => {\n if (!wrapRef.current) return 0;\n const rows = Math.ceil(\n ((wrapRef.current?.clientHeight || 0) - realHeaderHeight) / CELL_HEIGHT,\n );\n return rows - 1 < 0 ? 0 : rows - 1;\n }, [realHeaderHeight]);\n\n return (\n <ScrollArea\n ref={wrapRef}\n style={{ width, height, willChange: 'transform' }}\n onViewportScroll={() => {\n // const { scrollTop, scrollLeft } = e.target as HTMLDivElement;\n onScroll();\n }}\n className={cn(\n props.className,\n 'ald-data-preview-table tw-box-border tw-border tw-border-solid tw-border-[var(--alias-colors-border-default)] tw-text-xs tw-tabular-nums [&_*]:tw-box-border',\n {\n 'ald-data-preview-table-show-skeleton': dataStatus === 'pending',\n },\n )}\n >\n <div\n style={{\n height:\n dataStatus === 'pending'\n ? skeletonRows * CELL_HEIGHT + realHeaderHeight\n : contentHeight,\n position: 'relative',\n width: 'fit-content',\n }}\n >\n <div className=\"ald-data-preview-sticky tw-sticky tw-top-0 tw-z-[1]\">\n <Progress\n className=\"ald-data-preview-progress tw-fixed tw-left-0 tw-top-0 tw-z-[3] tw-w-full\"\n loading={!!loading}\n ref={progressRef}\n />\n <Header\n contentWidth={contentWidth}\n headerHeight={realHeaderHeight}\n columns={tableColumns}\n columnLayout={columnLayout}\n setWidth={setColumnsWidth}\n columnRange={columnRange}\n />\n </div>\n {dataStatus === 'pending' && tableColumns.length > 0 && (\n <div className=\"ald-data-preview-loading tw-fixed tw-flex tw-size-full tw-items-center tw-justify-center\">\n <Spin />\n </div>\n )}\n {dataStatus === 'success' && (\n <Body\n columns={tableColumns}\n columnRange={columnRange}\n columnLayout={columnLayout}\n datasource={datasource}\n rowRange={rowRange}\n headerHeight={realHeaderHeight}\n />\n )}\n {dataStatus === 'error' && (\n <Error\n errorMsg={errorMsg}\n wrapWidth={wrapRef.current?.clientWidth || 0}\n wrapHeight={wrapRef.current?.clientHeight || 0}\n headerHeight={realHeaderHeight}\n />\n )}\n </div>\n </ScrollArea>\n );\n});\n\nexport default memo(DataPreviewTable);\n"],"mappings":";;;;;;;;;;;AA+JA,IAAA,2BAAe,KA3IU,WAAW,SAClC,OACA,KACA;CACA,MAAM,EAAE,WAAW,WAAW,cAAc;CAC5C,MAAM,IAAI,cAAc,OAAO;CAE/B,MAAM,EACJ,UAAU,EAAE,EACZ,aAAa,EAAE,EACf,OACA,QACA,eAAe,GACf,SACA,YACA,WAAW,EAAE,iBAAiB,mBAC5B;CAEJ,MAAM,mBAAmB,KAAK,IAAI,cAAA,GAAoC;CACtE,MAAM,gBAAgB,cAAc;AAClC,SAAO,WAAW,SAAA,KAAuB;IACxC,CAAC,YAAY,iBAAiB,CAAC;CAClC,MAAM,UAAU,OAAuB,KAAK;CAC5C,MAAM,cAAc,OAAqB,KAAK;CAC9C,MAAM,EACJ,aACA,UACA,UACA,cACA,iBACA,cACA,iBACE,aAAa,SAAS,QAAQ;AAElC,qBAAoB,YAAY;EAC9B,uBAAuB,aAAqB;GAE1C,MAAM,YAAY,aAAa;AAC/B,OAAI,CAAC,UAAW;GAEhB,MAAM,EAAE,eAAe,QAAQ;GAC/B,MAAM,EAAE,MAAM,UAAU;GACxB,MAAM,iBAAiB,QAAQ,SAAS,eAAe;AACvD,OAAI,OAAO,WAET,SAAQ,SAAS,SAAS;IACxB;IACA,UAAU;IACX,CAAC;YACO,OAAO,QAAQ,aAAa,eAErC,SAAQ,SAAS,SAAS;IACxB,MAAM,OAAO,QAAQ;IACrB,UAAU;IACX,CAAC;;EAGN,uBAAuB;AACrB,eAAY,SAAS,SAAS;;EAEjC,EAAE;CAEH,MAAM,eAAe,cAAc;AACjC,MAAI,CAAC,QAAQ,QAAS,QAAO;EAC7B,MAAM,OAAO,KAAK,OACd,QAAQ,SAAS,gBAAgB,KAAK,oBAAA,GACzC;AACD,SAAO,OAAO,IAAI,IAAI,IAAI,OAAO;IAChC,CAAC,iBAAiB,CAAC;AAEtB,QACE,oBAAC,oBAAD;EACE,KAAK;EACL,OAAO;GAAE;GAAO;GAAQ,YAAY;GAAa;EACjD,wBAAwB;AAEtB,aAAU;;EAEZ,WAAW,GACT,MAAM,WACN,gKACA,EACE,wCAAwC,eAAe,WACxD,CACF;YAED,qBAAC,OAAD;GACE,OAAO;IACL,QACE,eAAe,YACX,eAAA,KAA6B,mBAC7B;IACN,UAAU;IACV,OAAO;IACR;aARH;IAUE,qBAAC,OAAD;KAAK,WAAU;eAAf,CACE,oBAAC,kBAAD;MACE,WAAU;MACV,SAAS,CAAC,CAAC;MACX,KAAK;MACL,CAAA,EACF,oBAAC,QAAD;MACgB;MACd,cAAc;MACd,SAAS;MACK;MACd,UAAU;MACG;MACb,CAAA,CACE;;IACL,eAAe,aAAa,aAAa,SAAS,KACjD,oBAAC,OAAD;KAAK,WAAU;eACb,oBAAC,YAAD,EAAQ,CAAA;KACJ,CAAA;IAEP,eAAe,aACd,oBAAC,cAAD;KACE,SAAS;KACI;KACC;KACF;KACF;KACV,cAAc;KACd,CAAA;IAEH,eAAe,WACd,oBAAC,eAAD;KACY;KACV,WAAW,QAAQ,SAAS,eAAe;KAC3C,YAAY,QAAQ,SAAS,gBAAgB;KAC7C,cAAc;KACd,CAAA;IAEA;;EACK,CAAA;EAEf,CAEmC"}
|
package/dist/DatePicker/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var SIZE_CLS = {
|
|
|
14
14
|
large: "ald-picker-lg"
|
|
15
15
|
};
|
|
16
16
|
var InternalDatePicker = forwardRef((props, ref) => {
|
|
17
|
-
const { size: customSize, disabled: customDisabled, className, status, bordered = true, prefixCls = "ald-picker", onChange, disabledDate, onSelect
|
|
17
|
+
const { size: customSize, disabled: customDisabled, className, status, bordered = true, prefixCls = "ald-picker", onChange, disabledDate, onSelect, onCalendarChange, popupClassName, locale: localeProp, ...restProps } = props;
|
|
18
18
|
const ctxSize = useContext(SizeContext);
|
|
19
19
|
const size = customSize || ctxSize || "middle";
|
|
20
20
|
const ctxDisabled = useContext(DisabledContext);
|
|
@@ -32,6 +32,16 @@ var InternalDatePicker = forwardRef((props, ref) => {
|
|
|
32
32
|
if (!disabledDate) return void 0;
|
|
33
33
|
return (date, info) => disabledDate(date, info);
|
|
34
34
|
}, [disabledDate]);
|
|
35
|
+
const rcOnCalendarChange = React.useMemo(() => {
|
|
36
|
+
if (!onCalendarChange && !onSelect) return void 0;
|
|
37
|
+
return (date, dateString, info) => {
|
|
38
|
+
onCalendarChange?.(date, dateString, info);
|
|
39
|
+
if (onSelect) {
|
|
40
|
+
const selectedDate = Array.isArray(date) ? date[0] : date;
|
|
41
|
+
if (selectedDate) onSelect(selectedDate);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}, [onCalendarChange, onSelect]);
|
|
35
45
|
const mergedClassNames = React.useMemo(() => {
|
|
36
46
|
if (!popupClassName) return restProps.classNames;
|
|
37
47
|
return {
|
|
@@ -49,6 +59,7 @@ var InternalDatePicker = forwardRef((props, ref) => {
|
|
|
49
59
|
...restProps,
|
|
50
60
|
classNames: mergedClassNames,
|
|
51
61
|
onChange: rcOnChange,
|
|
62
|
+
onCalendarChange: rcOnCalendarChange,
|
|
52
63
|
disabledDate: rcDisabledDate
|
|
53
64
|
});
|
|
54
65
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/DatePicker/index.tsx"],"sourcesContent":["import type { Dayjs } from 'dayjs';\nimport React, { forwardRef, useContext } from 'react';\nimport { Picker, RangePicker as RcRangePicker } from 'rc-picker';\nimport type {\n PickerProps,\n RangePickerProps as RcRangePickerProps,\n PickerRef,\n} from 'rc-picker';\nimport type { PanelMode, RangePickerRef } from 'rc-picker/es/interface';\nimport dayjsGenerateConfig from 'rc-picker/es/generate/dayjs';\nimport enUS from 'rc-picker/es/locale/en_US';\nimport { LocaleContext } from '../locale/default';\nimport DisabledContext from '../ConfigProvider/DisabledContext';\nimport SizeContext, { type SizeType } from '../ConfigProvider/sizeContext';\nimport { cn } from '../lib/utils';\nimport './date-picker.css';\n\n// ---- Types ----\n// Re-export compatible types\nexport type RangeValue<T = Dayjs> = [T | null, T | null] | null;\n\n/**\n * disabledDate compat: rc-picker v4 requires (date, info) => boolean,\n * but antd v4 consumers pass (current) => boolean. We accept both.\n */\ntype DisabledDateCompat = (\n current: Dayjs,\n info?: { type: PanelMode; from?: Dayjs },\n) => boolean;\n\nexport interface DatePickerProps\n extends Omit<\n PickerProps<Dayjs>,\n 'generateConfig' | 'locale' | 'prefixCls' | 'onChange' | 'disabledDate'\n > {\n /** Override size from ConfigProvider */\n size?: SizeType;\n /** Validation status */\n status?: 'error' | 'warning';\n /** @deprecated Use `variant` or className instead */\n bordered?: boolean;\n /** Custom prefixCls */\n prefixCls?: string;\n /**\n * Narrowed onChange — single picker uses Dayjs | null, not Dayjs | Dayjs[].\n * Uses import('dayjs').Dayjs to avoid duplicate-dayjs type conflicts.\n */\n onChange?: (date: import('dayjs').Dayjs | null, dateString: string) => void;\n /**\n * disabledDate — accepts both rc-picker v4 signature and antd v4 compat\n * signature `(current: Dayjs) => boolean`.\n */\n disabledDate?: DisabledDateCompat;\n /** Callback when a date is selected on the panel */\n onSelect?: (date: Dayjs) => void;\n /** @deprecated Use `classNames.popup` instead. Preserved for antd v4 compat. */\n popupClassName?: string;\n /** Override locale for this picker instance. Defaults to ConfigProvider locale. */\n locale?: Record<string, any>;\n}\n\nexport interface RangePickerProps\n extends Omit<\n RcRangePickerProps<Dayjs>,\n 'generateConfig' | 'locale' | 'prefixCls' | 'onChange' | 'disabledDate'\n > {\n size?: SizeType;\n status?: 'error' | 'warning';\n bordered?: boolean;\n prefixCls?: string;\n /** Narrowed onChange for RangePicker */\n onChange?: (\n dates: [import('dayjs').Dayjs | null, import('dayjs').Dayjs | null] | null,\n dateStrings: [string, string],\n ) => void;\n /**\n * disabledDate — accepts both rc-picker v4 signature and antd v4 compat\n * signature `(current: Dayjs) => boolean`.\n */\n disabledDate?: DisabledDateCompat;\n /** @deprecated Use `classNames.popup` instead. Preserved for antd v4 compat. */\n popupClassName?: string;\n /** Override locale for this picker instance. Defaults to ConfigProvider locale. */\n locale?: Record<string, any>;\n}\n\nexport type YearPickerProps = DatePickerProps;\nexport type QuarterPickerProps = DatePickerProps;\nexport type MonthPickerProps = DatePickerProps;\nexport type WeekPickerProps = DatePickerProps;\nexport type TimePickerProps = DatePickerProps;\n\n// ---- Size mapping ----\nconst SIZE_CLS: Record<string, string> = {\n small: 'ald-picker-sm',\n large: 'ald-picker-lg',\n};\n\n// ---- DatePicker ----\nconst InternalDatePicker = forwardRef<PickerRef, DatePickerProps>(\n (props, ref) => {\n const {\n size: customSize,\n disabled: customDisabled,\n className,\n status,\n bordered = true,\n prefixCls = 'ald-picker',\n onChange,\n disabledDate,\n onSelect: _onSelect, // exclude from restProps\n popupClassName,\n locale: localeProp,\n ...restProps\n } = props;\n\n const ctxSize = useContext(SizeContext);\n const size = customSize || ctxSize || 'middle';\n const ctxDisabled = useContext(DisabledContext);\n const mergedDisabled = customDisabled ?? ctxDisabled;\n const ctxLocale = useContext(LocaleContext);\n // antd locale 对象包含 DatePicker 字段(即 rc-picker 格式的 locale)\n const pickerLocale = localeProp || ctxLocale?.DatePicker || enUS;\n\n const sizeCls = SIZE_CLS[size] || '';\n\n // Wrap narrowed onChange to match rc-picker's wider signature\n const rcOnChange = React.useMemo(() => {\n if (!onChange) return undefined;\n return (date: Dayjs | Dayjs[], dateString: string | string[]) => {\n onChange(\n (Array.isArray(date) ? date[0] : date) as Dayjs | null,\n Array.isArray(dateString) ? dateString[0] : dateString,\n );\n };\n }, [onChange]);\n\n // Wrap compat disabledDate to rc-picker v4 signature\n const rcDisabledDate = React.useMemo(() => {\n if (!disabledDate) return undefined;\n return (date: Dayjs, info: { type: PanelMode; from?: Dayjs }) =>\n disabledDate(date, info);\n }, [disabledDate]);\n\n // Merge popupClassName into classNames.popup for rc-picker v4\n const mergedClassNames = React.useMemo(() => {\n if (!popupClassName) return restProps.classNames;\n return {\n ...restProps.classNames,\n popup: cn(restProps.classNames?.popup, popupClassName),\n };\n }, [popupClassName, restProps.classNames]);\n\n return (\n <Picker<Dayjs>\n ref={ref}\n generateConfig={dayjsGenerateConfig}\n locale={pickerLocale}\n prefixCls={prefixCls}\n disabled={mergedDisabled}\n className={cn(\n sizeCls,\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ant-picker',\n !bordered && 'ald-picker-borderless',\n status === 'error' && 'ald-picker-status-error',\n status === 'warning' && 'ald-picker-status-warning',\n className,\n )}\n {...restProps}\n classNames={mergedClassNames}\n onChange={rcOnChange}\n disabledDate={rcDisabledDate}\n />\n );\n },\n) as React.ForwardRefExoticComponent<\n DatePickerProps & React.RefAttributes<PickerRef>\n> & {\n RangePicker: typeof InternalRangePicker;\n WeekPicker: typeof WeekPicker;\n MonthPicker: typeof MonthPicker;\n YearPicker: typeof YearPicker;\n TimePicker: typeof TimePicker;\n QuarterPicker: typeof QuarterPicker;\n};\n\n// ---- RangePicker ----\nconst InternalRangePicker = forwardRef<RangePickerRef, RangePickerProps>(\n (props, ref) => {\n const {\n size: customSize,\n disabled: customDisabled,\n className,\n status,\n bordered = true,\n prefixCls = 'ald-picker',\n onChange,\n disabledDate,\n popupClassName,\n locale: localeProp,\n ...restProps\n } = props;\n\n const ctxSize = useContext(SizeContext);\n const size = customSize || ctxSize || 'middle';\n const ctxDisabled = useContext(DisabledContext);\n const mergedDisabled = customDisabled ?? ctxDisabled;\n const ctxLocale = useContext(LocaleContext);\n const pickerLocale = localeProp || ctxLocale?.DatePicker || enUS;\n\n const sizeCls = SIZE_CLS[size] || '';\n\n // Wrap narrowed onChange to match rc-picker's wider signature\n const rcOnChange = React.useMemo(() => {\n if (!onChange) return undefined;\n return (\n dates: [Dayjs | null, Dayjs | null] | null,\n dateStrings: [string, string],\n ) => {\n onChange(dates, dateStrings);\n };\n }, [onChange]);\n\n // Wrap compat disabledDate to rc-picker v4 signature\n const rcDisabledDate = React.useMemo(() => {\n if (!disabledDate) return undefined;\n return (date: Dayjs, info: { type: PanelMode; from?: Dayjs }) =>\n disabledDate(date, info);\n }, [disabledDate]);\n\n // Merge popupClassName into classNames.popup for rc-picker v4\n const mergedClassNames = React.useMemo(() => {\n if (!popupClassName) return restProps.classNames;\n return {\n ...restProps.classNames,\n popup: cn(restProps.classNames?.popup, popupClassName),\n };\n }, [popupClassName, restProps.classNames]);\n\n return (\n <RcRangePicker<Dayjs>\n ref={ref}\n generateConfig={dayjsGenerateConfig}\n locale={pickerLocale}\n prefixCls={prefixCls}\n disabled={mergedDisabled}\n className={cn(\n sizeCls,\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ant-picker',\n !bordered && 'ald-picker-borderless',\n status === 'error' && 'ald-picker-status-error',\n status === 'warning' && 'ald-picker-status-warning',\n className,\n )}\n {...restProps}\n classNames={mergedClassNames}\n onChange={rcOnChange}\n disabledDate={rcDisabledDate}\n />\n );\n },\n);\n\n// ---- Picker variants ----\nfunction createPickerVariant(\n pickerMode: DatePickerProps['picker'],\n defaultPlaceholder: string,\n) {\n const PickerVariant = forwardRef<PickerRef, DatePickerProps>((props, ref) => (\n <InternalDatePicker\n ref={ref}\n picker={pickerMode}\n placeholder={props.placeholder ?? defaultPlaceholder}\n {...props}\n />\n ));\n PickerVariant.displayName = `DatePicker.${pickerMode}Picker`;\n return PickerVariant;\n}\n\nconst WeekPicker = createPickerVariant('week', 'Select week');\nconst MonthPicker = createPickerVariant('month', 'Select month');\nconst YearPicker = createPickerVariant('year', 'Select year');\nconst QuarterPicker = createPickerVariant('quarter', 'Select quarter');\n\nconst TimePicker = forwardRef<PickerRef, DatePickerProps>((props, ref) => (\n <InternalDatePicker\n ref={ref}\n picker=\"time\"\n placeholder={props.placeholder ?? 'Select time'}\n {...props}\n />\n));\nTimePicker.displayName = 'DatePicker.TimePicker';\n\n// ---- Attach sub-components ----\nInternalDatePicker.RangePicker = InternalRangePicker;\nInternalDatePicker.WeekPicker = WeekPicker;\nInternalDatePicker.MonthPicker = MonthPicker;\nInternalDatePicker.YearPicker = YearPicker;\nInternalDatePicker.TimePicker = TimePicker;\nInternalDatePicker.QuarterPicker = QuarterPicker;\n\nconst DatePicker = InternalDatePicker;\nexport default DatePicker;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/DatePicker/index.tsx"],"sourcesContent":["import type { Dayjs } from 'dayjs';\nimport React, { forwardRef, useContext } from 'react';\nimport { Picker, RangePicker as RcRangePicker } from 'rc-picker';\nimport type {\n PickerProps,\n RangePickerProps as RcRangePickerProps,\n PickerRef,\n} from 'rc-picker';\nimport type { PanelMode, RangePickerRef } from 'rc-picker/es/interface';\nimport dayjsGenerateConfig from 'rc-picker/es/generate/dayjs';\nimport enUS from 'rc-picker/es/locale/en_US';\nimport { LocaleContext } from '../locale/default';\nimport DisabledContext from '../ConfigProvider/DisabledContext';\nimport SizeContext, { type SizeType } from '../ConfigProvider/sizeContext';\nimport { cn } from '../lib/utils';\nimport './date-picker.css';\n\n// ---- Types ----\n// Re-export compatible types\nexport type RangeValue<T = Dayjs> = [T | null, T | null] | null;\n\n/**\n * disabledDate compat: rc-picker v4 requires (date, info) => boolean,\n * but antd v4 consumers pass (current) => boolean. We accept both.\n */\ntype DisabledDateCompat = (\n current: Dayjs,\n info?: { type: PanelMode; from?: Dayjs },\n) => boolean;\n\nexport interface DatePickerProps\n extends Omit<\n PickerProps<Dayjs>,\n 'generateConfig' | 'locale' | 'prefixCls' | 'onChange' | 'disabledDate'\n > {\n /** Override size from ConfigProvider */\n size?: SizeType;\n /** Validation status */\n status?: 'error' | 'warning';\n /** @deprecated Use `variant` or className instead */\n bordered?: boolean;\n /** Custom prefixCls */\n prefixCls?: string;\n /**\n * Narrowed onChange — single picker uses Dayjs | null, not Dayjs | Dayjs[].\n * Uses import('dayjs').Dayjs to avoid duplicate-dayjs type conflicts.\n */\n onChange?: (date: import('dayjs').Dayjs | null, dateString: string) => void;\n /**\n * disabledDate — accepts both rc-picker v4 signature and antd v4 compat\n * signature `(current: Dayjs) => boolean`.\n */\n disabledDate?: DisabledDateCompat;\n /** Callback when a date is selected on the panel */\n onSelect?: (date: Dayjs) => void;\n /** @deprecated Use `classNames.popup` instead. Preserved for antd v4 compat. */\n popupClassName?: string;\n /** Override locale for this picker instance. Defaults to ConfigProvider locale. */\n locale?: Record<string, any>;\n}\n\nexport interface RangePickerProps\n extends Omit<\n RcRangePickerProps<Dayjs>,\n 'generateConfig' | 'locale' | 'prefixCls' | 'onChange' | 'disabledDate'\n > {\n size?: SizeType;\n status?: 'error' | 'warning';\n bordered?: boolean;\n prefixCls?: string;\n /** Narrowed onChange for RangePicker */\n onChange?: (\n dates: [import('dayjs').Dayjs | null, import('dayjs').Dayjs | null] | null,\n dateStrings: [string, string],\n ) => void;\n /**\n * disabledDate — accepts both rc-picker v4 signature and antd v4 compat\n * signature `(current: Dayjs) => boolean`.\n */\n disabledDate?: DisabledDateCompat;\n /** @deprecated Use `classNames.popup` instead. Preserved for antd v4 compat. */\n popupClassName?: string;\n /** Override locale for this picker instance. Defaults to ConfigProvider locale. */\n locale?: Record<string, any>;\n}\n\nexport type YearPickerProps = DatePickerProps;\nexport type QuarterPickerProps = DatePickerProps;\nexport type MonthPickerProps = DatePickerProps;\nexport type WeekPickerProps = DatePickerProps;\nexport type TimePickerProps = DatePickerProps;\n\n// ---- Size mapping ----\nconst SIZE_CLS: Record<string, string> = {\n small: 'ald-picker-sm',\n large: 'ald-picker-lg',\n};\n\n// ---- DatePicker ----\nconst InternalDatePicker = forwardRef<PickerRef, DatePickerProps>(\n (props, ref) => {\n const {\n size: customSize,\n disabled: customDisabled,\n className,\n status,\n bordered = true,\n prefixCls = 'ald-picker',\n onChange,\n disabledDate,\n onSelect,\n onCalendarChange,\n popupClassName,\n locale: localeProp,\n ...restProps\n } = props;\n\n const ctxSize = useContext(SizeContext);\n const size = customSize || ctxSize || 'middle';\n const ctxDisabled = useContext(DisabledContext);\n const mergedDisabled = customDisabled ?? ctxDisabled;\n const ctxLocale = useContext(LocaleContext);\n // antd locale 对象包含 DatePicker 字段(即 rc-picker 格式的 locale)\n const pickerLocale = localeProp || ctxLocale?.DatePicker || enUS;\n\n const sizeCls = SIZE_CLS[size] || '';\n\n // Wrap narrowed onChange to match rc-picker's wider signature\n const rcOnChange = React.useMemo(() => {\n if (!onChange) return undefined;\n return (date: Dayjs | Dayjs[], dateString: string | string[]) => {\n onChange(\n (Array.isArray(date) ? date[0] : date) as Dayjs | null,\n Array.isArray(dateString) ? dateString[0] : dateString,\n );\n };\n }, [onChange]);\n\n // Wrap compat disabledDate to rc-picker v4 signature\n const rcDisabledDate = React.useMemo(() => {\n if (!disabledDate) return undefined;\n return (date: Dayjs, info: { type: PanelMode; from?: Dayjs }) =>\n disabledDate(date, info);\n }, [disabledDate]);\n\n const rcOnCalendarChange = React.useMemo(() => {\n if (!onCalendarChange && !onSelect) return undefined;\n return (\n date: Parameters<\n NonNullable<PickerProps<Dayjs>['onCalendarChange']>\n >[0],\n dateString: Parameters<\n NonNullable<PickerProps<Dayjs>['onCalendarChange']>\n >[1],\n info: Parameters<\n NonNullable<PickerProps<Dayjs>['onCalendarChange']>\n >[2],\n ) => {\n onCalendarChange?.(date, dateString, info);\n if (onSelect) {\n const selectedDate = Array.isArray(date) ? date[0] : date;\n if (selectedDate) {\n onSelect(selectedDate);\n }\n }\n };\n }, [onCalendarChange, onSelect]);\n\n // Merge popupClassName into classNames.popup for rc-picker v4\n const mergedClassNames = React.useMemo(() => {\n if (!popupClassName) return restProps.classNames;\n return {\n ...restProps.classNames,\n popup: cn(restProps.classNames?.popup, popupClassName),\n };\n }, [popupClassName, restProps.classNames]);\n\n return (\n <Picker<Dayjs>\n ref={ref}\n generateConfig={dayjsGenerateConfig}\n locale={pickerLocale}\n prefixCls={prefixCls}\n disabled={mergedDisabled}\n className={cn(\n sizeCls,\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ant-picker',\n !bordered && 'ald-picker-borderless',\n status === 'error' && 'ald-picker-status-error',\n status === 'warning' && 'ald-picker-status-warning',\n className,\n )}\n {...restProps}\n classNames={mergedClassNames}\n onChange={rcOnChange}\n onCalendarChange={rcOnCalendarChange}\n disabledDate={rcDisabledDate}\n />\n );\n },\n) as React.ForwardRefExoticComponent<\n DatePickerProps & React.RefAttributes<PickerRef>\n> & {\n RangePicker: typeof InternalRangePicker;\n WeekPicker: typeof WeekPicker;\n MonthPicker: typeof MonthPicker;\n YearPicker: typeof YearPicker;\n TimePicker: typeof TimePicker;\n QuarterPicker: typeof QuarterPicker;\n};\n\n// ---- RangePicker ----\nconst InternalRangePicker = forwardRef<RangePickerRef, RangePickerProps>(\n (props, ref) => {\n const {\n size: customSize,\n disabled: customDisabled,\n className,\n status,\n bordered = true,\n prefixCls = 'ald-picker',\n onChange,\n disabledDate,\n popupClassName,\n locale: localeProp,\n ...restProps\n } = props;\n\n const ctxSize = useContext(SizeContext);\n const size = customSize || ctxSize || 'middle';\n const ctxDisabled = useContext(DisabledContext);\n const mergedDisabled = customDisabled ?? ctxDisabled;\n const ctxLocale = useContext(LocaleContext);\n const pickerLocale = localeProp || ctxLocale?.DatePicker || enUS;\n\n const sizeCls = SIZE_CLS[size] || '';\n\n // Wrap narrowed onChange to match rc-picker's wider signature\n const rcOnChange = React.useMemo(() => {\n if (!onChange) return undefined;\n return (\n dates: [Dayjs | null, Dayjs | null] | null,\n dateStrings: [string, string],\n ) => {\n onChange(dates, dateStrings);\n };\n }, [onChange]);\n\n // Wrap compat disabledDate to rc-picker v4 signature\n const rcDisabledDate = React.useMemo(() => {\n if (!disabledDate) return undefined;\n return (date: Dayjs, info: { type: PanelMode; from?: Dayjs }) =>\n disabledDate(date, info);\n }, [disabledDate]);\n\n // Merge popupClassName into classNames.popup for rc-picker v4\n const mergedClassNames = React.useMemo(() => {\n if (!popupClassName) return restProps.classNames;\n return {\n ...restProps.classNames,\n popup: cn(restProps.classNames?.popup, popupClassName),\n };\n }, [popupClassName, restProps.classNames]);\n\n return (\n <RcRangePicker<Dayjs>\n ref={ref}\n generateConfig={dayjsGenerateConfig}\n locale={pickerLocale}\n prefixCls={prefixCls}\n disabled={mergedDisabled}\n className={cn(\n sizeCls,\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ant-picker',\n !bordered && 'ald-picker-borderless',\n status === 'error' && 'ald-picker-status-error',\n status === 'warning' && 'ald-picker-status-warning',\n className,\n )}\n {...restProps}\n classNames={mergedClassNames}\n onChange={rcOnChange}\n disabledDate={rcDisabledDate}\n />\n );\n },\n);\n\n// ---- Picker variants ----\nfunction createPickerVariant(\n pickerMode: DatePickerProps['picker'],\n defaultPlaceholder: string,\n) {\n const PickerVariant = forwardRef<PickerRef, DatePickerProps>((props, ref) => (\n <InternalDatePicker\n ref={ref}\n picker={pickerMode}\n placeholder={props.placeholder ?? defaultPlaceholder}\n {...props}\n />\n ));\n PickerVariant.displayName = `DatePicker.${pickerMode}Picker`;\n return PickerVariant;\n}\n\nconst WeekPicker = createPickerVariant('week', 'Select week');\nconst MonthPicker = createPickerVariant('month', 'Select month');\nconst YearPicker = createPickerVariant('year', 'Select year');\nconst QuarterPicker = createPickerVariant('quarter', 'Select quarter');\n\nconst TimePicker = forwardRef<PickerRef, DatePickerProps>((props, ref) => (\n <InternalDatePicker\n ref={ref}\n picker=\"time\"\n placeholder={props.placeholder ?? 'Select time'}\n {...props}\n />\n));\nTimePicker.displayName = 'DatePicker.TimePicker';\n\n// ---- Attach sub-components ----\nInternalDatePicker.RangePicker = InternalRangePicker;\nInternalDatePicker.WeekPicker = WeekPicker;\nInternalDatePicker.MonthPicker = MonthPicker;\nInternalDatePicker.YearPicker = YearPicker;\nInternalDatePicker.TimePicker = TimePicker;\nInternalDatePicker.QuarterPicker = QuarterPicker;\n\nconst DatePicker = InternalDatePicker;\nexport default DatePicker;\n"],"mappings":"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"}
|
package/dist/Dropdown/index.js
CHANGED
|
@@ -18,6 +18,9 @@ function resolvePlacementSide(currentPlacement) {
|
|
|
18
18
|
if (currentPlacement.startsWith("right")) return "right";
|
|
19
19
|
return "bottom";
|
|
20
20
|
}
|
|
21
|
+
function hasTrigger(trigger, action) {
|
|
22
|
+
return Array.isArray(trigger) ? trigger.includes(action) : trigger === action;
|
|
23
|
+
}
|
|
21
24
|
function Dropdown(props) {
|
|
22
25
|
const { children, destroyPopupOnHide = true, getPopupContainer, menu, overlayClassName, placement = "bottom-start", trigger = "click", open, onOpenChange = () => {}, overlayStyle, overlayInnerStyle, dropdownRender, disabled, offset: offsetProps = 4, delay = 0, autoUpdatePos = false, initialFocus = -1, popupMatchTriggerWidth = false, allowOverlap = false } = props;
|
|
23
26
|
const [isOpen, setIsOpen] = useState(open || false);
|
|
@@ -123,9 +126,9 @@ function Dropdown(props) {
|
|
|
123
126
|
],
|
|
124
127
|
whileElementsMounted: autoUpdatePos ? autoUpdate : void 0
|
|
125
128
|
});
|
|
126
|
-
const click = useClick(context);
|
|
129
|
+
const click = useClick(context, { enabled: hasTrigger(trigger, "click") });
|
|
127
130
|
const hover = useHover(context, {
|
|
128
|
-
enabled: trigger
|
|
131
|
+
enabled: hasTrigger(trigger, "hover"),
|
|
129
132
|
handleClose: safePolygon({}),
|
|
130
133
|
delay
|
|
131
134
|
});
|
|
@@ -133,13 +136,8 @@ function Dropdown(props) {
|
|
|
133
136
|
const role = useRole(context);
|
|
134
137
|
const { getReferenceProps, getFloatingProps } = useInteractions(useMemo(() => {
|
|
135
138
|
const res = [dismiss, role];
|
|
136
|
-
|
|
137
|
-
if (
|
|
138
|
-
console.error("trigger should be a string, support \"hover\" or \"click\" now.");
|
|
139
|
-
finalTrigger = "click";
|
|
140
|
-
}
|
|
141
|
-
if (finalTrigger === "hover") res.unshift(hover);
|
|
142
|
-
else if (finalTrigger === "click") res.unshift(click);
|
|
139
|
+
if (hasTrigger(trigger, "hover")) res.unshift(hover);
|
|
140
|
+
if (hasTrigger(trigger, "click")) res.unshift(click);
|
|
143
141
|
return res;
|
|
144
142
|
}, [
|
|
145
143
|
trigger,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Dropdown/index.tsx"],"sourcesContent":["import './dropdown.css';\nimport {\n FloatingFocusManager,\n FloatingFocusManagerProps,\n FloatingNode,\n FloatingTree,\n OffsetOptions,\n UseHoverProps,\n autoUpdate,\n flip,\n offset,\n safePolygon,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingParentNodeId,\n useHover,\n useId,\n useInteractions,\n useRole,\n} from '@floating-ui/react';\nimport { useMemoizedFn } from 'ahooks';\nimport { cn } from '../lib/utils';\nimport React, {\n cloneElement,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport ReactDOM from 'react-dom';\nimport Menu, { MenuInfo, MenuProps } from '../Menu';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\n\nconst OVERLAY_EXIT_ANIMATION_MS = 200;\n\nfunction resolvePlacementSide(\n currentPlacement: string,\n): 'top' | 'bottom' | 'left' | 'right' {\n const [side] = currentPlacement.split('-');\n if (\n side === 'top' ||\n side === 'bottom' ||\n side === 'left' ||\n side === 'right'\n ) {\n return side;\n }\n if (currentPlacement.startsWith('top')) {\n return 'top';\n }\n if (currentPlacement.startsWith('bottom')) {\n return 'bottom';\n }\n if (currentPlacement.startsWith('left')) {\n return 'left';\n }\n if (currentPlacement.startsWith('right')) {\n return 'right';\n }\n return 'bottom';\n}\n\nexport type ActionType = 'hover' | 'click';\nexport type PlacementType =\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'top-start'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n | 'right-start'\n | 'right-end'\n // Legacy antd-style placement names\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight';\nexport interface IDropdownProps {\n children: React.ReactNode;\n /**\n * @description 菜单弹出位置的偏移量\n */\n offset?: OffsetOptions;\n /**\n * @description 关闭后是否销毁 Dropdown\n * @default false\n */\n destroyPopupOnHide?: boolean;\n /**\n * @description 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位\n * @default () => document.body\n */\n getPopupContainer?: () => HTMLElement;\n /**\n * @description 菜单\n * @type Menu | () => Menu\n * @default -\n */\n menu?: MenuProps;\n // /**\n // * @description 菜单\n // * @type Menu | () => Menu\n // * @default -\n // */\n // menu?: ReactElement | (() => ReactElement);\n /**\n * @description 下拉根元素的类名称\n * @default -\n */\n overlayClassName?: string;\n /**\n * @description 菜单弹出位置\n * @default bottomLeft\n */\n placement?: PlacementType;\n /**\n * @description 触发下拉的行为\n * @type ActionType, 其中 ActionType 为 'hover' | 'click' | 'contextMenu';\n * @default click\n */\n trigger?: ActionType | ActionType[];\n /**\n * @description 菜单是否显示\n * @default -\n */\n open?: boolean;\n /**\n * @description 菜单显示状态改变时调用,参数为 open,点击菜单按钮导致的消失不会触发\n * @default -\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * @description 下拉框外层 overlay 的内联样式(与定位 transform 合并)\n * @default -\n */\n overlayStyle?: React.CSSProperties;\n /**\n * @description 下拉框内层 surface 的内联样式。\n * 用于覆盖 surface 默认约束(默认 min-width:160px、max-width:320px);\n * 自定义 dropdownRender 内容若需大于 320px 宽,传 `{ width: 400, maxWidth: 'none' }` 即可。\n * @default -\n */\n overlayInnerStyle?: React.CSSProperties;\n\n /**\n * @description 自定义下拉框内容\n * @default -\n */\n dropdownRender?: (menus: React.ReactNode) => React.ReactNode;\n /**\n * @description 是否禁用\n * @default false\n */\n // 透传给子元素,antd的dropdown用cloneElement生成dropdown的子元素,劫持了disabled属性,因此如果Dropdown上没有disabled属性,子元素不能获得该属性\n disabled?: boolean;\n /**\n * @description 鼠标移入后延迟显示下拉框的时间,单位为毫秒\n * @default 0\n */\n delay?: UseHoverProps['delay'];\n /**\n * @description 是否在下拉框变化的时候自动更新位置\n * @default false\n */\n autoUpdatePos?: boolean;\n /**\n * @description 初始化焦点,参照:https://floating-ui.com/docs/floatingfocusmanager#initialfocus\n */\n initialFocus?: FloatingFocusManagerProps['initialFocus'];\n\n /**\n * @description 菜单是否跟随触发元素宽度\n * @default false\n */\n popupMatchTriggerWidth?: boolean | number;\n /**\n * @description 空间不足时自动计算菜单最大高度并启用滚动,启用后 offset 固定为 0\n * @default false\n */\n allowOverlap?: boolean;\n}\n\nexport default function Dropdown(props: IDropdownProps) {\n const {\n children,\n destroyPopupOnHide = true,\n getPopupContainer,\n menu,\n overlayClassName,\n placement = 'bottom-start',\n trigger = 'click',\n open,\n onOpenChange = () => {},\n overlayStyle,\n overlayInnerStyle,\n dropdownRender,\n disabled,\n offset: offsetProps = 4,\n delay = 0,\n autoUpdatePos = false,\n // 默认不自动 focus\n initialFocus = -1,\n popupMatchTriggerWidth = false,\n allowOverlap = false,\n } = props;\n const [isOpen, setIsOpen] = useState<boolean>(open || false);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n const closeAnimationTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const lastResolvedFloatingStylesRef = useRef<React.CSSProperties | null>(\n null,\n );\n const lastResolvedSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const currentFloatingStylesRef = useRef<React.CSSProperties | null>(null);\n const currentFloatingSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const popupZIndex = useFloatingPopupZIndex();\n\n const onOpenChangeFn = useMemoizedFn(onOpenChange);\n const isOpenControlled = open !== undefined;\n\n const clearCloseAnimationTimer = useCallback(() => {\n if (closeAnimationTimerRef.current) {\n clearTimeout(closeAnimationTimerRef.current);\n closeAnimationTimerRef.current = null;\n }\n }, []);\n\n const stopCloseAnimation = useCallback(() => {\n clearCloseAnimationTimer();\n document.body.classList.remove('ald-dropdown-root-closing');\n setIsAnimatingOut(false);\n }, [clearCloseAnimationTimer]);\n\n const markRootClosing = useCallback(() => {\n document.body.classList.add('ald-dropdown-root-closing');\n lastResolvedFloatingStylesRef.current =\n currentFloatingStylesRef.current ?? lastResolvedFloatingStylesRef.current;\n lastResolvedSideRef.current =\n currentFloatingSideRef.current ?? lastResolvedSideRef.current;\n }, []);\n\n const startCloseAnimation = useCallback(() => {\n clearCloseAnimationTimer();\n markRootClosing();\n setIsAnimatingOut(true);\n closeAnimationTimerRef.current = setTimeout(() => {\n document.body.classList.remove('ald-dropdown-root-closing');\n setIsAnimatingOut(false);\n closeAnimationTimerRef.current = null;\n }, OVERLAY_EXIT_ANIMATION_MS);\n }, [clearCloseAnimationTimer, markRootClosing]);\n\n useLayoutEffect(() => {\n if (!isOpenControlled) {\n return;\n }\n\n if (open) {\n stopCloseAnimation();\n setIsOpen(true);\n return;\n }\n\n if (isOpen) {\n startCloseAnimation();\n }\n setIsOpen(false);\n }, [isOpen, isOpenControlled, open, startCloseAnimation, stopCloseAnimation]);\n\n useEffect(() => {\n return () => {\n clearCloseAnimationTimer();\n };\n }, [clearCloseAnimationTimer]);\n\n useEffect(() => {\n return () => {\n document.body.classList.remove('ald-dropdown-root-closing');\n };\n }, []);\n\n const onChangeOpen = useCallback(\n (newOpen: boolean) => {\n if (newOpen) {\n stopCloseAnimation();\n } else {\n startCloseAnimation();\n }\n\n if (!isOpenControlled) {\n setIsOpen(newOpen);\n }\n onOpenChangeFn(newOpen);\n },\n [isOpenControlled, onOpenChangeFn, startCloseAnimation, stopCloseAnimation],\n );\n\n const nodeId = useFloatingNodeId();\n const {\n refs,\n floatingStyles,\n context,\n placement: floatingPlacement,\n x,\n y,\n } = useFloating({\n nodeId,\n placement: placement as any,\n open: isOpen,\n onOpenChange: onChangeOpen,\n middleware: [\n offset(allowOverlap ? 0 : offsetProps),\n flip({\n fallbackAxisSideDirection: 'end',\n ...(allowOverlap && { fallbackStrategy: 'bestFit' }),\n }),\n shift(allowOverlap ? { mainAxis: true } : undefined),\n size({\n ...(allowOverlap && { padding: 8 }),\n apply({ availableHeight, rects, elements }) {\n const widthStyle = popupMatchTriggerWidth\n ? {\n width:\n typeof popupMatchTriggerWidth === 'number'\n ? `${popupMatchTriggerWidth}px`\n : `${rects.reference.width}px`,\n }\n : { minWidth: '144px' };\n const heightStyle = allowOverlap\n ? {\n maxHeight: `${Math.max(100, availableHeight)}px`,\n overflowY: 'auto',\n }\n : {};\n Object.assign(elements.floating.style, {\n ...widthStyle,\n ...heightStyle,\n });\n },\n }),\n ],\n whileElementsMounted: autoUpdatePos ? autoUpdate : undefined,\n });\n\n const click = useClick(context);\n const hover = useHover(context, {\n enabled: trigger === 'hover',\n handleClose: safePolygon({}),\n delay: delay,\n });\n const dismiss = useDismiss(context, {});\n const role = useRole(context);\n\n const propsList = useMemo(() => {\n const res = [dismiss, role];\n\n let finalTrigger = trigger;\n if (Array.isArray(trigger)) {\n // 对于数组形式的 trigger,告警\n console.error(\n 'trigger should be a string, support \"hover\" or \"click\" now.',\n );\n finalTrigger = 'click';\n }\n\n if (finalTrigger === 'hover') {\n res.unshift(hover);\n } else if (finalTrigger === 'click') {\n res.unshift(click);\n }\n return res;\n }, [trigger, click, dismiss, role, hover]);\n\n const { getReferenceProps, getFloatingProps } = useInteractions(propsList);\n\n const headingId = useId();\n\n const child = children as React.ReactElement;\n const childProps = child.props || {};\n const referenceProps = getReferenceProps();\n const modifiedChild = cloneElement(child, {\n ...childProps,\n disabled,\n // ref: (node: HTMLDivElement) => refs.setReference(node),\n ...referenceProps,\n onClick: (event: React.MouseEvent<HTMLElement>) => {\n childProps.onClick?.(event);\n const { onClick: referenceOnClick } = referenceProps;\n if (typeof referenceOnClick === 'function') {\n referenceOnClick(event);\n }\n },\n });\n\n const onMenuItemClick = useCallback(\n (info: MenuInfo) => {\n if (menu?.onClick) {\n menu.onClick(info);\n }\n if (info.keepOpen) {\n document.body.classList.remove('ald-dropdown-root-closing');\n return;\n }\n onChangeOpen(false);\n },\n [menu, onChangeOpen],\n );\n\n const menuInstance = useMemo(() => {\n const menuProps = {\n ...menu,\n items: menu?.items || [],\n onBeforeLeafItemClick: markRootClosing,\n rootClosing: isAnimatingOut,\n };\n return (\n <Menu\n {...menuProps}\n onClick={onMenuItemClick}\n externalOverflow={allowOverlap}\n />\n );\n }, [allowOverlap, isAnimatingOut, markRootClosing, menu, onMenuItemClick]);\n\n const popupElement = useMemo(() => {\n return typeof dropdownRender === 'function'\n ? dropdownRender(menuInstance)\n : menuInstance;\n }, [dropdownRender, menuInstance]);\n\n const floatingSide = resolvePlacementSide(String(floatingPlacement));\n const shouldKeepMounted = !destroyPopupOnHide || isOpen || isAnimatingOut;\n const isPositionReady = x !== null && y !== null;\n const overlayHidden =\n (!isOpen && !isAnimatingOut) || (isOpen && !isPositionReady);\n const resolvedFloatingStyles = isAnimatingOut\n ? lastResolvedFloatingStylesRef.current ?? floatingStyles\n : floatingStyles;\n const resolvedFloatingSide = isAnimatingOut\n ? lastResolvedSideRef.current\n : floatingSide;\n\n if (isOpen && isPositionReady) {\n currentFloatingStylesRef.current = { ...floatingStyles };\n currentFloatingSideRef.current = floatingSide;\n lastResolvedFloatingStylesRef.current = { ...floatingStyles };\n lastResolvedSideRef.current = floatingSide;\n }\n\n // 渲染浮动内容到自定义容器\n const renderFloatingContent = useCallback(() => {\n const surface = (\n <div\n className={cn(\n 'ald-dropdown-overlay',\n // tw-outline-none:FloatingFocusManager 打开时会聚焦浮层容器,不抑制 outline 会渲染出蓝色焦点框\n 'tw-pointer-events-auto tw-z-[1001] tw-max-w-none tw-outline-none',\n overlayClassName,\n { 'ald-dropdown-overlay-hidden': overlayHidden },\n )}\n ref={refs.setFloating}\n style={{\n zIndex: popupZIndex,\n ...resolvedFloatingStyles,\n ...overlayStyle,\n }}\n aria-labelledby={headingId}\n {...(isAnimatingOut ? {} : getFloatingProps())}\n >\n <div\n className={cn(\n 'ald-dropdown-surface',\n 'tw-flex tw-flex-col tw-items-start tw-text-sm',\n )}\n style={overlayInnerStyle}\n data-state={isOpen ? 'open' : 'closed'}\n data-side={resolvedFloatingSide}\n >\n {popupElement}\n </div>\n </div>\n );\n\n const popupElem =\n isAnimatingOut && !isOpen ? (\n surface\n ) : (\n <FloatingFocusManager\n context={context}\n modal={false}\n initialFocus={initialFocus}\n >\n {surface}\n </FloatingFocusManager>\n );\n\n const popupContainer =\n typeof getPopupContainer === 'function'\n ? getPopupContainer()\n : document.body;\n return ReactDOM.createPortal(popupElem, popupContainer);\n }, [\n context,\n getFloatingProps,\n getPopupContainer,\n headingId,\n popupElement,\n refs.setFloating,\n overlayClassName,\n overlayStyle,\n overlayInnerStyle,\n popupZIndex,\n overlayHidden,\n isAnimatingOut,\n isOpen,\n initialFocus,\n resolvedFloatingSide,\n resolvedFloatingStyles,\n ]);\n\n const popup = shouldKeepMounted ? renderFloatingContent() : null;\n\n const setTargetRef = useCallback(\n (node: HTMLElement | null) => {\n if (node) {\n // display: contents 元素没有 box model,getBoundingClientRect() 返回零值\n // 需要获取实际的第一个子元素作为 floating-ui 的参考元素\n const target =\n node.style.display === 'contents'\n ? (node.firstElementChild as HTMLElement) || node\n : node;\n refs.setReference(target);\n } else {\n refs.setReference(null);\n }\n },\n [refs],\n );\n\n const content = (\n <>\n <span ref={setTargetRef} style={{ display: 'contents' }}>\n {modifiedChild}\n </span>\n <FloatingNode id={nodeId}>{popup}</FloatingNode>\n </>\n );\n\n const parentId = useFloatingParentNodeId();\n if (!parentId) {\n return <FloatingTree>{content}</FloatingTree>;\n }\n\n return content;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Dropdown/index.tsx"],"sourcesContent":["import './dropdown.css';\nimport {\n FloatingFocusManager,\n FloatingFocusManagerProps,\n FloatingNode,\n FloatingTree,\n OffsetOptions,\n UseHoverProps,\n autoUpdate,\n flip,\n offset,\n safePolygon,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingParentNodeId,\n useHover,\n useId,\n useInteractions,\n useRole,\n} from '@floating-ui/react';\nimport { useMemoizedFn } from 'ahooks';\nimport { cn } from '../lib/utils';\nimport React, {\n cloneElement,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport ReactDOM from 'react-dom';\nimport Menu, { MenuInfo, MenuProps } from '../Menu';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\n\nconst OVERLAY_EXIT_ANIMATION_MS = 200;\n\nfunction resolvePlacementSide(\n currentPlacement: string,\n): 'top' | 'bottom' | 'left' | 'right' {\n const [side] = currentPlacement.split('-');\n if (\n side === 'top' ||\n side === 'bottom' ||\n side === 'left' ||\n side === 'right'\n ) {\n return side;\n }\n if (currentPlacement.startsWith('top')) {\n return 'top';\n }\n if (currentPlacement.startsWith('bottom')) {\n return 'bottom';\n }\n if (currentPlacement.startsWith('left')) {\n return 'left';\n }\n if (currentPlacement.startsWith('right')) {\n return 'right';\n }\n return 'bottom';\n}\n\nexport type ActionType = 'hover' | 'click';\nexport type PlacementType =\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'top-start'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n | 'right-start'\n | 'right-end'\n // Legacy antd-style placement names\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight';\nexport interface IDropdownProps {\n children: React.ReactNode;\n /**\n * @description 菜单弹出位置的偏移量\n */\n offset?: OffsetOptions;\n /**\n * @description 关闭后是否销毁 Dropdown\n * @default false\n */\n destroyPopupOnHide?: boolean;\n /**\n * @description 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位\n * @default () => document.body\n */\n getPopupContainer?: () => HTMLElement;\n /**\n * @description 菜单\n * @type Menu | () => Menu\n * @default -\n */\n menu?: MenuProps;\n // /**\n // * @description 菜单\n // * @type Menu | () => Menu\n // * @default -\n // */\n // menu?: ReactElement | (() => ReactElement);\n /**\n * @description 下拉根元素的类名称\n * @default -\n */\n overlayClassName?: string;\n /**\n * @description 菜单弹出位置\n * @default bottomLeft\n */\n placement?: PlacementType;\n /**\n * @description 触发下拉的行为\n * @type ActionType, 其中 ActionType 为 'hover' | 'click' | 'contextMenu';\n * @default click\n */\n trigger?: ActionType | ActionType[];\n /**\n * @description 菜单是否显示\n * @default -\n */\n open?: boolean;\n /**\n * @description 菜单显示状态改变时调用,参数为 open,点击菜单按钮导致的消失不会触发\n * @default -\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * @description 下拉框外层 overlay 的内联样式(与定位 transform 合并)\n * @default -\n */\n overlayStyle?: React.CSSProperties;\n /**\n * @description 下拉框内层 surface 的内联样式。\n * 用于覆盖 surface 默认约束(默认 min-width:160px、max-width:320px);\n * 自定义 dropdownRender 内容若需大于 320px 宽,传 `{ width: 400, maxWidth: 'none' }` 即可。\n * @default -\n */\n overlayInnerStyle?: React.CSSProperties;\n\n /**\n * @description 自定义下拉框内容\n * @default -\n */\n dropdownRender?: (menus: React.ReactNode) => React.ReactNode;\n /**\n * @description 是否禁用\n * @default false\n */\n // 透传给子元素,antd的dropdown用cloneElement生成dropdown的子元素,劫持了disabled属性,因此如果Dropdown上没有disabled属性,子元素不能获得该属性\n disabled?: boolean;\n /**\n * @description 鼠标移入后延迟显示下拉框的时间,单位为毫秒\n * @default 0\n */\n delay?: UseHoverProps['delay'];\n /**\n * @description 是否在下拉框变化的时候自动更新位置\n * @default false\n */\n autoUpdatePos?: boolean;\n /**\n * @description 初始化焦点,参照:https://floating-ui.com/docs/floatingfocusmanager#initialfocus\n */\n initialFocus?: FloatingFocusManagerProps['initialFocus'];\n\n /**\n * @description 菜单是否跟随触发元素宽度\n * @default false\n */\n popupMatchTriggerWidth?: boolean | number;\n /**\n * @description 空间不足时自动计算菜单最大高度并启用滚动,启用后 offset 固定为 0\n * @default false\n */\n allowOverlap?: boolean;\n}\n\nfunction hasTrigger(\n trigger: ActionType | ActionType[],\n action: ActionType,\n): boolean {\n return Array.isArray(trigger) ? trigger.includes(action) : trigger === action;\n}\n\nexport default function Dropdown(props: IDropdownProps) {\n const {\n children,\n destroyPopupOnHide = true,\n getPopupContainer,\n menu,\n overlayClassName,\n placement = 'bottom-start',\n trigger = 'click',\n open,\n onOpenChange = () => {},\n overlayStyle,\n overlayInnerStyle,\n dropdownRender,\n disabled,\n offset: offsetProps = 4,\n delay = 0,\n autoUpdatePos = false,\n // 默认不自动 focus\n initialFocus = -1,\n popupMatchTriggerWidth = false,\n allowOverlap = false,\n } = props;\n const [isOpen, setIsOpen] = useState<boolean>(open || false);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n const closeAnimationTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const lastResolvedFloatingStylesRef = useRef<React.CSSProperties | null>(\n null,\n );\n const lastResolvedSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const currentFloatingStylesRef = useRef<React.CSSProperties | null>(null);\n const currentFloatingSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const popupZIndex = useFloatingPopupZIndex();\n\n const onOpenChangeFn = useMemoizedFn(onOpenChange);\n const isOpenControlled = open !== undefined;\n\n const clearCloseAnimationTimer = useCallback(() => {\n if (closeAnimationTimerRef.current) {\n clearTimeout(closeAnimationTimerRef.current);\n closeAnimationTimerRef.current = null;\n }\n }, []);\n\n const stopCloseAnimation = useCallback(() => {\n clearCloseAnimationTimer();\n document.body.classList.remove('ald-dropdown-root-closing');\n setIsAnimatingOut(false);\n }, [clearCloseAnimationTimer]);\n\n const markRootClosing = useCallback(() => {\n document.body.classList.add('ald-dropdown-root-closing');\n lastResolvedFloatingStylesRef.current =\n currentFloatingStylesRef.current ?? lastResolvedFloatingStylesRef.current;\n lastResolvedSideRef.current =\n currentFloatingSideRef.current ?? lastResolvedSideRef.current;\n }, []);\n\n const startCloseAnimation = useCallback(() => {\n clearCloseAnimationTimer();\n markRootClosing();\n setIsAnimatingOut(true);\n closeAnimationTimerRef.current = setTimeout(() => {\n document.body.classList.remove('ald-dropdown-root-closing');\n setIsAnimatingOut(false);\n closeAnimationTimerRef.current = null;\n }, OVERLAY_EXIT_ANIMATION_MS);\n }, [clearCloseAnimationTimer, markRootClosing]);\n\n useLayoutEffect(() => {\n if (!isOpenControlled) {\n return;\n }\n\n if (open) {\n stopCloseAnimation();\n setIsOpen(true);\n return;\n }\n\n if (isOpen) {\n startCloseAnimation();\n }\n setIsOpen(false);\n }, [isOpen, isOpenControlled, open, startCloseAnimation, stopCloseAnimation]);\n\n useEffect(() => {\n return () => {\n clearCloseAnimationTimer();\n };\n }, [clearCloseAnimationTimer]);\n\n useEffect(() => {\n return () => {\n document.body.classList.remove('ald-dropdown-root-closing');\n };\n }, []);\n\n const onChangeOpen = useCallback(\n (newOpen: boolean) => {\n if (newOpen) {\n stopCloseAnimation();\n } else {\n startCloseAnimation();\n }\n\n if (!isOpenControlled) {\n setIsOpen(newOpen);\n }\n onOpenChangeFn(newOpen);\n },\n [isOpenControlled, onOpenChangeFn, startCloseAnimation, stopCloseAnimation],\n );\n\n const nodeId = useFloatingNodeId();\n const {\n refs,\n floatingStyles,\n context,\n placement: floatingPlacement,\n x,\n y,\n } = useFloating({\n nodeId,\n placement: placement as any,\n open: isOpen,\n onOpenChange: onChangeOpen,\n middleware: [\n offset(allowOverlap ? 0 : offsetProps),\n flip({\n fallbackAxisSideDirection: 'end',\n ...(allowOverlap && { fallbackStrategy: 'bestFit' }),\n }),\n shift(allowOverlap ? { mainAxis: true } : undefined),\n size({\n ...(allowOverlap && { padding: 8 }),\n apply({ availableHeight, rects, elements }) {\n const widthStyle = popupMatchTriggerWidth\n ? {\n width:\n typeof popupMatchTriggerWidth === 'number'\n ? `${popupMatchTriggerWidth}px`\n : `${rects.reference.width}px`,\n }\n : { minWidth: '144px' };\n const heightStyle = allowOverlap\n ? {\n maxHeight: `${Math.max(100, availableHeight)}px`,\n overflowY: 'auto',\n }\n : {};\n Object.assign(elements.floating.style, {\n ...widthStyle,\n ...heightStyle,\n });\n },\n }),\n ],\n whileElementsMounted: autoUpdatePos ? autoUpdate : undefined,\n });\n\n const click = useClick(context, {\n enabled: hasTrigger(trigger, 'click'),\n });\n const hover = useHover(context, {\n enabled: hasTrigger(trigger, 'hover'),\n handleClose: safePolygon({}),\n delay: delay,\n });\n const dismiss = useDismiss(context, {});\n const role = useRole(context);\n\n const propsList = useMemo(() => {\n const res = [dismiss, role];\n\n if (hasTrigger(trigger, 'hover')) {\n res.unshift(hover);\n }\n if (hasTrigger(trigger, 'click')) {\n res.unshift(click);\n }\n return res;\n }, [trigger, click, dismiss, role, hover]);\n\n const { getReferenceProps, getFloatingProps } = useInteractions(propsList);\n\n const headingId = useId();\n\n const child = children as React.ReactElement;\n const childProps = child.props || {};\n const referenceProps = getReferenceProps();\n const modifiedChild = cloneElement(child, {\n ...childProps,\n disabled,\n // ref: (node: HTMLDivElement) => refs.setReference(node),\n ...referenceProps,\n onClick: (event: React.MouseEvent<HTMLElement>) => {\n childProps.onClick?.(event);\n const { onClick: referenceOnClick } = referenceProps;\n if (typeof referenceOnClick === 'function') {\n referenceOnClick(event);\n }\n },\n });\n\n const onMenuItemClick = useCallback(\n (info: MenuInfo) => {\n if (menu?.onClick) {\n menu.onClick(info);\n }\n if (info.keepOpen) {\n document.body.classList.remove('ald-dropdown-root-closing');\n return;\n }\n onChangeOpen(false);\n },\n [menu, onChangeOpen],\n );\n\n const menuInstance = useMemo(() => {\n const menuProps = {\n ...menu,\n items: menu?.items || [],\n onBeforeLeafItemClick: markRootClosing,\n rootClosing: isAnimatingOut,\n };\n return (\n <Menu\n {...menuProps}\n onClick={onMenuItemClick}\n externalOverflow={allowOverlap}\n />\n );\n }, [allowOverlap, isAnimatingOut, markRootClosing, menu, onMenuItemClick]);\n\n const popupElement = useMemo(() => {\n return typeof dropdownRender === 'function'\n ? dropdownRender(menuInstance)\n : menuInstance;\n }, [dropdownRender, menuInstance]);\n\n const floatingSide = resolvePlacementSide(String(floatingPlacement));\n const shouldKeepMounted = !destroyPopupOnHide || isOpen || isAnimatingOut;\n const isPositionReady = x !== null && y !== null;\n const overlayHidden =\n (!isOpen && !isAnimatingOut) || (isOpen && !isPositionReady);\n const resolvedFloatingStyles = isAnimatingOut\n ? lastResolvedFloatingStylesRef.current ?? floatingStyles\n : floatingStyles;\n const resolvedFloatingSide = isAnimatingOut\n ? lastResolvedSideRef.current\n : floatingSide;\n\n if (isOpen && isPositionReady) {\n currentFloatingStylesRef.current = { ...floatingStyles };\n currentFloatingSideRef.current = floatingSide;\n lastResolvedFloatingStylesRef.current = { ...floatingStyles };\n lastResolvedSideRef.current = floatingSide;\n }\n\n // 渲染浮动内容到自定义容器\n const renderFloatingContent = useCallback(() => {\n const surface = (\n <div\n className={cn(\n 'ald-dropdown-overlay',\n // tw-outline-none:FloatingFocusManager 打开时会聚焦浮层容器,不抑制 outline 会渲染出蓝色焦点框\n 'tw-pointer-events-auto tw-z-[1001] tw-max-w-none tw-outline-none',\n overlayClassName,\n { 'ald-dropdown-overlay-hidden': overlayHidden },\n )}\n ref={refs.setFloating}\n style={{\n zIndex: popupZIndex,\n ...resolvedFloatingStyles,\n ...overlayStyle,\n }}\n aria-labelledby={headingId}\n {...(isAnimatingOut ? {} : getFloatingProps())}\n >\n <div\n className={cn(\n 'ald-dropdown-surface',\n 'tw-flex tw-flex-col tw-items-start tw-text-sm',\n )}\n style={overlayInnerStyle}\n data-state={isOpen ? 'open' : 'closed'}\n data-side={resolvedFloatingSide}\n >\n {popupElement}\n </div>\n </div>\n );\n\n const popupElem =\n isAnimatingOut && !isOpen ? (\n surface\n ) : (\n <FloatingFocusManager\n context={context}\n modal={false}\n initialFocus={initialFocus}\n >\n {surface}\n </FloatingFocusManager>\n );\n\n const popupContainer =\n typeof getPopupContainer === 'function'\n ? getPopupContainer()\n : document.body;\n return ReactDOM.createPortal(popupElem, popupContainer);\n }, [\n context,\n getFloatingProps,\n getPopupContainer,\n headingId,\n popupElement,\n refs.setFloating,\n overlayClassName,\n overlayStyle,\n overlayInnerStyle,\n popupZIndex,\n overlayHidden,\n isAnimatingOut,\n isOpen,\n initialFocus,\n resolvedFloatingSide,\n resolvedFloatingStyles,\n ]);\n\n const popup = shouldKeepMounted ? renderFloatingContent() : null;\n\n const setTargetRef = useCallback(\n (node: HTMLElement | null) => {\n if (node) {\n // display: contents 元素没有 box model,getBoundingClientRect() 返回零值\n // 需要获取实际的第一个子元素作为 floating-ui 的参考元素\n const target =\n node.style.display === 'contents'\n ? (node.firstElementChild as HTMLElement) || node\n : node;\n refs.setReference(target);\n } else {\n refs.setReference(null);\n }\n },\n [refs],\n );\n\n const content = (\n <>\n <span ref={setTargetRef} style={{ display: 'contents' }}>\n {modifiedChild}\n </span>\n <FloatingNode id={nodeId}>{popup}</FloatingNode>\n </>\n );\n\n const parentId = useFloatingParentNodeId();\n if (!parentId) {\n return <FloatingTree>{content}</FloatingTree>;\n }\n\n return content;\n}\n"],"mappings":"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"}
|
package/dist/Empty/index.js
CHANGED
|
@@ -17,8 +17,7 @@ var searchEmptySmallImage = /* @__PURE__ */ jsx(SearchSmall, {});
|
|
|
17
17
|
var Empty = (props) => {
|
|
18
18
|
const { locale } = React$1.useContext(LocaleContext);
|
|
19
19
|
const t = getTranslator(locale);
|
|
20
|
-
const { className, image = props.size === "small" ? searchEmptySmallImage : searchEmptyImg, description, title = t.Empty.noContentFound, size, children, imageStyle, footerClassNames, ...restProps } = props;
|
|
21
|
-
const prefixCls = "ald-empty";
|
|
20
|
+
const { className, image = props.size === "small" ? searchEmptySmallImage : searchEmptyImg, description, title = t.Empty.noContentFound, size, children, imageStyle, footerClassNames, prefixCls = "ald-empty", ...restProps } = props;
|
|
22
21
|
const alt = typeof description === "string" ? description : "empty";
|
|
23
22
|
let imageNode = null;
|
|
24
23
|
if (typeof image === "string") imageNode = /* @__PURE__ */ jsx("img", {
|
package/dist/Empty/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Empty/index.tsx"],"sourcesContent":["import _ from 'lodash';\nimport * as React from 'react';\nimport { cn } from '../lib/utils';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport DataEmptyImg from './image/Data';\nimport SearchEmptyImg from './image/Search';\nimport SearchEmptySmallImage from './image/SearchSmall';\nimport UserEmptyImg from './image/User';\nimport WorkbookEmptyImg from './image/WorkBook';\n\nconst searchEmptyImg = <SearchEmptyImg />;\nconst userEmptyImg = <UserEmptyImg />;\nconst workbookEmptyImg = <WorkbookEmptyImg />;\nconst dataEmptyImg = <DataEmptyImg />;\nconst searchEmptySmallImage = <SearchEmptySmallImage />;\n\ntype TEmptySize = 'large' | 'small';\nexport interface IEmptyProps {\n prefixCls?: string;\n className?: string;\n style?: React.CSSProperties;\n title?: React.ReactNode;\n imageStyle?: React.CSSProperties;\n size?: TEmptySize;\n image?: React.ReactNode;\n description?: React.ReactNode;\n children?: React.ReactNode;\n footerClassNames?: string;\n}\n\ninterface IEmptyType extends React.FC<IEmptyProps> {\n PRESENTED_IMAGE_SEARCH: React.ReactNode;\n PRESENTED_IMAGE_USER: React.ReactNode;\n PRESENTED_IMAGE_WORKBOOK: React.ReactNode;\n PRESENTED_IMAGE_DATA: React.ReactNode;\n PRESENTED_IMAGE_SEARCH_SMALL: React.ReactNode;\n}\n\nconst Empty: IEmptyType = (props: IEmptyProps) => {\n const { locale } = React.useContext(LocaleContext);\n const t = getTranslator(locale);\n const {\n className,\n image = props.size === 'small' ? searchEmptySmallImage : searchEmptyImg,\n description,\n title = t.Empty.noContentFound,\n size,\n children,\n imageStyle,\n footerClassNames,\n ...restProps\n } = props;\n const
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Empty/index.tsx"],"sourcesContent":["import _ from 'lodash';\nimport * as React from 'react';\nimport { cn } from '../lib/utils';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport DataEmptyImg from './image/Data';\nimport SearchEmptyImg from './image/Search';\nimport SearchEmptySmallImage from './image/SearchSmall';\nimport UserEmptyImg from './image/User';\nimport WorkbookEmptyImg from './image/WorkBook';\n\nconst searchEmptyImg = <SearchEmptyImg />;\nconst userEmptyImg = <UserEmptyImg />;\nconst workbookEmptyImg = <WorkbookEmptyImg />;\nconst dataEmptyImg = <DataEmptyImg />;\nconst searchEmptySmallImage = <SearchEmptySmallImage />;\n\ntype TEmptySize = 'large' | 'small';\nexport interface IEmptyProps {\n prefixCls?: string;\n className?: string;\n style?: React.CSSProperties;\n title?: React.ReactNode;\n imageStyle?: React.CSSProperties;\n size?: TEmptySize;\n image?: React.ReactNode;\n description?: React.ReactNode;\n children?: React.ReactNode;\n footerClassNames?: string;\n}\n\ninterface IEmptyType extends React.FC<IEmptyProps> {\n PRESENTED_IMAGE_SEARCH: React.ReactNode;\n PRESENTED_IMAGE_USER: React.ReactNode;\n PRESENTED_IMAGE_WORKBOOK: React.ReactNode;\n PRESENTED_IMAGE_DATA: React.ReactNode;\n PRESENTED_IMAGE_SEARCH_SMALL: React.ReactNode;\n}\n\nconst Empty: IEmptyType = (props: IEmptyProps) => {\n const { locale } = React.useContext(LocaleContext);\n const t = getTranslator(locale);\n const {\n className,\n image = props.size === 'small' ? searchEmptySmallImage : searchEmptyImg,\n description,\n title = t.Empty.noContentFound,\n size,\n children,\n imageStyle,\n footerClassNames,\n prefixCls = 'ald-empty',\n ...restProps\n } = props;\n const alt = typeof description === 'string' ? description : 'empty';\n\n let imageNode: React.ReactNode = null;\n\n if (typeof image === 'string') {\n imageNode = <img alt={alt} src={image} />;\n } else {\n imageNode = image;\n }\n const getSize = (ESize: TEmptySize | undefined): TEmptySize => {\n if (ESize === undefined) {\n return 'large';\n }\n if (['small', 'large'].includes(ESize)) {\n return ESize;\n }\n return 'large';\n };\n\n const resolvedSize = getSize(size);\n const isSmall = resolvedSize === 'small';\n\n return (\n <div\n className={cn(\n prefixCls,\n 'tw-flex tw-h-full tw-flex-col tw-items-center tw-justify-center',\n `${prefixCls}-${resolvedSize}`,\n isSmall && 'tw-p-6',\n className,\n )}\n {...restProps}\n >\n {!_.isNull(imageNode) && (\n <div\n className={cn(\n `${prefixCls}-image-wrap`,\n 'tw-flex tw-items-center tw-justify-center',\n isSmall ? 'tw-size-10' : 'tw-size-40',\n )}\n style={imageStyle}\n >\n {imageNode}\n </div>\n )}\n\n {title && (\n <div\n className={cn(\n `${prefixCls}-title`,\n 'tw-mb-1 tw-mt-2 tw-text-sm tw-font-medium tw-leading-6',\n `${prefixCls}-title-${size}`,\n isSmall\n ? 'tw-font-normal tw-text-[var(--content-secondary)]'\n : 'tw-text-[var(--content-primary)]',\n )}\n >\n {title}\n </div>\n )}\n {description && size !== 'small' && (\n <div\n className={cn(\n `${prefixCls}-description`,\n 'tw-text-xs tw-font-normal tw-leading-5 tw-text-[var(--content-secondary)]',\n )}\n >\n {description}\n </div>\n )}\n {children && (\n <div className={cn(`${prefixCls}-footer`, 'tw-mt-6', footerClassNames)}>\n {children}\n </div>\n )}\n </div>\n );\n};\n\nEmpty.PRESENTED_IMAGE_SEARCH = searchEmptyImg;\nEmpty.PRESENTED_IMAGE_USER = userEmptyImg;\nEmpty.PRESENTED_IMAGE_WORKBOOK = workbookEmptyImg;\nEmpty.PRESENTED_IMAGE_DATA = dataEmptyImg;\nEmpty.PRESENTED_IMAGE_SEARCH_SMALL = searchEmptySmallImage;\n\nexport default Empty;\n"],"mappings":";;;;;;;;;;;AAUA,IAAM,iBAAiB,oBAAC,QAAD,EAAkB,CAAA;AACzC,IAAM,eAAe,oBAAC,MAAD,EAAgB,CAAA;AACrC,IAAM,mBAAmB,oBAAC,UAAD,EAAoB,CAAA;AAC7C,IAAM,eAAe,oBAAC,MAAD,EAAgB,CAAA;AACrC,IAAM,wBAAwB,oBAAC,aAAD,EAAyB,CAAA;AAwBvD,IAAM,SAAqB,UAAuB;CAChD,MAAM,EAAE,WAAW,QAAM,WAAW,cAAc;CAClD,MAAM,IAAI,cAAc,OAAO;CAC/B,MAAM,EACJ,WACA,QAAQ,MAAM,SAAS,UAAU,wBAAwB,gBACzD,aACA,QAAQ,EAAE,MAAM,gBAChB,MACA,UACA,YACA,kBACA,YAAY,aACZ,GAAG,cACD;CACJ,MAAM,MAAM,OAAO,gBAAgB,WAAW,cAAc;CAE5D,IAAI,YAA6B;AAEjC,KAAI,OAAO,UAAU,SACnB,aAAY,oBAAC,OAAD;EAAU;EAAK,KAAK;EAAS,CAAA;KAEzC,aAAY;CAEd,MAAM,WAAW,UAA8C;AAC7D,MAAI,UAAU,OACZ,QAAO;AAET,MAAI,CAAC,SAAS,QAAQ,CAAC,SAAS,MAAM,CACpC,QAAO;AAET,SAAO;;CAGT,MAAM,eAAe,QAAQ,KAAK;CAClC,MAAM,UAAU,iBAAiB;AAEjC,QACE,qBAAC,OAAD;EACE,WAAW,GACT,WACA,mEACA,GAAG,UAAU,GAAG,gBAChB,WAAW,UACX,UACD;EACD,GAAI;YARN;GAUG,CAAC,EAAE,OAAO,UAAU,IACnB,oBAAC,OAAD;IACE,WAAW,GACT,GAAG,UAAU,cACb,6CACA,UAAU,eAAe,aAC1B;IACD,OAAO;cAEN;IACG,CAAA;GAGP,SACC,oBAAC,OAAD;IACE,WAAW,GACT,GAAG,UAAU,SACb,0DACA,GAAG,UAAU,SAAS,QACtB,UACI,sDACA,mCACL;cAEA;IACG,CAAA;GAEP,eAAe,SAAS,WACvB,oBAAC,OAAD;IACE,WAAW,GACT,GAAG,UAAU,eACb,4EACD;cAEA;IACG,CAAA;GAEP,YACC,oBAAC,OAAD;IAAK,WAAW,GAAG,GAAG,UAAU,UAAU,WAAW,iBAAiB;IACnE;IACG,CAAA;GAEJ;;;AAIV,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,2BAA2B;AACjC,MAAM,uBAAuB;AAC7B,MAAM,+BAA+B"}
|
|
@@ -12,6 +12,10 @@ interface IIconButtonProps {
|
|
|
12
12
|
tooltip?: ITooltipProps;
|
|
13
13
|
id?: string;
|
|
14
14
|
mode?: 'light' | 'dark';
|
|
15
|
+
/** 透传到底层触发器 DOM 的 data-testid,用于自动化测试定位 */
|
|
16
|
+
'data-testid'?: string;
|
|
17
|
+
/** 透传到底层触发器 DOM 的 aria-label,用于可访问性与自动化测试定位 */
|
|
18
|
+
'aria-label'?: string;
|
|
15
19
|
}
|
|
16
20
|
declare const DropdownButton: React.ForwardRefExoticComponent<IIconButtonProps & Omit<IDropdownProps, "children"> & {
|
|
17
21
|
showArrow?: boolean | undefined;
|
package/dist/IconButton/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { forwardRef, useMemo } from "react";
|
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
//#region src/IconButton/index.tsx
|
|
10
10
|
var InternalIconButton = forwardRef(function(props, ref) {
|
|
11
|
-
const { icon, onClick = () => {}, disabled, size = "middle", keepFocus, className, tooltip, id, mode = "light" } = props;
|
|
11
|
+
const { icon, onClick = () => {}, disabled, size = "middle", keepFocus, className, tooltip, id, mode = "light", "data-testid": dataTestid, "aria-label": ariaLabel } = props;
|
|
12
12
|
const onButtonClick = (e) => {
|
|
13
13
|
if (disabled) {
|
|
14
14
|
e.stopPropagation();
|
|
@@ -29,6 +29,8 @@ var InternalIconButton = forwardRef(function(props, ref) {
|
|
|
29
29
|
}),
|
|
30
30
|
ref,
|
|
31
31
|
onClick: onButtonClick,
|
|
32
|
+
"data-testid": dataTestid,
|
|
33
|
+
"aria-label": ariaLabel,
|
|
32
34
|
children: /* @__PURE__ */ jsx("div", {
|
|
33
35
|
className: "ald-icon-button-wrap",
|
|
34
36
|
children: icon
|
|
@@ -37,7 +39,7 @@ var InternalIconButton = forwardRef(function(props, ref) {
|
|
|
37
39
|
});
|
|
38
40
|
});
|
|
39
41
|
var DropdownButton = forwardRef(function(props, ref) {
|
|
40
|
-
const { icon, onClick = () => {}, disabled, size = "middle", menu, className, onOpenChange, tooltip, id, showArrow, mode = "light", ...restDropdownProps } = props;
|
|
42
|
+
const { icon, onClick = () => {}, disabled, size = "middle", menu, className, onOpenChange, tooltip, id, showArrow, mode = "light", "data-testid": dataTestid, "aria-label": ariaLabel, ...restDropdownProps } = props;
|
|
41
43
|
const onButtonClick = (e) => {
|
|
42
44
|
if (disabled) {
|
|
43
45
|
e.stopPropagation();
|
|
@@ -59,6 +61,8 @@ var DropdownButton = forwardRef(function(props, ref) {
|
|
|
59
61
|
}),
|
|
60
62
|
ref,
|
|
61
63
|
onClick: onButtonClick,
|
|
64
|
+
"data-testid": dataTestid,
|
|
65
|
+
"aria-label": ariaLabel,
|
|
62
66
|
children: [/* @__PURE__ */ jsx("div", {
|
|
63
67
|
className: "ald-icon-button-wrap",
|
|
64
68
|
children: icon
|
|
@@ -80,6 +84,8 @@ var DropdownButton = forwardRef(function(props, ref) {
|
|
|
80
84
|
}),
|
|
81
85
|
ref,
|
|
82
86
|
onClick: onButtonClick,
|
|
87
|
+
"data-testid": dataTestid,
|
|
88
|
+
"aria-label": ariaLabel,
|
|
83
89
|
children: [/* @__PURE__ */ jsx("div", {
|
|
84
90
|
className: "ald-icon-button-wrap",
|
|
85
91
|
children: icon
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/IconButton/index.tsx"],"sourcesContent":["import './icon-button.css';\nimport { cn } from '../lib/utils';\nimport React, { forwardRef, useMemo } from 'react';\nimport Dropdown, { IDropdownProps } from '../Dropdown/index';\nimport { FoldDownFill } from '../Icon';\nimport { TSize } from '../Input';\nimport { getSizeType } from '../Input/components/Input';\nimport Tooltip, { ITooltipProps } from '../Tooltip';\ninterface IIconButtonProps {\n icon: React.ReactNode;\n onClick?: (e: React.MouseEvent) => void;\n disabled?: boolean;\n size?: TSize;\n className?: string;\n keepFocus?: boolean;\n tooltip?: ITooltipProps;\n id?: string;\n mode?: 'light' | 'dark';\n}\ntype IDropdownIconButtonProps = IIconButtonProps &\n Omit<IDropdownProps, 'children'> & {\n showArrow?: boolean;\n };\nconst InternalIconButton = forwardRef(function (\n props: IIconButtonProps,\n ref: React.Ref<HTMLDivElement>,\n) {\n const {\n icon,\n onClick = () => {},\n disabled,\n size = 'middle',\n keepFocus,\n className,\n tooltip,\n id,\n mode = 'light',\n } = props;\n const onButtonClick = (e: React.MouseEvent) => {\n if (disabled) {\n e.stopPropagation();\n e.preventDefault();\n return;\n }\n onClick(e);\n };\n\n return (\n <Tooltip {...tooltip} title={tooltip?.title}>\n <div\n id={id}\n className={cn(\n className,\n 'ald-icon-button',\n `ald-icon-button-${getSizeType(size)}`,\n {\n 'ald-icon-button-disabled': disabled,\n 'ald-icon-button-focus': keepFocus,\n 'ald-icon-button-dark': mode === 'dark',\n },\n )}\n ref={ref}\n onClick={onButtonClick}\n // disabled={disabled}\n >\n <div className=\"ald-icon-button-wrap\">{icon}</div>\n </div>\n </Tooltip>\n );\n});\n\nconst DropdownButton = forwardRef(function (\n props: IDropdownIconButtonProps,\n ref: React.Ref<HTMLDivElement>,\n) {\n const {\n icon,\n onClick = () => {},\n disabled,\n size = 'middle',\n menu,\n className,\n onOpenChange,\n tooltip,\n id,\n showArrow,\n mode = 'light',\n ...restDropdownProps\n } = props;\n const onButtonClick = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {\n if (disabled) {\n e.stopPropagation();\n e.preventDefault();\n return;\n }\n onClick(e);\n };\n\n const canDropdown = useMemo(() => {\n const hasMenu = menu && menu.items && menu.items.length > 0;\n return hasMenu && !disabled;\n }, [menu, disabled]);\n if (!canDropdown) {\n return (\n <Tooltip {...tooltip} title={tooltip?.title}>\n <div\n id={id}\n className={cn(\n className,\n 'ald-icon-button-dropdown',\n `ald-icon-button-${getSizeType(size)}`,\n {\n 'ald-icon-button-disabled': disabled,\n 'ald-icon-button-dark': mode === 'dark',\n },\n )}\n ref={ref}\n onClick={onButtonClick}\n >\n <div className=\"ald-icon-button-wrap\">{icon}</div>\n {showArrow && <FoldDownFill />}\n </div>\n </Tooltip>\n );\n }\n return (\n <Tooltip {...tooltip} title={tooltip?.title}>\n <Dropdown menu={menu} onOpenChange={onOpenChange} {...restDropdownProps}>\n <div\n id={id}\n className={cn(\n className,\n 'ald-icon-button-dropdown',\n `ald-icon-button-${getSizeType(size)}`,\n {\n 'ald-icon-button-disabled': disabled,\n 'ald-icon-button-dark': mode === 'dark',\n },\n )}\n ref={ref}\n onClick={onButtonClick}\n >\n <div className=\"ald-icon-button-wrap\">{icon}</div>\n {showArrow && <FoldDownFill />}\n </div>\n </Dropdown>\n </Tooltip>\n );\n});\nconst IconButton = InternalIconButton as typeof InternalIconButton & {\n dropdown: typeof DropdownButton;\n __ANT_BUTTON: boolean;\n};\nIconButton.dropdown = DropdownButton;\nIconButton.__ANT_BUTTON = true;\nexport default IconButton;\n"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/IconButton/index.tsx"],"sourcesContent":["import './icon-button.css';\nimport { cn } from '../lib/utils';\nimport React, { forwardRef, useMemo } from 'react';\nimport Dropdown, { IDropdownProps } from '../Dropdown/index';\nimport { FoldDownFill } from '../Icon';\nimport { TSize } from '../Input';\nimport { getSizeType } from '../Input/components/Input';\nimport Tooltip, { ITooltipProps } from '../Tooltip';\ninterface IIconButtonProps {\n icon: React.ReactNode;\n onClick?: (e: React.MouseEvent) => void;\n disabled?: boolean;\n size?: TSize;\n className?: string;\n keepFocus?: boolean;\n tooltip?: ITooltipProps;\n id?: string;\n mode?: 'light' | 'dark';\n /** 透传到底层触发器 DOM 的 data-testid,用于自动化测试定位 */\n 'data-testid'?: string;\n /** 透传到底层触发器 DOM 的 aria-label,用于可访问性与自动化测试定位 */\n 'aria-label'?: string;\n}\ntype IDropdownIconButtonProps = IIconButtonProps &\n Omit<IDropdownProps, 'children'> & {\n showArrow?: boolean;\n };\nconst InternalIconButton = forwardRef(function (\n props: IIconButtonProps,\n ref: React.Ref<HTMLDivElement>,\n) {\n const {\n icon,\n onClick = () => {},\n disabled,\n size = 'middle',\n keepFocus,\n className,\n tooltip,\n id,\n mode = 'light',\n 'data-testid': dataTestid,\n 'aria-label': ariaLabel,\n } = props;\n const onButtonClick = (e: React.MouseEvent) => {\n if (disabled) {\n e.stopPropagation();\n e.preventDefault();\n return;\n }\n onClick(e);\n };\n\n return (\n <Tooltip {...tooltip} title={tooltip?.title}>\n <div\n id={id}\n className={cn(\n className,\n 'ald-icon-button',\n `ald-icon-button-${getSizeType(size)}`,\n {\n 'ald-icon-button-disabled': disabled,\n 'ald-icon-button-focus': keepFocus,\n 'ald-icon-button-dark': mode === 'dark',\n },\n )}\n ref={ref}\n onClick={onButtonClick}\n data-testid={dataTestid}\n aria-label={ariaLabel}\n // disabled={disabled}\n >\n <div className=\"ald-icon-button-wrap\">{icon}</div>\n </div>\n </Tooltip>\n );\n});\n\nconst DropdownButton = forwardRef(function (\n props: IDropdownIconButtonProps,\n ref: React.Ref<HTMLDivElement>,\n) {\n const {\n icon,\n onClick = () => {},\n disabled,\n size = 'middle',\n menu,\n className,\n onOpenChange,\n tooltip,\n id,\n showArrow,\n mode = 'light',\n 'data-testid': dataTestid,\n 'aria-label': ariaLabel,\n ...restDropdownProps\n } = props;\n const onButtonClick = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {\n if (disabled) {\n e.stopPropagation();\n e.preventDefault();\n return;\n }\n onClick(e);\n };\n\n const canDropdown = useMemo(() => {\n const hasMenu = menu && menu.items && menu.items.length > 0;\n return hasMenu && !disabled;\n }, [menu, disabled]);\n if (!canDropdown) {\n return (\n <Tooltip {...tooltip} title={tooltip?.title}>\n <div\n id={id}\n className={cn(\n className,\n 'ald-icon-button-dropdown',\n `ald-icon-button-${getSizeType(size)}`,\n {\n 'ald-icon-button-disabled': disabled,\n 'ald-icon-button-dark': mode === 'dark',\n },\n )}\n ref={ref}\n onClick={onButtonClick}\n data-testid={dataTestid}\n aria-label={ariaLabel}\n >\n <div className=\"ald-icon-button-wrap\">{icon}</div>\n {showArrow && <FoldDownFill />}\n </div>\n </Tooltip>\n );\n }\n return (\n <Tooltip {...tooltip} title={tooltip?.title}>\n <Dropdown menu={menu} onOpenChange={onOpenChange} {...restDropdownProps}>\n <div\n id={id}\n className={cn(\n className,\n 'ald-icon-button-dropdown',\n `ald-icon-button-${getSizeType(size)}`,\n {\n 'ald-icon-button-disabled': disabled,\n 'ald-icon-button-dark': mode === 'dark',\n },\n )}\n ref={ref}\n onClick={onButtonClick}\n data-testid={dataTestid}\n aria-label={ariaLabel}\n >\n <div className=\"ald-icon-button-wrap\">{icon}</div>\n {showArrow && <FoldDownFill />}\n </div>\n </Dropdown>\n </Tooltip>\n );\n});\nconst IconButton = InternalIconButton as typeof InternalIconButton & {\n dropdown: typeof DropdownButton;\n __ANT_BUTTON: boolean;\n};\nIconButton.dropdown = DropdownButton;\nIconButton.__ANT_BUTTON = true;\nexport default IconButton;\n"],"mappings":";;;;;;;;;AA2BA,IAAM,qBAAqB,WAAW,SACpC,OACA,KACA;CACA,MAAM,EACJ,MACA,gBAAgB,IAChB,UACA,OAAO,UACP,WACA,WACA,SACA,IACA,OAAO,SACP,eAAe,YACf,cAAc,cACZ;CACJ,MAAM,iBAAiB,MAAwB;AAC7C,MAAI,UAAU;AACZ,KAAE,iBAAiB;AACnB,KAAE,gBAAgB;AAClB;;AAEF,UAAQ,EAAE;;AAGZ,QACE,oBAAC,SAAD;EAAS,GAAI;EAAS,OAAO,SAAS;YACpC,oBAAC,OAAD;GACM;GACJ,WAAW,GACT,WACA,mBACA,mBAAmB,YAAY,KAAK,IACpC;IACE,4BAA4B;IAC5B,yBAAyB;IACzB,wBAAwB,SAAS;IAClC,CACF;GACI;GACL,SAAS;GACT,eAAa;GACb,cAAY;aAGZ,oBAAC,OAAD;IAAK,WAAU;cAAwB;IAAW,CAAA;GAC9C,CAAA;EACE,CAAA;EAEZ;AAEF,IAAM,iBAAiB,WAAW,SAChC,OACA,KACA;CACA,MAAM,EACJ,MACA,gBAAgB,IAChB,UACA,OAAO,UACP,MACA,WACA,cACA,SACA,IACA,WACA,OAAO,SACP,eAAe,YACf,cAAc,WACd,GAAG,sBACD;CACJ,MAAM,iBAAiB,MAAoD;AACzE,MAAI,UAAU;AACZ,KAAE,iBAAiB;AACnB,KAAE,gBAAgB;AAClB;;AAEF,UAAQ,EAAE;;AAOZ,KAAI,CAJgB,cAAc;AAEhC,SADgB,QAAQ,KAAK,SAAS,KAAK,MAAM,SAAS,KACxC,CAAC;IAClB,CAAC,MAAM,SAAS,CAAC,CAElB,QACE,oBAAC,SAAD;EAAS,GAAI;EAAS,OAAO,SAAS;YACpC,qBAAC,OAAD;GACM;GACJ,WAAW,GACT,WACA,4BACA,mBAAmB,YAAY,KAAK,IACpC;IACE,4BAA4B;IAC5B,wBAAwB,SAAS;IAClC,CACF;GACI;GACL,SAAS;GACT,eAAa;GACb,cAAY;aAdd,CAgBE,oBAAC,OAAD;IAAK,WAAU;cAAwB;IAAW,CAAA,EACjD,aAAa,oBAAC,MAAD,EAAgB,CAAA,CAC1B;;EACE,CAAA;AAGd,QACE,oBAAC,SAAD;EAAS,GAAI;EAAS,OAAO,SAAS;YACpC,oBAAC,UAAD;GAAgB;GAAoB;GAAc,GAAI;aACpD,qBAAC,OAAD;IACM;IACJ,WAAW,GACT,WACA,4BACA,mBAAmB,YAAY,KAAK,IACpC;KACE,4BAA4B;KAC5B,wBAAwB,SAAS;KAClC,CACF;IACI;IACL,SAAS;IACT,eAAa;IACb,cAAY;cAdd,CAgBE,oBAAC,OAAD;KAAK,WAAU;eAAwB;KAAW,CAAA,EACjD,aAAa,oBAAC,MAAD,EAAgB,CAAA,CAC1B;;GACG,CAAA;EACH,CAAA;EAEZ;AACF,IAAM,aAAa;AAInB,WAAW,WAAW;AACtB,WAAW,eAAe"}
|
|
@@ -44,6 +44,10 @@ export interface IInputProps {
|
|
|
44
44
|
onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;
|
|
45
45
|
onCompositionStart?: React.CompositionEventHandler<HTMLInputElement>;
|
|
46
46
|
onCompositionEnd?: React.CompositionEventHandler<HTMLInputElement>;
|
|
47
|
+
/** 透传到内部 input 元素的 data-testid,用于自动化测试定位 */
|
|
48
|
+
'data-testid'?: string;
|
|
49
|
+
/** 透传到内部 input 元素的 aria-label,用于可访问性与自动化测试定位 */
|
|
50
|
+
'aria-label'?: string;
|
|
47
51
|
}
|
|
48
52
|
export declare function getSizeType(sizeType: TSize): TSize;
|
|
49
53
|
declare const Input: React.ForwardRefExoticComponent<IInputProps & React.RefAttributes<InputRef>>;
|
|
@@ -15,7 +15,7 @@ function getSizeType(sizeType) {
|
|
|
15
15
|
return "middle";
|
|
16
16
|
}
|
|
17
17
|
var Input = forwardRef((props, ref) => {
|
|
18
|
-
const { size: customSize, className, bordered = true, status, disabled, allowClear, prefix, suffix, addonBefore, addonAfter, showCount, maxLength, value: controlledValue, defaultValue, onChange, onPressEnter, onBlur, onFocus, onKeyDown, onCompositionStart, onCompositionEnd, placeholder, type, id, autoFocus, readOnly, style } = props;
|
|
18
|
+
const { size: customSize, className, bordered = true, status, disabled, allowClear, prefix, suffix, addonBefore, addonAfter, showCount, maxLength, minLength, value: controlledValue, defaultValue, onChange, onPressEnter, onBlur, onFocus, onKeyDown, onCompositionStart, onCompositionEnd, placeholder, type, id, autoComplete = "off", autoFocus, readOnly, width, style, "data-testid": dataTestid, "aria-label": ariaLabel } = props;
|
|
19
19
|
const contextDisabled = useContext(DisabledContext);
|
|
20
20
|
const mergedDisabled = disabled ?? contextDisabled;
|
|
21
21
|
const contentSize = useContext(SizeContext);
|
|
@@ -56,7 +56,10 @@ var Input = forwardRef((props, ref) => {
|
|
|
56
56
|
const compactClasses = compactItemClassnames ? cn(!compactItemClassnames["ald-input-compact-first-item"] && "!tw-rounded-l-none", !compactItemClassnames["ald-input-compact-last-item"] && "!tw-rounded-r-none", !compactItemClassnames["ald-input-compact-first-item"] && "-tw-ml-px") : void 0;
|
|
57
57
|
return /* @__PURE__ */ jsxs("span", {
|
|
58
58
|
className: cn("ald-input ant-input-affix-wrapper tw-inline-flex tw-w-full tw-items-center tw-bg-[var(--interaction-background-form-field)]", bordered && "tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--interaction-border-neutral-normal)]", focused && "ant-input-affix-wrapper-focused tw-border-[var(--interaction-focus-default)]", !mergedDisabled && !focused && "hover:tw-border-[var(--interaction-border-hover)]", `ald-input-${getSizeType(size)}`, size === "small" && "tw-h-7 tw-text-xs", size === "large" && "tw-h-9 tw-text-sm", (size === "middle" || !size) && "tw-h-8 tw-text-sm", status === "error" && `ald-input-error tw-border-[var(--border-negative-strong)]`, status === "warning" && `ald-input-warning tw-border-[var(--border-warning-subtle)]`, mergedDisabled && "ald-input-disabled tw-cursor-not-allowed tw-bg-[var(--global-cool-gray-alpha-50)] tw-text-[var(--content-secondary)]", compactClasses, className),
|
|
59
|
-
style
|
|
59
|
+
style: {
|
|
60
|
+
...style,
|
|
61
|
+
width
|
|
62
|
+
},
|
|
60
63
|
onMouseDown: (e) => {
|
|
61
64
|
if (e.target !== inputRef.current) {
|
|
62
65
|
if (document.activeElement === inputRef.current) e.preventDefault();
|
|
@@ -95,10 +98,13 @@ var Input = forwardRef((props, ref) => {
|
|
|
95
98
|
disabled: mergedDisabled,
|
|
96
99
|
placeholder,
|
|
97
100
|
maxLength,
|
|
98
|
-
|
|
101
|
+
minLength,
|
|
102
|
+
autoComplete,
|
|
99
103
|
autoFocus,
|
|
100
104
|
readOnly,
|
|
101
|
-
spellCheck: false
|
|
105
|
+
spellCheck: false,
|
|
106
|
+
"data-testid": dataTestid,
|
|
107
|
+
"aria-label": ariaLabel
|
|
102
108
|
}),
|
|
103
109
|
showClearIcon && /* @__PURE__ */ jsx("span", {
|
|
104
110
|
className: "ald-input-clear ant-input-clear-icon tw-flex tw-cursor-pointer tw-items-center tw-pr-1",
|