@ryanhe919/lumen-ui 0.2.2 → 0.3.0
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/LICENSE +21 -0
- package/dist/{LMBadge-OEGi87jW.js → LMBadge-BBDOGTps.js} +3 -3
- package/dist/{LMBadge-OEGi87jW.js.map → LMBadge-BBDOGTps.js.map} +1 -1
- package/dist/{LMBadge-1rGc3lqC.cjs → LMBadge-D95iccla.cjs} +3 -3
- package/dist/{LMBadge-1rGc3lqC.cjs.map → LMBadge-D95iccla.cjs.map} +1 -1
- package/dist/{LMCard-Sulq0Yjh.js → LMCard-D7ABNC95.js} +2 -2
- package/dist/{LMCard-Sulq0Yjh.js.map → LMCard-D7ABNC95.js.map} +1 -1
- package/dist/{LMCard-C48UclOk.cjs → LMCard-D_K051f2.cjs} +2 -2
- package/dist/{LMCard-C48UclOk.cjs.map → LMCard-D_K051f2.cjs.map} +1 -1
- package/dist/{LMDatePicker-BlKctoyr.cjs → LMDatePicker-BlUwN4On.cjs} +12 -12
- package/dist/LMDatePicker-BlUwN4On.cjs.map +1 -0
- package/dist/{LMDatePicker-CXiYSome.js → LMDatePicker-DSv28BFH.js} +12 -12
- package/dist/LMDatePicker-DSv28BFH.js.map +1 -0
- package/dist/{LMDrawer-BcVtcYCN.cjs → LMDrawer--lFV_a3m.cjs} +3 -3
- package/dist/{LMDrawer-BcVtcYCN.cjs.map → LMDrawer--lFV_a3m.cjs.map} +1 -1
- package/dist/{LMDrawer-DcPqwiuo.js → LMDrawer-DJ5ugeZR.js} +3 -3
- package/dist/{LMDrawer-DcPqwiuo.js.map → LMDrawer-DJ5ugeZR.js.map} +1 -1
- package/dist/{LMStatCard-4mDqhlHt.js → LMStatCard-D5HV9r6d.js} +4 -4
- package/dist/{LMStatCard-4mDqhlHt.js.map → LMStatCard-D5HV9r6d.js.map} +1 -1
- package/dist/{LMStatCard-Du5Mti-p.cjs → LMStatCard-MXs9Z0qH.cjs} +4 -4
- package/dist/{LMStatCard-Du5Mti-p.cjs.map → LMStatCard-MXs9Z0qH.cjs.map} +1 -1
- package/dist/{LMSwitch-CVFdgSPh.js → LMSwitch-CP1_nrfU.js} +2 -2
- package/dist/LMSwitch-CP1_nrfU.js.map +1 -0
- package/dist/{LMSwitch-CKnrY30F.cjs → LMSwitch-DYoSH6wE.cjs} +2 -2
- package/dist/LMSwitch-DYoSH6wE.cjs.map +1 -0
- package/dist/{LMTabs-DZFAU58t.js → LMTabs-D5n9lB8X.js} +3 -3
- package/dist/{LMTabs-DZFAU58t.js.map → LMTabs-D5n9lB8X.js.map} +1 -1
- package/dist/{LMTabs-DCVaqbrn.cjs → LMTabs-NPmOzPat.cjs} +3 -3
- package/dist/{LMTabs-DCVaqbrn.cjs.map → LMTabs-NPmOzPat.cjs.map} +1 -1
- package/dist/{LMUpload-B_GA4O8W.js → LMUpload-BwXoxIfE.js} +5 -5
- package/dist/LMUpload-BwXoxIfE.js.map +1 -0
- package/dist/{LMUpload-BpISVQGz.cjs → LMUpload-CJopkWc6.cjs} +5 -5
- package/dist/LMUpload-CJopkWc6.cjs.map +1 -0
- package/dist/components/Chat/LMChatBubble/LMChatBubble.d.ts +28 -0
- package/dist/components/Chat/LMChatBubble/LMChatBubble.d.ts.map +1 -0
- package/dist/components/Chat/LMChatBubble/LMChatBubble.stories.d.ts +25 -0
- package/dist/components/Chat/LMChatBubble/LMChatBubble.stories.d.ts.map +1 -0
- package/dist/components/Chat/LMChatBubble/index.d.ts +3 -0
- package/dist/components/Chat/LMChatBubble/index.d.ts.map +1 -0
- package/dist/components/Chat/LMChatContainer/LMChatContainer.d.ts +85 -0
- package/dist/components/Chat/LMChatContainer/LMChatContainer.d.ts.map +1 -0
- package/dist/components/Chat/LMChatContainer/LMChatContainer.stories.d.ts +23 -0
- package/dist/components/Chat/LMChatContainer/LMChatContainer.stories.d.ts.map +1 -0
- package/dist/components/Chat/LMChatContainer/index.d.ts +3 -0
- package/dist/components/Chat/LMChatContainer/index.d.ts.map +1 -0
- package/dist/components/Chat/LMChatInput/LMChatInput.d.ts +55 -0
- package/dist/components/Chat/LMChatInput/LMChatInput.d.ts.map +1 -0
- package/dist/components/Chat/LMChatInput/LMChatInput.stories.d.ts +27 -0
- package/dist/components/Chat/LMChatInput/LMChatInput.stories.d.ts.map +1 -0
- package/dist/components/Chat/LMChatInput/index.d.ts +3 -0
- package/dist/components/Chat/LMChatInput/index.d.ts.map +1 -0
- package/dist/components/Chat/LMChatList/LMChatList.d.ts +60 -0
- package/dist/components/Chat/LMChatList/LMChatList.d.ts.map +1 -0
- package/dist/components/Chat/LMChatList/LMChatList.stories.d.ts +21 -0
- package/dist/components/Chat/LMChatList/LMChatList.stories.d.ts.map +1 -0
- package/dist/components/Chat/LMChatList/index.d.ts +3 -0
- package/dist/components/Chat/LMChatList/index.d.ts.map +1 -0
- package/dist/components/Chat/LMChatMessage/LMChatMessage.d.ts +56 -0
- package/dist/components/Chat/LMChatMessage/LMChatMessage.d.ts.map +1 -0
- package/dist/components/Chat/LMChatMessage/LMChatMessage.stories.d.ts +27 -0
- package/dist/components/Chat/LMChatMessage/LMChatMessage.stories.d.ts.map +1 -0
- package/dist/components/Chat/LMChatMessage/index.d.ts +3 -0
- package/dist/components/Chat/LMChatMessage/index.d.ts.map +1 -0
- package/dist/components/Chat/LMCodeBlock/LMCodeBlock.d.ts +32 -0
- package/dist/components/Chat/LMCodeBlock/LMCodeBlock.d.ts.map +1 -0
- package/dist/components/Chat/LMCodeBlock/LMCodeBlock.stories.d.ts +27 -0
- package/dist/components/Chat/LMCodeBlock/LMCodeBlock.stories.d.ts.map +1 -0
- package/dist/components/Chat/LMCodeBlock/index.d.ts +3 -0
- package/dist/components/Chat/LMCodeBlock/index.d.ts.map +1 -0
- package/dist/components/Chat/LMMarkdownRenderer/LMMarkdownRenderer.d.ts +24 -0
- package/dist/components/Chat/LMMarkdownRenderer/LMMarkdownRenderer.d.ts.map +1 -0
- package/dist/components/Chat/LMMarkdownRenderer/LMMarkdownRenderer.stories.d.ts +23 -0
- package/dist/components/Chat/LMMarkdownRenderer/LMMarkdownRenderer.stories.d.ts.map +1 -0
- package/dist/components/Chat/LMMarkdownRenderer/index.d.ts +3 -0
- package/dist/components/Chat/LMMarkdownRenderer/index.d.ts.map +1 -0
- package/dist/components/Chat/LMTypingIndicator/LMTypingIndicator.d.ts +21 -0
- package/dist/components/Chat/LMTypingIndicator/LMTypingIndicator.d.ts.map +1 -0
- package/dist/components/Chat/LMTypingIndicator/LMTypingIndicator.stories.d.ts +25 -0
- package/dist/components/Chat/LMTypingIndicator/LMTypingIndicator.stories.d.ts.map +1 -0
- package/dist/components/Chat/LMTypingIndicator/index.d.ts +3 -0
- package/dist/components/Chat/LMTypingIndicator/index.d.ts.map +1 -0
- package/dist/components/Chat/index.d.ts +9 -0
- package/dist/components/Chat/index.d.ts.map +1 -0
- package/dist/components/badge/index.cjs +1 -1
- package/dist/components/badge/index.js +1 -1
- package/dist/components/card/index.cjs +1 -1
- package/dist/components/card/index.js +1 -1
- package/dist/components/date-picker/index.cjs +1 -1
- package/dist/components/date-picker/index.js +1 -1
- package/dist/components/drawer/index.cjs +1 -1
- package/dist/components/drawer/index.js +1 -1
- package/dist/components/stat-card/index.cjs +1 -1
- package/dist/components/stat-card/index.js +1 -1
- package/dist/components/switch/index.cjs +1 -1
- package/dist/components/switch/index.js +1 -1
- package/dist/components/tabs/index.cjs +1 -1
- package/dist/components/tabs/index.js +1 -1
- package/dist/components/upload/index.cjs +1 -1
- package/dist/components/upload/index.js +1 -1
- package/dist/index.cjs +2017 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2023 -13
- package/dist/index.js.map +1 -1
- package/dist/style.css +254 -2
- package/package.json +7 -7
- package/dist/LMDatePicker-BlKctoyr.cjs.map +0 -1
- package/dist/LMDatePicker-CXiYSome.js.map +0 -1
- package/dist/LMSwitch-CKnrY30F.cjs.map +0 -1
- package/dist/LMSwitch-CVFdgSPh.js.map +0 -1
- package/dist/LMUpload-B_GA4O8W.js.map +0 -1
- package/dist/LMUpload-BpISVQGz.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LMSwitch-DYoSH6wE.cjs","sources":["../src/components/Form/LMSwitch/LMSwitch.tsx"],"sourcesContent":["import React, { useId } from 'react'\nimport type { ComponentSize } from '../../../utils/componentSizes'\n\nexport interface LMSwitchProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'> {\n /** Label text */\n label?: string\n /** Description text */\n description?: string\n /** Error state */\n error?: boolean\n /** Error message */\n errorMessage?: string\n /** Size */\n size?: ComponentSize\n}\n\nconst sizeConfig = {\n xs: {\n container: 'p-2 gap-2',\n label: 'text-xs',\n description: 'text-xs mt-0.5',\n errorMessage: 'text-xs',\n track: 'w-7 h-4',\n thumb: 'w-2.5 h-2.5',\n translate: 'translate-x-3',\n },\n sm: {\n container: 'p-3 gap-2.5',\n label: 'text-sm',\n description: 'text-xs mt-1',\n errorMessage: 'text-xs',\n track: 'w-9 h-5',\n thumb: 'w-3 h-3',\n translate: 'translate-x-4',\n },\n md: {\n container: 'p-4 gap-3',\n label: 'text-base',\n description: 'text-sm mt-1',\n errorMessage: 'text-xs',\n track: 'w-11 h-6',\n thumb: 'w-4 h-4',\n translate: 'translate-x-5',\n },\n lg: {\n container: 'p-5 gap-4',\n label: 'text-lg',\n description: 'text-base mt-1.5',\n errorMessage: 'text-sm',\n track: 'w-14 h-7',\n thumb: 'w-5 h-5',\n translate: 'translate-x-7',\n },\n xl: {\n container: 'p-6 gap-4',\n label: 'text-xl',\n description: 'text-lg mt-2',\n errorMessage: 'text-sm',\n track: 'w-16 h-8',\n thumb: 'w-6 h-6',\n translate: 'translate-x-8',\n },\n '2xl': {\n container: 'p-8 gap-5',\n label: 'text-2xl',\n description: 'text-xl mt-2.5',\n errorMessage: 'text-base',\n track: 'w-20 h-10',\n thumb: 'w-8 h-8',\n translate: 'translate-x-10',\n },\n}\n\nconst LMSwitch: React.FC<LMSwitchProps> = ({\n label,\n description,\n error = false,\n errorMessage,\n size = 'md',\n id,\n ...props\n}) => {\n const autoId = useId()\n const controlId = id ?? `lm-switch-${autoId}`\n const errId = `lm-switch-err-${autoId}`\n\n const currentSize = sizeConfig[size]\n\n const getTrackBg = () => {\n if (props.disabled) return 'var(--lm-bg-paper)'\n if (error && !props.checked) return 'var(--lm-error-300)'\n if (props.checked) return 'var(--lm-primary-500)'\n return 'var(--lm-border-default)'\n }\n\n const getDisabledStyles = () => {\n if (props.disabled) {\n return {\n opacity: 0.6,\n cursor: 'not-allowed',\n } as React.CSSProperties\n }\n return {}\n }\n\n const getContainerStyles = () => {\n const base = { backgroundColor: 'var(--lm-bg-paper)' }\n return error ? { ...base, backgroundColor: 'var(--lm-error-50)' } : base\n }\n\n const getHoverContainerStyles = () =>\n error\n ? { backgroundColor: 'var(--lm-error-100)' }\n : { backgroundColor: 'var(--lm-bg-elevated)' }\n\n const getLabelStyles = () => {\n if (error) return { color: 'var(--lm-error-700)' }\n if (props.disabled)\n return { color: 'var(--lm-text-disabled)', cursor: 'not-allowed' }\n return { color: 'var(--lm-text-primary)', cursor: 'pointer' }\n }\n\n const getDescriptionStyles = () =>\n error\n ? { color: 'var(--lm-error-600)' }\n : { color: 'var(--lm-text-secondary)' }\n\n return (\n <div>\n <label\n htmlFor={controlId}\n className={`flex items-start rounded-2xl transition-colors duration-200 ${currentSize.container} ${\n props.disabled ? '' : 'cursor-pointer'\n }`}\n style={getContainerStyles()}\n onMouseEnter={(e) => {\n if (!props.disabled) {\n Object.assign(e.currentTarget.style, getHoverContainerStyles())\n }\n }}\n onMouseLeave={(e) => {\n if (!props.disabled) {\n Object.assign(e.currentTarget.style, getContainerStyles())\n }\n }}\n >\n <div className=\"shrink-0 relative\">\n <input\n type=\"checkbox\"\n id={controlId}\n {...props}\n className=\"sr-only peer\"\n aria-invalid={error || undefined}\n aria-describedby={errorMessage ? errId : undefined}\n style={getDisabledStyles()}\n />\n <div\n className={`${currentSize.track} rounded-full transition-all duration-300 relative`}\n style={{\n backgroundColor: getTrackBg(),\n ...getDisabledStyles(),\n }}\n >\n <div\n className={`${currentSize.thumb} absolute left-1 top-1/2 -translate-y-1/2 rounded-full transition-transform duration-300 ${\n props.checked ? currentSize.translate : 'translate-x-0'\n }`}\n style={{\n backgroundColor: 'var(--lm-bg-elevated)',\n boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',\n }}\n />\n </div>\n </div>\n\n {(label || description) && (\n <div className=\"flex-1\">\n {label && (\n <span\n className={`font-medium leading-tight transition-colors duration-200 ${currentSize.label}`}\n style={getLabelStyles()}\n >\n {label}\n </span>\n )}\n {description && (\n <p\n className={currentSize.description}\n style={getDescriptionStyles()}\n >\n {description}\n </p>\n )}\n </div>\n )}\n </label>\n\n {errorMessage && (\n <p\n id={errId}\n className={`flex items-center gap-1 mt-2 ${currentSize.errorMessage}`}\n style={{ color: 'var(--lm-error-500)' }}\n role=\"alert\"\n aria-live=\"polite\"\n >\n <svg\n className=\"w-3 h-3\"\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n aria-hidden=\"true\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n {errorMessage}\n </p>\n )}\n </div>\n )\n}\n\nexport default LMSwitch\n"],"names":["useId","jsxs","jsx"],"mappings":"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"}
|
|
@@ -148,7 +148,7 @@ const LMTabs = ({
|
|
|
148
148
|
Object.assign(e.currentTarget.style, getTabStyles(item, isActive));
|
|
149
149
|
},
|
|
150
150
|
children: [
|
|
151
|
-
item.icon && /* @__PURE__ */ jsx("span", { className: "
|
|
151
|
+
item.icon && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: item.icon }),
|
|
152
152
|
/* @__PURE__ */ jsx("span", { children: item.label })
|
|
153
153
|
]
|
|
154
154
|
},
|
|
@@ -197,7 +197,7 @@ const LMTabs = ({
|
|
|
197
197
|
]
|
|
198
198
|
}
|
|
199
199
|
),
|
|
200
|
-
tabBarExtraContent && !centered && /* @__PURE__ */ jsx("div", { className: "
|
|
200
|
+
tabBarExtraContent && !centered && /* @__PURE__ */ jsx("div", { className: "shrink-0 ml-4", children: tabBarExtraContent })
|
|
201
201
|
]
|
|
202
202
|
}
|
|
203
203
|
),
|
|
@@ -207,4 +207,4 @@ const LMTabs = ({
|
|
|
207
207
|
export {
|
|
208
208
|
LMTabs as L
|
|
209
209
|
};
|
|
210
|
-
//# sourceMappingURL=LMTabs-
|
|
210
|
+
//# sourceMappingURL=LMTabs-D5n9lB8X.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LMTabs-DZFAU58t.js","sources":["../src/components/DataDisplay/LMTabs/LMTabs.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useCallback } from 'react'\nimport {\n COMPONENT_SIZE_ORDER,\n SIZE_TEXT_CLASSES,\n SIZE_GAP_CLASSES,\n clampComponentSize,\n} from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\n\nexport interface LMTabItem {\n /** Unique key */\n key: string\n /** Tab label */\n label: React.ReactNode\n /** Tab content */\n children?: React.ReactNode\n /** Disabled state */\n disabled?: boolean\n /** Icon before label */\n icon?: React.ReactNode\n}\n\nexport interface LMTabsProps {\n /** Controlled active key */\n activeKey?: string\n /** Default active key */\n defaultActiveKey?: string\n /** Tab items */\n items: LMTabItem[]\n /** Tab style type */\n type?: 'line' | 'card' | 'rounded'\n /** Component size */\n size?: ComponentSize\n /** Center tabs */\n centered?: boolean\n /** Extra content on the right */\n tabBarExtraContent?: React.ReactNode\n /** Active key change handler */\n onChange?: (activeKey: string) => void\n /** Tab click handler */\n onTabClick?: (key: string) => void\n /** Custom class name */\n className?: string\n}\n\nconst LMTabs: React.FC<LMTabsProps> = ({\n activeKey: controlledActiveKey,\n defaultActiveKey,\n items,\n type = 'line',\n size = 'md',\n centered = false,\n tabBarExtraContent,\n onChange,\n onTabClick,\n className = '',\n}) => {\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const [internalActiveKey, setInternalActiveKey] = useState(\n defaultActiveKey || items[0]?.key || ''\n )\n const [inkStyle, setInkStyle] = useState<React.CSSProperties>({})\n const tabsRef = useRef<HTMLDivElement>(null)\n const tabRefs = useRef<Map<string, HTMLButtonElement>>(new Map())\n\n const activeKey = controlledActiveKey ?? internalActiveKey\n\n const tabPaddingClasses: Record<ComponentSize, string> = {\n xs: 'px-2 py-1',\n sm: 'px-3 py-1.5',\n md: 'px-4 py-2',\n lg: 'px-5 py-2.5',\n xl: 'px-6 py-3',\n '2xl': 'px-8 py-4',\n }\n\n const cardPaddingClasses: Record<ComponentSize, string> = {\n xs: 'px-2 py-1',\n sm: 'px-3 py-1.5',\n md: 'px-4 py-2',\n lg: 'px-5 py-2.5',\n xl: 'px-6 py-3',\n '2xl': 'px-8 py-4',\n }\n\n const updateInkBar = useCallback(() => {\n if (type !== 'line') return\n\n const activeTab = tabRefs.current.get(activeKey)\n const container = tabsRef.current\n\n if (activeTab && container) {\n const containerRect = container.getBoundingClientRect()\n const tabRect = activeTab.getBoundingClientRect()\n\n setInkStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n })\n }\n }, [activeKey, type])\n\n useEffect(() => {\n updateInkBar()\n }, [updateInkBar])\n\n useEffect(() => {\n const handleResize = () => updateInkBar()\n window.addEventListener('resize', handleResize)\n return () => window.removeEventListener('resize', handleResize)\n }, [updateInkBar])\n\n const handleTabClick = (item: LMTabItem) => {\n if (item.disabled) return\n\n onTabClick?.(item.key)\n\n if (controlledActiveKey === undefined) {\n setInternalActiveKey(item.key)\n }\n onChange?.(item.key)\n }\n\n const getTabStyles = (item: LMTabItem, isActive: boolean): React.CSSProperties => {\n if (item.disabled) {\n return {\n color: 'var(--lm-text-disabled)',\n cursor: 'not-allowed',\n }\n }\n\n if (type === 'line') {\n return {\n color: isActive ? 'var(--lm-primary-600)' : 'var(--lm-text-secondary)',\n backgroundColor: 'transparent',\n }\n }\n\n if (type === 'card') {\n return {\n color: isActive ? 'var(--lm-primary-600)' : 'var(--lm-text-secondary)',\n backgroundColor: isActive ? 'var(--lm-bg-elevated)' : 'transparent',\n borderColor: isActive ? 'var(--lm-border-default)' : 'transparent',\n borderBottomColor: isActive ? 'var(--lm-bg-elevated)' : 'transparent',\n }\n }\n\n // rounded\n return {\n color: isActive ? 'white' : 'var(--lm-text-secondary)',\n backgroundColor: isActive ? 'var(--lm-primary-500)' : 'transparent',\n }\n }\n\n const getTabHoverStyles = (item: LMTabItem, isActive: boolean): React.CSSProperties => {\n if (item.disabled || isActive) return {}\n\n if (type === 'line') {\n return {\n color: 'var(--lm-text-primary)',\n }\n }\n\n if (type === 'card') {\n return {\n color: 'var(--lm-text-primary)',\n backgroundColor: 'var(--lm-bg-hover)',\n }\n }\n\n // rounded\n return {\n color: 'var(--lm-text-primary)',\n backgroundColor: 'var(--lm-bg-hover)',\n }\n }\n\n const renderTab = (item: LMTabItem) => {\n const isActive = item.key === activeKey\n\n const baseClasses = `\n ${type === 'line' ? tabPaddingClasses[resolvedSize] : cardPaddingClasses[resolvedSize]}\n ${SIZE_TEXT_CLASSES[resolvedSize]}\n flex items-center ${SIZE_GAP_CLASSES[resolvedSize]}\n font-medium transition-all duration-200\n outline-none focus:ring-2 focus:ring-offset-1 focus:ring-[var(--lm-primary-400)]\n `\n\n const typeClasses = {\n line: '',\n card: `border border-b-0 rounded-t-lg ${isActive ? '-mb-px' : ''}`,\n rounded: 'rounded-full',\n }\n\n return (\n <button\n key={item.key}\n ref={(el) => {\n if (el) tabRefs.current.set(item.key, el)\n }}\n className={`${baseClasses} ${typeClasses[type]}`}\n style={getTabStyles(item, isActive)}\n onClick={() => handleTabClick(item)}\n disabled={item.disabled}\n role=\"tab\"\n aria-selected={isActive}\n aria-disabled={item.disabled}\n tabIndex={isActive ? 0 : -1}\n onMouseEnter={(e) => {\n if (!item.disabled && !isActive) {\n Object.assign(e.currentTarget.style, getTabHoverStyles(item, isActive))\n }\n }}\n onMouseLeave={(e) => {\n Object.assign(e.currentTarget.style, getTabStyles(item, isActive))\n }}\n >\n {item.icon && <span className=\"flex-shrink-0\">{item.icon}</span>}\n <span>{item.label}</span>\n </button>\n )\n }\n\n const activeItem = items.find((item) => item.key === activeKey)\n\n return (\n <div className={className}>\n {/* Tab bar */}\n <div\n className={`\n flex items-center\n ${centered ? 'justify-center' : 'justify-between'}\n ${type === 'line' ? 'border-b' : ''}\n ${type === 'card' ? 'border-b' : ''}\n `}\n style={{\n borderColor: type === 'line' || type === 'card' ? 'var(--lm-border-default)' : undefined,\n }}\n >\n {/* Tabs */}\n <div\n ref={tabsRef}\n className={`\n flex items-center relative\n ${type === 'rounded' ? `${SIZE_GAP_CLASSES[resolvedSize]} p-1 rounded-full` : ''}\n `}\n style={{\n backgroundColor: type === 'rounded' ? 'var(--lm-bg-paper)' : undefined,\n }}\n role=\"tablist\"\n >\n {items.map(renderTab)}\n\n {/* Ink bar for line type */}\n {type === 'line' && (\n <div\n className=\"absolute bottom-0 h-0.5 transition-all duration-300\"\n style={{\n ...inkStyle,\n backgroundColor: 'var(--lm-primary-500)',\n }}\n />\n )}\n </div>\n\n {/* Extra content */}\n {tabBarExtraContent && !centered && (\n <div className=\"flex-shrink-0 ml-4\">{tabBarExtraContent}</div>\n )}\n </div>\n\n {/* Tab content */}\n {activeItem?.children && (\n <div className=\"pt-4\" role=\"tabpanel\">\n {activeItem.children}\n </div>\n )}\n </div>\n )\n}\n\nexport default LMTabs\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LMTabs-D5n9lB8X.js","sources":["../src/components/DataDisplay/LMTabs/LMTabs.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useCallback } from 'react'\nimport {\n COMPONENT_SIZE_ORDER,\n SIZE_TEXT_CLASSES,\n SIZE_GAP_CLASSES,\n clampComponentSize,\n} from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\n\nexport interface LMTabItem {\n /** Unique key */\n key: string\n /** Tab label */\n label: React.ReactNode\n /** Tab content */\n children?: React.ReactNode\n /** Disabled state */\n disabled?: boolean\n /** Icon before label */\n icon?: React.ReactNode\n}\n\nexport interface LMTabsProps {\n /** Controlled active key */\n activeKey?: string\n /** Default active key */\n defaultActiveKey?: string\n /** Tab items */\n items: LMTabItem[]\n /** Tab style type */\n type?: 'line' | 'card' | 'rounded'\n /** Component size */\n size?: ComponentSize\n /** Center tabs */\n centered?: boolean\n /** Extra content on the right */\n tabBarExtraContent?: React.ReactNode\n /** Active key change handler */\n onChange?: (activeKey: string) => void\n /** Tab click handler */\n onTabClick?: (key: string) => void\n /** Custom class name */\n className?: string\n}\n\nconst LMTabs: React.FC<LMTabsProps> = ({\n activeKey: controlledActiveKey,\n defaultActiveKey,\n items,\n type = 'line',\n size = 'md',\n centered = false,\n tabBarExtraContent,\n onChange,\n onTabClick,\n className = '',\n}) => {\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const [internalActiveKey, setInternalActiveKey] = useState(\n defaultActiveKey || items[0]?.key || ''\n )\n const [inkStyle, setInkStyle] = useState<React.CSSProperties>({})\n const tabsRef = useRef<HTMLDivElement>(null)\n const tabRefs = useRef<Map<string, HTMLButtonElement>>(new Map())\n\n const activeKey = controlledActiveKey ?? internalActiveKey\n\n const tabPaddingClasses: Record<ComponentSize, string> = {\n xs: 'px-2 py-1',\n sm: 'px-3 py-1.5',\n md: 'px-4 py-2',\n lg: 'px-5 py-2.5',\n xl: 'px-6 py-3',\n '2xl': 'px-8 py-4',\n }\n\n const cardPaddingClasses: Record<ComponentSize, string> = {\n xs: 'px-2 py-1',\n sm: 'px-3 py-1.5',\n md: 'px-4 py-2',\n lg: 'px-5 py-2.5',\n xl: 'px-6 py-3',\n '2xl': 'px-8 py-4',\n }\n\n const updateInkBar = useCallback(() => {\n if (type !== 'line') return\n\n const activeTab = tabRefs.current.get(activeKey)\n const container = tabsRef.current\n\n if (activeTab && container) {\n const containerRect = container.getBoundingClientRect()\n const tabRect = activeTab.getBoundingClientRect()\n\n setInkStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n })\n }\n }, [activeKey, type])\n\n useEffect(() => {\n updateInkBar()\n }, [updateInkBar])\n\n useEffect(() => {\n const handleResize = () => updateInkBar()\n window.addEventListener('resize', handleResize)\n return () => window.removeEventListener('resize', handleResize)\n }, [updateInkBar])\n\n const handleTabClick = (item: LMTabItem) => {\n if (item.disabled) return\n\n onTabClick?.(item.key)\n\n if (controlledActiveKey === undefined) {\n setInternalActiveKey(item.key)\n }\n onChange?.(item.key)\n }\n\n const getTabStyles = (item: LMTabItem, isActive: boolean): React.CSSProperties => {\n if (item.disabled) {\n return {\n color: 'var(--lm-text-disabled)',\n cursor: 'not-allowed',\n }\n }\n\n if (type === 'line') {\n return {\n color: isActive ? 'var(--lm-primary-600)' : 'var(--lm-text-secondary)',\n backgroundColor: 'transparent',\n }\n }\n\n if (type === 'card') {\n return {\n color: isActive ? 'var(--lm-primary-600)' : 'var(--lm-text-secondary)',\n backgroundColor: isActive ? 'var(--lm-bg-elevated)' : 'transparent',\n borderColor: isActive ? 'var(--lm-border-default)' : 'transparent',\n borderBottomColor: isActive ? 'var(--lm-bg-elevated)' : 'transparent',\n }\n }\n\n // rounded\n return {\n color: isActive ? 'white' : 'var(--lm-text-secondary)',\n backgroundColor: isActive ? 'var(--lm-primary-500)' : 'transparent',\n }\n }\n\n const getTabHoverStyles = (item: LMTabItem, isActive: boolean): React.CSSProperties => {\n if (item.disabled || isActive) return {}\n\n if (type === 'line') {\n return {\n color: 'var(--lm-text-primary)',\n }\n }\n\n if (type === 'card') {\n return {\n color: 'var(--lm-text-primary)',\n backgroundColor: 'var(--lm-bg-hover)',\n }\n }\n\n // rounded\n return {\n color: 'var(--lm-text-primary)',\n backgroundColor: 'var(--lm-bg-hover)',\n }\n }\n\n const renderTab = (item: LMTabItem) => {\n const isActive = item.key === activeKey\n\n const baseClasses = `\n ${type === 'line' ? tabPaddingClasses[resolvedSize] : cardPaddingClasses[resolvedSize]}\n ${SIZE_TEXT_CLASSES[resolvedSize]}\n flex items-center ${SIZE_GAP_CLASSES[resolvedSize]}\n font-medium transition-all duration-200\n outline-none focus:ring-2 focus:ring-offset-1 focus:ring-[var(--lm-primary-400)]\n `\n\n const typeClasses = {\n line: '',\n card: `border border-b-0 rounded-t-lg ${isActive ? '-mb-px' : ''}`,\n rounded: 'rounded-full',\n }\n\n return (\n <button\n key={item.key}\n ref={(el) => {\n if (el) tabRefs.current.set(item.key, el)\n }}\n className={`${baseClasses} ${typeClasses[type]}`}\n style={getTabStyles(item, isActive)}\n onClick={() => handleTabClick(item)}\n disabled={item.disabled}\n role=\"tab\"\n aria-selected={isActive}\n aria-disabled={item.disabled}\n tabIndex={isActive ? 0 : -1}\n onMouseEnter={(e) => {\n if (!item.disabled && !isActive) {\n Object.assign(e.currentTarget.style, getTabHoverStyles(item, isActive))\n }\n }}\n onMouseLeave={(e) => {\n Object.assign(e.currentTarget.style, getTabStyles(item, isActive))\n }}\n >\n {item.icon && <span className=\"shrink-0\">{item.icon}</span>}\n <span>{item.label}</span>\n </button>\n )\n }\n\n const activeItem = items.find((item) => item.key === activeKey)\n\n return (\n <div className={className}>\n {/* Tab bar */}\n <div\n className={`\n flex items-center\n ${centered ? 'justify-center' : 'justify-between'}\n ${type === 'line' ? 'border-b' : ''}\n ${type === 'card' ? 'border-b' : ''}\n `}\n style={{\n borderColor: type === 'line' || type === 'card' ? 'var(--lm-border-default)' : undefined,\n }}\n >\n {/* Tabs */}\n <div\n ref={tabsRef}\n className={`\n flex items-center relative\n ${type === 'rounded' ? `${SIZE_GAP_CLASSES[resolvedSize]} p-1 rounded-full` : ''}\n `}\n style={{\n backgroundColor: type === 'rounded' ? 'var(--lm-bg-paper)' : undefined,\n }}\n role=\"tablist\"\n >\n {items.map(renderTab)}\n\n {/* Ink bar for line type */}\n {type === 'line' && (\n <div\n className=\"absolute bottom-0 h-0.5 transition-all duration-300\"\n style={{\n ...inkStyle,\n backgroundColor: 'var(--lm-primary-500)',\n }}\n />\n )}\n </div>\n\n {/* Extra content */}\n {tabBarExtraContent && !centered && (\n <div className=\"shrink-0 ml-4\">{tabBarExtraContent}</div>\n )}\n </div>\n\n {/* Tab content */}\n {activeItem?.children && (\n <div className=\"pt-4\" role=\"tabpanel\">\n {activeItem.children}\n </div>\n )}\n </div>\n )\n}\n\nexport default LMTabs\n"],"names":[],"mappings":"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"}
|
|
@@ -149,7 +149,7 @@ const LMTabs = ({
|
|
|
149
149
|
Object.assign(e.currentTarget.style, getTabStyles(item, isActive));
|
|
150
150
|
},
|
|
151
151
|
children: [
|
|
152
|
-
item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "
|
|
152
|
+
item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: item.icon }),
|
|
153
153
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label })
|
|
154
154
|
]
|
|
155
155
|
},
|
|
@@ -198,7 +198,7 @@ const LMTabs = ({
|
|
|
198
198
|
]
|
|
199
199
|
}
|
|
200
200
|
),
|
|
201
|
-
tabBarExtraContent && !centered && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
201
|
+
tabBarExtraContent && !centered && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 ml-4", children: tabBarExtraContent })
|
|
202
202
|
]
|
|
203
203
|
}
|
|
204
204
|
),
|
|
@@ -206,4 +206,4 @@ const LMTabs = ({
|
|
|
206
206
|
] });
|
|
207
207
|
};
|
|
208
208
|
exports.LMTabs = LMTabs;
|
|
209
|
-
//# sourceMappingURL=LMTabs-
|
|
209
|
+
//# sourceMappingURL=LMTabs-NPmOzPat.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LMTabs-DCVaqbrn.cjs","sources":["../src/components/DataDisplay/LMTabs/LMTabs.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useCallback } from 'react'\nimport {\n COMPONENT_SIZE_ORDER,\n SIZE_TEXT_CLASSES,\n SIZE_GAP_CLASSES,\n clampComponentSize,\n} from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\n\nexport interface LMTabItem {\n /** Unique key */\n key: string\n /** Tab label */\n label: React.ReactNode\n /** Tab content */\n children?: React.ReactNode\n /** Disabled state */\n disabled?: boolean\n /** Icon before label */\n icon?: React.ReactNode\n}\n\nexport interface LMTabsProps {\n /** Controlled active key */\n activeKey?: string\n /** Default active key */\n defaultActiveKey?: string\n /** Tab items */\n items: LMTabItem[]\n /** Tab style type */\n type?: 'line' | 'card' | 'rounded'\n /** Component size */\n size?: ComponentSize\n /** Center tabs */\n centered?: boolean\n /** Extra content on the right */\n tabBarExtraContent?: React.ReactNode\n /** Active key change handler */\n onChange?: (activeKey: string) => void\n /** Tab click handler */\n onTabClick?: (key: string) => void\n /** Custom class name */\n className?: string\n}\n\nconst LMTabs: React.FC<LMTabsProps> = ({\n activeKey: controlledActiveKey,\n defaultActiveKey,\n items,\n type = 'line',\n size = 'md',\n centered = false,\n tabBarExtraContent,\n onChange,\n onTabClick,\n className = '',\n}) => {\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const [internalActiveKey, setInternalActiveKey] = useState(\n defaultActiveKey || items[0]?.key || ''\n )\n const [inkStyle, setInkStyle] = useState<React.CSSProperties>({})\n const tabsRef = useRef<HTMLDivElement>(null)\n const tabRefs = useRef<Map<string, HTMLButtonElement>>(new Map())\n\n const activeKey = controlledActiveKey ?? internalActiveKey\n\n const tabPaddingClasses: Record<ComponentSize, string> = {\n xs: 'px-2 py-1',\n sm: 'px-3 py-1.5',\n md: 'px-4 py-2',\n lg: 'px-5 py-2.5',\n xl: 'px-6 py-3',\n '2xl': 'px-8 py-4',\n }\n\n const cardPaddingClasses: Record<ComponentSize, string> = {\n xs: 'px-2 py-1',\n sm: 'px-3 py-1.5',\n md: 'px-4 py-2',\n lg: 'px-5 py-2.5',\n xl: 'px-6 py-3',\n '2xl': 'px-8 py-4',\n }\n\n const updateInkBar = useCallback(() => {\n if (type !== 'line') return\n\n const activeTab = tabRefs.current.get(activeKey)\n const container = tabsRef.current\n\n if (activeTab && container) {\n const containerRect = container.getBoundingClientRect()\n const tabRect = activeTab.getBoundingClientRect()\n\n setInkStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n })\n }\n }, [activeKey, type])\n\n useEffect(() => {\n updateInkBar()\n }, [updateInkBar])\n\n useEffect(() => {\n const handleResize = () => updateInkBar()\n window.addEventListener('resize', handleResize)\n return () => window.removeEventListener('resize', handleResize)\n }, [updateInkBar])\n\n const handleTabClick = (item: LMTabItem) => {\n if (item.disabled) return\n\n onTabClick?.(item.key)\n\n if (controlledActiveKey === undefined) {\n setInternalActiveKey(item.key)\n }\n onChange?.(item.key)\n }\n\n const getTabStyles = (item: LMTabItem, isActive: boolean): React.CSSProperties => {\n if (item.disabled) {\n return {\n color: 'var(--lm-text-disabled)',\n cursor: 'not-allowed',\n }\n }\n\n if (type === 'line') {\n return {\n color: isActive ? 'var(--lm-primary-600)' : 'var(--lm-text-secondary)',\n backgroundColor: 'transparent',\n }\n }\n\n if (type === 'card') {\n return {\n color: isActive ? 'var(--lm-primary-600)' : 'var(--lm-text-secondary)',\n backgroundColor: isActive ? 'var(--lm-bg-elevated)' : 'transparent',\n borderColor: isActive ? 'var(--lm-border-default)' : 'transparent',\n borderBottomColor: isActive ? 'var(--lm-bg-elevated)' : 'transparent',\n }\n }\n\n // rounded\n return {\n color: isActive ? 'white' : 'var(--lm-text-secondary)',\n backgroundColor: isActive ? 'var(--lm-primary-500)' : 'transparent',\n }\n }\n\n const getTabHoverStyles = (item: LMTabItem, isActive: boolean): React.CSSProperties => {\n if (item.disabled || isActive) return {}\n\n if (type === 'line') {\n return {\n color: 'var(--lm-text-primary)',\n }\n }\n\n if (type === 'card') {\n return {\n color: 'var(--lm-text-primary)',\n backgroundColor: 'var(--lm-bg-hover)',\n }\n }\n\n // rounded\n return {\n color: 'var(--lm-text-primary)',\n backgroundColor: 'var(--lm-bg-hover)',\n }\n }\n\n const renderTab = (item: LMTabItem) => {\n const isActive = item.key === activeKey\n\n const baseClasses = `\n ${type === 'line' ? tabPaddingClasses[resolvedSize] : cardPaddingClasses[resolvedSize]}\n ${SIZE_TEXT_CLASSES[resolvedSize]}\n flex items-center ${SIZE_GAP_CLASSES[resolvedSize]}\n font-medium transition-all duration-200\n outline-none focus:ring-2 focus:ring-offset-1 focus:ring-[var(--lm-primary-400)]\n `\n\n const typeClasses = {\n line: '',\n card: `border border-b-0 rounded-t-lg ${isActive ? '-mb-px' : ''}`,\n rounded: 'rounded-full',\n }\n\n return (\n <button\n key={item.key}\n ref={(el) => {\n if (el) tabRefs.current.set(item.key, el)\n }}\n className={`${baseClasses} ${typeClasses[type]}`}\n style={getTabStyles(item, isActive)}\n onClick={() => handleTabClick(item)}\n disabled={item.disabled}\n role=\"tab\"\n aria-selected={isActive}\n aria-disabled={item.disabled}\n tabIndex={isActive ? 0 : -1}\n onMouseEnter={(e) => {\n if (!item.disabled && !isActive) {\n Object.assign(e.currentTarget.style, getTabHoverStyles(item, isActive))\n }\n }}\n onMouseLeave={(e) => {\n Object.assign(e.currentTarget.style, getTabStyles(item, isActive))\n }}\n >\n {item.icon && <span className=\"flex-shrink-0\">{item.icon}</span>}\n <span>{item.label}</span>\n </button>\n )\n }\n\n const activeItem = items.find((item) => item.key === activeKey)\n\n return (\n <div className={className}>\n {/* Tab bar */}\n <div\n className={`\n flex items-center\n ${centered ? 'justify-center' : 'justify-between'}\n ${type === 'line' ? 'border-b' : ''}\n ${type === 'card' ? 'border-b' : ''}\n `}\n style={{\n borderColor: type === 'line' || type === 'card' ? 'var(--lm-border-default)' : undefined,\n }}\n >\n {/* Tabs */}\n <div\n ref={tabsRef}\n className={`\n flex items-center relative\n ${type === 'rounded' ? `${SIZE_GAP_CLASSES[resolvedSize]} p-1 rounded-full` : ''}\n `}\n style={{\n backgroundColor: type === 'rounded' ? 'var(--lm-bg-paper)' : undefined,\n }}\n role=\"tablist\"\n >\n {items.map(renderTab)}\n\n {/* Ink bar for line type */}\n {type === 'line' && (\n <div\n className=\"absolute bottom-0 h-0.5 transition-all duration-300\"\n style={{\n ...inkStyle,\n backgroundColor: 'var(--lm-primary-500)',\n }}\n />\n )}\n </div>\n\n {/* Extra content */}\n {tabBarExtraContent && !centered && (\n <div className=\"flex-shrink-0 ml-4\">{tabBarExtraContent}</div>\n )}\n </div>\n\n {/* Tab content */}\n {activeItem?.children && (\n <div className=\"pt-4\" role=\"tabpanel\">\n {activeItem.children}\n </div>\n )}\n </div>\n )\n}\n\nexport default LMTabs\n"],"names":["clampComponentSize","COMPONENT_SIZE_ORDER","useState","useRef","useCallback","useEffect","SIZE_TEXT_CLASSES","SIZE_GAP_CLASSES","jsxs","jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LMTabs-NPmOzPat.cjs","sources":["../src/components/DataDisplay/LMTabs/LMTabs.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useCallback } from 'react'\nimport {\n COMPONENT_SIZE_ORDER,\n SIZE_TEXT_CLASSES,\n SIZE_GAP_CLASSES,\n clampComponentSize,\n} from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\n\nexport interface LMTabItem {\n /** Unique key */\n key: string\n /** Tab label */\n label: React.ReactNode\n /** Tab content */\n children?: React.ReactNode\n /** Disabled state */\n disabled?: boolean\n /** Icon before label */\n icon?: React.ReactNode\n}\n\nexport interface LMTabsProps {\n /** Controlled active key */\n activeKey?: string\n /** Default active key */\n defaultActiveKey?: string\n /** Tab items */\n items: LMTabItem[]\n /** Tab style type */\n type?: 'line' | 'card' | 'rounded'\n /** Component size */\n size?: ComponentSize\n /** Center tabs */\n centered?: boolean\n /** Extra content on the right */\n tabBarExtraContent?: React.ReactNode\n /** Active key change handler */\n onChange?: (activeKey: string) => void\n /** Tab click handler */\n onTabClick?: (key: string) => void\n /** Custom class name */\n className?: string\n}\n\nconst LMTabs: React.FC<LMTabsProps> = ({\n activeKey: controlledActiveKey,\n defaultActiveKey,\n items,\n type = 'line',\n size = 'md',\n centered = false,\n tabBarExtraContent,\n onChange,\n onTabClick,\n className = '',\n}) => {\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const [internalActiveKey, setInternalActiveKey] = useState(\n defaultActiveKey || items[0]?.key || ''\n )\n const [inkStyle, setInkStyle] = useState<React.CSSProperties>({})\n const tabsRef = useRef<HTMLDivElement>(null)\n const tabRefs = useRef<Map<string, HTMLButtonElement>>(new Map())\n\n const activeKey = controlledActiveKey ?? internalActiveKey\n\n const tabPaddingClasses: Record<ComponentSize, string> = {\n xs: 'px-2 py-1',\n sm: 'px-3 py-1.5',\n md: 'px-4 py-2',\n lg: 'px-5 py-2.5',\n xl: 'px-6 py-3',\n '2xl': 'px-8 py-4',\n }\n\n const cardPaddingClasses: Record<ComponentSize, string> = {\n xs: 'px-2 py-1',\n sm: 'px-3 py-1.5',\n md: 'px-4 py-2',\n lg: 'px-5 py-2.5',\n xl: 'px-6 py-3',\n '2xl': 'px-8 py-4',\n }\n\n const updateInkBar = useCallback(() => {\n if (type !== 'line') return\n\n const activeTab = tabRefs.current.get(activeKey)\n const container = tabsRef.current\n\n if (activeTab && container) {\n const containerRect = container.getBoundingClientRect()\n const tabRect = activeTab.getBoundingClientRect()\n\n setInkStyle({\n left: tabRect.left - containerRect.left,\n width: tabRect.width,\n })\n }\n }, [activeKey, type])\n\n useEffect(() => {\n updateInkBar()\n }, [updateInkBar])\n\n useEffect(() => {\n const handleResize = () => updateInkBar()\n window.addEventListener('resize', handleResize)\n return () => window.removeEventListener('resize', handleResize)\n }, [updateInkBar])\n\n const handleTabClick = (item: LMTabItem) => {\n if (item.disabled) return\n\n onTabClick?.(item.key)\n\n if (controlledActiveKey === undefined) {\n setInternalActiveKey(item.key)\n }\n onChange?.(item.key)\n }\n\n const getTabStyles = (item: LMTabItem, isActive: boolean): React.CSSProperties => {\n if (item.disabled) {\n return {\n color: 'var(--lm-text-disabled)',\n cursor: 'not-allowed',\n }\n }\n\n if (type === 'line') {\n return {\n color: isActive ? 'var(--lm-primary-600)' : 'var(--lm-text-secondary)',\n backgroundColor: 'transparent',\n }\n }\n\n if (type === 'card') {\n return {\n color: isActive ? 'var(--lm-primary-600)' : 'var(--lm-text-secondary)',\n backgroundColor: isActive ? 'var(--lm-bg-elevated)' : 'transparent',\n borderColor: isActive ? 'var(--lm-border-default)' : 'transparent',\n borderBottomColor: isActive ? 'var(--lm-bg-elevated)' : 'transparent',\n }\n }\n\n // rounded\n return {\n color: isActive ? 'white' : 'var(--lm-text-secondary)',\n backgroundColor: isActive ? 'var(--lm-primary-500)' : 'transparent',\n }\n }\n\n const getTabHoverStyles = (item: LMTabItem, isActive: boolean): React.CSSProperties => {\n if (item.disabled || isActive) return {}\n\n if (type === 'line') {\n return {\n color: 'var(--lm-text-primary)',\n }\n }\n\n if (type === 'card') {\n return {\n color: 'var(--lm-text-primary)',\n backgroundColor: 'var(--lm-bg-hover)',\n }\n }\n\n // rounded\n return {\n color: 'var(--lm-text-primary)',\n backgroundColor: 'var(--lm-bg-hover)',\n }\n }\n\n const renderTab = (item: LMTabItem) => {\n const isActive = item.key === activeKey\n\n const baseClasses = `\n ${type === 'line' ? tabPaddingClasses[resolvedSize] : cardPaddingClasses[resolvedSize]}\n ${SIZE_TEXT_CLASSES[resolvedSize]}\n flex items-center ${SIZE_GAP_CLASSES[resolvedSize]}\n font-medium transition-all duration-200\n outline-none focus:ring-2 focus:ring-offset-1 focus:ring-[var(--lm-primary-400)]\n `\n\n const typeClasses = {\n line: '',\n card: `border border-b-0 rounded-t-lg ${isActive ? '-mb-px' : ''}`,\n rounded: 'rounded-full',\n }\n\n return (\n <button\n key={item.key}\n ref={(el) => {\n if (el) tabRefs.current.set(item.key, el)\n }}\n className={`${baseClasses} ${typeClasses[type]}`}\n style={getTabStyles(item, isActive)}\n onClick={() => handleTabClick(item)}\n disabled={item.disabled}\n role=\"tab\"\n aria-selected={isActive}\n aria-disabled={item.disabled}\n tabIndex={isActive ? 0 : -1}\n onMouseEnter={(e) => {\n if (!item.disabled && !isActive) {\n Object.assign(e.currentTarget.style, getTabHoverStyles(item, isActive))\n }\n }}\n onMouseLeave={(e) => {\n Object.assign(e.currentTarget.style, getTabStyles(item, isActive))\n }}\n >\n {item.icon && <span className=\"shrink-0\">{item.icon}</span>}\n <span>{item.label}</span>\n </button>\n )\n }\n\n const activeItem = items.find((item) => item.key === activeKey)\n\n return (\n <div className={className}>\n {/* Tab bar */}\n <div\n className={`\n flex items-center\n ${centered ? 'justify-center' : 'justify-between'}\n ${type === 'line' ? 'border-b' : ''}\n ${type === 'card' ? 'border-b' : ''}\n `}\n style={{\n borderColor: type === 'line' || type === 'card' ? 'var(--lm-border-default)' : undefined,\n }}\n >\n {/* Tabs */}\n <div\n ref={tabsRef}\n className={`\n flex items-center relative\n ${type === 'rounded' ? `${SIZE_GAP_CLASSES[resolvedSize]} p-1 rounded-full` : ''}\n `}\n style={{\n backgroundColor: type === 'rounded' ? 'var(--lm-bg-paper)' : undefined,\n }}\n role=\"tablist\"\n >\n {items.map(renderTab)}\n\n {/* Ink bar for line type */}\n {type === 'line' && (\n <div\n className=\"absolute bottom-0 h-0.5 transition-all duration-300\"\n style={{\n ...inkStyle,\n backgroundColor: 'var(--lm-primary-500)',\n }}\n />\n )}\n </div>\n\n {/* Extra content */}\n {tabBarExtraContent && !centered && (\n <div className=\"shrink-0 ml-4\">{tabBarExtraContent}</div>\n )}\n </div>\n\n {/* Tab content */}\n {activeItem?.children && (\n <div className=\"pt-4\" role=\"tabpanel\">\n {activeItem.children}\n </div>\n )}\n </div>\n )\n}\n\nexport default LMTabs\n"],"names":["clampComponentSize","COMPONENT_SIZE_ORDER","useState","useRef","useCallback","useEffect","SIZE_TEXT_CLASSES","SIZE_GAP_CLASSES","jsxs","jsx"],"mappings":"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"}
|
|
@@ -210,7 +210,7 @@ const LMUpload = ({
|
|
|
210
210
|
listType === "picture" && isImage && file.url ? /* @__PURE__ */ jsx(
|
|
211
211
|
"div",
|
|
212
212
|
{
|
|
213
|
-
className: `${thumbSizeClasses[resolvedSize]} rounded-lg overflow-hidden
|
|
213
|
+
className: `${thumbSizeClasses[resolvedSize]} rounded-lg overflow-hidden shrink-0`,
|
|
214
214
|
style: { backgroundColor: "var(--lm-bg-elevated)" },
|
|
215
215
|
children: /* @__PURE__ */ jsx(
|
|
216
216
|
"img",
|
|
@@ -224,7 +224,7 @@ const LMUpload = ({
|
|
|
224
224
|
) : /* @__PURE__ */ jsx(
|
|
225
225
|
"div",
|
|
226
226
|
{
|
|
227
|
-
className: "p-2 rounded-lg
|
|
227
|
+
className: "p-2 rounded-lg shrink-0",
|
|
228
228
|
style: {
|
|
229
229
|
backgroundColor: file.status === "error" ? "var(--lm-error-100)" : "var(--lm-bg-elevated)",
|
|
230
230
|
color: file.status === "error" ? "var(--lm-error-500)" : "var(--lm-text-secondary)"
|
|
@@ -272,7 +272,7 @@ const LMUpload = ({
|
|
|
272
272
|
"button",
|
|
273
273
|
{
|
|
274
274
|
type: "button",
|
|
275
|
-
className: "p-1.5 rounded-lg transition-colors duration-200 hover:bg-
|
|
275
|
+
className: "p-1.5 rounded-lg transition-colors duration-200 hover:bg-(--lm-bg-hover) shrink-0",
|
|
276
276
|
style: { color: "var(--lm-text-tertiary)" },
|
|
277
277
|
onClick: () => handleRemove(file),
|
|
278
278
|
"aria-label": `删除 ${file.name}`,
|
|
@@ -307,7 +307,7 @@ const LMUpload = ({
|
|
|
307
307
|
border-2 border-dashed rounded-2xl
|
|
308
308
|
flex flex-col items-center justify-center
|
|
309
309
|
transition-all duration-200
|
|
310
|
-
${disabled ? "" : "cursor-pointer hover:border-
|
|
310
|
+
${disabled ? "" : "cursor-pointer hover:border-(--lm-primary-400)"}
|
|
311
311
|
`,
|
|
312
312
|
style: getDropzoneStyles(),
|
|
313
313
|
onClick: handleClick,
|
|
@@ -377,4 +377,4 @@ const LMUpload = ({
|
|
|
377
377
|
export {
|
|
378
378
|
LMUpload as L
|
|
379
379
|
};
|
|
380
|
-
//# sourceMappingURL=LMUpload-
|
|
380
|
+
//# sourceMappingURL=LMUpload-BwXoxIfE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LMUpload-BwXoxIfE.js","sources":["../src/components/Form/LMUpload/LMUpload.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useId } from 'react'\nimport {\n COMPONENT_SIZE_ORDER,\n SIZE_TEXT_CLASSES,\n SIZE_GAP_CLASSES,\n SIZE_PADDING_CLASSES,\n clampComponentSize,\n} from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\n\nexport interface LMUploadFile {\n /** Unique file ID */\n uid: string\n /** File name */\n name: string\n /** File size in bytes */\n size: number\n /** File type */\n type: string\n /** Upload status */\n status: 'uploading' | 'done' | 'error'\n /** Upload progress (0-100) */\n percent?: number\n /** Error message */\n error?: string\n /** Original file object */\n originFile?: File\n /** Preview URL (for images) */\n url?: string\n}\n\nexport interface LMUploadProps {\n /** File list (controlled) */\n fileList?: LMUploadFile[]\n /** Default file list */\n defaultFileList?: LMUploadFile[]\n /** Accept file types (e.g., \"image/*,.pdf\") */\n accept?: string\n /** Allow multiple files */\n multiple?: boolean\n /** Max file count */\n maxCount?: number\n /** Max file size in bytes */\n maxSize?: number\n /** Disabled state */\n disabled?: boolean\n /** Show file list */\n showFileList?: boolean\n /** Upload mode: drag area or button */\n listType?: 'text' | 'picture'\n /** Component size */\n size?: ComponentSize\n /** Custom upload handler */\n customRequest?: (file: File) => Promise<string>\n /** Change handler */\n onChange?: (fileList: LMUploadFile[]) => void\n /** Before upload hook, return false to prevent upload */\n beforeUpload?: (file: File) => boolean | Promise<boolean>\n /** Remove handler */\n onRemove?: (file: LMUploadFile) => void | boolean | Promise<boolean>\n /** Error state */\n error?: boolean\n /** Error message */\n errorMessage?: string\n /** Placeholder text */\n placeholder?: string\n /** Hint text below the upload area */\n hint?: string\n /** Custom class name */\n className?: string\n /** Children for custom trigger */\n children?: React.ReactNode\n}\n\nconst UploadIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-8 h-8'} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5\" />\n </svg>\n)\n\nconst FileIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-5 h-5'} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z\" />\n </svg>\n)\n\nconst ImageIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-5 h-5'} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z\" />\n </svg>\n)\n\nconst DeleteIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-4 h-4'} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n)\n\nconst CheckIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-4 h-4'} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n)\n\nconst ErrorIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-4 h-4'} viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path fillRule=\"evenodd\" d=\"M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zm-1.72 6.97a.75.75 0 10-1.06 1.06L10.94 12l-1.72 1.72a.75.75 0 101.06 1.06L12 13.06l1.72 1.72a.75.75 0 101.06-1.06L13.06 12l1.72-1.72a.75.75 0 10-1.06-1.06L12 10.94l-1.72-1.72z\" clipRule=\"evenodd\" />\n </svg>\n)\n\nlet fileIdCounter = 0\nconst generateFileId = () => `upload-${++fileIdCounter}-${Date.now()}`\n\nconst formatFileSize = (bytes: number): string => {\n if (bytes === 0) return '0 B'\n const k = 1024\n const sizes = ['B', 'KB', 'MB', 'GB']\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`\n}\n\nconst isImageFile = (file: LMUploadFile): boolean => {\n return file.type.startsWith('image/') || /\\.(jpg|jpeg|png|gif|webp|svg|bmp)$/i.test(file.name)\n}\n\nconst LMUpload: React.FC<LMUploadProps> = ({\n fileList: controlledFileList,\n defaultFileList = [],\n accept,\n multiple = false,\n maxCount,\n maxSize,\n disabled = false,\n showFileList = true,\n listType = 'text',\n size = 'md',\n customRequest,\n onChange,\n beforeUpload,\n onRemove,\n error = false,\n errorMessage,\n placeholder = '点击或拖拽文件到此区域上传',\n hint,\n className = '',\n children,\n}) => {\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const inputId = useId()\n const inputRef = useRef<HTMLInputElement>(null)\n const [internalFileList, setInternalFileList] = useState<LMUploadFile[]>(defaultFileList)\n const [isDragging, setIsDragging] = useState(false)\n\n const fileList = controlledFileList ?? internalFileList\n\n const updateFileList = useCallback((newFileList: LMUploadFile[]) => {\n if (controlledFileList === undefined) {\n setInternalFileList(newFileList)\n }\n onChange?.(newFileList)\n }, [controlledFileList, onChange])\n\n const uploadFile = useCallback(async (file: File) => {\n const uid = generateFileId()\n const newFile: LMUploadFile = {\n uid,\n name: file.name,\n size: file.size,\n type: file.type,\n status: 'uploading',\n percent: 0,\n originFile: file,\n }\n\n // Create preview URL for images\n if (file.type.startsWith('image/')) {\n newFile.url = URL.createObjectURL(file)\n }\n\n // Add file to list\n const updatedList = [...fileList, newFile]\n updateFileList(updatedList)\n\n if (customRequest) {\n try {\n const url = await customRequest(file)\n updateFileList([...updatedList.slice(0, -1), { ...newFile, status: 'done', percent: 100, url }])\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '上传失败'\n updateFileList([...updatedList.slice(0, -1), { ...newFile, status: 'error', error: errorMsg }])\n }\n } else {\n // Simulate upload progress\n let progress = 0\n const interval = setInterval(() => {\n progress += Math.random() * 30\n if (progress >= 100) {\n progress = 100\n clearInterval(interval)\n setInternalFileList(prev => prev.map(f =>\n f.uid === uid ? { ...f, status: 'done' as const, percent: 100 } : f\n ))\n } else {\n setInternalFileList(prev => prev.map(f =>\n f.uid === uid ? { ...f, percent: Math.round(progress) } : f\n ))\n }\n }, 200)\n }\n }, [fileList, customRequest, updateFileList])\n\n const handleFiles = useCallback(async (files: FileList | null) => {\n if (!files || files.length === 0 || disabled) return\n\n const fileArray = Array.from(files)\n\n for (const file of fileArray) {\n // Check max count\n if (maxCount && fileList.length >= maxCount) {\n console.warn(`Max file count (${maxCount}) reached`)\n break\n }\n\n // Check max size\n if (maxSize && file.size > maxSize) {\n console.warn(`File ${file.name} exceeds max size (${formatFileSize(maxSize)})`)\n continue\n }\n\n // Before upload hook\n if (beforeUpload) {\n const result = await beforeUpload(file)\n if (!result) continue\n }\n\n await uploadFile(file)\n }\n }, [disabled, maxCount, maxSize, fileList.length, beforeUpload, uploadFile])\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n }\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragging(true)\n }\n }\n\n const handleDragLeave = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragging(false)\n }\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragging(false)\n if (!disabled) {\n handleFiles(e.dataTransfer.files)\n }\n }\n\n const handleRemove = async (file: LMUploadFile) => {\n if (onRemove) {\n const result = await onRemove(file)\n if (result === false) return\n }\n\n // Revoke object URL to prevent memory leaks\n if (file.url?.startsWith('blob:')) {\n URL.revokeObjectURL(file.url)\n }\n\n const newFileList = fileList.filter(f => f.uid !== file.uid)\n updateFileList(newFileList)\n }\n\n const handleClick = () => {\n if (!disabled) {\n inputRef.current?.click()\n }\n }\n\n const iconSizeClasses: Record<ComponentSize, string> = {\n xs: 'w-6 h-6',\n sm: 'w-7 h-7',\n md: 'w-8 h-8',\n lg: 'w-10 h-10',\n xl: 'w-12 h-12',\n '2xl': 'w-14 h-14',\n }\n\n const thumbSizeClasses: Record<ComponentSize, string> = {\n xs: 'w-10 h-10',\n sm: 'w-12 h-12',\n md: 'w-14 h-14',\n lg: 'w-16 h-16',\n xl: 'w-20 h-20',\n '2xl': 'w-24 h-24',\n }\n\n const getDropzoneStyles = (): React.CSSProperties => {\n const base: React.CSSProperties = {\n backgroundColor: 'var(--lm-bg-elevated)',\n borderColor: error ? 'var(--lm-error-300)' : 'var(--lm-border-default)',\n }\n\n if (disabled) {\n return {\n ...base,\n backgroundColor: 'var(--lm-bg-paper)',\n cursor: 'not-allowed',\n opacity: 0.6,\n }\n }\n\n if (isDragging) {\n return {\n ...base,\n backgroundColor: 'var(--lm-primary-50)',\n borderColor: 'var(--lm-primary-400)',\n }\n }\n\n return base\n }\n\n const renderFileItem = (file: LMUploadFile) => {\n const isImage = isImageFile(file)\n\n return (\n <div\n key={file.uid}\n className={`flex items-center ${SIZE_GAP_CLASSES[resolvedSize]} ${SIZE_PADDING_CLASSES[resolvedSize]} rounded-xl border transition-all duration-200`}\n style={{\n backgroundColor: file.status === 'error' ? 'var(--lm-error-50)' : 'var(--lm-bg-paper)',\n borderColor: file.status === 'error' ? 'var(--lm-error-200)' : 'var(--lm-border-light)',\n }}\n >\n {/* Thumbnail / Icon */}\n {listType === 'picture' && isImage && file.url ? (\n <div\n className={`${thumbSizeClasses[resolvedSize]} rounded-lg overflow-hidden shrink-0`}\n style={{ backgroundColor: 'var(--lm-bg-elevated)' }}\n >\n <img\n src={file.url}\n alt={file.name}\n className=\"w-full h-full object-cover\"\n />\n </div>\n ) : (\n <div\n className=\"p-2 rounded-lg shrink-0\"\n style={{\n backgroundColor: file.status === 'error' ? 'var(--lm-error-100)' : 'var(--lm-bg-elevated)',\n color: file.status === 'error' ? 'var(--lm-error-500)' : 'var(--lm-text-secondary)',\n }}\n >\n {isImage ? <ImageIcon className=\"w-5 h-5\" /> : <FileIcon className=\"w-5 h-5\" />}\n </div>\n )}\n\n {/* File info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span\n className={`${SIZE_TEXT_CLASSES[resolvedSize]} font-medium truncate`}\n style={{ color: file.status === 'error' ? 'var(--lm-error-700)' : 'var(--lm-text-primary)' }}\n title={file.name}\n >\n {file.name}\n </span>\n {file.status === 'done' && (\n <span style={{ color: 'var(--lm-success-500)' }}>\n <CheckIcon className=\"w-4 h-4\" />\n </span>\n )}\n {file.status === 'error' && (\n <span style={{ color: 'var(--lm-error-500)' }}>\n <ErrorIcon className=\"w-4 h-4\" />\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-2 mt-1\">\n <span className=\"text-xs\" style={{ color: 'var(--lm-text-tertiary)' }}>\n {formatFileSize(file.size)}\n </span>\n {file.status === 'error' && file.error && (\n <span className=\"text-xs\" style={{ color: 'var(--lm-error-500)' }}>\n {file.error}\n </span>\n )}\n </div>\n\n {/* Progress bar */}\n {file.status === 'uploading' && (\n <div className=\"mt-2\">\n <div\n className=\"h-1.5 rounded-full overflow-hidden\"\n style={{ backgroundColor: 'var(--lm-bg-active)' }}\n >\n <div\n className=\"h-full rounded-full transition-all duration-300\"\n style={{\n width: `${file.percent || 0}%`,\n backgroundColor: 'var(--lm-primary-500)',\n }}\n />\n </div>\n </div>\n )}\n </div>\n\n {/* Remove button */}\n <button\n type=\"button\"\n className=\"p-1.5 rounded-lg transition-colors duration-200 hover:bg-(--lm-bg-hover) shrink-0\"\n style={{ color: 'var(--lm-text-tertiary)' }}\n onClick={() => handleRemove(file)}\n aria-label={`删除 ${file.name}`}\n >\n <DeleteIcon />\n </button>\n </div>\n )\n }\n\n return (\n <div className={className}>\n {/* Hidden file input */}\n <input\n ref={inputRef}\n id={inputId}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={handleInputChange}\n className=\"hidden\"\n aria-describedby={errorMessage ? `${inputId}-error` : undefined}\n />\n\n {/* Upload area */}\n {children ? (\n <div onClick={handleClick} style={{ cursor: disabled ? 'not-allowed' : 'pointer' }}>\n {children}\n </div>\n ) : (\n <div\n className={`\n ${SIZE_PADDING_CLASSES[resolvedSize]}\n border-2 border-dashed rounded-2xl\n flex flex-col items-center justify-center\n transition-all duration-200\n ${disabled ? '' : 'cursor-pointer hover:border-(--lm-primary-400)'}\n `}\n style={getDropzoneStyles()}\n onClick={handleClick}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n handleClick()\n }\n }}\n >\n <div\n className=\"mb-3\"\n style={{ color: isDragging ? 'var(--lm-primary-500)' : 'var(--lm-text-tertiary)' }}\n >\n <UploadIcon className={iconSizeClasses[resolvedSize]} />\n </div>\n <p\n className={`${SIZE_TEXT_CLASSES[resolvedSize]} font-medium text-center`}\n style={{ color: isDragging ? 'var(--lm-primary-600)' : 'var(--lm-text-secondary)' }}\n >\n {placeholder}\n </p>\n {hint && (\n <p\n className=\"text-xs mt-2 text-center\"\n style={{ color: 'var(--lm-text-tertiary)' }}\n >\n {hint}\n </p>\n )}\n </div>\n )}\n\n {/* Error message */}\n {error && errorMessage && (\n <p\n id={`${inputId}-error`}\n className=\"text-xs flex items-center gap-1 mt-2\"\n style={{ color: 'var(--lm-error-500)' }}\n role=\"alert\"\n >\n <svg className=\"w-3 h-3\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path\n fillRule=\"evenodd\"\n d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n {errorMessage}\n </p>\n )}\n\n {/* File list */}\n {showFileList && fileList.length > 0 && (\n <div className={`mt-4 space-y-2`}>\n {fileList.map(renderFileItem)}\n </div>\n )}\n </div>\n )\n}\n\nexport default LMUpload\n"],"names":[],"mappings":"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"}
|
|
@@ -211,7 +211,7 @@ const LMUpload = ({
|
|
|
211
211
|
listType === "picture" && isImage && file.url ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
212
212
|
"div",
|
|
213
213
|
{
|
|
214
|
-
className: `${thumbSizeClasses[resolvedSize]} rounded-lg overflow-hidden
|
|
214
|
+
className: `${thumbSizeClasses[resolvedSize]} rounded-lg overflow-hidden shrink-0`,
|
|
215
215
|
style: { backgroundColor: "var(--lm-bg-elevated)" },
|
|
216
216
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
217
217
|
"img",
|
|
@@ -225,7 +225,7 @@ const LMUpload = ({
|
|
|
225
225
|
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
226
226
|
"div",
|
|
227
227
|
{
|
|
228
|
-
className: "p-2 rounded-lg
|
|
228
|
+
className: "p-2 rounded-lg shrink-0",
|
|
229
229
|
style: {
|
|
230
230
|
backgroundColor: file.status === "error" ? "var(--lm-error-100)" : "var(--lm-bg-elevated)",
|
|
231
231
|
color: file.status === "error" ? "var(--lm-error-500)" : "var(--lm-text-secondary)"
|
|
@@ -273,7 +273,7 @@ const LMUpload = ({
|
|
|
273
273
|
"button",
|
|
274
274
|
{
|
|
275
275
|
type: "button",
|
|
276
|
-
className: "p-1.5 rounded-lg transition-colors duration-200 hover:bg-
|
|
276
|
+
className: "p-1.5 rounded-lg transition-colors duration-200 hover:bg-(--lm-bg-hover) shrink-0",
|
|
277
277
|
style: { color: "var(--lm-text-tertiary)" },
|
|
278
278
|
onClick: () => handleRemove(file),
|
|
279
279
|
"aria-label": `删除 ${file.name}`,
|
|
@@ -308,7 +308,7 @@ const LMUpload = ({
|
|
|
308
308
|
border-2 border-dashed rounded-2xl
|
|
309
309
|
flex flex-col items-center justify-center
|
|
310
310
|
transition-all duration-200
|
|
311
|
-
${disabled ? "" : "cursor-pointer hover:border-
|
|
311
|
+
${disabled ? "" : "cursor-pointer hover:border-(--lm-primary-400)"}
|
|
312
312
|
`,
|
|
313
313
|
style: getDropzoneStyles(),
|
|
314
314
|
onClick: handleClick,
|
|
@@ -376,4 +376,4 @@ const LMUpload = ({
|
|
|
376
376
|
] });
|
|
377
377
|
};
|
|
378
378
|
exports.LMUpload = LMUpload;
|
|
379
|
-
//# sourceMappingURL=LMUpload-
|
|
379
|
+
//# sourceMappingURL=LMUpload-CJopkWc6.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LMUpload-CJopkWc6.cjs","sources":["../src/components/Form/LMUpload/LMUpload.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useId } from 'react'\nimport {\n COMPONENT_SIZE_ORDER,\n SIZE_TEXT_CLASSES,\n SIZE_GAP_CLASSES,\n SIZE_PADDING_CLASSES,\n clampComponentSize,\n} from '../../../utils/componentSizes'\nimport type { ComponentSize } from '../../../utils/componentSizes'\n\nexport interface LMUploadFile {\n /** Unique file ID */\n uid: string\n /** File name */\n name: string\n /** File size in bytes */\n size: number\n /** File type */\n type: string\n /** Upload status */\n status: 'uploading' | 'done' | 'error'\n /** Upload progress (0-100) */\n percent?: number\n /** Error message */\n error?: string\n /** Original file object */\n originFile?: File\n /** Preview URL (for images) */\n url?: string\n}\n\nexport interface LMUploadProps {\n /** File list (controlled) */\n fileList?: LMUploadFile[]\n /** Default file list */\n defaultFileList?: LMUploadFile[]\n /** Accept file types (e.g., \"image/*,.pdf\") */\n accept?: string\n /** Allow multiple files */\n multiple?: boolean\n /** Max file count */\n maxCount?: number\n /** Max file size in bytes */\n maxSize?: number\n /** Disabled state */\n disabled?: boolean\n /** Show file list */\n showFileList?: boolean\n /** Upload mode: drag area or button */\n listType?: 'text' | 'picture'\n /** Component size */\n size?: ComponentSize\n /** Custom upload handler */\n customRequest?: (file: File) => Promise<string>\n /** Change handler */\n onChange?: (fileList: LMUploadFile[]) => void\n /** Before upload hook, return false to prevent upload */\n beforeUpload?: (file: File) => boolean | Promise<boolean>\n /** Remove handler */\n onRemove?: (file: LMUploadFile) => void | boolean | Promise<boolean>\n /** Error state */\n error?: boolean\n /** Error message */\n errorMessage?: string\n /** Placeholder text */\n placeholder?: string\n /** Hint text below the upload area */\n hint?: string\n /** Custom class name */\n className?: string\n /** Children for custom trigger */\n children?: React.ReactNode\n}\n\nconst UploadIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-8 h-8'} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5\" />\n </svg>\n)\n\nconst FileIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-5 h-5'} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z\" />\n </svg>\n)\n\nconst ImageIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-5 h-5'} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z\" />\n </svg>\n)\n\nconst DeleteIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-4 h-4'} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n)\n\nconst CheckIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-4 h-4'} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n)\n\nconst ErrorIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className || 'w-4 h-4'} viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path fillRule=\"evenodd\" d=\"M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zm-1.72 6.97a.75.75 0 10-1.06 1.06L10.94 12l-1.72 1.72a.75.75 0 101.06 1.06L12 13.06l1.72 1.72a.75.75 0 101.06-1.06L13.06 12l1.72-1.72a.75.75 0 10-1.06-1.06L12 10.94l-1.72-1.72z\" clipRule=\"evenodd\" />\n </svg>\n)\n\nlet fileIdCounter = 0\nconst generateFileId = () => `upload-${++fileIdCounter}-${Date.now()}`\n\nconst formatFileSize = (bytes: number): string => {\n if (bytes === 0) return '0 B'\n const k = 1024\n const sizes = ['B', 'KB', 'MB', 'GB']\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`\n}\n\nconst isImageFile = (file: LMUploadFile): boolean => {\n return file.type.startsWith('image/') || /\\.(jpg|jpeg|png|gif|webp|svg|bmp)$/i.test(file.name)\n}\n\nconst LMUpload: React.FC<LMUploadProps> = ({\n fileList: controlledFileList,\n defaultFileList = [],\n accept,\n multiple = false,\n maxCount,\n maxSize,\n disabled = false,\n showFileList = true,\n listType = 'text',\n size = 'md',\n customRequest,\n onChange,\n beforeUpload,\n onRemove,\n error = false,\n errorMessage,\n placeholder = '点击或拖拽文件到此区域上传',\n hint,\n className = '',\n children,\n}) => {\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const inputId = useId()\n const inputRef = useRef<HTMLInputElement>(null)\n const [internalFileList, setInternalFileList] = useState<LMUploadFile[]>(defaultFileList)\n const [isDragging, setIsDragging] = useState(false)\n\n const fileList = controlledFileList ?? internalFileList\n\n const updateFileList = useCallback((newFileList: LMUploadFile[]) => {\n if (controlledFileList === undefined) {\n setInternalFileList(newFileList)\n }\n onChange?.(newFileList)\n }, [controlledFileList, onChange])\n\n const uploadFile = useCallback(async (file: File) => {\n const uid = generateFileId()\n const newFile: LMUploadFile = {\n uid,\n name: file.name,\n size: file.size,\n type: file.type,\n status: 'uploading',\n percent: 0,\n originFile: file,\n }\n\n // Create preview URL for images\n if (file.type.startsWith('image/')) {\n newFile.url = URL.createObjectURL(file)\n }\n\n // Add file to list\n const updatedList = [...fileList, newFile]\n updateFileList(updatedList)\n\n if (customRequest) {\n try {\n const url = await customRequest(file)\n updateFileList([...updatedList.slice(0, -1), { ...newFile, status: 'done', percent: 100, url }])\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '上传失败'\n updateFileList([...updatedList.slice(0, -1), { ...newFile, status: 'error', error: errorMsg }])\n }\n } else {\n // Simulate upload progress\n let progress = 0\n const interval = setInterval(() => {\n progress += Math.random() * 30\n if (progress >= 100) {\n progress = 100\n clearInterval(interval)\n setInternalFileList(prev => prev.map(f =>\n f.uid === uid ? { ...f, status: 'done' as const, percent: 100 } : f\n ))\n } else {\n setInternalFileList(prev => prev.map(f =>\n f.uid === uid ? { ...f, percent: Math.round(progress) } : f\n ))\n }\n }, 200)\n }\n }, [fileList, customRequest, updateFileList])\n\n const handleFiles = useCallback(async (files: FileList | null) => {\n if (!files || files.length === 0 || disabled) return\n\n const fileArray = Array.from(files)\n\n for (const file of fileArray) {\n // Check max count\n if (maxCount && fileList.length >= maxCount) {\n console.warn(`Max file count (${maxCount}) reached`)\n break\n }\n\n // Check max size\n if (maxSize && file.size > maxSize) {\n console.warn(`File ${file.name} exceeds max size (${formatFileSize(maxSize)})`)\n continue\n }\n\n // Before upload hook\n if (beforeUpload) {\n const result = await beforeUpload(file)\n if (!result) continue\n }\n\n await uploadFile(file)\n }\n }, [disabled, maxCount, maxSize, fileList.length, beforeUpload, uploadFile])\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n }\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragging(true)\n }\n }\n\n const handleDragLeave = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragging(false)\n }\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragging(false)\n if (!disabled) {\n handleFiles(e.dataTransfer.files)\n }\n }\n\n const handleRemove = async (file: LMUploadFile) => {\n if (onRemove) {\n const result = await onRemove(file)\n if (result === false) return\n }\n\n // Revoke object URL to prevent memory leaks\n if (file.url?.startsWith('blob:')) {\n URL.revokeObjectURL(file.url)\n }\n\n const newFileList = fileList.filter(f => f.uid !== file.uid)\n updateFileList(newFileList)\n }\n\n const handleClick = () => {\n if (!disabled) {\n inputRef.current?.click()\n }\n }\n\n const iconSizeClasses: Record<ComponentSize, string> = {\n xs: 'w-6 h-6',\n sm: 'w-7 h-7',\n md: 'w-8 h-8',\n lg: 'w-10 h-10',\n xl: 'w-12 h-12',\n '2xl': 'w-14 h-14',\n }\n\n const thumbSizeClasses: Record<ComponentSize, string> = {\n xs: 'w-10 h-10',\n sm: 'w-12 h-12',\n md: 'w-14 h-14',\n lg: 'w-16 h-16',\n xl: 'w-20 h-20',\n '2xl': 'w-24 h-24',\n }\n\n const getDropzoneStyles = (): React.CSSProperties => {\n const base: React.CSSProperties = {\n backgroundColor: 'var(--lm-bg-elevated)',\n borderColor: error ? 'var(--lm-error-300)' : 'var(--lm-border-default)',\n }\n\n if (disabled) {\n return {\n ...base,\n backgroundColor: 'var(--lm-bg-paper)',\n cursor: 'not-allowed',\n opacity: 0.6,\n }\n }\n\n if (isDragging) {\n return {\n ...base,\n backgroundColor: 'var(--lm-primary-50)',\n borderColor: 'var(--lm-primary-400)',\n }\n }\n\n return base\n }\n\n const renderFileItem = (file: LMUploadFile) => {\n const isImage = isImageFile(file)\n\n return (\n <div\n key={file.uid}\n className={`flex items-center ${SIZE_GAP_CLASSES[resolvedSize]} ${SIZE_PADDING_CLASSES[resolvedSize]} rounded-xl border transition-all duration-200`}\n style={{\n backgroundColor: file.status === 'error' ? 'var(--lm-error-50)' : 'var(--lm-bg-paper)',\n borderColor: file.status === 'error' ? 'var(--lm-error-200)' : 'var(--lm-border-light)',\n }}\n >\n {/* Thumbnail / Icon */}\n {listType === 'picture' && isImage && file.url ? (\n <div\n className={`${thumbSizeClasses[resolvedSize]} rounded-lg overflow-hidden shrink-0`}\n style={{ backgroundColor: 'var(--lm-bg-elevated)' }}\n >\n <img\n src={file.url}\n alt={file.name}\n className=\"w-full h-full object-cover\"\n />\n </div>\n ) : (\n <div\n className=\"p-2 rounded-lg shrink-0\"\n style={{\n backgroundColor: file.status === 'error' ? 'var(--lm-error-100)' : 'var(--lm-bg-elevated)',\n color: file.status === 'error' ? 'var(--lm-error-500)' : 'var(--lm-text-secondary)',\n }}\n >\n {isImage ? <ImageIcon className=\"w-5 h-5\" /> : <FileIcon className=\"w-5 h-5\" />}\n </div>\n )}\n\n {/* File info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span\n className={`${SIZE_TEXT_CLASSES[resolvedSize]} font-medium truncate`}\n style={{ color: file.status === 'error' ? 'var(--lm-error-700)' : 'var(--lm-text-primary)' }}\n title={file.name}\n >\n {file.name}\n </span>\n {file.status === 'done' && (\n <span style={{ color: 'var(--lm-success-500)' }}>\n <CheckIcon className=\"w-4 h-4\" />\n </span>\n )}\n {file.status === 'error' && (\n <span style={{ color: 'var(--lm-error-500)' }}>\n <ErrorIcon className=\"w-4 h-4\" />\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-2 mt-1\">\n <span className=\"text-xs\" style={{ color: 'var(--lm-text-tertiary)' }}>\n {formatFileSize(file.size)}\n </span>\n {file.status === 'error' && file.error && (\n <span className=\"text-xs\" style={{ color: 'var(--lm-error-500)' }}>\n {file.error}\n </span>\n )}\n </div>\n\n {/* Progress bar */}\n {file.status === 'uploading' && (\n <div className=\"mt-2\">\n <div\n className=\"h-1.5 rounded-full overflow-hidden\"\n style={{ backgroundColor: 'var(--lm-bg-active)' }}\n >\n <div\n className=\"h-full rounded-full transition-all duration-300\"\n style={{\n width: `${file.percent || 0}%`,\n backgroundColor: 'var(--lm-primary-500)',\n }}\n />\n </div>\n </div>\n )}\n </div>\n\n {/* Remove button */}\n <button\n type=\"button\"\n className=\"p-1.5 rounded-lg transition-colors duration-200 hover:bg-(--lm-bg-hover) shrink-0\"\n style={{ color: 'var(--lm-text-tertiary)' }}\n onClick={() => handleRemove(file)}\n aria-label={`删除 ${file.name}`}\n >\n <DeleteIcon />\n </button>\n </div>\n )\n }\n\n return (\n <div className={className}>\n {/* Hidden file input */}\n <input\n ref={inputRef}\n id={inputId}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={handleInputChange}\n className=\"hidden\"\n aria-describedby={errorMessage ? `${inputId}-error` : undefined}\n />\n\n {/* Upload area */}\n {children ? (\n <div onClick={handleClick} style={{ cursor: disabled ? 'not-allowed' : 'pointer' }}>\n {children}\n </div>\n ) : (\n <div\n className={`\n ${SIZE_PADDING_CLASSES[resolvedSize]}\n border-2 border-dashed rounded-2xl\n flex flex-col items-center justify-center\n transition-all duration-200\n ${disabled ? '' : 'cursor-pointer hover:border-(--lm-primary-400)'}\n `}\n style={getDropzoneStyles()}\n onClick={handleClick}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n handleClick()\n }\n }}\n >\n <div\n className=\"mb-3\"\n style={{ color: isDragging ? 'var(--lm-primary-500)' : 'var(--lm-text-tertiary)' }}\n >\n <UploadIcon className={iconSizeClasses[resolvedSize]} />\n </div>\n <p\n className={`${SIZE_TEXT_CLASSES[resolvedSize]} font-medium text-center`}\n style={{ color: isDragging ? 'var(--lm-primary-600)' : 'var(--lm-text-secondary)' }}\n >\n {placeholder}\n </p>\n {hint && (\n <p\n className=\"text-xs mt-2 text-center\"\n style={{ color: 'var(--lm-text-tertiary)' }}\n >\n {hint}\n </p>\n )}\n </div>\n )}\n\n {/* Error message */}\n {error && errorMessage && (\n <p\n id={`${inputId}-error`}\n className=\"text-xs flex items-center gap-1 mt-2\"\n style={{ color: 'var(--lm-error-500)' }}\n role=\"alert\"\n >\n <svg className=\"w-3 h-3\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path\n fillRule=\"evenodd\"\n d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n {errorMessage}\n </p>\n )}\n\n {/* File list */}\n {showFileList && fileList.length > 0 && (\n <div className={`mt-4 space-y-2`}>\n {fileList.map(renderFileItem)}\n </div>\n )}\n </div>\n )\n}\n\nexport default LMUpload\n"],"names":["jsx","clampComponentSize","COMPONENT_SIZE_ORDER","useId","useRef","useState","useCallback","jsxs","SIZE_GAP_CLASSES","SIZE_PADDING_CLASSES","SIZE_TEXT_CLASSES"],"mappings":";;;;AA0EA,MAAM,aAA+C,CAAC,EAAE,gBACtDA,2BAAAA,IAAC,OAAA,EAAI,WAAW,aAAa,WAAW,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAa,KACzG,UAAAA,2BAAAA,IAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,yGAAA,CAAyG,EAAA,CAChK;AAGF,MAAM,WAA6C,CAAC,EAAE,gBACpDA,2BAAAA,IAAC,OAAA,EAAI,WAAW,aAAa,WAAW,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAa,KACzG,UAAAA,2BAAAA,IAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,+PAAA,CAA+P,EAAA,CACtT;AAGF,MAAM,YAA8C,CAAC,EAAE,gBACrDA,2BAAAA,IAAC,OAAA,EAAI,WAAW,aAAa,WAAW,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAa,KACzG,UAAAA,2BAAAA,IAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,4SAAA,CAA4S,EAAA,CACnW;AAGF,MAAM,aAA+C,CAAC,EAAE,gBACtDA,2BAAAA,IAAC,OAAA,EAAI,WAAW,aAAa,WAAW,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAa,GACzG,UAAAA,2BAAAA,IAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,uBAAA,CAAuB,EAAA,CAC9E;AAGF,MAAM,YAA8C,CAAC,EAAE,gBACrDA,2BAAAA,IAAC,OAAA,EAAI,WAAW,aAAa,WAAW,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAa,GACzG,UAAAA,2BAAAA,IAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,iBAAA,CAAiB,EAAA,CACxE;AAGF,MAAM,YAA8C,CAAC,EAAE,UAAA,MACrDA,+BAAC,OAAA,EAAI,WAAW,aAAa,WAAW,SAAQ,aAAY,MAAK,gBAC/D,yCAAC,QAAA,EAAK,UAAS,WAAU,GAAE,yRAAwR,UAAS,UAAA,CAAU,EAAA,CACxU;AAGF,IAAI,gBAAgB;AACpB,MAAM,iBAAiB,MAAM,UAAU,EAAE,aAAa,IAAI,KAAK,KAAK;AAEpE,MAAM,iBAAiB,CAAC,UAA0B;AAChD,MAAI,UAAU,EAAG,QAAO;AACxB,QAAM,IAAI;AACV,QAAM,QAAQ,CAAC,KAAK,MAAM,MAAM,IAAI;AACpC,QAAM,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;AAClD,SAAO,GAAG,YAAY,QAAQ,KAAK,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;AACvE;AAEA,MAAM,cAAc,CAAC,SAAgC;AACnD,SAAO,KAAK,KAAK,WAAW,QAAQ,KAAK,sCAAsC,KAAK,KAAK,IAAI;AAC/F;AAEA,MAAM,WAAoC,CAAC;AAAA,EACzC,UAAU;AAAA,EACV,kBAAkB,CAAA;AAAA,EAClB;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,eAAe;AAAA,EACf,WAAW;AAAA,EACX,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,YAAY;AAAA,EACZ;AACF,MAAM;AACJ,QAAM,eAAeC,eAAAA,mBAAmB,MAAMC,mCAAoB;AAClE,QAAM,UAAUC,MAAAA,MAAA;AAChB,QAAM,WAAWC,MAAAA,OAAyB,IAAI;AAC9C,QAAM,CAAC,kBAAkB,mBAAmB,IAAIC,MAAAA,SAAyB,eAAe;AACxF,QAAM,CAAC,YAAY,aAAa,IAAIA,MAAAA,SAAS,KAAK;AAElD,QAAM,WAAW,sBAAsB;AAEvC,QAAM,iBAAiBC,kBAAY,CAAC,gBAAgC;AAClE,QAAI,uBAAuB,QAAW;AACpC,0BAAoB,WAAW;AAAA,IACjC;AACA,yCAAW;AAAA,EACb,GAAG,CAAC,oBAAoB,QAAQ,CAAC;AAEjC,QAAM,aAAaA,kBAAY,OAAO,SAAe;AACnD,UAAM,MAAM,eAAA;AACZ,UAAM,UAAwB;AAAA,MAC5B;AAAA,MACA,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA,IAAA;AAId,QAAI,KAAK,KAAK,WAAW,QAAQ,GAAG;AAClC,cAAQ,MAAM,IAAI,gBAAgB,IAAI;AAAA,IACxC;AAGA,UAAM,cAAc,CAAC,GAAG,UAAU,OAAO;AACzC,mBAAe,WAAW;AAE1B,QAAI,eAAe;AACjB,UAAI;AACF,cAAM,MAAM,MAAM,cAAc,IAAI;AACpC,uBAAe,CAAC,GAAG,YAAY,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,SAAS,QAAQ,QAAQ,SAAS,KAAK,IAAA,CAAK,CAAC;AAAA,MACjG,SAAS,KAAK;AACZ,cAAM,WAAW,eAAe,QAAQ,IAAI,UAAU;AACtD,uBAAe,CAAC,GAAG,YAAY,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,SAAS,QAAQ,SAAS,OAAO,SAAA,CAAU,CAAC;AAAA,MAChG;AAAA,IACF,OAAO;AAEL,UAAI,WAAW;AACf,YAAM,WAAW,YAAY,MAAM;AACjC,oBAAY,KAAK,WAAW;AAC5B,YAAI,YAAY,KAAK;AACnB,qBAAW;AACX,wBAAc,QAAQ;AACtB,8BAAoB,UAAQ,KAAK;AAAA,YAAI,CAAA,MACnC,EAAE,QAAQ,MAAM,EAAE,GAAG,GAAG,QAAQ,QAAiB,SAAS,IAAA,IAAQ;AAAA,UAAA,CACnE;AAAA,QACH,OAAO;AACL,8BAAoB,UAAQ,KAAK;AAAA,YAAI,CAAA,MACnC,EAAE,QAAQ,MAAM,EAAE,GAAG,GAAG,SAAS,KAAK,MAAM,QAAQ,EAAA,IAAM;AAAA,UAAA,CAC3D;AAAA,QACH;AAAA,MACF,GAAG,GAAG;AAAA,IACR;AAAA,EACF,GAAG,CAAC,UAAU,eAAe,cAAc,CAAC;AAE5C,QAAM,cAAcA,kBAAY,OAAO,UAA2B;AAChE,QAAI,CAAC,SAAS,MAAM,WAAW,KAAK,SAAU;AAE9C,UAAM,YAAY,MAAM,KAAK,KAAK;AAElC,eAAW,QAAQ,WAAW;AAE5B,UAAI,YAAY,SAAS,UAAU,UAAU;AAC3C,gBAAQ,KAAK,mBAAmB,QAAQ,WAAW;AACnD;AAAA,MACF;AAGA,UAAI,WAAW,KAAK,OAAO,SAAS;AAClC,gBAAQ,KAAK,QAAQ,KAAK,IAAI,sBAAsB,eAAe,OAAO,CAAC,GAAG;AAC9E;AAAA,MACF;AAGA,UAAI,cAAc;AAChB,cAAM,SAAS,MAAM,aAAa,IAAI;AACtC,YAAI,CAAC,OAAQ;AAAA,MACf;AAEA,YAAM,WAAW,IAAI;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,UAAU,UAAU,SAAS,SAAS,QAAQ,cAAc,UAAU,CAAC;AAE3E,QAAM,oBAAoB,CAAC,MAA2C;AACpE,gBAAY,EAAE,OAAO,KAAK;AAE1B,QAAI,SAAS,SAAS;AACpB,eAAS,QAAQ,QAAQ;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,MAAuB;AAC7C,MAAE,eAAA;AACF,MAAE,gBAAA;AACF,QAAI,CAAC,UAAU;AACb,oBAAc,IAAI;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,kBAAkB,CAAC,MAAuB;AAC9C,MAAE,eAAA;AACF,MAAE,gBAAA;AACF,kBAAc,KAAK;AAAA,EACrB;AAEA,QAAM,aAAa,CAAC,MAAuB;AACzC,MAAE,eAAA;AACF,MAAE,gBAAA;AACF,kBAAc,KAAK;AACnB,QAAI,CAAC,UAAU;AACb,kBAAY,EAAE,aAAa,KAAK;AAAA,IAClC;AAAA,EACF;AAEA,QAAM,eAAe,OAAO,SAAuB;;AACjD,QAAI,UAAU;AACZ,YAAM,SAAS,MAAM,SAAS,IAAI;AAClC,UAAI,WAAW,MAAO;AAAA,IACxB;AAGA,SAAI,UAAK,QAAL,mBAAU,WAAW,UAAU;AACjC,UAAI,gBAAgB,KAAK,GAAG;AAAA,IAC9B;AAEA,UAAM,cAAc,SAAS,OAAO,OAAK,EAAE,QAAQ,KAAK,GAAG;AAC3D,mBAAe,WAAW;AAAA,EAC5B;AAEA,QAAM,cAAc,MAAM;;AACxB,QAAI,CAAC,UAAU;AACb,qBAAS,YAAT,mBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,kBAAiD;AAAA,IACrD,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,OAAO;AAAA,EAAA;AAGT,QAAM,mBAAkD;AAAA,IACtD,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,OAAO;AAAA,EAAA;AAGT,QAAM,oBAAoB,MAA2B;AACnD,UAAM,OAA4B;AAAA,MAChC,iBAAiB;AAAA,MACjB,aAAa,QAAQ,wBAAwB;AAAA,IAAA;AAG/C,QAAI,UAAU;AACZ,aAAO;AAAA,QACL,GAAG;AAAA,QACH,iBAAiB;AAAA,QACjB,QAAQ;AAAA,QACR,SAAS;AAAA,MAAA;AAAA,IAEb;AAEA,QAAI,YAAY;AACd,aAAO;AAAA,QACL,GAAG;AAAA,QACH,iBAAiB;AAAA,QACjB,aAAa;AAAA,MAAA;AAAA,IAEjB;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,CAAC,SAAuB;AAC7C,UAAM,UAAU,YAAY,IAAI;AAEhC,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAW,qBAAqBC,eAAAA,iBAAiB,YAAY,CAAC,IAAIC,eAAAA,qBAAqB,YAAY,CAAC;AAAA,QACpG,OAAO;AAAA,UACL,iBAAiB,KAAK,WAAW,UAAU,uBAAuB;AAAA,UAClE,aAAa,KAAK,WAAW,UAAU,wBAAwB;AAAA,QAAA;AAAA,QAIhE,UAAA;AAAA,UAAA,aAAa,aAAa,WAAW,KAAK,MACzCT,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW,GAAG,iBAAiB,YAAY,CAAC;AAAA,cAC5C,OAAO,EAAE,iBAAiB,wBAAA;AAAA,cAE1B,UAAAA,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,KAAK,KAAK;AAAA,kBACV,KAAK,KAAK;AAAA,kBACV,WAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,YACZ;AAAA,UAAA,IAGFA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,iBAAiB,KAAK,WAAW,UAAU,wBAAwB;AAAA,gBACnE,OAAO,KAAK,WAAW,UAAU,wBAAwB;AAAA,cAAA;AAAA,cAG1D,UAAA,yCAAW,WAAA,EAAU,WAAU,WAAU,IAAKA,2BAAAA,IAAC,UAAA,EAAS,WAAU,UAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAKjFO,2BAAAA,KAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,YAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,cAAAP,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAW,GAAGU,eAAAA,kBAAkB,YAAY,CAAC;AAAA,kBAC7C,OAAO,EAAE,OAAO,KAAK,WAAW,UAAU,wBAAwB,yBAAA;AAAA,kBAClE,OAAO,KAAK;AAAA,kBAEX,UAAA,KAAK;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEP,KAAK,WAAW,UACfV,2BAAAA,IAAC,UAAK,OAAO,EAAE,OAAO,wBAAA,GACpB,UAAAA,2BAAAA,IAAC,WAAA,EAAU,WAAU,WAAU,GACjC;AAAA,cAED,KAAK,WAAW,WACfA,2BAAAA,IAAC,UAAK,OAAO,EAAE,OAAO,sBAAA,GACpB,UAAAA,+BAAC,WAAA,EAAU,WAAU,WAAU,EAAA,CACjC;AAAA,YAAA,GAEJ;AAAA,YACAO,2BAAAA,KAAC,OAAA,EAAI,WAAU,gCACb,UAAA;AAAA,cAAAP,2BAAAA,IAAC,QAAA,EAAK,WAAU,WAAU,OAAO,EAAE,OAAO,0BAAA,GACvC,UAAA,eAAe,KAAK,IAAI,EAAA,CAC3B;AAAA,cACC,KAAK,WAAW,WAAW,KAAK,SAC/BA,2BAAAA,IAAC,QAAA,EAAK,WAAU,WAAU,OAAO,EAAE,OAAO,sBAAA,GACvC,eAAK,MAAA,CACR;AAAA,YAAA,GAEJ;AAAA,YAGC,KAAK,WAAW,eACfA,2BAAAA,IAAC,OAAA,EAAI,WAAU,QACb,UAAAA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,EAAE,iBAAiB,sBAAA;AAAA,gBAE1B,UAAAA,2BAAAA;AAAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAU;AAAA,oBACV,OAAO;AAAA,sBACL,OAAO,GAAG,KAAK,WAAW,CAAC;AAAA,sBAC3B,iBAAiB;AAAA,oBAAA;AAAA,kBACnB;AAAA,gBAAA;AAAA,cACF;AAAA,YAAA,EACF,CACF;AAAA,UAAA,GAEJ;AAAA,UAGAA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,0BAAA;AAAA,cAChB,SAAS,MAAM,aAAa,IAAI;AAAA,cAChC,cAAY,MAAM,KAAK,IAAI;AAAA,cAE3B,yCAAC,YAAA,CAAA,CAAW;AAAA,YAAA;AAAA,UAAA;AAAA,QACd;AAAA,MAAA;AAAA,MA3FK,KAAK;AAAA,IAAA;AAAA,EA8FhB;AAEA,SACEO,gCAAC,SAAI,WAEH,UAAA;AAAA,IAAAP,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL,IAAI;AAAA,QACJ,MAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV,WAAU;AAAA,QACV,oBAAkB,eAAe,GAAG,OAAO,WAAW;AAAA,MAAA;AAAA,IAAA;AAAA,IAIvD,WACCA,2BAAAA,IAAC,OAAA,EAAI,SAAS,aAAa,OAAO,EAAE,QAAQ,WAAW,gBAAgB,UAAA,GACpE,UACH,IAEAO,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,cACPE,eAAAA,qBAAqB,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA,cAIlC,WAAW,KAAK,gDAAgD;AAAA;AAAA,QAEpE,OAAO,kBAAA;AAAA,QACP,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,MAAK;AAAA,QACL,UAAU,WAAW,KAAK;AAAA,QAC1B,iBAAe;AAAA,QACf,WAAW,CAAC,MAAM;AAChB,cAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,cAAE,eAAA;AACF,wBAAA;AAAA,UACF;AAAA,QACF;AAAA,QAEA,UAAA;AAAA,UAAAT,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,aAAa,0BAA0B,0BAAA;AAAA,cAEvD,UAAAA,2BAAAA,IAAC,YAAA,EAAW,WAAW,gBAAgB,YAAY,EAAA,CAAG;AAAA,YAAA;AAAA,UAAA;AAAA,UAExDA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW,GAAGU,eAAAA,kBAAkB,YAAY,CAAC;AAAA,cAC7C,OAAO,EAAE,OAAO,aAAa,0BAA0B,2BAAA;AAAA,cAEtD,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAEF,QACCV,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,0BAAA;AAAA,cAEf,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QACH;AAAA,MAAA;AAAA,IAAA;AAAA,IAML,SAAS,gBACRO,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAI,GAAG,OAAO;AAAA,QACd,WAAU;AAAA,QACV,OAAO,EAAE,OAAO,sBAAA;AAAA,QAChB,MAAK;AAAA,QAEL,UAAA;AAAA,UAAAP,+BAAC,SAAI,WAAU,WAAU,MAAK,gBAAe,SAAQ,aACnD,UAAAA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,UAAS;AAAA,cACT,GAAE;AAAA,cACF,UAAS;AAAA,YAAA;AAAA,UAAA,GAEb;AAAA,UACC;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAKJ,gBAAgB,SAAS,SAAS,KACjCA,2BAAAA,IAAC,OAAA,EAAI,WAAW,kBACb,UAAA,SAAS,IAAI,cAAc,EAAA,CAC9B;AAAA,EAAA,GAEJ;AAEJ;;"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { ComponentSize } from '../../../utils/componentSizes';
|
|
3
|
+
|
|
4
|
+
export type ChatRole = 'user' | 'assistant' | 'system';
|
|
5
|
+
export type ChatBubbleVariant = 'default' | 'filled' | 'outline' | 'soft';
|
|
6
|
+
export interface LMChatBubbleProps {
|
|
7
|
+
/** 消息角色 */
|
|
8
|
+
role?: ChatRole;
|
|
9
|
+
/** 气泡变体 */
|
|
10
|
+
variant?: ChatBubbleVariant;
|
|
11
|
+
/** 尺寸 */
|
|
12
|
+
size?: ComponentSize;
|
|
13
|
+
/** 气泡内容 */
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
/** 是否正在打字(流式输出中) */
|
|
16
|
+
isStreaming?: boolean;
|
|
17
|
+
/** 自定义类名 */
|
|
18
|
+
className?: string;
|
|
19
|
+
/** 错误状态 */
|
|
20
|
+
error?: boolean;
|
|
21
|
+
/** 尾部装饰(如时间戳、状态图标) */
|
|
22
|
+
footer?: React.ReactNode;
|
|
23
|
+
/** 自定义样式 */
|
|
24
|
+
style?: React.CSSProperties;
|
|
25
|
+
}
|
|
26
|
+
declare const _default: React.NamedExoticComponent<LMChatBubbleProps>;
|
|
27
|
+
export default _default;
|
|
28
|
+
//# sourceMappingURL=LMChatBubble.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LMChatBubble.d.ts","sourceRoot":"","sources":["../../../../src/components/Chat/LMChatBubble/LMChatBubble.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAe,MAAM,OAAO,CAAA;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAiClE,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;AAEtD,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAA;AAEzE,MAAM,WAAW,iBAAiB;IAChC,WAAW;IACX,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,WAAW;IACX,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,SAAS;IACT,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,WAAW;IACX,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,oBAAoB;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,YAAY;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW;IACX,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,sBAAsB;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB,YAAY;IACZ,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;CAC5B;;AA+MD,wBAAiC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { default as LMChatBubble } from './LMChatBubble';
|
|
3
|
+
|
|
4
|
+
declare const meta: Meta<typeof LMChatBubble>;
|
|
5
|
+
export default meta;
|
|
6
|
+
type Story = StoryObj<typeof meta>;
|
|
7
|
+
/** 用户消息 - 默认蓝色主题 */
|
|
8
|
+
export declare const UserMessage: Story;
|
|
9
|
+
/** 助手消息 - 默认白色主题 */
|
|
10
|
+
export declare const AssistantMessage: Story;
|
|
11
|
+
/** 系统消息 - 虚线边框 */
|
|
12
|
+
export declare const SystemMessage: Story;
|
|
13
|
+
/** 所有角色对比 */
|
|
14
|
+
export declare const AllRoles: Story;
|
|
15
|
+
/** 流式输出中 - 显示闪烁光标 */
|
|
16
|
+
export declare const Streaming: Story;
|
|
17
|
+
/** 错误状态 */
|
|
18
|
+
export declare const Error: Story;
|
|
19
|
+
/** 带尾部装饰 */
|
|
20
|
+
export declare const WithFooter: Story;
|
|
21
|
+
/** 尺寸展示 - 所有可用尺寸 */
|
|
22
|
+
export declare const Sizes: Story;
|
|
23
|
+
/** 打字机效果 - 模拟流式输出 */
|
|
24
|
+
export declare const TypewriterEffect: Story;
|
|
25
|
+
//# sourceMappingURL=LMChatBubble.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LMChatBubble.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/Chat/LMChatBubble/LMChatBubble.stories.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,YAAY,MAAM,gBAAgB,CAAA;AAEzC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,YAAY,CA4CnC,CAAA;AAED,eAAe,IAAI,CAAA;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;AAElC,oBAAoB;AACpB,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAA;AAED,oBAAoB;AACpB,eAAO,MAAM,gBAAgB,EAAE,KAK9B,CAAA;AAED,kBAAkB;AAClB,eAAO,MAAM,aAAa,EAAE,KAK3B,CAAA;AAED,aAAa;AACb,eAAO,MAAM,QAAQ,EAAE,KActB,CAAA;AAED,qBAAqB;AACrB,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAA;AAED,WAAW;AACX,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAA;AAED,YAAY;AACZ,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAA;AAED,oBAAoB;AACpB,eAAO,MAAM,KAAK,EAAE,KAWnB,CAAA;AAsDD,qBAAqB;AACrB,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Chat/LMChatBubble/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACxD,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { ComponentSize } from '../../../utils/componentSizes';
|
|
3
|
+
import { ChatMessage, LMChatListProps } from '../LMChatList';
|
|
4
|
+
|
|
5
|
+
export interface LMChatContainerProps {
|
|
6
|
+
/** 消息列表 */
|
|
7
|
+
messages: ChatMessage[];
|
|
8
|
+
/** 尺寸 */
|
|
9
|
+
size?: ComponentSize;
|
|
10
|
+
/** 消息气泡变体 */
|
|
11
|
+
variant?: 'default' | 'filled' | 'outline' | 'soft';
|
|
12
|
+
/** 发送消息回调 */
|
|
13
|
+
onSend?: (content: string) => void;
|
|
14
|
+
/** 停止生成回调 */
|
|
15
|
+
onStop?: () => void;
|
|
16
|
+
/** 是否正在生成 */
|
|
17
|
+
isGenerating?: boolean;
|
|
18
|
+
/** 是否禁用输入 */
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/** 输入框占位符 */
|
|
21
|
+
placeholder?: string;
|
|
22
|
+
/** 输入框值(受控) */
|
|
23
|
+
inputValue?: string;
|
|
24
|
+
/** 输入框值变化回调 */
|
|
25
|
+
onInputChange?: (value: string) => void;
|
|
26
|
+
/** 最大输入字符数 */
|
|
27
|
+
maxInputLength?: number;
|
|
28
|
+
/** 显示字符计数 */
|
|
29
|
+
showInputCount?: boolean;
|
|
30
|
+
/** 是否显示打字指示器 */
|
|
31
|
+
showTypingIndicator?: boolean;
|
|
32
|
+
/** 打字指示器文字 */
|
|
33
|
+
typingIndicatorText?: string;
|
|
34
|
+
/** 打字指示器头像 */
|
|
35
|
+
typingIndicatorAvatar?: React.ReactNode;
|
|
36
|
+
/** 自定义类名 */
|
|
37
|
+
className?: string;
|
|
38
|
+
/** 头部内容 */
|
|
39
|
+
header?: React.ReactNode;
|
|
40
|
+
/** 底部额外内容(输入框上方) */
|
|
41
|
+
footer?: React.ReactNode;
|
|
42
|
+
/** 输入框右侧插槽 */
|
|
43
|
+
inputRightSlot?: React.ReactNode;
|
|
44
|
+
/** 输入框底部工具栏 */
|
|
45
|
+
inputToolbar?: React.ReactNode;
|
|
46
|
+
/** 空状态内容 */
|
|
47
|
+
emptyContent?: React.ReactNode;
|
|
48
|
+
/** 加载中状态 */
|
|
49
|
+
loading?: boolean;
|
|
50
|
+
/** 加载更多回调 */
|
|
51
|
+
onLoadMore?: () => void;
|
|
52
|
+
/** 是否还有更多消息 */
|
|
53
|
+
hasMore?: boolean;
|
|
54
|
+
/** 消息重试回调 */
|
|
55
|
+
onMessageRetry?: (messageId: string) => void;
|
|
56
|
+
/** 自定义渲染消息 */
|
|
57
|
+
renderMessage?: LMChatListProps['renderMessage'];
|
|
58
|
+
/** 输入框自动聚焦 */
|
|
59
|
+
autoFocus?: boolean;
|
|
60
|
+
/** 按 Enter 发送 */
|
|
61
|
+
enterToSend?: boolean;
|
|
62
|
+
/** 高度 */
|
|
63
|
+
height?: string | number;
|
|
64
|
+
/** 最大高度 */
|
|
65
|
+
maxHeight?: string | number;
|
|
66
|
+
/** 气泡最大宽度(默认 85%) */
|
|
67
|
+
bubbleMaxWidth?: string | number;
|
|
68
|
+
}
|
|
69
|
+
export interface LMChatContainerRef {
|
|
70
|
+
/** 滚动到底部 */
|
|
71
|
+
scrollToBottom: (behavior?: 'auto' | 'smooth') => void;
|
|
72
|
+
/** 滚动到指定消息 */
|
|
73
|
+
scrollToMessage: (messageId: string, behavior?: 'auto' | 'smooth') => void;
|
|
74
|
+
/** 聚焦输入框 */
|
|
75
|
+
focusInput: () => void;
|
|
76
|
+
/** 获取输入框值 */
|
|
77
|
+
getInputValue: () => string;
|
|
78
|
+
/** 设置输入框值 */
|
|
79
|
+
setInputValue: (value: string) => void;
|
|
80
|
+
/** 清空输入框 */
|
|
81
|
+
clearInput: () => void;
|
|
82
|
+
}
|
|
83
|
+
declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<LMChatContainerProps & React.RefAttributes<LMChatContainerRef>>>;
|
|
84
|
+
export default _default;
|
|
85
|
+
//# sourceMappingURL=LMChatContainer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LMChatContainer.d.ts","sourceRoot":"","sources":["../../../../src/components/Chat/LMChatContainer/LMChatContainer.tsx"],"names":[],"mappings":"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"}
|