@aloudata/aloudata-design 3.1.0 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AProgress/index.js +10 -0
- package/dist/AProgress/index.js.map +1 -1
- package/dist/Alert/index.js +3 -1
- package/dist/Alert/index.js.map +1 -1
- package/dist/Badge/index.js +37 -11
- package/dist/Badge/index.js.map +1 -1
- package/dist/Breadcrumb/index.js +12 -2
- package/dist/Breadcrumb/index.js.map +1 -1
- package/dist/Button/index.d.ts +1 -1
- package/dist/Button/index.js +20 -6
- package/dist/Button/index.js.map +1 -1
- package/dist/Card/index.js +1 -1
- package/dist/Card/index.js.map +1 -1
- package/dist/Carousel/index.js +9 -1
- package/dist/Carousel/index.js.map +1 -1
- package/dist/Checkbox/index.js +17 -2
- package/dist/Checkbox/index.js.map +1 -1
- package/dist/Checkbox/type.d.ts +10 -2
- package/dist/ColorPicker/index.js +112 -46
- package/dist/ColorPicker/index.js.map +1 -1
- package/dist/DataPreviewTable/components/Body/Cell.d.ts +2 -0
- package/dist/DataPreviewTable/components/Body/Cell.js +9 -1
- package/dist/DataPreviewTable/components/Body/Cell.js.map +1 -1
- package/dist/DataPreviewTable/components/Body/index.d.ts +1 -0
- package/dist/DataPreviewTable/components/Body/index.js +35 -23
- package/dist/DataPreviewTable/components/Body/index.js.map +1 -1
- package/dist/DataPreviewTable/components/Header/index.d.ts +1 -0
- package/dist/DataPreviewTable/components/Header/index.js +36 -28
- package/dist/DataPreviewTable/components/Header/index.js.map +1 -1
- package/dist/DataPreviewTable/index.js +19 -2
- package/dist/DataPreviewTable/index.js.map +1 -1
- package/dist/Drawer/index.d.ts +4 -0
- package/dist/Drawer/index.js +93 -79
- package/dist/Drawer/index.js.map +1 -1
- package/dist/Dropdown/index.d.ts +1 -1
- package/dist/Dropdown/index.js +64 -13
- package/dist/Dropdown/index.js.map +1 -1
- package/dist/Form/FormItemContext.d.ts +1 -1
- package/dist/Form/FormItemContext.js.map +1 -1
- package/dist/Form/index.js +50 -7
- package/dist/Form/index.js.map +1 -1
- package/dist/IconButton/index.d.ts +2 -2
- package/dist/IconButton/index.js +9 -3
- package/dist/IconButton/index.js.map +1 -1
- package/dist/Input/components/Input/index.js +18 -8
- package/dist/Input/components/Input/index.js.map +1 -1
- package/dist/Input/components/TextArea/index.js +18 -7
- package/dist/Input/components/TextArea/index.js.map +1 -1
- package/dist/Input/privateSemanticOwner.d.ts +2 -0
- package/dist/Input/privateSemanticOwner.js +1 -0
- package/dist/InputNumber/index.js +16 -9
- package/dist/InputNumber/index.js.map +1 -1
- package/dist/InputNumber/type.d.ts +2 -2
- package/dist/LogicTree/components/LogicItem/index.d.ts +2 -1
- package/dist/LogicTree/components/LogicItem/index.js +13 -2
- package/dist/LogicTree/components/LogicItem/index.js.map +1 -1
- package/dist/LogicTree/index.js +2 -0
- package/dist/LogicTree/index.js.map +1 -1
- package/dist/MemberPicker/components/MemberSelection.d.ts +2 -0
- package/dist/MemberPicker/components/MemberSelection.js +15 -13
- package/dist/MemberPicker/components/MemberSelection.js.map +1 -1
- package/dist/MemberPicker/components/MultipleOption.js +12 -0
- package/dist/MemberPicker/components/MultipleOption.js.map +1 -1
- package/dist/MemberPicker/components/Panel.d.ts +2 -0
- package/dist/MemberPicker/components/Panel.js +11 -1
- package/dist/MemberPicker/components/Panel.js.map +1 -1
- package/dist/MemberPicker/components/PanelWrapper.js +2 -0
- package/dist/MemberPicker/components/PanelWrapper.js.map +1 -1
- package/dist/MemberPicker/components/SelectedMemberTags.js +14 -6
- package/dist/MemberPicker/components/SelectedMemberTags.js.map +1 -1
- package/dist/MemberPicker/components/SingleOption.js +12 -0
- package/dist/MemberPicker/components/SingleOption.js.map +1 -1
- package/dist/MemberPicker/components/UserGroupSelection.d.ts +3 -1
- package/dist/MemberPicker/components/UserGroupSelection.js +65 -42
- package/dist/MemberPicker/components/UserGroupSelection.js.map +1 -1
- package/dist/MemberPicker/index.js +134 -108
- package/dist/MemberPicker/index.js.map +1 -1
- package/dist/Menu/index.d.ts +8 -0
- package/dist/Menu/index.js +33 -3
- package/dist/Menu/index.js.map +1 -1
- package/dist/Modal/index.d.ts +4 -0
- package/dist/Modal/index.js +55 -66
- package/dist/Modal/index.js.map +1 -1
- package/dist/OverflowCount/index.js +10 -0
- package/dist/OverflowCount/index.js.map +1 -1
- package/dist/Pagination/index.js +1 -0
- package/dist/Pagination/index.js.map +1 -1
- package/dist/Popconfirm/index.js +9 -1
- package/dist/Popconfirm/index.js.map +1 -1
- package/dist/Popover/index.js +52 -1
- package/dist/Popover/index.js.map +1 -1
- package/dist/Progress/index.js +4 -0
- package/dist/Progress/index.js.map +1 -1
- package/dist/Radio/components/Group/index.d.ts +5 -1
- package/dist/Radio/components/Group/index.js +7 -2
- package/dist/Radio/components/Group/index.js.map +1 -1
- package/dist/Radio/components/Radio/index.js +26 -0
- package/dist/Radio/components/Radio/index.js.map +1 -1
- package/dist/Radio/interface/radio.d.ts +7 -0
- package/dist/Radio/interface/radioGroup.d.ts +2 -0
- package/dist/RenameInput/index.js +11 -0
- package/dist/RenameInput/index.js.map +1 -1
- package/dist/Select/BaseSelect.d.ts +3 -0
- package/dist/Select/BaseSelect.js +229 -32
- package/dist/Select/BaseSelect.js.map +1 -1
- package/dist/Select/SelectTrigger.d.ts +2 -0
- package/dist/Select/SelectTrigger.js +13 -5
- package/dist/Select/SelectTrigger.js.map +1 -1
- package/dist/Select/components/OptionCollection.d.ts +41 -0
- package/dist/Select/components/OptionCollection.js +124 -0
- package/dist/Select/components/OptionCollection.js.map +1 -0
- package/dist/Select/index.js +45 -3
- package/dist/Select/index.js.map +1 -1
- package/dist/Select/interface.d.ts +1 -1
- package/dist/Skeleton/index.js +1 -1
- package/dist/Skeleton/index.js.map +1 -1
- package/dist/Spin/index.d.ts +1 -1
- package/dist/Spin/index.js +22 -7
- package/dist/Spin/index.js.map +1 -1
- package/dist/Switch/index.d.ts +5 -0
- package/dist/Switch/index.js +15 -5
- package/dist/Switch/index.js.map +1 -1
- package/dist/Table/components/Header.js +0 -1
- package/dist/Table/components/Header.js.map +1 -1
- package/dist/Table/index.js +42 -27
- package/dist/Table/index.js.map +1 -1
- package/dist/Tabs/index.js +1 -0
- package/dist/Tabs/index.js.map +1 -1
- package/dist/Tag/index.js +20 -1
- package/dist/Tag/index.js.map +1 -1
- package/dist/Tooltip/index.js +34 -5
- package/dist/Tooltip/index.js.map +1 -1
- package/dist/Tour/index.js +13 -1
- package/dist/Tour/index.js.map +1 -1
- package/dist/Tree/Tree2.js +2 -0
- package/dist/Tree/Tree2.js.map +1 -1
- package/dist/_utils/dialogAccessibility.d.ts +17 -0
- package/dist/_utils/dialogAccessibility.js +110 -0
- package/dist/_utils/dialogAccessibility.js.map +1 -0
- package/dist/_utils/formControlSemanticOwner.d.ts +3 -0
- package/dist/_utils/formControlSemanticOwner.js +17 -0
- package/dist/_utils/formControlSemanticOwner.js.map +1 -0
- package/dist/_utils/overlayCoordinator.js +1 -11
- package/dist/_utils/overlayCoordinator.js.map +1 -1
- package/dist/aloudata-design.css +1 -1
- package/dist/governance/semantic.d.ts +1 -0
- package/dist/governance/semantic.js +2 -0
- package/dist/governance/semantic.json +1737 -0
- package/dist/theme/contract/baselineResolvedTokenValueManifest.d.ts +1 -1
- package/dist/theme/contract/darkResolvedTokenValueManifest.d.ts +1 -1
- package/dist/theme/contract/tokenOutputContract.js +1 -0
- package/dist/theme/contract/tokenOutputContract.js.map +1 -1
- package/dist/theme/generator/acceptedColorValues.d.ts +2 -1
- package/dist/theme/generator/baselineTokenValueDelivery.d.ts +9 -1
- package/dist/theme/generator/minimalAcceptedColorValues.d.ts +2 -2
- package/dist/theme/generator/neutralSourceResolver.d.ts +28 -0
- package/dist/theme/generator/neutralSourceResolver.js +2 -0
- package/dist/theme/generator/neutralSourceValues.d.ts +28 -0
- package/dist/theme/generator/neutralSourceValues.js +2 -0
- package/dist/theme/governance/semanticGovernanceContract.d.ts +91 -0
- package/dist/theme/governance/semanticGovernanceContract.js +342 -0
- package/dist/theme/governance/semanticGovernanceContract.js.map +1 -0
- package/dist/theme/index.d.ts +2 -0
- package/dist/theme/index.js +1 -0
- package/dist/theme/neutralSourceContract.d.ts +3 -0
- package/dist/theme/neutralSourceContract.js +11 -0
- package/dist/theme/neutralSourceContract.js.map +1 -0
- package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.d.ts +1 -1
- package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.js +46 -45
- package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.js.map +1 -1
- package/dist/theme/runtime/colorValueMode/generated/slateDarkDeclarations.d.ts +3 -0
- package/dist/theme/runtime/colorValueMode/generated/slateDarkDeclarations.js +2 -0
- package/dist/theme/runtime/colorValueMode/generated/slateLightDeclarations.d.ts +3 -0
- package/dist/theme/runtime/colorValueMode/generated/slateLightDeclarations.js +2 -0
- package/dist/theme/runtime/colorValueMode/generated/stoneDarkDeclarations.d.ts +3 -0
- package/dist/theme/runtime/colorValueMode/generated/stoneDarkDeclarations.js +2 -0
- package/dist/theme/runtime/colorValueMode/generated/stoneLightDeclarations.d.ts +3 -0
- package/dist/theme/runtime/colorValueMode/generated/stoneLightDeclarations.js +2 -0
- package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.d.ts +1 -1
- package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.js +42 -41
- package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.js.map +1 -1
- package/dist/theme/runtime/colorValueMode/index.js +2 -12
- package/dist/theme/runtime/colorValueMode/index.js.map +1 -1
- package/dist/theme/runtime/colorValueMode/legacyNeutralCompatibility.d.ts +2 -0
- package/dist/theme/runtime/colorValueMode/legacyNeutralCompatibility.js +48 -0
- package/dist/theme/runtime/colorValueMode/legacyNeutralCompatibility.js.map +1 -0
- package/dist/theme/runtime/colorValueMode/registry.d.ts +1 -1
- package/dist/theme/runtime/colorValueMode/registry.js +2 -1
- package/dist/theme/runtime/colorValueMode/registry.js.map +1 -1
- package/dist/theme/runtime/initAldTheme.js +1 -3
- package/dist/theme/runtime/initAldTheme.js.map +1 -1
- package/dist/theme/runtime/neutralSource/index.d.ts +6 -0
- package/dist/theme/runtime/neutralSource/index.js +11 -0
- package/dist/theme/runtime/neutralSource/index.js.map +1 -0
- package/dist/theme/runtime/neutralSource.d.ts +2 -0
- package/package.json +12 -2
package/dist/AProgress/index.js
CHANGED
|
@@ -21,6 +21,11 @@ function AProgress(props) {
|
|
|
21
21
|
height: circleSize,
|
|
22
22
|
...style
|
|
23
23
|
},
|
|
24
|
+
role: "progressbar",
|
|
25
|
+
"aria-valuemin": 0,
|
|
26
|
+
"aria-valuemax": 100,
|
|
27
|
+
"aria-valuenow": clampedPercent,
|
|
28
|
+
"aria-label": `Progress ${clampedPercent}%`,
|
|
24
29
|
children: [/* @__PURE__ */ jsxs("svg", {
|
|
25
30
|
viewBox: `0 0 ${circleSize} ${circleSize}`,
|
|
26
31
|
width: circleSize,
|
|
@@ -63,6 +68,11 @@ function AProgress(props) {
|
|
|
63
68
|
return /* @__PURE__ */ jsx("div", {
|
|
64
69
|
className: cn("ald-progress ald-progress-line tw-w-full", className),
|
|
65
70
|
style,
|
|
71
|
+
role: "progressbar",
|
|
72
|
+
"aria-valuemin": 0,
|
|
73
|
+
"aria-valuemax": 100,
|
|
74
|
+
"aria-valuenow": clampedPercent,
|
|
75
|
+
"aria-label": `Progress ${clampedPercent}%`,
|
|
66
76
|
children: /* @__PURE__ */ jsxs("div", {
|
|
67
77
|
className: "tw-flex tw-items-center tw-gap-2",
|
|
68
78
|
children: [/* @__PURE__ */ jsx("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/AProgress/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../lib/utils';\n\nexport interface AProgressProps {\n percent?: number;\n type?: 'line' | 'circle' | 'dashboard';\n status?: 'success' | 'exception' | 'normal' | 'active';\n showInfo?: boolean;\n strokeColor?: string;\n trailColor?: string;\n strokeWidth?: number;\n width?: number;\n format?: (percent?: number) => React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n size?: 'default' | 'small';\n}\n\nfunction AProgress(props: AProgressProps) {\n const {\n percent = 0,\n type = 'line',\n status,\n showInfo = true,\n strokeColor = 'var(--action-primary-normal)',\n trailColor = 'var(--background-neutral-subtle)',\n strokeWidth,\n width = 120,\n format,\n className,\n style,\n size,\n } = props;\n\n const clampedPercent = Math.min(100, Math.max(0, percent));\n const resolvedStatus =\n status || (clampedPercent >= 100 ? 'success' : 'normal');\n\n const statusColor =\n resolvedStatus === 'success'\n ? 'var(--content-positive-secondary)'\n : resolvedStatus === 'exception'\n ? 'var(--content-negative-secondary)'\n : resolvedStatus === 'active'\n ? 'var(--content-informative-secondary)'\n : strokeColor;\n const resolvedStrokeWidth = strokeWidth || (size === 'small' ? 3 : 4);\n\n if (type === 'circle' || type === 'dashboard') {\n const circleSize = width;\n const sw = resolvedStrokeWidth;\n const radius = (circleSize - sw) / 2;\n const circumference = 2 * Math.PI * radius;\n const dashOffset = circumference * (1 - clampedPercent / 100);\n\n return (\n <div\n className={cn(\n 'ald-progress ald-progress-circle tw-relative tw-inline-flex tw-items-center tw-justify-center',\n className,\n )}\n style={{ width: circleSize, height: circleSize, ...style }}\n >\n <svg\n viewBox={`0 0 ${circleSize} ${circleSize}`}\n width={circleSize}\n height={circleSize}\n >\n <circle\n cx={circleSize / 2}\n cy={circleSize / 2}\n r={radius}\n fill=\"none\"\n stroke={trailColor}\n strokeWidth={sw}\n />\n <circle\n cx={circleSize / 2}\n cy={circleSize / 2}\n r={radius}\n fill=\"none\"\n stroke={statusColor}\n strokeWidth={sw}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={dashOffset}\n transform={`rotate(-90 ${circleSize / 2} ${circleSize / 2})`}\n className=\"tw-transition-all tw-duration-300\"\n />\n </svg>\n {showInfo && (\n <span\n className=\"tw-absolute tw-z-[1] tw-inline-flex tw-items-center tw-justify-center tw-rounded-full tw-text-sm tw-font-medium\"\n style={{\n minWidth: '4ch',\n padding: '0 4px',\n color: 'var(--content-primary)',\n backgroundColor: 'var(--background-neutral-surface)',\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n {format ? format(clampedPercent) : `${clampedPercent}%`}\n </span>\n )}\n </div>\n );\n }\n\n const lineHeight = resolvedStrokeWidth;\n\n return (\n <div\n className={cn('ald-progress ald-progress-line tw-w-full', className)}\n style={style}\n >\n <div className=\"tw-flex tw-items-center tw-gap-2\">\n <div\n className=\"ald-progress-outer tw-flex-1 tw-overflow-hidden tw-rounded-full\"\n style={{ height: lineHeight, backgroundColor: trailColor }}\n >\n <div\n className=\"ald-progress-inner tw-h-full tw-rounded-full tw-transition-all tw-duration-300\"\n style={{\n width: `${clampedPercent}%`,\n backgroundColor: statusColor,\n }}\n />\n </div>\n {showInfo && (\n <span\n className=\"ald-progress-text tw-inline-block tw-whitespace-nowrap tw-text-left tw-text-sm\"\n style={{\n minWidth: '4ch',\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n {format ? format(clampedPercent) : `${clampedPercent}%`}\n </span>\n )}\n </div>\n </div>\n );\n}\n\nexport default AProgress;\n"],"mappings":";;;;AAkBA,SAAS,UAAU,OAAuB;CACxC,MAAM,EACJ,UAAU,GACV,OAAO,QACP,QACA,WAAW,MACX,cAAc,gCACd,aAAa,oCACb,aACA,QAAQ,KACR,QACA,WACA,OACA,SACE;CAEJ,MAAM,iBAAiB,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,QAAQ,CAAC;CAC1D,MAAM,iBACJ,WAAW,kBAAkB,MAAM,YAAY;CAEjD,MAAM,cACJ,mBAAmB,YACf,sCACA,mBAAmB,cACnB,sCACA,mBAAmB,WACnB,yCACA;CACN,MAAM,sBAAsB,gBAAgB,SAAS,UAAU,IAAI;AAEnE,KAAI,SAAS,YAAY,SAAS,aAAa;EAC7C,MAAM,aAAa;EACnB,MAAM,KAAK;EACX,MAAM,UAAU,aAAa,MAAM;EACnC,MAAM,gBAAgB,IAAI,KAAK,KAAK;EACpC,MAAM,aAAa,iBAAiB,IAAI,iBAAiB;AAEzD,SACE,qBAAC,OAAD;GACE,WAAW,GACT,iGACA,UACD;GACD,OAAO;IAAE,OAAO;IAAY,QAAQ;IAAY,GAAG;IAAO;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/AProgress/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../lib/utils';\n\nexport interface AProgressProps {\n percent?: number;\n type?: 'line' | 'circle' | 'dashboard';\n status?: 'success' | 'exception' | 'normal' | 'active';\n showInfo?: boolean;\n strokeColor?: string;\n trailColor?: string;\n strokeWidth?: number;\n width?: number;\n format?: (percent?: number) => React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n size?: 'default' | 'small';\n}\n\nfunction AProgress(props: AProgressProps) {\n const {\n percent = 0,\n type = 'line',\n status,\n showInfo = true,\n strokeColor = 'var(--action-primary-normal)',\n trailColor = 'var(--background-neutral-subtle)',\n strokeWidth,\n width = 120,\n format,\n className,\n style,\n size,\n } = props;\n\n const clampedPercent = Math.min(100, Math.max(0, percent));\n const resolvedStatus =\n status || (clampedPercent >= 100 ? 'success' : 'normal');\n\n const statusColor =\n resolvedStatus === 'success'\n ? 'var(--content-positive-secondary)'\n : resolvedStatus === 'exception'\n ? 'var(--content-negative-secondary)'\n : resolvedStatus === 'active'\n ? 'var(--content-informative-secondary)'\n : strokeColor;\n const resolvedStrokeWidth = strokeWidth || (size === 'small' ? 3 : 4);\n\n if (type === 'circle' || type === 'dashboard') {\n const circleSize = width;\n const sw = resolvedStrokeWidth;\n const radius = (circleSize - sw) / 2;\n const circumference = 2 * Math.PI * radius;\n const dashOffset = circumference * (1 - clampedPercent / 100);\n\n return (\n <div\n className={cn(\n 'ald-progress ald-progress-circle tw-relative tw-inline-flex tw-items-center tw-justify-center',\n className,\n )}\n style={{ width: circleSize, height: circleSize, ...style }}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={clampedPercent}\n aria-label={`Progress ${clampedPercent}%`}\n >\n <svg\n viewBox={`0 0 ${circleSize} ${circleSize}`}\n width={circleSize}\n height={circleSize}\n >\n <circle\n cx={circleSize / 2}\n cy={circleSize / 2}\n r={radius}\n fill=\"none\"\n stroke={trailColor}\n strokeWidth={sw}\n />\n <circle\n cx={circleSize / 2}\n cy={circleSize / 2}\n r={radius}\n fill=\"none\"\n stroke={statusColor}\n strokeWidth={sw}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={dashOffset}\n transform={`rotate(-90 ${circleSize / 2} ${circleSize / 2})`}\n className=\"tw-transition-all tw-duration-300\"\n />\n </svg>\n {showInfo && (\n <span\n className=\"tw-absolute tw-z-[1] tw-inline-flex tw-items-center tw-justify-center tw-rounded-full tw-text-sm tw-font-medium\"\n style={{\n minWidth: '4ch',\n padding: '0 4px',\n color: 'var(--content-primary)',\n backgroundColor: 'var(--background-neutral-surface)',\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n {format ? format(clampedPercent) : `${clampedPercent}%`}\n </span>\n )}\n </div>\n );\n }\n\n const lineHeight = resolvedStrokeWidth;\n\n return (\n <div\n className={cn('ald-progress ald-progress-line tw-w-full', className)}\n style={style}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={clampedPercent}\n aria-label={`Progress ${clampedPercent}%`}\n >\n <div className=\"tw-flex tw-items-center tw-gap-2\">\n <div\n className=\"ald-progress-outer tw-flex-1 tw-overflow-hidden tw-rounded-full\"\n style={{ height: lineHeight, backgroundColor: trailColor }}\n >\n <div\n className=\"ald-progress-inner tw-h-full tw-rounded-full tw-transition-all tw-duration-300\"\n style={{\n width: `${clampedPercent}%`,\n backgroundColor: statusColor,\n }}\n />\n </div>\n {showInfo && (\n <span\n className=\"ald-progress-text tw-inline-block tw-whitespace-nowrap tw-text-left tw-text-sm\"\n style={{\n minWidth: '4ch',\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n {format ? format(clampedPercent) : `${clampedPercent}%`}\n </span>\n )}\n </div>\n </div>\n );\n}\n\nexport default AProgress;\n"],"mappings":";;;;AAkBA,SAAS,UAAU,OAAuB;CACxC,MAAM,EACJ,UAAU,GACV,OAAO,QACP,QACA,WAAW,MACX,cAAc,gCACd,aAAa,oCACb,aACA,QAAQ,KACR,QACA,WACA,OACA,SACE;CAEJ,MAAM,iBAAiB,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,QAAQ,CAAC;CAC1D,MAAM,iBACJ,WAAW,kBAAkB,MAAM,YAAY;CAEjD,MAAM,cACJ,mBAAmB,YACf,sCACA,mBAAmB,cACnB,sCACA,mBAAmB,WACnB,yCACA;CACN,MAAM,sBAAsB,gBAAgB,SAAS,UAAU,IAAI;AAEnE,KAAI,SAAS,YAAY,SAAS,aAAa;EAC7C,MAAM,aAAa;EACnB,MAAM,KAAK;EACX,MAAM,UAAU,aAAa,MAAM;EACnC,MAAM,gBAAgB,IAAI,KAAK,KAAK;EACpC,MAAM,aAAa,iBAAiB,IAAI,iBAAiB;AAEzD,SACE,qBAAC,OAAD;GACE,WAAW,GACT,iGACA,UACD;GACD,OAAO;IAAE,OAAO;IAAY,QAAQ;IAAY,GAAG;IAAO;GAC1D,MAAK;GACL,iBAAe;GACf,iBAAe;GACf,iBAAe;GACf,cAAY,YAAY,eAAe;aAVzC,CAYE,qBAAC,OAAD;IACE,SAAS,OAAO,WAAW,GAAG;IAC9B,OAAO;IACP,QAAQ;cAHV,CAKE,oBAAC,UAAD;KACE,IAAI,aAAa;KACjB,IAAI,aAAa;KACjB,GAAG;KACH,MAAK;KACL,QAAQ;KACR,aAAa;KACb,CAAA,EACF,oBAAC,UAAD;KACE,IAAI,aAAa;KACjB,IAAI,aAAa;KACjB,GAAG;KACH,MAAK;KACL,QAAQ;KACR,aAAa;KACb,eAAc;KACd,iBAAiB;KACjB,kBAAkB;KAClB,WAAW,cAAc,aAAa,EAAE,GAAG,aAAa,EAAE;KAC1D,WAAU;KACV,CAAA,CACE;OACL,YACC,oBAAC,QAAD;IACE,WAAU;IACV,OAAO;KACL,UAAU;KACV,SAAS;KACT,OAAO;KACP,iBAAiB;KACjB,YACE;KACF,oBAAoB;KACrB;cAEA,SAAS,OAAO,eAAe,GAAG,GAAG,eAAe;IAChD,CAAA,CAEL;;;CAIV,MAAM,aAAa;AAEnB,QACE,oBAAC,OAAD;EACE,WAAW,GAAG,4CAA4C,UAAU;EAC7D;EACP,MAAK;EACL,iBAAe;EACf,iBAAe;EACf,iBAAe;EACf,cAAY,YAAY,eAAe;YAEvC,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,OAAD;IACE,WAAU;IACV,OAAO;KAAE,QAAQ;KAAY,iBAAiB;KAAY;cAE1D,oBAAC,OAAD;KACE,WAAU;KACV,OAAO;MACL,OAAO,GAAG,eAAe;MACzB,iBAAiB;MAClB;KACD,CAAA;IACE,CAAA,EACL,YACC,oBAAC,QAAD;IACE,WAAU;IACV,OAAO;KACL,UAAU;KACV,YACE;KACF,oBAAoB;KACrB;cAEA,SAAS,OAAO,eAAe,GAAG,GAAG,eAAe;IAChD,CAAA,CAEL;;EACF,CAAA"}
|
package/dist/Alert/index.js
CHANGED
|
@@ -85,6 +85,7 @@ function Alert(props) {
|
|
|
85
85
|
}),
|
|
86
86
|
closable && /* @__PURE__ */ jsx("button", {
|
|
87
87
|
type: "button",
|
|
88
|
+
"aria-label": "Close alert",
|
|
88
89
|
className: "ald-alert-close-icon tw-flex tw-cursor-pointer tw-items-center tw-self-start tw-border-0 tw-bg-[var(--action-ghost-normal)] tw-p-0 tw-pt-0.5",
|
|
89
90
|
onClick: (e) => {
|
|
90
91
|
setClosed(true);
|
|
@@ -93,7 +94,8 @@ function Alert(props) {
|
|
|
93
94
|
},
|
|
94
95
|
children: /* @__PURE__ */ jsx(Memo$3, {
|
|
95
96
|
size: 16,
|
|
96
|
-
color: "var(--content-secondary)"
|
|
97
|
+
color: "var(--content-secondary)",
|
|
98
|
+
"aria-hidden": "true"
|
|
97
99
|
})
|
|
98
100
|
})
|
|
99
101
|
]
|
package/dist/Alert/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Alert/index.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport {\n AttentionTriangleFill,\n CheckCircleFill,\n CloseCircleFill,\n CloseLightLine,\n InformationCircleFill,\n} from '../Icon';\nimport { cn } from '../lib/utils';\n\nexport interface AlertProps {\n type?: 'success' | 'info' | 'warning' | 'error' | 'none';\n message?: React.ReactNode;\n description?: React.ReactNode;\n closable?: boolean;\n onClose?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n afterClose?: () => void;\n showIcon?: boolean;\n icon?: React.ReactNode;\n banner?: boolean;\n action?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst typeConfig: Record<\n string,\n { bg: string; border: string; icon: React.ReactNode; titleColor: string }\n> = {\n success: {\n bg: 'tw-bg-[var(--background-positive-subtle)]',\n border: 'tw-border-[var(--border-positive-subtle)]',\n titleColor: 'tw-text-[var(--content-positive-primary)]',\n icon: (\n <CheckCircleFill size={16} color=\"var(--content-positive-secondary)\" />\n ),\n },\n info: {\n bg: 'tw-bg-[var(--background-informative-subtle)]',\n border: 'tw-border-[var(--border-informative-subtle)]',\n titleColor: 'tw-text-[var(--content-informative-primary)]',\n icon: (\n <InformationCircleFill\n size={16}\n color=\"var(--content-informative-secondary)\"\n />\n ),\n },\n warning: {\n bg: 'tw-bg-[var(--background-warning-subtle)]',\n border: 'tw-border-[var(--border-warning-subtle)]',\n titleColor: 'tw-text-[var(--content-warning-primary)]',\n icon: (\n <AttentionTriangleFill\n size={16}\n color=\"var(--content-warning-secondary)\"\n />\n ),\n },\n error: {\n bg: 'tw-bg-[var(--background-negative-subtle)]',\n border: 'tw-border-[var(--border-negative-subtle)]',\n titleColor: 'tw-text-[var(--content-negative-primary)]',\n icon: (\n <CloseCircleFill size={16} color=\"var(--content-negative-secondary)\" />\n ),\n },\n none: {\n bg: 'tw-bg-[var(--background-neutral-subtle)]',\n border: 'tw-border-[var(--border-neutral-subtle)]',\n titleColor: 'tw-text-[var(--content-primary)]',\n icon: <InformationCircleFill size={16} color=\"var(--content-secondary)\" />,\n },\n};\n\nfunction Alert(props: AlertProps) {\n const {\n type = 'info',\n message,\n description,\n closable,\n onClose,\n afterClose,\n showIcon = true,\n icon,\n banner,\n action,\n className,\n style,\n } = props;\n\n const [closed, setClosed] = useState(false);\n\n if (closed) return null;\n\n const config = typeConfig[type] || typeConfig.info;\n\n return (\n <div\n className={cn(\n 'ald-alert tw-flex tw-items-start tw-gap-2 tw-rounded-r-75 tw-border tw-border-solid tw-p-3',\n banner && 'ald-alert-banner !tw-rounded-none',\n config.bg,\n config.border,\n className,\n )}\n style={style}\n role=\"alert\"\n >\n {showIcon && (\n <span className=\"ald-alert-icon tw-flex tw-items-center tw-pt-0.5\">\n {icon || config.icon}\n </span>\n )}\n <div className=\"ald-alert-content tw-min-w-0 tw-flex-1\">\n {message && (\n <div\n className={cn(\n 'ald-alert-message tw-text-sm tw-font-medium tw-leading-5',\n config.titleColor,\n )}\n >\n {message}\n </div>\n )}\n {description && (\n <div\n className=\"ald-alert-description tw-mt-1 tw-text-sm tw-font-normal tw-leading-5 tw-text-[var(--content-secondary)]\"\n style={{ fontFeatureSettings: \"'liga' off, 'clig' off\" }}\n >\n {description}\n </div>\n )}\n </div>\n {action && <div className=\"ald-alert-action\">{action}</div>}\n {closable && (\n <button\n type=\"button\"\n className=\"ald-alert-close-icon tw-flex tw-cursor-pointer tw-items-center tw-self-start tw-border-0 tw-bg-[var(--action-ghost-normal)] tw-p-0 tw-pt-0.5\"\n onClick={(e) => {\n setClosed(true);\n onClose?.(e);\n afterClose?.();\n }}\n >\n <CloseLightLine
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Alert/index.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport {\n AttentionTriangleFill,\n CheckCircleFill,\n CloseCircleFill,\n CloseLightLine,\n InformationCircleFill,\n} from '../Icon';\nimport { cn } from '../lib/utils';\n\nexport interface AlertProps {\n type?: 'success' | 'info' | 'warning' | 'error' | 'none';\n message?: React.ReactNode;\n description?: React.ReactNode;\n closable?: boolean;\n onClose?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n afterClose?: () => void;\n showIcon?: boolean;\n icon?: React.ReactNode;\n banner?: boolean;\n action?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst typeConfig: Record<\n string,\n { bg: string; border: string; icon: React.ReactNode; titleColor: string }\n> = {\n success: {\n bg: 'tw-bg-[var(--background-positive-subtle)]',\n border: 'tw-border-[var(--border-positive-subtle)]',\n titleColor: 'tw-text-[var(--content-positive-primary)]',\n icon: (\n <CheckCircleFill size={16} color=\"var(--content-positive-secondary)\" />\n ),\n },\n info: {\n bg: 'tw-bg-[var(--background-informative-subtle)]',\n border: 'tw-border-[var(--border-informative-subtle)]',\n titleColor: 'tw-text-[var(--content-informative-primary)]',\n icon: (\n <InformationCircleFill\n size={16}\n color=\"var(--content-informative-secondary)\"\n />\n ),\n },\n warning: {\n bg: 'tw-bg-[var(--background-warning-subtle)]',\n border: 'tw-border-[var(--border-warning-subtle)]',\n titleColor: 'tw-text-[var(--content-warning-primary)]',\n icon: (\n <AttentionTriangleFill\n size={16}\n color=\"var(--content-warning-secondary)\"\n />\n ),\n },\n error: {\n bg: 'tw-bg-[var(--background-negative-subtle)]',\n border: 'tw-border-[var(--border-negative-subtle)]',\n titleColor: 'tw-text-[var(--content-negative-primary)]',\n icon: (\n <CloseCircleFill size={16} color=\"var(--content-negative-secondary)\" />\n ),\n },\n none: {\n bg: 'tw-bg-[var(--background-neutral-subtle)]',\n border: 'tw-border-[var(--border-neutral-subtle)]',\n titleColor: 'tw-text-[var(--content-primary)]',\n icon: <InformationCircleFill size={16} color=\"var(--content-secondary)\" />,\n },\n};\n\nfunction Alert(props: AlertProps) {\n const {\n type = 'info',\n message,\n description,\n closable,\n onClose,\n afterClose,\n showIcon = true,\n icon,\n banner,\n action,\n className,\n style,\n } = props;\n\n const [closed, setClosed] = useState(false);\n\n if (closed) return null;\n\n const config = typeConfig[type] || typeConfig.info;\n\n return (\n <div\n className={cn(\n 'ald-alert tw-flex tw-items-start tw-gap-2 tw-rounded-r-75 tw-border tw-border-solid tw-p-3',\n banner && 'ald-alert-banner !tw-rounded-none',\n config.bg,\n config.border,\n className,\n )}\n style={style}\n role=\"alert\"\n >\n {showIcon && (\n <span className=\"ald-alert-icon tw-flex tw-items-center tw-pt-0.5\">\n {icon || config.icon}\n </span>\n )}\n <div className=\"ald-alert-content tw-min-w-0 tw-flex-1\">\n {message && (\n <div\n className={cn(\n 'ald-alert-message tw-text-sm tw-font-medium tw-leading-5',\n config.titleColor,\n )}\n >\n {message}\n </div>\n )}\n {description && (\n <div\n className=\"ald-alert-description tw-mt-1 tw-text-sm tw-font-normal tw-leading-5 tw-text-[var(--content-secondary)]\"\n style={{ fontFeatureSettings: \"'liga' off, 'clig' off\" }}\n >\n {description}\n </div>\n )}\n </div>\n {action && <div className=\"ald-alert-action\">{action}</div>}\n {closable && (\n <button\n type=\"button\"\n aria-label=\"Close alert\"\n className=\"ald-alert-close-icon tw-flex tw-cursor-pointer tw-items-center tw-self-start tw-border-0 tw-bg-[var(--action-ghost-normal)] tw-p-0 tw-pt-0.5\"\n onClick={(e) => {\n setClosed(true);\n onClose?.(e);\n afterClose?.();\n }}\n >\n <CloseLightLine\n size={16}\n color=\"var(--content-secondary)\"\n aria-hidden=\"true\"\n />\n </button>\n )}\n </div>\n );\n}\n\nexport default Alert;\n"],"mappings":";;;;;;;;;AAyBA,IAAM,aAGF;CACF,SAAS;EACP,IAAI;EACJ,QAAQ;EACR,YAAY;EACZ,MACE,oBAAC,QAAD;GAAiB,MAAM;GAAI,OAAM;GAAsC,CAAA;EAE1E;CACD,MAAM;EACJ,IAAI;EACJ,QAAQ;EACR,YAAY;EACZ,MACE,oBAAC,QAAD;GACE,MAAM;GACN,OAAM;GACN,CAAA;EAEL;CACD,SAAS;EACP,IAAI;EACJ,QAAQ;EACR,YAAY;EACZ,MACE,oBAAC,MAAD;GACE,MAAM;GACN,OAAM;GACN,CAAA;EAEL;CACD,OAAO;EACL,IAAI;EACJ,QAAQ;EACR,YAAY;EACZ,MACE,oBAAC,QAAD;GAAiB,MAAM;GAAI,OAAM;GAAsC,CAAA;EAE1E;CACD,MAAM;EACJ,IAAI;EACJ,QAAQ;EACR,YAAY;EACZ,MAAM,oBAAC,QAAD;GAAuB,MAAM;GAAI,OAAM;GAA6B,CAAA;EAC3E;CACF;AAED,SAAS,MAAM,OAAmB;CAChC,MAAM,EACJ,OAAO,QACP,SACA,aACA,UACA,SACA,YACA,WAAW,MACX,MACA,QACA,QACA,WACA,UACE;CAEJ,MAAM,CAAC,QAAQ,aAAa,SAAS,MAAM;AAE3C,KAAI,OAAQ,QAAO;CAEnB,MAAM,SAAS,WAAW,SAAS,WAAW;AAE9C,QACE,qBAAC,OAAD;EACE,WAAW,GACT,8FACA,UAAU,qCACV,OAAO,IACP,OAAO,QACP,UACD;EACM;EACP,MAAK;YATP;GAWG,YACC,oBAAC,QAAD;IAAM,WAAU;cACb,QAAQ,OAAO;IACX,CAAA;GAET,qBAAC,OAAD;IAAK,WAAU;cAAf,CACG,WACC,oBAAC,OAAD;KACE,WAAW,GACT,4DACA,OAAO,WACR;eAEA;KACG,CAAA,EAEP,eACC,oBAAC,OAAD;KACE,WAAU;KACV,OAAO,EAAE,qBAAqB,0BAA0B;eAEvD;KACG,CAAA,CAEJ;;GACL,UAAU,oBAAC,OAAD;IAAK,WAAU;cAAoB;IAAa,CAAA;GAC1D,YACC,oBAAC,UAAD;IACE,MAAK;IACL,cAAW;IACX,WAAU;IACV,UAAU,MAAM;AACd,eAAU,KAAK;AACf,eAAU,EAAE;AACZ,mBAAc;;cAGhB,oBAAC,QAAD;KACE,MAAM;KACN,OAAM;KACN,eAAY;KACZ,CAAA;IACK,CAAA;GAEP"}
|
package/dist/Badge/index.js
CHANGED
|
@@ -36,17 +36,33 @@ var badgeVariants = cva("ald-badge tw-inline-flex tw-cursor-default tw-items-cen
|
|
|
36
36
|
});
|
|
37
37
|
function Badge(props) {
|
|
38
38
|
const { count, status = "default", size, className, style, onClick, ...rest } = props;
|
|
39
|
-
if (count === "" || count === void 0)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
if (count === "" || count === void 0) {
|
|
40
|
+
const dotClassName = cn("ald-badge ald-badge-dot tw-flex tw-aspect-square tw-items-start tw-rounded-full", STATUS_DOT_COLORS[status], typeof onClick === "function" && "tw-cursor-pointer", className);
|
|
41
|
+
if (onClick) return /* @__PURE__ */ jsx("button", {
|
|
42
|
+
type: "button",
|
|
43
|
+
...rest,
|
|
44
|
+
className: dotClassName,
|
|
45
|
+
style: {
|
|
46
|
+
width: 8,
|
|
47
|
+
height: 8,
|
|
48
|
+
gap: 8,
|
|
49
|
+
...style
|
|
50
|
+
},
|
|
51
|
+
"aria-label": "Badge",
|
|
52
|
+
onClick
|
|
53
|
+
});
|
|
54
|
+
return /* @__PURE__ */ jsx("div", {
|
|
55
|
+
...rest,
|
|
56
|
+
className: cn("ald-badge ald-badge-dot tw-flex tw-aspect-square tw-items-start tw-rounded-full", STATUS_DOT_COLORS[status], typeof onClick === "function" && "tw-cursor-pointer", className),
|
|
57
|
+
style: {
|
|
58
|
+
width: 8,
|
|
59
|
+
height: 8,
|
|
60
|
+
gap: 8,
|
|
61
|
+
...style
|
|
62
|
+
},
|
|
63
|
+
onClick
|
|
64
|
+
});
|
|
65
|
+
}
|
|
50
66
|
const isNumeric = typeof count === "number" || typeof count === "string" && /^[+-]?\d+$/.test(count.trim());
|
|
51
67
|
return /* @__PURE__ */ jsx("div", {
|
|
52
68
|
...rest,
|
|
@@ -59,6 +75,16 @@ function Badge(props) {
|
|
|
59
75
|
fontFamily: "monospace",
|
|
60
76
|
...style
|
|
61
77
|
} : style,
|
|
78
|
+
...onClick ? {
|
|
79
|
+
role: "button",
|
|
80
|
+
tabIndex: 0,
|
|
81
|
+
onKeyDown: (event) => {
|
|
82
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
onClick(event);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
} : {},
|
|
62
88
|
onClick,
|
|
63
89
|
children: count
|
|
64
90
|
});
|
package/dist/Badge/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Badge/index.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority';\nimport React from 'react';\nimport { cn } from '../lib/utils';\n\nexport interface BadgeProps {\n /**\n * 展示的文本内容\n */\n count: string | number;\n /**\n * 状态\n */\n status?: 'success' | 'error' | 'default' | 'info' | 'warning';\n /**\n * 大小\n */\n size?: 'default' | 'large';\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler;\n}\n\nconst STATUS_DOT_COLORS: Record<string, string> = {\n default: 'tw-bg-[var(--content-secondary)]',\n success: 'tw-bg-[var(--content-positive-secondary)]',\n error: 'tw-bg-[var(--content-negative-secondary)]',\n info: 'tw-bg-[var(--content-informative-secondary)]',\n warning: 'tw-bg-[var(--content-warning-secondary)]',\n};\n\nconst badgeVariants = cva(\n 'ald-badge tw-inline-flex tw-cursor-default tw-items-center tw-justify-center tw-rounded-[99px]',\n {\n variants: {\n size: {\n default:\n 'tw-[font-feature-settings:\"liga\"_off,\"clig\"_off] tw-h-[var(--3xs)] tw-min-w-[var(--3xs)] tw-gap-[var(--component-gap-xs)] tw-px-[var(--component-padding-xs)] tw-text-xs tw-font-normal tw-leading-4',\n large:\n 'ald-badge-large tw-[font-feature-settings:\"liga\"_off,\"clig\"_off] tw-h-[var(--2xs)] tw-min-w-[var(--2xs)] tw-gap-[var(--component-gap-xs)] tw-px-[var(--component-padding-sm)] tw-text-sm tw-font-normal tw-leading-5',\n },\n status: {\n default:\n 'ald-badge-default tw-bg-[var(--background-neutral-muted)] tw-text-[var(--content-primary)]',\n success:\n 'ald-badge-success tw-bg-[var(--background-positive-muted)] tw-text-[var(--content-positive-primary)]',\n error:\n 'ald-badge-error tw-bg-[var(--background-negative-muted)] tw-text-[var(--content-negative-primary)]',\n info: 'ald-badge-info tw-bg-[var(--background-informative-muted)] tw-text-[var(--content-informative-primary)]',\n warning:\n 'ald-badge-warning tw-bg-[var(--background-warning-muted)] tw-text-[var(--content-warning-primary)]',\n },\n clickable: {\n true: 'ald-badge-clickable tw-cursor-pointer',\n false: '',\n },\n },\n defaultVariants: {\n size: 'default',\n status: 'default',\n clickable: false,\n },\n },\n);\n\nexport default function Badge(props: BadgeProps) {\n const {\n count,\n status = 'default',\n size,\n className,\n style,\n onClick,\n ...rest\n } = props;\n\n const isDot = count === '' || count === undefined;\n\n if (isDot) {\n return (\n <div\n {...rest}\n className={cn(\n 'ald-badge ald-badge-dot tw-flex tw-aspect-square tw-items-start tw-rounded-full',\n STATUS_DOT_COLORS[status],\n typeof onClick === 'function' && 'tw-cursor-pointer',\n className,\n )}\n style={{ width: 8, height: 8, gap: 8, ...style }}\n onClick={onClick}\n />\n );\n }\n\n const isNumeric =\n typeof count === 'number' ||\n (typeof count === 'string' && /^[+-]?\\d+$/.test(count.trim()));\n\n return (\n <div\n {...rest}\n className={cn(\n badgeVariants({\n size: size || 'default',\n status,\n clickable: typeof onClick === 'function',\n }),\n className,\n )}\n style={isNumeric ? { fontFamily: 'monospace', ...style } : style}\n onClick={onClick}\n >\n {count}\n </div>\n );\n}\n"],"mappings":";;;;;AAsBA,IAAM,oBAA4C;CAChD,SAAS;CACT,SAAS;CACT,OAAO;CACP,MAAM;CACN,SAAS;CACV;AAED,IAAM,gBAAgB,IACpB,kGACA;CACE,UAAU;EACR,MAAM;GACJ,SACE;GACF,OACE;GACH;EACD,QAAQ;GACN,SACE;GACF,SACE;GACF,OACE;GACF,MAAM;GACN,SACE;GACH;EACD,WAAW;GACT,MAAM;GACN,OAAO;GACR;EACF;CACD,iBAAiB;EACf,MAAM;EACN,QAAQ;EACR,WAAW;EACZ;CACF,CACF;AAED,SAAwB,MAAM,OAAmB;CAC/C,MAAM,EACJ,OACA,SAAS,WACT,MACA,WACA,OACA,SACA,GAAG,SACD;AAIJ,KAFc,UAAU,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Badge/index.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority';\nimport React from 'react';\nimport { cn } from '../lib/utils';\n\nexport interface BadgeProps {\n /**\n * 展示的文本内容\n */\n count: string | number;\n /**\n * 状态\n */\n status?: 'success' | 'error' | 'default' | 'info' | 'warning';\n /**\n * 大小\n */\n size?: 'default' | 'large';\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler;\n}\n\nconst STATUS_DOT_COLORS: Record<string, string> = {\n default: 'tw-bg-[var(--content-secondary)]',\n success: 'tw-bg-[var(--content-positive-secondary)]',\n error: 'tw-bg-[var(--content-negative-secondary)]',\n info: 'tw-bg-[var(--content-informative-secondary)]',\n warning: 'tw-bg-[var(--content-warning-secondary)]',\n};\n\nconst badgeVariants = cva(\n 'ald-badge tw-inline-flex tw-cursor-default tw-items-center tw-justify-center tw-rounded-[99px]',\n {\n variants: {\n size: {\n default:\n 'tw-[font-feature-settings:\"liga\"_off,\"clig\"_off] tw-h-[var(--3xs)] tw-min-w-[var(--3xs)] tw-gap-[var(--component-gap-xs)] tw-px-[var(--component-padding-xs)] tw-text-xs tw-font-normal tw-leading-4',\n large:\n 'ald-badge-large tw-[font-feature-settings:\"liga\"_off,\"clig\"_off] tw-h-[var(--2xs)] tw-min-w-[var(--2xs)] tw-gap-[var(--component-gap-xs)] tw-px-[var(--component-padding-sm)] tw-text-sm tw-font-normal tw-leading-5',\n },\n status: {\n default:\n 'ald-badge-default tw-bg-[var(--background-neutral-muted)] tw-text-[var(--content-primary)]',\n success:\n 'ald-badge-success tw-bg-[var(--background-positive-muted)] tw-text-[var(--content-positive-primary)]',\n error:\n 'ald-badge-error tw-bg-[var(--background-negative-muted)] tw-text-[var(--content-negative-primary)]',\n info: 'ald-badge-info tw-bg-[var(--background-informative-muted)] tw-text-[var(--content-informative-primary)]',\n warning:\n 'ald-badge-warning tw-bg-[var(--background-warning-muted)] tw-text-[var(--content-warning-primary)]',\n },\n clickable: {\n true: 'ald-badge-clickable tw-cursor-pointer',\n false: '',\n },\n },\n defaultVariants: {\n size: 'default',\n status: 'default',\n clickable: false,\n },\n },\n);\n\nexport default function Badge(props: BadgeProps) {\n const {\n count,\n status = 'default',\n size,\n className,\n style,\n onClick,\n ...rest\n } = props;\n\n const isDot = count === '' || count === undefined;\n\n if (isDot) {\n const dotClassName = cn(\n 'ald-badge ald-badge-dot tw-flex tw-aspect-square tw-items-start tw-rounded-full',\n STATUS_DOT_COLORS[status],\n typeof onClick === 'function' && 'tw-cursor-pointer',\n className,\n );\n\n if (onClick) {\n return (\n <button\n type=\"button\"\n {...rest}\n className={dotClassName}\n style={{ width: 8, height: 8, gap: 8, ...style }}\n aria-label=\"Badge\"\n onClick={onClick}\n />\n );\n }\n\n return (\n <div\n {...rest}\n className={cn(\n 'ald-badge ald-badge-dot tw-flex tw-aspect-square tw-items-start tw-rounded-full',\n STATUS_DOT_COLORS[status],\n typeof onClick === 'function' && 'tw-cursor-pointer',\n className,\n )}\n style={{ width: 8, height: 8, gap: 8, ...style }}\n onClick={onClick}\n />\n );\n }\n\n const isNumeric =\n typeof count === 'number' ||\n (typeof count === 'string' && /^[+-]?\\d+$/.test(count.trim()));\n\n return (\n <div\n {...rest}\n className={cn(\n badgeVariants({\n size: size || 'default',\n status,\n clickable: typeof onClick === 'function',\n }),\n className,\n )}\n style={isNumeric ? { fontFamily: 'monospace', ...style } : style}\n {...(onClick\n ? {\n role: 'button',\n tabIndex: 0,\n onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onClick(event as unknown as React.MouseEvent);\n }\n },\n }\n : {})}\n onClick={onClick}\n >\n {count}\n </div>\n );\n}\n"],"mappings":";;;;;AAsBA,IAAM,oBAA4C;CAChD,SAAS;CACT,SAAS;CACT,OAAO;CACP,MAAM;CACN,SAAS;CACV;AAED,IAAM,gBAAgB,IACpB,kGACA;CACE,UAAU;EACR,MAAM;GACJ,SACE;GACF,OACE;GACH;EACD,QAAQ;GACN,SACE;GACF,SACE;GACF,OACE;GACF,MAAM;GACN,SACE;GACH;EACD,WAAW;GACT,MAAM;GACN,OAAO;GACR;EACF;CACD,iBAAiB;EACf,MAAM;EACN,QAAQ;EACR,WAAW;EACZ;CACF,CACF;AAED,SAAwB,MAAM,OAAmB;CAC/C,MAAM,EACJ,OACA,SAAS,WACT,MACA,WACA,OACA,SACA,GAAG,SACD;AAIJ,KAFc,UAAU,MAAM,UAAU,QAE7B;EACT,MAAM,eAAe,GACnB,mFACA,kBAAkB,SAClB,OAAO,YAAY,cAAc,qBACjC,UACD;AAED,MAAI,QACF,QACE,oBAAC,UAAD;GACE,MAAK;GACL,GAAI;GACJ,WAAW;GACX,OAAO;IAAE,OAAO;IAAG,QAAQ;IAAG,KAAK;IAAG,GAAG;IAAO;GAChD,cAAW;GACF;GACT,CAAA;AAIN,SACE,oBAAC,OAAD;GACE,GAAI;GACJ,WAAW,GACT,mFACA,kBAAkB,SAClB,OAAO,YAAY,cAAc,qBACjC,UACD;GACD,OAAO;IAAE,OAAO;IAAG,QAAQ;IAAG,KAAK;IAAG,GAAG;IAAO;GACvC;GACT,CAAA;;CAIN,MAAM,YACJ,OAAO,UAAU,YAChB,OAAO,UAAU,YAAY,aAAa,KAAK,MAAM,MAAM,CAAC;AAE/D,QACE,oBAAC,OAAD;EACE,GAAI;EACJ,WAAW,GACT,cAAc;GACZ,MAAM,QAAQ;GACd;GACA,WAAW,OAAO,YAAY;GAC/B,CAAC,EACF,UACD;EACD,OAAO,YAAY;GAAE,YAAY;GAAa,GAAG;GAAO,GAAG;EAC3D,GAAK,UACD;GACE,MAAM;GACN,UAAU;GACV,YAAY,UAA+C;AACzD,QAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,WAAM,gBAAgB;AACtB,aAAQ,MAAqC;;;GAGlD,GACD,EAAE;EACG;YAER;EACG,CAAA"}
|
package/dist/Breadcrumb/index.js
CHANGED
|
@@ -30,13 +30,16 @@ var Breadcrumb = (props) => {
|
|
|
30
30
|
className: "ald-breadcrumb-link tw-text-[var(--content-brand-secondary)] hover:tw-text-[var(--content-brand-primary)]",
|
|
31
31
|
href: item.href,
|
|
32
32
|
onClick: item.onClick,
|
|
33
|
+
"aria-current": isLast ? "page" : void 0,
|
|
33
34
|
children: item.title
|
|
34
35
|
}) : /* @__PURE__ */ jsx("span", {
|
|
35
36
|
onClick: item.onClick,
|
|
37
|
+
"aria-current": isLast ? "page" : void 0,
|
|
36
38
|
children: item.title
|
|
37
39
|
})
|
|
38
40
|
}), separator !== null && !isLast && /* @__PURE__ */ jsx("span", {
|
|
39
41
|
className: "ald-breadcrumb-separator tw-inline-flex tw-items-center",
|
|
42
|
+
"aria-hidden": "true",
|
|
40
43
|
children: separator
|
|
41
44
|
})] }, index);
|
|
42
45
|
});
|
|
@@ -45,6 +48,7 @@ var Breadcrumb = (props) => {
|
|
|
45
48
|
const isLast = index === childArray.length - 1;
|
|
46
49
|
return /* @__PURE__ */ jsxs(React.Fragment, { children: [React.isValidElement(child) ? React.cloneElement(child, { "data-last": isLast ? "true" : void 0 }) : child, separator !== null && !isLast && /* @__PURE__ */ jsx("span", {
|
|
47
50
|
className: "ald-breadcrumb-separator tw-inline-flex tw-items-center",
|
|
51
|
+
"aria-hidden": "true",
|
|
48
52
|
children: separator
|
|
49
53
|
})] }, index);
|
|
50
54
|
});
|
|
@@ -52,19 +56,25 @@ var Breadcrumb = (props) => {
|
|
|
52
56
|
return /* @__PURE__ */ jsx("nav", {
|
|
53
57
|
className: cn("ald-breadcrumb tw-flex tw-items-center tw-text-sm", className),
|
|
54
58
|
style,
|
|
59
|
+
"aria-label": "Breadcrumb",
|
|
55
60
|
children: renderItems()
|
|
56
61
|
});
|
|
57
62
|
};
|
|
58
63
|
var BreadcrumbItem = (props) => {
|
|
59
64
|
const { className, children, href, onClick, ...rest } = props;
|
|
65
|
+
const isLast = rest["data-last"] === "true";
|
|
60
66
|
return /* @__PURE__ */ jsx("span", {
|
|
61
|
-
className: cn("ald-breadcrumb-item tw-cursor-pointer tw-text-sm [&_a:hover]:tw-text-[var(--content-brand-primary)] [&_a]:tw-text-[var(--content-brand-secondary)]",
|
|
67
|
+
className: cn("ald-breadcrumb-item tw-cursor-pointer tw-text-sm [&_a:hover]:tw-text-[var(--content-brand-primary)] [&_a]:tw-text-[var(--content-brand-secondary)]", isLast ? "tw-text-[var(--content-primary)]" : "tw-text-[var(--content-tertiary)] hover:tw-text-[var(--content-primary)]", className),
|
|
62
68
|
onClick,
|
|
63
69
|
children: href ? /* @__PURE__ */ jsx("a", {
|
|
64
70
|
className: "ald-breadcrumb-link tw-text-[var(--content-brand-secondary)] hover:tw-text-[var(--content-brand-primary)]",
|
|
65
71
|
href,
|
|
72
|
+
"aria-current": isLast ? "page" : void 0,
|
|
66
73
|
children
|
|
67
|
-
}) :
|
|
74
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
75
|
+
"aria-current": isLast ? "page" : void 0,
|
|
76
|
+
children
|
|
77
|
+
})
|
|
68
78
|
});
|
|
69
79
|
};
|
|
70
80
|
BreadcrumbItem.__ANT_BREADCRUMB_ITEM = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Breadcrumb/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../lib/utils';\n\nconst DefaultSeparator = () => (\n <span className=\"default-separator tw-mx-1 tw-inline-flex tw-items-center tw-text-[var(--content-tertiary)]\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 3.5L10.5 8L6 12.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n);\n\nexport interface BreadcrumbProps {\n className?: string;\n style?: React.CSSProperties;\n separator?: React.ReactNode;\n items?: Array<{\n title: React.ReactNode;\n href?: string;\n onClick?: (e: React.MouseEvent) => void;\n className?: string;\n }>;\n children?: React.ReactNode;\n}\n\nexport interface BreadcrumbItemProps {\n className?: string;\n children?: React.ReactNode;\n href?: string;\n onClick?: (e: React.MouseEvent) => void;\n}\n\ninterface IBreadcrumbItemInterface extends React.FC<BreadcrumbItemProps> {\n __ANT_BREADCRUMB_ITEM: boolean;\n}\n\nconst Breadcrumb = (props: BreadcrumbProps) => {\n const {\n className,\n style,\n separator = <DefaultSeparator />,\n items,\n children,\n } = props;\n\n const renderItems = () => {\n if (items) {\n return items.map((item, index) => {\n const isLast = index === items.length - 1;\n return (\n <React.Fragment key={index}>\n <span\n className={cn(\n 'ald-breadcrumb-item tw-cursor-pointer tw-text-sm [&_a:hover]:tw-text-[var(--content-brand-primary)] [&_a]:tw-text-[var(--content-brand-secondary)]',\n isLast\n ? 'tw-text-[var(--content-primary)]'\n : 'tw-text-[var(--content-tertiary)] hover:tw-text-[var(--content-primary)]',\n item.className,\n )}\n >\n {item.href ? (\n <a\n className=\"ald-breadcrumb-link tw-text-[var(--content-brand-secondary)] hover:tw-text-[var(--content-brand-primary)]\"\n href={item.href}\n onClick={item.onClick}\n >\n {item.title}\n </a>\n ) : (\n <span
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Breadcrumb/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../lib/utils';\n\nconst DefaultSeparator = () => (\n <span className=\"default-separator tw-mx-1 tw-inline-flex tw-items-center tw-text-[var(--content-tertiary)]\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 3.5L10.5 8L6 12.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n);\n\nexport interface BreadcrumbProps {\n className?: string;\n style?: React.CSSProperties;\n separator?: React.ReactNode;\n items?: Array<{\n title: React.ReactNode;\n href?: string;\n onClick?: (e: React.MouseEvent) => void;\n className?: string;\n }>;\n children?: React.ReactNode;\n}\n\nexport interface BreadcrumbItemProps {\n className?: string;\n children?: React.ReactNode;\n href?: string;\n onClick?: (e: React.MouseEvent) => void;\n}\n\ninterface IBreadcrumbItemInterface extends React.FC<BreadcrumbItemProps> {\n __ANT_BREADCRUMB_ITEM: boolean;\n}\n\nconst Breadcrumb = (props: BreadcrumbProps) => {\n const {\n className,\n style,\n separator = <DefaultSeparator />,\n items,\n children,\n } = props;\n\n const renderItems = () => {\n if (items) {\n return items.map((item, index) => {\n const isLast = index === items.length - 1;\n return (\n <React.Fragment key={index}>\n <span\n className={cn(\n 'ald-breadcrumb-item tw-cursor-pointer tw-text-sm [&_a:hover]:tw-text-[var(--content-brand-primary)] [&_a]:tw-text-[var(--content-brand-secondary)]',\n isLast\n ? 'tw-text-[var(--content-primary)]'\n : 'tw-text-[var(--content-tertiary)] hover:tw-text-[var(--content-primary)]',\n item.className,\n )}\n >\n {item.href ? (\n <a\n className=\"ald-breadcrumb-link tw-text-[var(--content-brand-secondary)] hover:tw-text-[var(--content-brand-primary)]\"\n href={item.href}\n onClick={item.onClick}\n aria-current={isLast ? 'page' : undefined}\n >\n {item.title}\n </a>\n ) : (\n <span\n onClick={item.onClick}\n aria-current={isLast ? 'page' : undefined}\n >\n {item.title}\n </span>\n )}\n </span>\n {separator !== null && !isLast && (\n <span\n className=\"ald-breadcrumb-separator tw-inline-flex tw-items-center\"\n aria-hidden=\"true\"\n >\n {separator}\n </span>\n )}\n </React.Fragment>\n );\n });\n }\n\n const childArray = React.Children.toArray(children);\n return childArray.map((child, index) => {\n const isLast = index === childArray.length - 1;\n return (\n <React.Fragment key={index}>\n {React.isValidElement(child)\n ? React.cloneElement(child as React.ReactElement, {\n 'data-last': isLast ? 'true' : undefined,\n })\n : child}\n {separator !== null && !isLast && (\n <span\n className=\"ald-breadcrumb-separator tw-inline-flex tw-items-center\"\n aria-hidden=\"true\"\n >\n {separator}\n </span>\n )}\n </React.Fragment>\n );\n });\n };\n\n return (\n <nav\n className={cn(\n 'ald-breadcrumb tw-flex tw-items-center tw-text-sm',\n className,\n )}\n style={style}\n aria-label=\"Breadcrumb\"\n >\n {renderItems()}\n </nav>\n );\n};\n\nconst BreadcrumbItem: IBreadcrumbItemInterface = (\n props: BreadcrumbItemProps & { 'data-last'?: string },\n) => {\n const { className, children, href, onClick, ...rest } = props;\n const isLast = rest['data-last'] === 'true';\n return (\n <span\n className={cn(\n 'ald-breadcrumb-item tw-cursor-pointer tw-text-sm [&_a:hover]:tw-text-[var(--content-brand-primary)] [&_a]:tw-text-[var(--content-brand-secondary)]',\n isLast\n ? 'tw-text-[var(--content-primary)]'\n : 'tw-text-[var(--content-tertiary)] hover:tw-text-[var(--content-primary)]',\n className,\n )}\n onClick={onClick}\n >\n {href ? (\n <a\n className=\"ald-breadcrumb-link tw-text-[var(--content-brand-secondary)] hover:tw-text-[var(--content-brand-primary)]\"\n href={href}\n aria-current={isLast ? 'page' : undefined}\n >\n {children}\n </a>\n ) : (\n <span aria-current={isLast ? 'page' : undefined}>{children}</span>\n )}\n </span>\n );\n};\n\nBreadcrumbItem.__ANT_BREADCRUMB_ITEM = true;\n\nBreadcrumb.Item = BreadcrumbItem;\n\nexport default Breadcrumb;\n"],"mappings":";;;;AAGA,IAAM,yBACJ,oBAAC,QAAD;CAAM,WAAU;WACd,oBAAC,OAAD;EACE,OAAM;EACN,QAAO;EACP,SAAQ;EACR,MAAK;EACL,OAAM;YAEN,oBAAC,QAAD;GACE,GAAE;GACF,QAAO;GACP,aAAY;GACZ,eAAc;GACd,gBAAe;GACf,CAAA;EACE,CAAA;CACD,CAAA;AA2BT,IAAM,cAAc,UAA2B;CAC7C,MAAM,EACJ,WACA,OACA,YAAY,oBAAC,kBAAD,EAAoB,CAAA,EAChC,OACA,aACE;CAEJ,MAAM,oBAAoB;AACxB,MAAI,MACF,QAAO,MAAM,KAAK,MAAM,UAAU;GAChC,MAAM,SAAS,UAAU,MAAM,SAAS;AACxC,UACE,qBAAC,MAAM,UAAP,EAAA,UAAA,CACE,oBAAC,QAAD;IACE,WAAW,GACT,sJACA,SACI,qCACA,4EACJ,KAAK,UACN;cAEA,KAAK,OACJ,oBAAC,KAAD;KACE,WAAU;KACV,MAAM,KAAK;KACX,SAAS,KAAK;KACd,gBAAc,SAAS,SAAS;eAE/B,KAAK;KACJ,CAAA,GAEJ,oBAAC,QAAD;KACE,SAAS,KAAK;KACd,gBAAc,SAAS,SAAS;eAE/B,KAAK;KACD,CAAA;IAEJ,CAAA,EACN,cAAc,QAAQ,CAAC,UACtB,oBAAC,QAAD;IACE,WAAU;IACV,eAAY;cAEX;IACI,CAAA,CAEM,EAAA,EApCI,MAoCJ;IAEnB;EAGJ,MAAM,aAAa,MAAM,SAAS,QAAQ,SAAS;AACnD,SAAO,WAAW,KAAK,OAAO,UAAU;GACtC,MAAM,SAAS,UAAU,WAAW,SAAS;AAC7C,UACE,qBAAC,MAAM,UAAP,EAAA,UAAA,CACG,MAAM,eAAe,MAAM,GACxB,MAAM,aAAa,OAA6B,EAC9C,aAAa,SAAS,SAAS,QAChC,CAAC,GACF,OACH,cAAc,QAAQ,CAAC,UACtB,oBAAC,QAAD;IACE,WAAU;IACV,eAAY;cAEX;IACI,CAAA,CAEM,EAAA,EAdI,MAcJ;IAEnB;;AAGJ,QACE,oBAAC,OAAD;EACE,WAAW,GACT,qDACA,UACD;EACM;EACP,cAAW;YAEV,aAAa;EACV,CAAA;;AAIV,IAAM,kBACJ,UACG;CACH,MAAM,EAAE,WAAW,UAAU,MAAM,SAAS,GAAG,SAAS;CACxD,MAAM,SAAS,KAAK,iBAAiB;AACrC,QACE,oBAAC,QAAD;EACE,WAAW,GACT,sJACA,SACI,qCACA,4EACJ,UACD;EACQ;YAER,OACC,oBAAC,KAAD;GACE,WAAU;GACJ;GACN,gBAAc,SAAS,SAAS;GAE/B;GACC,CAAA,GAEJ,oBAAC,QAAD;GAAM,gBAAc,SAAS,SAAS;GAAY;GAAgB,CAAA;EAE/D,CAAA;;AAIX,eAAe,wBAAwB;AAEvC,WAAW,OAAO"}
|
package/dist/Button/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
export declare const btnPrefix = "ald-btn";
|
|
3
|
-
export type ButtonType = 'primary' | 'secondary' | 'dangerous' | 'text' | 'inverse' | 'link';
|
|
3
|
+
export type ButtonType = 'primary' | 'secondary' | 'dangerous' | 'text' | 'inverse' | 'link' | 'ghost' | 'ghostIcon';
|
|
4
4
|
export type Size = 'small' | 'middle' | 'large';
|
|
5
5
|
export interface IButtonProps {
|
|
6
6
|
type?: ButtonType;
|
package/dist/Button/index.js
CHANGED
|
@@ -41,9 +41,9 @@ var buttonVariants = cva([
|
|
|
41
41
|
],
|
|
42
42
|
secondary: [
|
|
43
43
|
`${btnPrefix}-secondary`,
|
|
44
|
-
"tw-border-[var(--
|
|
45
|
-
"hover:tw-border-[var(--
|
|
46
|
-
"active:tw-border-[var(--
|
|
44
|
+
"tw-border-[var(--border-default)] tw-bg-[var(--action-inverted-normal)] tw-text-[var(--action-neutral-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]",
|
|
45
|
+
"hover:tw-border-[var(--border-neutral-strong)] hover:tw-bg-[var(--action-inverted-normal)]",
|
|
46
|
+
"active:tw-border-[var(--border-neutral-strong)] active:tw-bg-[var(--action-inverted-active)] active:tw-text-[var(--action-neutral-active)]"
|
|
47
47
|
],
|
|
48
48
|
dangerous: [
|
|
49
49
|
`${btnPrefix}-dangerous`,
|
|
@@ -68,6 +68,18 @@ var buttonVariants = cva([
|
|
|
68
68
|
"tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--action-primary-normal)]",
|
|
69
69
|
"hover:tw-text-[var(--action-primary-hover)]",
|
|
70
70
|
"active:tw-text-[var(--action-primary-active)]"
|
|
71
|
+
],
|
|
72
|
+
ghost: [
|
|
73
|
+
`${btnPrefix}-ghost`,
|
|
74
|
+
"tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--action-neutral-normal)] tw-shadow-none",
|
|
75
|
+
"hover:tw-bg-[var(--action-ghost-hover)] hover:tw-text-[var(--action-neutral-hover)]",
|
|
76
|
+
"active:tw-bg-[var(--action-ghost-active)] active:tw-text-[var(--action-neutral-active)]"
|
|
77
|
+
],
|
|
78
|
+
ghostIcon: [
|
|
79
|
+
`${btnPrefix}-ghost-icon`,
|
|
80
|
+
"tw-border-0 tw-bg-[var(--action-ghost-normal)] tw-text-[var(--content-secondary)] tw-shadow-none",
|
|
81
|
+
"hover:tw-bg-[var(--action-ghost-hover)] hover:tw-text-[var(--content-primary)]",
|
|
82
|
+
"active:tw-bg-[var(--action-ghost-active)] active:tw-text-[var(--content-primary)]"
|
|
71
83
|
]
|
|
72
84
|
},
|
|
73
85
|
size: {
|
|
@@ -114,7 +126,9 @@ var VALID_TYPES = [
|
|
|
114
126
|
"dangerous",
|
|
115
127
|
"text",
|
|
116
128
|
"inverse",
|
|
117
|
-
"link"
|
|
129
|
+
"link",
|
|
130
|
+
"ghost",
|
|
131
|
+
"ghostIcon"
|
|
118
132
|
];
|
|
119
133
|
function Button(props, ref) {
|
|
120
134
|
const { type: rawType = "secondary", size: customSize, shape = "default", loading = false, disabled, icon, className, children, href, target, onClick, block, htmlType = "button", style, ghost, showArrow = false, ...rest } = props;
|
|
@@ -133,7 +147,7 @@ function Button(props, ref) {
|
|
|
133
147
|
setInnerLoading(!!loading);
|
|
134
148
|
}, [loading]);
|
|
135
149
|
const isDisabled = innerLoading || mergedDisabled;
|
|
136
|
-
const iconNode = setIcon(icon, innerLoading, size === "small" ? 12 : 14);
|
|
150
|
+
const iconNode = setIcon(icon, innerLoading, type === "ghostIcon" ? size === "small" ? 16 : size === "large" ? 24 : 20 : size === "small" ? 12 : 14);
|
|
137
151
|
const compactClasses = compactItemClassnames ? cn(!compactItemClassnames[`ald-btn-compact-first-item`] && "!tw-rounded-l-none", !compactItemClassnames[`ald-btn-compact-last-item`] && "!tw-rounded-r-none", !compactItemClassnames[`ald-btn-compact-first-item`] && "-tw-ml-px") : void 0;
|
|
138
152
|
const isIconOnly = !!icon && !children && !showArrow;
|
|
139
153
|
const focusRingClasses = !isDisabled && [
|
|
@@ -149,7 +163,7 @@ function Button(props, ref) {
|
|
|
149
163
|
disabled: !!isDisabled,
|
|
150
164
|
block: !!block,
|
|
151
165
|
shape
|
|
152
|
-
}), ghost && "!tw-border-[var(--action-ghost-normal)] !tw-bg-[var(--action-ghost-normal)] !tw-shadow-none hover:!tw-border-[var(--action-ghost-normal)]", ghost && type === "primary" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "dangerous" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "secondary" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "inverse" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-bg-[var(--action-ghost-normal)] !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "primary" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-primary-subtle-hover)]", ghost && type === "dangerous" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-destructive-hover)]", ghost && type === "secondary" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-hover)]", ghost && type === "inverse" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-inverted-hover)]", ghost && type === "primary" && "!tw-text-[var(--action-primary-normal)]", ghost && type === "dangerous" && "!tw-text-[var(--action-destructive-normal)]", ghost && type === "secondary" && "!tw-text-[var(--action-neutral-normal)]", ghost && type === "inverse" && "!tw-text-[var(--action-inverted-normal)]", isIconOnly && "tw-aspect-square !tw-px-0", isIconOnly && size === "small" && "!tw-min-w-7", isIconOnly && size === "middle" && "!tw-min-w-8", isIconOnly && size === "large" && "!tw-min-w-10", focusRingClasses, compactClasses, className);
|
|
166
|
+
}), ghost && "!tw-border-[var(--action-ghost-normal)] !tw-bg-[var(--action-ghost-normal)] !tw-shadow-none hover:!tw-border-[var(--action-ghost-normal)]", ghost && type === "primary" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "dangerous" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "secondary" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "inverse" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-bg-[var(--action-ghost-normal)] !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "primary" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-primary-subtle-hover)]", ghost && type === "dangerous" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-destructive-hover)]", ghost && type === "secondary" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-hover)]", ghost && type === "inverse" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-inverted-hover)]", ghost && type === "primary" && "!tw-text-[var(--action-primary-normal)]", ghost && type === "dangerous" && "!tw-text-[var(--action-destructive-normal)]", ghost && type === "secondary" && "!tw-text-[var(--action-neutral-normal)]", ghost && type === "inverse" && "!tw-text-[var(--action-inverted-normal)]", isIconOnly && "tw-aspect-square !tw-px-0", isIconOnly && size === "small" && "!tw-min-w-7", isIconOnly && size === "middle" && "!tw-min-w-8", isIconOnly && size === "large" && "!tw-min-w-10", type === "ghostIcon" && "!tw-aspect-auto !tw-min-w-0 !tw-gap-0 !tw-border-0 !tw-p-0 !tw-shadow-none", type === "ghostIcon" && size === "small" && "!tw-h-5 !tw-w-5 !tw-rounded-r-50", type === "ghostIcon" && size === "middle" && "!tw-h-6 !tw-w-6 !tw-rounded-r-75", type === "ghostIcon" && size === "large" && "!tw-h-7 !tw-w-7 !tw-rounded-r-100", focusRingClasses, compactClasses, className);
|
|
153
167
|
const contentClasses = cn("tw-inline-flex tw-min-w-0 tw-items-center tw-gap-1 tw-truncate tw-text-typography-label", ghost && type === "inverse" && size === "middle" && "tw-flex-[1_0_0] tw-text-[var(--action-inverted-normal)]");
|
|
154
168
|
const buttonContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
155
169
|
iconNode,
|
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 { ChevronDownLine, 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 'aria-label'?: string;\n /** 透传到 button 元素的 data-testid,用于自动化测试定位(经 rest props 透传) */\n 'data-testid'?: string;\n ghost?: boolean;\n danger?: boolean;\n color?: string;\n showArrow?: 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 size: string | number = '1em',\n) => {\n if (loading) {\n return (\n <LoadingLine\n className=\"ald-loading-spin tw-shrink-0 tw-animate-spin\"\n size={size}\n color=\"currentColor\"\n />\n );\n }\n\n if (iconNode) {\n const p: Record<string, string | number> = {\n className: '',\n fill: 'currentColor',\n ...iconNode.props,\n };\n p.size = size;\n return React.cloneElement(iconNode, p);\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-no-underline tw-transition-colors [&_.i-icon]:tw-inline-flex [&_.i-icon]:tw-items-center',\n 'tw-border tw-border-solid',\n ],\n {\n variants: {\n type: {\n primary: [\n `${btnPrefix}-primary`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)] tw-text-[var(--action-inverted-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-bg-[var(--action-primary-hover)]',\n '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)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-border-[var(--action-outline-hover)] hover:tw-bg-[var(--action-inverted-normal)]',\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-ghost-normal)] tw-bg-[var(--action-destructive-normal)] tw-text-[var(--action-inverted-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-bg-[var(--action-destructive-hover)]',\n 'active:tw-bg-[var(--action-destructive-active)]',\n ],\n text: [\n `${btnPrefix}-text`,\n 'tw-border-[var(--action-ghost-normal)] 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-[var(--action-neutral-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--content-inverted-primary)]',\n 'hover:tw-border-[var(--action-ghost-inverted-hover)] hover:tw-bg-[var(--action-ghost-normal)]',\n 'active:tw-bg-[var(--action-ghost-inverted-active)]',\n ],\n link: [\n `${btnPrefix}-link`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-ghost-normal)] 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 // Component Geometry: size variants own the control envelope. The\n // inline gap remains relationship-preserving implementation while the\n // Action Association Constraint has no Primitive Resolution.\n small: [\n `${btnPrefix}-small`,\n 'tw-h-7 tw-min-w-7 tw-gap-1 tw-rounded-r-75',\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-8 tw-gap-1 tw-rounded-r-75',\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-10 tw-min-w-10 tw-gap-1 tw-rounded-r-75',\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 'link',\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 showArrow = false,\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 iconSize = size === 'small' ? 12 : 14;\n const iconNode = setIcon(icon as React.ReactElement, innerLoading, iconSize);\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 && !showArrow;\n const focusRingClasses = !isDisabled && [\n 'focus-visible:tw-outline',\n 'focus-visible:tw-outline-2',\n 'focus-visible:tw-outline-offset-2',\n 'focus-visible:tw-outline-[var(--focus-ring)]',\n 'forced-colors:focus-visible:tw-outline-[Highlight]',\n ];\n\n const classes = cn(\n buttonVariants({\n type,\n size,\n disabled: !!isDisabled,\n block: !!block,\n shape,\n }),\n ghost &&\n '!tw-border-[var(--action-ghost-normal)] !tw-bg-[var(--action-ghost-normal)] !tw-shadow-none hover:!tw-border-[var(--action-ghost-normal)]',\n ghost &&\n type === 'primary' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'dangerous' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'secondary' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'inverse' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-bg-[var(--action-ghost-normal)] !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'primary' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-primary-subtle-hover)]',\n ghost &&\n type === 'dangerous' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-destructive-hover)]',\n ghost &&\n type === 'secondary' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-hover)]',\n ghost &&\n type === 'inverse' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-inverted-hover)]',\n ghost && type === 'primary' && '!tw-text-[var(--action-primary-normal)]',\n ghost &&\n type === 'dangerous' &&\n '!tw-text-[var(--action-destructive-normal)]',\n ghost && type === 'secondary' && '!tw-text-[var(--action-neutral-normal)]',\n ghost && type === 'inverse' && '!tw-text-[var(--action-inverted-normal)]',\n // icon-only 方形按钮:宽度由 aspect-ratio 从 height 反推,但该反推值\n // 不构成 flex shrink 的下限——父行 max-content 被低估时(同行存在\n // width:auto Select / RangePicker 等子树时 Chromium 恒少算几 px),\n // 缺口会全压到本按钮上把它压扁。必须按 size 显式钳 min-width 兜底\n // (v2/antd 的 icon-only 即固定 width);带 ! 以盖过 shape=circle\n // 的 tw-min-w-0\n isIconOnly && 'tw-aspect-square !tw-px-0',\n isIconOnly && size === 'small' && '!tw-min-w-7',\n isIconOnly && size === 'middle' && '!tw-min-w-8',\n isIconOnly && size === 'large' && '!tw-min-w-10',\n focusRingClasses,\n compactClasses,\n className,\n );\n\n const contentClasses = cn(\n // Typography: the approved Label utility belongs to the text-bearing\n // element. Icon-only controls intentionally have no label Typography.\n 'tw-inline-flex tw-min-w-0 tw-items-center tw-gap-1 tw-truncate tw-text-typography-label',\n ghost &&\n type === 'inverse' &&\n size === 'middle' &&\n 'tw-flex-[1_0_0] tw-text-[var(--action-inverted-normal)]',\n );\n\n const arrowNode = showArrow ? (\n <span className=\"ald-btn-arrow tw-inline-flex tw-shrink-0 tw-items-center\">\n <ChevronDownLine size={16} />\n </span>\n ) : null;\n\n const buttonContent = (\n <>\n {iconNode}\n {children && <span className={contentClasses}>{children}</span>}\n {arrowNode}\n </>\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 {buttonContent}\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 {buttonContent}\n </button>\n );\n}\n\nexport default forwardRef(Button);\n"],"mappings":";;;;;;;;;;AAQA,IAAa,YAAY;AAmDzB,IAAa,WACX,UACA,SACA,OAAwB,UACrB;AACH,KAAI,QACF,QACE,oBAAC,QAAD;EACE,WAAU;EACJ;EACN,OAAM;EACN,CAAA;AAIN,KAAI,UAAU;EACZ,MAAM,IAAqC;GACzC,WAAW;GACX,MAAM;GACN,GAAG,SAAS;GACb;AACD,IAAE,OAAO;AACT,SAAO,MAAM,aAAa,UAAU,EAAE;;AAExC,QAAO,oBAAA,UAAA,EAAK,CAAA;;AAGd,IAAM,iBAAiB,IACrB;CACE;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;GAIJ,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;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,YAAY,OACZ,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;CAEnC,MAAM,WAAW,QAAQ,MAA4B,cADpC,SAAS,UAAU,KAAK,GACmC;CAG5E,MAAM,iBAAiB,wBACnB,GAEE,CAAC,sBAAsB,iCACrB,sBACF,CAAC,sBAAsB,gCACrB,sBAEF,CAAC,sBAAsB,iCACrB,YACH,GACD;CAEJ,MAAM,aAAa,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;CAC3C,MAAM,mBAAmB,CAAC,cAAc;EACtC;EACA;EACA;EACA;EACA;EACD;CAED,MAAM,UAAU,GACd,eAAe;EACb;EACA;EACA,UAAU,CAAC,CAAC;EACZ,OAAO,CAAC,CAAC;EACT;EACD,CAAC,EACF,SACE,6IACF,SACE,SAAS,aACT,SAAS,YACT,wHACF,SACE,SAAS,eACT,SAAS,YACT,wHACF,SACE,SAAS,eACT,SAAS,YACT,wHACF,SACE,SAAS,aACT,SAAS,YACT,4JACF,SACE,SAAS,aACT,sEACF,SACE,SAAS,eACT,yEACF,SACE,SAAS,eACT,6DACF,SACE,SAAS,aACT,sEACF,SAAS,SAAS,aAAa,2CAC/B,SACE,SAAS,eACT,+CACF,SAAS,SAAS,eAAe,2CACjC,SAAS,SAAS,aAAa,4CAO/B,cAAc,6BACd,cAAc,SAAS,WAAW,eAClC,cAAc,SAAS,YAAY,eACnC,cAAc,SAAS,WAAW,gBAClC,kBACA,gBACA,UACD;CAED,MAAM,iBAAiB,GAGrB,2FACA,SACE,SAAS,aACT,SAAS,YACT,0DACH;CAQD,MAAM,gBACJ,qBAAA,UAAA,EAAA,UAAA;EACG;EACA,YAAY,oBAAC,QAAD;GAAM,WAAW;GAAiB;GAAgB,CAAA;EATjD,YAChB,oBAAC,QAAD;GAAM,WAAU;aACd,oBAAC,MAAD,EAAiB,MAAM,IAAM,CAAA;GACxB,CAAA,GACL;EAOC,EAAA,CAAA;AAGL,KAAI,KACF,QACE,oBAAC,KAAD;EACE,GAAI;EACJ,WAAW;EACJ;EACP,MAAM,aAAa,SAAY;EACvB;EACH;EACL,SAAS,aAAa,SAAY;EAClC,iBAAe,cAAc;YAE5B;EACC,CAAA;AAIR,QACE,oBAAC,UAAD;EACE,GAAI;EACJ,MACE,aAAa,WACT,WACA,aAAa,UACb,UACA;EAEN,WAAW;EACJ;EACP,UAAU;EACV,iBAAe,cAAc;EACxB;EACI;YAER;EACM,CAAA;;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 { ChevronDownLine, 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'\n | 'ghost'\n | 'ghostIcon';\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 'aria-label'?: string;\n /** 透传到 button 元素的 data-testid,用于自动化测试定位(经 rest props 透传) */\n 'data-testid'?: string;\n ghost?: boolean;\n danger?: boolean;\n color?: string;\n showArrow?: 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 size: string | number = '1em',\n) => {\n if (loading) {\n return (\n <LoadingLine\n className=\"ald-loading-spin tw-shrink-0 tw-animate-spin\"\n size={size}\n color=\"currentColor\"\n />\n );\n }\n\n if (iconNode) {\n const p: Record<string, string | number> = {\n className: '',\n fill: 'currentColor',\n ...iconNode.props,\n };\n p.size = size;\n return React.cloneElement(iconNode, p);\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-no-underline tw-transition-colors [&_.i-icon]:tw-inline-flex [&_.i-icon]:tw-items-center',\n 'tw-border tw-border-solid',\n ],\n {\n variants: {\n type: {\n primary: [\n `${btnPrefix}-primary`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)] tw-text-[var(--action-inverted-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-bg-[var(--action-primary-hover)]',\n 'active:tw-bg-[var(--action-primary-active)]',\n ],\n secondary: [\n `${btnPrefix}-secondary`,\n 'tw-border-[var(--border-default)] tw-bg-[var(--action-inverted-normal)] tw-text-[var(--action-neutral-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-border-[var(--border-neutral-strong)] hover:tw-bg-[var(--action-inverted-normal)]',\n 'active:tw-border-[var(--border-neutral-strong)] 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-ghost-normal)] tw-bg-[var(--action-destructive-normal)] tw-text-[var(--action-inverted-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-bg-[var(--action-destructive-hover)]',\n 'active:tw-bg-[var(--action-destructive-active)]',\n ],\n text: [\n `${btnPrefix}-text`,\n 'tw-border-[var(--action-ghost-normal)] 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-[var(--action-neutral-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--content-inverted-primary)]',\n 'hover:tw-border-[var(--action-ghost-inverted-hover)] hover:tw-bg-[var(--action-ghost-normal)]',\n 'active:tw-bg-[var(--action-ghost-inverted-active)]',\n ],\n link: [\n `${btnPrefix}-link`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--action-primary-normal)]',\n 'hover:tw-text-[var(--action-primary-hover)]',\n 'active:tw-text-[var(--action-primary-active)]',\n ],\n ghost: [\n `${btnPrefix}-ghost`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--action-neutral-normal)] tw-shadow-none',\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 ghostIcon: [\n `${btnPrefix}-ghost-icon`,\n 'tw-border-0 tw-bg-[var(--action-ghost-normal)] tw-text-[var(--content-secondary)] tw-shadow-none',\n 'hover:tw-bg-[var(--action-ghost-hover)] hover:tw-text-[var(--content-primary)]',\n 'active:tw-bg-[var(--action-ghost-active)] active:tw-text-[var(--content-primary)]',\n ],\n },\n size: {\n // Component Geometry: size variants own the control envelope. The\n // inline gap remains relationship-preserving implementation while the\n // Action Association Constraint has no Primitive Resolution.\n small: [\n `${btnPrefix}-small`,\n 'tw-h-7 tw-min-w-7 tw-gap-1 tw-rounded-r-75',\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-8 tw-gap-1 tw-rounded-r-75',\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-10 tw-min-w-10 tw-gap-1 tw-rounded-r-75',\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 'link',\n 'ghost',\n 'ghostIcon',\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 showArrow = false,\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 iconSize =\n type === 'ghostIcon'\n ? size === 'small'\n ? 16\n : size === 'large'\n ? 24\n : 20\n : size === 'small'\n ? 12\n : 14;\n const iconNode = setIcon(icon as React.ReactElement, innerLoading, iconSize);\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 && !showArrow;\n const focusRingClasses = !isDisabled && [\n 'focus-visible:tw-outline',\n 'focus-visible:tw-outline-2',\n 'focus-visible:tw-outline-offset-2',\n 'focus-visible:tw-outline-[var(--focus-ring)]',\n 'forced-colors:focus-visible:tw-outline-[Highlight]',\n ];\n\n const classes = cn(\n buttonVariants({\n type,\n size,\n disabled: !!isDisabled,\n block: !!block,\n shape,\n }),\n ghost &&\n '!tw-border-[var(--action-ghost-normal)] !tw-bg-[var(--action-ghost-normal)] !tw-shadow-none hover:!tw-border-[var(--action-ghost-normal)]',\n ghost &&\n type === 'primary' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'dangerous' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'secondary' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'inverse' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-bg-[var(--action-ghost-normal)] !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'primary' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-primary-subtle-hover)]',\n ghost &&\n type === 'dangerous' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-destructive-hover)]',\n ghost &&\n type === 'secondary' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-hover)]',\n ghost &&\n type === 'inverse' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-inverted-hover)]',\n ghost && type === 'primary' && '!tw-text-[var(--action-primary-normal)]',\n ghost &&\n type === 'dangerous' &&\n '!tw-text-[var(--action-destructive-normal)]',\n ghost && type === 'secondary' && '!tw-text-[var(--action-neutral-normal)]',\n ghost && type === 'inverse' && '!tw-text-[var(--action-inverted-normal)]',\n // icon-only 方形按钮:宽度由 aspect-ratio 从 height 反推,但该反推值\n // 不构成 flex shrink 的下限——父行 max-content 被低估时(同行存在\n // width:auto Select / RangePicker 等子树时 Chromium 恒少算几 px),\n // 缺口会全压到本按钮上把它压扁。必须按 size 显式钳 min-width 兜底\n // (v2/antd 的 icon-only 即固定 width);带 ! 以盖过 shape=circle\n // 的 tw-min-w-0\n isIconOnly && 'tw-aspect-square !tw-px-0',\n isIconOnly && size === 'small' && '!tw-min-w-7',\n isIconOnly && size === 'middle' && '!tw-min-w-8',\n isIconOnly && size === 'large' && '!tw-min-w-10',\n type === 'ghostIcon' &&\n '!tw-aspect-auto !tw-min-w-0 !tw-gap-0 !tw-border-0 !tw-p-0 !tw-shadow-none',\n type === 'ghostIcon' &&\n size === 'small' &&\n '!tw-h-5 !tw-w-5 !tw-rounded-r-50',\n type === 'ghostIcon' &&\n size === 'middle' &&\n '!tw-h-6 !tw-w-6 !tw-rounded-r-75',\n type === 'ghostIcon' &&\n size === 'large' &&\n '!tw-h-7 !tw-w-7 !tw-rounded-r-100',\n focusRingClasses,\n compactClasses,\n className,\n );\n\n const contentClasses = cn(\n // Typography: the approved Label utility belongs to the text-bearing\n // element. Icon-only controls intentionally have no label Typography.\n 'tw-inline-flex tw-min-w-0 tw-items-center tw-gap-1 tw-truncate tw-text-typography-label',\n ghost &&\n type === 'inverse' &&\n size === 'middle' &&\n 'tw-flex-[1_0_0] tw-text-[var(--action-inverted-normal)]',\n );\n\n const arrowNode = showArrow ? (\n <span className=\"ald-btn-arrow tw-inline-flex tw-shrink-0 tw-items-center\">\n <ChevronDownLine size={16} />\n </span>\n ) : null;\n\n const buttonContent = (\n <>\n {iconNode}\n {children && <span className={contentClasses}>{children}</span>}\n {arrowNode}\n </>\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 {buttonContent}\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 {buttonContent}\n </button>\n );\n}\n\nexport default forwardRef(Button);\n"],"mappings":";;;;;;;;;;AAQA,IAAa,YAAY;AAqDzB,IAAa,WACX,UACA,SACA,OAAwB,UACrB;AACH,KAAI,QACF,QACE,oBAAC,QAAD;EACE,WAAU;EACJ;EACN,OAAM;EACN,CAAA;AAIN,KAAI,UAAU;EACZ,MAAM,IAAqC;GACzC,WAAW;GACX,MAAM;GACN,GAAG,SAAS;GACb;AACD,IAAE,OAAO;AACT,SAAO,MAAM,aAAa,UAAU,EAAE;;AAExC,QAAO,oBAAA,UAAA,EAAK,CAAA;;AAGd,IAAM,iBAAiB,IACrB;CACE;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;GACD,OAAO;IACL,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,WAAW;IACT,GAAG,UAAU;IACb;IACA;IACA;IACD;GACF;EACD,MAAM;GAIJ,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;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,YAAY,OACZ,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;CAWnC,MAAM,WAAW,QAAQ,MAA4B,cATnD,SAAS,cACL,SAAS,UACP,KACA,SAAS,UACT,KACA,KACF,SAAS,UACT,KACA,GACsE;CAG5E,MAAM,iBAAiB,wBACnB,GAEE,CAAC,sBAAsB,iCACrB,sBACF,CAAC,sBAAsB,gCACrB,sBAEF,CAAC,sBAAsB,iCACrB,YACH,GACD;CAEJ,MAAM,aAAa,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;CAC3C,MAAM,mBAAmB,CAAC,cAAc;EACtC;EACA;EACA;EACA;EACA;EACD;CAED,MAAM,UAAU,GACd,eAAe;EACb;EACA;EACA,UAAU,CAAC,CAAC;EACZ,OAAO,CAAC,CAAC;EACT;EACD,CAAC,EACF,SACE,6IACF,SACE,SAAS,aACT,SAAS,YACT,wHACF,SACE,SAAS,eACT,SAAS,YACT,wHACF,SACE,SAAS,eACT,SAAS,YACT,wHACF,SACE,SAAS,aACT,SAAS,YACT,4JACF,SACE,SAAS,aACT,sEACF,SACE,SAAS,eACT,yEACF,SACE,SAAS,eACT,6DACF,SACE,SAAS,aACT,sEACF,SAAS,SAAS,aAAa,2CAC/B,SACE,SAAS,eACT,+CACF,SAAS,SAAS,eAAe,2CACjC,SAAS,SAAS,aAAa,4CAO/B,cAAc,6BACd,cAAc,SAAS,WAAW,eAClC,cAAc,SAAS,YAAY,eACnC,cAAc,SAAS,WAAW,gBAClC,SAAS,eACP,8EACF,SAAS,eACP,SAAS,WACT,oCACF,SAAS,eACP,SAAS,YACT,oCACF,SAAS,eACP,SAAS,WACT,qCACF,kBACA,gBACA,UACD;CAED,MAAM,iBAAiB,GAGrB,2FACA,SACE,SAAS,aACT,SAAS,YACT,0DACH;CAQD,MAAM,gBACJ,qBAAA,UAAA,EAAA,UAAA;EACG;EACA,YAAY,oBAAC,QAAD;GAAM,WAAW;GAAiB;GAAgB,CAAA;EATjD,YAChB,oBAAC,QAAD;GAAM,WAAU;aACd,oBAAC,MAAD,EAAiB,MAAM,IAAM,CAAA;GACxB,CAAA,GACL;EAOC,EAAA,CAAA;AAGL,KAAI,KACF,QACE,oBAAC,KAAD;EACE,GAAI;EACJ,WAAW;EACJ;EACP,MAAM,aAAa,SAAY;EACvB;EACH;EACL,SAAS,aAAa,SAAY;EAClC,iBAAe,cAAc;YAE5B;EACC,CAAA;AAIR,QACE,oBAAC,UAAD;EACE,GAAI;EACJ,MACE,aAAa,WACT,WACA,aAAa,UACb,UACA;EAEN,WAAW;EACJ;EACP,UAAU;EACV,iBAAe,cAAc;EACxB;EACI;YAER;EACM,CAAA;;AAIb,IAAA,iBAAe,WAAW,OAAO"}
|
package/dist/Card/index.js
CHANGED
|
@@ -40,7 +40,7 @@ function Card(props) {
|
|
|
40
40
|
}
|
|
41
41
|
function Grid({ className, style, hoverable, children }) {
|
|
42
42
|
return /* @__PURE__ */ jsx("div", {
|
|
43
|
-
className: cn("ald-card-grid tw-w-1/3 tw-border-0 tw-border-b tw-border-r tw-border-solid tw-border-[var(--border-default)] tw-p-6", hoverable && "tw-transition-shadow hover:tw-shadow-md", className),
|
|
43
|
+
className: cn("ald-card-grid tw-w-1/3 tw-border-0 tw-border-b tw-border-r tw-border-solid tw-border-[var(--border-default)] tw-p-6", hoverable && "tw-transition-shadow hover:tw-shadow-[var(--elevation-bottom-bottom-md)]", className),
|
|
44
44
|
style,
|
|
45
45
|
children
|
|
46
46
|
});
|
package/dist/Card/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Card/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../lib/utils';\n\nexport interface CardProps {\n title?: React.ReactNode;\n extra?: React.ReactNode;\n bordered?: boolean;\n hoverable?: boolean;\n loading?: boolean;\n size?: 'default' | 'small';\n type?: 'inner';\n className?: string;\n style?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n headStyle?: React.CSSProperties;\n children?: React.ReactNode;\n cover?: React.ReactNode;\n actions?: React.ReactNode[];\n}\n\nexport interface CardGridProps {\n className?: string;\n style?: React.CSSProperties;\n hoverable?: boolean;\n children?: React.ReactNode;\n}\n\nexport interface CardMetaProps {\n className?: string;\n style?: React.CSSProperties;\n avatar?: React.ReactNode;\n title?: React.ReactNode;\n description?: React.ReactNode;\n}\n\nfunction Card(props: CardProps) {\n const {\n title,\n extra,\n bordered = true,\n hoverable,\n size,\n type,\n className,\n style,\n bodyStyle,\n headStyle,\n children,\n cover,\n actions,\n } = props;\n\n return (\n <div\n className={cn(\n 'ald-card tw-flex tw-flex-col tw-items-stretch tw-overflow-hidden tw-rounded-r-150 tw-bg-[var(--background-default)] tw-shadow-[var(--elevation-bottom-bottom-md)] tw-outline tw-outline-1 tw-outline-[var(--border-default-alpha)]',\n !bordered && '!tw-outline-transparent',\n hoverable &&\n 'tw-cursor-pointer tw-transition-shadow hover:tw-shadow-[var(--elevation-bottom-bottom-lg)]',\n size === 'small' && 'ald-card-small',\n type === 'inner' && 'ald-card-inner',\n className,\n )}\n style={style}\n >\n {(title || extra) && (\n <div\n className={cn(\n 'ald-card-head tw-flex tw-items-center tw-justify-between tw-gap-4 tw-self-stretch tw-border-0 tw-border-b tw-border-solid tw-border-[var(--border-default)] tw-px-6 tw-py-4',\n size === 'small' && '!tw-px-4 !tw-py-3',\n )}\n style={headStyle}\n >\n {title && (\n <div\n className={cn(\n 'ald-card-head-title tw-text-base tw-font-semibold tw-text-[var(--content-primary)]',\n size === 'small' && '!tw-text-sm',\n )}\n >\n {title}\n </div>\n )}\n {extra && <div className=\"ald-card-extra tw-text-sm\">{extra}</div>}\n </div>\n )}\n {cover && <div className=\"ald-card-cover\">{cover}</div>}\n <div\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n className={cn(\n 'ald-card-body ant-card-body tw-flex tw-flex-col tw-items-start tw-gap-5 tw-self-stretch tw-p-6',\n size === 'small' && '!tw-gap-3 !tw-p-4',\n )}\n style={bodyStyle}\n >\n {children}\n </div>\n {actions && actions.length > 0 && (\n <div className=\"ald-card-actions tw-flex tw-border-t tw-border-solid tw-border-[var(--border-default)]\">\n {actions.map((action, i) => (\n <div\n key={i}\n className=\"ald-card-action tw-flex-1 tw-py-3 tw-text-center\"\n >\n {action}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction Grid({ className, style, hoverable, children }: CardGridProps) {\n return (\n <div\n className={cn(\n 'ald-card-grid tw-w-1/3 tw-border-0 tw-border-b tw-border-r tw-border-solid tw-border-[var(--border-default)] tw-p-6',\n hoverable
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Card/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../lib/utils';\n\nexport interface CardProps {\n title?: React.ReactNode;\n extra?: React.ReactNode;\n bordered?: boolean;\n hoverable?: boolean;\n loading?: boolean;\n size?: 'default' | 'small';\n type?: 'inner';\n className?: string;\n style?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n headStyle?: React.CSSProperties;\n children?: React.ReactNode;\n cover?: React.ReactNode;\n actions?: React.ReactNode[];\n}\n\nexport interface CardGridProps {\n className?: string;\n style?: React.CSSProperties;\n hoverable?: boolean;\n children?: React.ReactNode;\n}\n\nexport interface CardMetaProps {\n className?: string;\n style?: React.CSSProperties;\n avatar?: React.ReactNode;\n title?: React.ReactNode;\n description?: React.ReactNode;\n}\n\nfunction Card(props: CardProps) {\n const {\n title,\n extra,\n bordered = true,\n hoverable,\n size,\n type,\n className,\n style,\n bodyStyle,\n headStyle,\n children,\n cover,\n actions,\n } = props;\n\n return (\n <div\n className={cn(\n 'ald-card tw-flex tw-flex-col tw-items-stretch tw-overflow-hidden tw-rounded-r-150 tw-bg-[var(--background-default)] tw-shadow-[var(--elevation-bottom-bottom-md)] tw-outline tw-outline-1 tw-outline-[var(--border-default-alpha)]',\n !bordered && '!tw-outline-transparent',\n hoverable &&\n 'tw-cursor-pointer tw-transition-shadow hover:tw-shadow-[var(--elevation-bottom-bottom-lg)]',\n size === 'small' && 'ald-card-small',\n type === 'inner' && 'ald-card-inner',\n className,\n )}\n style={style}\n >\n {(title || extra) && (\n <div\n className={cn(\n 'ald-card-head tw-flex tw-items-center tw-justify-between tw-gap-4 tw-self-stretch tw-border-0 tw-border-b tw-border-solid tw-border-[var(--border-default)] tw-px-6 tw-py-4',\n size === 'small' && '!tw-px-4 !tw-py-3',\n )}\n style={headStyle}\n >\n {title && (\n <div\n className={cn(\n 'ald-card-head-title tw-text-base tw-font-semibold tw-text-[var(--content-primary)]',\n size === 'small' && '!tw-text-sm',\n )}\n >\n {title}\n </div>\n )}\n {extra && <div className=\"ald-card-extra tw-text-sm\">{extra}</div>}\n </div>\n )}\n {cover && <div className=\"ald-card-cover\">{cover}</div>}\n <div\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n className={cn(\n 'ald-card-body ant-card-body tw-flex tw-flex-col tw-items-start tw-gap-5 tw-self-stretch tw-p-6',\n size === 'small' && '!tw-gap-3 !tw-p-4',\n )}\n style={bodyStyle}\n >\n {children}\n </div>\n {actions && actions.length > 0 && (\n <div className=\"ald-card-actions tw-flex tw-border-t tw-border-solid tw-border-[var(--border-default)]\">\n {actions.map((action, i) => (\n <div\n key={i}\n className=\"ald-card-action tw-flex-1 tw-py-3 tw-text-center\"\n >\n {action}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction Grid({ className, style, hoverable, children }: CardGridProps) {\n return (\n <div\n className={cn(\n 'ald-card-grid tw-w-1/3 tw-border-0 tw-border-b tw-border-r tw-border-solid tw-border-[var(--border-default)] tw-p-6',\n hoverable &&\n 'tw-transition-shadow hover:tw-shadow-[var(--elevation-bottom-bottom-md)]',\n className,\n )}\n style={style}\n >\n {children}\n </div>\n );\n}\n\nfunction Meta({ className, style, avatar, title, description }: CardMetaProps) {\n return (\n <div\n className={cn('ald-card-meta tw-flex tw-items-start tw-gap-4', className)}\n style={style}\n >\n {avatar && (\n <div className=\"ald-card-meta-avatar tw-flex-none\">{avatar}</div>\n )}\n <div className=\"ald-card-meta-detail tw-flex-1 tw-overflow-hidden\">\n {title && (\n <div className=\"ald-card-meta-title tw-truncate tw-text-base tw-font-medium tw-text-[var(--content-primary)]\">\n {title}\n </div>\n )}\n {description && (\n <div className=\"ald-card-meta-description tw-text-sm tw-text-[var(--content-secondary)]\">\n {description}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nCard.Grid = Grid;\nCard.Meta = Meta;\n\nexport default Card;\n"],"mappings":";;;;AAmCA,SAAS,KAAK,OAAkB;CAC9B,MAAM,EACJ,OACA,OACA,WAAW,MACX,WACA,MACA,MACA,WACA,OACA,WACA,WACA,UACA,OACA,YACE;AAEJ,QACE,qBAAC,OAAD;EACE,WAAW,GACT,sOACA,CAAC,YAAY,2BACb,aACE,8FACF,SAAS,WAAW,kBACpB,SAAS,WAAW,kBACpB,UACD;EACM;YAVT;IAYI,SAAS,UACT,qBAAC,OAAD;IACE,WAAW,GACT,+KACA,SAAS,WAAW,oBACrB;IACD,OAAO;cALT,CAOG,SACC,oBAAC,OAAD;KACE,WAAW,GACT,sFACA,SAAS,WAAW,cACrB;eAEA;KACG,CAAA,EAEP,SAAS,oBAAC,OAAD;KAAK,WAAU;eAA6B;KAAY,CAAA,CAC9D;;GAEP,SAAS,oBAAC,OAAD;IAAK,WAAU;cAAkB;IAAY,CAAA;GACvD,oBAAC,OAAD;IAEE,WAAW,GACT,kGACA,SAAS,WAAW,oBACrB;IACD,OAAO;IAEN;IACG,CAAA;GACL,WAAW,QAAQ,SAAS,KAC3B,oBAAC,OAAD;IAAK,WAAU;cACZ,QAAQ,KAAK,QAAQ,MACpB,oBAAC,OAAD;KAEE,WAAU;eAET;KACG,EAJC,EAID,CACN;IACE,CAAA;GAEJ;;;AAIV,SAAS,KAAK,EAAE,WAAW,OAAO,WAAW,YAA2B;AACtE,QACE,oBAAC,OAAD;EACE,WAAW,GACT,uHACA,aACE,4EACF,UACD;EACM;EAEN;EACG,CAAA;;AAIV,SAAS,KAAK,EAAE,WAAW,OAAO,QAAQ,OAAO,eAA8B;AAC7E,QACE,qBAAC,OAAD;EACE,WAAW,GAAG,iDAAiD,UAAU;EAClE;YAFT,CAIG,UACC,oBAAC,OAAD;GAAK,WAAU;aAAqC;GAAa,CAAA,EAEnE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,SACC,oBAAC,OAAD;IAAK,WAAU;cACZ;IACG,CAAA,EAEP,eACC,oBAAC,OAAD;IAAK,WAAU;cACZ;IACG,CAAA,CAEJ;KACF;;;AAIV,KAAK,OAAO;AACZ,KAAK,OAAO"}
|
package/dist/Carousel/index.js
CHANGED
|
@@ -72,12 +72,16 @@ var Carousel = React.forwardRef((props, ref) => {
|
|
|
72
72
|
type: "button",
|
|
73
73
|
className: cn("ald-carousel-dot", index === selectedIndex && "ald-carousel-dot--active"),
|
|
74
74
|
onClick: () => goTo(index),
|
|
75
|
-
"aria-label": `Go to slide ${index + 1}
|
|
75
|
+
"aria-label": `Go to slide ${index + 1}`,
|
|
76
|
+
"aria-current": index === selectedIndex ? "true" : void 0
|
|
76
77
|
}, index))
|
|
77
78
|
}) : null;
|
|
78
79
|
return /* @__PURE__ */ jsxs("div", {
|
|
79
80
|
className: cn("ald-carousel", isVertical && "ald-carousel--vertical", isFade && "ald-carousel--fade", className),
|
|
80
81
|
style,
|
|
82
|
+
role: "region",
|
|
83
|
+
"aria-roledescription": "carousel",
|
|
84
|
+
"aria-label": "Carousel",
|
|
81
85
|
children: [
|
|
82
86
|
dotPosition === "top" && dotsEl,
|
|
83
87
|
/* @__PURE__ */ jsx("div", {
|
|
@@ -88,6 +92,10 @@ var Carousel = React.forwardRef((props, ref) => {
|
|
|
88
92
|
children: slides.map((slide, index) => /* @__PURE__ */ jsx("div", {
|
|
89
93
|
className: cn("ald-carousel-slide", isFade && index === selectedIndex && "ald-carousel-slide--active"),
|
|
90
94
|
style: isFade ? void 0 : slideStyle,
|
|
95
|
+
role: "group",
|
|
96
|
+
"aria-roledescription": "slide",
|
|
97
|
+
"aria-label": `${index + 1} of ${slides.length}`,
|
|
98
|
+
"aria-hidden": index === selectedIndex ? void 0 : true,
|
|
91
99
|
children: slide
|
|
92
100
|
}, index))
|
|
93
101
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Carousel/index.tsx"],"sourcesContent":["import useEmblaCarousel from 'embla-carousel-react';\nimport type { EmblaCarouselType } from 'embla-carousel';\nimport Autoplay from 'embla-carousel-autoplay';\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport './carousel.css';\n\nexport interface CarouselProps {\n /** Enable autoplay */\n autoplay?: boolean;\n /** Autoplay interval in milliseconds (default 3000) */\n autoplaySpeed?: number;\n /** Show dot indicators (default true) */\n dots?: boolean;\n /** Position of dot indicators */\n dotPosition?: 'top' | 'bottom' | 'left' | 'right';\n /** Slide transition effect */\n effect?: 'scrollx' | 'fade';\n /** Easing function name — reserved for future use */\n easing?: string;\n /** Enable infinite loop (default false) */\n infinite?: boolean;\n /** Number of slides to show at once (default 1) */\n slidesToShow?: number;\n /** Number of slides to scroll per step (default 1) */\n slidesToScroll?: number;\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n /** Called after the slide index changes */\n afterChange?: (current: number) => void;\n /** Called before the slide index changes */\n beforeChange?: (from: number, to: number) => void;\n}\n\nexport interface CarouselRef {\n goTo: (slide: number) => void;\n next: () => void;\n prev: () => void;\n}\n\nconst Carousel = React.forwardRef<CarouselRef, CarouselProps>((props, ref) => {\n const {\n autoplay: autoplayEnabled = false,\n autoplaySpeed = 3000,\n dots = true,\n dotPosition = 'bottom',\n effect = 'scrollx',\n infinite = false,\n slidesToShow = 1,\n slidesToScroll = 1,\n className,\n style,\n children,\n afterChange,\n beforeChange,\n } = props;\n\n const slides = React.Children.toArray(children);\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [scrollSnaps, setScrollSnaps] = useState<number[]>([]);\n const previousIndexRef = useRef(0);\n const isFade = effect === 'fade';\n\n // Build embla plugins array\n const plugins = useMemo(() => {\n const list = [];\n if (autoplayEnabled) {\n list.push(\n Autoplay({\n delay: autoplaySpeed,\n stopOnInteraction: false,\n stopOnMouseEnter: true,\n }),\n );\n }\n return list;\n }, [autoplayEnabled, autoplaySpeed]);\n\n // Embla options\n const emblaOptions = useMemo(\n () => ({\n loop: infinite,\n slidesToScroll,\n align: 'start' as const,\n ...(isFade\n ? {\n // For fade effect we disable dragging; transitions are CSS-only\n watchDrag: false,\n }\n : {}),\n }),\n [infinite, slidesToScroll, isFade],\n );\n\n const [emblaRef, emblaApi] = useEmblaCarousel(emblaOptions, plugins);\n\n // ── Sync selected index ──\n const onSelect = useCallback(\n (api: EmblaCarouselType) => {\n const newIndex = api.selectedScrollSnap();\n const prevIndex = previousIndexRef.current;\n if (newIndex !== prevIndex) {\n beforeChange?.(prevIndex, newIndex);\n }\n setSelectedIndex(newIndex);\n previousIndexRef.current = newIndex;\n if (newIndex !== prevIndex) {\n afterChange?.(newIndex);\n }\n },\n [beforeChange, afterChange],\n );\n\n useEffect(() => {\n if (!emblaApi) return;\n\n setScrollSnaps(emblaApi.scrollSnapList());\n onSelect(emblaApi);\n\n emblaApi.on('select', onSelect);\n emblaApi.on('reInit', onSelect);\n\n return () => {\n emblaApi.off('select', onSelect);\n emblaApi.off('reInit', onSelect);\n };\n }, [emblaApi, onSelect]);\n\n // ── Imperative API ──\n const goTo = useCallback(\n (index: number) => {\n emblaApi?.scrollTo(index);\n },\n [emblaApi],\n );\n\n const next = useCallback(() => {\n emblaApi?.scrollNext();\n }, [emblaApi]);\n\n const prev = useCallback(() => {\n emblaApi?.scrollPrev();\n }, [emblaApi]);\n\n React.useImperativeHandle(ref, () => ({ goTo, next, prev }));\n\n // ── Slide width for slidesToShow ──\n const slideStyle: React.CSSProperties = useMemo(\n () =>\n slidesToShow > 1\n ? { flex: `0 0 ${100 / slidesToShow}%` }\n : { flex: '0 0 100%' },\n [slidesToShow],\n );\n\n // ── Vertical carousel support ──\n const isVertical = dotPosition === 'left' || dotPosition === 'right';\n\n // ── Render dots ──\n const dotsEl =\n dots && scrollSnaps.length > 1 ? (\n <div\n className={cn('ald-carousel-dots', `ald-carousel-dots--${dotPosition}`)}\n >\n {scrollSnaps.map((_, index) => (\n <button\n type=\"button\"\n key={index}\n className={cn(\n 'ald-carousel-dot',\n index === selectedIndex && 'ald-carousel-dot--active',\n )}\n onClick={() => goTo(index)}\n aria-label={`Go to slide ${index + 1}`}\n />\n ))}\n </div>\n ) : null;\n\n return (\n <div\n className={cn(\n 'ald-carousel',\n isVertical && 'ald-carousel--vertical',\n isFade && 'ald-carousel--fade',\n className,\n )}\n style={style}\n >\n {dotPosition === 'top' && dotsEl}\n\n <div className=\"ald-carousel-viewport\" ref={emblaRef}>\n <div className=\"ald-carousel-container\">\n {slides.map((slide, index) => (\n <div\n key={index}\n className={cn(\n 'ald-carousel-slide',\n isFade &&\n index === selectedIndex &&\n 'ald-carousel-slide--active',\n )}\n style={isFade ? undefined : slideStyle}\n >\n {slide}\n </div>\n ))}\n </div>\n </div>\n\n {dotPosition !== 'top' && dotsEl}\n </div>\n );\n});\n\nCarousel.displayName = 'Carousel';\n\nexport default Carousel;\n"],"mappings":";;;;;;;AA+CA,IAAM,WAAW,MAAM,YAAwC,OAAO,QAAQ;CAC5E,MAAM,EACJ,UAAU,kBAAkB,OAC5B,gBAAgB,KAChB,OAAO,MACP,cAAc,UACd,SAAS,WACT,WAAW,OACX,eAAe,GACf,iBAAiB,GACjB,WACA,OACA,UACA,aACA,iBACE;CAEJ,MAAM,SAAS,MAAM,SAAS,QAAQ,SAAS;CAC/C,MAAM,CAAC,eAAe,oBAAoB,SAAS,EAAE;CACrD,MAAM,CAAC,aAAa,kBAAkB,SAAmB,EAAE,CAAC;CAC5D,MAAM,mBAAmB,OAAO,EAAE;CAClC,MAAM,SAAS,WAAW;CAG1B,MAAM,UAAU,cAAc;EAC5B,MAAM,OAAO,EAAE;AACf,MAAI,gBACF,MAAK,KACH,SAAS;GACP,OAAO;GACP,mBAAmB;GACnB,kBAAkB;GACnB,CAAC,CACH;AAEH,SAAO;IACN,CAAC,iBAAiB,cAAc,CAAC;CAkBpC,MAAM,CAAC,UAAU,YAAY,iBAfR,eACZ;EACL,MAAM;EACN;EACA,OAAO;EACP,GAAI,SACA,EAEE,WAAW,OACZ,GACD,EAAE;EACP,GACD;EAAC;EAAU;EAAgB;EAAO,CACnC,EAE2D,QAAQ;CAGpE,MAAM,WAAW,aACd,QAA2B;EAC1B,MAAM,WAAW,IAAI,oBAAoB;EACzC,MAAM,YAAY,iBAAiB;AACnC,MAAI,aAAa,UACf,gBAAe,WAAW,SAAS;AAErC,mBAAiB,SAAS;AAC1B,mBAAiB,UAAU;AAC3B,MAAI,aAAa,UACf,eAAc,SAAS;IAG3B,CAAC,cAAc,YAAY,CAC5B;AAED,iBAAgB;AACd,MAAI,CAAC,SAAU;AAEf,iBAAe,SAAS,gBAAgB,CAAC;AACzC,WAAS,SAAS;AAElB,WAAS,GAAG,UAAU,SAAS;AAC/B,WAAS,GAAG,UAAU,SAAS;AAE/B,eAAa;AACX,YAAS,IAAI,UAAU,SAAS;AAChC,YAAS,IAAI,UAAU,SAAS;;IAEjC,CAAC,UAAU,SAAS,CAAC;CAGxB,MAAM,OAAO,aACV,UAAkB;AACjB,YAAU,SAAS,MAAM;IAE3B,CAAC,SAAS,CACX;CAED,MAAM,OAAO,kBAAkB;AAC7B,YAAU,YAAY;IACrB,CAAC,SAAS,CAAC;CAEd,MAAM,OAAO,kBAAkB;AAC7B,YAAU,YAAY;IACrB,CAAC,SAAS,CAAC;AAEd,OAAM,oBAAoB,YAAY;EAAE;EAAM;EAAM;EAAM,EAAE;CAG5D,MAAM,aAAkC,cAEpC,eAAe,IACX,EAAE,MAAM,OAAO,MAAM,aAAa,IAAI,GACtC,EAAE,MAAM,YAAY,EAC1B,CAAC,aAAa,CACf;CAGD,MAAM,aAAa,gBAAgB,UAAU,gBAAgB;CAG7D,MAAM,SACJ,QAAQ,YAAY,SAAS,IAC3B,oBAAC,OAAD;EACE,WAAW,GAAG,qBAAqB,sBAAsB,cAAc;YAEtE,YAAY,KAAK,GAAG,UACnB,oBAAC,UAAD;GACE,MAAK;GAEL,WAAW,GACT,oBACA,UAAU,iBAAiB,2BAC5B;GACD,eAAe,KAAK,MAAM;GAC1B,cAAY,eAAe,QAAQ;GACnC,
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Carousel/index.tsx"],"sourcesContent":["import useEmblaCarousel from 'embla-carousel-react';\nimport type { EmblaCarouselType } from 'embla-carousel';\nimport Autoplay from 'embla-carousel-autoplay';\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport './carousel.css';\n\nexport interface CarouselProps {\n /** Enable autoplay */\n autoplay?: boolean;\n /** Autoplay interval in milliseconds (default 3000) */\n autoplaySpeed?: number;\n /** Show dot indicators (default true) */\n dots?: boolean;\n /** Position of dot indicators */\n dotPosition?: 'top' | 'bottom' | 'left' | 'right';\n /** Slide transition effect */\n effect?: 'scrollx' | 'fade';\n /** Easing function name — reserved for future use */\n easing?: string;\n /** Enable infinite loop (default false) */\n infinite?: boolean;\n /** Number of slides to show at once (default 1) */\n slidesToShow?: number;\n /** Number of slides to scroll per step (default 1) */\n slidesToScroll?: number;\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n /** Called after the slide index changes */\n afterChange?: (current: number) => void;\n /** Called before the slide index changes */\n beforeChange?: (from: number, to: number) => void;\n}\n\nexport interface CarouselRef {\n goTo: (slide: number) => void;\n next: () => void;\n prev: () => void;\n}\n\nconst Carousel = React.forwardRef<CarouselRef, CarouselProps>((props, ref) => {\n const {\n autoplay: autoplayEnabled = false,\n autoplaySpeed = 3000,\n dots = true,\n dotPosition = 'bottom',\n effect = 'scrollx',\n infinite = false,\n slidesToShow = 1,\n slidesToScroll = 1,\n className,\n style,\n children,\n afterChange,\n beforeChange,\n } = props;\n\n const slides = React.Children.toArray(children);\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [scrollSnaps, setScrollSnaps] = useState<number[]>([]);\n const previousIndexRef = useRef(0);\n const isFade = effect === 'fade';\n\n // Build embla plugins array\n const plugins = useMemo(() => {\n const list = [];\n if (autoplayEnabled) {\n list.push(\n Autoplay({\n delay: autoplaySpeed,\n stopOnInteraction: false,\n stopOnMouseEnter: true,\n }),\n );\n }\n return list;\n }, [autoplayEnabled, autoplaySpeed]);\n\n // Embla options\n const emblaOptions = useMemo(\n () => ({\n loop: infinite,\n slidesToScroll,\n align: 'start' as const,\n ...(isFade\n ? {\n // For fade effect we disable dragging; transitions are CSS-only\n watchDrag: false,\n }\n : {}),\n }),\n [infinite, slidesToScroll, isFade],\n );\n\n const [emblaRef, emblaApi] = useEmblaCarousel(emblaOptions, plugins);\n\n // ── Sync selected index ──\n const onSelect = useCallback(\n (api: EmblaCarouselType) => {\n const newIndex = api.selectedScrollSnap();\n const prevIndex = previousIndexRef.current;\n if (newIndex !== prevIndex) {\n beforeChange?.(prevIndex, newIndex);\n }\n setSelectedIndex(newIndex);\n previousIndexRef.current = newIndex;\n if (newIndex !== prevIndex) {\n afterChange?.(newIndex);\n }\n },\n [beforeChange, afterChange],\n );\n\n useEffect(() => {\n if (!emblaApi) return;\n\n setScrollSnaps(emblaApi.scrollSnapList());\n onSelect(emblaApi);\n\n emblaApi.on('select', onSelect);\n emblaApi.on('reInit', onSelect);\n\n return () => {\n emblaApi.off('select', onSelect);\n emblaApi.off('reInit', onSelect);\n };\n }, [emblaApi, onSelect]);\n\n // ── Imperative API ──\n const goTo = useCallback(\n (index: number) => {\n emblaApi?.scrollTo(index);\n },\n [emblaApi],\n );\n\n const next = useCallback(() => {\n emblaApi?.scrollNext();\n }, [emblaApi]);\n\n const prev = useCallback(() => {\n emblaApi?.scrollPrev();\n }, [emblaApi]);\n\n React.useImperativeHandle(ref, () => ({ goTo, next, prev }));\n\n // ── Slide width for slidesToShow ──\n const slideStyle: React.CSSProperties = useMemo(\n () =>\n slidesToShow > 1\n ? { flex: `0 0 ${100 / slidesToShow}%` }\n : { flex: '0 0 100%' },\n [slidesToShow],\n );\n\n // ── Vertical carousel support ──\n const isVertical = dotPosition === 'left' || dotPosition === 'right';\n\n // ── Render dots ──\n const dotsEl =\n dots && scrollSnaps.length > 1 ? (\n <div\n className={cn('ald-carousel-dots', `ald-carousel-dots--${dotPosition}`)}\n >\n {scrollSnaps.map((_, index) => (\n <button\n type=\"button\"\n key={index}\n className={cn(\n 'ald-carousel-dot',\n index === selectedIndex && 'ald-carousel-dot--active',\n )}\n onClick={() => goTo(index)}\n aria-label={`Go to slide ${index + 1}`}\n aria-current={index === selectedIndex ? 'true' : undefined}\n />\n ))}\n </div>\n ) : null;\n\n return (\n <div\n className={cn(\n 'ald-carousel',\n isVertical && 'ald-carousel--vertical',\n isFade && 'ald-carousel--fade',\n className,\n )}\n style={style}\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label=\"Carousel\"\n >\n {dotPosition === 'top' && dotsEl}\n\n <div className=\"ald-carousel-viewport\" ref={emblaRef}>\n <div className=\"ald-carousel-container\">\n {slides.map((slide, index) => (\n <div\n key={index}\n className={cn(\n 'ald-carousel-slide',\n isFade &&\n index === selectedIndex &&\n 'ald-carousel-slide--active',\n )}\n style={isFade ? undefined : slideStyle}\n role=\"group\"\n aria-roledescription=\"slide\"\n aria-label={`${index + 1} of ${slides.length}`}\n aria-hidden={index === selectedIndex ? undefined : true}\n >\n {slide}\n </div>\n ))}\n </div>\n </div>\n\n {dotPosition !== 'top' && dotsEl}\n </div>\n );\n});\n\nCarousel.displayName = 'Carousel';\n\nexport default Carousel;\n"],"mappings":";;;;;;;AA+CA,IAAM,WAAW,MAAM,YAAwC,OAAO,QAAQ;CAC5E,MAAM,EACJ,UAAU,kBAAkB,OAC5B,gBAAgB,KAChB,OAAO,MACP,cAAc,UACd,SAAS,WACT,WAAW,OACX,eAAe,GACf,iBAAiB,GACjB,WACA,OACA,UACA,aACA,iBACE;CAEJ,MAAM,SAAS,MAAM,SAAS,QAAQ,SAAS;CAC/C,MAAM,CAAC,eAAe,oBAAoB,SAAS,EAAE;CACrD,MAAM,CAAC,aAAa,kBAAkB,SAAmB,EAAE,CAAC;CAC5D,MAAM,mBAAmB,OAAO,EAAE;CAClC,MAAM,SAAS,WAAW;CAG1B,MAAM,UAAU,cAAc;EAC5B,MAAM,OAAO,EAAE;AACf,MAAI,gBACF,MAAK,KACH,SAAS;GACP,OAAO;GACP,mBAAmB;GACnB,kBAAkB;GACnB,CAAC,CACH;AAEH,SAAO;IACN,CAAC,iBAAiB,cAAc,CAAC;CAkBpC,MAAM,CAAC,UAAU,YAAY,iBAfR,eACZ;EACL,MAAM;EACN;EACA,OAAO;EACP,GAAI,SACA,EAEE,WAAW,OACZ,GACD,EAAE;EACP,GACD;EAAC;EAAU;EAAgB;EAAO,CACnC,EAE2D,QAAQ;CAGpE,MAAM,WAAW,aACd,QAA2B;EAC1B,MAAM,WAAW,IAAI,oBAAoB;EACzC,MAAM,YAAY,iBAAiB;AACnC,MAAI,aAAa,UACf,gBAAe,WAAW,SAAS;AAErC,mBAAiB,SAAS;AAC1B,mBAAiB,UAAU;AAC3B,MAAI,aAAa,UACf,eAAc,SAAS;IAG3B,CAAC,cAAc,YAAY,CAC5B;AAED,iBAAgB;AACd,MAAI,CAAC,SAAU;AAEf,iBAAe,SAAS,gBAAgB,CAAC;AACzC,WAAS,SAAS;AAElB,WAAS,GAAG,UAAU,SAAS;AAC/B,WAAS,GAAG,UAAU,SAAS;AAE/B,eAAa;AACX,YAAS,IAAI,UAAU,SAAS;AAChC,YAAS,IAAI,UAAU,SAAS;;IAEjC,CAAC,UAAU,SAAS,CAAC;CAGxB,MAAM,OAAO,aACV,UAAkB;AACjB,YAAU,SAAS,MAAM;IAE3B,CAAC,SAAS,CACX;CAED,MAAM,OAAO,kBAAkB;AAC7B,YAAU,YAAY;IACrB,CAAC,SAAS,CAAC;CAEd,MAAM,OAAO,kBAAkB;AAC7B,YAAU,YAAY;IACrB,CAAC,SAAS,CAAC;AAEd,OAAM,oBAAoB,YAAY;EAAE;EAAM;EAAM;EAAM,EAAE;CAG5D,MAAM,aAAkC,cAEpC,eAAe,IACX,EAAE,MAAM,OAAO,MAAM,aAAa,IAAI,GACtC,EAAE,MAAM,YAAY,EAC1B,CAAC,aAAa,CACf;CAGD,MAAM,aAAa,gBAAgB,UAAU,gBAAgB;CAG7D,MAAM,SACJ,QAAQ,YAAY,SAAS,IAC3B,oBAAC,OAAD;EACE,WAAW,GAAG,qBAAqB,sBAAsB,cAAc;YAEtE,YAAY,KAAK,GAAG,UACnB,oBAAC,UAAD;GACE,MAAK;GAEL,WAAW,GACT,oBACA,UAAU,iBAAiB,2BAC5B;GACD,eAAe,KAAK,MAAM;GAC1B,cAAY,eAAe,QAAQ;GACnC,gBAAc,UAAU,gBAAgB,SAAS;GACjD,EARK,MAQL,CACF;EACE,CAAA,GACJ;AAEN,QACE,qBAAC,OAAD;EACE,WAAW,GACT,gBACA,cAAc,0BACd,UAAU,sBACV,UACD;EACM;EACP,MAAK;EACL,wBAAqB;EACrB,cAAW;YAVb;GAYG,gBAAgB,SAAS;GAE1B,oBAAC,OAAD;IAAK,WAAU;IAAwB,KAAK;cAC1C,oBAAC,OAAD;KAAK,WAAU;eACZ,OAAO,KAAK,OAAO,UAClB,oBAAC,OAAD;MAEE,WAAW,GACT,sBACA,UACE,UAAU,iBACV,6BACH;MACD,OAAO,SAAS,SAAY;MAC5B,MAAK;MACL,wBAAqB;MACrB,cAAY,GAAG,QAAQ,EAAE,MAAM,OAAO;MACtC,eAAa,UAAU,gBAAgB,SAAY;gBAElD;MACG,EAdC,MAcD,CACN;KACE,CAAA;IACF,CAAA;GAEL,gBAAgB,SAAS;GACtB;;EAER;AAEF,SAAS,cAAc"}
|