@aloudata/aloudata-design 3.0.0-beta.5 → 3.0.0-beta.6
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/Button/index.d.ts +2 -0
- package/dist/Button/index.js.map +1 -1
- package/dist/Checkbox/type.d.ts +1 -0
- package/dist/Drawer/index.d.ts +1 -0
- package/dist/Drawer/index.js.map +1 -1
- package/dist/Form/index.d.ts +3 -0
- package/dist/Form/index.js.map +1 -1
- package/dist/Input/components/Input/index.d.ts +3 -0
- package/dist/Input/components/Input/index.js.map +1 -1
- package/dist/Input/components/TextArea/index.d.ts +4 -0
- package/dist/Input/components/TextArea/index.js.map +1 -1
- package/dist/InputNumber/type.d.ts +1 -0
- package/dist/Popover/index.d.ts +1 -0
- package/dist/Popover/index.js.map +1 -1
- package/dist/Tabs/index.d.ts +1 -0
- package/dist/Tabs/index.js.map +1 -1
- package/dist/Upload/index.d.ts +1 -1
- package/dist/Upload/index.js.map +1 -1
- package/package.json +1 -1
package/dist/Button/index.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ export interface IButtonProps {
|
|
|
23
23
|
tabIndex?: number;
|
|
24
24
|
title?: string;
|
|
25
25
|
ghost?: boolean;
|
|
26
|
+
danger?: boolean;
|
|
27
|
+
color?: string;
|
|
26
28
|
}
|
|
27
29
|
export declare function getButtonType(buttonType: ButtonType): string;
|
|
28
30
|
export declare function getDangerStatus(buttonType: ButtonType): boolean;
|
package/dist/Button/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Button/index.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority';\nimport React, { forwardRef, useContext, useEffect, useState } from 'react';\nimport DisabledContext from '../ConfigProvider/DisabledContext';\nimport SizeContext from '../ConfigProvider/sizeContext';\nimport { LoadingLine } from '../Icon';\nimport { cn } from '../lib/utils';\nimport { useCompactItemContext } from '../Space/CompactContext';\n\nexport const btnPrefix = 'ald-btn';\n\nexport type ButtonType =\n | 'primary'\n | 'secondary'\n | 'dangerous'\n | 'text'\n | 'inverse'\n | 'link';\nexport type Size = 'small' | 'middle' | 'large';\nexport interface IButtonProps {\n type?: ButtonType;\n size?: Size;\n disabled?: boolean;\n icon?: React.ReactNode;\n shape?: 'circle' | 'default';\n href?: string;\n target?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n loading?: boolean | { delay?: number };\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n block?: boolean;\n htmlType?: 'submit' | 'button' | 'reset';\n id?: string;\n tabIndex?: number;\n title?: string;\n ghost?: boolean;\n}\n\nexport function getButtonType(buttonType: ButtonType): string {\n return buttonType;\n}\nexport function getDangerStatus(buttonType: ButtonType): boolean {\n return buttonType === 'dangerous';\n}\nexport function getButtonSizeClass(s: Size): string {\n return ['small', 'large'].includes(s)\n ? `${btnPrefix}-${s}`\n : `${btnPrefix}-middle`;\n}\nexport function getShape(s: 'circle' | 'default'): 'circle' | 'default' {\n return s;\n}\nexport const setIcon = (\n iconNode: React.ReactElement,\n loading: boolean | { delay?: number },\n) => {\n if (iconNode) {\n const p: Record<string, string | number> = {\n className: '',\n fill: 'currentColor',\n ...iconNode.props,\n };\n p.size = '1em';\n return React.cloneElement(iconNode, p);\n }\n if (loading) {\n return (\n <LoadingLine\n className=\"ald-loading-spin tw-shrink-0 tw-animate-spin\"\n size={'1em'}\n color=\"currentColor\"\n />\n );\n }\n return <></>;\n};\n\nconst buttonVariants = cva(\n [\n btnPrefix,\n 'tw-inline-flex tw-cursor-pointer tw-appearance-none tw-items-center tw-justify-center tw-font-medium tw-no-underline tw-transition-colors [&_.i-icon]:tw-inline-flex [&_.i-icon]:tw-items-center',\n 'tw-border tw-border-solid',\n 'focus-visible:tw-outline-none',\n ],\n {\n variants: {\n type: {\n primary: [\n `${btnPrefix}-primary`,\n 'tw-border-[var(--action-primary-normal)] tw-bg-[var(--action-primary-normal)] tw-text-[var(--action-inverted-normal)]',\n 'hover:tw-border-[var(--action-primary-hover)] hover:tw-bg-[var(--action-primary-hover)] hover:tw-text-[var(--action-inverted-hover)]',\n 'active:tw-border-[var(--action-primary-active)] active:tw-bg-[var(--action-primary-active)]',\n ],\n secondary: [\n `${btnPrefix}-secondary`,\n 'tw-border-[var(--action-outline-normal)] tw-bg-[var(--action-inverted-normal)] tw-text-[var(--action-neutral-normal)]',\n 'hover:tw-border-[var(--action-outline-hover)] hover:tw-bg-[var(--action-inverted-hover)] hover:tw-text-[var(--action-neutral-hover)]',\n 'active:tw-border-[var(--action-outline-active)] active:tw-bg-[var(--action-inverted-active)] active:tw-text-[var(--action-neutral-active)]',\n ],\n dangerous: [\n `${btnPrefix}-dangerous`,\n 'tw-border-[var(--action-destructive-normal)] tw-bg-[var(--action-destructive-normal)] tw-text-[var(--action-inverted-normal)]',\n 'hover:tw-border-[var(--action-destructive-hover)] hover:tw-bg-[var(--action-destructive-hover)]',\n 'active:tw-border-[var(--action-destructive-active)] active:tw-bg-[var(--action-destructive-active)]',\n ],\n text: [\n `${btnPrefix}-text`,\n 'tw-border-transparent tw-bg-[var(--action-ghost-normal)] tw-text-[var(--action-neutral-normal)]',\n 'hover:tw-bg-[var(--action-ghost-hover)] hover:tw-text-[var(--action-neutral-hover)]',\n 'active:tw-bg-[var(--action-ghost-active)] active:tw-text-[var(--action-neutral-active)]',\n ],\n inverse: [\n `${btnPrefix}-inverse`,\n 'tw-border-transparent tw-bg-[var(--alias-colors-bg-skeleton-inverse-subtle)] tw-text-[var(--alias-colors-text-inverse-default)]',\n 'hover:tw-bg-[var(--alias-colors-bg-skeleton-inverse-strong)]',\n 'active:tw-bg-[var(--alias-colors-bg-skeleton-inverse-stronger)]',\n ],\n link: [\n `${btnPrefix}-link`,\n 'tw-border-transparent tw-bg-transparent tw-text-[var(--action-primary-normal)]',\n 'hover:tw-text-[var(--action-primary-hover)]',\n 'active:tw-text-[var(--action-primary-active)]',\n ],\n },\n size: {\n small: [\n `${btnPrefix}-small`,\n 'tw-h-7 tw-min-w-[48px] tw-gap-[var(--alias-radius-50)] tw-rounded-r-50 tw-text-xs tw-leading-4',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n middle: [\n `${btnPrefix}-middle`,\n 'tw-h-8 tw-min-w-[52px] tw-gap-1 tw-rounded-r-75 tw-text-sm tw-leading-5',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n large: [\n `${btnPrefix}-large`,\n 'tw-h-9 tw-min-w-[56px] tw-gap-2 tw-rounded-r-100 tw-text-sm tw-leading-6',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n },\n disabled: {\n true: 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n false: '',\n },\n block: {\n true: 'tw-w-full',\n false: '',\n },\n shape: {\n circle: 'tw-min-w-0 tw-rounded-full tw-p-0',\n default: '',\n },\n },\n defaultVariants: {\n type: 'secondary',\n size: 'middle',\n disabled: false,\n block: false,\n shape: 'default',\n },\n },\n);\n\nconst VALID_TYPES: ButtonType[] = [\n 'primary',\n 'secondary',\n 'dangerous',\n 'text',\n 'inverse',\n];\n\nfunction Button(props: IButtonProps, ref: React.Ref<HTMLElement>) {\n const {\n type: rawType = 'secondary',\n size: customSize,\n shape = 'default',\n loading = false,\n disabled,\n icon,\n className,\n children,\n href,\n target,\n onClick,\n block,\n htmlType = 'button',\n style,\n ghost,\n ...rest\n } = props;\n\n // Radix Trigger asChild 会传入 type=\"button\"(HTML button type),与组件的 type 变体冲突\n // 当收到非法变体值时回退到 'secondary'\n const type: ButtonType = VALID_TYPES.includes(rawType as ButtonType)\n ? (rawType as ButtonType)\n : 'secondary';\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const { compactSize, compactItemClassnames } =\n useCompactItemContext(btnPrefix);\n const size = customSize || compactSize || contentSize || 'middle';\n\n const [innerLoading, setInnerLoading] = useState(false);\n\n useEffect(() => {\n if (typeof loading === 'object' && loading.delay) {\n const timer = setTimeout(() => setInnerLoading(true), loading.delay);\n return () => clearTimeout(timer);\n }\n setInnerLoading(!!loading);\n }, [loading]);\n\n const isDisabled = innerLoading || mergedDisabled;\n const iconNode = setIcon(icon as React.ReactElement, innerLoading);\n\n // Build compact-mode border-radius and margin overrides\n const compactClasses = compactItemClassnames\n ? cn(\n // all compact items: remove border-radius on inner edges\n !compactItemClassnames[`${btnPrefix}-compact-first-item`] &&\n '!tw-rounded-l-none',\n !compactItemClassnames[`${btnPrefix}-compact-last-item`] &&\n '!tw-rounded-r-none',\n // merge borders via negative margin (except first item)\n !compactItemClassnames[`${btnPrefix}-compact-first-item`] &&\n '-tw-ml-px',\n )\n : undefined;\n\n const isIconOnly = !!icon && !children;\n\n const classes = cn(\n buttonVariants({\n type,\n size,\n disabled: !!isDisabled,\n block: !!block,\n shape,\n }),\n ghost && '!tw-border-current !tw-bg-transparent',\n // icon-only: square button, no min-width, centered padding\n isIconOnly && 'tw-aspect-square !tw-min-w-0 !tw-px-0',\n compactClasses,\n className,\n );\n\n if (href) {\n return (\n <a\n {...rest}\n className={classes}\n style={style}\n href={isDisabled ? undefined : href}\n target={target}\n ref={ref as React.Ref<HTMLAnchorElement>}\n onClick={isDisabled ? undefined : onClick}\n aria-disabled={isDisabled || undefined}\n >\n {iconNode}\n {children && (\n <span className=\"tw-inline-flex tw-items-center tw-gap-1\">\n {children}\n </span>\n )}\n </a>\n );\n }\n\n return (\n <button\n {...rest}\n type={\n htmlType === 'submit'\n ? 'submit'\n : htmlType === 'reset'\n ? 'reset'\n : 'button'\n }\n className={classes}\n style={style}\n disabled={isDisabled}\n aria-disabled={isDisabled || undefined}\n ref={ref as React.Ref<HTMLButtonElement>}\n onClick={onClick}\n >\n {iconNode}\n {children && (\n <span className=\"tw-inline-flex tw-items-center tw-gap-1\">\n {children}\n </span>\n )}\n </button>\n );\n}\n\nexport default forwardRef(Button);\n"],"mappings":";;;;;;;;;AAQA,IAAa,YAAY;AA6CzB,IAAa,WACX,UACA,YACG;AACH,KAAI,UAAU;EACZ,MAAM,IAAqC;GACzC,WAAW;GACX,MAAM;GACN,GAAG,SAAS;GACb;AACD,IAAE,OAAO;AACT,SAAO,MAAM,aAAa,UAAU,EAAE;;AAExC,KAAI,QACF,QACE,oBAAC,MAAD;EACE,WAAU;EACV,MAAM;EACN,OAAM;EACN,CAAA;AAGN,QAAO,oBAAA,UAAA,EAAK,CAAA;;AAGd,IAAM,iBAAiB,IACrB;CACE;CACA;CACA;CACA;CACD,EACD;CACE,UAAU;EACR,MAAM;GACJ,SAAS;IACP,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,WAAW;IACT,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,WAAW;IACT,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,MAAM;IACJ,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,SAAS;IACP,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,MAAM;IACJ,GAAG,UAAU;IACb;IACA;IACA;IACD;GACF;EACD,MAAM;GACJ,OAAO;IACL,GAAG,UAAU;IACb;IACA;IACD;GACD,QAAQ;IACN,GAAG,UAAU;IACb;IACA;IACD;GACD,OAAO;IACL,GAAG,UAAU;IACb;IACA;IACD;GACF;EACD,UAAU;GACR,MAAM;GACN,OAAO;GACR;EACD,OAAO;GACL,MAAM;GACN,OAAO;GACR;EACD,OAAO;GACL,QAAQ;GACR,SAAS;GACV;EACF;CACD,iBAAiB;EACf,MAAM;EACN,MAAM;EACN,UAAU;EACV,OAAO;EACP,OAAO;EACR;CACF,CACF;AAED,IAAM,cAA4B;CAChC;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,OAAO,OAAqB,KAA6B;CAChE,MAAM,EACJ,MAAM,UAAU,aAChB,MAAM,YACN,QAAQ,WACR,UAAU,OACV,UACA,MACA,WACA,UACA,MACA,QACA,SACA,OACA,WAAW,UACX,OACA,OACA,GAAG,SACD;CAIJ,MAAM,OAAmB,YAAY,SAAS,QAAsB,GAC/D,UACD;CAEJ,MAAM,kBAAkB,WAAW,gBAAgB;CACnD,MAAM,iBAAiB,YAAY;CAEnC,MAAM,cAAc,WAAW,YAAY;CAC3C,MAAM,EAAE,aAAa,0BACnB,sBAAsB,UAAU;CAClC,MAAM,OAAO,cAAc,eAAe,eAAe;CAEzD,MAAM,CAAC,cAAc,mBAAmB,SAAS,MAAM;AAEvD,iBAAgB;AACd,MAAI,OAAO,YAAY,YAAY,QAAQ,OAAO;GAChD,MAAM,QAAQ,iBAAiB,gBAAgB,KAAK,EAAE,QAAQ,MAAM;AACpE,gBAAa,aAAa,MAAM;;AAElC,kBAAgB,CAAC,CAAC,QAAQ;IACzB,CAAC,QAAQ,CAAC;CAEb,MAAM,aAAa,gBAAgB;CACnC,MAAM,WAAW,QAAQ,MAA4B,aAAa;CAGlE,MAAM,iBAAiB,wBACnB,GAEE,CAAC,sBAAsB,iCACrB,sBACF,CAAC,sBAAsB,gCACrB,sBAEF,CAAC,sBAAsB,iCACrB,YACH,GACD;CAEJ,MAAM,aAAa,CAAC,CAAC,QAAQ,CAAC;CAE9B,MAAM,UAAU,GACd,eAAe;EACb;EACA;EACA,UAAU,CAAC,CAAC;EACZ,OAAO,CAAC,CAAC;EACT;EACD,CAAC,EACF,SAAS,yCAET,cAAc,yCACd,gBACA,UACD;AAED,KAAI,KACF,QACE,qBAAC,KAAD;EACE,GAAI;EACJ,WAAW;EACJ;EACP,MAAM,aAAa,SAAY;EACvB;EACH;EACL,SAAS,aAAa,SAAY;EAClC,iBAAe,cAAc;YAR/B,CAUG,UACA,YACC,oBAAC,QAAD;GAAM,WAAU;GACb;GACI,CAAA,CAEP;;AAIR,QACE,qBAAC,UAAD;EACE,GAAI;EACJ,MACE,aAAa,WACT,WACA,aAAa,UACb,UACA;EAEN,WAAW;EACJ;EACP,UAAU;EACV,iBAAe,cAAc;EACxB;EACI;YAdX,CAgBG,UACA,YACC,oBAAC,QAAD;GAAM,WAAU;GACb;GACI,CAAA,CAEF;;;AAIb,IAAA,iBAAe,WAAW,OAAO"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Button/index.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority';\nimport React, { forwardRef, useContext, useEffect, useState } from 'react';\nimport DisabledContext from '../ConfigProvider/DisabledContext';\nimport SizeContext from '../ConfigProvider/sizeContext';\nimport { LoadingLine } from '../Icon';\nimport { cn } from '../lib/utils';\nimport { useCompactItemContext } from '../Space/CompactContext';\n\nexport const btnPrefix = 'ald-btn';\n\nexport type ButtonType =\n | 'primary'\n | 'secondary'\n | 'dangerous'\n | 'text'\n | 'inverse'\n | 'link';\nexport type Size = 'small' | 'middle' | 'large';\nexport interface IButtonProps {\n type?: ButtonType;\n size?: Size;\n disabled?: boolean;\n icon?: React.ReactNode;\n shape?: 'circle' | 'default';\n href?: string;\n target?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n loading?: boolean | { delay?: number };\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n block?: boolean;\n htmlType?: 'submit' | 'button' | 'reset';\n id?: string;\n tabIndex?: number;\n title?: string;\n ghost?: boolean;\n danger?: boolean;\n color?: string;\n}\n\nexport function getButtonType(buttonType: ButtonType): string {\n return buttonType;\n}\nexport function getDangerStatus(buttonType: ButtonType): boolean {\n return buttonType === 'dangerous';\n}\nexport function getButtonSizeClass(s: Size): string {\n return ['small', 'large'].includes(s)\n ? `${btnPrefix}-${s}`\n : `${btnPrefix}-middle`;\n}\nexport function getShape(s: 'circle' | 'default'): 'circle' | 'default' {\n return s;\n}\nexport const setIcon = (\n iconNode: React.ReactElement,\n loading: boolean | { delay?: number },\n) => {\n if (iconNode) {\n const p: Record<string, string | number> = {\n className: '',\n fill: 'currentColor',\n ...iconNode.props,\n };\n p.size = '1em';\n return React.cloneElement(iconNode, p);\n }\n if (loading) {\n return (\n <LoadingLine\n className=\"ald-loading-spin tw-shrink-0 tw-animate-spin\"\n size={'1em'}\n color=\"currentColor\"\n />\n );\n }\n return <></>;\n};\n\nconst buttonVariants = cva(\n [\n btnPrefix,\n 'tw-inline-flex tw-cursor-pointer tw-appearance-none tw-items-center tw-justify-center tw-font-medium tw-no-underline tw-transition-colors [&_.i-icon]:tw-inline-flex [&_.i-icon]:tw-items-center',\n 'tw-border tw-border-solid',\n 'focus-visible:tw-outline-none',\n ],\n {\n variants: {\n type: {\n primary: [\n `${btnPrefix}-primary`,\n 'tw-border-[var(--action-primary-normal)] tw-bg-[var(--action-primary-normal)] tw-text-[var(--action-inverted-normal)]',\n 'hover:tw-border-[var(--action-primary-hover)] hover:tw-bg-[var(--action-primary-hover)] hover:tw-text-[var(--action-inverted-hover)]',\n 'active:tw-border-[var(--action-primary-active)] active:tw-bg-[var(--action-primary-active)]',\n ],\n secondary: [\n `${btnPrefix}-secondary`,\n 'tw-border-[var(--action-outline-normal)] tw-bg-[var(--action-inverted-normal)] tw-text-[var(--action-neutral-normal)]',\n 'hover:tw-border-[var(--action-outline-hover)] hover:tw-bg-[var(--action-inverted-hover)] hover:tw-text-[var(--action-neutral-hover)]',\n 'active:tw-border-[var(--action-outline-active)] active:tw-bg-[var(--action-inverted-active)] active:tw-text-[var(--action-neutral-active)]',\n ],\n dangerous: [\n `${btnPrefix}-dangerous`,\n 'tw-border-[var(--action-destructive-normal)] tw-bg-[var(--action-destructive-normal)] tw-text-[var(--action-inverted-normal)]',\n 'hover:tw-border-[var(--action-destructive-hover)] hover:tw-bg-[var(--action-destructive-hover)]',\n 'active:tw-border-[var(--action-destructive-active)] active:tw-bg-[var(--action-destructive-active)]',\n ],\n text: [\n `${btnPrefix}-text`,\n 'tw-border-transparent tw-bg-[var(--action-ghost-normal)] tw-text-[var(--action-neutral-normal)]',\n 'hover:tw-bg-[var(--action-ghost-hover)] hover:tw-text-[var(--action-neutral-hover)]',\n 'active:tw-bg-[var(--action-ghost-active)] active:tw-text-[var(--action-neutral-active)]',\n ],\n inverse: [\n `${btnPrefix}-inverse`,\n 'tw-border-transparent tw-bg-[var(--alias-colors-bg-skeleton-inverse-subtle)] tw-text-[var(--alias-colors-text-inverse-default)]',\n 'hover:tw-bg-[var(--alias-colors-bg-skeleton-inverse-strong)]',\n 'active:tw-bg-[var(--alias-colors-bg-skeleton-inverse-stronger)]',\n ],\n link: [\n `${btnPrefix}-link`,\n 'tw-border-transparent tw-bg-transparent tw-text-[var(--action-primary-normal)]',\n 'hover:tw-text-[var(--action-primary-hover)]',\n 'active:tw-text-[var(--action-primary-active)]',\n ],\n },\n size: {\n small: [\n `${btnPrefix}-small`,\n 'tw-h-7 tw-min-w-[48px] tw-gap-[var(--alias-radius-50)] tw-rounded-r-50 tw-text-xs tw-leading-4',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n middle: [\n `${btnPrefix}-middle`,\n 'tw-h-8 tw-min-w-[52px] tw-gap-1 tw-rounded-r-75 tw-text-sm tw-leading-5',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n large: [\n `${btnPrefix}-large`,\n 'tw-h-9 tw-min-w-[56px] tw-gap-2 tw-rounded-r-100 tw-text-sm tw-leading-6',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n },\n disabled: {\n true: 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n false: '',\n },\n block: {\n true: 'tw-w-full',\n false: '',\n },\n shape: {\n circle: 'tw-min-w-0 tw-rounded-full tw-p-0',\n default: '',\n },\n },\n defaultVariants: {\n type: 'secondary',\n size: 'middle',\n disabled: false,\n block: false,\n shape: 'default',\n },\n },\n);\n\nconst VALID_TYPES: ButtonType[] = [\n 'primary',\n 'secondary',\n 'dangerous',\n 'text',\n 'inverse',\n];\n\nfunction Button(props: IButtonProps, ref: React.Ref<HTMLElement>) {\n const {\n type: rawType = 'secondary',\n size: customSize,\n shape = 'default',\n loading = false,\n disabled,\n icon,\n className,\n children,\n href,\n target,\n onClick,\n block,\n htmlType = 'button',\n style,\n ghost,\n ...rest\n } = props;\n\n // Radix Trigger asChild 会传入 type=\"button\"(HTML button type),与组件的 type 变体冲突\n // 当收到非法变体值时回退到 'secondary'\n const type: ButtonType = VALID_TYPES.includes(rawType as ButtonType)\n ? (rawType as ButtonType)\n : 'secondary';\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const { compactSize, compactItemClassnames } =\n useCompactItemContext(btnPrefix);\n const size = customSize || compactSize || contentSize || 'middle';\n\n const [innerLoading, setInnerLoading] = useState(false);\n\n useEffect(() => {\n if (typeof loading === 'object' && loading.delay) {\n const timer = setTimeout(() => setInnerLoading(true), loading.delay);\n return () => clearTimeout(timer);\n }\n setInnerLoading(!!loading);\n }, [loading]);\n\n const isDisabled = innerLoading || mergedDisabled;\n const iconNode = setIcon(icon as React.ReactElement, innerLoading);\n\n // Build compact-mode border-radius and margin overrides\n const compactClasses = compactItemClassnames\n ? cn(\n // all compact items: remove border-radius on inner edges\n !compactItemClassnames[`${btnPrefix}-compact-first-item`] &&\n '!tw-rounded-l-none',\n !compactItemClassnames[`${btnPrefix}-compact-last-item`] &&\n '!tw-rounded-r-none',\n // merge borders via negative margin (except first item)\n !compactItemClassnames[`${btnPrefix}-compact-first-item`] &&\n '-tw-ml-px',\n )\n : undefined;\n\n const isIconOnly = !!icon && !children;\n\n const classes = cn(\n buttonVariants({\n type,\n size,\n disabled: !!isDisabled,\n block: !!block,\n shape,\n }),\n ghost && '!tw-border-current !tw-bg-transparent',\n // icon-only: square button, no min-width, centered padding\n isIconOnly && 'tw-aspect-square !tw-min-w-0 !tw-px-0',\n compactClasses,\n className,\n );\n\n if (href) {\n return (\n <a\n {...rest}\n className={classes}\n style={style}\n href={isDisabled ? undefined : href}\n target={target}\n ref={ref as React.Ref<HTMLAnchorElement>}\n onClick={isDisabled ? undefined : onClick}\n aria-disabled={isDisabled || undefined}\n >\n {iconNode}\n {children && (\n <span className=\"tw-inline-flex tw-items-center tw-gap-1\">\n {children}\n </span>\n )}\n </a>\n );\n }\n\n return (\n <button\n {...rest}\n type={\n htmlType === 'submit'\n ? 'submit'\n : htmlType === 'reset'\n ? 'reset'\n : 'button'\n }\n className={classes}\n style={style}\n disabled={isDisabled}\n aria-disabled={isDisabled || undefined}\n ref={ref as React.Ref<HTMLButtonElement>}\n onClick={onClick}\n >\n {iconNode}\n {children && (\n <span className=\"tw-inline-flex tw-items-center tw-gap-1\">\n {children}\n </span>\n )}\n </button>\n );\n}\n\nexport default forwardRef(Button);\n"],"mappings":";;;;;;;;;AAQA,IAAa,YAAY;AA+CzB,IAAa,WACX,UACA,YACG;AACH,KAAI,UAAU;EACZ,MAAM,IAAqC;GACzC,WAAW;GACX,MAAM;GACN,GAAG,SAAS;GACb;AACD,IAAE,OAAO;AACT,SAAO,MAAM,aAAa,UAAU,EAAE;;AAExC,KAAI,QACF,QACE,oBAAC,MAAD;EACE,WAAU;EACV,MAAM;EACN,OAAM;EACN,CAAA;AAGN,QAAO,oBAAA,UAAA,EAAK,CAAA;;AAGd,IAAM,iBAAiB,IACrB;CACE;CACA;CACA;CACA;CACD,EACD;CACE,UAAU;EACR,MAAM;GACJ,SAAS;IACP,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,WAAW;IACT,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,WAAW;IACT,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,MAAM;IACJ,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,SAAS;IACP,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,MAAM;IACJ,GAAG,UAAU;IACb;IACA;IACA;IACD;GACF;EACD,MAAM;GACJ,OAAO;IACL,GAAG,UAAU;IACb;IACA;IACD;GACD,QAAQ;IACN,GAAG,UAAU;IACb;IACA;IACD;GACD,OAAO;IACL,GAAG,UAAU;IACb;IACA;IACD;GACF;EACD,UAAU;GACR,MAAM;GACN,OAAO;GACR;EACD,OAAO;GACL,MAAM;GACN,OAAO;GACR;EACD,OAAO;GACL,QAAQ;GACR,SAAS;GACV;EACF;CACD,iBAAiB;EACf,MAAM;EACN,MAAM;EACN,UAAU;EACV,OAAO;EACP,OAAO;EACR;CACF,CACF;AAED,IAAM,cAA4B;CAChC;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,OAAO,OAAqB,KAA6B;CAChE,MAAM,EACJ,MAAM,UAAU,aAChB,MAAM,YACN,QAAQ,WACR,UAAU,OACV,UACA,MACA,WACA,UACA,MACA,QACA,SACA,OACA,WAAW,UACX,OACA,OACA,GAAG,SACD;CAIJ,MAAM,OAAmB,YAAY,SAAS,QAAsB,GAC/D,UACD;CAEJ,MAAM,kBAAkB,WAAW,gBAAgB;CACnD,MAAM,iBAAiB,YAAY;CAEnC,MAAM,cAAc,WAAW,YAAY;CAC3C,MAAM,EAAE,aAAa,0BACnB,sBAAsB,UAAU;CAClC,MAAM,OAAO,cAAc,eAAe,eAAe;CAEzD,MAAM,CAAC,cAAc,mBAAmB,SAAS,MAAM;AAEvD,iBAAgB;AACd,MAAI,OAAO,YAAY,YAAY,QAAQ,OAAO;GAChD,MAAM,QAAQ,iBAAiB,gBAAgB,KAAK,EAAE,QAAQ,MAAM;AACpE,gBAAa,aAAa,MAAM;;AAElC,kBAAgB,CAAC,CAAC,QAAQ;IACzB,CAAC,QAAQ,CAAC;CAEb,MAAM,aAAa,gBAAgB;CACnC,MAAM,WAAW,QAAQ,MAA4B,aAAa;CAGlE,MAAM,iBAAiB,wBACnB,GAEE,CAAC,sBAAsB,iCACrB,sBACF,CAAC,sBAAsB,gCACrB,sBAEF,CAAC,sBAAsB,iCACrB,YACH,GACD;CAEJ,MAAM,aAAa,CAAC,CAAC,QAAQ,CAAC;CAE9B,MAAM,UAAU,GACd,eAAe;EACb;EACA;EACA,UAAU,CAAC,CAAC;EACZ,OAAO,CAAC,CAAC;EACT;EACD,CAAC,EACF,SAAS,yCAET,cAAc,yCACd,gBACA,UACD;AAED,KAAI,KACF,QACE,qBAAC,KAAD;EACE,GAAI;EACJ,WAAW;EACJ;EACP,MAAM,aAAa,SAAY;EACvB;EACH;EACL,SAAS,aAAa,SAAY;EAClC,iBAAe,cAAc;YAR/B,CAUG,UACA,YACC,oBAAC,QAAD;GAAM,WAAU;GACb;GACI,CAAA,CAEP;;AAIR,QACE,qBAAC,UAAD;EACE,GAAI;EACJ,MACE,aAAa,WACT,WACA,aAAa,UACb,UACA;EAEN,WAAW;EACJ;EACP,UAAU;EACV,iBAAe,cAAc;EACxB;EACI;YAdX,CAgBG,UACA,YACC,oBAAC,QAAD;GAAM,WAAU;GACb;GACI,CAAA,CAEF;;;AAIb,IAAA,iBAAe,WAAW,OAAO"}
|
package/dist/Checkbox/type.d.ts
CHANGED
package/dist/Drawer/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export interface DrawerProps {
|
|
|
16
16
|
contentWrapperStyle?: React.CSSProperties;
|
|
17
17
|
bodyStyle?: React.CSSProperties;
|
|
18
18
|
headerStyle?: React.CSSProperties;
|
|
19
|
+
maskStyle?: React.CSSProperties;
|
|
19
20
|
footer?: React.ReactNode;
|
|
20
21
|
footerStyle?: React.CSSProperties;
|
|
21
22
|
extra?: React.ReactNode;
|
package/dist/Drawer/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Drawer/index.tsx"],"sourcesContent":["import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport React from 'react';\nimport { CloseLightLine } from '../Icon';\nimport { cn } from '../lib/utils';\n\nexport interface DrawerProps {\n open?: boolean;\n onClose?: (e?: React.MouseEvent | React.KeyboardEvent) => void;\n title?: React.ReactNode;\n placement?: 'top' | 'right' | 'bottom' | 'left';\n width?: number | string;\n height?: number | string;\n size?: 'default' | 'large';\n closable?: boolean;\n mask?: boolean;\n maskClosable?: boolean;\n destroyOnClose?: boolean;\n className?: string;\n style?: React.CSSProperties;\n contentWrapperStyle?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n headerStyle?: React.CSSProperties;\n footer?: React.ReactNode;\n footerStyle?: React.CSSProperties;\n extra?: React.ReactNode;\n children?: React.ReactNode;\n zIndex?: number;\n keyboard?: boolean;\n getContainer?: () => HTMLElement;\n}\n\nconst sizePresets: Record<string, number> = {\n default: 378,\n large: 736,\n};\n\nconst placementStyles: Record<string, string> = {\n right: 'tw-inset-y-0 tw-right-0 tw-h-full',\n left: 'tw-inset-y-0 tw-left-0 tw-h-full',\n top: 'tw-inset-x-0 tw-top-0 tw-w-full',\n bottom: 'tw-inset-x-0 tw-bottom-0 tw-w-full',\n};\n\nconst slideAnimationStyles: Record<string, string> = {\n right: 'tw-animate-in tw-slide-in-from-right tw-duration-300',\n left: 'tw-animate-in tw-slide-in-from-left tw-duration-300',\n top: 'tw-animate-in tw-slide-in-from-top tw-duration-300',\n bottom: 'tw-animate-in tw-slide-in-from-bottom tw-duration-300',\n};\n\nfunction Drawer(props: DrawerProps) {\n const {\n open = false,\n onClose,\n title,\n placement = 'right',\n width,\n height,\n size = 'default',\n closable = true,\n mask = true,\n maskClosable = true,\n className,\n style,\n contentWrapperStyle,\n bodyStyle,\n headerStyle,\n footer,\n footerStyle,\n extra,\n children,\n zIndex = 1000,\n } = props;\n\n const isHorizontal = placement === 'left' || placement === 'right';\n const preset = sizePresets[size] || sizePresets.default;\n const effectiveWidth = width ?? preset;\n const effectiveHeight = height ?? preset;\n const sizeStyle = isHorizontal\n ? { width: effectiveWidth, maxWidth: '100vw' }\n : { height: effectiveHeight, maxHeight: '100vh' };\n\n return (\n <DialogPrimitive.Root\n open={open}\n onOpenChange={(val) => {\n if (!val) onClose?.();\n }}\n >\n <DialogPrimitive.Portal>\n {mask && (\n <DialogPrimitive.Overlay\n className=\"ald-drawer-mask tw-animate-in tw-fade-in-0 tw-fixed tw-inset-0 tw-bg-black/45\"\n style={{ zIndex }}\n onClick={maskClosable ? () => onClose?.() : undefined}\n />\n )}\n <DialogPrimitive.Content\n className={cn(\n 'ald-drawer tw-fixed tw-flex tw-flex-col tw-bg-[var(--background-default)] tw-shadow-xl',\n placementStyles[placement],\n slideAnimationStyles[placement],\n className,\n )}\n style={{\n zIndex: zIndex + 1,\n ...sizeStyle,\n ...contentWrapperStyle,\n ...style,\n }}\n onEscapeKeyDown={() => onClose?.()}\n onInteractOutside={maskClosable ? () => onClose?.() : undefined}\n >\n {(title || closable || extra) && (\n <div\n className=\"ald-drawer-header tw-flex tw-items-center tw-justify-between tw-border-b tw-border-solid tw-border-[var(--border-default)] tw-px-6 tw-py-4\"\n style={headerStyle}\n >\n <DialogPrimitive.Title className=\"ald-drawer-title tw-m-0 tw-text-base tw-font-semibold tw-text-[var(--content-primary)]\">\n {title}\n </DialogPrimitive.Title>\n <div className=\"tw-flex tw-items-center tw-gap-2\">\n {extra}\n {closable && (\n <DialogPrimitive.Close asChild>\n <button\n type=\"button\"\n className=\"ald-drawer-close tw-flex tw-size-8 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded-r-50 tw-border-0 tw-bg-transparent hover:tw-bg-[var(--action-ghost-hover)]\"\n onClick={() => onClose?.()}\n >\n <CloseLightLine\n size={20}\n color=\"var(--content-secondary)\"\n />\n </button>\n </DialogPrimitive.Close>\n )}\n </div>\n </div>\n )}\n <div\n className=\"ald-drawer-body tw-flex-1 tw-overflow-auto tw-px-6 tw-py-4\"\n style={bodyStyle}\n >\n {children}\n </div>\n {footer && (\n <div\n className=\"ald-drawer-footer tw-border-t tw-border-solid tw-border-[var(--border-default)] tw-px-6 tw-py-4\"\n style={footerStyle}\n >\n {footer}\n </div>\n )}\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\nexport default Drawer;\n"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Drawer/index.tsx"],"sourcesContent":["import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport React from 'react';\nimport { CloseLightLine } from '../Icon';\nimport { cn } from '../lib/utils';\n\nexport interface DrawerProps {\n open?: boolean;\n onClose?: (e?: React.MouseEvent | React.KeyboardEvent) => void;\n title?: React.ReactNode;\n placement?: 'top' | 'right' | 'bottom' | 'left';\n width?: number | string;\n height?: number | string;\n size?: 'default' | 'large';\n closable?: boolean;\n mask?: boolean;\n maskClosable?: boolean;\n destroyOnClose?: boolean;\n className?: string;\n style?: React.CSSProperties;\n contentWrapperStyle?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n headerStyle?: React.CSSProperties;\n maskStyle?: React.CSSProperties;\n footer?: React.ReactNode;\n footerStyle?: React.CSSProperties;\n extra?: React.ReactNode;\n children?: React.ReactNode;\n zIndex?: number;\n keyboard?: boolean;\n getContainer?: () => HTMLElement;\n}\n\nconst sizePresets: Record<string, number> = {\n default: 378,\n large: 736,\n};\n\nconst placementStyles: Record<string, string> = {\n right: 'tw-inset-y-0 tw-right-0 tw-h-full',\n left: 'tw-inset-y-0 tw-left-0 tw-h-full',\n top: 'tw-inset-x-0 tw-top-0 tw-w-full',\n bottom: 'tw-inset-x-0 tw-bottom-0 tw-w-full',\n};\n\nconst slideAnimationStyles: Record<string, string> = {\n right: 'tw-animate-in tw-slide-in-from-right tw-duration-300',\n left: 'tw-animate-in tw-slide-in-from-left tw-duration-300',\n top: 'tw-animate-in tw-slide-in-from-top tw-duration-300',\n bottom: 'tw-animate-in tw-slide-in-from-bottom tw-duration-300',\n};\n\nfunction Drawer(props: DrawerProps) {\n const {\n open = false,\n onClose,\n title,\n placement = 'right',\n width,\n height,\n size = 'default',\n closable = true,\n mask = true,\n maskClosable = true,\n className,\n style,\n contentWrapperStyle,\n bodyStyle,\n headerStyle,\n footer,\n footerStyle,\n extra,\n children,\n zIndex = 1000,\n } = props;\n\n const isHorizontal = placement === 'left' || placement === 'right';\n const preset = sizePresets[size] || sizePresets.default;\n const effectiveWidth = width ?? preset;\n const effectiveHeight = height ?? preset;\n const sizeStyle = isHorizontal\n ? { width: effectiveWidth, maxWidth: '100vw' }\n : { height: effectiveHeight, maxHeight: '100vh' };\n\n return (\n <DialogPrimitive.Root\n open={open}\n onOpenChange={(val) => {\n if (!val) onClose?.();\n }}\n >\n <DialogPrimitive.Portal>\n {mask && (\n <DialogPrimitive.Overlay\n className=\"ald-drawer-mask tw-animate-in tw-fade-in-0 tw-fixed tw-inset-0 tw-bg-black/45\"\n style={{ zIndex }}\n onClick={maskClosable ? () => onClose?.() : undefined}\n />\n )}\n <DialogPrimitive.Content\n className={cn(\n 'ald-drawer tw-fixed tw-flex tw-flex-col tw-bg-[var(--background-default)] tw-shadow-xl',\n placementStyles[placement],\n slideAnimationStyles[placement],\n className,\n )}\n style={{\n zIndex: zIndex + 1,\n ...sizeStyle,\n ...contentWrapperStyle,\n ...style,\n }}\n onEscapeKeyDown={() => onClose?.()}\n onInteractOutside={maskClosable ? () => onClose?.() : undefined}\n >\n {(title || closable || extra) && (\n <div\n className=\"ald-drawer-header tw-flex tw-items-center tw-justify-between tw-border-b tw-border-solid tw-border-[var(--border-default)] tw-px-6 tw-py-4\"\n style={headerStyle}\n >\n <DialogPrimitive.Title className=\"ald-drawer-title tw-m-0 tw-text-base tw-font-semibold tw-text-[var(--content-primary)]\">\n {title}\n </DialogPrimitive.Title>\n <div className=\"tw-flex tw-items-center tw-gap-2\">\n {extra}\n {closable && (\n <DialogPrimitive.Close asChild>\n <button\n type=\"button\"\n className=\"ald-drawer-close tw-flex tw-size-8 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded-r-50 tw-border-0 tw-bg-transparent hover:tw-bg-[var(--action-ghost-hover)]\"\n onClick={() => onClose?.()}\n >\n <CloseLightLine\n size={20}\n color=\"var(--content-secondary)\"\n />\n </button>\n </DialogPrimitive.Close>\n )}\n </div>\n </div>\n )}\n <div\n className=\"ald-drawer-body tw-flex-1 tw-overflow-auto tw-px-6 tw-py-4\"\n style={bodyStyle}\n >\n {children}\n </div>\n {footer && (\n <div\n className=\"ald-drawer-footer tw-border-t tw-border-solid tw-border-[var(--border-default)] tw-px-6 tw-py-4\"\n style={footerStyle}\n >\n {footer}\n </div>\n )}\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\nexport default Drawer;\n"],"mappings":";;;;;;AAgCA,IAAM,cAAsC;CAC1C,SAAS;CACT,OAAO;CACR;AAED,IAAM,kBAA0C;CAC9C,OAAO;CACP,MAAM;CACN,KAAK;CACL,QAAQ;CACT;AAED,IAAM,uBAA+C;CACnD,OAAO;CACP,MAAM;CACN,KAAK;CACL,QAAQ;CACT;AAED,SAAS,OAAO,OAAoB;CAClC,MAAM,EACJ,OAAO,OACP,SACA,OACA,YAAY,SACZ,OACA,QACA,OAAO,WACP,WAAW,MACX,OAAO,MACP,eAAe,MACf,WACA,OACA,qBACA,WACA,aACA,QACA,aACA,OACA,UACA,SAAS,QACP;CAEJ,MAAM,eAAe,cAAc,UAAU,cAAc;CAC3D,MAAM,SAAS,YAAY,SAAS,YAAY;CAGhD,MAAM,YAAY,eACd;EAAE,OAHiB,SAAS;EAGH,UAAU;EAAS,GAC5C;EAAE,QAHkB,UAAU;EAGH,WAAW;EAAS;AAEnD,QACE,oBAAC,gBAAgB,MAAjB;EACQ;EACN,eAAe,QAAQ;AACrB,OAAI,CAAC,IAAK,YAAW;;YAGvB,qBAAC,gBAAgB,QAAjB,EAAA,UAAA,CACG,QACC,oBAAC,gBAAgB,SAAjB;GACE,WAAU;GACV,OAAO,EAAE,QAAQ;GACjB,SAAS,qBAAqB,WAAW,GAAG;GAC5C,CAAA,EAEJ,qBAAC,gBAAgB,SAAjB;GACE,WAAW,GACT,0FACA,gBAAgB,YAChB,qBAAqB,YACrB,UACD;GACD,OAAO;IACL,QAAQ,SAAS;IACjB,GAAG;IACH,GAAG;IACH,GAAG;IACJ;GACD,uBAAuB,WAAW;GAClC,mBAAmB,qBAAqB,WAAW,GAAG;aAdxD;KAgBI,SAAS,YAAY,UACrB,qBAAC,OAAD;KACE,WAAU;KACV,OAAO;eAFT,CAIE,oBAAC,gBAAgB,OAAjB;MAAuB,WAAU;gBAC9B;MACqB,CAAA,EACxB,qBAAC,OAAD;MAAK,WAAU;gBAAf,CACG,OACA,YACC,oBAAC,gBAAgB,OAAjB;OAAuB,SAAA;iBACrB,oBAAC,UAAD;QACE,MAAK;QACL,WAAU;QACV,eAAe,WAAW;kBAE1B,oBAAC,MAAD;SACE,MAAM;SACN,OAAM;SACN,CAAA;QACK,CAAA;OACa,CAAA,CAEtB;QACF;;IAER,oBAAC,OAAD;KACE,WAAU;KACV,OAAO;KAEN;KACG,CAAA;IACL,UACC,oBAAC,OAAD;KACE,WAAU;KACV,OAAO;eAEN;KACG,CAAA;IAEgB;KACH,EAAA,CAAA;EACJ,CAAA"}
|
package/dist/Form/index.d.ts
CHANGED
|
@@ -54,10 +54,12 @@ export interface FormItemProps {
|
|
|
54
54
|
labelCol?: {
|
|
55
55
|
span?: number;
|
|
56
56
|
offset?: number;
|
|
57
|
+
[key: string]: any;
|
|
57
58
|
};
|
|
58
59
|
wrapperCol?: {
|
|
59
60
|
span?: number;
|
|
60
61
|
offset?: number;
|
|
62
|
+
[key: string]: any;
|
|
61
63
|
};
|
|
62
64
|
validateStatus?: ValidateStatus;
|
|
63
65
|
colon?: boolean;
|
|
@@ -96,6 +98,7 @@ declare const AldForm: <Values = any>(props: FormProps<Values> & {
|
|
|
96
98
|
}) => React.ReactElement;
|
|
97
99
|
interface IFormItemProps extends FormItemProps {
|
|
98
100
|
labelWidth?: number;
|
|
101
|
+
labelAlign?: 'left' | 'right';
|
|
99
102
|
}
|
|
100
103
|
declare const AldFormItem: {
|
|
101
104
|
(props: IFormItemProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/Form/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Form/index.tsx"],"sourcesContent":["import RcForm, {\n Field,\n FormInstance as RcFormInstance,\n FormProvider,\n List,\n useForm as rcUseForm,\n useWatch,\n} from 'rc-field-form';\nimport type { FormProps as RcFormProps } from 'rc-field-form';\nimport FieldContext from 'rc-field-form/es/FieldContext';\nimport type { Rule, RuleObject, RuleRender } from 'rc-field-form/es/interface';\nimport type { Meta, NamePath } from 'rc-field-form/es/interface';\nimport React, { forwardRef, useContext, useMemo } from 'react';\nimport SizeContext, {\n SizeContextProvider,\n} from '../ConfigProvider/sizeContext';\nimport DisabledContext from '../ConfigProvider/DisabledContext';\nimport { cn } from '../lib/utils';\nimport {\n FormContext,\n FormItemInputContext,\n type ValidateStatus,\n} from './FormItemContext';\n\n// FormInstance type compatible with antd\nexport type FormInstance<Values = any> = RcFormInstance<Values> & {\n /** Scroll to field position (antd-compatible extension) */\n scrollToField?: (\n name: NamePath,\n options?: { behavior?: 'smooth' | 'auto' },\n ) => void;\n};\n\n// FormProps compatible with antd\nexport interface FormProps<Values = any> extends Omit<RcFormProps, 'form'> {\n form?: FormInstance<Values>;\n layout?: 'horizontal' | 'vertical' | 'inline';\n size?: 'small' | 'middle' | 'large';\n colon?: boolean;\n disabled?: boolean;\n labelCol?: { span?: number; offset?: number };\n wrapperCol?: { span?: number; offset?: number };\n className?: string;\n style?: React.CSSProperties;\n requiredMark?: boolean | 'optional';\n labelWidth?: number;\n labelAlign?: 'left' | 'right';\n}\n\n// FormItemProps\nexport interface FormItemProps {\n name?: NamePath;\n label?: React.ReactNode;\n rules?: Rule[];\n children?: React.ReactNode | ((form: RcFormInstance) => React.ReactNode);\n className?: string;\n style?: React.CSSProperties;\n required?: boolean;\n hidden?: boolean;\n initialValue?: any;\n dependencies?: NamePath[];\n shouldUpdate?: boolean | ((prevValues: any, curValues: any) => boolean);\n help?: React.ReactNode;\n extra?: React.ReactNode;\n validateTrigger?: string | string[];\n valuePropName?: string;\n getValueFromEvent?: (...args: any[]) => any;\n noStyle?: boolean;\n labelWidth?: number;\n tooltip?:\n | React.ReactNode\n | { title?: React.ReactNode; icon?: React.ReactNode };\n labelCol?: { span?: number; offset?: number };\n wrapperCol?: { span?: number; offset?: number };\n validateStatus?: ValidateStatus;\n colon?: boolean;\n trigger?: string;\n normalize?: (value: any, prevValue: any, allValues: any) => any;\n getValueProps?: (value: any) => Record<string, any>;\n}\n\nexport interface ErrorListProps {\n errors?: React.ReactNode[];\n help?: React.ReactNode;\n className?: string;\n}\n\nexport type FormListFieldData = {\n name: number;\n key: number;\n isListField: boolean;\n};\n\nexport type FormListOperation = {\n add: (defaultValue?: any, insertIndex?: number) => void;\n remove: (index: number | number[]) => void;\n move: (from: number, to: number) => void;\n};\n\nexport type FormListProps = {\n name: NamePath;\n rules?: Rule[];\n children: (\n fields: FormListFieldData[],\n operation: FormListOperation,\n meta: { errors: React.ReactNode[] },\n ) => React.ReactNode;\n initialValue?: any[];\n};\n\n// ============== Helpers ==============\n\n/** Convert a 24-column span/offset to Tailwind-compatible inline styles */\nfunction colStyle(col?: {\n span?: number;\n offset?: number;\n}): React.CSSProperties | undefined {\n if (!col) return undefined;\n const s: React.CSSProperties = {};\n if (col.span !== null && col.span !== undefined) {\n // 24-column grid: width = span / 24 * 100%\n s.width = `${(col.span / 24) * 100}%`;\n s.flex = `0 0 ${(col.span / 24) * 100}%`;\n }\n if (col.offset !== null && col.offset !== undefined && col.offset > 0) {\n s.marginLeft = `${(col.offset / 24) * 100}%`;\n }\n return s;\n}\n\n// ============== Form ==============\n\nconst AldForm = forwardRef((props: any, ref: any) => {\n const contextSize = useContext(SizeContext);\n const {\n children,\n size = contextSize,\n labelWidth,\n style = {},\n className,\n layout = 'horizontal',\n disabled,\n labelCol,\n wrapperCol,\n colon,\n requiredMark,\n ...restProps\n } = props;\n const customStyle = labelWidth\n ? { ...style, '--label-width': `${labelWidth}px` }\n : style;\n\n const formContextValue = useMemo(\n () => ({ layout, labelCol, wrapperCol, colon, requiredMark, labelWidth }),\n [layout, labelCol, wrapperCol, colon, requiredMark, labelWidth],\n );\n\n return (\n <FormContext.Provider value={formContextValue}>\n <DisabledContext.Provider value={disabled}>\n <SizeContextProvider size={size}>\n <RcForm\n style={customStyle}\n className={cn('ald-form', `ald-form-${layout}`, className)}\n {...restProps}\n ref={ref}\n >\n {children}\n </RcForm>\n </SizeContextProvider>\n </DisabledContext.Provider>\n </FormContext.Provider>\n );\n}) as <Values = any>(\n props: React.PropsWithChildren<FormProps<Values>> & {\n ref?: React.Ref<FormInstance<Values>>;\n labelWidth?: number;\n },\n) => React.ReactElement;\n\n// ============== Form.Item ==============\n\ninterface IFormItemProps extends FormItemProps {\n labelWidth?: number;\n}\n\n/** Derive status from meta or manual validateStatus */\nfunction deriveStatus(\n meta?: Meta,\n validateStatus?: ValidateStatus,\n): ValidateStatus {\n if (validateStatus) return validateStatus;\n if (!meta) return '';\n if (meta.validating) return 'validating';\n if (meta.errors && meta.errors.length > 0) return 'error';\n if (meta.warnings && meta.warnings.length > 0) return 'warning';\n if (meta.touched) return 'success';\n return '';\n}\n\n/** Status-based border class for the control wrapper */\nfunction statusClassName(status: ValidateStatus): string {\n switch (status) {\n case 'error':\n return 'ald-form-item-has-error';\n case 'warning':\n return 'ald-form-item-has-warning';\n case 'success':\n return 'ald-form-item-has-success';\n case 'validating':\n return 'ald-form-item-is-validating';\n default:\n return '';\n }\n}\n\n/** Render the inner label + control layout, receiving meta from Field */\nfunction FormItemLayout({\n label,\n children,\n meta,\n help,\n extra,\n required,\n hidden,\n className,\n customStyle,\n noStyle,\n labelCol: itemLabelCol,\n wrapperCol: itemWrapperCol,\n validateStatus: manualStatus,\n colon: itemColon,\n formContext,\n}: {\n label?: React.ReactNode;\n children: React.ReactNode;\n meta?: Meta;\n help?: React.ReactNode;\n extra?: React.ReactNode;\n required?: boolean;\n hidden?: boolean;\n className?: string;\n customStyle?: React.CSSProperties;\n noStyle?: boolean;\n labelCol?: { span?: number; offset?: number };\n wrapperCol?: { span?: number; offset?: number };\n validateStatus?: ValidateStatus;\n colon?: boolean;\n formContext: {\n layout?: string;\n labelCol?: { span?: number; offset?: number };\n wrapperCol?: { span?: number; offset?: number };\n colon?: boolean;\n requiredMark?: boolean | 'optional';\n labelWidth?: number;\n };\n}) {\n const status = deriveStatus(meta, manualStatus);\n const errors = useMemo(() => meta?.errors ?? [], [meta?.errors]);\n const warnings = useMemo(() => meta?.warnings ?? [], [meta?.warnings]);\n\n // Provide status context to child controls\n const itemInputContextValue = useMemo(\n () => ({\n status,\n isFormItemInput: true,\n errors,\n warnings,\n }),\n [status, errors, warnings],\n );\n\n if (noStyle) {\n return <>{children}</>;\n }\n\n // Determine if we should show required mark\n const { requiredMark } = formContext;\n const isRequired = required || (meta && (meta as any).required);\n const showRequired = requiredMark !== false && isRequired;\n const showOptional = requiredMark === 'optional' && !isRequired;\n\n // Resolve cols: item-level overrides form-level\n const resolvedLabelCol = itemLabelCol ?? formContext.labelCol;\n const resolvedWrapperCol = itemWrapperCol ?? formContext.wrapperCol;\n const layout = formContext.layout || 'horizontal';\n const showColon =\n (itemColon ?? formContext.colon) !== false && layout === 'horizontal';\n\n // Decide whether to use grid-style layout\n const useGridLayout =\n layout === 'horizontal' && (resolvedLabelCol || resolvedWrapperCol);\n\n // Determine display errors: if help is provided, show help instead of validation errors\n const displayMessages = help !== null && help !== undefined ? [help] : errors;\n const hasError = status === 'error' || (errors.length > 0 && help === null);\n const hasWarning =\n status === 'warning' || (warnings.length > 0 && help === null);\n\n const labelNode =\n label !== null && label !== undefined ? (\n <label\n className={cn(\n 'ald-form-item-label tw-text-sm tw-font-medium tw-text-[var(--content-primary)]',\n layout === 'vertical' && 'tw-mb-1 tw-block',\n layout === 'horizontal' && !useGridLayout && 'tw-mr-3 tw-shrink-0',\n layout === 'horizontal' && formContext.labelWidth && 'tw-shrink-0',\n )}\n style={\n !useGridLayout && layout === 'horizontal' && formContext.labelWidth\n ? { width: `var(--label-width, ${formContext.labelWidth}px)` }\n : useGridLayout\n ? colStyle(resolvedLabelCol)\n : undefined\n }\n >\n {showRequired && (\n <span className=\"tw-mr-1 tw-text-[var(--content-negative-primary)]\">\n *\n </span>\n )}\n {label}\n {showOptional && (\n <span className=\"tw-ml-1 tw-text-xs tw-font-normal tw-text-[var(--content-secondary)]\">\n (optional)\n </span>\n )}\n {showColon && label ? ':' : null}\n </label>\n ) : null;\n\n const controlNode = (\n <div\n className={cn(\n 'ald-form-item-control',\n layout === 'horizontal' && 'tw-flex-1',\n )}\n style={useGridLayout ? colStyle(resolvedWrapperCol) : undefined}\n >\n <FormItemInputContext.Provider value={itemInputContextValue}>\n <div className=\"ald-form-item-control-input\">{children}</div>\n </FormItemInputContext.Provider>\n {displayMessages.length > 0 && (\n <div\n className={cn(\n 'ald-form-item-explain tw-mt-1 tw-text-xs tw-transition-all tw-duration-200',\n hasError && 'tw-text-[var(--content-negative-secondary)]',\n hasWarning &&\n !hasError &&\n 'tw-text-[color:var(--content-warning-primary,#faad14)]',\n !hasError &&\n !hasWarning &&\n help !== null &&\n help !== undefined &&\n 'tw-text-[var(--content-secondary)]',\n )}\n >\n {displayMessages.map((msg, i) => (\n <div key={i}>{msg}</div>\n ))}\n </div>\n )}\n {extra && (\n <div className=\"ald-form-item-extra tw-mt-1 tw-text-xs tw-text-[var(--content-secondary)]\">\n {extra}\n </div>\n )}\n </div>\n );\n\n return (\n <div\n className={cn(\n 'ald-form-item tw-mb-6',\n hidden && 'tw-hidden',\n showRequired && 'ald-form-item-required',\n statusClassName(status),\n layout === 'horizontal' && 'tw-flex tw-flex-row tw-items-start',\n layout === 'inline' &&\n 'tw-mr-4 tw-inline-flex tw-flex-row tw-items-start',\n className,\n )}\n style={customStyle as React.CSSProperties}\n >\n {labelNode}\n {controlNode}\n </div>\n );\n}\n\nconst AldFormItem = function (props: IFormItemProps) {\n const {\n labelWidth,\n style = {},\n label,\n name,\n rules,\n children,\n className,\n required,\n hidden,\n initialValue,\n dependencies,\n shouldUpdate,\n help,\n extra,\n validateTrigger,\n valuePropName,\n getValueFromEvent,\n normalize,\n getValueProps,\n noStyle,\n labelCol,\n wrapperCol,\n validateStatus,\n colon,\n } = props;\n\n const formContext = useContext(FormContext);\n\n const customStyle = labelWidth\n ? { ...style, '--label-width': `${labelWidth}px` }\n : style;\n\n // If no name is provided (e.g. a submit button wrapper), we don't need Field\n // Also when shouldUpdate or dependencies are used without name, Field is still needed for re-render\n const needField =\n (name !== null && name !== undefined) ||\n (shouldUpdate !== null && shouldUpdate !== undefined) ||\n (dependencies !== null && dependencies !== undefined);\n\n if (!needField) {\n return (\n <FormItemLayout\n label={label}\n help={help}\n extra={extra}\n required={required}\n hidden={hidden}\n className={className}\n customStyle={customStyle as React.CSSProperties}\n noStyle={noStyle}\n labelCol={labelCol}\n wrapperCol={wrapperCol}\n validateStatus={validateStatus}\n colon={colon}\n formContext={formContext}\n >\n {children as React.ReactNode}\n </FormItemLayout>\n );\n }\n\n return (\n <Field\n name={name}\n rules={rules}\n initialValue={initialValue}\n dependencies={dependencies}\n shouldUpdate={shouldUpdate}\n validateTrigger={validateTrigger}\n valuePropName={valuePropName}\n getValueFromEvent={getValueFromEvent}\n normalize={normalize}\n getValueProps={getValueProps}\n >\n {(control, meta, form) => {\n // If children is a render function (shouldUpdate / dependencies pattern),\n // call it with the form instance and wrap in layout\n if (typeof children === 'function') {\n const childContent = (\n children as (form: RcFormInstance) => React.ReactNode\n )(form);\n if (noStyle) {\n return childContent;\n }\n return (\n <FormItemLayout\n label={label}\n meta={meta}\n help={help}\n extra={extra}\n required={required}\n hidden={hidden}\n className={className}\n customStyle={customStyle as React.CSSProperties}\n noStyle={noStyle}\n labelCol={labelCol}\n wrapperCol={wrapperCol}\n validateStatus={validateStatus}\n colon={colon}\n formContext={formContext}\n >\n {childContent}\n </FormItemLayout>\n );\n }\n\n // For noStyle, just clone with control props\n if (noStyle) {\n if (React.isValidElement(children)) {\n return React.cloneElement(\n children as React.ReactElement<any>,\n control,\n );\n }\n return children;\n }\n\n // Clone control props onto the single child element\n let childNode: React.ReactNode = children;\n if (React.isValidElement(children)) {\n childNode = React.cloneElement(\n children as React.ReactElement<any>,\n control,\n );\n }\n\n return (\n <FormItemLayout\n label={label}\n meta={meta}\n help={help}\n extra={extra}\n required={required}\n hidden={hidden}\n className={className}\n customStyle={customStyle as React.CSSProperties}\n labelCol={labelCol}\n wrapperCol={wrapperCol}\n validateStatus={validateStatus}\n colon={colon}\n formContext={formContext}\n >\n {childNode}\n </FormItemLayout>\n );\n }}\n </Field>\n );\n};\n\nfunction useFormItemStatus() {\n const ctx = useContext(FormItemInputContext);\n return {\n status: ctx.status,\n errors: ctx.errors ?? [],\n warnings: ctx.warnings ?? [],\n };\n}\n\nAldFormItem.useStatus = useFormItemStatus;\n\n// ============== ErrorList ==============\n\nfunction ErrorListComponent(props: ErrorListProps) {\n const { errors, className } = props;\n if (!errors || errors.length === 0) return null;\n return (\n <div className={cn('ald-form-error-list', className)}>\n {errors.map((err, i) => (\n <div\n key={i}\n className=\"tw-text-xs tw-text-[var(--content-negative-secondary)]\"\n >\n {err}\n </div>\n ))}\n </div>\n );\n}\n\n// ============== useFormInstance ==============\n\nfunction useFormInstance<T = any>(): FormInstance<T> {\n const form = useContext(FieldContext);\n return form as unknown as FormInstance<T>;\n}\n\n// ============== Compound component ==============\n\ntype InternalFormType = typeof AldForm;\ntype CompoundedComponent = InternalFormType & {\n useForm: <T = any>(...args: any[]) => [FormInstance<T>];\n useFormInstance: typeof useFormInstance;\n useWatch: typeof useWatch;\n Item: typeof AldFormItem;\n List: typeof List;\n ErrorList: typeof ErrorListComponent;\n Provider: typeof FormProvider;\n create: () => void;\n};\n\nconst Form = AldForm as CompoundedComponent;\n\nForm.Item = AldFormItem;\nForm.List = List;\nForm.ErrorList = ErrorListComponent;\nForm.useForm = rcUseForm;\nForm.useFormInstance = useFormInstance;\nForm.useWatch = useWatch;\nForm.Provider = FormProvider;\nForm.create = () => {\n console.warn('Form.create is deprecated. Please use Form.useForm() instead.');\n};\n\nexport type { Rule, RuleObject, RuleRender };\nexport default Form;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Form/index.tsx"],"sourcesContent":["import RcForm, {\n Field,\n FormInstance as RcFormInstance,\n FormProvider,\n List,\n useForm as rcUseForm,\n useWatch,\n} from 'rc-field-form';\nimport type { FormProps as RcFormProps } from 'rc-field-form';\nimport FieldContext from 'rc-field-form/es/FieldContext';\nimport type { Rule, RuleObject, RuleRender } from 'rc-field-form/es/interface';\nimport type { Meta, NamePath } from 'rc-field-form/es/interface';\nimport React, { forwardRef, useContext, useMemo } from 'react';\nimport SizeContext, {\n SizeContextProvider,\n} from '../ConfigProvider/sizeContext';\nimport DisabledContext from '../ConfigProvider/DisabledContext';\nimport { cn } from '../lib/utils';\nimport {\n FormContext,\n FormItemInputContext,\n type ValidateStatus,\n} from './FormItemContext';\n\n// FormInstance type compatible with antd\nexport type FormInstance<Values = any> = RcFormInstance<Values> & {\n /** Scroll to field position (antd-compatible extension) */\n scrollToField?: (\n name: NamePath,\n options?: { behavior?: 'smooth' | 'auto' },\n ) => void;\n};\n\n// FormProps compatible with antd\nexport interface FormProps<Values = any> extends Omit<RcFormProps, 'form'> {\n form?: FormInstance<Values>;\n layout?: 'horizontal' | 'vertical' | 'inline';\n size?: 'small' | 'middle' | 'large';\n colon?: boolean;\n disabled?: boolean;\n labelCol?: { span?: number; offset?: number };\n wrapperCol?: { span?: number; offset?: number };\n className?: string;\n style?: React.CSSProperties;\n requiredMark?: boolean | 'optional';\n labelWidth?: number;\n labelAlign?: 'left' | 'right';\n}\n\n// FormItemProps\nexport interface FormItemProps {\n name?: NamePath;\n label?: React.ReactNode;\n rules?: Rule[];\n children?: React.ReactNode | ((form: RcFormInstance) => React.ReactNode);\n className?: string;\n style?: React.CSSProperties;\n required?: boolean;\n hidden?: boolean;\n initialValue?: any;\n dependencies?: NamePath[];\n shouldUpdate?: boolean | ((prevValues: any, curValues: any) => boolean);\n help?: React.ReactNode;\n extra?: React.ReactNode;\n validateTrigger?: string | string[];\n valuePropName?: string;\n getValueFromEvent?: (...args: any[]) => any;\n noStyle?: boolean;\n labelWidth?: number;\n tooltip?:\n | React.ReactNode\n | { title?: React.ReactNode; icon?: React.ReactNode };\n labelCol?: { span?: number; offset?: number; [key: string]: any };\n wrapperCol?: { span?: number; offset?: number; [key: string]: any };\n validateStatus?: ValidateStatus;\n colon?: boolean;\n trigger?: string;\n normalize?: (value: any, prevValue: any, allValues: any) => any;\n getValueProps?: (value: any) => Record<string, any>;\n}\n\nexport interface ErrorListProps {\n errors?: React.ReactNode[];\n help?: React.ReactNode;\n className?: string;\n}\n\nexport type FormListFieldData = {\n name: number;\n key: number;\n isListField: boolean;\n};\n\nexport type FormListOperation = {\n add: (defaultValue?: any, insertIndex?: number) => void;\n remove: (index: number | number[]) => void;\n move: (from: number, to: number) => void;\n};\n\nexport type FormListProps = {\n name: NamePath;\n rules?: Rule[];\n children: (\n fields: FormListFieldData[],\n operation: FormListOperation,\n meta: { errors: React.ReactNode[] },\n ) => React.ReactNode;\n initialValue?: any[];\n};\n\n// ============== Helpers ==============\n\n/** Convert a 24-column span/offset to Tailwind-compatible inline styles */\nfunction colStyle(col?: {\n span?: number;\n offset?: number;\n}): React.CSSProperties | undefined {\n if (!col) return undefined;\n const s: React.CSSProperties = {};\n if (col.span !== null && col.span !== undefined) {\n // 24-column grid: width = span / 24 * 100%\n s.width = `${(col.span / 24) * 100}%`;\n s.flex = `0 0 ${(col.span / 24) * 100}%`;\n }\n if (col.offset !== null && col.offset !== undefined && col.offset > 0) {\n s.marginLeft = `${(col.offset / 24) * 100}%`;\n }\n return s;\n}\n\n// ============== Form ==============\n\nconst AldForm = forwardRef((props: any, ref: any) => {\n const contextSize = useContext(SizeContext);\n const {\n children,\n size = contextSize,\n labelWidth,\n style = {},\n className,\n layout = 'horizontal',\n disabled,\n labelCol,\n wrapperCol,\n colon,\n requiredMark,\n ...restProps\n } = props;\n const customStyle = labelWidth\n ? { ...style, '--label-width': `${labelWidth}px` }\n : style;\n\n const formContextValue = useMemo(\n () => ({ layout, labelCol, wrapperCol, colon, requiredMark, labelWidth }),\n [layout, labelCol, wrapperCol, colon, requiredMark, labelWidth],\n );\n\n return (\n <FormContext.Provider value={formContextValue}>\n <DisabledContext.Provider value={disabled}>\n <SizeContextProvider size={size}>\n <RcForm\n style={customStyle}\n className={cn('ald-form', `ald-form-${layout}`, className)}\n {...restProps}\n ref={ref}\n >\n {children}\n </RcForm>\n </SizeContextProvider>\n </DisabledContext.Provider>\n </FormContext.Provider>\n );\n}) as <Values = any>(\n props: React.PropsWithChildren<FormProps<Values>> & {\n ref?: React.Ref<FormInstance<Values>>;\n labelWidth?: number;\n },\n) => React.ReactElement;\n\n// ============== Form.Item ==============\n\ninterface IFormItemProps extends FormItemProps {\n labelWidth?: number;\n labelAlign?: 'left' | 'right';\n}\n\n/** Derive status from meta or manual validateStatus */\nfunction deriveStatus(\n meta?: Meta,\n validateStatus?: ValidateStatus,\n): ValidateStatus {\n if (validateStatus) return validateStatus;\n if (!meta) return '';\n if (meta.validating) return 'validating';\n if (meta.errors && meta.errors.length > 0) return 'error';\n if (meta.warnings && meta.warnings.length > 0) return 'warning';\n if (meta.touched) return 'success';\n return '';\n}\n\n/** Status-based border class for the control wrapper */\nfunction statusClassName(status: ValidateStatus): string {\n switch (status) {\n case 'error':\n return 'ald-form-item-has-error';\n case 'warning':\n return 'ald-form-item-has-warning';\n case 'success':\n return 'ald-form-item-has-success';\n case 'validating':\n return 'ald-form-item-is-validating';\n default:\n return '';\n }\n}\n\n/** Render the inner label + control layout, receiving meta from Field */\nfunction FormItemLayout({\n label,\n children,\n meta,\n help,\n extra,\n required,\n hidden,\n className,\n customStyle,\n noStyle,\n labelCol: itemLabelCol,\n wrapperCol: itemWrapperCol,\n validateStatus: manualStatus,\n colon: itemColon,\n formContext,\n}: {\n label?: React.ReactNode;\n children: React.ReactNode;\n meta?: Meta;\n help?: React.ReactNode;\n extra?: React.ReactNode;\n required?: boolean;\n hidden?: boolean;\n className?: string;\n customStyle?: React.CSSProperties;\n noStyle?: boolean;\n labelCol?: { span?: number; offset?: number };\n wrapperCol?: { span?: number; offset?: number };\n validateStatus?: ValidateStatus;\n colon?: boolean;\n formContext: {\n layout?: string;\n labelCol?: { span?: number; offset?: number };\n wrapperCol?: { span?: number; offset?: number };\n colon?: boolean;\n requiredMark?: boolean | 'optional';\n labelWidth?: number;\n };\n}) {\n const status = deriveStatus(meta, manualStatus);\n const errors = useMemo(() => meta?.errors ?? [], [meta?.errors]);\n const warnings = useMemo(() => meta?.warnings ?? [], [meta?.warnings]);\n\n // Provide status context to child controls\n const itemInputContextValue = useMemo(\n () => ({\n status,\n isFormItemInput: true,\n errors,\n warnings,\n }),\n [status, errors, warnings],\n );\n\n if (noStyle) {\n return <>{children}</>;\n }\n\n // Determine if we should show required mark\n const { requiredMark } = formContext;\n const isRequired = required || (meta && (meta as any).required);\n const showRequired = requiredMark !== false && isRequired;\n const showOptional = requiredMark === 'optional' && !isRequired;\n\n // Resolve cols: item-level overrides form-level\n const resolvedLabelCol = itemLabelCol ?? formContext.labelCol;\n const resolvedWrapperCol = itemWrapperCol ?? formContext.wrapperCol;\n const layout = formContext.layout || 'horizontal';\n const showColon =\n (itemColon ?? formContext.colon) !== false && layout === 'horizontal';\n\n // Decide whether to use grid-style layout\n const useGridLayout =\n layout === 'horizontal' && (resolvedLabelCol || resolvedWrapperCol);\n\n // Determine display errors: if help is provided, show help instead of validation errors\n const displayMessages = help !== null && help !== undefined ? [help] : errors;\n const hasError = status === 'error' || (errors.length > 0 && help === null);\n const hasWarning =\n status === 'warning' || (warnings.length > 0 && help === null);\n\n const labelNode =\n label !== null && label !== undefined ? (\n <label\n className={cn(\n 'ald-form-item-label tw-text-sm tw-font-medium tw-text-[var(--content-primary)]',\n layout === 'vertical' && 'tw-mb-1 tw-block',\n layout === 'horizontal' && !useGridLayout && 'tw-mr-3 tw-shrink-0',\n layout === 'horizontal' && formContext.labelWidth && 'tw-shrink-0',\n )}\n style={\n !useGridLayout && layout === 'horizontal' && formContext.labelWidth\n ? { width: `var(--label-width, ${formContext.labelWidth}px)` }\n : useGridLayout\n ? colStyle(resolvedLabelCol)\n : undefined\n }\n >\n {showRequired && (\n <span className=\"tw-mr-1 tw-text-[var(--content-negative-primary)]\">\n *\n </span>\n )}\n {label}\n {showOptional && (\n <span className=\"tw-ml-1 tw-text-xs tw-font-normal tw-text-[var(--content-secondary)]\">\n (optional)\n </span>\n )}\n {showColon && label ? ':' : null}\n </label>\n ) : null;\n\n const controlNode = (\n <div\n className={cn(\n 'ald-form-item-control',\n layout === 'horizontal' && 'tw-flex-1',\n )}\n style={useGridLayout ? colStyle(resolvedWrapperCol) : undefined}\n >\n <FormItemInputContext.Provider value={itemInputContextValue}>\n <div className=\"ald-form-item-control-input\">{children}</div>\n </FormItemInputContext.Provider>\n {displayMessages.length > 0 && (\n <div\n className={cn(\n 'ald-form-item-explain tw-mt-1 tw-text-xs tw-transition-all tw-duration-200',\n hasError && 'tw-text-[var(--content-negative-secondary)]',\n hasWarning &&\n !hasError &&\n 'tw-text-[color:var(--content-warning-primary,#faad14)]',\n !hasError &&\n !hasWarning &&\n help !== null &&\n help !== undefined &&\n 'tw-text-[var(--content-secondary)]',\n )}\n >\n {displayMessages.map((msg, i) => (\n <div key={i}>{msg}</div>\n ))}\n </div>\n )}\n {extra && (\n <div className=\"ald-form-item-extra tw-mt-1 tw-text-xs tw-text-[var(--content-secondary)]\">\n {extra}\n </div>\n )}\n </div>\n );\n\n return (\n <div\n className={cn(\n 'ald-form-item tw-mb-6',\n hidden && 'tw-hidden',\n showRequired && 'ald-form-item-required',\n statusClassName(status),\n layout === 'horizontal' && 'tw-flex tw-flex-row tw-items-start',\n layout === 'inline' &&\n 'tw-mr-4 tw-inline-flex tw-flex-row tw-items-start',\n className,\n )}\n style={customStyle as React.CSSProperties}\n >\n {labelNode}\n {controlNode}\n </div>\n );\n}\n\nconst AldFormItem = function (props: IFormItemProps) {\n const {\n labelWidth,\n style = {},\n label,\n name,\n rules,\n children,\n className,\n required,\n hidden,\n initialValue,\n dependencies,\n shouldUpdate,\n help,\n extra,\n validateTrigger,\n valuePropName,\n getValueFromEvent,\n normalize,\n getValueProps,\n noStyle,\n labelCol,\n wrapperCol,\n validateStatus,\n colon,\n } = props;\n\n const formContext = useContext(FormContext);\n\n const customStyle = labelWidth\n ? { ...style, '--label-width': `${labelWidth}px` }\n : style;\n\n // If no name is provided (e.g. a submit button wrapper), we don't need Field\n // Also when shouldUpdate or dependencies are used without name, Field is still needed for re-render\n const needField =\n (name !== null && name !== undefined) ||\n (shouldUpdate !== null && shouldUpdate !== undefined) ||\n (dependencies !== null && dependencies !== undefined);\n\n if (!needField) {\n return (\n <FormItemLayout\n label={label}\n help={help}\n extra={extra}\n required={required}\n hidden={hidden}\n className={className}\n customStyle={customStyle as React.CSSProperties}\n noStyle={noStyle}\n labelCol={labelCol}\n wrapperCol={wrapperCol}\n validateStatus={validateStatus}\n colon={colon}\n formContext={formContext}\n >\n {children as React.ReactNode}\n </FormItemLayout>\n );\n }\n\n return (\n <Field\n name={name}\n rules={rules}\n initialValue={initialValue}\n dependencies={dependencies}\n shouldUpdate={shouldUpdate}\n validateTrigger={validateTrigger}\n valuePropName={valuePropName}\n getValueFromEvent={getValueFromEvent}\n normalize={normalize}\n getValueProps={getValueProps}\n >\n {(control, meta, form) => {\n // If children is a render function (shouldUpdate / dependencies pattern),\n // call it with the form instance and wrap in layout\n if (typeof children === 'function') {\n const childContent = (\n children as (form: RcFormInstance) => React.ReactNode\n )(form);\n if (noStyle) {\n return childContent;\n }\n return (\n <FormItemLayout\n label={label}\n meta={meta}\n help={help}\n extra={extra}\n required={required}\n hidden={hidden}\n className={className}\n customStyle={customStyle as React.CSSProperties}\n noStyle={noStyle}\n labelCol={labelCol}\n wrapperCol={wrapperCol}\n validateStatus={validateStatus}\n colon={colon}\n formContext={formContext}\n >\n {childContent}\n </FormItemLayout>\n );\n }\n\n // For noStyle, just clone with control props\n if (noStyle) {\n if (React.isValidElement(children)) {\n return React.cloneElement(\n children as React.ReactElement<any>,\n control,\n );\n }\n return children;\n }\n\n // Clone control props onto the single child element\n let childNode: React.ReactNode = children;\n if (React.isValidElement(children)) {\n childNode = React.cloneElement(\n children as React.ReactElement<any>,\n control,\n );\n }\n\n return (\n <FormItemLayout\n label={label}\n meta={meta}\n help={help}\n extra={extra}\n required={required}\n hidden={hidden}\n className={className}\n customStyle={customStyle as React.CSSProperties}\n labelCol={labelCol}\n wrapperCol={wrapperCol}\n validateStatus={validateStatus}\n colon={colon}\n formContext={formContext}\n >\n {childNode}\n </FormItemLayout>\n );\n }}\n </Field>\n );\n};\n\nfunction useFormItemStatus() {\n const ctx = useContext(FormItemInputContext);\n return {\n status: ctx.status,\n errors: ctx.errors ?? [],\n warnings: ctx.warnings ?? [],\n };\n}\n\nAldFormItem.useStatus = useFormItemStatus;\n\n// ============== ErrorList ==============\n\nfunction ErrorListComponent(props: ErrorListProps) {\n const { errors, className } = props;\n if (!errors || errors.length === 0) return null;\n return (\n <div className={cn('ald-form-error-list', className)}>\n {errors.map((err, i) => (\n <div\n key={i}\n className=\"tw-text-xs tw-text-[var(--content-negative-secondary)]\"\n >\n {err}\n </div>\n ))}\n </div>\n );\n}\n\n// ============== useFormInstance ==============\n\nfunction useFormInstance<T = any>(): FormInstance<T> {\n const form = useContext(FieldContext);\n return form as unknown as FormInstance<T>;\n}\n\n// ============== Compound component ==============\n\ntype InternalFormType = typeof AldForm;\ntype CompoundedComponent = InternalFormType & {\n useForm: <T = any>(...args: any[]) => [FormInstance<T>];\n useFormInstance: typeof useFormInstance;\n useWatch: typeof useWatch;\n Item: typeof AldFormItem;\n List: typeof List;\n ErrorList: typeof ErrorListComponent;\n Provider: typeof FormProvider;\n create: () => void;\n};\n\nconst Form = AldForm as CompoundedComponent;\n\nForm.Item = AldFormItem;\nForm.List = List;\nForm.ErrorList = ErrorListComponent;\nForm.useForm = rcUseForm;\nForm.useFormInstance = useFormInstance;\nForm.useWatch = useWatch;\nForm.Provider = FormProvider;\nForm.create = () => {\n console.warn('Form.create is deprecated. Please use Form.useForm() instead.');\n};\n\nexport type { Rule, RuleObject, RuleRender };\nexport default Form;\n"],"mappings":"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"}
|
|
@@ -20,6 +20,8 @@ export interface IInputProps {
|
|
|
20
20
|
disabled?: boolean;
|
|
21
21
|
showCount?: boolean | IShowCountProps;
|
|
22
22
|
maxLength?: number;
|
|
23
|
+
minLength?: number;
|
|
24
|
+
max?: number;
|
|
23
25
|
value?: string;
|
|
24
26
|
defaultValue?: string;
|
|
25
27
|
onPressEnter?: React.KeyboardEventHandler<HTMLInputElement>;
|
|
@@ -33,6 +35,7 @@ export interface IInputProps {
|
|
|
33
35
|
autoComplete?: string;
|
|
34
36
|
autoFocus?: boolean;
|
|
35
37
|
readOnly?: boolean;
|
|
38
|
+
width?: number | string;
|
|
36
39
|
onBlur?: React.FocusEventHandler<HTMLInputElement>;
|
|
37
40
|
onFocus?: React.FocusEventHandler<HTMLInputElement>;
|
|
38
41
|
onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/Input/components/Input/index.tsx"],"sourcesContent":["import React, {\n ReactNode,\n forwardRef,\n useContext,\n useRef,\n useState,\n} from 'react';\nimport DisabledContext from '../../../ConfigProvider/DisabledContext';\nimport SizeContext, { SizeType } from '../../../ConfigProvider/sizeContext';\nimport { CloseCircleFill } from '../../../Icon';\nimport { cn } from '../../../lib/utils';\nimport { useCompactItemContext } from '../../../Space/CompactContext';\n\ninterface IShowCountProps {\n formatter: (args: { count: number; maxLength?: number }) => string;\n}\nexport type TSize = SizeType;\nexport type InputRef = HTMLInputElement;\n\ntype ChangeEventHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;\n\nexport interface IInputProps {\n addonAfter?: ReactNode;\n addonBefore?: ReactNode;\n size?: TSize;\n id?: string;\n prefix?: ReactNode;\n suffix?: ReactNode;\n allowClear?: boolean;\n disabled?: boolean;\n showCount?: boolean | IShowCountProps;\n maxLength?: number;\n value?: string;\n defaultValue?: string;\n onPressEnter?: React.KeyboardEventHandler<HTMLInputElement>;\n onChange?: ChangeEventHandler;\n className?: string;\n style?: React.CSSProperties;\n placeholder?: string;\n type?: string;\n bordered?: boolean;\n status?: 'error' | 'warning' | '';\n autoComplete?: string;\n autoFocus?: boolean;\n readOnly?: boolean;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onCompositionStart?: React.CompositionEventHandler<HTMLInputElement>;\n onCompositionEnd?: React.CompositionEventHandler<HTMLInputElement>;\n}\n\nexport function getSizeType(sizeType: TSize): TSize {\n if (['small', 'middle', 'large'].includes(sizeType || '')) {\n return sizeType;\n }\n return 'middle';\n}\n\nconst Input = forwardRef<InputRef, IInputProps>((props, ref) => {\n const {\n size: customSize,\n className,\n bordered = true,\n status,\n disabled,\n allowClear,\n prefix,\n suffix,\n addonBefore,\n addonAfter,\n showCount,\n maxLength,\n value: controlledValue,\n defaultValue,\n onChange,\n onPressEnter,\n onBlur,\n onFocus,\n onKeyDown,\n onCompositionStart,\n onCompositionEnd,\n placeholder,\n type,\n id,\n autoFocus,\n readOnly,\n style,\n } = props;\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const { compactSize, compactItemClassnames } =\n useCompactItemContext('ald-input');\n const size = customSize || compactSize || contentSize || 'middle';\n\n const isControlled = 'value' in props;\n const [innerValue, setInnerValue] = useState(defaultValue ?? '');\n const currentValue = isControlled ? controlledValue ?? '' : innerValue;\n const [focused, setFocused] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n React.useImperativeHandle(ref, () => inputRef.current!);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) setInnerValue(e.target.value);\n onChange?.(e);\n };\n\n const handleClear = () => {\n const nativeEvent = new Event('input', { bubbles: true });\n if (inputRef.current) {\n const nativeSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeSetter?.call(inputRef.current, '');\n inputRef.current.dispatchEvent(nativeEvent);\n }\n if (!isControlled) setInnerValue('');\n onChange?.({\n target: { value: '' },\n } as React.ChangeEvent<HTMLInputElement>);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') onPressEnter?.(e);\n onKeyDown?.(e);\n };\n\n const showClearIcon = allowClear && currentValue && !mergedDisabled;\n\n const countInfo =\n showCount && typeof showCount === 'object'\n ? showCount.formatter({\n count: currentValue.length,\n maxLength,\n })\n : showCount\n ? `${currentValue.length}${maxLength ? `/${maxLength}` : ''}`\n : null;\n\n // Build compact-mode border-radius and margin overrides\n const compactClasses = compactItemClassnames\n ? cn(\n !compactItemClassnames['ald-input-compact-first-item'] &&\n '!tw-rounded-l-none',\n !compactItemClassnames['ald-input-compact-last-item'] &&\n '!tw-rounded-r-none',\n !compactItemClassnames['ald-input-compact-first-item'] && '-tw-ml-px',\n )\n : undefined;\n\n return (\n <span\n className={cn(\n 'ald-input tw-inline-flex tw-w-full tw-items-center tw-bg-[var(--interaction-background-form-field)]',\n bordered &&\n 'tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--interaction-border-neutral-normal)]',\n focused &&\n 'tw-border-[var(--interaction-focus-default)] tw-outline tw-outline-1 tw-outline-[var(--interaction-focus-default)]',\n !mergedDisabled &&\n !focused &&\n 'hover:tw-border-[var(--interaction-border-hover)]',\n `ald-input-${getSizeType(size)}`,\n size === 'small' && 'tw-h-7 tw-text-xs',\n size === 'large' && 'tw-h-9 tw-text-sm',\n (size === 'middle' || !size) && 'tw-h-8 tw-text-sm',\n status === 'error' &&\n `ald-input-error tw-border-[var(--border-negative-strong)]`,\n status === 'warning' &&\n `ald-input-warning tw-border-[var(--border-warning-subtle)]`,\n mergedDisabled &&\n 'ald-input-disabled tw-cursor-not-allowed tw-bg-[var(--global-cool-gray-alpha-50)] tw-text-[var(--content-secondary)]',\n compactClasses,\n className,\n )}\n style={style}\n >\n {addonBefore && (\n <span className=\"ald-input-addon tw-flex tw-shrink-0 tw-items-center tw-self-stretch tw-border-r tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-neutral-subtle)] tw-px-3 tw-text-[var(--content-secondary)]\">\n {addonBefore}\n </span>\n )}\n {prefix && (\n <span className=\"ald-input-prefix tw-flex tw-items-center tw-pl-2 tw-text-[var(--content-secondary)]\">\n {prefix}\n </span>\n )}\n <input\n ref={inputRef}\n id={id}\n type={type || 'text'}\n className=\"tw-min-w-0 tw-flex-1 tw-border-0 tw-bg-transparent tw-px-2 tw-text-[var(--content-primary)] tw-text-inherit tw-outline-none\"\n value={currentValue}\n onChange={handleChange}\n onBlur={(e) => {\n setFocused(false);\n onBlur?.(e);\n }}\n onFocus={(e) => {\n setFocused(true);\n onFocus?.(e);\n }}\n onKeyDown={handleKeyDown}\n onCompositionStart={onCompositionStart}\n onCompositionEnd={onCompositionEnd}\n disabled={mergedDisabled}\n placeholder={placeholder}\n maxLength={maxLength}\n autoComplete=\"off\"\n autoFocus={autoFocus}\n readOnly={readOnly}\n spellCheck={false}\n />\n {showClearIcon && (\n <span\n className=\"ald-input-clear tw-flex tw-cursor-pointer tw-items-center tw-pr-1\"\n onClick={handleClear}\n >\n <CloseCircleFill size={16} color=\"var(--alias-colors-icon-subtle)\" />\n </span>\n )}\n {suffix && (\n <span className=\"ald-input-suffix tw-flex tw-items-center tw-pr-2 tw-text-[var(--content-secondary)]\">\n {suffix}\n </span>\n )}\n {countInfo && (\n <span className=\"ald-input-count tw-pr-2 tw-text-xs tw-text-[var(--content-tertiary)]\">\n {countInfo}\n </span>\n )}\n {addonAfter && (\n <span className=\"ald-input-addon tw-border-l tw-border-solid tw-border-[var(--border-default)] tw-px-2 tw-text-[var(--content-secondary)]\">\n {addonAfter}\n </span>\n )}\n </span>\n );\n});\n\nexport default Input;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/Input/components/Input/index.tsx"],"sourcesContent":["import React, {\n ReactNode,\n forwardRef,\n useContext,\n useRef,\n useState,\n} from 'react';\nimport DisabledContext from '../../../ConfigProvider/DisabledContext';\nimport SizeContext, { SizeType } from '../../../ConfigProvider/sizeContext';\nimport { CloseCircleFill } from '../../../Icon';\nimport { cn } from '../../../lib/utils';\nimport { useCompactItemContext } from '../../../Space/CompactContext';\n\ninterface IShowCountProps {\n formatter: (args: { count: number; maxLength?: number }) => string;\n}\nexport type TSize = SizeType;\nexport type InputRef = HTMLInputElement;\n\ntype ChangeEventHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;\n\nexport interface IInputProps {\n addonAfter?: ReactNode;\n addonBefore?: ReactNode;\n size?: TSize;\n id?: string;\n prefix?: ReactNode;\n suffix?: ReactNode;\n allowClear?: boolean;\n disabled?: boolean;\n showCount?: boolean | IShowCountProps;\n maxLength?: number;\n minLength?: number;\n max?: number;\n value?: string;\n defaultValue?: string;\n onPressEnter?: React.KeyboardEventHandler<HTMLInputElement>;\n onChange?: ChangeEventHandler;\n className?: string;\n style?: React.CSSProperties;\n placeholder?: string;\n type?: string;\n bordered?: boolean;\n status?: 'error' | 'warning' | '';\n autoComplete?: string;\n autoFocus?: boolean;\n readOnly?: boolean;\n width?: number | string;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onCompositionStart?: React.CompositionEventHandler<HTMLInputElement>;\n onCompositionEnd?: React.CompositionEventHandler<HTMLInputElement>;\n}\n\nexport function getSizeType(sizeType: TSize): TSize {\n if (['small', 'middle', 'large'].includes(sizeType || '')) {\n return sizeType;\n }\n return 'middle';\n}\n\nconst Input = forwardRef<InputRef, IInputProps>((props, ref) => {\n const {\n size: customSize,\n className,\n bordered = true,\n status,\n disabled,\n allowClear,\n prefix,\n suffix,\n addonBefore,\n addonAfter,\n showCount,\n maxLength,\n value: controlledValue,\n defaultValue,\n onChange,\n onPressEnter,\n onBlur,\n onFocus,\n onKeyDown,\n onCompositionStart,\n onCompositionEnd,\n placeholder,\n type,\n id,\n autoFocus,\n readOnly,\n style,\n } = props;\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const { compactSize, compactItemClassnames } =\n useCompactItemContext('ald-input');\n const size = customSize || compactSize || contentSize || 'middle';\n\n const isControlled = 'value' in props;\n const [innerValue, setInnerValue] = useState(defaultValue ?? '');\n const currentValue = isControlled ? controlledValue ?? '' : innerValue;\n const [focused, setFocused] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n React.useImperativeHandle(ref, () => inputRef.current!);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) setInnerValue(e.target.value);\n onChange?.(e);\n };\n\n const handleClear = () => {\n const nativeEvent = new Event('input', { bubbles: true });\n if (inputRef.current) {\n const nativeSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeSetter?.call(inputRef.current, '');\n inputRef.current.dispatchEvent(nativeEvent);\n }\n if (!isControlled) setInnerValue('');\n onChange?.({\n target: { value: '' },\n } as React.ChangeEvent<HTMLInputElement>);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') onPressEnter?.(e);\n onKeyDown?.(e);\n };\n\n const showClearIcon = allowClear && currentValue && !mergedDisabled;\n\n const countInfo =\n showCount && typeof showCount === 'object'\n ? showCount.formatter({\n count: currentValue.length,\n maxLength,\n })\n : showCount\n ? `${currentValue.length}${maxLength ? `/${maxLength}` : ''}`\n : null;\n\n // Build compact-mode border-radius and margin overrides\n const compactClasses = compactItemClassnames\n ? cn(\n !compactItemClassnames['ald-input-compact-first-item'] &&\n '!tw-rounded-l-none',\n !compactItemClassnames['ald-input-compact-last-item'] &&\n '!tw-rounded-r-none',\n !compactItemClassnames['ald-input-compact-first-item'] && '-tw-ml-px',\n )\n : undefined;\n\n return (\n <span\n className={cn(\n 'ald-input tw-inline-flex tw-w-full tw-items-center tw-bg-[var(--interaction-background-form-field)]',\n bordered &&\n 'tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--interaction-border-neutral-normal)]',\n focused &&\n 'tw-border-[var(--interaction-focus-default)] tw-outline tw-outline-1 tw-outline-[var(--interaction-focus-default)]',\n !mergedDisabled &&\n !focused &&\n 'hover:tw-border-[var(--interaction-border-hover)]',\n `ald-input-${getSizeType(size)}`,\n size === 'small' && 'tw-h-7 tw-text-xs',\n size === 'large' && 'tw-h-9 tw-text-sm',\n (size === 'middle' || !size) && 'tw-h-8 tw-text-sm',\n status === 'error' &&\n `ald-input-error tw-border-[var(--border-negative-strong)]`,\n status === 'warning' &&\n `ald-input-warning tw-border-[var(--border-warning-subtle)]`,\n mergedDisabled &&\n 'ald-input-disabled tw-cursor-not-allowed tw-bg-[var(--global-cool-gray-alpha-50)] tw-text-[var(--content-secondary)]',\n compactClasses,\n className,\n )}\n style={style}\n >\n {addonBefore && (\n <span className=\"ald-input-addon tw-flex tw-shrink-0 tw-items-center tw-self-stretch tw-border-r tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-neutral-subtle)] tw-px-3 tw-text-[var(--content-secondary)]\">\n {addonBefore}\n </span>\n )}\n {prefix && (\n <span className=\"ald-input-prefix tw-flex tw-items-center tw-pl-2 tw-text-[var(--content-secondary)]\">\n {prefix}\n </span>\n )}\n <input\n ref={inputRef}\n id={id}\n type={type || 'text'}\n className=\"tw-min-w-0 tw-flex-1 tw-border-0 tw-bg-transparent tw-px-2 tw-text-[var(--content-primary)] tw-text-inherit tw-outline-none\"\n value={currentValue}\n onChange={handleChange}\n onBlur={(e) => {\n setFocused(false);\n onBlur?.(e);\n }}\n onFocus={(e) => {\n setFocused(true);\n onFocus?.(e);\n }}\n onKeyDown={handleKeyDown}\n onCompositionStart={onCompositionStart}\n onCompositionEnd={onCompositionEnd}\n disabled={mergedDisabled}\n placeholder={placeholder}\n maxLength={maxLength}\n autoComplete=\"off\"\n autoFocus={autoFocus}\n readOnly={readOnly}\n spellCheck={false}\n />\n {showClearIcon && (\n <span\n className=\"ald-input-clear tw-flex tw-cursor-pointer tw-items-center tw-pr-1\"\n onClick={handleClear}\n >\n <CloseCircleFill size={16} color=\"var(--alias-colors-icon-subtle)\" />\n </span>\n )}\n {suffix && (\n <span className=\"ald-input-suffix tw-flex tw-items-center tw-pr-2 tw-text-[var(--content-secondary)]\">\n {suffix}\n </span>\n )}\n {countInfo && (\n <span className=\"ald-input-count tw-pr-2 tw-text-xs tw-text-[var(--content-tertiary)]\">\n {countInfo}\n </span>\n )}\n {addonAfter && (\n <span className=\"ald-input-addon tw-border-l tw-border-solid tw-border-[var(--border-default)] tw-px-2 tw-text-[var(--content-secondary)]\">\n {addonAfter}\n </span>\n )}\n </span>\n );\n});\n\nexport default Input;\n"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { default as React } from 'react';
|
|
|
2
2
|
import { TSize } from '../Input';
|
|
3
3
|
export type TextAreaRef = HTMLTextAreaElement;
|
|
4
4
|
export interface ITextAreaProps {
|
|
5
|
+
autoFocus?: boolean;
|
|
5
6
|
allowClear?: boolean;
|
|
6
7
|
autoSize?: boolean | {
|
|
7
8
|
minRows?: number;
|
|
@@ -31,6 +32,9 @@ export interface ITextAreaProps {
|
|
|
31
32
|
onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
32
33
|
onBlur?: React.FocusEventHandler<HTMLTextAreaElement>;
|
|
33
34
|
onFocus?: React.FocusEventHandler<HTMLTextAreaElement>;
|
|
35
|
+
onKeyDown?: React.KeyboardEventHandler<HTMLTextAreaElement>;
|
|
36
|
+
onCompositionStart?: React.CompositionEventHandler<HTMLTextAreaElement>;
|
|
37
|
+
onCompositionEnd?: React.CompositionEventHandler<HTMLTextAreaElement>;
|
|
34
38
|
style?: React.CSSProperties;
|
|
35
39
|
}
|
|
36
40
|
declare const _default: React.ForwardRefExoticComponent<ITextAreaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/Input/components/TextArea/index.tsx"],"sourcesContent":["import React, { forwardRef, useContext, useRef, useState } from 'react';\nimport DisabledContext from '../../../ConfigProvider/DisabledContext';\nimport SizeContext from '../../../ConfigProvider/sizeContext';\nimport { CloseCircleFill } from '../../../Icon';\nimport { cn } from '../../../lib/utils';\nimport { TSize, getSizeType } from '../Input';\n\nexport type TextAreaRef = HTMLTextAreaElement;\n\nexport interface ITextAreaProps {\n allowClear?: boolean;\n autoSize?: boolean | { minRows?: number; maxRows?: number };\n defaultValue?: string;\n maxLength?: number;\n showCount?:\n | boolean\n | { formatter: (args: { count: number; maxLength?: number }) => string };\n value?: string;\n onPressEnter?: React.KeyboardEventHandler<HTMLTextAreaElement>;\n onResize?: (size: { width: number; height: number }) => void;\n border?: boolean;\n bordered?: boolean;\n className?: string;\n size?: TSize;\n disabled?: boolean;\n placeholder?: string;\n rows?: number;\n onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\n onBlur?: React.FocusEventHandler<HTMLTextAreaElement>;\n onFocus?: React.FocusEventHandler<HTMLTextAreaElement>;\n style?: React.CSSProperties;\n}\n\nexport default forwardRef<TextAreaRef, ITextAreaProps>((props, ref) => {\n const {\n bordered,\n border,\n size: customSize,\n disabled,\n className = '',\n allowClear = false,\n value: controlledValue,\n defaultValue,\n onChange,\n onPressEnter,\n maxLength,\n showCount,\n autoSize,\n placeholder,\n rows,\n onBlur,\n onFocus,\n style,\n } = props;\n\n const isBordered = bordered ?? border ?? true;\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const size = customSize || contentSize || 'middle';\n const isControlled = 'value' in props;\n const [innerValue, setInnerValue] = useState(defaultValue ?? '');\n const currentValue = isControlled ? controlledValue ?? '' : innerValue;\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n React.useImperativeHandle(ref, () => textareaRef.current!);\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (!isControlled) setInnerValue(e.target.value);\n onChange?.(e);\n };\n\n const handleClear = () => {\n if (!isControlled) setInnerValue('');\n onChange?.({\n target: { value: '' },\n } as React.ChangeEvent<HTMLTextAreaElement>);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter') onPressEnter?.(e);\n };\n\n const minRows = typeof autoSize === 'object' ? autoSize.minRows : undefined;\n const maxRows = typeof autoSize === 'object' ? autoSize.maxRows : undefined;\n\n return (\n <div\n className={cn(\n 'ald-input ald-input-textarea tw-relative',\n `ald-input-textarea-${getSizeType(size)}`,\n isBordered &&\n 'tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-default)]',\n mergedDisabled && 'ald-input-disabled tw-opacity-50',\n className,\n )}\n style={style}\n >\n <textarea\n ref={textareaRef}\n className=\"tw-w-full tw-resize-y tw-border-0 tw-bg-transparent tw-px-3 tw-py-2 tw-text-sm tw-text-[var(--content-primary)] tw-outline-none\"\n value={currentValue}\n onChange={handleChange}\n onBlur={onBlur}\n onFocus={onFocus}\n onKeyDown={handleKeyDown}\n disabled={mergedDisabled}\n placeholder={placeholder}\n maxLength={maxLength}\n rows={rows || (minRows ?? 3)}\n spellCheck={false}\n autoComplete=\"off\"\n style={{\n minHeight: minRows ? `${minRows * 22}px` : undefined,\n maxHeight: maxRows ? `${maxRows * 22}px` : undefined,\n }}\n />\n {allowClear && currentValue && !mergedDisabled && (\n <span\n className=\"tw-absolute tw-right-2 tw-top-2 tw-cursor-pointer\"\n onClick={handleClear}\n >\n <CloseCircleFill size={16} color=\"var(--alias-colors-icon-subtle)\" />\n </span>\n )}\n {showCount && (\n <div className=\"tw-px-2 tw-pb-1 tw-text-right tw-text-xs tw-text-[var(--content-tertiary)]\">\n {typeof showCount === 'object'\n ? showCount.formatter({ count: currentValue.length, maxLength })\n : `${currentValue.length}${maxLength ? `/${maxLength}` : ''}`}\n </div>\n )}\n </div>\n );\n});\n"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/Input/components/TextArea/index.tsx"],"sourcesContent":["import React, { forwardRef, useContext, useRef, useState } from 'react';\nimport DisabledContext from '../../../ConfigProvider/DisabledContext';\nimport SizeContext from '../../../ConfigProvider/sizeContext';\nimport { CloseCircleFill } from '../../../Icon';\nimport { cn } from '../../../lib/utils';\nimport { TSize, getSizeType } from '../Input';\n\nexport type TextAreaRef = HTMLTextAreaElement;\n\nexport interface ITextAreaProps {\n autoFocus?: boolean;\n allowClear?: boolean;\n autoSize?: boolean | { minRows?: number; maxRows?: number };\n defaultValue?: string;\n maxLength?: number;\n showCount?:\n | boolean\n | { formatter: (args: { count: number; maxLength?: number }) => string };\n value?: string;\n onPressEnter?: React.KeyboardEventHandler<HTMLTextAreaElement>;\n onResize?: (size: { width: number; height: number }) => void;\n border?: boolean;\n bordered?: boolean;\n className?: string;\n size?: TSize;\n disabled?: boolean;\n placeholder?: string;\n rows?: number;\n onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\n onBlur?: React.FocusEventHandler<HTMLTextAreaElement>;\n onFocus?: React.FocusEventHandler<HTMLTextAreaElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLTextAreaElement>;\n onCompositionStart?: React.CompositionEventHandler<HTMLTextAreaElement>;\n onCompositionEnd?: React.CompositionEventHandler<HTMLTextAreaElement>;\n style?: React.CSSProperties;\n}\n\nexport default forwardRef<TextAreaRef, ITextAreaProps>((props, ref) => {\n const {\n bordered,\n border,\n size: customSize,\n disabled,\n className = '',\n allowClear = false,\n value: controlledValue,\n defaultValue,\n onChange,\n onPressEnter,\n maxLength,\n showCount,\n autoSize,\n placeholder,\n rows,\n onBlur,\n onFocus,\n style,\n } = props;\n\n const isBordered = bordered ?? border ?? true;\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const size = customSize || contentSize || 'middle';\n const isControlled = 'value' in props;\n const [innerValue, setInnerValue] = useState(defaultValue ?? '');\n const currentValue = isControlled ? controlledValue ?? '' : innerValue;\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n React.useImperativeHandle(ref, () => textareaRef.current!);\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (!isControlled) setInnerValue(e.target.value);\n onChange?.(e);\n };\n\n const handleClear = () => {\n if (!isControlled) setInnerValue('');\n onChange?.({\n target: { value: '' },\n } as React.ChangeEvent<HTMLTextAreaElement>);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter') onPressEnter?.(e);\n };\n\n const minRows = typeof autoSize === 'object' ? autoSize.minRows : undefined;\n const maxRows = typeof autoSize === 'object' ? autoSize.maxRows : undefined;\n\n return (\n <div\n className={cn(\n 'ald-input ald-input-textarea tw-relative',\n `ald-input-textarea-${getSizeType(size)}`,\n isBordered &&\n 'tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-default)]',\n mergedDisabled && 'ald-input-disabled tw-opacity-50',\n className,\n )}\n style={style}\n >\n <textarea\n ref={textareaRef}\n className=\"tw-w-full tw-resize-y tw-border-0 tw-bg-transparent tw-px-3 tw-py-2 tw-text-sm tw-text-[var(--content-primary)] tw-outline-none\"\n value={currentValue}\n onChange={handleChange}\n onBlur={onBlur}\n onFocus={onFocus}\n onKeyDown={handleKeyDown}\n disabled={mergedDisabled}\n placeholder={placeholder}\n maxLength={maxLength}\n rows={rows || (minRows ?? 3)}\n spellCheck={false}\n autoComplete=\"off\"\n style={{\n minHeight: minRows ? `${minRows * 22}px` : undefined,\n maxHeight: maxRows ? `${maxRows * 22}px` : undefined,\n }}\n />\n {allowClear && currentValue && !mergedDisabled && (\n <span\n className=\"tw-absolute tw-right-2 tw-top-2 tw-cursor-pointer\"\n onClick={handleClear}\n >\n <CloseCircleFill size={16} color=\"var(--alias-colors-icon-subtle)\" />\n </span>\n )}\n {showCount && (\n <div className=\"tw-px-2 tw-pb-1 tw-text-right tw-text-xs tw-text-[var(--content-tertiary)]\">\n {typeof showCount === 'object'\n ? showCount.formatter({ count: currentValue.length, maxLength })\n : `${currentValue.length}${maxLength ? `/${maxLength}` : ''}`}\n </div>\n )}\n </div>\n );\n});\n"],"mappings":";;;;;;;;AAqCA,IAAA,mBAAe,YAAyC,OAAO,QAAQ;CACrE,MAAM,EACJ,UACA,QACA,MAAM,YACN,UACA,YAAY,IACZ,aAAa,OACb,OAAO,iBACP,cACA,UACA,cACA,WACA,WACA,UACA,aACA,MACA,QACA,SACA,UACE;CAEJ,MAAM,aAAa,YAAY,UAAU;CAEzC,MAAM,kBAAkB,WAAW,gBAAgB;CACnD,MAAM,iBAAiB,YAAY;CAEnC,MAAM,cAAc,WAAW,YAAY;CAC3C,MAAM,OAAO,cAAc,eAAe;CAC1C,MAAM,eAAe,WAAW;CAChC,MAAM,CAAC,YAAY,iBAAiB,SAAS,gBAAgB,GAAG;CAChE,MAAM,eAAe,eAAe,mBAAmB,KAAK;CAC5D,MAAM,cAAc,OAA4B,KAAK;AAErD,OAAM,oBAAoB,WAAW,YAAY,QAAS;CAE1D,MAAM,gBAAgB,MAA8C;AAClE,MAAI,CAAC,aAAc,eAAc,EAAE,OAAO,MAAM;AAChD,aAAW,EAAE;;CAGf,MAAM,oBAAoB;AACxB,MAAI,CAAC,aAAc,eAAc,GAAG;AACpC,aAAW,EACT,QAAQ,EAAE,OAAO,IAAI,EACtB,CAA2C;;CAG9C,MAAM,iBAAiB,MAAgD;AACrE,MAAI,EAAE,QAAQ,QAAS,gBAAe,EAAE;;CAG1C,MAAM,UAAU,OAAO,aAAa,WAAW,SAAS,UAAU;CAClE,MAAM,UAAU,OAAO,aAAa,WAAW,SAAS,UAAU;AAElE,QACE,qBAAC,OAAD;EACE,WAAW,GACT,4CACA,sBAAsB,YAAY,KAAK,IACvC,cACE,+EACF,kBAAkB,oCAClB,UACD;EACM;YATT;GAWE,oBAAC,YAAD;IACE,KAAK;IACL,WAAU;IACV,OAAO;IACP,UAAU;IACF;IACC;IACT,WAAW;IACX,UAAU;IACG;IACF;IACX,MAAM,SAAS,WAAW;IAC1B,YAAY;IACZ,cAAa;IACb,OAAO;KACL,WAAW,UAAU,GAAG,UAAU,GAAG,MAAM;KAC3C,WAAW,UAAU,GAAG,UAAU,GAAG,MAAM;KAC5C;IACD,CAAA;GACD,cAAc,gBAAgB,CAAC,kBAC9B,oBAAC,QAAD;IACE,WAAU;IACV,SAAS;cAET,oBAAC,MAAD;KAAiB,MAAM;KAAI,OAAM;KAAoC,CAAA;IAChE,CAAA;GAER,aACC,oBAAC,OAAD;IAAK,WAAU;cACZ,OAAO,cAAc,WAClB,UAAU,UAAU;KAAE,OAAO,aAAa;KAAQ;KAAW,CAAC,GAC9D,GAAG,aAAa,SAAS,YAAY,IAAI,cAAc;IACvD,CAAA;GAEJ;;EAER"}
|
package/dist/Popover/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export interface PopoverProps {
|
|
|
8
8
|
defaultOpen?: boolean;
|
|
9
9
|
onOpenChange?: (open: boolean) => void;
|
|
10
10
|
trigger?: TriggerType | TriggerType[];
|
|
11
|
+
rootClassName?: string;
|
|
11
12
|
placement?: 'top' | 'bottom' | 'left' | 'right' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom';
|
|
12
13
|
overlayClassName?: string;
|
|
13
14
|
overlayStyle?: React.CSSProperties;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Popover/index.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover';\nimport React from 'react';\nimport { cn } from '../lib/utils';\n\ntype TriggerType = 'hover' | 'click' | 'focus';\n\nexport interface PopoverProps {\n content?: React.ReactNode;\n title?: React.ReactNode;\n children?: React.ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: TriggerType | TriggerType[];\n placement?:\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n overlayClassName?: string;\n overlayStyle?: React.CSSProperties;\n arrow?: boolean;\n mouseEnterDelay?: number;\n mouseLeaveDelay?: number;\n className?: string;\n style?: React.CSSProperties;\n getPopupContainer?: () => HTMLElement;\n zIndex?: number;\n}\n\nconst placementMap: Record<\n string,\n PopoverPrimitive.PopoverContentProps['side']\n> = {\n top: 'top',\n bottom: 'bottom',\n left: 'left',\n right: 'right',\n topLeft: 'top',\n topRight: 'top',\n bottomLeft: 'bottom',\n bottomRight: 'bottom',\n leftTop: 'left',\n leftBottom: 'left',\n rightTop: 'right',\n rightBottom: 'right',\n};\n\nconst alignMap: Record<string, PopoverPrimitive.PopoverContentProps['align']> =\n {\n topLeft: 'start',\n topRight: 'end',\n bottomLeft: 'start',\n bottomRight: 'end',\n leftTop: 'start',\n leftBottom: 'end',\n rightTop: 'start',\n rightBottom: 'end',\n };\n\nfunction normalizeTrigger(trigger: PopoverProps['trigger']): Set<TriggerType> {\n if (Array.isArray(trigger)) return new Set(trigger);\n if (trigger) return new Set([trigger]);\n return new Set<TriggerType>(['hover']);\n}\n\nfunction Popover(props: PopoverProps) {\n const {\n content,\n title,\n children,\n open,\n defaultOpen,\n onOpenChange,\n trigger = 'hover',\n placement = 'top',\n overlayClassName,\n overlayStyle,\n arrow = false,\n getPopupContainer,\n zIndex,\n } = props;\n\n const containerRef = React.useRef<HTMLElement | undefined>(\n getPopupContainer?.(),\n );\n\n const [hoverOpen, setHoverOpen] = React.useState(false);\n const triggers = normalizeTrigger(trigger);\n\n const isControlled = open !== undefined;\n const isHoverTrigger = triggers.has('hover');\n const isOpen = isControlled\n ? open\n : isHoverTrigger\n ? hoverOpen\n : triggers.size === 0\n ? false\n : undefined;\n\n const handleOpenChange = (val: boolean) => {\n if (!isControlled && isHoverTrigger) {\n setHoverOpen(val);\n }\n onOpenChange?.(val);\n };\n\n const side = placementMap[placement] || 'top';\n const align = alignMap[placement] || 'center';\n\n const triggerChild = React.isValidElement(children) ? (\n children\n ) : (\n <span>{children}</span>\n );\n\n if (triggers.size === 0 && !isControlled) {\n return <>{children}</>;\n }\n\n return (\n <PopoverPrimitive.Root\n open={isOpen}\n defaultOpen={defaultOpen}\n onOpenChange={handleOpenChange}\n >\n <PopoverPrimitive.Trigger asChild>\n {isHoverTrigger ? (\n <span\n onMouseEnter={() => handleOpenChange(true)}\n onMouseLeave={() => handleOpenChange(false)}\n >\n {triggerChild}\n </span>\n ) : (\n triggerChild\n )}\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={containerRef.current}>\n <PopoverPrimitive.Content\n side={side}\n align={align}\n sideOffset={4}\n className={cn(\n 'ald-popover tw-z-50 tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--alias-colors-bg-skeleton-subtler)] tw-p-3 tw-outline-none',\n 'tw-animate-in tw-fade-in-0 tw-zoom-in-95',\n overlayClassName,\n )}\n style={{\n boxShadow: 'var(--elevation-bottom-bottom-sm)',\n zIndex,\n ...overlayStyle,\n }}\n onMouseEnter={\n isHoverTrigger ? () => handleOpenChange(true) : undefined\n }\n onMouseLeave={\n isHoverTrigger ? () => handleOpenChange(false) : undefined\n }\n >\n {title && (\n <div className=\"ald-popover-title tw-mb-2 tw-text-sm tw-font-medium tw-text-[var(--content-primary)]\">\n {title}\n </div>\n )}\n {content && (\n <div className=\"ald-popover-inner-content\">{content}</div>\n )}\n {arrow && (\n <PopoverPrimitive.Arrow\n style={{ fill: 'var(--alias-colors-bg-skeleton-subtler, #fff)' }}\n />\n )}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n}\n\nexport default Popover;\n"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Popover/index.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover';\nimport React from 'react';\nimport { cn } from '../lib/utils';\n\ntype TriggerType = 'hover' | 'click' | 'focus';\n\nexport interface PopoverProps {\n content?: React.ReactNode;\n title?: React.ReactNode;\n children?: React.ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: TriggerType | TriggerType[];\n rootClassName?: string;\n placement?:\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n overlayClassName?: string;\n overlayStyle?: React.CSSProperties;\n arrow?: boolean;\n mouseEnterDelay?: number;\n mouseLeaveDelay?: number;\n className?: string;\n style?: React.CSSProperties;\n getPopupContainer?: () => HTMLElement;\n zIndex?: number;\n}\n\nconst placementMap: Record<\n string,\n PopoverPrimitive.PopoverContentProps['side']\n> = {\n top: 'top',\n bottom: 'bottom',\n left: 'left',\n right: 'right',\n topLeft: 'top',\n topRight: 'top',\n bottomLeft: 'bottom',\n bottomRight: 'bottom',\n leftTop: 'left',\n leftBottom: 'left',\n rightTop: 'right',\n rightBottom: 'right',\n};\n\nconst alignMap: Record<string, PopoverPrimitive.PopoverContentProps['align']> =\n {\n topLeft: 'start',\n topRight: 'end',\n bottomLeft: 'start',\n bottomRight: 'end',\n leftTop: 'start',\n leftBottom: 'end',\n rightTop: 'start',\n rightBottom: 'end',\n };\n\nfunction normalizeTrigger(trigger: PopoverProps['trigger']): Set<TriggerType> {\n if (Array.isArray(trigger)) return new Set(trigger);\n if (trigger) return new Set([trigger]);\n return new Set<TriggerType>(['hover']);\n}\n\nfunction Popover(props: PopoverProps) {\n const {\n content,\n title,\n children,\n open,\n defaultOpen,\n onOpenChange,\n trigger = 'hover',\n placement = 'top',\n overlayClassName,\n overlayStyle,\n arrow = false,\n getPopupContainer,\n zIndex,\n } = props;\n\n const containerRef = React.useRef<HTMLElement | undefined>(\n getPopupContainer?.(),\n );\n\n const [hoverOpen, setHoverOpen] = React.useState(false);\n const triggers = normalizeTrigger(trigger);\n\n const isControlled = open !== undefined;\n const isHoverTrigger = triggers.has('hover');\n const isOpen = isControlled\n ? open\n : isHoverTrigger\n ? hoverOpen\n : triggers.size === 0\n ? false\n : undefined;\n\n const handleOpenChange = (val: boolean) => {\n if (!isControlled && isHoverTrigger) {\n setHoverOpen(val);\n }\n onOpenChange?.(val);\n };\n\n const side = placementMap[placement] || 'top';\n const align = alignMap[placement] || 'center';\n\n const triggerChild = React.isValidElement(children) ? (\n children\n ) : (\n <span>{children}</span>\n );\n\n if (triggers.size === 0 && !isControlled) {\n return <>{children}</>;\n }\n\n return (\n <PopoverPrimitive.Root\n open={isOpen}\n defaultOpen={defaultOpen}\n onOpenChange={handleOpenChange}\n >\n <PopoverPrimitive.Trigger asChild>\n {isHoverTrigger ? (\n <span\n onMouseEnter={() => handleOpenChange(true)}\n onMouseLeave={() => handleOpenChange(false)}\n >\n {triggerChild}\n </span>\n ) : (\n triggerChild\n )}\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={containerRef.current}>\n <PopoverPrimitive.Content\n side={side}\n align={align}\n sideOffset={4}\n className={cn(\n 'ald-popover tw-z-50 tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--alias-colors-bg-skeleton-subtler)] tw-p-3 tw-outline-none',\n 'tw-animate-in tw-fade-in-0 tw-zoom-in-95',\n overlayClassName,\n )}\n style={{\n boxShadow: 'var(--elevation-bottom-bottom-sm)',\n zIndex,\n ...overlayStyle,\n }}\n onMouseEnter={\n isHoverTrigger ? () => handleOpenChange(true) : undefined\n }\n onMouseLeave={\n isHoverTrigger ? () => handleOpenChange(false) : undefined\n }\n >\n {title && (\n <div className=\"ald-popover-title tw-mb-2 tw-text-sm tw-font-medium tw-text-[var(--content-primary)]\">\n {title}\n </div>\n )}\n {content && (\n <div className=\"ald-popover-inner-content\">{content}</div>\n )}\n {arrow && (\n <PopoverPrimitive.Arrow\n style={{ fill: 'var(--alias-colors-bg-skeleton-subtler, #fff)' }}\n />\n )}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n}\n\nexport default Popover;\n"],"mappings":";;;;;AAuCA,IAAM,eAGF;CACF,KAAK;CACL,QAAQ;CACR,MAAM;CACN,OAAO;CACP,SAAS;CACT,UAAU;CACV,YAAY;CACZ,aAAa;CACb,SAAS;CACT,YAAY;CACZ,UAAU;CACV,aAAa;CACd;AAED,IAAM,WACJ;CACE,SAAS;CACT,UAAU;CACV,YAAY;CACZ,aAAa;CACb,SAAS;CACT,YAAY;CACZ,UAAU;CACV,aAAa;CACd;AAEH,SAAS,iBAAiB,SAAoD;AAC5E,KAAI,MAAM,QAAQ,QAAQ,CAAE,QAAO,IAAI,IAAI,QAAQ;AACnD,KAAI,QAAS,QAAO,IAAI,IAAI,CAAC,QAAQ,CAAC;AACtC,QAAO,IAAI,IAAiB,CAAC,QAAQ,CAAC;;AAGxC,SAAS,QAAQ,OAAqB;CACpC,MAAM,EACJ,SACA,OACA,UACA,MACA,aACA,cACA,UAAU,SACV,YAAY,OACZ,kBACA,cACA,QAAQ,OACR,mBACA,WACE;CAEJ,MAAM,eAAe,MAAM,OACzB,qBAAqB,CACtB;CAED,MAAM,CAAC,WAAW,gBAAgB,MAAM,SAAS,MAAM;CACvD,MAAM,WAAW,iBAAiB,QAAQ;CAE1C,MAAM,eAAe,SAAS;CAC9B,MAAM,iBAAiB,SAAS,IAAI,QAAQ;CAC5C,MAAM,SAAS,eACX,OACA,iBACA,YACA,SAAS,SAAS,IAClB,QACA;CAEJ,MAAM,oBAAoB,QAAiB;AACzC,MAAI,CAAC,gBAAgB,eACnB,cAAa,IAAI;AAEnB,iBAAe,IAAI;;CAGrB,MAAM,OAAO,aAAa,cAAc;CACxC,MAAM,QAAQ,SAAS,cAAc;CAErC,MAAM,eAAe,MAAM,eAAe,SAAS,GACjD,WAEA,oBAAC,QAAD,EAAO,UAAgB,CAAA;AAGzB,KAAI,SAAS,SAAS,KAAK,CAAC,aAC1B,QAAO,oBAAA,UAAA,EAAG,UAAY,CAAA;AAGxB,QACE,qBAAC,iBAAiB,MAAlB;EACE,MAAM;EACO;EACb,cAAc;YAHhB,CAKE,oBAAC,iBAAiB,SAAlB;GAA0B,SAAA;aACvB,iBACC,oBAAC,QAAD;IACE,oBAAoB,iBAAiB,KAAK;IAC1C,oBAAoB,iBAAiB,MAAM;cAE1C;IACI,CAAA,GAEP;GAEuB,CAAA,EAC3B,oBAAC,iBAAiB,QAAlB;GAAyB,WAAW,aAAa;aAC/C,qBAAC,iBAAiB,SAAlB;IACQ;IACC;IACP,YAAY;IACZ,WAAW,GACT,gLACA,4CACA,iBACD;IACD,OAAO;KACL,WAAW;KACX;KACA,GAAG;KACJ;IACD,cACE,uBAAuB,iBAAiB,KAAK,GAAG;IAElD,cACE,uBAAuB,iBAAiB,MAAM,GAAG;cAlBrD;KAqBG,SACC,oBAAC,OAAD;MAAK,WAAU;gBACZ;MACG,CAAA;KAEP,WACC,oBAAC,OAAD;MAAK,WAAU;gBAA6B;MAAc,CAAA;KAE3D,SACC,oBAAC,iBAAiB,OAAlB,EACE,OAAO,EAAE,MAAM,iDAAiD,EAChE,CAAA;KAEqB;;GACH,CAAA,CACJ"}
|
package/dist/Tabs/index.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ export interface ITabsProps {
|
|
|
38
38
|
style?: React.CSSProperties;
|
|
39
39
|
popupClassName?: string;
|
|
40
40
|
tabBarGutter?: number;
|
|
41
|
+
moreIcon?: React.ReactNode;
|
|
41
42
|
}
|
|
42
43
|
declare function Tabs(props: ITabsProps): import("react/jsx-runtime").JSX.Element;
|
|
43
44
|
declare namespace Tabs {
|
package/dist/Tabs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Tabs/index.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport { ChevronLeftLine, ChevronRightLine, CloseLightLine } from '../Icon';\nimport TabPane from './TabPane';\n\nexport type TabsSize = 'default' | 'small';\n\ninterface TabItem {\n key: string;\n label: React.ReactNode;\n children?: React.ReactNode;\n disabled?: boolean;\n closable?: boolean;\n icon?: React.ReactNode;\n forceRender?: boolean;\n className?: string;\n}\n\nexport interface ITabsProps {\n size?: TabsSize;\n activeKey?: string;\n defaultActiveKey?: string;\n onChange?: (activeKey: string) => void;\n onTabClick?: (activeKey: string, e: React.MouseEvent) => void;\n destroyInactiveTabPane?: boolean;\n centered?: boolean;\n adaptHeight?: boolean;\n tabPosition?: 'left' | 'right' | 'top' | 'bottom';\n className?: string;\n children?: React.ReactNode;\n headerBackgroundColor?: string;\n monospace?: boolean;\n padding?: boolean | number;\n compact?: boolean;\n hasDividing?: boolean;\n items?: TabItem[];\n type?: 'line' | 'card' | 'editable-card';\n tabBarExtraContent?:\n | React.ReactNode\n | { left?: React.ReactNode; right?: React.ReactNode };\n onEdit?: (\n targetKey: string | React.MouseEvent | React.KeyboardEvent,\n action: 'add' | 'remove',\n ) => void;\n hideAdd?: boolean;\n style?: React.CSSProperties;\n popupClassName?: string;\n tabBarGutter?: number;\n}\n\nexport default function Tabs(props: ITabsProps) {\n const {\n size,\n className,\n adaptHeight,\n style = {},\n monospace: propsMonospace,\n tabPosition = 'top',\n padding: propsPadding = false,\n compact,\n hasDividing = true,\n items,\n activeKey: controlledActiveKey,\n defaultActiveKey,\n onChange,\n onTabClick,\n destroyInactiveTabPane,\n tabBarExtraContent,\n headerBackgroundColor,\n children,\n type,\n onEdit,\n hideAdd,\n } = props;\n\n const isEditable = type === 'editable-card';\n const isCard = type === 'card' || type === 'editable-card';\n\n // Derive items from children if not provided\n const resolvedItems: TabItem[] = useMemo(() => {\n if (items) return items;\n return React.Children.toArray(children)\n .filter(React.isValidElement)\n .map((child: any) => ({\n key: child.key || child.props.key || '',\n label: child.props.tab,\n children: child.props.children,\n disabled: child.props.disabled,\n closable: child.props.closable,\n forceRender: child.props.forceRender,\n }));\n }, [items, children]);\n\n const firstKey = resolvedItems[0]?.key || '';\n const [innerActiveKey, setInnerActiveKey] = useState(\n defaultActiveKey || firstKey,\n );\n const activeKey =\n controlledActiveKey !== undefined ? controlledActiveKey : innerActiveKey;\n\n const handleTabClick = (key: string, e: React.MouseEvent) => {\n if (controlledActiveKey === undefined) {\n setInnerActiveKey(key);\n }\n onChange?.(key);\n onTabClick?.(key, e);\n };\n\n const handleRemove = (key: string, e: React.MouseEvent) => {\n e.stopPropagation();\n onEdit?.(key, 'remove');\n };\n\n const handleAdd = (e: React.MouseEvent) => {\n onEdit?.(e, 'add');\n };\n\n const monospace = tabPosition !== 'top' ? false : propsMonospace;\n const paddingVal = useMemo(() => {\n if (tabPosition !== 'top') return 0;\n if (typeof propsPadding === 'number') return propsPadding;\n if (typeof propsPadding === 'boolean' && propsPadding) return 20;\n return 0;\n }, [propsPadding, tabPosition]);\n\n const isVertical = tabPosition === 'left' || tabPosition === 'right';\n\n const extraLeft =\n tabBarExtraContent &&\n typeof tabBarExtraContent === 'object' &&\n 'left' in tabBarExtraContent\n ? tabBarExtraContent.left\n : null;\n const extraRight = tabBarExtraContent\n ? typeof tabBarExtraContent === 'object' && 'right' in tabBarExtraContent\n ? tabBarExtraContent.right\n : React.isValidElement(tabBarExtraContent)\n ? tabBarExtraContent\n : null\n : null;\n\n // Scroll state for overflow\n const navListRef = useRef<HTMLDivElement>(null);\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const checkScroll = useCallback(() => {\n const el = navListRef.current;\n if (!el || isVertical) {\n setCanScrollLeft(false);\n setCanScrollRight(false);\n return;\n }\n const { scrollLeft, scrollWidth, clientWidth } = el;\n setCanScrollLeft(scrollLeft > 1);\n setCanScrollRight(scrollLeft + clientWidth < scrollWidth - 1);\n }, [isVertical]);\n\n useEffect(() => {\n checkScroll();\n const el = navListRef.current;\n if (!el) return;\n // Use ResizeObserver to detect size changes\n let ro: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => checkScroll());\n ro.observe(el);\n }\n el.addEventListener('scroll', checkScroll, { passive: true });\n return () => {\n el.removeEventListener('scroll', checkScroll);\n ro?.disconnect();\n };\n }, [checkScroll, resolvedItems.length]);\n\n const scrollBy = (delta: number) => {\n const el = navListRef.current;\n if (el) {\n el.scrollBy({ left: delta, behavior: 'smooth' });\n }\n };\n\n const showScrollButtons = canScrollLeft || canScrollRight;\n\n return (\n <div\n className={cn(\n 'ald-tabs tw-flex',\n isVertical ? 'tw-flex-row' : 'tw-flex-col',\n adaptHeight && 'ald-adapt-height tw-h-full',\n size !== 'small' && 'ald-tabs-default',\n monospace && 'ald-tabs-monospace',\n compact && 'ald-tabs-compact',\n !hasDividing && 'ald-tabs-no-dividing',\n className,\n )}\n style={\n {\n ...style,\n '--header-bg-color': headerBackgroundColor,\n '--tabs-padding': `${paddingVal}px`,\n } as React.CSSProperties\n }\n >\n {/* Tab nav */}\n <div\n className={cn(\n 'ald-tabs-nav tw-flex tw-items-center',\n !isVertical &&\n hasDividing &&\n 'tw-mb-5 tw-border-0 tw-border-b tw-border-solid tw-border-b-[var(--global-cool-grey-100)]',\n !isVertical && compact && '!tw-mb-0',\n isVertical &&\n 'tw-flex-col tw-border-0 tw-border-r tw-border-solid tw-border-r-[var(--global-cool-grey-100)]',\n paddingVal && `tw-px-[${paddingVal}px]`,\n )}\n style={\n headerBackgroundColor\n ? { backgroundColor: headerBackgroundColor }\n : undefined\n }\n >\n {extraLeft}\n\n {/* Scroll left button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-transparent tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollLeft && 'tw-invisible',\n )}\n onClick={() => scrollBy(-200)}\n aria-label=\"Scroll tabs left\"\n >\n <ChevronLeftLine size={16} />\n </button>\n )}\n\n <div\n ref={navListRef}\n className={cn(\n 'ald-tabs-nav-list tw-flex tw-flex-1 tw-overflow-hidden',\n isVertical && 'tw-flex-col',\n monospace && '[&>*]:tw-flex-1',\n isCard ? 'tw-gap-1' : !monospace && 'tw-gap-8',\n )}\n style={\n !isVertical\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = activeKey === item.key;\n // For editable-card, closable defaults to true unless explicitly set to false\n const showClose = isEditable && item.closable !== false;\n\n return (\n <div\n key={item.key}\n className={cn(\n 'ald-tabs-tab tw-relative tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-gap-2 tw-whitespace-nowrap tw-transition-colors',\n // Card / editable-card styling\n isCard\n ? cn(\n 'tw-h-10 tw-rounded-t-[6px] tw-border tw-border-b-0 tw-border-solid tw-px-4 tw-text-sm tw-leading-5',\n 'tw-gap-sp-75',\n isActive\n ? 'tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--background-default)] tw-font-medium tw-text-[var(--alias-colors-text-selected)]'\n : 'tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--alias-colors-bg-skeleton-subtler)] tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit',\n )\n : cn(\n size === 'small'\n ? 'tw-py-2 tw-text-xs tw-leading-4'\n : 'tw-py-2.5 tw-text-sm tw-leading-5',\n monospace && 'tw-justify-center',\n isActive\n ? 'tw-font-medium tw-text-[var(--alias-colors-text-selected)]'\n : 'tw-font-medium tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit',\n ),\n item.disabled &&\n 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n )}\n onClick={\n item.disabled ? undefined : (e) => handleTabClick(item.key, e)\n }\n >\n {item.icon}\n <span>{item.label}</span>\n {/* Close button for editable-card */}\n {showClose && (\n <span\n className=\"ald-tabs-tab-remove tw-m-0 tw-grid tw-size-4 tw-cursor-pointer tw-place-items-center tw-p-0 tw-text-[var(--alias-colors-icon-subtle)] tw-transition-colors hover:tw-text-[var(--alias-colors-text-default)]\"\n onClick={(e) => handleRemove(item.key, e)}\n aria-label={`Remove ${item.label}`}\n >\n <CloseLightLine size={12} />\n </span>\n )}\n {/* Active indicator for non-card line tabs */}\n {!isCard && isActive && !isVertical && (\n <div className=\"tw-absolute tw-inset-x-0 tw--bottom-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]\" />\n )}\n {!isCard && isActive && isVertical && (\n <div className=\"tw-absolute tw-inset-y-0 tw--right-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]\" />\n )}\n </div>\n );\n })}\n </div>\n\n {/* Scroll right button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-transparent tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollRight && 'tw-invisible',\n )}\n onClick={() => scrollBy(200)}\n aria-label=\"Scroll tabs right\"\n >\n <ChevronRightLine size={16} />\n </button>\n )}\n\n {/* Add button for editable-card */}\n {isEditable && !hideAdd && (\n <button\n type=\"button\"\n className=\"ald-tabs-nav-add tw-ml-1 tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded tw-border tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-2 tw-py-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={handleAdd}\n aria-label=\"Add tab\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n )}\n\n {extraRight}\n </div>\n\n {/* Tab content */}\n <div className=\"ald-tabs-content tw-min-h-0 tw-flex-1\">\n {resolvedItems.map((item) => {\n const isActive = item.key === activeKey;\n if (!isActive && destroyInactiveTabPane && !item.forceRender) {\n return null;\n }\n return (\n <div\n key={item.key}\n className={cn(\n 'ald-tabs-tabpane',\n isActive ? 'tw-block' : 'tw-hidden',\n )}\n role=\"tabpanel\"\n >\n {item.children}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nTabs.TabPane = TabPane;\n"],"mappings":";;;;;;;;AAwDA,SAAwB,KAAK,OAAmB;CAC9C,MAAM,EACJ,MACA,WACA,aACA,QAAQ,EAAE,EACV,WAAW,gBACX,cAAc,OACd,SAAS,eAAe,OACxB,SACA,cAAc,MACd,OACA,WAAW,qBACX,kBACA,UACA,YACA,wBACA,oBACA,uBACA,UACA,MACA,QACA,YACE;CAEJ,MAAM,aAAa,SAAS;CAC5B,MAAM,SAAS,SAAS,UAAU,SAAS;CAG3C,MAAM,gBAA2B,cAAc;AAC7C,MAAI,MAAO,QAAO;AAClB,SAAO,MAAM,SAAS,QAAQ,SAAS,CACpC,OAAO,MAAM,eAAe,CAC5B,KAAK,WAAgB;GACpB,KAAK,MAAM,OAAO,MAAM,MAAM,OAAO;GACrC,OAAO,MAAM,MAAM;GACnB,UAAU,MAAM,MAAM;GACtB,UAAU,MAAM,MAAM;GACtB,UAAU,MAAM,MAAM;GACtB,aAAa,MAAM,MAAM;GAC1B,EAAE;IACJ,CAAC,OAAO,SAAS,CAAC;CAErB,MAAM,WAAW,cAAc,IAAI,OAAO;CAC1C,MAAM,CAAC,gBAAgB,qBAAqB,SAC1C,oBAAoB,SACrB;CACD,MAAM,YACJ,wBAAwB,SAAY,sBAAsB;CAE5D,MAAM,kBAAkB,KAAa,MAAwB;AAC3D,MAAI,wBAAwB,OAC1B,mBAAkB,IAAI;AAExB,aAAW,IAAI;AACf,eAAa,KAAK,EAAE;;CAGtB,MAAM,gBAAgB,KAAa,MAAwB;AACzD,IAAE,iBAAiB;AACnB,WAAS,KAAK,SAAS;;CAGzB,MAAM,aAAa,MAAwB;AACzC,WAAS,GAAG,MAAM;;CAGpB,MAAM,YAAY,gBAAgB,QAAQ,QAAQ;CAClD,MAAM,aAAa,cAAc;AAC/B,MAAI,gBAAgB,MAAO,QAAO;AAClC,MAAI,OAAO,iBAAiB,SAAU,QAAO;AAC7C,MAAI,OAAO,iBAAiB,aAAa,aAAc,QAAO;AAC9D,SAAO;IACN,CAAC,cAAc,YAAY,CAAC;CAE/B,MAAM,aAAa,gBAAgB,UAAU,gBAAgB;CAE7D,MAAM,YACJ,sBACA,OAAO,uBAAuB,YAC9B,UAAU,qBACN,mBAAmB,OACnB;CACN,MAAM,aAAa,qBACf,OAAO,uBAAuB,YAAY,WAAW,qBACnD,mBAAmB,QACnB,MAAM,eAAe,mBAAmB,GACxC,qBACA,OACF;CAGJ,MAAM,aAAa,OAAuB,KAAK;CAC/C,MAAM,CAAC,eAAe,oBAAoB,SAAS,MAAM;CACzD,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,MAAM;CAE3D,MAAM,cAAc,kBAAkB;EACpC,MAAM,KAAK,WAAW;AACtB,MAAI,CAAC,MAAM,YAAY;AACrB,oBAAiB,MAAM;AACvB,qBAAkB,MAAM;AACxB;;EAEF,MAAM,EAAE,YAAY,aAAa,gBAAgB;AACjD,mBAAiB,aAAa,EAAE;AAChC,oBAAkB,aAAa,cAAc,cAAc,EAAE;IAC5D,CAAC,WAAW,CAAC;AAEhB,iBAAgB;AACd,eAAa;EACb,MAAM,KAAK,WAAW;AACtB,MAAI,CAAC,GAAI;EAET,IAAI;AACJ,MAAI,OAAO,mBAAmB,aAAa;AACzC,QAAK,IAAI,qBAAqB,aAAa,CAAC;AAC5C,MAAG,QAAQ,GAAG;;AAEhB,KAAG,iBAAiB,UAAU,aAAa,EAAE,SAAS,MAAM,CAAC;AAC7D,eAAa;AACX,MAAG,oBAAoB,UAAU,YAAY;AAC7C,OAAI,YAAY;;IAEjB,CAAC,aAAa,cAAc,OAAO,CAAC;CAEvC,MAAM,YAAY,UAAkB;EAClC,MAAM,KAAK,WAAW;AACtB,MAAI,GACF,IAAG,SAAS;GAAE,MAAM;GAAO,UAAU;GAAU,CAAC;;CAIpD,MAAM,oBAAoB,iBAAiB;AAE3C,QACE,qBAAC,OAAD;EACE,WAAW,GACT,oBACA,aAAa,gBAAgB,eAC7B,eAAe,8BACf,SAAS,WAAW,oBACpB,aAAa,sBACb,WAAW,oBACX,CAAC,eAAe,wBAChB,UACD;EACD,OACE;GACE,GAAG;GACH,qBAAqB;GACrB,kBAAkB,GAAG,WAAW;GACjC;YAhBL,CAoBE,qBAAC,OAAD;GACE,WAAW,GACT,wCACA,CAAC,cACC,eACA,6FACF,CAAC,cAAc,WAAW,YAC1B,cACE,iGACF,cAAc,UAAU,WAAW,KACpC;GACD,OACE,wBACI,EAAE,iBAAiB,uBAAuB,GAC1C;aAdR;IAiBG;IAGA,qBAAqB,CAAC,cACrB,oBAAC,UAAD;KACE,MAAK;KACL,WAAW,GACT,oNACA,CAAC,iBAAiB,eACnB;KACD,eAAe,SAAS,KAAK;KAC7B,cAAW;eAEX,oBAAC,MAAD,EAAiB,MAAM,IAAM,CAAA;KACtB,CAAA;IAGX,oBAAC,OAAD;KACE,KAAK;KACL,WAAW,GACT,0DACA,cAAc,eACd,aAAa,mBACb,SAAS,aAAa,CAAC,aAAa,WACrC;KACD,OACE,CAAC,aACG;MAAE,gBAAgB;MAAQ,iBAAiB;MAAQ,GACnD;eAGL,cAAc,KAAK,SAAS;MAC3B,MAAM,WAAW,cAAc,KAAK;MAEpC,MAAM,YAAY,cAAc,KAAK,aAAa;AAElD,aACE,qBAAC,OAAD;OAEE,WAAW,GACT,qIAEA,SACI,GACE,sGACA,gBACA,WACI,gJACA,iKACL,GACD,GACE,SAAS,UACL,oCACA,qCACJ,aAAa,qBACb,WACI,+DACA,iFACL,EACL,KAAK,YACH,yDACH;OACD,SACE,KAAK,WAAW,UAAa,MAAM,eAAe,KAAK,KAAK,EAAE;iBA1BlE;QA6BG,KAAK;QACN,oBAAC,QAAD,EAAA,UAAO,KAAK,OAAa,CAAA;QAExB,aACC,oBAAC,QAAD;SACE,WAAU;SACV,UAAU,MAAM,aAAa,KAAK,KAAK,EAAE;SACzC,cAAY,UAAU,KAAK;mBAE3B,oBAAC,QAAD,EAAgB,MAAM,IAAM,CAAA;SACvB,CAAA;QAGR,CAAC,UAAU,YAAY,CAAC,cACvB,oBAAC,OAAD,EAAK,WAAU,kHAAmH,CAAA;QAEnI,CAAC,UAAU,YAAY,cACtB,oBAAC,OAAD,EAAK,WAAU,iHAAkH,CAAA;QAE/H;SA/CC,KAAK,IA+CN;OAER;KACE,CAAA;IAGL,qBAAqB,CAAC,cACrB,oBAAC,UAAD;KACE,MAAK;KACL,WAAW,GACT,oNACA,CAAC,kBAAkB,eACpB;KACD,eAAe,SAAS,IAAI;KAC5B,cAAW;eAEX,oBAAC,QAAD,EAAkB,MAAM,IAAM,CAAA;KACvB,CAAA;IAIV,cAAc,CAAC,WACd,oBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,SAAS;KACT,cAAW;eAEX,qBAAC,OAAD;MACE,OAAM;MACN,OAAM;MACN,QAAO;MACP,SAAQ;MACR,MAAK;MACL,QAAO;MACP,aAAY;MACZ,eAAc;MACd,gBAAe;gBATjB,CAWE,oBAAC,QAAD;OAAM,IAAG;OAAK,IAAG;OAAI,IAAG;OAAK,IAAG;OAAO,CAAA,EACvC,oBAAC,QAAD;OAAM,IAAG;OAAI,IAAG;OAAK,IAAG;OAAK,IAAG;OAAO,CAAA,CACnC;;KACC,CAAA;IAGV;IACG;MAGN,oBAAC,OAAD;GAAK,WAAU;aACZ,cAAc,KAAK,SAAS;IAC3B,MAAM,WAAW,KAAK,QAAQ;AAC9B,QAAI,CAAC,YAAY,0BAA0B,CAAC,KAAK,YAC/C,QAAO;AAET,WACE,oBAAC,OAAD;KAEE,WAAW,GACT,oBACA,WAAW,aAAa,YACzB;KACD,MAAK;eAEJ,KAAK;KACF,EARC,KAAK,IAQN;KAER;GACE,CAAA,CACF;;;AAIV,KAAK,UAAU"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Tabs/index.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport { ChevronLeftLine, ChevronRightLine, CloseLightLine } from '../Icon';\nimport TabPane from './TabPane';\n\nexport type TabsSize = 'default' | 'small';\n\ninterface TabItem {\n key: string;\n label: React.ReactNode;\n children?: React.ReactNode;\n disabled?: boolean;\n closable?: boolean;\n icon?: React.ReactNode;\n forceRender?: boolean;\n className?: string;\n}\n\nexport interface ITabsProps {\n size?: TabsSize;\n activeKey?: string;\n defaultActiveKey?: string;\n onChange?: (activeKey: string) => void;\n onTabClick?: (activeKey: string, e: React.MouseEvent) => void;\n destroyInactiveTabPane?: boolean;\n centered?: boolean;\n adaptHeight?: boolean;\n tabPosition?: 'left' | 'right' | 'top' | 'bottom';\n className?: string;\n children?: React.ReactNode;\n headerBackgroundColor?: string;\n monospace?: boolean;\n padding?: boolean | number;\n compact?: boolean;\n hasDividing?: boolean;\n items?: TabItem[];\n type?: 'line' | 'card' | 'editable-card';\n tabBarExtraContent?:\n | React.ReactNode\n | { left?: React.ReactNode; right?: React.ReactNode };\n onEdit?: (\n targetKey: string | React.MouseEvent | React.KeyboardEvent,\n action: 'add' | 'remove',\n ) => void;\n hideAdd?: boolean;\n style?: React.CSSProperties;\n popupClassName?: string;\n tabBarGutter?: number;\n moreIcon?: React.ReactNode;\n}\n\nexport default function Tabs(props: ITabsProps) {\n const {\n size,\n className,\n adaptHeight,\n style = {},\n monospace: propsMonospace,\n tabPosition = 'top',\n padding: propsPadding = false,\n compact,\n hasDividing = true,\n items,\n activeKey: controlledActiveKey,\n defaultActiveKey,\n onChange,\n onTabClick,\n destroyInactiveTabPane,\n tabBarExtraContent,\n headerBackgroundColor,\n children,\n type,\n onEdit,\n hideAdd,\n } = props;\n\n const isEditable = type === 'editable-card';\n const isCard = type === 'card' || type === 'editable-card';\n\n // Derive items from children if not provided\n const resolvedItems: TabItem[] = useMemo(() => {\n if (items) return items;\n return React.Children.toArray(children)\n .filter(React.isValidElement)\n .map((child: any) => ({\n key: child.key || child.props.key || '',\n label: child.props.tab,\n children: child.props.children,\n disabled: child.props.disabled,\n closable: child.props.closable,\n forceRender: child.props.forceRender,\n }));\n }, [items, children]);\n\n const firstKey = resolvedItems[0]?.key || '';\n const [innerActiveKey, setInnerActiveKey] = useState(\n defaultActiveKey || firstKey,\n );\n const activeKey =\n controlledActiveKey !== undefined ? controlledActiveKey : innerActiveKey;\n\n const handleTabClick = (key: string, e: React.MouseEvent) => {\n if (controlledActiveKey === undefined) {\n setInnerActiveKey(key);\n }\n onChange?.(key);\n onTabClick?.(key, e);\n };\n\n const handleRemove = (key: string, e: React.MouseEvent) => {\n e.stopPropagation();\n onEdit?.(key, 'remove');\n };\n\n const handleAdd = (e: React.MouseEvent) => {\n onEdit?.(e, 'add');\n };\n\n const monospace = tabPosition !== 'top' ? false : propsMonospace;\n const paddingVal = useMemo(() => {\n if (tabPosition !== 'top') return 0;\n if (typeof propsPadding === 'number') return propsPadding;\n if (typeof propsPadding === 'boolean' && propsPadding) return 20;\n return 0;\n }, [propsPadding, tabPosition]);\n\n const isVertical = tabPosition === 'left' || tabPosition === 'right';\n\n const extraLeft =\n tabBarExtraContent &&\n typeof tabBarExtraContent === 'object' &&\n 'left' in tabBarExtraContent\n ? tabBarExtraContent.left\n : null;\n const extraRight = tabBarExtraContent\n ? typeof tabBarExtraContent === 'object' && 'right' in tabBarExtraContent\n ? tabBarExtraContent.right\n : React.isValidElement(tabBarExtraContent)\n ? tabBarExtraContent\n : null\n : null;\n\n // Scroll state for overflow\n const navListRef = useRef<HTMLDivElement>(null);\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const checkScroll = useCallback(() => {\n const el = navListRef.current;\n if (!el || isVertical) {\n setCanScrollLeft(false);\n setCanScrollRight(false);\n return;\n }\n const { scrollLeft, scrollWidth, clientWidth } = el;\n setCanScrollLeft(scrollLeft > 1);\n setCanScrollRight(scrollLeft + clientWidth < scrollWidth - 1);\n }, [isVertical]);\n\n useEffect(() => {\n checkScroll();\n const el = navListRef.current;\n if (!el) return;\n // Use ResizeObserver to detect size changes\n let ro: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => checkScroll());\n ro.observe(el);\n }\n el.addEventListener('scroll', checkScroll, { passive: true });\n return () => {\n el.removeEventListener('scroll', checkScroll);\n ro?.disconnect();\n };\n }, [checkScroll, resolvedItems.length]);\n\n const scrollBy = (delta: number) => {\n const el = navListRef.current;\n if (el) {\n el.scrollBy({ left: delta, behavior: 'smooth' });\n }\n };\n\n const showScrollButtons = canScrollLeft || canScrollRight;\n\n return (\n <div\n className={cn(\n 'ald-tabs tw-flex',\n isVertical ? 'tw-flex-row' : 'tw-flex-col',\n adaptHeight && 'ald-adapt-height tw-h-full',\n size !== 'small' && 'ald-tabs-default',\n monospace && 'ald-tabs-monospace',\n compact && 'ald-tabs-compact',\n !hasDividing && 'ald-tabs-no-dividing',\n className,\n )}\n style={\n {\n ...style,\n '--header-bg-color': headerBackgroundColor,\n '--tabs-padding': `${paddingVal}px`,\n } as React.CSSProperties\n }\n >\n {/* Tab nav */}\n <div\n className={cn(\n 'ald-tabs-nav tw-flex tw-items-center',\n !isVertical &&\n hasDividing &&\n 'tw-mb-5 tw-border-0 tw-border-b tw-border-solid tw-border-b-[var(--global-cool-grey-100)]',\n !isVertical && compact && '!tw-mb-0',\n isVertical &&\n 'tw-flex-col tw-border-0 tw-border-r tw-border-solid tw-border-r-[var(--global-cool-grey-100)]',\n paddingVal && `tw-px-[${paddingVal}px]`,\n )}\n style={\n headerBackgroundColor\n ? { backgroundColor: headerBackgroundColor }\n : undefined\n }\n >\n {extraLeft}\n\n {/* Scroll left button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-transparent tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollLeft && 'tw-invisible',\n )}\n onClick={() => scrollBy(-200)}\n aria-label=\"Scroll tabs left\"\n >\n <ChevronLeftLine size={16} />\n </button>\n )}\n\n <div\n ref={navListRef}\n className={cn(\n 'ald-tabs-nav-list tw-flex tw-flex-1 tw-overflow-hidden',\n isVertical && 'tw-flex-col',\n monospace && '[&>*]:tw-flex-1',\n isCard ? 'tw-gap-1' : !monospace && 'tw-gap-8',\n )}\n style={\n !isVertical\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = activeKey === item.key;\n // For editable-card, closable defaults to true unless explicitly set to false\n const showClose = isEditable && item.closable !== false;\n\n return (\n <div\n key={item.key}\n className={cn(\n 'ald-tabs-tab tw-relative tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-gap-2 tw-whitespace-nowrap tw-transition-colors',\n // Card / editable-card styling\n isCard\n ? cn(\n 'tw-h-10 tw-rounded-t-[6px] tw-border tw-border-b-0 tw-border-solid tw-px-4 tw-text-sm tw-leading-5',\n 'tw-gap-sp-75',\n isActive\n ? 'tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--background-default)] tw-font-medium tw-text-[var(--alias-colors-text-selected)]'\n : 'tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--alias-colors-bg-skeleton-subtler)] tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit',\n )\n : cn(\n size === 'small'\n ? 'tw-py-2 tw-text-xs tw-leading-4'\n : 'tw-py-2.5 tw-text-sm tw-leading-5',\n monospace && 'tw-justify-center',\n isActive\n ? 'tw-font-medium tw-text-[var(--alias-colors-text-selected)]'\n : 'tw-font-medium tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit',\n ),\n item.disabled &&\n 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n )}\n onClick={\n item.disabled ? undefined : (e) => handleTabClick(item.key, e)\n }\n >\n {item.icon}\n <span>{item.label}</span>\n {/* Close button for editable-card */}\n {showClose && (\n <span\n className=\"ald-tabs-tab-remove tw-m-0 tw-grid tw-size-4 tw-cursor-pointer tw-place-items-center tw-p-0 tw-text-[var(--alias-colors-icon-subtle)] tw-transition-colors hover:tw-text-[var(--alias-colors-text-default)]\"\n onClick={(e) => handleRemove(item.key, e)}\n aria-label={`Remove ${item.label}`}\n >\n <CloseLightLine size={12} />\n </span>\n )}\n {/* Active indicator for non-card line tabs */}\n {!isCard && isActive && !isVertical && (\n <div className=\"tw-absolute tw-inset-x-0 tw--bottom-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]\" />\n )}\n {!isCard && isActive && isVertical && (\n <div className=\"tw-absolute tw-inset-y-0 tw--right-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]\" />\n )}\n </div>\n );\n })}\n </div>\n\n {/* Scroll right button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-transparent tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollRight && 'tw-invisible',\n )}\n onClick={() => scrollBy(200)}\n aria-label=\"Scroll tabs right\"\n >\n <ChevronRightLine size={16} />\n </button>\n )}\n\n {/* Add button for editable-card */}\n {isEditable && !hideAdd && (\n <button\n type=\"button\"\n className=\"ald-tabs-nav-add tw-ml-1 tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded tw-border tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-2 tw-py-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={handleAdd}\n aria-label=\"Add tab\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n )}\n\n {extraRight}\n </div>\n\n {/* Tab content */}\n <div className=\"ald-tabs-content tw-min-h-0 tw-flex-1\">\n {resolvedItems.map((item) => {\n const isActive = item.key === activeKey;\n if (!isActive && destroyInactiveTabPane && !item.forceRender) {\n return null;\n }\n return (\n <div\n key={item.key}\n className={cn(\n 'ald-tabs-tabpane',\n isActive ? 'tw-block' : 'tw-hidden',\n )}\n role=\"tabpanel\"\n >\n {item.children}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nTabs.TabPane = TabPane;\n"],"mappings":"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"}
|
package/dist/Upload/index.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export interface UploadProps<T = any> {
|
|
|
33
33
|
data?: Record<string, unknown> | ((file: RcFile | string | Blob) => Record<string, unknown>);
|
|
34
34
|
withCredentials?: boolean;
|
|
35
35
|
beforeUpload?: (file: RcFile, fileList: RcFile[]) => boolean | Promise<void | Blob | File>;
|
|
36
|
-
customRequest?: RcUploadProps['customRequest'];
|
|
36
|
+
customRequest?: RcUploadProps['customRequest'] | ((options: any) => any);
|
|
37
37
|
disabled?: boolean;
|
|
38
38
|
fileList?: UploadFile<T>[];
|
|
39
39
|
defaultFileList?: UploadFile<T>[];
|
package/dist/Upload/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Upload/index.tsx"],"sourcesContent":["import './upload.css';\n\nimport RcUpload from 'rc-upload';\nimport type {\n RcFile as RcUploadFile,\n UploadProgressEvent,\n UploadProps as RcUploadProps,\n} from 'rc-upload/es/interface';\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\nimport {\n CheckCircleFill,\n CloseCircleFill,\n CloseLightLine,\n EyeOnLine,\n LoadingLine,\n TrashLightLine,\n} from '../Icon';\nimport { cn } from '../lib/utils';\nimport Tooltip from '../Tooltip';\n\n// ---------------------------------------------------------------------------\n// Public types – preserved from the previous API surface\n// ---------------------------------------------------------------------------\n\nexport interface UploadFile<T = any> {\n uid: string;\n name: string;\n status?: 'uploading' | 'done' | 'error' | 'removed';\n url?: string;\n thumbUrl?: string;\n size?: number;\n type?: string;\n percent?: number;\n originFileObj?: RcFile;\n response?: T;\n error?: any;\n linkProps?: any;\n}\n\nexport type RcFile = RcUploadFile;\n\nexport interface UploadChangeParam<T = UploadFile> {\n file: T;\n fileList: T[];\n event?: UploadProgressEvent;\n}\n\nexport interface ShowUploadListInterface {\n showRemoveIcon?: boolean;\n showPreviewIcon?: boolean;\n showDownloadIcon?: boolean;\n}\n\nexport interface UploadProps<T = any> {\n accept?: string;\n action?: string | ((file: RcFile) => string | Promise<string>);\n method?: 'POST' | 'PUT' | 'PATCH' | 'post' | 'put' | 'patch';\n headers?: Record<string, string>;\n data?:\n | Record<string, unknown>\n | ((file: RcFile | string | Blob) => Record<string, unknown>);\n withCredentials?: boolean;\n beforeUpload?: (\n file: RcFile,\n fileList: RcFile[],\n ) => boolean | Promise<void | Blob | File>;\n customRequest?: RcUploadProps['customRequest'];\n disabled?: boolean;\n fileList?: UploadFile<T>[];\n defaultFileList?: UploadFile<T>[];\n maxCount?: number;\n multiple?: boolean;\n directory?: boolean;\n name?: string;\n listType?: 'text' | 'picture' | 'picture-card';\n showUploadList?: boolean | ShowUploadListInterface;\n onChange?: (info: UploadChangeParam<UploadFile<T>>) => void;\n onRemove?: (file: UploadFile<T>) => void | boolean | Promise<void | boolean>;\n onPreview?: (file: UploadFile<T>) => void;\n onDownload?: (file: UploadFile<T>) => void;\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n openFileDialogOnClick?: boolean;\n /** @deprecated Use `id` instead */\n prefixCls?: string;\n id?: string;\n}\n\nexport interface UploadListProps {\n items?: UploadFile[];\n listType?: 'text' | 'picture' | 'picture-card';\n showUploadList?: boolean | ShowUploadListInterface;\n onRemove?: (file: UploadFile) => void;\n onPreview?: (file: UploadFile) => void;\n onDownload?: (file: UploadFile) => void;\n disabled?: boolean;\n}\n\nexport interface DraggerProps extends UploadProps {\n height?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nlet fileUid = 0;\n\nfunction getUid(): string {\n fileUid += 1;\n return `ald-upload-${Date.now()}-${fileUid}`;\n}\n\nfunction fileToUploadFile(\n file: RcFile,\n status: UploadFile['status'] = 'uploading',\n): UploadFile {\n return {\n uid: file.uid ?? getUid(),\n name: file.name,\n size: file.size,\n type: file.type,\n status,\n percent: 0,\n originFileObj: file,\n };\n}\n\nfunction isImageUrl(file: UploadFile): boolean {\n if (file.type) return file.type.startsWith('image/');\n const ext = file.name?.split('.').pop()?.toLowerCase() ?? '';\n return ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'svg', 'ico'].includes(\n ext,\n );\n}\n\nfunction getThumbUrl(file: UploadFile): string | undefined {\n if (file.thumbUrl) return file.thumbUrl;\n if (file.url) return file.url;\n if (file.originFileObj && isImageUrl(file)) {\n try {\n return URL.createObjectURL(file.originFileObj);\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// UploadList\n// ---------------------------------------------------------------------------\n\nfunction UploadList({\n items = [],\n listType = 'text',\n showUploadList = true,\n onRemove,\n onPreview,\n disabled,\n}: UploadListProps) {\n if (!showUploadList || items.length === 0) return null;\n\n const showConfig: ShowUploadListInterface =\n typeof showUploadList === 'object'\n ? showUploadList\n : {\n showRemoveIcon: true,\n showPreviewIcon: true,\n showDownloadIcon: false,\n };\n\n const isPictureType = listType === 'picture' || listType === 'picture-card';\n\n return (\n <ul className={cn('ald-upload-list', `ald-upload-list-${listType}`)}>\n {items.map((file) => {\n const thumbUrl = isPictureType ? getThumbUrl(file) : undefined;\n\n return (\n <li\n key={file.uid}\n className={cn(\n 'ald-upload-list-item',\n `ald-upload-list-item-${file.status || 'done'}`,\n )}\n >\n {/* Thumbnail for picture types */}\n {isPictureType && (\n <div className=\"ald-upload-list-item-thumbnail\">\n {thumbUrl ? (\n <img src={thumbUrl} alt={file.name} />\n ) : (\n <div className=\"ald-upload-list-item-file-icon\">\n <FileIcon />\n </div>\n )}\n </div>\n )}\n\n {/* Status icon for text type */}\n {!isPictureType && (\n <span className=\"ald-upload-list-item-status-icon\">\n {file.status === 'uploading' && (\n <span className=\"ald-upload-list-item-loading-icon\">\n <LoadingLine style={{ fontSize: 14 }} />\n </span>\n )}\n {file.status === 'done' && (\n <CheckCircleFill style={{ fontSize: 14 }} />\n )}\n {file.status === 'error' && (\n <CloseCircleFill style={{ fontSize: 14 }} />\n )}\n </span>\n )}\n\n {/* File name */}\n <Tooltip title={file.name}>\n <span\n className=\"ald-upload-list-item-name\"\n onClick={() => onPreview?.(file)}\n style={onPreview ? { cursor: 'pointer' } : undefined}\n >\n {file.name}\n </span>\n </Tooltip>\n\n {/* Actions */}\n <span className=\"ald-upload-list-item-actions\">\n {showConfig.showPreviewIcon &&\n onPreview &&\n file.status === 'done' && (\n <button\n type=\"button\"\n className=\"ald-upload-list-item-action\"\n title=\"Preview\"\n onClick={() => onPreview(file)}\n >\n <EyeOnLine style={{ fontSize: 14 }} />\n </button>\n )}\n {showConfig.showRemoveIcon !== false && !disabled && (\n <button\n type=\"button\"\n className=\"ald-upload-list-item-action\"\n title=\"Remove\"\n onClick={() => onRemove?.(file)}\n >\n {listType === 'picture-card' ? (\n <TrashLightLine style={{ fontSize: 14 }} />\n ) : (\n <CloseLightLine style={{ fontSize: 14 }} />\n )}\n </button>\n )}\n </span>\n\n {/* Progress bar */}\n {file.status === 'uploading' && (\n <div className=\"ald-upload-list-item-progress\">\n <div\n className=\"ald-upload-list-item-progress-bar\"\n style={{ width: `${file.percent ?? 0}%` }}\n />\n </div>\n )}\n </li>\n );\n })}\n </ul>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Simple file icon SVG (inline to avoid extra dependency)\n// ---------------------------------------------------------------------------\n\nfunction FileIcon() {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Upload component\n// ---------------------------------------------------------------------------\n\nfunction Upload<T = any>(props: UploadProps<T>) {\n const {\n accept,\n action,\n method,\n headers,\n data,\n withCredentials,\n beforeUpload,\n customRequest,\n disabled = false,\n fileList: controlledFileList,\n defaultFileList,\n maxCount,\n multiple,\n directory,\n name = 'file',\n listType = 'text',\n showUploadList = true,\n onChange,\n onRemove,\n onPreview,\n onDownload,\n className,\n style,\n children,\n openFileDialogOnClick = true,\n id,\n } = props;\n\n const isControlled = controlledFileList !== undefined;\n const [internalFileList, setInternalFileList] = useState<UploadFile<T>[]>(\n defaultFileList ?? [],\n );\n\n const mergedFileList = isControlled ? controlledFileList! : internalFileList;\n\n // Keep a ref to latest list so callbacks always see fresh state\n const fileListRef = useRef(mergedFileList);\n fileListRef.current = mergedFileList;\n\n const rcUploadRef = useRef<any>(null);\n\n // ----- helpers to update state & fire onChange -----\n\n const updateFileList = useCallback(\n (newFile: UploadFile<T>, event?: UploadProgressEvent) => {\n const nextList = fileListRef.current.map((f) =>\n f.uid === newFile.uid ? newFile : f,\n );\n // If the file is new, append it\n if (!nextList.some((f) => f.uid === newFile.uid)) {\n nextList.push(newFile);\n }\n if (!isControlled) {\n setInternalFileList(nextList);\n }\n onChange?.({\n file: newFile,\n fileList: nextList,\n event,\n });\n },\n [isControlled, onChange],\n );\n\n // ----- rc-upload callback props -----\n\n const onBatchStart: RcUploadProps['onBatchStart'] = useCallback(\n (batchFileInfoList: { file: RcFile; parsedFile: any }[]) => {\n let nextList = [...fileListRef.current];\n\n for (const { file } of batchFileInfoList) {\n const uploadFile = fileToUploadFile(file, 'uploading') as UploadFile<T>;\n\n if (maxCount && nextList.length >= maxCount) {\n // replace if maxCount === 1, otherwise skip\n if (maxCount === 1) {\n nextList = [uploadFile];\n }\n continue;\n }\n nextList.push(uploadFile);\n }\n\n if (!isControlled) {\n setInternalFileList(nextList);\n }\n\n // Fire onChange for the first new file\n const firstNew = batchFileInfoList[0];\n if (firstNew) {\n const f = nextList.find((x) => x.uid === firstNew.file.uid);\n if (f) {\n onChange?.({ file: f, fileList: nextList });\n }\n }\n },\n [isControlled, maxCount, onChange],\n );\n\n const onRcProgress = useCallback(\n (event: UploadProgressEvent, file: RcFile) => {\n const target = fileListRef.current.find((f) => f.uid === file.uid);\n if (!target) return;\n const updated: UploadFile<T> = {\n ...target,\n status: 'uploading',\n percent: event.percent ?? 0,\n };\n updateFileList(updated, event);\n },\n [updateFileList],\n );\n\n const onRcSuccess = useCallback(\n (response: any, file: RcFile) => {\n const target = fileListRef.current.find((f) => f.uid === file.uid);\n if (!target) return;\n const updated: UploadFile<T> = {\n ...target,\n status: 'done',\n percent: 100,\n response,\n };\n updateFileList(updated);\n },\n [updateFileList],\n );\n\n const onRcError = useCallback(\n (error: Error, _ret: any, file: RcFile) => {\n const target = fileListRef.current.find((f) => f.uid === file.uid);\n if (!target) return;\n const updated: UploadFile<T> = {\n ...target,\n status: 'error',\n error,\n };\n updateFileList(updated);\n },\n [updateFileList],\n );\n\n // ----- remove handler -----\n\n const handleRemove = useCallback(\n async (file: UploadFile<T>) => {\n const result = await onRemove?.(file as any);\n if (result === false) return;\n const nextList = fileListRef.current.filter((f) => f.uid !== file.uid);\n if (!isControlled) {\n setInternalFileList(nextList);\n }\n const removedFile: UploadFile<T> = { ...file, status: 'removed' };\n onChange?.({ file: removedFile, fileList: nextList });\n },\n [isControlled, onChange, onRemove],\n );\n\n // ----- rc-upload props -----\n\n const rcUploadProps: RcUploadProps = useMemo(\n () => ({\n accept,\n action: action as RcUploadProps['action'],\n method,\n headers,\n data: data as RcUploadProps['data'],\n withCredentials,\n beforeUpload: beforeUpload as RcUploadProps['beforeUpload'],\n customRequest,\n disabled,\n multiple,\n directory,\n name,\n openFileDialogOnClick,\n id,\n prefixCls: 'ald-upload',\n onBatchStart,\n onProgress: onRcProgress,\n onSuccess: onRcSuccess,\n onError: onRcError,\n }),\n [\n accept,\n action,\n method,\n headers,\n data,\n withCredentials,\n beforeUpload,\n customRequest,\n disabled,\n multiple,\n directory,\n name,\n openFileDialogOnClick,\n id,\n onBatchStart,\n onRcProgress,\n onRcSuccess,\n onRcError,\n ],\n );\n\n const isPictureCard = listType === 'picture-card';\n\n return (\n <span\n className={cn(\n 'ald-upload',\n { 'ald-upload-disabled': disabled },\n className,\n )}\n style={style}\n >\n {isPictureCard ? (\n // picture-card: render list first, then the upload trigger\n <>\n <UploadList\n items={mergedFileList as UploadFile[]}\n listType={listType}\n showUploadList={showUploadList}\n onRemove={handleRemove as any}\n onPreview={onPreview as any}\n onDownload={onDownload as any}\n disabled={disabled}\n />\n {(!maxCount || mergedFileList.length < maxCount) && (\n <RcUpload {...rcUploadProps} ref={rcUploadRef}>\n <div className=\"ald-upload-select\">{children}</div>\n </RcUpload>\n )}\n </>\n ) : (\n // text / picture: render trigger then list\n <>\n <RcUpload {...rcUploadProps} ref={rcUploadRef}>\n <div className=\"ald-upload-select\">{children}</div>\n </RcUpload>\n <UploadList\n items={mergedFileList as UploadFile[]}\n listType={listType}\n showUploadList={showUploadList}\n onRemove={handleRemove as any}\n onPreview={onPreview as any}\n onDownload={onDownload as any}\n disabled={disabled}\n />\n </>\n )}\n </span>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Dragger sub-component\n// ---------------------------------------------------------------------------\n\nfunction Dragger(props: DraggerProps) {\n const { height, style, disabled, className, children, ...restProps } = props;\n const [dragOver, setDragOver] = useState(false);\n\n const mergedStyle: React.CSSProperties = {\n ...style,\n ...(height !== null && height !== undefined ? { height } : {}),\n };\n\n return (\n <Upload\n {...restProps}\n disabled={disabled}\n className={cn('ald-upload-dragger-wrapper', className)}\n style={mergedStyle}\n >\n <div\n className={cn('ald-upload-dragger', {\n 'ald-upload-drag-hover': dragOver,\n 'ald-upload-disabled': disabled,\n })}\n onDragOver={(e) => {\n e.preventDefault();\n if (!disabled) setDragOver(true);\n }}\n onDragLeave={() => setDragOver(false)}\n onDrop={() => setDragOver(false)}\n >\n {children}\n </div>\n </Upload>\n );\n}\n\nUpload.Dragger = Dragger;\n\nexport default Upload as typeof Upload & { Dragger: typeof Dragger };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Upload/index.tsx"],"sourcesContent":["import './upload.css';\n\nimport RcUpload from 'rc-upload';\nimport type {\n RcFile as RcUploadFile,\n UploadProgressEvent,\n UploadProps as RcUploadProps,\n} from 'rc-upload/es/interface';\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\nimport {\n CheckCircleFill,\n CloseCircleFill,\n CloseLightLine,\n EyeOnLine,\n LoadingLine,\n TrashLightLine,\n} from '../Icon';\nimport { cn } from '../lib/utils';\nimport Tooltip from '../Tooltip';\n\n// ---------------------------------------------------------------------------\n// Public types – preserved from the previous API surface\n// ---------------------------------------------------------------------------\n\nexport interface UploadFile<T = any> {\n uid: string;\n name: string;\n status?: 'uploading' | 'done' | 'error' | 'removed';\n url?: string;\n thumbUrl?: string;\n size?: number;\n type?: string;\n percent?: number;\n originFileObj?: RcFile;\n response?: T;\n error?: any;\n linkProps?: any;\n}\n\nexport type RcFile = RcUploadFile;\n\nexport interface UploadChangeParam<T = UploadFile> {\n file: T;\n fileList: T[];\n event?: UploadProgressEvent;\n}\n\nexport interface ShowUploadListInterface {\n showRemoveIcon?: boolean;\n showPreviewIcon?: boolean;\n showDownloadIcon?: boolean;\n}\n\nexport interface UploadProps<T = any> {\n accept?: string;\n action?: string | ((file: RcFile) => string | Promise<string>);\n method?: 'POST' | 'PUT' | 'PATCH' | 'post' | 'put' | 'patch';\n headers?: Record<string, string>;\n data?:\n | Record<string, unknown>\n | ((file: RcFile | string | Blob) => Record<string, unknown>);\n withCredentials?: boolean;\n beforeUpload?: (\n file: RcFile,\n fileList: RcFile[],\n ) => boolean | Promise<void | Blob | File>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n customRequest?: RcUploadProps['customRequest'] | ((options: any) => any);\n disabled?: boolean;\n fileList?: UploadFile<T>[];\n defaultFileList?: UploadFile<T>[];\n maxCount?: number;\n multiple?: boolean;\n directory?: boolean;\n name?: string;\n listType?: 'text' | 'picture' | 'picture-card';\n showUploadList?: boolean | ShowUploadListInterface;\n onChange?: (info: UploadChangeParam<UploadFile<T>>) => void;\n onRemove?: (file: UploadFile<T>) => void | boolean | Promise<void | boolean>;\n onPreview?: (file: UploadFile<T>) => void;\n onDownload?: (file: UploadFile<T>) => void;\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n openFileDialogOnClick?: boolean;\n /** @deprecated Use `id` instead */\n prefixCls?: string;\n id?: string;\n}\n\nexport interface UploadListProps {\n items?: UploadFile[];\n listType?: 'text' | 'picture' | 'picture-card';\n showUploadList?: boolean | ShowUploadListInterface;\n onRemove?: (file: UploadFile) => void;\n onPreview?: (file: UploadFile) => void;\n onDownload?: (file: UploadFile) => void;\n disabled?: boolean;\n}\n\nexport interface DraggerProps extends UploadProps {\n height?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nlet fileUid = 0;\n\nfunction getUid(): string {\n fileUid += 1;\n return `ald-upload-${Date.now()}-${fileUid}`;\n}\n\nfunction fileToUploadFile(\n file: RcFile,\n status: UploadFile['status'] = 'uploading',\n): UploadFile {\n return {\n uid: file.uid ?? getUid(),\n name: file.name,\n size: file.size,\n type: file.type,\n status,\n percent: 0,\n originFileObj: file,\n };\n}\n\nfunction isImageUrl(file: UploadFile): boolean {\n if (file.type) return file.type.startsWith('image/');\n const ext = file.name?.split('.').pop()?.toLowerCase() ?? '';\n return ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'svg', 'ico'].includes(\n ext,\n );\n}\n\nfunction getThumbUrl(file: UploadFile): string | undefined {\n if (file.thumbUrl) return file.thumbUrl;\n if (file.url) return file.url;\n if (file.originFileObj && isImageUrl(file)) {\n try {\n return URL.createObjectURL(file.originFileObj);\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// UploadList\n// ---------------------------------------------------------------------------\n\nfunction UploadList({\n items = [],\n listType = 'text',\n showUploadList = true,\n onRemove,\n onPreview,\n disabled,\n}: UploadListProps) {\n if (!showUploadList || items.length === 0) return null;\n\n const showConfig: ShowUploadListInterface =\n typeof showUploadList === 'object'\n ? showUploadList\n : {\n showRemoveIcon: true,\n showPreviewIcon: true,\n showDownloadIcon: false,\n };\n\n const isPictureType = listType === 'picture' || listType === 'picture-card';\n\n return (\n <ul className={cn('ald-upload-list', `ald-upload-list-${listType}`)}>\n {items.map((file) => {\n const thumbUrl = isPictureType ? getThumbUrl(file) : undefined;\n\n return (\n <li\n key={file.uid}\n className={cn(\n 'ald-upload-list-item',\n `ald-upload-list-item-${file.status || 'done'}`,\n )}\n >\n {/* Thumbnail for picture types */}\n {isPictureType && (\n <div className=\"ald-upload-list-item-thumbnail\">\n {thumbUrl ? (\n <img src={thumbUrl} alt={file.name} />\n ) : (\n <div className=\"ald-upload-list-item-file-icon\">\n <FileIcon />\n </div>\n )}\n </div>\n )}\n\n {/* Status icon for text type */}\n {!isPictureType && (\n <span className=\"ald-upload-list-item-status-icon\">\n {file.status === 'uploading' && (\n <span className=\"ald-upload-list-item-loading-icon\">\n <LoadingLine style={{ fontSize: 14 }} />\n </span>\n )}\n {file.status === 'done' && (\n <CheckCircleFill style={{ fontSize: 14 }} />\n )}\n {file.status === 'error' && (\n <CloseCircleFill style={{ fontSize: 14 }} />\n )}\n </span>\n )}\n\n {/* File name */}\n <Tooltip title={file.name}>\n <span\n className=\"ald-upload-list-item-name\"\n onClick={() => onPreview?.(file)}\n style={onPreview ? { cursor: 'pointer' } : undefined}\n >\n {file.name}\n </span>\n </Tooltip>\n\n {/* Actions */}\n <span className=\"ald-upload-list-item-actions\">\n {showConfig.showPreviewIcon &&\n onPreview &&\n file.status === 'done' && (\n <button\n type=\"button\"\n className=\"ald-upload-list-item-action\"\n title=\"Preview\"\n onClick={() => onPreview(file)}\n >\n <EyeOnLine style={{ fontSize: 14 }} />\n </button>\n )}\n {showConfig.showRemoveIcon !== false && !disabled && (\n <button\n type=\"button\"\n className=\"ald-upload-list-item-action\"\n title=\"Remove\"\n onClick={() => onRemove?.(file)}\n >\n {listType === 'picture-card' ? (\n <TrashLightLine style={{ fontSize: 14 }} />\n ) : (\n <CloseLightLine style={{ fontSize: 14 }} />\n )}\n </button>\n )}\n </span>\n\n {/* Progress bar */}\n {file.status === 'uploading' && (\n <div className=\"ald-upload-list-item-progress\">\n <div\n className=\"ald-upload-list-item-progress-bar\"\n style={{ width: `${file.percent ?? 0}%` }}\n />\n </div>\n )}\n </li>\n );\n })}\n </ul>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Simple file icon SVG (inline to avoid extra dependency)\n// ---------------------------------------------------------------------------\n\nfunction FileIcon() {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Upload component\n// ---------------------------------------------------------------------------\n\nfunction Upload<T = any>(props: UploadProps<T>) {\n const {\n accept,\n action,\n method,\n headers,\n data,\n withCredentials,\n beforeUpload,\n customRequest,\n disabled = false,\n fileList: controlledFileList,\n defaultFileList,\n maxCount,\n multiple,\n directory,\n name = 'file',\n listType = 'text',\n showUploadList = true,\n onChange,\n onRemove,\n onPreview,\n onDownload,\n className,\n style,\n children,\n openFileDialogOnClick = true,\n id,\n } = props;\n\n const isControlled = controlledFileList !== undefined;\n const [internalFileList, setInternalFileList] = useState<UploadFile<T>[]>(\n defaultFileList ?? [],\n );\n\n const mergedFileList = isControlled ? controlledFileList! : internalFileList;\n\n // Keep a ref to latest list so callbacks always see fresh state\n const fileListRef = useRef(mergedFileList);\n fileListRef.current = mergedFileList;\n\n const rcUploadRef = useRef<any>(null);\n\n // ----- helpers to update state & fire onChange -----\n\n const updateFileList = useCallback(\n (newFile: UploadFile<T>, event?: UploadProgressEvent) => {\n const nextList = fileListRef.current.map((f) =>\n f.uid === newFile.uid ? newFile : f,\n );\n // If the file is new, append it\n if (!nextList.some((f) => f.uid === newFile.uid)) {\n nextList.push(newFile);\n }\n if (!isControlled) {\n setInternalFileList(nextList);\n }\n onChange?.({\n file: newFile,\n fileList: nextList,\n event,\n });\n },\n [isControlled, onChange],\n );\n\n // ----- rc-upload callback props -----\n\n const onBatchStart: RcUploadProps['onBatchStart'] = useCallback(\n (batchFileInfoList: { file: RcFile; parsedFile: any }[]) => {\n let nextList = [...fileListRef.current];\n\n for (const { file } of batchFileInfoList) {\n const uploadFile = fileToUploadFile(file, 'uploading') as UploadFile<T>;\n\n if (maxCount && nextList.length >= maxCount) {\n // replace if maxCount === 1, otherwise skip\n if (maxCount === 1) {\n nextList = [uploadFile];\n }\n continue;\n }\n nextList.push(uploadFile);\n }\n\n if (!isControlled) {\n setInternalFileList(nextList);\n }\n\n // Fire onChange for the first new file\n const firstNew = batchFileInfoList[0];\n if (firstNew) {\n const f = nextList.find((x) => x.uid === firstNew.file.uid);\n if (f) {\n onChange?.({ file: f, fileList: nextList });\n }\n }\n },\n [isControlled, maxCount, onChange],\n );\n\n const onRcProgress = useCallback(\n (event: UploadProgressEvent, file: RcFile) => {\n const target = fileListRef.current.find((f) => f.uid === file.uid);\n if (!target) return;\n const updated: UploadFile<T> = {\n ...target,\n status: 'uploading',\n percent: event.percent ?? 0,\n };\n updateFileList(updated, event);\n },\n [updateFileList],\n );\n\n const onRcSuccess = useCallback(\n (response: any, file: RcFile) => {\n const target = fileListRef.current.find((f) => f.uid === file.uid);\n if (!target) return;\n const updated: UploadFile<T> = {\n ...target,\n status: 'done',\n percent: 100,\n response,\n };\n updateFileList(updated);\n },\n [updateFileList],\n );\n\n const onRcError = useCallback(\n (error: Error, _ret: any, file: RcFile) => {\n const target = fileListRef.current.find((f) => f.uid === file.uid);\n if (!target) return;\n const updated: UploadFile<T> = {\n ...target,\n status: 'error',\n error,\n };\n updateFileList(updated);\n },\n [updateFileList],\n );\n\n // ----- remove handler -----\n\n const handleRemove = useCallback(\n async (file: UploadFile<T>) => {\n const result = await onRemove?.(file as any);\n if (result === false) return;\n const nextList = fileListRef.current.filter((f) => f.uid !== file.uid);\n if (!isControlled) {\n setInternalFileList(nextList);\n }\n const removedFile: UploadFile<T> = { ...file, status: 'removed' };\n onChange?.({ file: removedFile, fileList: nextList });\n },\n [isControlled, onChange, onRemove],\n );\n\n // ----- rc-upload props -----\n\n const rcUploadProps: RcUploadProps = useMemo(\n () => ({\n accept,\n action: action as RcUploadProps['action'],\n method,\n headers,\n data: data as RcUploadProps['data'],\n withCredentials,\n beforeUpload: beforeUpload as RcUploadProps['beforeUpload'],\n customRequest,\n disabled,\n multiple,\n directory,\n name,\n openFileDialogOnClick,\n id,\n prefixCls: 'ald-upload',\n onBatchStart,\n onProgress: onRcProgress,\n onSuccess: onRcSuccess,\n onError: onRcError,\n }),\n [\n accept,\n action,\n method,\n headers,\n data,\n withCredentials,\n beforeUpload,\n customRequest,\n disabled,\n multiple,\n directory,\n name,\n openFileDialogOnClick,\n id,\n onBatchStart,\n onRcProgress,\n onRcSuccess,\n onRcError,\n ],\n );\n\n const isPictureCard = listType === 'picture-card';\n\n return (\n <span\n className={cn(\n 'ald-upload',\n { 'ald-upload-disabled': disabled },\n className,\n )}\n style={style}\n >\n {isPictureCard ? (\n // picture-card: render list first, then the upload trigger\n <>\n <UploadList\n items={mergedFileList as UploadFile[]}\n listType={listType}\n showUploadList={showUploadList}\n onRemove={handleRemove as any}\n onPreview={onPreview as any}\n onDownload={onDownload as any}\n disabled={disabled}\n />\n {(!maxCount || mergedFileList.length < maxCount) && (\n <RcUpload {...rcUploadProps} ref={rcUploadRef}>\n <div className=\"ald-upload-select\">{children}</div>\n </RcUpload>\n )}\n </>\n ) : (\n // text / picture: render trigger then list\n <>\n <RcUpload {...rcUploadProps} ref={rcUploadRef}>\n <div className=\"ald-upload-select\">{children}</div>\n </RcUpload>\n <UploadList\n items={mergedFileList as UploadFile[]}\n listType={listType}\n showUploadList={showUploadList}\n onRemove={handleRemove as any}\n onPreview={onPreview as any}\n onDownload={onDownload as any}\n disabled={disabled}\n />\n </>\n )}\n </span>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Dragger sub-component\n// ---------------------------------------------------------------------------\n\nfunction Dragger(props: DraggerProps) {\n const { height, style, disabled, className, children, ...restProps } = props;\n const [dragOver, setDragOver] = useState(false);\n\n const mergedStyle: React.CSSProperties = {\n ...style,\n ...(height !== null && height !== undefined ? { height } : {}),\n };\n\n return (\n <Upload\n {...restProps}\n disabled={disabled}\n className={cn('ald-upload-dragger-wrapper', className)}\n style={mergedStyle}\n >\n <div\n className={cn('ald-upload-dragger', {\n 'ald-upload-drag-hover': dragOver,\n 'ald-upload-disabled': disabled,\n })}\n onDragOver={(e) => {\n e.preventDefault();\n if (!disabled) setDragOver(true);\n }}\n onDragLeave={() => setDragOver(false)}\n onDrop={() => setDragOver(false)}\n >\n {children}\n </div>\n </Upload>\n );\n}\n\nUpload.Dragger = Dragger;\n\nexport default Upload as typeof Upload & { Dragger: typeof Dragger };\n"],"mappings":"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"}
|