@lax-wp/design-system 0.14.31 → 0.14.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/floating-bar/FloatingBar.cjs.js +1 -1
- package/dist/components/floating-bar/FloatingBar.cjs.js.map +1 -1
- package/dist/components/floating-bar/FloatingBar.es.js +49 -46
- package/dist/components/floating-bar/FloatingBar.es.js.map +1 -1
- package/dist/components/forms/icon-picker/IconPicker.cjs.js +1 -1
- package/dist/components/forms/icon-picker/IconPicker.cjs.js.map +1 -1
- package/dist/components/forms/icon-picker/IconPicker.es.js +11 -12
- package/dist/components/forms/icon-picker/IconPicker.es.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),C=require("antd"),i=require("../../_virtual/index.cjs.js"),g=require("framer-motion"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),C=require("antd"),i=require("../../_virtual/index.cjs.js"),g=require("framer-motion"),p=require("react"),q=require("react-i18next"),s=require("../data-display/typography/Typography.cjs.js"),D=require("../buttons/option-button/OptionButton.cjs.js"),F=require("../button/IconButton.cjs.js"),j=require("../tooltip/Tooltip.cjs.js"),R=require("../icon/icons.generated.cjs.js"),z=({size:n=24,fill:o="currentColor",className:m})=>t.jsx("svg",{className:m,width:n,height:n,viewBox:"0 0 20 20",fill:o,xmlns:"http://www.w3.org/2000/svg",children:t.jsx("path",{d:"M10.0002 11.1666L5.91683 15.2499C5.76405 15.4027 5.56961 15.4791 5.3335 15.4791C5.09739 15.4791 4.90294 15.4027 4.75016 15.2499C4.59738 15.0971 4.521 14.9027 4.521 14.6666C4.521 14.4305 4.59738 14.236 4.75016 14.0833L8.8335 9.99992L4.75016 5.91659C4.59738 5.76381 4.521 5.56936 4.521 5.33325C4.521 5.09714 4.59738 4.9027 4.75016 4.74992C4.90294 4.59714 5.09739 4.52075 5.3335 4.52075C5.56961 4.52075 5.76405 4.59714 5.91683 4.74992L10.0002 8.83325L14.0835 4.74992C14.2363 4.59714 14.4307 4.52075 14.6668 4.52075C14.9029 4.52075 15.0974 4.59714 15.2502 4.74992C15.4029 4.9027 15.4793 5.09714 15.4793 5.33325C15.4793 5.56936 15.4029 5.76381 15.2502 5.91659L11.1668 9.99992L15.2502 14.0833C15.4029 14.236 15.4793 14.4305 15.4793 14.6666C15.4793 14.9027 15.4029 15.0971 15.2502 15.2499C15.0974 15.4027 14.9029 15.4791 14.6668 15.4791C14.4307 15.4791 14.2363 15.4027 14.0835 15.2499L10.0002 11.1666Z"})}),A=({fill:n="#cccccc",className:o})=>t.jsx("svg",{height:"20",width:"20",viewBox:"0 0 20 20",focusable:"false",className:o,children:t.jsx("path",{fill:n,d:"M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z"})}),k=n=>{const{show:o,isFlowDashboard:m,onClose:N,actionItems:x,selectedItemsCount:I,deleteConfig:c,showActionBg:S}=n,{t:h}=q.useTranslation(),[b,y]=p.useState(!1),[B,f]=p.useState(!0),l=p.useRef(null),v=p.useRef(null);p.useEffect(()=>{const e=new ResizeObserver(()=>{if(l.current&&v.current){const r=l.current.scrollWidth-100;x.length*180+100>r?f(!1):f(!0)}});return l.current&&e.observe(l.current),()=>{l.current&&e.unobserve(l.current)}});const a={label:h("Delete"),icon:t.jsx(R.DeleteIcon,{className:"text-error-700 w-icon h-icon"}),onClick:c?.onClick,...c},d=e=>{const r=e.label?.toLowerCase()??"";return r.includes("delete")||r==="remove"||r==="move to trash"},L=[...x].sort((e,r)=>Number(d(e))-Number(d(r))),T=x.some(e=>e.visible!==!1)||!!c,u=x.filter(e=>e.visible!==!1).map((e,r)=>({key:r,label:t.jsx(D.OptionButton,{icon:e.dropdownIcon,text:e?.label||"",onClick:e.onClick,className:"font-inter text-base font-medium text-black-900 dark:text-black-200 gap-1.5"}),children:e.dropdownItems,disabled:!1}));return o?t.jsx(g.motion.div,{initial:{y:20,opacity:0},animate:{y:0,opacity:1},exit:{y:20,opacity:0},transition:{duration:.2,ease:[.4,0,.2,1],opacity:{duration:.15}},ref:l,className:i("h-[36px] mb-4",m?"ml-60 w-1/2":"w-full"),children:t.jsxs("div",{className:i("h-[36px] border-y border-neutral-900 dark:border-[#0d1014 px-[12px] text-white bg-neutral-900 dark:bg-black-900 flex justify-between items-center"),children:[t.jsxs("div",{className:"flex items-center gap-[12px]",children:[t.jsxs("div",{className:"flex items-center gap-[8px]",children:[t.jsx(F,{tooltip:"Close",variant:"ghost",onClick:N,className:"!p-0 text-white hover:opacity-80 hover:rotate-90 transition-all duration-200",children:t.jsx(z,{size:16})}),t.jsx("div",{className:"w-px h-[14px] rounded-[1px] bg-neutral-700 dark:bg-[#1d242c]"})]}),t.jsxs("div",{className:"flex items-center gap-[6px]",children:[t.jsx("span",{className:"inline-flex items-center justify-center min-w-[20px] h-[16px] px-[8px] rounded-[9px] border text-[12px] leading-[18px] font-normal text-primary-600 dark:text-primary-400 bg-primary-50 dark:bg-[rgba(0,50,95,0.3)] border-primary-200 dark:border-primary-800",children:I||0}),t.jsx(s.Typography,{size:"extra-small",appearance:"custom",className:"text-white dark:text-neutral-50",children:h("Selected")})]})]}),T?t.jsx("div",{ref:v,className:i("h-[36px] flex items-center font-inter bg-neutral-800 dark:bg-black-800 pl-[10px] rounded-[43px]"),children:B?t.jsxs(g.motion.div,{initial:{opacity:0},animate:{opacity:1},transition:{duration:.2},className:"flex items-center h-[36px] bg-neutral-800 dark:bg-black-800 px-[10px] rounded-[43px]",children:[L.map((e,r)=>e.visible!==!1&&t.jsx("div",{children:e.type==="dropdown"?t.jsx(C.Dropdown,{menu:{items:e.dropdownItems},trigger:[e.dropdownTrigger||"click"],overlayClassName:"!min-w-[148px]",placement:"bottomRight",getPopupContainer:w=>w.parentElement,open:b,onOpenChange:y,children:t.jsx("button",{id:`btn-floating-bar-${e.label}`,onClick:e.onClick,disabled:e.disabled,className:i(e?.label?"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent":"bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80",e?.hideLabel&&"!p-1.5",d(e)&&"!text-error-500 dark:!text-error-700",e.disabled&&"opacity-70"),children:t.jsxs(j,{hideTooltip:!e.tooltip,title:e.tooltip,className:"flex items-center gap-1.5",children:[e.icon,!e?.hideLabel&&e.label&&t.jsx(s.Typography,{size:"small",variant:"medium",className:i("text-inherit",d(e)&&"!text-error-500 dark:!text-error-700"),appearance:"custom",children:e.label})]})},r)}):t.jsx("button",{id:`btn-floating-bar-${e.label}`,onClick:e.onClick,disabled:e.disabled,className:i(e?.label?"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent":"bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80",e?.hideLabel&&"!p-1.5",d(e)&&"!text-error-500 dark:!text-error-700",e.disabled&&"opacity-70"),children:t.jsxs(j,{hideTooltip:!e.tooltip,title:e.tooltip,className:"flex items-center gap-1.5",children:[e.icon,!e?.hideLabel&&e.label&&t.jsx(s.Typography,{size:"small",variant:"medium",className:"text-inherit",appearance:"custom",children:e.label})]})})},r)),c?t.jsxs("button",{id:`btn-floating-bar-${a.label}`,onClick:a.onClick,disabled:a.disabled,className:i("flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200",a.disabled&&"opacity-70"),children:[a.icon,t.jsx(s.Typography,{size:"small",variant:"medium",className:"text-error-700",appearance:"custom",children:a.label})]}):null]}):t.jsxs(g.motion.div,{initial:{opacity:0},animate:{opacity:1},transition:{duration:.2},className:"minw-[150px] p-1.5 flex items-center",children:[t.jsx(C.Dropdown,{menu:{items:u},trigger:["click"],overlayClassName:"!min-w-[148px]",placement:"bottomRight",getPopupContainer:e=>e.parentElement,open:b,onOpenChange:y,children:t.jsxs("button",{id:"btn-floating-bar-actions",disabled:u.length===0,className:i("flex items-center gap-1.5 px-2 py-1 w-22 h-7 rounded-full bg-[#34405473]/45 dark:bg-black-700 hover:scale-105 hover:opacity-80 transition-all duration-200",u.length===0&&"opacity-60 hover:scale-100 hover:opacity-60"),type:"button",children:[t.jsx(s.Typography,{size:"small",variant:"medium",className:"text-white",children:h("Actions")}),t.jsx(A,{fill:"#FFFFFF",className:"w-[16px] h-[16px]"})]})}),c?t.jsxs("button",{id:`btn-floating-bar-${a.label}`,onClick:a.onClick,disabled:a.disabled,className:i("flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200",a.disabled&&"opacity-70"),type:"button",children:[a.icon,t.jsx(s.Typography,{size:"small",variant:"medium",className:"text-error-700",appearance:"custom",children:a.label})]}):null]})}):null]})}):null};k.displayName="FloatingBar";exports.FloatingBar=k;
|
|
2
2
|
//# sourceMappingURL=FloatingBar.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingBar.cjs.js","sources":["../../../src/components/floating-bar/FloatingBar.tsx"],"sourcesContent":["import { Dropdown } from \"antd\";\nimport cn from \"classnames\";\nimport { motion } from \"framer-motion\";\nimport { useEffect, useRef, useState, type FC, type ReactNode } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Typography } from \"../data-display/typography/Typography\";\nimport { OptionButton } from \"../buttons/option-button/OptionButton\";\nimport IconButton from \"../button/IconButton\";\nimport Tooltip from \"../tooltip/Tooltip\";\nimport { DeleteIcon } from \"../icon\";\n\n/**\n * Close icon component\n */\nconst CloseIcon: FC<{ size?: number; fill?: string; className?: string }> = ({\n size = 24,\n fill = \"currentColor\",\n className,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 20 20\"\n fill={fill}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M10.0002 11.1666L5.91683 15.2499C5.76405 15.4027 5.56961 15.4791 5.3335 15.4791C5.09739 15.4791 4.90294 15.4027 4.75016 15.2499C4.59738 15.0971 4.521 14.9027 4.521 14.6666C4.521 14.4305 4.59738 14.236 4.75016 14.0833L8.8335 9.99992L4.75016 5.91659C4.59738 5.76381 4.521 5.56936 4.521 5.33325C4.521 5.09714 4.59738 4.9027 4.75016 4.74992C4.90294 4.59714 5.09739 4.52075 5.3335 4.52075C5.56961 4.52075 5.76405 4.59714 5.91683 4.74992L10.0002 8.83325L14.0835 4.74992C14.2363 4.59714 14.4307 4.52075 14.6668 4.52075C14.9029 4.52075 15.0974 4.59714 15.2502 4.74992C15.4029 4.9027 15.4793 5.09714 15.4793 5.33325C15.4793 5.56936 15.4029 5.76381 15.2502 5.91659L11.1668 9.99992L15.2502 14.0833C15.4029 14.236 15.4793 14.4305 15.4793 14.6666C15.4793 14.9027 15.4029 15.0971 15.2502 15.2499C15.0974 15.4027 14.9029 15.4791 14.6668 15.4791C14.4307 15.4791 14.2363 15.4027 14.0835 15.2499L10.0002 11.1666Z\" />\n </svg>\n);\n\n/**\n * Dropdown arrow icon component\n */\nconst DropdownArrowIcon: FC<{ fill?: string; className?: string }> = ({\n fill = \"#cccccc\",\n className,\n}) => (\n <svg\n height=\"20\"\n width=\"20\"\n viewBox=\"0 0 20 20\"\n focusable=\"false\"\n className={className}\n >\n <path\n fill={fill}\n d=\"M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z\"\n />\n </svg>\n);\n\n/**\n * Configuration for action buttons in the floating bar\n */\nexport type ButtonConfig = {\n /** Button label text */\n label?: string;\n /** Icon element to display */\n icon: ReactNode;\n /** Click handler for the action */\n onClick?: () => void;\n /** Icon for dropdown mode */\n dropdownIcon?: ReactNode;\n /** Whether the action is visible */\n visible?: boolean;\n /** Whether the action is disabled */\n disabled?: boolean;\n /** Tooltip text */\n tooltip?: string;\n /** Whether to hide the label text */\n hideLabel?: boolean;\n /** Action type */\n type?: \"button\" | \"dropdown\";\n /** Dropdown trigger mode */\n dropdownTrigger?: \"click\" | \"hover\";\n /** Dropdown menu items */\n dropdownItems?: Array<{\n label: ReactNode;\n key: string;\n disabled?: boolean;\n }>;\n};\n\n/**\n * Props for the FloatingBar component\n */\nexport type TFloatingBar = {\n /** Whether the floating bar is visible */\n show?: boolean;\n /** Close handler */\n onClose: () => void;\n /** Whether this is used in flow dashboard layout */\n isFlowDashboard?: boolean;\n /** Array of action configurations */\n actionItems: ButtonConfig[];\n /** Number of selected items */\n selectedItemsCount?: number;\n /** Delete action configuration */\n deleteConfig?: {\n label?: string;\n disabled?: boolean;\n onClick?: () => void;\n };\n /** Whether to show action background */\n showActionBg?: boolean;\n};\n\n/**\n * FloatingBar component provides a floating action bar for bulk operations.\n * Drop-in replacement matching the lax-web-portal implementation.\n *\n * @example\n * ```tsx\n * <FloatingBar\n * show={selectedItems.length > 0}\n * onClose={() => setSelectedItems([])}\n * selectedItemsCount={selectedItems.length}\n * actionItems={[\n * {\n * label: \"Edit\",\n * icon: <EditIcon size={16} />,\n * onClick: handleEdit,\n * },\n * {\n * label: \"Archive\",\n * icon: <ArchiveIcon size={16} />,\n * onClick: handleArchive,\n * },\n * ]}\n * deleteConfig={{\n * label: \"Delete\",\n * onClick: handleDelete,\n * }}\n * />\n * ```\n */\nexport const FloatingBar: FC<TFloatingBar> = (props) => {\n const {\n show,\n isFlowDashboard,\n onClose,\n actionItems,\n selectedItemsCount,\n deleteConfig,\n showActionBg,\n } = props;\n\n const { t } = useTranslation();\n const [showDropdown, setShowDropdown] = useState<boolean>(false);\n const [showButtons, setShowButtons] = useState<boolean>(true);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const actionContainerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const observer = new ResizeObserver(() => {\n if (containerRef.current && actionContainerRef.current) {\n const containerWidth = containerRef.current.scrollWidth - 100;\n const totalActionItemsWidth = actionItems.length * 180 + 100;\n if (totalActionItemsWidth > containerWidth) {\n setShowButtons(false);\n } else {\n setShowButtons(true);\n }\n }\n });\n\n if (containerRef.current) {\n observer.observe(containerRef.current);\n }\n\n return () => {\n if (containerRef.current) {\n observer.unobserve(containerRef.current);\n }\n };\n });\n\n const deleteButtonConfig = {\n label: t(\"Delete\"),\n icon: <DeleteIcon className=\"text-error-700 w-icon h-icon\" />,\n color: \"text-error-700 dark:text-error-700\",\n onClick: deleteConfig?.onClick,\n ...deleteConfig,\n };\n\n /** Whether a button represents a destructive/delete action */\n const isDeleteAction = (button: ButtonConfig) => {\n const label = button.label?.toLowerCase() ?? \"\";\n return (\n label.includes(\"delete\") ||\n label === \"remove\" ||\n label === \"move to trash\"\n );\n };\n\n /** Delete actions are always displayed last (on the right) */\n const sortedActionItems = [...actionItems].sort(\n (a, b) => Number(isDeleteAction(a)) - Number(isDeleteAction(b))\n );\n\n /** Whether the action area has anything to render — avoids an empty pill */\n const hasActions =\n actionItems.some((button) => button.visible !== false) || Boolean(deleteConfig);\n\n const dropDownItems = actionItems\n .filter((button) => button.visible !== false)\n .map((button, index) => ({\n key: index,\n label: (\n <OptionButton\n icon={button.dropdownIcon}\n text={button?.label || \"\"}\n onClick={button.onClick}\n className=\"font-inter text-base font-medium text-black-900 dark:text-black-200 gap-1.5\"\n />\n ),\n children: button.dropdownItems,\n disabled: false,\n }));\n\n return !show ? null : (\n <motion.div\n initial={{ y: 20, opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n exit={{ y: 20, opacity: 0 }}\n transition={{\n duration: 0.2,\n ease: [0.4, 0, 0.2, 1],\n opacity: { duration: 0.15 },\n }}\n ref={containerRef}\n className={cn(\"h-[36px] mb-4\", isFlowDashboard ? \"ml-60 w-1/2\" : \"w-full\")}\n >\n <div\n className={cn(\n \"h-[36px] border-y border-neutral-900 dark:border-[#0d1014 px-[12px] text-white bg-neutral-900 dark:bg-black-900 flex justify-between items-center\"\n )}\n >\n <div className=\"flex items-center gap-[12px]\">\n <div className=\"flex items-center gap-[8px]\">\n <IconButton\n tooltip=\"Close\"\n variant=\"ghost\"\n onClick={onClose}\n className=\"!p-0 text-white hover:opacity-80 hover:rotate-90 transition-all duration-200\"\n >\n <CloseIcon size={16} />\n </IconButton>\n <div className=\"w-px h-[14px] rounded-[1px] bg-neutral-700 dark:bg-[#1d242c]\" />\n </div>\n <div className=\"flex items-center gap-[6px]\">\n <span className=\"inline-flex items-center justify-center min-w-[20px] h-[16px] px-[8px] rounded-[9px] border text-[12px] leading-[18px] font-normal text-primary-600 dark:text-primary-400 bg-primary-50 dark:bg-[rgba(0,50,95,0.3)] border-primary-200 dark:border-primary-800\">\n {selectedItemsCount || 0}\n </span>\n <Typography\n size=\"extra-small\"\n appearance=\"custom\"\n className=\"text-white dark:text-neutral-50\"\n >\n {t(\"Selected\")}\n </Typography>\n </div>\n </div>\n {hasActions ? (\n <div\n ref={actionContainerRef}\n className={cn(\n \"h-[36px] flex items-center font-inter bg-neutral-800 dark:bg-black-800 pl-[10px] rounded-[43px]\"\n )}\n >\n {showButtons ? (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.2 }}\n className=\"flex items-center h-[36px] bg-neutral-800 dark:bg-black-800 px-[10px] rounded-[43px]\"\n >\n {sortedActionItems.map(\n (button, index) =>\n button.visible !== false && (\n <div key={index}>\n {button.type === \"dropdown\" ? (\n <Dropdown\n menu={{\n items: button.dropdownItems,\n }}\n trigger={[button.dropdownTrigger || \"click\"]}\n overlayClassName=\"!min-w-[148px]\"\n placement=\"bottomRight\"\n getPopupContainer={(trigger) =>\n trigger.parentElement as HTMLElement\n }\n open={showDropdown}\n onOpenChange={setShowDropdown}\n >\n <button\n key={index}\n id={`btn-floating-bar-${button.label}`}\n onClick={button.onClick}\n disabled={button.disabled}\n className={cn(\n !button?.label\n ? \"bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80\"\n : \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent\",\n button?.hideLabel && \"!p-1.5\",\n isDeleteAction(button) && \"!text-error-500 dark:!text-error-700\",\n button.disabled && \"opacity-70\"\n )}\n >\n <Tooltip\n hideTooltip={!button.tooltip}\n title={button.tooltip}\n className=\"flex items-center gap-1.5\"\n >\n {button.icon}\n {!button?.hideLabel && button.label && (\n <Typography\n size=\"small\"\n variant=\"medium\"\n className={\"text-inherit !text-error-500 dark:!text-error-700\"}\n appearance=\"custom\"\n >\n {button.label}\n </Typography>\n )}\n </Tooltip>\n </button>\n </Dropdown>\n ) : (\n <button\n id={`btn-floating-bar-${button.label}`}\n onClick={button.onClick}\n disabled={button.disabled}\n className={cn(\n !button?.label\n ? \"bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80\"\n : \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent\",\n button?.hideLabel && \"!p-1.5\",\n isDeleteAction(button) && \"!text-error-500 dark:!text-error-700\",\n button.disabled && \"opacity-70\"\n )}\n >\n <Tooltip\n hideTooltip={!button.tooltip}\n title={button.tooltip}\n className=\"flex items-center gap-1.5\"\n >\n {button.icon}\n\n {!button?.hideLabel && button.label && (\n <Typography\n size=\"small\"\n variant=\"medium\"\n className={\"text-inherit\"}\n appearance=\"custom\"\n >\n {button.label}\n </Typography>\n )}\n </Tooltip>\n </button>\n )}\n </div>\n )\n )}\n {deleteConfig ? (\n <button\n id={`btn-floating-bar-${deleteButtonConfig.label}`}\n onClick={deleteButtonConfig.onClick}\n disabled={deleteButtonConfig.disabled}\n className={cn(\n \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200\",\n deleteButtonConfig.disabled && \"opacity-70\"\n )}\n >\n {deleteButtonConfig.icon}\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-error-700\"\n appearance=\"custom\"\n >\n {deleteButtonConfig.label}\n </Typography>\n </button>\n ) : null}\n </motion.div>\n ) : (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.2 }}\n className=\"minw-[150px] p-1.5 flex items-center\"\n >\n <Dropdown\n menu={{\n items: dropDownItems,\n }}\n trigger={[\"click\"]}\n overlayClassName=\"!min-w-[148px]\"\n placement=\"bottomRight\"\n getPopupContainer={(trigger) =>\n trigger.parentElement as HTMLElement\n }\n open={showDropdown}\n onOpenChange={setShowDropdown}\n >\n <button\n id={`btn-floating-bar-actions`}\n disabled={dropDownItems.length === 0}\n className={cn(\n \"flex items-center gap-1.5 px-2 py-1 w-22 h-7 rounded-full bg-[#34405473]/45 dark:bg-black-700 hover:scale-105 hover:opacity-80 transition-all duration-200\",\n dropDownItems.length === 0 &&\n \"opacity-60 hover:scale-100 hover:opacity-60\"\n )}\n type=\"button\"\n >\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-white\"\n >\n {t(\"Actions\")}\n </Typography>\n <DropdownArrowIcon\n fill=\"#FFFFFF\"\n className=\"w-[16px] h-[16px]\"\n />\n </button>\n </Dropdown>\n {deleteConfig ? (\n <button\n id={`btn-floating-bar-${deleteButtonConfig.label}`}\n onClick={deleteButtonConfig.onClick}\n disabled={deleteButtonConfig.disabled}\n className={cn(\n \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200\",\n deleteButtonConfig.disabled && \"opacity-70\"\n )}\n type=\"button\"\n >\n {deleteButtonConfig.icon}\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-error-700\"\n appearance=\"custom\"\n >\n {deleteButtonConfig.label}\n </Typography>\n </button>\n ) : null}\n </motion.div>\n )}\n </div>\n ) : null}\n </div>\n </motion.div>\n );\n};\n\nFloatingBar.displayName = \"FloatingBar\";\n\n// Re-export types for convenience\nexport type { ButtonConfig as FloatingBarActionConfig };\nexport type FloatingBarDeleteConfig = TFloatingBar[\"deleteConfig\"];\nexport type FloatingBarProps = TFloatingBar;\n\n// Legacy type exports for backwards compatibility\nexport type FloatingBarSize = \"small\" | \"medium\" | \"large\";\nexport type FloatingBarPosition = \"top\" | \"bottom\";\nexport type FloatingBarTheme = \"primary\" | \"dark\" | \"light\";\n"],"names":["CloseIcon","size","fill","className","jsx","DropdownArrowIcon","FloatingBar","props","show","isFlowDashboard","onClose","actionItems","selectedItemsCount","deleteConfig","showActionBg","t","useTranslation","showDropdown","setShowDropdown","useState","showButtons","setShowButtons","containerRef","useRef","actionContainerRef","useEffect","observer","containerWidth","deleteButtonConfig","DeleteIcon","isDeleteAction","button","label","sortedActionItems","a","b","hasActions","dropDownItems","index","OptionButton","motion","cn","jsxs","IconButton","Typography","Dropdown","trigger","Tooltip"],"mappings":"yeAcMA,EAAsE,CAAC,CAC3E,KAAAC,EAAO,GACP,KAAAC,EAAO,eACP,UAAAC,CACF,IACEC,EAAAA,IAAC,MAAA,CACC,UAAAD,EACA,MAAOF,EACP,OAAQA,EACR,QAAQ,YACR,KAAAC,EACA,MAAM,6BAEN,SAAAE,EAAAA,IAAC,OAAA,CAAK,EAAE,g4BAAA,CAAi4B,CAAA,CAC34B,EAMIC,EAA+D,CAAC,CACpE,KAAAH,EAAO,UACP,UAAAC,CACF,IACEC,EAAAA,IAAC,MAAA,CACC,OAAO,KACP,MAAM,KACN,QAAQ,YACR,UAAU,QACV,UAAAD,EAEA,SAAAC,EAAAA,IAAC,OAAA,CACC,KAAAF,EACA,EAAE,uRAAA,CAAA,CACJ,CACF,EAwFWI,EAAiCC,GAAU,CACtD,KAAM,CACJ,KAAAC,EACA,gBAAAC,EACA,QAAAC,EACA,YAAAC,EACA,mBAAAC,EACA,aAAAC,EACA,aAAAC,CAAA,EACEP,EAEE,CAAE,EAAAQ,CAAA,EAAMC,iBAAA,EACR,CAACC,EAAcC,CAAe,EAAIC,EAAAA,SAAkB,EAAK,EACzD,CAACC,EAAaC,CAAc,EAAIF,EAAAA,SAAkB,EAAI,EAEtDG,EAAeC,EAAAA,OAAuB,IAAI,EAC1CC,EAAqBD,EAAAA,OAAuB,IAAI,EAEtDE,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAW,IAAI,eAAe,IAAM,CACxC,GAAIJ,EAAa,SAAWE,EAAmB,QAAS,CACtD,MAAMG,EAAiBL,EAAa,QAAQ,YAAc,IAC5BX,EAAY,OAAS,IAAM,IAC7BgB,EAC1BN,EAAe,EAAK,EAEpBA,EAAe,EAAI,CAEvB,CACF,CAAC,EAED,OAAIC,EAAa,SACfI,EAAS,QAAQJ,EAAa,OAAO,EAGhC,IAAM,CACPA,EAAa,SACfI,EAAS,UAAUJ,EAAa,OAAO,CAE3C,CACF,CAAC,EAED,MAAMM,EAAqB,CACzB,MAAOb,EAAE,QAAQ,EACjB,KAAMX,EAAAA,IAACyB,EAAAA,WAAA,CAAW,UAAU,8BAAA,CAA+B,EAE3D,QAAShB,GAAc,QACvB,GAAGA,CAAA,EAICiB,EAAkBC,GAAyB,CAC/C,MAAMC,EAAQD,EAAO,OAAO,YAAA,GAAiB,GAC7C,OACEC,EAAM,SAAS,QAAQ,GACvBA,IAAU,UACVA,IAAU,eAEd,EAGMC,EAAoB,CAAC,GAAGtB,CAAW,EAAE,KACzC,CAACuB,EAAGC,IAAM,OAAOL,EAAeI,CAAC,CAAC,EAAI,OAAOJ,EAAeK,CAAC,CAAC,CAAA,EAI1DC,EACJzB,EAAY,KAAMoB,GAAWA,EAAO,UAAY,EAAK,GAAK,EAAQlB,EAE9DwB,EAAgB1B,EACnB,OAAQoB,GAAWA,EAAO,UAAY,EAAK,EAC3C,IAAI,CAACA,EAAQO,KAAW,CACvB,IAAKA,EACL,MACElC,EAAAA,IAACmC,EAAAA,aAAA,CACC,KAAMR,EAAO,aACb,KAAMA,GAAQ,OAAS,GACvB,QAASA,EAAO,QAChB,UAAU,6EAAA,CAAA,EAGd,SAAUA,EAAO,cACjB,SAAU,EAAA,EACV,EAEJ,OAAQvB,EACNJ,EAAAA,IAACoC,EAAAA,OAAO,IAAP,CACC,QAAS,CAAE,EAAG,GAAI,QAAS,CAAA,EAC3B,QAAS,CAAE,EAAG,EAAG,QAAS,CAAA,EAC1B,KAAM,CAAE,EAAG,GAAI,QAAS,CAAA,EACxB,WAAY,CACV,SAAU,GACV,KAAM,CAAC,GAAK,EAAG,GAAK,CAAC,EACrB,QAAS,CAAE,SAAU,GAAA,CAAK,EAE5B,IAAKlB,EACL,UAAWmB,EAAG,gBAAiBhC,EAAkB,cAAgB,QAAQ,EAEzE,SAAAiC,EAAAA,KAAC,MAAA,CACC,UAAWD,EACT,mJAAA,EAGF,SAAA,CAAAC,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,8BACb,SAAA,CAAAtC,EAAAA,IAACuC,EAAA,CACC,QAAQ,QACR,QAAQ,QACR,QAASjC,EACT,UAAU,+EAEV,SAAAN,EAAAA,IAACJ,EAAA,CAAU,KAAM,EAAA,CAAI,CAAA,CAAA,EAEvBI,EAAAA,IAAC,MAAA,CAAI,UAAU,8DAAA,CAA+D,CAAA,EAChF,EACAsC,EAAAA,KAAC,MAAA,CAAI,UAAU,8BACb,SAAA,CAAAtC,EAAAA,IAAC,OAAA,CAAK,UAAU,iQACb,SAAAQ,GAAsB,EACzB,EACAR,EAAAA,IAACwC,EAAAA,WAAA,CACC,KAAK,cACL,WAAW,SACX,UAAU,kCAET,WAAE,UAAU,CAAA,CAAA,CACf,CAAA,CACF,CAAA,EACF,EACCR,EACChC,EAAAA,IAAC,MAAA,CACC,IAAKoB,EACL,UAAWiB,EACT,iGAAA,EAGD,SAAArB,EACDsB,EAAAA,KAACF,EAAAA,OAAO,IAAP,CACC,QAAS,CAAE,QAAS,CAAA,EACpB,QAAS,CAAE,QAAS,CAAA,EACpB,WAAY,CAAE,SAAU,EAAA,EACxB,UAAU,uFAET,SAAA,CAAAP,EAAkB,IACjB,CAACF,EAAQO,IACPP,EAAO,UAAY,IACjB3B,EAAAA,IAAC,MAAA,CACE,SAAA2B,EAAO,OAAS,WACf3B,EAAAA,IAACyC,EAAAA,SAAA,CACC,KAAM,CACJ,MAAOd,EAAO,aAAA,EAEhB,QAAS,CAACA,EAAO,iBAAmB,OAAO,EAC3C,iBAAiB,iBACjB,UAAU,cACV,kBAAoBe,GAClBA,EAAQ,cAEV,KAAM7B,EACN,aAAcC,EAEd,SAAAd,EAAAA,IAAC,SAAA,CAEC,GAAI,oBAAoB2B,EAAO,KAAK,GACpC,QAASA,EAAO,QAChB,SAAUA,EAAO,SACjB,UAAWU,EACRV,GAAQ,MAEL,oLADA,+FAEJA,GAAQ,WAAa,SACrBD,EAAeC,CAAM,GAAK,uCAC1BA,EAAO,UAAY,YAAA,EAGrB,SAAAW,EAAAA,KAACK,EAAA,CACC,YAAa,CAAChB,EAAO,QACrB,MAAOA,EAAO,QACd,UAAU,4BAET,SAAA,CAAAA,EAAO,KACP,CAACA,GAAQ,WAAaA,EAAO,OAC5B3B,EAAAA,IAACwC,EAAAA,WAAA,CACC,KAAK,QACL,QAAQ,SACR,UAAW,oDACX,WAAW,SAEV,SAAAb,EAAO,KAAA,CAAA,CACV,CAAA,CAAA,CAEJ,EA7BKO,CAAA,CA8BP,CAAA,EAGFlC,EAAAA,IAAC,SAAA,CACC,GAAI,oBAAoB2B,EAAO,KAAK,GACpC,QAASA,EAAO,QAChB,SAAUA,EAAO,SACjB,UAAWU,EACRV,GAAQ,MAEL,oLADA,+FAEJA,GAAQ,WAAa,SACrBD,EAAeC,CAAM,GAAK,uCAC1BA,EAAO,UAAY,YAAA,EAGrB,SAAAW,EAAAA,KAACK,EAAA,CACC,YAAa,CAAChB,EAAO,QACrB,MAAOA,EAAO,QACd,UAAU,4BAET,SAAA,CAAAA,EAAO,KAEP,CAACA,GAAQ,WAAaA,EAAO,OAC5B3B,EAAAA,IAACwC,EAAAA,WAAA,CACC,KAAK,QACL,QAAQ,SACR,UAAW,eACX,WAAW,SAEV,SAAAb,EAAO,KAAA,CAAA,CACV,CAAA,CAAA,CAEJ,CAAA,GA/EIO,CAkFV,CAAA,EAGLzB,EACC6B,EAAAA,KAAC,SAAA,CACC,GAAI,oBAAoBd,EAAmB,KAAK,GAChD,QAASA,EAAmB,QAC5B,SAAUA,EAAmB,SAC7B,UAAWa,EACT,qIACAb,EAAmB,UAAY,YAAA,EAGhC,SAAA,CAAAA,EAAmB,KACpBxB,EAAAA,IAACwC,EAAAA,WAAA,CACC,KAAK,QACL,QAAQ,SACR,UAAU,iBACV,WAAW,SAEV,SAAAhB,EAAmB,KAAA,CAAA,CACtB,CAAA,CAAA,EAEA,IAAA,CAAA,CAAA,EAGNc,EAAAA,KAACF,EAAAA,OAAO,IAAP,CACC,QAAS,CAAE,QAAS,CAAA,EACpB,QAAS,CAAE,QAAS,CAAA,EACpB,WAAY,CAAE,SAAU,EAAA,EACxB,UAAU,uCAEV,SAAA,CAAApC,EAAAA,IAACyC,EAAAA,SAAA,CACC,KAAM,CACJ,MAAOR,CAAA,EAET,QAAS,CAAC,OAAO,EACjB,iBAAiB,iBACjB,UAAU,cACV,kBAAoBS,GAClBA,EAAQ,cAEV,KAAM7B,EACN,aAAcC,EAEd,SAAAwB,EAAAA,KAAC,SAAA,CACC,GAAI,2BACJ,SAAUL,EAAc,SAAW,EACnC,UAAWI,EACT,6JACAJ,EAAc,SAAW,GACzB,6CAAA,EAEF,KAAK,SAEL,SAAA,CAAAjC,EAAAA,IAACwC,EAAAA,WAAA,CACC,KAAK,QACL,QAAQ,SACR,UAAU,aAET,WAAE,SAAS,CAAA,CAAA,EAEdxC,EAAAA,IAACC,EAAA,CACC,KAAK,UACL,UAAU,mBAAA,CAAA,CACZ,CAAA,CAAA,CACF,CAAA,EAEDQ,EACC6B,EAAAA,KAAC,SAAA,CACC,GAAI,oBAAoBd,EAAmB,KAAK,GAChD,QAASA,EAAmB,QAC5B,SAAUA,EAAmB,SAC7B,UAAWa,EACT,qIACAb,EAAmB,UAAY,YAAA,EAEjC,KAAK,SAEJ,SAAA,CAAAA,EAAmB,KACpBxB,EAAAA,IAACwC,EAAAA,WAAA,CACC,KAAK,QACL,QAAQ,SACR,UAAU,iBACV,WAAW,SAEV,SAAAhB,EAAmB,KAAA,CAAA,CACtB,CAAA,CAAA,EAEA,IAAA,CAAA,CAAA,CACJ,CAAA,EAGF,IAAA,CAAA,CAAA,CACN,CAAA,EA5OW,IA+OjB,EAEAtB,EAAY,YAAc"}
|
|
1
|
+
{"version":3,"file":"FloatingBar.cjs.js","sources":["../../../src/components/floating-bar/FloatingBar.tsx"],"sourcesContent":["import { Dropdown } from \"antd\";\nimport cn from \"classnames\";\nimport { motion } from \"framer-motion\";\nimport { useEffect, useRef, useState, type FC, type ReactNode } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Typography } from \"../data-display/typography/Typography\";\nimport { OptionButton } from \"../buttons/option-button/OptionButton\";\nimport IconButton from \"../button/IconButton\";\nimport Tooltip from \"../tooltip/Tooltip\";\nimport { DeleteIcon } from \"../icon\";\n\n/**\n * Close icon component\n */\nconst CloseIcon: FC<{ size?: number; fill?: string; className?: string }> = ({\n size = 24,\n fill = \"currentColor\",\n className,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 20 20\"\n fill={fill}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M10.0002 11.1666L5.91683 15.2499C5.76405 15.4027 5.56961 15.4791 5.3335 15.4791C5.09739 15.4791 4.90294 15.4027 4.75016 15.2499C4.59738 15.0971 4.521 14.9027 4.521 14.6666C4.521 14.4305 4.59738 14.236 4.75016 14.0833L8.8335 9.99992L4.75016 5.91659C4.59738 5.76381 4.521 5.56936 4.521 5.33325C4.521 5.09714 4.59738 4.9027 4.75016 4.74992C4.90294 4.59714 5.09739 4.52075 5.3335 4.52075C5.56961 4.52075 5.76405 4.59714 5.91683 4.74992L10.0002 8.83325L14.0835 4.74992C14.2363 4.59714 14.4307 4.52075 14.6668 4.52075C14.9029 4.52075 15.0974 4.59714 15.2502 4.74992C15.4029 4.9027 15.4793 5.09714 15.4793 5.33325C15.4793 5.56936 15.4029 5.76381 15.2502 5.91659L11.1668 9.99992L15.2502 14.0833C15.4029 14.236 15.4793 14.4305 15.4793 14.6666C15.4793 14.9027 15.4029 15.0971 15.2502 15.2499C15.0974 15.4027 14.9029 15.4791 14.6668 15.4791C14.4307 15.4791 14.2363 15.4027 14.0835 15.2499L10.0002 11.1666Z\" />\n </svg>\n);\n\n/**\n * Dropdown arrow icon component\n */\nconst DropdownArrowIcon: FC<{ fill?: string; className?: string }> = ({\n fill = \"#cccccc\",\n className,\n}) => (\n <svg\n height=\"20\"\n width=\"20\"\n viewBox=\"0 0 20 20\"\n focusable=\"false\"\n className={className}\n >\n <path\n fill={fill}\n d=\"M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z\"\n />\n </svg>\n);\n\n/**\n * Configuration for action buttons in the floating bar\n */\nexport type ButtonConfig = {\n /** Button label text */\n label?: string;\n /** Icon element to display */\n icon: ReactNode;\n /** Click handler for the action */\n onClick?: () => void;\n /** Icon for dropdown mode */\n dropdownIcon?: ReactNode;\n /** Whether the action is visible */\n visible?: boolean;\n /** Whether the action is disabled */\n disabled?: boolean;\n /** Tooltip text */\n tooltip?: string;\n /** Whether to hide the label text */\n hideLabel?: boolean;\n /** Action type */\n type?: \"button\" | \"dropdown\";\n /** Dropdown trigger mode */\n dropdownTrigger?: \"click\" | \"hover\";\n /** Dropdown menu items */\n dropdownItems?: Array<{\n label: ReactNode;\n key: string;\n disabled?: boolean;\n }>;\n};\n\n/**\n * Props for the FloatingBar component\n */\nexport type TFloatingBar = {\n /** Whether the floating bar is visible */\n show?: boolean;\n /** Close handler */\n onClose: () => void;\n /** Whether this is used in flow dashboard layout */\n isFlowDashboard?: boolean;\n /** Array of action configurations */\n actionItems: ButtonConfig[];\n /** Number of selected items */\n selectedItemsCount?: number;\n /** Delete action configuration */\n deleteConfig?: {\n label?: string;\n disabled?: boolean;\n onClick?: () => void;\n };\n /** Whether to show action background */\n showActionBg?: boolean;\n};\n\n/**\n * FloatingBar component provides a floating action bar for bulk operations.\n * Drop-in replacement matching the lax-web-portal implementation.\n *\n * @example\n * ```tsx\n * <FloatingBar\n * show={selectedItems.length > 0}\n * onClose={() => setSelectedItems([])}\n * selectedItemsCount={selectedItems.length}\n * actionItems={[\n * {\n * label: \"Edit\",\n * icon: <EditIcon size={16} />,\n * onClick: handleEdit,\n * },\n * {\n * label: \"Archive\",\n * icon: <ArchiveIcon size={16} />,\n * onClick: handleArchive,\n * },\n * ]}\n * deleteConfig={{\n * label: \"Delete\",\n * onClick: handleDelete,\n * }}\n * />\n * ```\n */\nexport const FloatingBar: FC<TFloatingBar> = (props) => {\n const {\n show,\n isFlowDashboard,\n onClose,\n actionItems,\n selectedItemsCount,\n deleteConfig,\n showActionBg,\n } = props;\n\n const { t } = useTranslation();\n const [showDropdown, setShowDropdown] = useState<boolean>(false);\n const [showButtons, setShowButtons] = useState<boolean>(true);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const actionContainerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const observer = new ResizeObserver(() => {\n if (containerRef.current && actionContainerRef.current) {\n const containerWidth = containerRef.current.scrollWidth - 100;\n const totalActionItemsWidth = actionItems.length * 180 + 100;\n if (totalActionItemsWidth > containerWidth) {\n setShowButtons(false);\n } else {\n setShowButtons(true);\n }\n }\n });\n\n if (containerRef.current) {\n observer.observe(containerRef.current);\n }\n\n return () => {\n if (containerRef.current) {\n observer.unobserve(containerRef.current);\n }\n };\n });\n\n const deleteButtonConfig = {\n label: t(\"Delete\"),\n icon: <DeleteIcon className=\"text-error-700 w-icon h-icon\" />,\n color: \"text-error-700 dark:text-error-700\",\n onClick: deleteConfig?.onClick,\n ...deleteConfig,\n };\n\n /** Whether a button represents a destructive/delete action */\n const isDeleteAction = (button: ButtonConfig) => {\n const label = button.label?.toLowerCase() ?? \"\";\n return (\n label.includes(\"delete\") ||\n label === \"remove\" ||\n label === \"move to trash\"\n );\n };\n\n /** Delete actions are always displayed last (on the right) */\n const sortedActionItems = [...actionItems].sort(\n (a, b) => Number(isDeleteAction(a)) - Number(isDeleteAction(b))\n );\n\n /** Whether the action area has anything to render — avoids an empty pill */\n const hasActions =\n actionItems.some((button) => button.visible !== false) || Boolean(deleteConfig);\n\n const dropDownItems = actionItems\n .filter((button) => button.visible !== false)\n .map((button, index) => ({\n key: index,\n label: (\n <OptionButton\n icon={button.dropdownIcon}\n text={button?.label || \"\"}\n onClick={button.onClick}\n className=\"font-inter text-base font-medium text-black-900 dark:text-black-200 gap-1.5\"\n />\n ),\n children: button.dropdownItems,\n disabled: false,\n }));\n\n return !show ? null : (\n <motion.div\n initial={{ y: 20, opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n exit={{ y: 20, opacity: 0 }}\n transition={{\n duration: 0.2,\n ease: [0.4, 0, 0.2, 1],\n opacity: { duration: 0.15 },\n }}\n ref={containerRef}\n className={cn(\"h-[36px] mb-4\", isFlowDashboard ? \"ml-60 w-1/2\" : \"w-full\")}\n >\n <div\n className={cn(\n \"h-[36px] border-y border-neutral-900 dark:border-[#0d1014 px-[12px] text-white bg-neutral-900 dark:bg-black-900 flex justify-between items-center\"\n )}\n >\n <div className=\"flex items-center gap-[12px]\">\n <div className=\"flex items-center gap-[8px]\">\n <IconButton\n tooltip=\"Close\"\n variant=\"ghost\"\n onClick={onClose}\n className=\"!p-0 text-white hover:opacity-80 hover:rotate-90 transition-all duration-200\"\n >\n <CloseIcon size={16} />\n </IconButton>\n <div className=\"w-px h-[14px] rounded-[1px] bg-neutral-700 dark:bg-[#1d242c]\" />\n </div>\n <div className=\"flex items-center gap-[6px]\">\n <span className=\"inline-flex items-center justify-center min-w-[20px] h-[16px] px-[8px] rounded-[9px] border text-[12px] leading-[18px] font-normal text-primary-600 dark:text-primary-400 bg-primary-50 dark:bg-[rgba(0,50,95,0.3)] border-primary-200 dark:border-primary-800\">\n {selectedItemsCount || 0}\n </span>\n <Typography\n size=\"extra-small\"\n appearance=\"custom\"\n className=\"text-white dark:text-neutral-50\"\n >\n {t(\"Selected\")}\n </Typography>\n </div>\n </div>\n {hasActions ? (\n <div\n ref={actionContainerRef}\n className={cn(\n \"h-[36px] flex items-center font-inter bg-neutral-800 dark:bg-black-800 pl-[10px] rounded-[43px]\"\n )}\n >\n {showButtons ? (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.2 }}\n className=\"flex items-center h-[36px] bg-neutral-800 dark:bg-black-800 px-[10px] rounded-[43px]\"\n >\n {sortedActionItems.map(\n (button, index) =>\n button.visible !== false && (\n <div key={index}>\n {button.type === \"dropdown\" ? (\n <Dropdown\n menu={{\n items: button.dropdownItems,\n }}\n trigger={[button.dropdownTrigger || \"click\"]}\n overlayClassName=\"!min-w-[148px]\"\n placement=\"bottomRight\"\n getPopupContainer={(trigger) =>\n trigger.parentElement as HTMLElement\n }\n open={showDropdown}\n onOpenChange={setShowDropdown}\n >\n <button\n key={index}\n id={`btn-floating-bar-${button.label}`}\n onClick={button.onClick}\n disabled={button.disabled}\n className={cn(\n !button?.label\n ? \"bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80\"\n : \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent\",\n button?.hideLabel && \"!p-1.5\",\n isDeleteAction(button) && \"!text-error-500 dark:!text-error-700\",\n button.disabled && \"opacity-70\"\n )}\n >\n <Tooltip\n hideTooltip={!button.tooltip}\n title={button.tooltip}\n className=\"flex items-center gap-1.5\"\n >\n {button.icon}\n {!button?.hideLabel && button.label && (\n <Typography\n size=\"small\"\n variant=\"medium\"\n className={cn(\n \"text-inherit\",\n isDeleteAction(button) &&\n \"!text-error-500 dark:!text-error-700\"\n )}\n appearance=\"custom\"\n >\n {button.label}\n </Typography>\n )}\n </Tooltip>\n </button>\n </Dropdown>\n ) : (\n <button\n id={`btn-floating-bar-${button.label}`}\n onClick={button.onClick}\n disabled={button.disabled}\n className={cn(\n !button?.label\n ? \"bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80\"\n : \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent\",\n button?.hideLabel && \"!p-1.5\",\n isDeleteAction(button) && \"!text-error-500 dark:!text-error-700\",\n button.disabled && \"opacity-70\"\n )}\n >\n <Tooltip\n hideTooltip={!button.tooltip}\n title={button.tooltip}\n className=\"flex items-center gap-1.5\"\n >\n {button.icon}\n\n {!button?.hideLabel && button.label && (\n <Typography\n size=\"small\"\n variant=\"medium\"\n className={\"text-inherit\"}\n appearance=\"custom\"\n >\n {button.label}\n </Typography>\n )}\n </Tooltip>\n </button>\n )}\n </div>\n )\n )}\n {deleteConfig ? (\n <button\n id={`btn-floating-bar-${deleteButtonConfig.label}`}\n onClick={deleteButtonConfig.onClick}\n disabled={deleteButtonConfig.disabled}\n className={cn(\n \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200\",\n deleteButtonConfig.disabled && \"opacity-70\"\n )}\n >\n {deleteButtonConfig.icon}\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-error-700\"\n appearance=\"custom\"\n >\n {deleteButtonConfig.label}\n </Typography>\n </button>\n ) : null}\n </motion.div>\n ) : (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.2 }}\n className=\"minw-[150px] p-1.5 flex items-center\"\n >\n <Dropdown\n menu={{\n items: dropDownItems,\n }}\n trigger={[\"click\"]}\n overlayClassName=\"!min-w-[148px]\"\n placement=\"bottomRight\"\n getPopupContainer={(trigger) =>\n trigger.parentElement as HTMLElement\n }\n open={showDropdown}\n onOpenChange={setShowDropdown}\n >\n <button\n id={`btn-floating-bar-actions`}\n disabled={dropDownItems.length === 0}\n className={cn(\n \"flex items-center gap-1.5 px-2 py-1 w-22 h-7 rounded-full bg-[#34405473]/45 dark:bg-black-700 hover:scale-105 hover:opacity-80 transition-all duration-200\",\n dropDownItems.length === 0 &&\n \"opacity-60 hover:scale-100 hover:opacity-60\"\n )}\n type=\"button\"\n >\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-white\"\n >\n {t(\"Actions\")}\n </Typography>\n <DropdownArrowIcon\n fill=\"#FFFFFF\"\n className=\"w-[16px] h-[16px]\"\n />\n </button>\n </Dropdown>\n {deleteConfig ? (\n <button\n id={`btn-floating-bar-${deleteButtonConfig.label}`}\n onClick={deleteButtonConfig.onClick}\n disabled={deleteButtonConfig.disabled}\n className={cn(\n \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200\",\n deleteButtonConfig.disabled && \"opacity-70\"\n )}\n type=\"button\"\n >\n {deleteButtonConfig.icon}\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-error-700\"\n appearance=\"custom\"\n >\n {deleteButtonConfig.label}\n </Typography>\n </button>\n ) : null}\n </motion.div>\n )}\n </div>\n ) : null}\n </div>\n </motion.div>\n );\n};\n\nFloatingBar.displayName = \"FloatingBar\";\n\n// Re-export types for convenience\nexport type { ButtonConfig as FloatingBarActionConfig };\nexport type FloatingBarDeleteConfig = TFloatingBar[\"deleteConfig\"];\nexport type FloatingBarProps = TFloatingBar;\n\n// Legacy type exports for backwards compatibility\nexport type FloatingBarSize = \"small\" | \"medium\" | \"large\";\nexport type FloatingBarPosition = \"top\" | \"bottom\";\nexport type FloatingBarTheme = \"primary\" | \"dark\" | \"light\";\n"],"names":["CloseIcon","size","fill","className","jsx","DropdownArrowIcon","FloatingBar","props","show","isFlowDashboard","onClose","actionItems","selectedItemsCount","deleteConfig","showActionBg","t","useTranslation","showDropdown","setShowDropdown","useState","showButtons","setShowButtons","containerRef","useRef","actionContainerRef","useEffect","observer","containerWidth","deleteButtonConfig","DeleteIcon","isDeleteAction","button","label","sortedActionItems","a","b","hasActions","dropDownItems","index","OptionButton","motion","cn","jsxs","IconButton","Typography","Dropdown","trigger","Tooltip"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as
|
|
1
|
+
import { jsx as a, jsxs as i } from "react/jsx-runtime";
|
|
2
2
|
import { Dropdown as C } from "antd";
|
|
3
3
|
import l from "../../_virtual/index.es.js";
|
|
4
4
|
import { motion as f } from "framer-motion";
|
|
@@ -13,7 +13,7 @@ const S = ({
|
|
|
13
13
|
size: n = 24,
|
|
14
14
|
fill: c = "currentColor",
|
|
15
15
|
className: h
|
|
16
|
-
}) => /* @__PURE__ */
|
|
16
|
+
}) => /* @__PURE__ */ a(
|
|
17
17
|
"svg",
|
|
18
18
|
{
|
|
19
19
|
className: h,
|
|
@@ -22,12 +22,12 @@ const S = ({
|
|
|
22
22
|
viewBox: "0 0 20 20",
|
|
23
23
|
fill: c,
|
|
24
24
|
xmlns: "http://www.w3.org/2000/svg",
|
|
25
|
-
children: /* @__PURE__ */
|
|
25
|
+
children: /* @__PURE__ */ a("path", { d: "M10.0002 11.1666L5.91683 15.2499C5.76405 15.4027 5.56961 15.4791 5.3335 15.4791C5.09739 15.4791 4.90294 15.4027 4.75016 15.2499C4.59738 15.0971 4.521 14.9027 4.521 14.6666C4.521 14.4305 4.59738 14.236 4.75016 14.0833L8.8335 9.99992L4.75016 5.91659C4.59738 5.76381 4.521 5.56936 4.521 5.33325C4.521 5.09714 4.59738 4.9027 4.75016 4.74992C4.90294 4.59714 5.09739 4.52075 5.3335 4.52075C5.56961 4.52075 5.76405 4.59714 5.91683 4.74992L10.0002 8.83325L14.0835 4.74992C14.2363 4.59714 14.4307 4.52075 14.6668 4.52075C14.9029 4.52075 15.0974 4.59714 15.2502 4.74992C15.4029 4.9027 15.4793 5.09714 15.4793 5.33325C15.4793 5.56936 15.4029 5.76381 15.2502 5.91659L11.1668 9.99992L15.2502 14.0833C15.4029 14.236 15.4793 14.4305 15.4793 14.6666C15.4793 14.9027 15.4029 15.0971 15.2502 15.2499C15.0974 15.4027 14.9029 15.4791 14.6668 15.4791C14.4307 15.4791 14.2363 15.4027 14.0835 15.2499L10.0002 11.1666Z" })
|
|
26
26
|
}
|
|
27
27
|
), W = ({
|
|
28
28
|
fill: n = "#cccccc",
|
|
29
29
|
className: c
|
|
30
|
-
}) => /* @__PURE__ */
|
|
30
|
+
}) => /* @__PURE__ */ a(
|
|
31
31
|
"svg",
|
|
32
32
|
{
|
|
33
33
|
height: "20",
|
|
@@ -35,7 +35,7 @@ const S = ({
|
|
|
35
35
|
viewBox: "0 0 20 20",
|
|
36
36
|
focusable: "false",
|
|
37
37
|
className: c,
|
|
38
|
-
children: /* @__PURE__ */
|
|
38
|
+
children: /* @__PURE__ */ a(
|
|
39
39
|
"path",
|
|
40
40
|
{
|
|
41
41
|
fill: n,
|
|
@@ -48,7 +48,7 @@ const S = ({
|
|
|
48
48
|
show: c,
|
|
49
49
|
isFlowDashboard: h,
|
|
50
50
|
onClose: L,
|
|
51
|
-
actionItems:
|
|
51
|
+
actionItems: m,
|
|
52
52
|
selectedItemsCount: B,
|
|
53
53
|
deleteConfig: p,
|
|
54
54
|
showActionBg: E
|
|
@@ -57,26 +57,26 @@ const S = ({
|
|
|
57
57
|
const e = new ResizeObserver(() => {
|
|
58
58
|
if (o.current && y.current) {
|
|
59
59
|
const r = o.current.scrollWidth - 100;
|
|
60
|
-
|
|
60
|
+
m.length * 180 + 100 > r ? v(!1) : v(!0);
|
|
61
61
|
}
|
|
62
62
|
});
|
|
63
63
|
return o.current && e.observe(o.current), () => {
|
|
64
64
|
o.current && e.unobserve(o.current);
|
|
65
65
|
};
|
|
66
66
|
});
|
|
67
|
-
const
|
|
67
|
+
const t = {
|
|
68
68
|
label: x("Delete"),
|
|
69
|
-
icon: /* @__PURE__ */
|
|
69
|
+
icon: /* @__PURE__ */ a(O, { className: "text-error-700 w-icon h-icon" }),
|
|
70
70
|
onClick: p?.onClick,
|
|
71
71
|
...p
|
|
72
|
-
},
|
|
72
|
+
}, d = (e) => {
|
|
73
73
|
const r = e.label?.toLowerCase() ?? "";
|
|
74
74
|
return r.includes("delete") || r === "remove" || r === "move to trash";
|
|
75
|
-
}, F = [...
|
|
76
|
-
(e, r) => Number(
|
|
77
|
-
), z =
|
|
75
|
+
}, F = [...m].sort(
|
|
76
|
+
(e, r) => Number(d(e)) - Number(d(r))
|
|
77
|
+
), z = m.some((e) => e.visible !== !1) || !!p, b = m.filter((e) => e.visible !== !1).map((e, r) => ({
|
|
78
78
|
key: r,
|
|
79
|
-
label: /* @__PURE__ */
|
|
79
|
+
label: /* @__PURE__ */ a(
|
|
80
80
|
T,
|
|
81
81
|
{
|
|
82
82
|
icon: e.dropdownIcon,
|
|
@@ -88,7 +88,7 @@ const S = ({
|
|
|
88
88
|
children: e.dropdownItems,
|
|
89
89
|
disabled: !1
|
|
90
90
|
}));
|
|
91
|
-
return c ? /* @__PURE__ */
|
|
91
|
+
return c ? /* @__PURE__ */ a(
|
|
92
92
|
f.div,
|
|
93
93
|
{
|
|
94
94
|
initial: { y: 20, opacity: 0 },
|
|
@@ -110,21 +110,21 @@ const S = ({
|
|
|
110
110
|
children: [
|
|
111
111
|
/* @__PURE__ */ i("div", { className: "flex items-center gap-[12px]", children: [
|
|
112
112
|
/* @__PURE__ */ i("div", { className: "flex items-center gap-[8px]", children: [
|
|
113
|
-
/* @__PURE__ */
|
|
113
|
+
/* @__PURE__ */ a(
|
|
114
114
|
j,
|
|
115
115
|
{
|
|
116
116
|
tooltip: "Close",
|
|
117
117
|
variant: "ghost",
|
|
118
118
|
onClick: L,
|
|
119
119
|
className: "!p-0 text-white hover:opacity-80 hover:rotate-90 transition-all duration-200",
|
|
120
|
-
children: /* @__PURE__ */
|
|
120
|
+
children: /* @__PURE__ */ a(S, { size: 16 })
|
|
121
121
|
}
|
|
122
122
|
),
|
|
123
|
-
/* @__PURE__ */
|
|
123
|
+
/* @__PURE__ */ a("div", { className: "w-px h-[14px] rounded-[1px] bg-neutral-700 dark:bg-[#1d242c]" })
|
|
124
124
|
] }),
|
|
125
125
|
/* @__PURE__ */ i("div", { className: "flex items-center gap-[6px]", children: [
|
|
126
|
-
/* @__PURE__ */
|
|
127
|
-
/* @__PURE__ */
|
|
126
|
+
/* @__PURE__ */ a("span", { className: "inline-flex items-center justify-center min-w-[20px] h-[16px] px-[8px] rounded-[9px] border text-[12px] leading-[18px] font-normal text-primary-600 dark:text-primary-400 bg-primary-50 dark:bg-[rgba(0,50,95,0.3)] border-primary-200 dark:border-primary-800", children: B || 0 }),
|
|
127
|
+
/* @__PURE__ */ a(
|
|
128
128
|
s,
|
|
129
129
|
{
|
|
130
130
|
size: "extra-small",
|
|
@@ -135,7 +135,7 @@ const S = ({
|
|
|
135
135
|
)
|
|
136
136
|
] })
|
|
137
137
|
] }),
|
|
138
|
-
z ? /* @__PURE__ */
|
|
138
|
+
z ? /* @__PURE__ */ a(
|
|
139
139
|
"div",
|
|
140
140
|
{
|
|
141
141
|
ref: y,
|
|
@@ -151,7 +151,7 @@ const S = ({
|
|
|
151
151
|
className: "flex items-center h-[36px] bg-neutral-800 dark:bg-black-800 px-[10px] rounded-[43px]",
|
|
152
152
|
children: [
|
|
153
153
|
F.map(
|
|
154
|
-
(e, r) => e.visible !== !1 && /* @__PURE__ */
|
|
154
|
+
(e, r) => e.visible !== !1 && /* @__PURE__ */ a("div", { children: e.type === "dropdown" ? /* @__PURE__ */ a(
|
|
155
155
|
C,
|
|
156
156
|
{
|
|
157
157
|
menu: {
|
|
@@ -163,7 +163,7 @@ const S = ({
|
|
|
163
163
|
getPopupContainer: (w) => w.parentElement,
|
|
164
164
|
open: g,
|
|
165
165
|
onOpenChange: u,
|
|
166
|
-
children: /* @__PURE__ */
|
|
166
|
+
children: /* @__PURE__ */ a(
|
|
167
167
|
"button",
|
|
168
168
|
{
|
|
169
169
|
id: `btn-floating-bar-${e.label}`,
|
|
@@ -172,7 +172,7 @@ const S = ({
|
|
|
172
172
|
className: l(
|
|
173
173
|
e?.label ? "flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent" : "bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80",
|
|
174
174
|
e?.hideLabel && "!p-1.5",
|
|
175
|
-
|
|
175
|
+
d(e) && "!text-error-500 dark:!text-error-700",
|
|
176
176
|
e.disabled && "opacity-70"
|
|
177
177
|
),
|
|
178
178
|
children: /* @__PURE__ */ i(
|
|
@@ -183,12 +183,15 @@ const S = ({
|
|
|
183
183
|
className: "flex items-center gap-1.5",
|
|
184
184
|
children: [
|
|
185
185
|
e.icon,
|
|
186
|
-
!e?.hideLabel && e.label && /* @__PURE__ */
|
|
186
|
+
!e?.hideLabel && e.label && /* @__PURE__ */ a(
|
|
187
187
|
s,
|
|
188
188
|
{
|
|
189
189
|
size: "small",
|
|
190
190
|
variant: "medium",
|
|
191
|
-
className:
|
|
191
|
+
className: l(
|
|
192
|
+
"text-inherit",
|
|
193
|
+
d(e) && "!text-error-500 dark:!text-error-700"
|
|
194
|
+
),
|
|
192
195
|
appearance: "custom",
|
|
193
196
|
children: e.label
|
|
194
197
|
}
|
|
@@ -200,7 +203,7 @@ const S = ({
|
|
|
200
203
|
r
|
|
201
204
|
)
|
|
202
205
|
}
|
|
203
|
-
) : /* @__PURE__ */
|
|
206
|
+
) : /* @__PURE__ */ a(
|
|
204
207
|
"button",
|
|
205
208
|
{
|
|
206
209
|
id: `btn-floating-bar-${e.label}`,
|
|
@@ -209,7 +212,7 @@ const S = ({
|
|
|
209
212
|
className: l(
|
|
210
213
|
e?.label ? "flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent" : "bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80",
|
|
211
214
|
e?.hideLabel && "!p-1.5",
|
|
212
|
-
|
|
215
|
+
d(e) && "!text-error-500 dark:!text-error-700",
|
|
213
216
|
e.disabled && "opacity-70"
|
|
214
217
|
),
|
|
215
218
|
children: /* @__PURE__ */ i(
|
|
@@ -220,7 +223,7 @@ const S = ({
|
|
|
220
223
|
className: "flex items-center gap-1.5",
|
|
221
224
|
children: [
|
|
222
225
|
e.icon,
|
|
223
|
-
!e?.hideLabel && e.label && /* @__PURE__ */
|
|
226
|
+
!e?.hideLabel && e.label && /* @__PURE__ */ a(
|
|
224
227
|
s,
|
|
225
228
|
{
|
|
226
229
|
size: "small",
|
|
@@ -239,23 +242,23 @@ const S = ({
|
|
|
239
242
|
p ? /* @__PURE__ */ i(
|
|
240
243
|
"button",
|
|
241
244
|
{
|
|
242
|
-
id: `btn-floating-bar-${
|
|
243
|
-
onClick:
|
|
244
|
-
disabled:
|
|
245
|
+
id: `btn-floating-bar-${t.label}`,
|
|
246
|
+
onClick: t.onClick,
|
|
247
|
+
disabled: t.disabled,
|
|
245
248
|
className: l(
|
|
246
249
|
"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200",
|
|
247
|
-
|
|
250
|
+
t.disabled && "opacity-70"
|
|
248
251
|
),
|
|
249
252
|
children: [
|
|
250
|
-
|
|
251
|
-
/* @__PURE__ */
|
|
253
|
+
t.icon,
|
|
254
|
+
/* @__PURE__ */ a(
|
|
252
255
|
s,
|
|
253
256
|
{
|
|
254
257
|
size: "small",
|
|
255
258
|
variant: "medium",
|
|
256
259
|
className: "text-error-700",
|
|
257
260
|
appearance: "custom",
|
|
258
|
-
children:
|
|
261
|
+
children: t.label
|
|
259
262
|
}
|
|
260
263
|
)
|
|
261
264
|
]
|
|
@@ -271,7 +274,7 @@ const S = ({
|
|
|
271
274
|
transition: { duration: 0.2 },
|
|
272
275
|
className: "minw-[150px] p-1.5 flex items-center",
|
|
273
276
|
children: [
|
|
274
|
-
/* @__PURE__ */
|
|
277
|
+
/* @__PURE__ */ a(
|
|
275
278
|
C,
|
|
276
279
|
{
|
|
277
280
|
menu: {
|
|
@@ -294,7 +297,7 @@ const S = ({
|
|
|
294
297
|
),
|
|
295
298
|
type: "button",
|
|
296
299
|
children: [
|
|
297
|
-
/* @__PURE__ */
|
|
300
|
+
/* @__PURE__ */ a(
|
|
298
301
|
s,
|
|
299
302
|
{
|
|
300
303
|
size: "small",
|
|
@@ -303,7 +306,7 @@ const S = ({
|
|
|
303
306
|
children: x("Actions")
|
|
304
307
|
}
|
|
305
308
|
),
|
|
306
|
-
/* @__PURE__ */
|
|
309
|
+
/* @__PURE__ */ a(
|
|
307
310
|
W,
|
|
308
311
|
{
|
|
309
312
|
fill: "#FFFFFF",
|
|
@@ -318,24 +321,24 @@ const S = ({
|
|
|
318
321
|
p ? /* @__PURE__ */ i(
|
|
319
322
|
"button",
|
|
320
323
|
{
|
|
321
|
-
id: `btn-floating-bar-${
|
|
322
|
-
onClick:
|
|
323
|
-
disabled:
|
|
324
|
+
id: `btn-floating-bar-${t.label}`,
|
|
325
|
+
onClick: t.onClick,
|
|
326
|
+
disabled: t.disabled,
|
|
324
327
|
className: l(
|
|
325
328
|
"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200",
|
|
326
|
-
|
|
329
|
+
t.disabled && "opacity-70"
|
|
327
330
|
),
|
|
328
331
|
type: "button",
|
|
329
332
|
children: [
|
|
330
|
-
|
|
331
|
-
/* @__PURE__ */
|
|
333
|
+
t.icon,
|
|
334
|
+
/* @__PURE__ */ a(
|
|
332
335
|
s,
|
|
333
336
|
{
|
|
334
337
|
size: "small",
|
|
335
338
|
variant: "medium",
|
|
336
339
|
className: "text-error-700",
|
|
337
340
|
appearance: "custom",
|
|
338
|
-
children:
|
|
341
|
+
children: t.label
|
|
339
342
|
}
|
|
340
343
|
)
|
|
341
344
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingBar.es.js","sources":["../../../src/components/floating-bar/FloatingBar.tsx"],"sourcesContent":["import { Dropdown } from \"antd\";\nimport cn from \"classnames\";\nimport { motion } from \"framer-motion\";\nimport { useEffect, useRef, useState, type FC, type ReactNode } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Typography } from \"../data-display/typography/Typography\";\nimport { OptionButton } from \"../buttons/option-button/OptionButton\";\nimport IconButton from \"../button/IconButton\";\nimport Tooltip from \"../tooltip/Tooltip\";\nimport { DeleteIcon } from \"../icon\";\n\n/**\n * Close icon component\n */\nconst CloseIcon: FC<{ size?: number; fill?: string; className?: string }> = ({\n size = 24,\n fill = \"currentColor\",\n className,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 20 20\"\n fill={fill}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M10.0002 11.1666L5.91683 15.2499C5.76405 15.4027 5.56961 15.4791 5.3335 15.4791C5.09739 15.4791 4.90294 15.4027 4.75016 15.2499C4.59738 15.0971 4.521 14.9027 4.521 14.6666C4.521 14.4305 4.59738 14.236 4.75016 14.0833L8.8335 9.99992L4.75016 5.91659C4.59738 5.76381 4.521 5.56936 4.521 5.33325C4.521 5.09714 4.59738 4.9027 4.75016 4.74992C4.90294 4.59714 5.09739 4.52075 5.3335 4.52075C5.56961 4.52075 5.76405 4.59714 5.91683 4.74992L10.0002 8.83325L14.0835 4.74992C14.2363 4.59714 14.4307 4.52075 14.6668 4.52075C14.9029 4.52075 15.0974 4.59714 15.2502 4.74992C15.4029 4.9027 15.4793 5.09714 15.4793 5.33325C15.4793 5.56936 15.4029 5.76381 15.2502 5.91659L11.1668 9.99992L15.2502 14.0833C15.4029 14.236 15.4793 14.4305 15.4793 14.6666C15.4793 14.9027 15.4029 15.0971 15.2502 15.2499C15.0974 15.4027 14.9029 15.4791 14.6668 15.4791C14.4307 15.4791 14.2363 15.4027 14.0835 15.2499L10.0002 11.1666Z\" />\n </svg>\n);\n\n/**\n * Dropdown arrow icon component\n */\nconst DropdownArrowIcon: FC<{ fill?: string; className?: string }> = ({\n fill = \"#cccccc\",\n className,\n}) => (\n <svg\n height=\"20\"\n width=\"20\"\n viewBox=\"0 0 20 20\"\n focusable=\"false\"\n className={className}\n >\n <path\n fill={fill}\n d=\"M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z\"\n />\n </svg>\n);\n\n/**\n * Configuration for action buttons in the floating bar\n */\nexport type ButtonConfig = {\n /** Button label text */\n label?: string;\n /** Icon element to display */\n icon: ReactNode;\n /** Click handler for the action */\n onClick?: () => void;\n /** Icon for dropdown mode */\n dropdownIcon?: ReactNode;\n /** Whether the action is visible */\n visible?: boolean;\n /** Whether the action is disabled */\n disabled?: boolean;\n /** Tooltip text */\n tooltip?: string;\n /** Whether to hide the label text */\n hideLabel?: boolean;\n /** Action type */\n type?: \"button\" | \"dropdown\";\n /** Dropdown trigger mode */\n dropdownTrigger?: \"click\" | \"hover\";\n /** Dropdown menu items */\n dropdownItems?: Array<{\n label: ReactNode;\n key: string;\n disabled?: boolean;\n }>;\n};\n\n/**\n * Props for the FloatingBar component\n */\nexport type TFloatingBar = {\n /** Whether the floating bar is visible */\n show?: boolean;\n /** Close handler */\n onClose: () => void;\n /** Whether this is used in flow dashboard layout */\n isFlowDashboard?: boolean;\n /** Array of action configurations */\n actionItems: ButtonConfig[];\n /** Number of selected items */\n selectedItemsCount?: number;\n /** Delete action configuration */\n deleteConfig?: {\n label?: string;\n disabled?: boolean;\n onClick?: () => void;\n };\n /** Whether to show action background */\n showActionBg?: boolean;\n};\n\n/**\n * FloatingBar component provides a floating action bar for bulk operations.\n * Drop-in replacement matching the lax-web-portal implementation.\n *\n * @example\n * ```tsx\n * <FloatingBar\n * show={selectedItems.length > 0}\n * onClose={() => setSelectedItems([])}\n * selectedItemsCount={selectedItems.length}\n * actionItems={[\n * {\n * label: \"Edit\",\n * icon: <EditIcon size={16} />,\n * onClick: handleEdit,\n * },\n * {\n * label: \"Archive\",\n * icon: <ArchiveIcon size={16} />,\n * onClick: handleArchive,\n * },\n * ]}\n * deleteConfig={{\n * label: \"Delete\",\n * onClick: handleDelete,\n * }}\n * />\n * ```\n */\nexport const FloatingBar: FC<TFloatingBar> = (props) => {\n const {\n show,\n isFlowDashboard,\n onClose,\n actionItems,\n selectedItemsCount,\n deleteConfig,\n showActionBg,\n } = props;\n\n const { t } = useTranslation();\n const [showDropdown, setShowDropdown] = useState<boolean>(false);\n const [showButtons, setShowButtons] = useState<boolean>(true);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const actionContainerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const observer = new ResizeObserver(() => {\n if (containerRef.current && actionContainerRef.current) {\n const containerWidth = containerRef.current.scrollWidth - 100;\n const totalActionItemsWidth = actionItems.length * 180 + 100;\n if (totalActionItemsWidth > containerWidth) {\n setShowButtons(false);\n } else {\n setShowButtons(true);\n }\n }\n });\n\n if (containerRef.current) {\n observer.observe(containerRef.current);\n }\n\n return () => {\n if (containerRef.current) {\n observer.unobserve(containerRef.current);\n }\n };\n });\n\n const deleteButtonConfig = {\n label: t(\"Delete\"),\n icon: <DeleteIcon className=\"text-error-700 w-icon h-icon\" />,\n color: \"text-error-700 dark:text-error-700\",\n onClick: deleteConfig?.onClick,\n ...deleteConfig,\n };\n\n /** Whether a button represents a destructive/delete action */\n const isDeleteAction = (button: ButtonConfig) => {\n const label = button.label?.toLowerCase() ?? \"\";\n return (\n label.includes(\"delete\") ||\n label === \"remove\" ||\n label === \"move to trash\"\n );\n };\n\n /** Delete actions are always displayed last (on the right) */\n const sortedActionItems = [...actionItems].sort(\n (a, b) => Number(isDeleteAction(a)) - Number(isDeleteAction(b))\n );\n\n /** Whether the action area has anything to render — avoids an empty pill */\n const hasActions =\n actionItems.some((button) => button.visible !== false) || Boolean(deleteConfig);\n\n const dropDownItems = actionItems\n .filter((button) => button.visible !== false)\n .map((button, index) => ({\n key: index,\n label: (\n <OptionButton\n icon={button.dropdownIcon}\n text={button?.label || \"\"}\n onClick={button.onClick}\n className=\"font-inter text-base font-medium text-black-900 dark:text-black-200 gap-1.5\"\n />\n ),\n children: button.dropdownItems,\n disabled: false,\n }));\n\n return !show ? null : (\n <motion.div\n initial={{ y: 20, opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n exit={{ y: 20, opacity: 0 }}\n transition={{\n duration: 0.2,\n ease: [0.4, 0, 0.2, 1],\n opacity: { duration: 0.15 },\n }}\n ref={containerRef}\n className={cn(\"h-[36px] mb-4\", isFlowDashboard ? \"ml-60 w-1/2\" : \"w-full\")}\n >\n <div\n className={cn(\n \"h-[36px] border-y border-neutral-900 dark:border-[#0d1014 px-[12px] text-white bg-neutral-900 dark:bg-black-900 flex justify-between items-center\"\n )}\n >\n <div className=\"flex items-center gap-[12px]\">\n <div className=\"flex items-center gap-[8px]\">\n <IconButton\n tooltip=\"Close\"\n variant=\"ghost\"\n onClick={onClose}\n className=\"!p-0 text-white hover:opacity-80 hover:rotate-90 transition-all duration-200\"\n >\n <CloseIcon size={16} />\n </IconButton>\n <div className=\"w-px h-[14px] rounded-[1px] bg-neutral-700 dark:bg-[#1d242c]\" />\n </div>\n <div className=\"flex items-center gap-[6px]\">\n <span className=\"inline-flex items-center justify-center min-w-[20px] h-[16px] px-[8px] rounded-[9px] border text-[12px] leading-[18px] font-normal text-primary-600 dark:text-primary-400 bg-primary-50 dark:bg-[rgba(0,50,95,0.3)] border-primary-200 dark:border-primary-800\">\n {selectedItemsCount || 0}\n </span>\n <Typography\n size=\"extra-small\"\n appearance=\"custom\"\n className=\"text-white dark:text-neutral-50\"\n >\n {t(\"Selected\")}\n </Typography>\n </div>\n </div>\n {hasActions ? (\n <div\n ref={actionContainerRef}\n className={cn(\n \"h-[36px] flex items-center font-inter bg-neutral-800 dark:bg-black-800 pl-[10px] rounded-[43px]\"\n )}\n >\n {showButtons ? (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.2 }}\n className=\"flex items-center h-[36px] bg-neutral-800 dark:bg-black-800 px-[10px] rounded-[43px]\"\n >\n {sortedActionItems.map(\n (button, index) =>\n button.visible !== false && (\n <div key={index}>\n {button.type === \"dropdown\" ? (\n <Dropdown\n menu={{\n items: button.dropdownItems,\n }}\n trigger={[button.dropdownTrigger || \"click\"]}\n overlayClassName=\"!min-w-[148px]\"\n placement=\"bottomRight\"\n getPopupContainer={(trigger) =>\n trigger.parentElement as HTMLElement\n }\n open={showDropdown}\n onOpenChange={setShowDropdown}\n >\n <button\n key={index}\n id={`btn-floating-bar-${button.label}`}\n onClick={button.onClick}\n disabled={button.disabled}\n className={cn(\n !button?.label\n ? \"bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80\"\n : \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent\",\n button?.hideLabel && \"!p-1.5\",\n isDeleteAction(button) && \"!text-error-500 dark:!text-error-700\",\n button.disabled && \"opacity-70\"\n )}\n >\n <Tooltip\n hideTooltip={!button.tooltip}\n title={button.tooltip}\n className=\"flex items-center gap-1.5\"\n >\n {button.icon}\n {!button?.hideLabel && button.label && (\n <Typography\n size=\"small\"\n variant=\"medium\"\n className={\"text-inherit !text-error-500 dark:!text-error-700\"}\n appearance=\"custom\"\n >\n {button.label}\n </Typography>\n )}\n </Tooltip>\n </button>\n </Dropdown>\n ) : (\n <button\n id={`btn-floating-bar-${button.label}`}\n onClick={button.onClick}\n disabled={button.disabled}\n className={cn(\n !button?.label\n ? \"bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80\"\n : \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent\",\n button?.hideLabel && \"!p-1.5\",\n isDeleteAction(button) && \"!text-error-500 dark:!text-error-700\",\n button.disabled && \"opacity-70\"\n )}\n >\n <Tooltip\n hideTooltip={!button.tooltip}\n title={button.tooltip}\n className=\"flex items-center gap-1.5\"\n >\n {button.icon}\n\n {!button?.hideLabel && button.label && (\n <Typography\n size=\"small\"\n variant=\"medium\"\n className={\"text-inherit\"}\n appearance=\"custom\"\n >\n {button.label}\n </Typography>\n )}\n </Tooltip>\n </button>\n )}\n </div>\n )\n )}\n {deleteConfig ? (\n <button\n id={`btn-floating-bar-${deleteButtonConfig.label}`}\n onClick={deleteButtonConfig.onClick}\n disabled={deleteButtonConfig.disabled}\n className={cn(\n \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200\",\n deleteButtonConfig.disabled && \"opacity-70\"\n )}\n >\n {deleteButtonConfig.icon}\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-error-700\"\n appearance=\"custom\"\n >\n {deleteButtonConfig.label}\n </Typography>\n </button>\n ) : null}\n </motion.div>\n ) : (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.2 }}\n className=\"minw-[150px] p-1.5 flex items-center\"\n >\n <Dropdown\n menu={{\n items: dropDownItems,\n }}\n trigger={[\"click\"]}\n overlayClassName=\"!min-w-[148px]\"\n placement=\"bottomRight\"\n getPopupContainer={(trigger) =>\n trigger.parentElement as HTMLElement\n }\n open={showDropdown}\n onOpenChange={setShowDropdown}\n >\n <button\n id={`btn-floating-bar-actions`}\n disabled={dropDownItems.length === 0}\n className={cn(\n \"flex items-center gap-1.5 px-2 py-1 w-22 h-7 rounded-full bg-[#34405473]/45 dark:bg-black-700 hover:scale-105 hover:opacity-80 transition-all duration-200\",\n dropDownItems.length === 0 &&\n \"opacity-60 hover:scale-100 hover:opacity-60\"\n )}\n type=\"button\"\n >\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-white\"\n >\n {t(\"Actions\")}\n </Typography>\n <DropdownArrowIcon\n fill=\"#FFFFFF\"\n className=\"w-[16px] h-[16px]\"\n />\n </button>\n </Dropdown>\n {deleteConfig ? (\n <button\n id={`btn-floating-bar-${deleteButtonConfig.label}`}\n onClick={deleteButtonConfig.onClick}\n disabled={deleteButtonConfig.disabled}\n className={cn(\n \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200\",\n deleteButtonConfig.disabled && \"opacity-70\"\n )}\n type=\"button\"\n >\n {deleteButtonConfig.icon}\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-error-700\"\n appearance=\"custom\"\n >\n {deleteButtonConfig.label}\n </Typography>\n </button>\n ) : null}\n </motion.div>\n )}\n </div>\n ) : null}\n </div>\n </motion.div>\n );\n};\n\nFloatingBar.displayName = \"FloatingBar\";\n\n// Re-export types for convenience\nexport type { ButtonConfig as FloatingBarActionConfig };\nexport type FloatingBarDeleteConfig = TFloatingBar[\"deleteConfig\"];\nexport type FloatingBarProps = TFloatingBar;\n\n// Legacy type exports for backwards compatibility\nexport type FloatingBarSize = \"small\" | \"medium\" | \"large\";\nexport type FloatingBarPosition = \"top\" | \"bottom\";\nexport type FloatingBarTheme = \"primary\" | \"dark\" | \"light\";\n"],"names":["CloseIcon","size","fill","className","jsx","DropdownArrowIcon","FloatingBar","props","show","isFlowDashboard","onClose","actionItems","selectedItemsCount","deleteConfig","showActionBg","t","useTranslation","showDropdown","setShowDropdown","useState","showButtons","setShowButtons","containerRef","useRef","actionContainerRef","useEffect","observer","containerWidth","deleteButtonConfig","DeleteIcon","isDeleteAction","button","label","sortedActionItems","a","b","hasActions","dropDownItems","index","OptionButton","motion","cn","jsxs","IconButton","Typography","Dropdown","trigger","Tooltip"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FloatingBar.es.js","sources":["../../../src/components/floating-bar/FloatingBar.tsx"],"sourcesContent":["import { Dropdown } from \"antd\";\nimport cn from \"classnames\";\nimport { motion } from \"framer-motion\";\nimport { useEffect, useRef, useState, type FC, type ReactNode } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Typography } from \"../data-display/typography/Typography\";\nimport { OptionButton } from \"../buttons/option-button/OptionButton\";\nimport IconButton from \"../button/IconButton\";\nimport Tooltip from \"../tooltip/Tooltip\";\nimport { DeleteIcon } from \"../icon\";\n\n/**\n * Close icon component\n */\nconst CloseIcon: FC<{ size?: number; fill?: string; className?: string }> = ({\n size = 24,\n fill = \"currentColor\",\n className,\n}) => (\n <svg\n className={className}\n width={size}\n height={size}\n viewBox=\"0 0 20 20\"\n fill={fill}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M10.0002 11.1666L5.91683 15.2499C5.76405 15.4027 5.56961 15.4791 5.3335 15.4791C5.09739 15.4791 4.90294 15.4027 4.75016 15.2499C4.59738 15.0971 4.521 14.9027 4.521 14.6666C4.521 14.4305 4.59738 14.236 4.75016 14.0833L8.8335 9.99992L4.75016 5.91659C4.59738 5.76381 4.521 5.56936 4.521 5.33325C4.521 5.09714 4.59738 4.9027 4.75016 4.74992C4.90294 4.59714 5.09739 4.52075 5.3335 4.52075C5.56961 4.52075 5.76405 4.59714 5.91683 4.74992L10.0002 8.83325L14.0835 4.74992C14.2363 4.59714 14.4307 4.52075 14.6668 4.52075C14.9029 4.52075 15.0974 4.59714 15.2502 4.74992C15.4029 4.9027 15.4793 5.09714 15.4793 5.33325C15.4793 5.56936 15.4029 5.76381 15.2502 5.91659L11.1668 9.99992L15.2502 14.0833C15.4029 14.236 15.4793 14.4305 15.4793 14.6666C15.4793 14.9027 15.4029 15.0971 15.2502 15.2499C15.0974 15.4027 14.9029 15.4791 14.6668 15.4791C14.4307 15.4791 14.2363 15.4027 14.0835 15.2499L10.0002 11.1666Z\" />\n </svg>\n);\n\n/**\n * Dropdown arrow icon component\n */\nconst DropdownArrowIcon: FC<{ fill?: string; className?: string }> = ({\n fill = \"#cccccc\",\n className,\n}) => (\n <svg\n height=\"20\"\n width=\"20\"\n viewBox=\"0 0 20 20\"\n focusable=\"false\"\n className={className}\n >\n <path\n fill={fill}\n d=\"M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z\"\n />\n </svg>\n);\n\n/**\n * Configuration for action buttons in the floating bar\n */\nexport type ButtonConfig = {\n /** Button label text */\n label?: string;\n /** Icon element to display */\n icon: ReactNode;\n /** Click handler for the action */\n onClick?: () => void;\n /** Icon for dropdown mode */\n dropdownIcon?: ReactNode;\n /** Whether the action is visible */\n visible?: boolean;\n /** Whether the action is disabled */\n disabled?: boolean;\n /** Tooltip text */\n tooltip?: string;\n /** Whether to hide the label text */\n hideLabel?: boolean;\n /** Action type */\n type?: \"button\" | \"dropdown\";\n /** Dropdown trigger mode */\n dropdownTrigger?: \"click\" | \"hover\";\n /** Dropdown menu items */\n dropdownItems?: Array<{\n label: ReactNode;\n key: string;\n disabled?: boolean;\n }>;\n};\n\n/**\n * Props for the FloatingBar component\n */\nexport type TFloatingBar = {\n /** Whether the floating bar is visible */\n show?: boolean;\n /** Close handler */\n onClose: () => void;\n /** Whether this is used in flow dashboard layout */\n isFlowDashboard?: boolean;\n /** Array of action configurations */\n actionItems: ButtonConfig[];\n /** Number of selected items */\n selectedItemsCount?: number;\n /** Delete action configuration */\n deleteConfig?: {\n label?: string;\n disabled?: boolean;\n onClick?: () => void;\n };\n /** Whether to show action background */\n showActionBg?: boolean;\n};\n\n/**\n * FloatingBar component provides a floating action bar for bulk operations.\n * Drop-in replacement matching the lax-web-portal implementation.\n *\n * @example\n * ```tsx\n * <FloatingBar\n * show={selectedItems.length > 0}\n * onClose={() => setSelectedItems([])}\n * selectedItemsCount={selectedItems.length}\n * actionItems={[\n * {\n * label: \"Edit\",\n * icon: <EditIcon size={16} />,\n * onClick: handleEdit,\n * },\n * {\n * label: \"Archive\",\n * icon: <ArchiveIcon size={16} />,\n * onClick: handleArchive,\n * },\n * ]}\n * deleteConfig={{\n * label: \"Delete\",\n * onClick: handleDelete,\n * }}\n * />\n * ```\n */\nexport const FloatingBar: FC<TFloatingBar> = (props) => {\n const {\n show,\n isFlowDashboard,\n onClose,\n actionItems,\n selectedItemsCount,\n deleteConfig,\n showActionBg,\n } = props;\n\n const { t } = useTranslation();\n const [showDropdown, setShowDropdown] = useState<boolean>(false);\n const [showButtons, setShowButtons] = useState<boolean>(true);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const actionContainerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const observer = new ResizeObserver(() => {\n if (containerRef.current && actionContainerRef.current) {\n const containerWidth = containerRef.current.scrollWidth - 100;\n const totalActionItemsWidth = actionItems.length * 180 + 100;\n if (totalActionItemsWidth > containerWidth) {\n setShowButtons(false);\n } else {\n setShowButtons(true);\n }\n }\n });\n\n if (containerRef.current) {\n observer.observe(containerRef.current);\n }\n\n return () => {\n if (containerRef.current) {\n observer.unobserve(containerRef.current);\n }\n };\n });\n\n const deleteButtonConfig = {\n label: t(\"Delete\"),\n icon: <DeleteIcon className=\"text-error-700 w-icon h-icon\" />,\n color: \"text-error-700 dark:text-error-700\",\n onClick: deleteConfig?.onClick,\n ...deleteConfig,\n };\n\n /** Whether a button represents a destructive/delete action */\n const isDeleteAction = (button: ButtonConfig) => {\n const label = button.label?.toLowerCase() ?? \"\";\n return (\n label.includes(\"delete\") ||\n label === \"remove\" ||\n label === \"move to trash\"\n );\n };\n\n /** Delete actions are always displayed last (on the right) */\n const sortedActionItems = [...actionItems].sort(\n (a, b) => Number(isDeleteAction(a)) - Number(isDeleteAction(b))\n );\n\n /** Whether the action area has anything to render — avoids an empty pill */\n const hasActions =\n actionItems.some((button) => button.visible !== false) || Boolean(deleteConfig);\n\n const dropDownItems = actionItems\n .filter((button) => button.visible !== false)\n .map((button, index) => ({\n key: index,\n label: (\n <OptionButton\n icon={button.dropdownIcon}\n text={button?.label || \"\"}\n onClick={button.onClick}\n className=\"font-inter text-base font-medium text-black-900 dark:text-black-200 gap-1.5\"\n />\n ),\n children: button.dropdownItems,\n disabled: false,\n }));\n\n return !show ? null : (\n <motion.div\n initial={{ y: 20, opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n exit={{ y: 20, opacity: 0 }}\n transition={{\n duration: 0.2,\n ease: [0.4, 0, 0.2, 1],\n opacity: { duration: 0.15 },\n }}\n ref={containerRef}\n className={cn(\"h-[36px] mb-4\", isFlowDashboard ? \"ml-60 w-1/2\" : \"w-full\")}\n >\n <div\n className={cn(\n \"h-[36px] border-y border-neutral-900 dark:border-[#0d1014 px-[12px] text-white bg-neutral-900 dark:bg-black-900 flex justify-between items-center\"\n )}\n >\n <div className=\"flex items-center gap-[12px]\">\n <div className=\"flex items-center gap-[8px]\">\n <IconButton\n tooltip=\"Close\"\n variant=\"ghost\"\n onClick={onClose}\n className=\"!p-0 text-white hover:opacity-80 hover:rotate-90 transition-all duration-200\"\n >\n <CloseIcon size={16} />\n </IconButton>\n <div className=\"w-px h-[14px] rounded-[1px] bg-neutral-700 dark:bg-[#1d242c]\" />\n </div>\n <div className=\"flex items-center gap-[6px]\">\n <span className=\"inline-flex items-center justify-center min-w-[20px] h-[16px] px-[8px] rounded-[9px] border text-[12px] leading-[18px] font-normal text-primary-600 dark:text-primary-400 bg-primary-50 dark:bg-[rgba(0,50,95,0.3)] border-primary-200 dark:border-primary-800\">\n {selectedItemsCount || 0}\n </span>\n <Typography\n size=\"extra-small\"\n appearance=\"custom\"\n className=\"text-white dark:text-neutral-50\"\n >\n {t(\"Selected\")}\n </Typography>\n </div>\n </div>\n {hasActions ? (\n <div\n ref={actionContainerRef}\n className={cn(\n \"h-[36px] flex items-center font-inter bg-neutral-800 dark:bg-black-800 pl-[10px] rounded-[43px]\"\n )}\n >\n {showButtons ? (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.2 }}\n className=\"flex items-center h-[36px] bg-neutral-800 dark:bg-black-800 px-[10px] rounded-[43px]\"\n >\n {sortedActionItems.map(\n (button, index) =>\n button.visible !== false && (\n <div key={index}>\n {button.type === \"dropdown\" ? (\n <Dropdown\n menu={{\n items: button.dropdownItems,\n }}\n trigger={[button.dropdownTrigger || \"click\"]}\n overlayClassName=\"!min-w-[148px]\"\n placement=\"bottomRight\"\n getPopupContainer={(trigger) =>\n trigger.parentElement as HTMLElement\n }\n open={showDropdown}\n onOpenChange={setShowDropdown}\n >\n <button\n key={index}\n id={`btn-floating-bar-${button.label}`}\n onClick={button.onClick}\n disabled={button.disabled}\n className={cn(\n !button?.label\n ? \"bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80\"\n : \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent\",\n button?.hideLabel && \"!p-1.5\",\n isDeleteAction(button) && \"!text-error-500 dark:!text-error-700\",\n button.disabled && \"opacity-70\"\n )}\n >\n <Tooltip\n hideTooltip={!button.tooltip}\n title={button.tooltip}\n className=\"flex items-center gap-1.5\"\n >\n {button.icon}\n {!button?.hideLabel && button.label && (\n <Typography\n size=\"small\"\n variant=\"medium\"\n className={cn(\n \"text-inherit\",\n isDeleteAction(button) &&\n \"!text-error-500 dark:!text-error-700\"\n )}\n appearance=\"custom\"\n >\n {button.label}\n </Typography>\n )}\n </Tooltip>\n </button>\n </Dropdown>\n ) : (\n <button\n id={`btn-floating-bar-${button.label}`}\n onClick={button.onClick}\n disabled={button.disabled}\n className={cn(\n !button?.label\n ? \"bg-transparent p-1.5 rounded-xl transition-all duration-200 hover:scale-105 hover:opacity-80\"\n : \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] text-white dark:text-neutral-50 hover:opacity-80 hover:scale-105 transition-all duration-200 bg-transparent\",\n button?.hideLabel && \"!p-1.5\",\n isDeleteAction(button) && \"!text-error-500 dark:!text-error-700\",\n button.disabled && \"opacity-70\"\n )}\n >\n <Tooltip\n hideTooltip={!button.tooltip}\n title={button.tooltip}\n className=\"flex items-center gap-1.5\"\n >\n {button.icon}\n\n {!button?.hideLabel && button.label && (\n <Typography\n size=\"small\"\n variant=\"medium\"\n className={\"text-inherit\"}\n appearance=\"custom\"\n >\n {button.label}\n </Typography>\n )}\n </Tooltip>\n </button>\n )}\n </div>\n )\n )}\n {deleteConfig ? (\n <button\n id={`btn-floating-bar-${deleteButtonConfig.label}`}\n onClick={deleteButtonConfig.onClick}\n disabled={deleteButtonConfig.disabled}\n className={cn(\n \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200\",\n deleteButtonConfig.disabled && \"opacity-70\"\n )}\n >\n {deleteButtonConfig.icon}\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-error-700\"\n appearance=\"custom\"\n >\n {deleteButtonConfig.label}\n </Typography>\n </button>\n ) : null}\n </motion.div>\n ) : (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ duration: 0.2 }}\n className=\"minw-[150px] p-1.5 flex items-center\"\n >\n <Dropdown\n menu={{\n items: dropDownItems,\n }}\n trigger={[\"click\"]}\n overlayClassName=\"!min-w-[148px]\"\n placement=\"bottomRight\"\n getPopupContainer={(trigger) =>\n trigger.parentElement as HTMLElement\n }\n open={showDropdown}\n onOpenChange={setShowDropdown}\n >\n <button\n id={`btn-floating-bar-actions`}\n disabled={dropDownItems.length === 0}\n className={cn(\n \"flex items-center gap-1.5 px-2 py-1 w-22 h-7 rounded-full bg-[#34405473]/45 dark:bg-black-700 hover:scale-105 hover:opacity-80 transition-all duration-200\",\n dropDownItems.length === 0 &&\n \"opacity-60 hover:scale-100 hover:opacity-60\"\n )}\n type=\"button\"\n >\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-white\"\n >\n {t(\"Actions\")}\n </Typography>\n <DropdownArrowIcon\n fill=\"#FFFFFF\"\n className=\"w-[16px] h-[16px]\"\n />\n </button>\n </Dropdown>\n {deleteConfig ? (\n <button\n id={`btn-floating-bar-${deleteButtonConfig.label}`}\n onClick={deleteButtonConfig.onClick}\n disabled={deleteButtonConfig.disabled}\n className={cn(\n \"flex items-center gap-[6px] pl-[8px] pr-[12px] py-[4px] rounded-[6px] hover:scale-105 hover:opacity-80 transition-all duration-200\",\n deleteButtonConfig.disabled && \"opacity-70\"\n )}\n type=\"button\"\n >\n {deleteButtonConfig.icon}\n <Typography\n size=\"small\"\n variant=\"medium\"\n className=\"text-error-700\"\n appearance=\"custom\"\n >\n {deleteButtonConfig.label}\n </Typography>\n </button>\n ) : null}\n </motion.div>\n )}\n </div>\n ) : null}\n </div>\n </motion.div>\n );\n};\n\nFloatingBar.displayName = \"FloatingBar\";\n\n// Re-export types for convenience\nexport type { ButtonConfig as FloatingBarActionConfig };\nexport type FloatingBarDeleteConfig = TFloatingBar[\"deleteConfig\"];\nexport type FloatingBarProps = TFloatingBar;\n\n// Legacy type exports for backwards compatibility\nexport type FloatingBarSize = \"small\" | \"medium\" | \"large\";\nexport type FloatingBarPosition = \"top\" | \"bottom\";\nexport type FloatingBarTheme = \"primary\" | \"dark\" | \"light\";\n"],"names":["CloseIcon","size","fill","className","jsx","DropdownArrowIcon","FloatingBar","props","show","isFlowDashboard","onClose","actionItems","selectedItemsCount","deleteConfig","showActionBg","t","useTranslation","showDropdown","setShowDropdown","useState","showButtons","setShowButtons","containerRef","useRef","actionContainerRef","useEffect","observer","containerWidth","deleteButtonConfig","DeleteIcon","isDeleteAction","button","label","sortedActionItems","a","b","hasActions","dropDownItems","index","OptionButton","motion","cn","jsxs","IconButton","Typography","Dropdown","trigger","Tooltip"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),j=require("../../../_virtual/index.cjs.js"),f=require("react"),v=require("react-window"),N=require("@mui/icons-material"),I=require("@mui/material"),w=require("antd"),y=require("../../data-display/typography/Typography.cjs.js"),P=require("../input-field/InputField.cjs.js"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),j=require("../../../_virtual/index.cjs.js"),f=require("react"),v=require("react-window"),N=require("@mui/icons-material"),I=require("@mui/material"),w=require("antd"),y=require("../../data-display/typography/Typography.cjs.js"),P=require("../input-field/InputField.cjs.js"),x=require("../../../types/icon-picker.cjs.js"),q=require("../../../utils/countryFlags.cjs.js"),S=require("../shared/InputLabel.cjs.js"),R=require("../../icon/icons.generated.cjs.js");function O(e){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const a in e)if(a!=="default"){const s=Object.getOwnPropertyDescriptor(e,a);Object.defineProperty(n,a,s.get?s:{enumerable:!0,get:()=>e[a]})}}return n.default=e,Object.freeze(n)}const h=O(N),D=Object.keys(h).filter(e=>e?.endsWith("Rounded")),T=[...D||[],...(x.COUNTRY_CODES||[]).map(e=>`flag-${e}`)],L=e=>{if(e?.startsWith("flag-")){const n=e?.replace("flag-","");return x.countryNameFromCode(n||"")||n}return e.replaceAll(/([A-Z])/g," $1").trim()},F=({onChange:e,selectedIcon:n,setOpen:a})=>{const[s,p]=f.useState(""),c=(T||[]).filter(r=>{if(r?.startsWith("flag-")){const u=r?.replace("flag-","");return u?.toLowerCase()?.includes(s?.trim()?.toLowerCase()||"")||x.countryNameFromCode(u||"")?.toLowerCase()?.includes(s?.trim()?.toLowerCase()||"")}return r?.trim()?.toLowerCase()?.includes(s?.trim()?.toLowerCase()||"")}),m=(r,u)=>{if(u.stopPropagation(),n===r){e?.(null);return}e?.(r),a?.(!1)};return t.jsxs("div",{className:"flex flex-col gap-3",onKeyDown:r=>{r.key==="Enter"&&(r.preventDefault(),r.stopPropagation())},children:[t.jsx(P.InputField,{id:"input-field-icon-picker",placeholder:"Search icons...",onChange:r=>p(r||""),fieldSuffix:t.jsx(h.Search,{className:"!w-4 !h-4 text-neutral-400"})}),t.jsx(v.FixedSizeGrid,{columnCount:5,rowCount:Math.ceil((c?.length||0)/5),columnWidth:40,rowHeight:40,width:220,height:240,children:({columnIndex:r,rowIndex:u,style:l})=>{const g=u*5+r,i=c?.[g];return i?t.jsx("div",{style:l,className:"p-1",children:t.jsx(w.Tooltip,{title:L(i),placement:"bottom",children:t.jsx(I.IconButton,{type:"button",className:j("flex items-center justify-center !rounded-md hover:bg-neutral-200 dark:hover:bg-black-700",{"!bg-primary-50 dark:!bg-black-800":n===i}),onClick:d=>m(i,d),onKeyDown:d=>{d.key==="Enter"&&(d.preventDefault(),d.stopPropagation())},children:t.jsx(b,{iconName:i,className:"!w-5 !h-5 text-neutral-900 dark:text-white"})})})}):null}})]})},b=({iconName:e,sx:n,className:a,isHovering:s})=>{if(e?.startsWith?.("flag-")){const c=e?.replace("flag-","");return q.getFlagComponent?.(c||"",s||!1)||t.jsx("div",{children:"-"})}const p=h?.[e];return p?t.jsx(p,{sx:n,className:a,isHovering:s}):t.jsx("div",{children:"-"})},E=({selectedIcon:e,onChange:n,label:a,required:s=!1,allowClear:p=!0,disabled:c=!1,errorMessage:m,dropdownPosition:r="bottom",className:u})=>{const[l,g]=f.useState(!1),i=f.useRef(!1),d=f.useRef(null),k=f.useRef(!1);f.useEffect(()=>{k.current&&!l&&d.current?.focus(),k.current=l},[l]);const C=o=>{o.stopPropagation(),n?.("")};return t.jsx(w.Popover,{arrow:!1,placement:r,trigger:"click",getPopupContainer:o=>o?.parentElement||document.body,open:l,onOpenChange:o=>{o?(i.current&&g(!0),i.current=!1):g(!1)},content:t.jsx(F,{onChange:n,selectedIcon:e,setOpen:g}),children:t.jsxs("div",{className:"flex flex-col gap-1",children:[a?t.jsx(S.InputLabel,{label:a||"",required:s||!1}):null,t.jsxs("button",{ref:d,type:"button",id:`btn-icon-picker-icon-${e?"selected":"unselected"}`,className:`lax-form-trigger min-w-[83px] h-8 py-1.5 px-3 rounded-md border ${c?"cursor-not-allowed opacity-60 bg-neutral-50 dark:bg-black-800":"bg-white dark:bg-black-800"} ${m?"border-red-500":"focus:border-primary-600 dark:focus:border-primary-400"} flex items-center justify-between gap-2 ${u}`,disabled:c,"aria-haspopup":"dialog","aria-expanded":l,onClick:o=>{if(c){o.preventDefault(),o.stopPropagation();return}o.detail>0&&(i.current=!0)},onKeyDown:o=>{o.key==="Enter"&&(o.preventDefault(),l||o.currentTarget.closest("form")?.querySelector('button[type="submit"]')?.click())},children:[e?t.jsx(b,{iconName:e,className:"!w-5 !h-5 text-neutral-900 dark:text-white"}):t.jsx(y.Typography,{size:"small",variant:"regular",appearance:"subtitle",children:"Select Icon"}),t.jsxs("span",{className:"flex shrink-0 items-center gap-1",children:[e&&p&&!c?t.jsx(h.CloseRounded,{className:"!w-5 !h-5 hover:bg-neutral-100 dark:hover:bg-black-800 rounded-full transition-colors cursor-pointer text-neutral-400 dark:text-neutral-500",onClick:C}):null,t.jsx(R.KeyboardArrowDownIcon,{className:j("h-4 w-4 shrink-0 text-neutral-400 transition-transform duration-200",{"rotate-180":l})})]})]}),m&&t.jsx(y.Typography,{size:"extra-small",className:"text-red-500 font-medium",children:m})]})})},W=f.lazy(()=>Promise.resolve({default:e=>t.jsx(f.Suspense,{fallback:t.jsx("div",{className:"min-w-20 h-8 animate-pulse bg-neutral-100 dark:bg-black-800 rounded-md"}),children:t.jsx(E,{...e})})}));exports.IconPicker=W;exports.IconRenderer=b;
|
|
2
2
|
//# sourceMappingURL=IconPicker.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconPicker.cjs.js","sources":["../../../../src/components/forms/icon-picker/IconPicker.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport React, { Suspense, useEffect, useRef, useState } from 'react';\nimport { FixedSizeGrid, type GridChildComponentProps } from 'react-window';\nimport * as AllIcons from '@mui/icons-material';\nimport { IconButton, type SvgIconOwnProps } from '@mui/material';\nimport { Popover, Tooltip } from \"antd\";\nimport { Typography } from \"../../data-display/typography/Typography\";\nimport { InputField } from \"../input-field/InputField\";\nimport { COUNTRY_CODES, countryNameFromCode } from \"../../../types/icon-picker\";\nimport { getFlagComponent } from \"../../../utils/countryFlags\";\nimport { KeyboardArrowDownIcon } from \"../../icon\";\nimport { InputLabel } from '../shared/InputLabel';\n\nconst roundedIconNames = Object.keys(AllIcons).filter((name) =>\n name?.endsWith(\"Rounded\")\n);\n\n// Merge icon names and country codes for the picker\nconst mergedIconNames = [\n ...(roundedIconNames || []),\n ...(COUNTRY_CODES || []).map((code) => `flag-${code}`),\n];\n\n// Utility function to convert camelCase to human-readable format\nconst formatIconName = (iconName: string): string => {\n // Handle flag icons\n if (iconName?.startsWith(\"flag-\")) {\n const code = iconName?.replace(\"flag-\", \"\");\n return countryNameFromCode(code || \"\") || code;\n }\n\n // Convert camelCase to space-separated words\n // e.g., \"PersonRounded\" -> \"Person Rounded\"\n return iconName.replaceAll(/([A-Z])/g, \" $1\").trim();\n};\n\n/** Ant Design `Popover` placement for the icon panel (bottom edge of the trigger). */\nexport type IconPickerDropdownPosition = 'bottom' | 'bottomLeft' | 'bottomRight';\n\nexport interface IconPickerContentProps {\n selectedIcon: string | null;\n onChange: (iconName: string | null) => void;\n label?: string;\n required?: boolean;\n allowClear?: boolean;\n disabled?: boolean;\n errorMessage?: string;\n /** Popover placement: `bottom` | `bottomLeft` | `bottomRight`. Default: `bottom`. */\n dropdownPosition?: IconPickerDropdownPosition;\n className?: string\n}\n\ninterface IconPickerContentInternalProps {\n onChange: (iconName: string | null) => void;\n selectedIcon: string | null;\n setOpen?: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\nconst IconPickerContent = ({\n onChange,\n selectedIcon,\n setOpen,\n}: IconPickerContentInternalProps) => {\n const [searchTerm, setSearchTerm] = useState<string>(\"\");\n\n // Filter both icons and flags\n const filteredIcons = (mergedIconNames || []).filter((name) => {\n if (name?.startsWith(\"flag-\")) {\n // For flags, allow search by country code or country name\n const code = name?.replace(\"flag-\", \"\");\n return (\n code\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\") ||\n countryNameFromCode(code || \"\")\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\")\n );\n }\n return name\n ?.trim()\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\");\n });\n\n const handleClick = (icon: string, event: React.MouseEvent) => {\n event.stopPropagation();\n if (selectedIcon === icon) {\n onChange?.(null);\n return;\n }\n onChange?.(icon);\n setOpen?.(false);\n };\n\n return (\n <div \n className=\"flex flex-col gap-3\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n }\n }}\n >\n <InputField\n id={`input-field-icon-picker`}\n placeholder=\"Search icons...\"\n onChange={(value) => setSearchTerm(value || \"\")}\n fieldSuffix={\n <AllIcons.Search className=\"!w-4 !h-4 text-neutral-400\" />\n }\n />\n <FixedSizeGrid\n columnCount={5}\n rowCount={Math.ceil((filteredIcons?.length || 0) / 5)}\n columnWidth={40}\n rowHeight={40}\n width={220}\n height={240}\n >\n {({ columnIndex, rowIndex, style }: GridChildComponentProps) => {\n const itemIndex = rowIndex * 5 + columnIndex;\n const iconName = filteredIcons?.[itemIndex];\n return iconName ? (\n <div style={style} className=\"p-1\">\n <Tooltip title={formatIconName(iconName)} placement='bottom'>\n <IconButton\n type='button'\n className={classNames(\n \"flex items-center justify-center !rounded-md hover:bg-neutral-200 dark:hover:bg-black-700\",\n {\n \"!bg-primary-50 dark:!bg-black-800\":\n selectedIcon === iconName,\n }\n )}\n onClick={(event) => handleClick(iconName, event)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n }\n }}\n >\n <IconRenderer\n iconName={iconName}\n className=\"!w-5 !h-5 text-neutral-900 dark:text-white\"\n />\n </IconButton>\n </Tooltip>\n </div>\n ) : null;\n }}\n </FixedSizeGrid>\n </div>\n );\n};\n\ninterface IconRendererProps {\n iconName: string;\n sx?: SvgIconOwnProps['sx'];\n className?: string;\n isHovering?: boolean;\n}\n\nexport const IconRenderer = ({ iconName, sx, className, isHovering }: IconRendererProps) => {\n // Render flag if iconName starts with 'flag-'\n if (iconName?.startsWith?.('flag-')) {\n const code = iconName?.replace('flag-', '');\n return getFlagComponent?.(code || '', isHovering || false) || <div>-</div>;\n }\n const Icon = AllIcons?.[iconName as keyof typeof AllIcons] as React.ComponentType<{\n sx?: SvgIconOwnProps['sx'];\n className?: string;\n isHovering?: boolean;\n }>;\n\n if (!Icon) {\n return <div>-</div>;\n }\n\n return <Icon sx={sx} className={className} isHovering={isHovering} />;\n};\n\nconst IconPickerBase = ({\n selectedIcon,\n onChange,\n label,\n required = false,\n allowClear = true,\n disabled = false,\n errorMessage,\n dropdownPosition = 'bottom',\n className\n}: IconPickerContentProps) => {\n const [open, setOpen] = useState(false);\n const mouseClickRef = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const wasOpenRef = useRef(false);\n\n useEffect(() => {\n if (wasOpenRef.current && !open) {\n buttonRef.current?.focus();\n }\n wasOpenRef.current = open;\n }, [open]);\n const handleClearIcon = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange?.('');\n };\n\n return (\n <Popover\n arrow={false}\n placement={dropdownPosition}\n trigger='click'\n getPopupContainer={(triggerNode) => triggerNode?.parentElement || document.body}\n open={open}\n onOpenChange={(newOpen) => {\n if (newOpen) {\n if (mouseClickRef.current) {\n setOpen(true);\n }\n mouseClickRef.current = false;\n } else {\n setOpen(false);\n }\n }}\n content={<IconPickerContent onChange={onChange} selectedIcon={selectedIcon} setOpen={setOpen} />}\n >\n <div className='flex flex-col gap-1'>\n {label ? (\n <InputLabel label={label || \"\"} required={required || false} />\n ) : null}\n <button\n ref={buttonRef}\n type='button'\n id={`btn-icon-picker-icon-${selectedIcon ? 'selected' : 'unselected'}`}\n className={`lax-form-trigger min-w-[83px] h-8 py-1.5 px-3 rounded-md border ${\n disabled ? 'cursor-not-allowed opacity-60 bg-neutral-50 dark:bg-black-800' : 'bg-white dark:bg-black-800'\n } ${errorMessage ? 'border-red-500' : 'focus:border-primary-600 dark:focus:border-primary-400'} flex items-center justify-between gap-2 ${className}`}\n disabled={disabled}\n aria-haspopup='dialog'\n aria-expanded={open}\n onClick={(e) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (e.detail > 0) {\n mouseClickRef.current = true;\n }\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n if (!open) {\n const form = (e.currentTarget as HTMLElement).closest('form');\n const submitBtn = form?.querySelector('button[type=\"submit\"]') as HTMLButtonElement | null;\n submitBtn?.click();\n }\n }\n }}\n >\n {selectedIcon ? (\n <IconRenderer iconName={selectedIcon} className='!w-5 !h-5 text-neutral-900 dark:text-white' />\n ) : (\n <Typography\n size='small'\n variant='regular'\n appearance='subtitle'\n >\n Select Icon\n </Typography>\n )}\n <span className='flex shrink-0 items-center gap-1'>\n {selectedIcon && allowClear && !disabled ? (\n <AllIcons.CloseRounded\n className='!w-5 !h-5 hover:bg-neutral-100 dark:hover:bg-black-800 rounded-full transition-colors cursor-pointer text-neutral-400 dark:text-neutral-500'\n onClick={handleClearIcon}\n />\n ) : (\n null\n )}\n <KeyboardArrowDownIcon\n size={16}\n className={classNames(\n 'shrink-0 text-neutral-400 dark:text-neutral-500 transition-transform duration-200',\n { 'rotate-180': open }\n )}\n />\n </span>\n </button>\n {errorMessage && (\n <Typography size='extra-small' className='text-red-500 font-medium'>\n {errorMessage}\n </Typography>\n )}\n </div>\n </Popover>\n );\n};\n\nexport const IconPicker = React.lazy(() =>\n Promise.resolve({\n default: (props: IconPickerContentProps) => (\n <Suspense fallback={<div className='min-w-20 h-8 animate-pulse bg-neutral-100 dark:bg-black-800 rounded-md' />}>\n <IconPickerBase {...props} />\n </Suspense>\n ),\n }),\n);\n\n"],"names":["roundedIconNames","AllIcons","name","mergedIconNames","COUNTRY_CODES","code","formatIconName","iconName","countryNameFromCode","IconPickerContent","onChange","selectedIcon","setOpen","searchTerm","setSearchTerm","useState","filteredIcons","handleClick","icon","event","jsxs","e","jsx","InputField","value","FixedSizeGrid","columnIndex","rowIndex","style","itemIndex","Tooltip","IconButton","classNames","IconRenderer","sx","className","isHovering","getFlagComponent","Icon","IconPickerBase","label","required","allowClear","disabled","errorMessage","dropdownPosition","open","mouseClickRef","useRef","buttonRef","wasOpenRef","useEffect","handleClearIcon","Popover","triggerNode","newOpen","InputLabel","Typography","KeyboardArrowDownIcon","IconPicker","React","props","Suspense"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IconPicker.cjs.js","sources":["../../../../src/components/forms/icon-picker/IconPicker.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport React, { Suspense, useEffect, useRef, useState } from 'react';\nimport { FixedSizeGrid, type GridChildComponentProps } from 'react-window';\nimport * as AllIcons from '@mui/icons-material';\nimport { IconButton, type SvgIconOwnProps } from '@mui/material';\nimport { Popover, Tooltip } from \"antd\";\nimport { Typography } from \"../../data-display/typography/Typography\";\nimport { InputField } from \"../input-field/InputField\";\nimport { COUNTRY_CODES, countryNameFromCode } from \"../../../types/icon-picker\";\nimport { getFlagComponent } from \"../../../utils/countryFlags\";\nimport { KeyboardArrowDownIcon } from \"../../icon\";\nimport { InputLabel } from '../shared/InputLabel';\n\nconst roundedIconNames = Object.keys(AllIcons).filter((name) =>\n name?.endsWith(\"Rounded\")\n);\n\n// Merge icon names and country codes for the picker\nconst mergedIconNames = [\n ...(roundedIconNames || []),\n ...(COUNTRY_CODES || []).map((code) => `flag-${code}`),\n];\n\n// Utility function to convert camelCase to human-readable format\nconst formatIconName = (iconName: string): string => {\n // Handle flag icons\n if (iconName?.startsWith(\"flag-\")) {\n const code = iconName?.replace(\"flag-\", \"\");\n return countryNameFromCode(code || \"\") || code;\n }\n\n // Convert camelCase to space-separated words\n // e.g., \"PersonRounded\" -> \"Person Rounded\"\n return iconName.replaceAll(/([A-Z])/g, \" $1\").trim();\n};\n\n/** Ant Design `Popover` placement for the icon panel (bottom edge of the trigger). */\nexport type IconPickerDropdownPosition = 'bottom' | 'bottomLeft' | 'bottomRight';\n\nexport interface IconPickerContentProps {\n selectedIcon: string | null;\n onChange: (iconName: string | null) => void;\n label?: string;\n required?: boolean;\n allowClear?: boolean;\n disabled?: boolean;\n errorMessage?: string;\n /** Popover placement: `bottom` | `bottomLeft` | `bottomRight`. Default: `bottom`. */\n dropdownPosition?: IconPickerDropdownPosition;\n className?: string\n}\n\ninterface IconPickerContentInternalProps {\n onChange: (iconName: string | null) => void;\n selectedIcon: string | null;\n setOpen?: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\nconst IconPickerContent = ({\n onChange,\n selectedIcon,\n setOpen,\n}: IconPickerContentInternalProps) => {\n const [searchTerm, setSearchTerm] = useState<string>(\"\");\n\n // Filter both icons and flags\n const filteredIcons = (mergedIconNames || []).filter((name) => {\n if (name?.startsWith(\"flag-\")) {\n // For flags, allow search by country code or country name\n const code = name?.replace(\"flag-\", \"\");\n return (\n code\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\") ||\n countryNameFromCode(code || \"\")\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\")\n );\n }\n return name\n ?.trim()\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\");\n });\n\n const handleClick = (icon: string, event: React.MouseEvent) => {\n event.stopPropagation();\n if (selectedIcon === icon) {\n onChange?.(null);\n return;\n }\n onChange?.(icon);\n setOpen?.(false);\n };\n\n return (\n <div \n className=\"flex flex-col gap-3\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n }\n }}\n >\n <InputField\n id={`input-field-icon-picker`}\n placeholder=\"Search icons...\"\n onChange={(value) => setSearchTerm(value || \"\")}\n fieldSuffix={\n <AllIcons.Search className=\"!w-4 !h-4 text-neutral-400\" />\n }\n />\n <FixedSizeGrid\n columnCount={5}\n rowCount={Math.ceil((filteredIcons?.length || 0) / 5)}\n columnWidth={40}\n rowHeight={40}\n width={220}\n height={240}\n >\n {({ columnIndex, rowIndex, style }: GridChildComponentProps) => {\n const itemIndex = rowIndex * 5 + columnIndex;\n const iconName = filteredIcons?.[itemIndex];\n return iconName ? (\n <div style={style} className=\"p-1\">\n <Tooltip title={formatIconName(iconName)} placement='bottom'>\n <IconButton\n type='button'\n className={classNames(\n \"flex items-center justify-center !rounded-md hover:bg-neutral-200 dark:hover:bg-black-700\",\n {\n \"!bg-primary-50 dark:!bg-black-800\":\n selectedIcon === iconName,\n }\n )}\n onClick={(event) => handleClick(iconName, event)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n }\n }}\n >\n <IconRenderer\n iconName={iconName}\n className=\"!w-5 !h-5 text-neutral-900 dark:text-white\"\n />\n </IconButton>\n </Tooltip>\n </div>\n ) : null;\n }}\n </FixedSizeGrid>\n </div>\n );\n};\n\ninterface IconRendererProps {\n iconName: string;\n sx?: SvgIconOwnProps['sx'];\n className?: string;\n isHovering?: boolean;\n}\n\nexport const IconRenderer = ({ iconName, sx, className, isHovering }: IconRendererProps) => {\n // Render flag if iconName starts with 'flag-'\n if (iconName?.startsWith?.('flag-')) {\n const code = iconName?.replace('flag-', '');\n return getFlagComponent?.(code || '', isHovering || false) || <div>-</div>;\n }\n const Icon = AllIcons?.[iconName as keyof typeof AllIcons] as React.ComponentType<{\n sx?: SvgIconOwnProps['sx'];\n className?: string;\n isHovering?: boolean;\n }>;\n\n if (!Icon) {\n return <div>-</div>;\n }\n\n return <Icon sx={sx} className={className} isHovering={isHovering} />;\n};\n\nconst IconPickerBase = ({\n selectedIcon,\n onChange,\n label,\n required = false,\n allowClear = true,\n disabled = false,\n errorMessage,\n dropdownPosition = 'bottom',\n className\n}: IconPickerContentProps) => {\n const [open, setOpen] = useState(false);\n const mouseClickRef = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const wasOpenRef = useRef(false);\n\n useEffect(() => {\n if (wasOpenRef.current && !open) {\n buttonRef.current?.focus();\n }\n wasOpenRef.current = open;\n }, [open]);\n const handleClearIcon = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange?.('');\n };\n\n return (\n <Popover\n arrow={false}\n placement={dropdownPosition}\n trigger='click'\n getPopupContainer={(triggerNode) => triggerNode?.parentElement || document.body}\n open={open}\n onOpenChange={(newOpen) => {\n if (newOpen) {\n if (mouseClickRef.current) {\n setOpen(true);\n }\n mouseClickRef.current = false;\n } else {\n setOpen(false);\n }\n }}\n content={<IconPickerContent onChange={onChange} selectedIcon={selectedIcon} setOpen={setOpen} />}\n >\n <div className='flex flex-col gap-1'>\n {label ? (\n <InputLabel label={label || \"\"} required={required || false} />\n ) : null}\n <button\n ref={buttonRef}\n type='button'\n id={`btn-icon-picker-icon-${selectedIcon ? 'selected' : 'unselected'}`}\n className={`lax-form-trigger min-w-[83px] h-8 py-1.5 px-3 rounded-md border ${\n disabled ? 'cursor-not-allowed opacity-60 bg-neutral-50 dark:bg-black-800' : 'bg-white dark:bg-black-800'\n } ${errorMessage ? 'border-red-500' : 'focus:border-primary-600 dark:focus:border-primary-400'} flex items-center justify-between gap-2 ${className}`}\n disabled={disabled}\n aria-haspopup='dialog'\n aria-expanded={open}\n onClick={(e) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (e.detail > 0) {\n mouseClickRef.current = true;\n }\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n if (!open) {\n const form = (e.currentTarget as HTMLElement).closest('form');\n const submitBtn = form?.querySelector('button[type=\"submit\"]') as HTMLButtonElement | null;\n submitBtn?.click();\n }\n }\n }}\n >\n {selectedIcon ? (\n <IconRenderer iconName={selectedIcon} className='!w-5 !h-5 text-neutral-900 dark:text-white' />\n ) : (\n <Typography\n size='small'\n variant='regular'\n appearance='subtitle'\n >\n Select Icon\n </Typography>\n )}\n <span className='flex shrink-0 items-center gap-1'>\n {selectedIcon && allowClear && !disabled ? (\n <AllIcons.CloseRounded\n className='!w-5 !h-5 hover:bg-neutral-100 dark:hover:bg-black-800 rounded-full transition-colors cursor-pointer text-neutral-400 dark:text-neutral-500'\n onClick={handleClearIcon}\n />\n ) : (\n null\n )}\n <KeyboardArrowDownIcon\n className={classNames(\n 'h-4 w-4 shrink-0 text-neutral-400 transition-transform duration-200',\n { 'rotate-180': open }\n )}\n />\n </span>\n </button>\n {errorMessage && (\n <Typography size='extra-small' className='text-red-500 font-medium'>\n {errorMessage}\n </Typography>\n )}\n </div>\n </Popover>\n );\n};\n\nexport const IconPicker = React.lazy(() =>\n Promise.resolve({\n default: (props: IconPickerContentProps) => (\n <Suspense fallback={<div className='min-w-20 h-8 animate-pulse bg-neutral-100 dark:bg-black-800 rounded-md' />}>\n <IconPickerBase {...props} />\n </Suspense>\n ),\n }),\n);\n\n"],"names":["roundedIconNames","AllIcons","name","mergedIconNames","COUNTRY_CODES","code","formatIconName","iconName","countryNameFromCode","IconPickerContent","onChange","selectedIcon","setOpen","searchTerm","setSearchTerm","useState","filteredIcons","handleClick","icon","event","jsxs","e","jsx","InputField","value","FixedSizeGrid","columnIndex","rowIndex","style","itemIndex","Tooltip","IconButton","classNames","IconRenderer","sx","className","isHovering","getFlagComponent","Icon","IconPickerBase","label","required","allowClear","disabled","errorMessage","dropdownPosition","open","mouseClickRef","useRef","buttonRef","wasOpenRef","useEffect","handleClearIcon","Popover","triggerNode","newOpen","InputLabel","Typography","KeyboardArrowDownIcon","IconPicker","React","props","Suspense"],"mappings":"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"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { jsx as t, jsxs as h } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
2
|
+
import x from "../../../_virtual/index.es.js";
|
|
3
3
|
import I, { Suspense as P, useState as y, useRef as b, useEffect as S } from "react";
|
|
4
4
|
import { FixedSizeGrid as D } from "react-window";
|
|
5
5
|
import * as g from "@mui/icons-material";
|
|
6
6
|
import { IconButton as R } from "@mui/material";
|
|
7
7
|
import { Popover as L, Tooltip as E } from "antd";
|
|
8
|
-
import { Typography as
|
|
8
|
+
import { Typography as w } from "../../data-display/typography/Typography.es.js";
|
|
9
9
|
import { InputField as O } from "../input-field/InputField.es.js";
|
|
10
10
|
import { COUNTRY_CODES as T, countryNameFromCode as C } from "../../../types/icon-picker.es.js";
|
|
11
11
|
import { getFlagComponent as $ } from "../../../utils/countryFlags.es.js";
|
|
12
12
|
import { InputLabel as j } from "../shared/InputLabel.es.js";
|
|
13
|
-
import { KeyboardArrowDownIcon as
|
|
14
|
-
const
|
|
13
|
+
import { KeyboardArrowDownIcon as W } from "../../icon/icons.generated.es.js";
|
|
14
|
+
const z = Object.keys(g).filter(
|
|
15
15
|
(e) => e?.endsWith("Rounded")
|
|
16
16
|
), A = [
|
|
17
|
-
...
|
|
17
|
+
...z || [],
|
|
18
18
|
...(T || []).map((e) => `flag-${e}`)
|
|
19
19
|
], B = (e) => {
|
|
20
20
|
if (e?.startsWith("flag-")) {
|
|
@@ -72,7 +72,7 @@ const W = Object.keys(g).filter(
|
|
|
72
72
|
R,
|
|
73
73
|
{
|
|
74
74
|
type: "button",
|
|
75
|
-
className:
|
|
75
|
+
className: x(
|
|
76
76
|
"flex items-center justify-center !rounded-md hover:bg-neutral-200 dark:hover:bg-black-700",
|
|
77
77
|
{
|
|
78
78
|
"!bg-primary-50 dark:!bg-black-800": n === i
|
|
@@ -158,7 +158,7 @@ const W = Object.keys(g).filter(
|
|
|
158
158
|
},
|
|
159
159
|
children: [
|
|
160
160
|
e ? /* @__PURE__ */ t(v, { iconName: e, className: "!w-5 !h-5 text-neutral-900 dark:text-white" }) : /* @__PURE__ */ t(
|
|
161
|
-
|
|
161
|
+
w,
|
|
162
162
|
{
|
|
163
163
|
size: "small",
|
|
164
164
|
variant: "regular",
|
|
@@ -175,11 +175,10 @@ const W = Object.keys(g).filter(
|
|
|
175
175
|
}
|
|
176
176
|
) : null,
|
|
177
177
|
/* @__PURE__ */ t(
|
|
178
|
-
|
|
178
|
+
W,
|
|
179
179
|
{
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
"shrink-0 text-neutral-400 dark:text-neutral-500 transition-transform duration-200",
|
|
180
|
+
className: x(
|
|
181
|
+
"h-4 w-4 shrink-0 text-neutral-400 transition-transform duration-200",
|
|
183
182
|
{ "rotate-180": l }
|
|
184
183
|
)
|
|
185
184
|
}
|
|
@@ -188,7 +187,7 @@ const W = Object.keys(g).filter(
|
|
|
188
187
|
]
|
|
189
188
|
}
|
|
190
189
|
),
|
|
191
|
-
d && /* @__PURE__ */ t(
|
|
190
|
+
d && /* @__PURE__ */ t(w, { size: "extra-small", className: "text-red-500 font-medium", children: d })
|
|
192
191
|
] })
|
|
193
192
|
}
|
|
194
193
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconPicker.es.js","sources":["../../../../src/components/forms/icon-picker/IconPicker.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport React, { Suspense, useEffect, useRef, useState } from 'react';\nimport { FixedSizeGrid, type GridChildComponentProps } from 'react-window';\nimport * as AllIcons from '@mui/icons-material';\nimport { IconButton, type SvgIconOwnProps } from '@mui/material';\nimport { Popover, Tooltip } from \"antd\";\nimport { Typography } from \"../../data-display/typography/Typography\";\nimport { InputField } from \"../input-field/InputField\";\nimport { COUNTRY_CODES, countryNameFromCode } from \"../../../types/icon-picker\";\nimport { getFlagComponent } from \"../../../utils/countryFlags\";\nimport { KeyboardArrowDownIcon } from \"../../icon\";\nimport { InputLabel } from '../shared/InputLabel';\n\nconst roundedIconNames = Object.keys(AllIcons).filter((name) =>\n name?.endsWith(\"Rounded\")\n);\n\n// Merge icon names and country codes for the picker\nconst mergedIconNames = [\n ...(roundedIconNames || []),\n ...(COUNTRY_CODES || []).map((code) => `flag-${code}`),\n];\n\n// Utility function to convert camelCase to human-readable format\nconst formatIconName = (iconName: string): string => {\n // Handle flag icons\n if (iconName?.startsWith(\"flag-\")) {\n const code = iconName?.replace(\"flag-\", \"\");\n return countryNameFromCode(code || \"\") || code;\n }\n\n // Convert camelCase to space-separated words\n // e.g., \"PersonRounded\" -> \"Person Rounded\"\n return iconName.replaceAll(/([A-Z])/g, \" $1\").trim();\n};\n\n/** Ant Design `Popover` placement for the icon panel (bottom edge of the trigger). */\nexport type IconPickerDropdownPosition = 'bottom' | 'bottomLeft' | 'bottomRight';\n\nexport interface IconPickerContentProps {\n selectedIcon: string | null;\n onChange: (iconName: string | null) => void;\n label?: string;\n required?: boolean;\n allowClear?: boolean;\n disabled?: boolean;\n errorMessage?: string;\n /** Popover placement: `bottom` | `bottomLeft` | `bottomRight`. Default: `bottom`. */\n dropdownPosition?: IconPickerDropdownPosition;\n className?: string\n}\n\ninterface IconPickerContentInternalProps {\n onChange: (iconName: string | null) => void;\n selectedIcon: string | null;\n setOpen?: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\nconst IconPickerContent = ({\n onChange,\n selectedIcon,\n setOpen,\n}: IconPickerContentInternalProps) => {\n const [searchTerm, setSearchTerm] = useState<string>(\"\");\n\n // Filter both icons and flags\n const filteredIcons = (mergedIconNames || []).filter((name) => {\n if (name?.startsWith(\"flag-\")) {\n // For flags, allow search by country code or country name\n const code = name?.replace(\"flag-\", \"\");\n return (\n code\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\") ||\n countryNameFromCode(code || \"\")\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\")\n );\n }\n return name\n ?.trim()\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\");\n });\n\n const handleClick = (icon: string, event: React.MouseEvent) => {\n event.stopPropagation();\n if (selectedIcon === icon) {\n onChange?.(null);\n return;\n }\n onChange?.(icon);\n setOpen?.(false);\n };\n\n return (\n <div \n className=\"flex flex-col gap-3\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n }\n }}\n >\n <InputField\n id={`input-field-icon-picker`}\n placeholder=\"Search icons...\"\n onChange={(value) => setSearchTerm(value || \"\")}\n fieldSuffix={\n <AllIcons.Search className=\"!w-4 !h-4 text-neutral-400\" />\n }\n />\n <FixedSizeGrid\n columnCount={5}\n rowCount={Math.ceil((filteredIcons?.length || 0) / 5)}\n columnWidth={40}\n rowHeight={40}\n width={220}\n height={240}\n >\n {({ columnIndex, rowIndex, style }: GridChildComponentProps) => {\n const itemIndex = rowIndex * 5 + columnIndex;\n const iconName = filteredIcons?.[itemIndex];\n return iconName ? (\n <div style={style} className=\"p-1\">\n <Tooltip title={formatIconName(iconName)} placement='bottom'>\n <IconButton\n type='button'\n className={classNames(\n \"flex items-center justify-center !rounded-md hover:bg-neutral-200 dark:hover:bg-black-700\",\n {\n \"!bg-primary-50 dark:!bg-black-800\":\n selectedIcon === iconName,\n }\n )}\n onClick={(event) => handleClick(iconName, event)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n }\n }}\n >\n <IconRenderer\n iconName={iconName}\n className=\"!w-5 !h-5 text-neutral-900 dark:text-white\"\n />\n </IconButton>\n </Tooltip>\n </div>\n ) : null;\n }}\n </FixedSizeGrid>\n </div>\n );\n};\n\ninterface IconRendererProps {\n iconName: string;\n sx?: SvgIconOwnProps['sx'];\n className?: string;\n isHovering?: boolean;\n}\n\nexport const IconRenderer = ({ iconName, sx, className, isHovering }: IconRendererProps) => {\n // Render flag if iconName starts with 'flag-'\n if (iconName?.startsWith?.('flag-')) {\n const code = iconName?.replace('flag-', '');\n return getFlagComponent?.(code || '', isHovering || false) || <div>-</div>;\n }\n const Icon = AllIcons?.[iconName as keyof typeof AllIcons] as React.ComponentType<{\n sx?: SvgIconOwnProps['sx'];\n className?: string;\n isHovering?: boolean;\n }>;\n\n if (!Icon) {\n return <div>-</div>;\n }\n\n return <Icon sx={sx} className={className} isHovering={isHovering} />;\n};\n\nconst IconPickerBase = ({\n selectedIcon,\n onChange,\n label,\n required = false,\n allowClear = true,\n disabled = false,\n errorMessage,\n dropdownPosition = 'bottom',\n className\n}: IconPickerContentProps) => {\n const [open, setOpen] = useState(false);\n const mouseClickRef = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const wasOpenRef = useRef(false);\n\n useEffect(() => {\n if (wasOpenRef.current && !open) {\n buttonRef.current?.focus();\n }\n wasOpenRef.current = open;\n }, [open]);\n const handleClearIcon = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange?.('');\n };\n\n return (\n <Popover\n arrow={false}\n placement={dropdownPosition}\n trigger='click'\n getPopupContainer={(triggerNode) => triggerNode?.parentElement || document.body}\n open={open}\n onOpenChange={(newOpen) => {\n if (newOpen) {\n if (mouseClickRef.current) {\n setOpen(true);\n }\n mouseClickRef.current = false;\n } else {\n setOpen(false);\n }\n }}\n content={<IconPickerContent onChange={onChange} selectedIcon={selectedIcon} setOpen={setOpen} />}\n >\n <div className='flex flex-col gap-1'>\n {label ? (\n <InputLabel label={label || \"\"} required={required || false} />\n ) : null}\n <button\n ref={buttonRef}\n type='button'\n id={`btn-icon-picker-icon-${selectedIcon ? 'selected' : 'unselected'}`}\n className={`lax-form-trigger min-w-[83px] h-8 py-1.5 px-3 rounded-md border ${\n disabled ? 'cursor-not-allowed opacity-60 bg-neutral-50 dark:bg-black-800' : 'bg-white dark:bg-black-800'\n } ${errorMessage ? 'border-red-500' : 'focus:border-primary-600 dark:focus:border-primary-400'} flex items-center justify-between gap-2 ${className}`}\n disabled={disabled}\n aria-haspopup='dialog'\n aria-expanded={open}\n onClick={(e) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (e.detail > 0) {\n mouseClickRef.current = true;\n }\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n if (!open) {\n const form = (e.currentTarget as HTMLElement).closest('form');\n const submitBtn = form?.querySelector('button[type=\"submit\"]') as HTMLButtonElement | null;\n submitBtn?.click();\n }\n }\n }}\n >\n {selectedIcon ? (\n <IconRenderer iconName={selectedIcon} className='!w-5 !h-5 text-neutral-900 dark:text-white' />\n ) : (\n <Typography\n size='small'\n variant='regular'\n appearance='subtitle'\n >\n Select Icon\n </Typography>\n )}\n <span className='flex shrink-0 items-center gap-1'>\n {selectedIcon && allowClear && !disabled ? (\n <AllIcons.CloseRounded\n className='!w-5 !h-5 hover:bg-neutral-100 dark:hover:bg-black-800 rounded-full transition-colors cursor-pointer text-neutral-400 dark:text-neutral-500'\n onClick={handleClearIcon}\n />\n ) : (\n null\n )}\n <KeyboardArrowDownIcon\n size={16}\n className={classNames(\n 'shrink-0 text-neutral-400 dark:text-neutral-500 transition-transform duration-200',\n { 'rotate-180': open }\n )}\n />\n </span>\n </button>\n {errorMessage && (\n <Typography size='extra-small' className='text-red-500 font-medium'>\n {errorMessage}\n </Typography>\n )}\n </div>\n </Popover>\n );\n};\n\nexport const IconPicker = React.lazy(() =>\n Promise.resolve({\n default: (props: IconPickerContentProps) => (\n <Suspense fallback={<div className='min-w-20 h-8 animate-pulse bg-neutral-100 dark:bg-black-800 rounded-md' />}>\n <IconPickerBase {...props} />\n </Suspense>\n ),\n }),\n);\n\n"],"names":["roundedIconNames","AllIcons","name","mergedIconNames","COUNTRY_CODES","code","formatIconName","iconName","countryNameFromCode","IconPickerContent","onChange","selectedIcon","setOpen","searchTerm","setSearchTerm","useState","filteredIcons","handleClick","icon","event","jsxs","e","jsx","InputField","value","FixedSizeGrid","columnIndex","rowIndex","style","itemIndex","Tooltip","IconButton","classNames","IconRenderer","sx","className","isHovering","getFlagComponent","Icon","IconPickerBase","label","required","allowClear","disabled","errorMessage","dropdownPosition","open","mouseClickRef","useRef","buttonRef","wasOpenRef","useEffect","handleClearIcon","Popover","triggerNode","newOpen","InputLabel","Typography","KeyboardArrowDownIcon","IconPicker","React","props","Suspense"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IconPicker.es.js","sources":["../../../../src/components/forms/icon-picker/IconPicker.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport React, { Suspense, useEffect, useRef, useState } from 'react';\nimport { FixedSizeGrid, type GridChildComponentProps } from 'react-window';\nimport * as AllIcons from '@mui/icons-material';\nimport { IconButton, type SvgIconOwnProps } from '@mui/material';\nimport { Popover, Tooltip } from \"antd\";\nimport { Typography } from \"../../data-display/typography/Typography\";\nimport { InputField } from \"../input-field/InputField\";\nimport { COUNTRY_CODES, countryNameFromCode } from \"../../../types/icon-picker\";\nimport { getFlagComponent } from \"../../../utils/countryFlags\";\nimport { KeyboardArrowDownIcon } from \"../../icon\";\nimport { InputLabel } from '../shared/InputLabel';\n\nconst roundedIconNames = Object.keys(AllIcons).filter((name) =>\n name?.endsWith(\"Rounded\")\n);\n\n// Merge icon names and country codes for the picker\nconst mergedIconNames = [\n ...(roundedIconNames || []),\n ...(COUNTRY_CODES || []).map((code) => `flag-${code}`),\n];\n\n// Utility function to convert camelCase to human-readable format\nconst formatIconName = (iconName: string): string => {\n // Handle flag icons\n if (iconName?.startsWith(\"flag-\")) {\n const code = iconName?.replace(\"flag-\", \"\");\n return countryNameFromCode(code || \"\") || code;\n }\n\n // Convert camelCase to space-separated words\n // e.g., \"PersonRounded\" -> \"Person Rounded\"\n return iconName.replaceAll(/([A-Z])/g, \" $1\").trim();\n};\n\n/** Ant Design `Popover` placement for the icon panel (bottom edge of the trigger). */\nexport type IconPickerDropdownPosition = 'bottom' | 'bottomLeft' | 'bottomRight';\n\nexport interface IconPickerContentProps {\n selectedIcon: string | null;\n onChange: (iconName: string | null) => void;\n label?: string;\n required?: boolean;\n allowClear?: boolean;\n disabled?: boolean;\n errorMessage?: string;\n /** Popover placement: `bottom` | `bottomLeft` | `bottomRight`. Default: `bottom`. */\n dropdownPosition?: IconPickerDropdownPosition;\n className?: string\n}\n\ninterface IconPickerContentInternalProps {\n onChange: (iconName: string | null) => void;\n selectedIcon: string | null;\n setOpen?: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\nconst IconPickerContent = ({\n onChange,\n selectedIcon,\n setOpen,\n}: IconPickerContentInternalProps) => {\n const [searchTerm, setSearchTerm] = useState<string>(\"\");\n\n // Filter both icons and flags\n const filteredIcons = (mergedIconNames || []).filter((name) => {\n if (name?.startsWith(\"flag-\")) {\n // For flags, allow search by country code or country name\n const code = name?.replace(\"flag-\", \"\");\n return (\n code\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\") ||\n countryNameFromCode(code || \"\")\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\")\n );\n }\n return name\n ?.trim()\n ?.toLowerCase()\n ?.includes(searchTerm?.trim()?.toLowerCase() || \"\");\n });\n\n const handleClick = (icon: string, event: React.MouseEvent) => {\n event.stopPropagation();\n if (selectedIcon === icon) {\n onChange?.(null);\n return;\n }\n onChange?.(icon);\n setOpen?.(false);\n };\n\n return (\n <div \n className=\"flex flex-col gap-3\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n }\n }}\n >\n <InputField\n id={`input-field-icon-picker`}\n placeholder=\"Search icons...\"\n onChange={(value) => setSearchTerm(value || \"\")}\n fieldSuffix={\n <AllIcons.Search className=\"!w-4 !h-4 text-neutral-400\" />\n }\n />\n <FixedSizeGrid\n columnCount={5}\n rowCount={Math.ceil((filteredIcons?.length || 0) / 5)}\n columnWidth={40}\n rowHeight={40}\n width={220}\n height={240}\n >\n {({ columnIndex, rowIndex, style }: GridChildComponentProps) => {\n const itemIndex = rowIndex * 5 + columnIndex;\n const iconName = filteredIcons?.[itemIndex];\n return iconName ? (\n <div style={style} className=\"p-1\">\n <Tooltip title={formatIconName(iconName)} placement='bottom'>\n <IconButton\n type='button'\n className={classNames(\n \"flex items-center justify-center !rounded-md hover:bg-neutral-200 dark:hover:bg-black-700\",\n {\n \"!bg-primary-50 dark:!bg-black-800\":\n selectedIcon === iconName,\n }\n )}\n onClick={(event) => handleClick(iconName, event)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n }\n }}\n >\n <IconRenderer\n iconName={iconName}\n className=\"!w-5 !h-5 text-neutral-900 dark:text-white\"\n />\n </IconButton>\n </Tooltip>\n </div>\n ) : null;\n }}\n </FixedSizeGrid>\n </div>\n );\n};\n\ninterface IconRendererProps {\n iconName: string;\n sx?: SvgIconOwnProps['sx'];\n className?: string;\n isHovering?: boolean;\n}\n\nexport const IconRenderer = ({ iconName, sx, className, isHovering }: IconRendererProps) => {\n // Render flag if iconName starts with 'flag-'\n if (iconName?.startsWith?.('flag-')) {\n const code = iconName?.replace('flag-', '');\n return getFlagComponent?.(code || '', isHovering || false) || <div>-</div>;\n }\n const Icon = AllIcons?.[iconName as keyof typeof AllIcons] as React.ComponentType<{\n sx?: SvgIconOwnProps['sx'];\n className?: string;\n isHovering?: boolean;\n }>;\n\n if (!Icon) {\n return <div>-</div>;\n }\n\n return <Icon sx={sx} className={className} isHovering={isHovering} />;\n};\n\nconst IconPickerBase = ({\n selectedIcon,\n onChange,\n label,\n required = false,\n allowClear = true,\n disabled = false,\n errorMessage,\n dropdownPosition = 'bottom',\n className\n}: IconPickerContentProps) => {\n const [open, setOpen] = useState(false);\n const mouseClickRef = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const wasOpenRef = useRef(false);\n\n useEffect(() => {\n if (wasOpenRef.current && !open) {\n buttonRef.current?.focus();\n }\n wasOpenRef.current = open;\n }, [open]);\n const handleClearIcon = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange?.('');\n };\n\n return (\n <Popover\n arrow={false}\n placement={dropdownPosition}\n trigger='click'\n getPopupContainer={(triggerNode) => triggerNode?.parentElement || document.body}\n open={open}\n onOpenChange={(newOpen) => {\n if (newOpen) {\n if (mouseClickRef.current) {\n setOpen(true);\n }\n mouseClickRef.current = false;\n } else {\n setOpen(false);\n }\n }}\n content={<IconPickerContent onChange={onChange} selectedIcon={selectedIcon} setOpen={setOpen} />}\n >\n <div className='flex flex-col gap-1'>\n {label ? (\n <InputLabel label={label || \"\"} required={required || false} />\n ) : null}\n <button\n ref={buttonRef}\n type='button'\n id={`btn-icon-picker-icon-${selectedIcon ? 'selected' : 'unselected'}`}\n className={`lax-form-trigger min-w-[83px] h-8 py-1.5 px-3 rounded-md border ${\n disabled ? 'cursor-not-allowed opacity-60 bg-neutral-50 dark:bg-black-800' : 'bg-white dark:bg-black-800'\n } ${errorMessage ? 'border-red-500' : 'focus:border-primary-600 dark:focus:border-primary-400'} flex items-center justify-between gap-2 ${className}`}\n disabled={disabled}\n aria-haspopup='dialog'\n aria-expanded={open}\n onClick={(e) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (e.detail > 0) {\n mouseClickRef.current = true;\n }\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n if (!open) {\n const form = (e.currentTarget as HTMLElement).closest('form');\n const submitBtn = form?.querySelector('button[type=\"submit\"]') as HTMLButtonElement | null;\n submitBtn?.click();\n }\n }\n }}\n >\n {selectedIcon ? (\n <IconRenderer iconName={selectedIcon} className='!w-5 !h-5 text-neutral-900 dark:text-white' />\n ) : (\n <Typography\n size='small'\n variant='regular'\n appearance='subtitle'\n >\n Select Icon\n </Typography>\n )}\n <span className='flex shrink-0 items-center gap-1'>\n {selectedIcon && allowClear && !disabled ? (\n <AllIcons.CloseRounded\n className='!w-5 !h-5 hover:bg-neutral-100 dark:hover:bg-black-800 rounded-full transition-colors cursor-pointer text-neutral-400 dark:text-neutral-500'\n onClick={handleClearIcon}\n />\n ) : (\n null\n )}\n <KeyboardArrowDownIcon\n className={classNames(\n 'h-4 w-4 shrink-0 text-neutral-400 transition-transform duration-200',\n { 'rotate-180': open }\n )}\n />\n </span>\n </button>\n {errorMessage && (\n <Typography size='extra-small' className='text-red-500 font-medium'>\n {errorMessage}\n </Typography>\n )}\n </div>\n </Popover>\n );\n};\n\nexport const IconPicker = React.lazy(() =>\n Promise.resolve({\n default: (props: IconPickerContentProps) => (\n <Suspense fallback={<div className='min-w-20 h-8 animate-pulse bg-neutral-100 dark:bg-black-800 rounded-md' />}>\n <IconPickerBase {...props} />\n </Suspense>\n ),\n }),\n);\n\n"],"names":["roundedIconNames","AllIcons","name","mergedIconNames","COUNTRY_CODES","code","formatIconName","iconName","countryNameFromCode","IconPickerContent","onChange","selectedIcon","setOpen","searchTerm","setSearchTerm","useState","filteredIcons","handleClick","icon","event","jsxs","e","jsx","InputField","value","FixedSizeGrid","columnIndex","rowIndex","style","itemIndex","Tooltip","IconButton","classNames","IconRenderer","sx","className","isHovering","getFlagComponent","Icon","IconPickerBase","label","required","allowClear","disabled","errorMessage","dropdownPosition","open","mouseClickRef","useRef","buttonRef","wasOpenRef","useEffect","handleClearIcon","Popover","triggerNode","newOpen","InputLabel","Typography","KeyboardArrowDownIcon","IconPicker","React","props","Suspense"],"mappings":"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"}
|