@banzamel/mineralui 2.1.2 → 2.1.4

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.
Files changed (121) hide show
  1. package/README.md +1 -1
  2. package/dist/{MDetailList-BhKBJwpd.cjs → MDetailList-DTLU7HQZ.cjs} +2 -2
  3. package/dist/{MDetailList-BhKBJwpd.cjs.map → MDetailList-DTLU7HQZ.cjs.map} +1 -1
  4. package/dist/{MDetailList-BjvZUyNj.js → MDetailList-fDhVyhm7.js} +3 -3
  5. package/dist/{MDetailList-BjvZUyNj.js.map → MDetailList-fDhVyhm7.js.map} +1 -1
  6. package/dist/{MDropdownMenu-hXaIMkAj.cjs → MDropdownMenu-BvN5grK5.cjs} +2 -2
  7. package/dist/{MDropdownMenu-hXaIMkAj.cjs.map → MDropdownMenu-BvN5grK5.cjs.map} +1 -1
  8. package/dist/{MDropdownMenu-CZmU3uku.js → MDropdownMenu-CFoKJ7V6.js} +2 -2
  9. package/dist/{MDropdownMenu-CZmU3uku.js.map → MDropdownMenu-CFoKJ7V6.js.map} +1 -1
  10. package/dist/{MInput-BhTAfpYS.cjs → MInput-BpTlP8GE.cjs} +2 -2
  11. package/dist/{MInput-BhTAfpYS.cjs.map → MInput-BpTlP8GE.cjs.map} +1 -1
  12. package/dist/{MInput-CgtX0fUN.js → MInput-C8ObGzQk.js} +2 -2
  13. package/dist/{MInput-CgtX0fUN.js.map → MInput-C8ObGzQk.js.map} +1 -1
  14. package/dist/{MInputCVC-BGYhUGDE.js → MInputCVC-B4V0QI5h.js} +24 -24
  15. package/dist/{MInputCVC-BGYhUGDE.js.map → MInputCVC-B4V0QI5h.js.map} +1 -1
  16. package/dist/{MInputCVC-E2Z2hYfy.cjs → MInputCVC-BlY5OrVn.cjs} +2 -2
  17. package/dist/{MInputCVC-E2Z2hYfy.cjs.map → MInputCVC-BlY5OrVn.cjs.map} +1 -1
  18. package/dist/{MInputSearch-DE9Jqp0i.cjs → MInputSearch-9wcXlY8-.cjs} +2 -2
  19. package/dist/{MInputSearch-DE9Jqp0i.cjs.map → MInputSearch-9wcXlY8-.cjs.map} +1 -1
  20. package/dist/{MInputSearch-DEr5HBgw.js → MInputSearch-BM8gLlJ1.js} +3 -3
  21. package/dist/{MInputSearch-DEr5HBgw.js.map → MInputSearch-BM8gLlJ1.js.map} +1 -1
  22. package/dist/{MPagination-DTqT33Mx.cjs → MPagination-C6QQdEj_.cjs} +2 -2
  23. package/dist/{MPagination-DTqT33Mx.cjs.map → MPagination-C6QQdEj_.cjs.map} +1 -1
  24. package/dist/{MPagination-7yTbB8dZ.js → MPagination-CgmNEAZX.js} +6 -6
  25. package/dist/{MPagination-7yTbB8dZ.js.map → MPagination-CgmNEAZX.js.map} +1 -1
  26. package/dist/MPopover-C5aaGhma.js +150 -0
  27. package/dist/MPopover-C5aaGhma.js.map +1 -0
  28. package/dist/MPopover-CV-9MArH.cjs +2 -0
  29. package/dist/MPopover-CV-9MArH.cjs.map +1 -0
  30. package/dist/{MTag-BtlOVMRl.cjs → MTag-BzTp1crT.cjs} +2 -2
  31. package/dist/{MTag-BtlOVMRl.cjs.map → MTag-BzTp1crT.cjs.map} +1 -1
  32. package/dist/{MTag-BF6htPr-.js → MTag-D9q6faIk.js} +2 -2
  33. package/dist/{MTag-BF6htPr-.js.map → MTag-D9q6faIk.js.map} +1 -1
  34. package/dist/{MTreeView-DQaRF0ty.js → MTreeView-B1J7uqd1.js} +63 -63
  35. package/dist/{MTreeView-DQaRF0ty.js.map → MTreeView-B1J7uqd1.js.map} +1 -1
  36. package/dist/{MTreeView-1IqmVPMv.cjs → MTreeView-DuQkm0ZV.cjs} +2 -2
  37. package/dist/{MTreeView-1IqmVPMv.cjs.map → MTreeView-DuQkm0ZV.cjs.map} +1 -1
  38. package/dist/{cards-BBYh24NQ.cjs → cards-CQSYgH9U.cjs} +2 -2
  39. package/dist/{cards-BBYh24NQ.cjs.map → cards-CQSYgH9U.cjs.map} +1 -1
  40. package/dist/{cards-Du2kX3Br.js → cards-Cpr9B8Mu.js} +73 -73
  41. package/dist/{cards-Du2kX3Br.js.map → cards-Cpr9B8Mu.js.map} +1 -1
  42. package/dist/cards.cjs +1 -1
  43. package/dist/cards.js +1 -1
  44. package/dist/components/primitives/MPopover/popoverStack.d.ts +32 -0
  45. package/dist/{controls-Cbv4FmNq.js → controls-BKAhqjNM.js} +2 -2
  46. package/dist/{controls-Cbv4FmNq.js.map → controls-BKAhqjNM.js.map} +1 -1
  47. package/dist/{controls-DrdHBBtm.cjs → controls-CT_0lIPr.cjs} +2 -2
  48. package/dist/{controls-DrdHBBtm.cjs.map → controls-CT_0lIPr.cjs.map} +1 -1
  49. package/dist/controls.cjs +1 -1
  50. package/dist/controls.js +1 -1
  51. package/dist/{data-Csb03WFo.cjs → data-BZ92hzXx.cjs} +2 -2
  52. package/dist/{data-Csb03WFo.cjs.map → data-BZ92hzXx.cjs.map} +1 -1
  53. package/dist/{data-BgTkBMkP.js → data-C-6DP7iY.js} +16 -16
  54. package/dist/{data-BgTkBMkP.js.map → data-C-6DP7iY.js.map} +1 -1
  55. package/dist/data.cjs +1 -1
  56. package/dist/data.js +2 -2
  57. package/dist/{display-D9H8MP8D.js → display-BF4jASt9.js} +16 -16
  58. package/dist/{display-D9H8MP8D.js.map → display-BF4jASt9.js.map} +1 -1
  59. package/dist/{display-IMWtdmxS.cjs → display-DMix8BmD.cjs} +3 -3
  60. package/dist/{display-IMWtdmxS.cjs.map → display-DMix8BmD.cjs.map} +1 -1
  61. package/dist/display.cjs +1 -1
  62. package/dist/display.js +2 -2
  63. package/dist/{dropdowns-oj4--GbK.js → dropdowns-DiThUF7D.js} +91 -91
  64. package/dist/{dropdowns-oj4--GbK.js.map → dropdowns-DiThUF7D.js.map} +1 -1
  65. package/dist/{dropdowns-D_nUdflh.cjs → dropdowns-bQ0cEKNN.cjs} +2 -2
  66. package/dist/{dropdowns-D_nUdflh.cjs.map → dropdowns-bQ0cEKNN.cjs.map} +1 -1
  67. package/dist/dropdowns.cjs +1 -1
  68. package/dist/dropdowns.js +1 -1
  69. package/dist/{feedback-u1ssUT7e.cjs → feedback-4TjD57rX.cjs} +2 -2
  70. package/dist/{feedback-u1ssUT7e.cjs.map → feedback-4TjD57rX.cjs.map} +1 -1
  71. package/dist/{feedback-D7BTlioj.js → feedback-DW-cehnb.js} +35 -35
  72. package/dist/{feedback-D7BTlioj.js.map → feedback-DW-cehnb.js.map} +1 -1
  73. package/dist/feedback.cjs +1 -1
  74. package/dist/feedback.js +2 -2
  75. package/dist/icons/glyphs/MCoinIcon.d.ts +2 -0
  76. package/dist/icons/glyphs/MMoneyIcon.d.ts +2 -0
  77. package/dist/icons/glyphs/MReceiptIcon.d.ts +2 -0
  78. package/dist/icons/glyphs/MWalletIcon.d.ts +2 -0
  79. package/dist/icons/index.d.ts +4 -0
  80. package/dist/{icons-DLP-Rs6z.js → icons-CBMl-kOM.js} +221 -166
  81. package/dist/icons-CBMl-kOM.js.map +1 -0
  82. package/dist/icons-D675Im0B.cjs +2 -0
  83. package/dist/icons-D675Im0B.cjs.map +1 -0
  84. package/dist/icons.cjs +1 -1
  85. package/dist/icons.js +2 -2
  86. package/dist/index.cjs +1 -1
  87. package/dist/index.js +53 -53
  88. package/dist/{inputs-DQrjGfwd.js → inputs-CQoi402V.js} +180 -180
  89. package/dist/{inputs-DQrjGfwd.js.map → inputs-CQoi402V.js.map} +1 -1
  90. package/dist/{inputs-DsFdc0Io.cjs → inputs-yaaTPTsY.cjs} +2 -2
  91. package/dist/{inputs-DsFdc0Io.cjs.map → inputs-yaaTPTsY.cjs.map} +1 -1
  92. package/dist/inputs.cjs +1 -1
  93. package/dist/inputs.js +4 -4
  94. package/dist/{layout-BuvV-N9H.js → layout-CdSpVJuK.js} +32 -32
  95. package/dist/{layout-BuvV-N9H.js.map → layout-CdSpVJuK.js.map} +1 -1
  96. package/dist/{layout-B_2yBP1M.cjs → layout-Ddo7HUPu.cjs} +2 -2
  97. package/dist/{layout-B_2yBP1M.cjs.map → layout-Ddo7HUPu.cjs.map} +1 -1
  98. package/dist/layout.cjs +1 -1
  99. package/dist/layout.js +2 -2
  100. package/dist/{media-Xt6MkVhb.cjs → media-DRz3JZfr.cjs} +2 -2
  101. package/dist/{media-Xt6MkVhb.cjs.map → media-DRz3JZfr.cjs.map} +1 -1
  102. package/dist/{media-5IsYrhIQ.js → media-vOQOIYFD.js} +11 -11
  103. package/dist/{media-5IsYrhIQ.js.map → media-vOQOIYFD.js.map} +1 -1
  104. package/dist/media.cjs +1 -1
  105. package/dist/media.js +1 -1
  106. package/dist/{overlays-BAJDNT1m.cjs → overlays-BUZEaZaJ.cjs} +2 -2
  107. package/dist/{overlays-BAJDNT1m.cjs.map → overlays-BUZEaZaJ.cjs.map} +1 -1
  108. package/dist/{overlays-WA3jnWTG.js → overlays-C1vO_A2I.js} +50 -50
  109. package/dist/{overlays-WA3jnWTG.js.map → overlays-C1vO_A2I.js.map} +1 -1
  110. package/dist/overlays.cjs +1 -1
  111. package/dist/overlays.js +2 -2
  112. package/dist/primitives.cjs +1 -1
  113. package/dist/primitives.js +1 -1
  114. package/package.json +1 -1
  115. package/dist/MPopover-BRuwva-c.js +0 -95
  116. package/dist/MPopover-BRuwva-c.js.map +0 -1
  117. package/dist/MPopover-hDqrn317.cjs +0 -2
  118. package/dist/MPopover-hDqrn317.cjs.map +0 -1
  119. package/dist/icons-BfdQ45F2.cjs +0 -2
  120. package/dist/icons-BfdQ45F2.cjs.map +0 -1
  121. package/dist/icons-DLP-Rs6z.js.map +0 -1
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Modern React UI framework with a sharp admin aesthetic, theming system, and production-ready components.
4
4
 
5
5
  - npm: `@banzamel/mineralui`
6
- - version: `2.1.2`
6
+ - version: `2.1.4`
7
7
  - peer dependencies: `react >= 19`, `react-dom >= 19`
8
8
  - repository: `https://github.com/Banzamel/mineralui`
9
9
  - homepage: `https://mineralui.io`
@@ -1,2 +1,2 @@
1
- const e=require(`./icons-BfdQ45F2.cjs`),t=require(`./cn-CU5TNITO.cjs`),n=require(`./MSurface-CYeVFOw_.cjs`),r=require(`./MText-j6Zbbj5Y.cjs`),i=require(`./MLink-Biipj7xz.cjs`),a=require(`./MStack-BP_BUeCc.cjs`);require(`./core-DBpQf3uY.cjs`);let o=require(`react`),s=require(`react/jsx-runtime`);function c({value:n=0,max:r=5,color:i=`warning`,size:a=`md`,readOnly:c=!1,onChange:l,className:u,...d}){let[f,p]=(0,o.useState)(null),m=f??n,h=e=>{c||l?.(e)};return(0,s.jsx)(`div`,{className:t.t(`rating`,`color-${i}`,a,c&&`read-only`,u),role:`radiogroup`,"aria-label":`MRating`,onMouseLeave:()=>p(null),...d,children:Array.from({length:r},(t,n)=>{let r=n+1,i=m>=r;return(0,s.jsx)(`button`,{type:`button`,className:`rating-star`,onClick:()=>h(r),onMouseEnter:()=>!c&&p(r),"aria-label":`${r} star${r>1?`s`:``}`,tabIndex:c?-1:0,disabled:c,children:(0,s.jsx)(`span`,{className:`star-icon`,"aria-hidden":`true`,children:i?(0,s.jsx)(e.mi,{}):(0,s.jsx)(e.hi,{})})},n)})})}var l={xs:`xs`,sm:`xs`,md:`sm`,lg:`md`,xl:`md`};function u({items:e,size:o=`md`,bordered:c=!0,emptyState:u=null,className:d,...f}){if(!e.length)return u?(0,s.jsx)(`div`,{className:t.t(`detail-list`,d),children:u}):null;let p=l[o];return(0,s.jsx)(`div`,{className:t.t(`detail-list`,`size-${o}`,c&&`bordered`,d),...f,children:e.map(e=>{let t=e.key??e.label?.toString(),o=e.component||e.to||e.href?(0,s.jsx)(i.t,{component:e.component,to:e.to,href:e.href,target:e.target,rel:e.rel,children:e.value}):e.value;return(0,s.jsx)(`div`,{className:`detail-list-item`,children:(0,s.jsxs)(n.n,{justify:`between`,align:`start`,children:[(0,s.jsxs)(a.t,{children:[(0,s.jsx)(r.t,{size:p,tone:`muted`,children:e.label}),o&&(0,s.jsx)(`div`,{className:`detail-list-value`,children:o}),e.helperText&&(0,s.jsx)(r.t,{size:p,tone:`muted`,children:e.helperText})]}),e.status&&(0,s.jsx)(`div`,{className:`detail-list-status`,children:e.status})]})},t)})})}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return u}});
2
- //# sourceMappingURL=MDetailList-BhKBJwpd.cjs.map
1
+ const e=require(`./icons-D675Im0B.cjs`),t=require(`./cn-CU5TNITO.cjs`),n=require(`./MSurface-CYeVFOw_.cjs`),r=require(`./MText-j6Zbbj5Y.cjs`),i=require(`./MLink-Biipj7xz.cjs`),a=require(`./MStack-BP_BUeCc.cjs`);require(`./core-DBpQf3uY.cjs`);let o=require(`react`),s=require(`react/jsx-runtime`);function c({value:n=0,max:r=5,color:i=`warning`,size:a=`md`,readOnly:c=!1,onChange:l,className:u,...d}){let[f,p]=(0,o.useState)(null),m=f??n,h=e=>{c||l?.(e)};return(0,s.jsx)(`div`,{className:t.t(`rating`,`color-${i}`,a,c&&`read-only`,u),role:`radiogroup`,"aria-label":`MRating`,onMouseLeave:()=>p(null),...d,children:Array.from({length:r},(t,n)=>{let r=n+1,i=m>=r;return(0,s.jsx)(`button`,{type:`button`,className:`rating-star`,onClick:()=>h(r),onMouseEnter:()=>!c&&p(r),"aria-label":`${r} star${r>1?`s`:``}`,tabIndex:c?-1:0,disabled:c,children:(0,s.jsx)(`span`,{className:`star-icon`,"aria-hidden":`true`,children:i?(0,s.jsx)(e.vi,{}):(0,s.jsx)(e.yi,{})})},n)})})}var l={xs:`xs`,sm:`xs`,md:`sm`,lg:`md`,xl:`md`};function u({items:e,size:o=`md`,bordered:c=!0,emptyState:u=null,className:d,...f}){if(!e.length)return u?(0,s.jsx)(`div`,{className:t.t(`detail-list`,d),children:u}):null;let p=l[o];return(0,s.jsx)(`div`,{className:t.t(`detail-list`,`size-${o}`,c&&`bordered`,d),...f,children:e.map(e=>{let t=e.key??e.label?.toString(),o=e.component||e.to||e.href?(0,s.jsx)(i.t,{component:e.component,to:e.to,href:e.href,target:e.target,rel:e.rel,children:e.value}):e.value;return(0,s.jsx)(`div`,{className:`detail-list-item`,children:(0,s.jsxs)(n.n,{justify:`between`,align:`start`,children:[(0,s.jsxs)(a.t,{children:[(0,s.jsx)(r.t,{size:p,tone:`muted`,children:e.label}),o&&(0,s.jsx)(`div`,{className:`detail-list-value`,children:o}),e.helperText&&(0,s.jsx)(r.t,{size:p,tone:`muted`,children:e.helperText})]}),e.status&&(0,s.jsx)(`div`,{className:`detail-list-status`,children:e.status})]})},t)})})}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return u}});
2
+ //# sourceMappingURL=MDetailList-DTLU7HQZ.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MDetailList-BhKBJwpd.cjs","names":[],"sources":["../src/components/display/MRating/MRating.tsx","../src/components/display/MDetailList/MDetailList.tsx"],"sourcesContent":["import {useState} from 'react'\nimport type {MRatingProps} from './MRating.types'\nimport {MStarFillIcon, MStarIcon} from '../../../icons'\nimport {cn} from '../../../utils/cn'\nimport './MRating.css'\n\n// Render an interactive star-based rating control.\nexport function MRating({\n value = 0,\n max = 5,\n color = 'warning',\n size = 'md',\n readOnly = false,\n onChange,\n className,\n ...rest\n}: MRatingProps) {\n const [hovered, setHovered] = useState<number | null>(null)\n const displayValue = hovered ?? value\n\n const handleClick = (index: number) => {\n if (readOnly) return\n onChange?.(index)\n }\n\n return (\n <div\n className={cn('rating', `color-${color}`, size, readOnly && 'read-only', className)}\n role=\"radiogroup\"\n aria-label=\"MRating\"\n onMouseLeave={() => setHovered(null)}\n {...rest}\n >\n {Array.from({length: max}, (_, i) => {\n const starIndex = i + 1\n const filled = displayValue >= starIndex\n return (\n <button\n key={i}\n type=\"button\"\n className=\"rating-star\"\n onClick={() => handleClick(starIndex)}\n onMouseEnter={() => !readOnly && setHovered(starIndex)}\n aria-label={`${starIndex} star${starIndex > 1 ? 's' : ''}`}\n tabIndex={readOnly ? -1 : 0}\n disabled={readOnly}\n >\n <span className=\"star-icon\" aria-hidden=\"true\">\n {filled ? <MStarFillIcon /> : <MStarIcon />}\n </span>\n </button>\n )\n })}\n </div>\n )\n}\n","import type {MSize} from '../../../theme'\nimport type {MDetailListProps} from './MDetailList.types'\nimport {cn} from '../../../utils/cn'\nimport {MInline, MStack} from '../../layout'\nimport {MLink, MText} from '../../typography'\nimport type {MTextSize} from '../../typography'\nimport './MDetailList.css'\n\n// Maps the list's outer size to the secondary-text size used for labels and helper text.\n// Labels sit one notch below the value so they read as metadata, not headline copy.\nconst LABEL_SIZE_MAP: Record<MSize, MTextSize> = {\n xs: 'xs',\n sm: 'xs',\n md: 'sm',\n lg: 'md',\n xl: 'md',\n}\n\nexport function MDetailList({\n items,\n size = 'md',\n bordered = true,\n emptyState = null,\n className,\n ...rest\n}: MDetailListProps) {\n if (!items.length) {\n return emptyState ? <div className={cn('detail-list', className)}>{emptyState}</div> : null\n }\n\n const labelSize = LABEL_SIZE_MAP[size]\n\n return (\n <div className={cn('detail-list', `size-${size}`, bordered && 'bordered', className)} {...rest}>\n {items.map((item) => {\n const key = item.key ?? item.label?.toString()\n const value =\n item.component || item.to || item.href ? (\n <MLink\n component={item.component}\n to={item.to}\n href={item.href}\n target={item.target}\n rel={item.rel}\n >\n {item.value}\n </MLink>\n ) : (\n item.value\n )\n\n return (\n <div key={key} className=\"detail-list-item\">\n <MInline justify={'between'} align={'start'}>\n <MStack>\n <MText size={labelSize} tone={'muted'}>\n {item.label}\n </MText>\n {value && <div className=\"detail-list-value\">{value}</div>}\n {item.helperText && (\n <MText size={labelSize} tone={'muted'}>\n {item.helperText}\n </MText>\n )}\n </MStack>\n {item.status && <div className=\"detail-list-status\">{item.status}</div>}\n </MInline>\n </div>\n )\n })}\n </div>\n )\n}\n"],"mappings":"wSAOA,SAAgB,EAAQ,CACpB,QAAQ,EACR,MAAM,EACN,QAAQ,UACR,OAAO,KACP,WAAW,GACX,WACA,YACA,GAAG,GACU,CACb,GAAM,CAAC,EAAS,IAAA,EAAA,EAAA,UAAsC,KAAK,CACrD,EAAe,GAAW,EAE1B,EAAe,GAAkB,CAC/B,GACJ,IAAW,EAAM,EAGrB,OACI,EAAA,EAAA,KAAC,MAAD,CACI,UAAW,EAAA,EAAG,SAAU,SAAS,IAAS,EAAM,GAAY,YAAa,EAAU,CACnF,KAAK,aACL,aAAW,UACX,iBAAoB,EAAW,KAAK,CACpC,GAAI,WAEH,MAAM,KAAK,CAAC,OAAQ,EAAI,EAAG,EAAG,IAAM,CACjC,IAAM,EAAY,EAAI,EAChB,EAAS,GAAgB,EAC/B,OACI,EAAA,EAAA,KAAC,SAAD,CAEI,KAAK,SACL,UAAU,cACV,YAAe,EAAY,EAAU,CACrC,iBAAoB,CAAC,GAAY,EAAW,EAAU,CACtD,aAAY,GAAG,EAAU,OAAO,EAAY,EAAI,IAAM,KACtD,SAAU,EAAW,GAAK,EAC1B,SAAU,YAEV,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,YAAY,cAAY,gBACnC,GAAS,EAAA,EAAA,KAAC,EAAA,GAAD,EAAiB,CAAA,EAAG,EAAA,EAAA,KAAC,EAAA,GAAD,EAAa,CAAA,CACxC,CAAA,CACF,CAZA,EAYA,EAEf,CACA,CAAA,CC3Cd,IAAM,EAA2C,CAC7C,GAAI,KACJ,GAAI,KACJ,GAAI,KACJ,GAAI,KACJ,GAAI,KACP,CAED,SAAgB,EAAY,CACxB,QACA,OAAO,KACP,WAAW,GACX,aAAa,KACb,YACA,GAAG,GACc,CACjB,GAAI,CAAC,EAAM,OACP,OAAO,GAAa,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAA,EAAG,cAAe,EAAU,UAAG,EAAiB,CAAA,CAAG,KAG3F,IAAM,EAAY,EAAe,GAEjC,OACI,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAA,EAAG,cAAe,QAAQ,IAAQ,GAAY,WAAY,EAAU,CAAE,GAAI,WACrF,EAAM,IAAK,GAAS,CACjB,IAAM,EAAM,EAAK,KAAO,EAAK,OAAO,UAAU,CACxC,EACF,EAAK,WAAa,EAAK,IAAM,EAAK,MAC9B,EAAA,EAAA,KAAC,EAAA,EAAD,CACI,UAAW,EAAK,UAChB,GAAI,EAAK,GACT,KAAM,EAAK,KACX,OAAQ,EAAK,OACb,IAAK,EAAK,aAET,EAAK,MACF,CAAA,CAER,EAAK,MAGb,OACI,EAAA,EAAA,KAAC,MAAD,CAAe,UAAU,6BACrB,EAAA,EAAA,MAAC,EAAA,EAAD,CAAS,QAAS,UAAW,MAAO,iBAApC,EACI,EAAA,EAAA,MAAC,EAAA,EAAD,CAAA,SAAA,EACI,EAAA,EAAA,KAAC,EAAA,EAAD,CAAO,KAAM,EAAW,KAAM,iBACzB,EAAK,MACF,CAAA,CACP,IAAS,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,6BAAqB,EAAY,CAAA,CACzD,EAAK,aACF,EAAA,EAAA,KAAC,EAAA,EAAD,CAAO,KAAM,EAAW,KAAM,iBACzB,EAAK,WACF,CAAA,CAEP,CAAA,CAAA,CACR,EAAK,SAAU,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,8BAAsB,EAAK,OAAa,CAAA,CACjE,GACR,CAfI,EAeJ,EAEZ,CACA,CAAA"}
1
+ {"version":3,"file":"MDetailList-DTLU7HQZ.cjs","names":[],"sources":["../src/components/display/MRating/MRating.tsx","../src/components/display/MDetailList/MDetailList.tsx"],"sourcesContent":["import {useState} from 'react'\nimport type {MRatingProps} from './MRating.types'\nimport {MStarFillIcon, MStarIcon} from '../../../icons'\nimport {cn} from '../../../utils/cn'\nimport './MRating.css'\n\n// Render an interactive star-based rating control.\nexport function MRating({\n value = 0,\n max = 5,\n color = 'warning',\n size = 'md',\n readOnly = false,\n onChange,\n className,\n ...rest\n}: MRatingProps) {\n const [hovered, setHovered] = useState<number | null>(null)\n const displayValue = hovered ?? value\n\n const handleClick = (index: number) => {\n if (readOnly) return\n onChange?.(index)\n }\n\n return (\n <div\n className={cn('rating', `color-${color}`, size, readOnly && 'read-only', className)}\n role=\"radiogroup\"\n aria-label=\"MRating\"\n onMouseLeave={() => setHovered(null)}\n {...rest}\n >\n {Array.from({length: max}, (_, i) => {\n const starIndex = i + 1\n const filled = displayValue >= starIndex\n return (\n <button\n key={i}\n type=\"button\"\n className=\"rating-star\"\n onClick={() => handleClick(starIndex)}\n onMouseEnter={() => !readOnly && setHovered(starIndex)}\n aria-label={`${starIndex} star${starIndex > 1 ? 's' : ''}`}\n tabIndex={readOnly ? -1 : 0}\n disabled={readOnly}\n >\n <span className=\"star-icon\" aria-hidden=\"true\">\n {filled ? <MStarFillIcon /> : <MStarIcon />}\n </span>\n </button>\n )\n })}\n </div>\n )\n}\n","import type {MSize} from '../../../theme'\nimport type {MDetailListProps} from './MDetailList.types'\nimport {cn} from '../../../utils/cn'\nimport {MInline, MStack} from '../../layout'\nimport {MLink, MText} from '../../typography'\nimport type {MTextSize} from '../../typography'\nimport './MDetailList.css'\n\n// Maps the list's outer size to the secondary-text size used for labels and helper text.\n// Labels sit one notch below the value so they read as metadata, not headline copy.\nconst LABEL_SIZE_MAP: Record<MSize, MTextSize> = {\n xs: 'xs',\n sm: 'xs',\n md: 'sm',\n lg: 'md',\n xl: 'md',\n}\n\nexport function MDetailList({\n items,\n size = 'md',\n bordered = true,\n emptyState = null,\n className,\n ...rest\n}: MDetailListProps) {\n if (!items.length) {\n return emptyState ? <div className={cn('detail-list', className)}>{emptyState}</div> : null\n }\n\n const labelSize = LABEL_SIZE_MAP[size]\n\n return (\n <div className={cn('detail-list', `size-${size}`, bordered && 'bordered', className)} {...rest}>\n {items.map((item) => {\n const key = item.key ?? item.label?.toString()\n const value =\n item.component || item.to || item.href ? (\n <MLink\n component={item.component}\n to={item.to}\n href={item.href}\n target={item.target}\n rel={item.rel}\n >\n {item.value}\n </MLink>\n ) : (\n item.value\n )\n\n return (\n <div key={key} className=\"detail-list-item\">\n <MInline justify={'between'} align={'start'}>\n <MStack>\n <MText size={labelSize} tone={'muted'}>\n {item.label}\n </MText>\n {value && <div className=\"detail-list-value\">{value}</div>}\n {item.helperText && (\n <MText size={labelSize} tone={'muted'}>\n {item.helperText}\n </MText>\n )}\n </MStack>\n {item.status && <div className=\"detail-list-status\">{item.status}</div>}\n </MInline>\n </div>\n )\n })}\n </div>\n )\n}\n"],"mappings":"wSAOA,SAAgB,EAAQ,CACpB,QAAQ,EACR,MAAM,EACN,QAAQ,UACR,OAAO,KACP,WAAW,GACX,WACA,YACA,GAAG,GACU,CACb,GAAM,CAAC,EAAS,IAAA,EAAA,EAAA,UAAsC,KAAK,CACrD,EAAe,GAAW,EAE1B,EAAe,GAAkB,CAC/B,GACJ,IAAW,EAAM,EAGrB,OACI,EAAA,EAAA,KAAC,MAAD,CACI,UAAW,EAAA,EAAG,SAAU,SAAS,IAAS,EAAM,GAAY,YAAa,EAAU,CACnF,KAAK,aACL,aAAW,UACX,iBAAoB,EAAW,KAAK,CACpC,GAAI,WAEH,MAAM,KAAK,CAAC,OAAQ,EAAI,EAAG,EAAG,IAAM,CACjC,IAAM,EAAY,EAAI,EAChB,EAAS,GAAgB,EAC/B,OACI,EAAA,EAAA,KAAC,SAAD,CAEI,KAAK,SACL,UAAU,cACV,YAAe,EAAY,EAAU,CACrC,iBAAoB,CAAC,GAAY,EAAW,EAAU,CACtD,aAAY,GAAG,EAAU,OAAO,EAAY,EAAI,IAAM,KACtD,SAAU,EAAW,GAAK,EAC1B,SAAU,YAEV,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,YAAY,cAAY,gBACnC,GAAS,EAAA,EAAA,KAAC,EAAA,GAAD,EAAiB,CAAA,EAAG,EAAA,EAAA,KAAC,EAAA,GAAD,EAAa,CAAA,CACxC,CAAA,CACF,CAZA,EAYA,EAEf,CACA,CAAA,CC3Cd,IAAM,EAA2C,CAC7C,GAAI,KACJ,GAAI,KACJ,GAAI,KACJ,GAAI,KACJ,GAAI,KACP,CAED,SAAgB,EAAY,CACxB,QACA,OAAO,KACP,WAAW,GACX,aAAa,KACb,YACA,GAAG,GACc,CACjB,GAAI,CAAC,EAAM,OACP,OAAO,GAAa,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAA,EAAG,cAAe,EAAU,UAAG,EAAiB,CAAA,CAAG,KAG3F,IAAM,EAAY,EAAe,GAEjC,OACI,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAA,EAAG,cAAe,QAAQ,IAAQ,GAAY,WAAY,EAAU,CAAE,GAAI,WACrF,EAAM,IAAK,GAAS,CACjB,IAAM,EAAM,EAAK,KAAO,EAAK,OAAO,UAAU,CACxC,EACF,EAAK,WAAa,EAAK,IAAM,EAAK,MAC9B,EAAA,EAAA,KAAC,EAAA,EAAD,CACI,UAAW,EAAK,UAChB,GAAI,EAAK,GACT,KAAM,EAAK,KACX,OAAQ,EAAK,OACb,IAAK,EAAK,aAET,EAAK,MACF,CAAA,CAER,EAAK,MAGb,OACI,EAAA,EAAA,KAAC,MAAD,CAAe,UAAU,6BACrB,EAAA,EAAA,MAAC,EAAA,EAAD,CAAS,QAAS,UAAW,MAAO,iBAApC,EACI,EAAA,EAAA,MAAC,EAAA,EAAD,CAAA,SAAA,EACI,EAAA,EAAA,KAAC,EAAA,EAAD,CAAO,KAAM,EAAW,KAAM,iBACzB,EAAK,MACF,CAAA,CACP,IAAS,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,6BAAqB,EAAY,CAAA,CACzD,EAAK,aACF,EAAA,EAAA,KAAC,EAAA,EAAD,CAAO,KAAM,EAAW,KAAM,iBACzB,EAAK,WACF,CAAA,CAEP,CAAA,CAAA,CACR,EAAK,SAAU,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,8BAAsB,EAAK,OAAa,CAAA,CACjE,GACR,CAfI,EAeJ,EAEZ,CACA,CAAA"}
@@ -1,4 +1,4 @@
1
- import { hi as e, mi as t } from "./icons-DLP-Rs6z.js";
1
+ import { vi as e, yi as t } from "./icons-CBMl-kOM.js";
2
2
  import { t as n } from "./cn-YER3QsV1.js";
3
3
  import { n as r } from "./MSurface-B-sjyczH.js";
4
4
  import { t as i } from "./MText-CL-LPcXi.js";
@@ -30,7 +30,7 @@ function u({ value: r = 0, max: i = 5, color: a = "warning", size: o = "md", rea
30
30
  children: /* @__PURE__ */ c("span", {
31
31
  className: "star-icon",
32
32
  "aria-hidden": "true",
33
- children: c(a ? t : e, {})
33
+ children: c(a ? e : t, {})
34
34
  })
35
35
  }, r);
36
36
  })
@@ -95,4 +95,4 @@ function f({ items: e, size: t = "md", bordered: s = !0, emptyState: u = null, c
95
95
  //#endregion
96
96
  export { u as n, f as t };
97
97
 
98
- //# sourceMappingURL=MDetailList-BjvZUyNj.js.map
98
+ //# sourceMappingURL=MDetailList-fDhVyhm7.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MDetailList-BjvZUyNj.js","names":[],"sources":["../src/components/display/MRating/MRating.tsx","../src/components/display/MDetailList/MDetailList.tsx"],"sourcesContent":["import {useState} from 'react'\nimport type {MRatingProps} from './MRating.types'\nimport {MStarFillIcon, MStarIcon} from '../../../icons'\nimport {cn} from '../../../utils/cn'\nimport './MRating.css'\n\n// Render an interactive star-based rating control.\nexport function MRating({\n value = 0,\n max = 5,\n color = 'warning',\n size = 'md',\n readOnly = false,\n onChange,\n className,\n ...rest\n}: MRatingProps) {\n const [hovered, setHovered] = useState<number | null>(null)\n const displayValue = hovered ?? value\n\n const handleClick = (index: number) => {\n if (readOnly) return\n onChange?.(index)\n }\n\n return (\n <div\n className={cn('rating', `color-${color}`, size, readOnly && 'read-only', className)}\n role=\"radiogroup\"\n aria-label=\"MRating\"\n onMouseLeave={() => setHovered(null)}\n {...rest}\n >\n {Array.from({length: max}, (_, i) => {\n const starIndex = i + 1\n const filled = displayValue >= starIndex\n return (\n <button\n key={i}\n type=\"button\"\n className=\"rating-star\"\n onClick={() => handleClick(starIndex)}\n onMouseEnter={() => !readOnly && setHovered(starIndex)}\n aria-label={`${starIndex} star${starIndex > 1 ? 's' : ''}`}\n tabIndex={readOnly ? -1 : 0}\n disabled={readOnly}\n >\n <span className=\"star-icon\" aria-hidden=\"true\">\n {filled ? <MStarFillIcon /> : <MStarIcon />}\n </span>\n </button>\n )\n })}\n </div>\n )\n}\n","import type {MSize} from '../../../theme'\nimport type {MDetailListProps} from './MDetailList.types'\nimport {cn} from '../../../utils/cn'\nimport {MInline, MStack} from '../../layout'\nimport {MLink, MText} from '../../typography'\nimport type {MTextSize} from '../../typography'\nimport './MDetailList.css'\n\n// Maps the list's outer size to the secondary-text size used for labels and helper text.\n// Labels sit one notch below the value so they read as metadata, not headline copy.\nconst LABEL_SIZE_MAP: Record<MSize, MTextSize> = {\n xs: 'xs',\n sm: 'xs',\n md: 'sm',\n lg: 'md',\n xl: 'md',\n}\n\nexport function MDetailList({\n items,\n size = 'md',\n bordered = true,\n emptyState = null,\n className,\n ...rest\n}: MDetailListProps) {\n if (!items.length) {\n return emptyState ? <div className={cn('detail-list', className)}>{emptyState}</div> : null\n }\n\n const labelSize = LABEL_SIZE_MAP[size]\n\n return (\n <div className={cn('detail-list', `size-${size}`, bordered && 'bordered', className)} {...rest}>\n {items.map((item) => {\n const key = item.key ?? item.label?.toString()\n const value =\n item.component || item.to || item.href ? (\n <MLink\n component={item.component}\n to={item.to}\n href={item.href}\n target={item.target}\n rel={item.rel}\n >\n {item.value}\n </MLink>\n ) : (\n item.value\n )\n\n return (\n <div key={key} className=\"detail-list-item\">\n <MInline justify={'between'} align={'start'}>\n <MStack>\n <MText size={labelSize} tone={'muted'}>\n {item.label}\n </MText>\n {value && <div className=\"detail-list-value\">{value}</div>}\n {item.helperText && (\n <MText size={labelSize} tone={'muted'}>\n {item.helperText}\n </MText>\n )}\n </MStack>\n {item.status && <div className=\"detail-list-status\">{item.status}</div>}\n </MInline>\n </div>\n )\n })}\n </div>\n )\n}\n"],"mappings":";;;;;;;;;AAOA,SAAgB,EAAQ,EACpB,WAAQ,GACR,SAAM,GACN,WAAQ,WACR,UAAO,MACP,cAAW,IACX,aACA,cACA,GAAG,KACU;CACb,IAAM,CAAC,GAAS,KAAc,EAAwB,KAAK,EACrD,IAAe,KAAW,GAE1B,KAAe,MAAkB;AAC/B,OACJ,IAAW,EAAM;;AAGrB,QACI,kBAAC,OAAD;EACI,WAAW,EAAG,UAAU,SAAS,KAAS,GAAM,KAAY,aAAa,EAAU;EACnF,MAAK;EACL,cAAW;EACX,oBAAoB,EAAW,KAAK;EACpC,GAAI;YAEH,MAAM,KAAK,EAAC,QAAQ,GAAI,GAAG,GAAG,MAAM;GACjC,IAAM,IAAY,IAAI,GAChB,IAAS,KAAgB;AAC/B,UACI,kBAAC,UAAD;IAEI,MAAK;IACL,WAAU;IACV,eAAe,EAAY,EAAU;IACrC,oBAAoB,CAAC,KAAY,EAAW,EAAU;IACtD,cAAY,GAAG,EAAU,OAAO,IAAY,IAAI,MAAM;IACtD,UAAU,IAAW,KAAK;IAC1B,UAAU;cAEV,kBAAC,QAAD;KAAM,WAAU;KAAY,eAAY;eAC1B,EAAT,IAAU,IAAoB,GAArB,EAAiB,CAAgB;KACxC,CAAA;IACF,EAZA,EAYA;IAEf;EACA,CAAA;;;;AC3Cd,IAAM,IAA2C;CAC7C,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACP;AAED,SAAgB,EAAY,EACxB,UACA,UAAO,MACP,cAAW,IACX,gBAAa,MACb,cACA,GAAG,KACc;AACjB,KAAI,CAAC,EAAM,OACP,QAAO,IAAa,kBAAC,OAAD;EAAK,WAAW,EAAG,eAAe,EAAU;YAAG;EAAiB,CAAA,GAAG;CAG3F,IAAM,IAAY,EAAe;AAEjC,QACI,kBAAC,OAAD;EAAK,WAAW,EAAG,eAAe,QAAQ,KAAQ,KAAY,YAAY,EAAU;EAAE,GAAI;YACrF,EAAM,KAAK,MAAS;GACjB,IAAM,IAAM,EAAK,OAAO,EAAK,OAAO,UAAU,EACxC,IACF,EAAK,aAAa,EAAK,MAAM,EAAK,OAC9B,kBAAC,GAAD;IACI,WAAW,EAAK;IAChB,IAAI,EAAK;IACT,MAAM,EAAK;IACX,QAAQ,EAAK;IACb,KAAK,EAAK;cAET,EAAK;IACF,CAAA,GAER,EAAK;AAGb,UACI,kBAAC,OAAD;IAAe,WAAU;cACrB,kBAAC,GAAD;KAAS,SAAS;KAAW,OAAO;eAApC,CACI,kBAAC,GAAD,EAAA,UAAA;MACI,kBAAC,GAAD;OAAO,MAAM;OAAW,MAAM;iBACzB,EAAK;OACF,CAAA;MACP,KAAS,kBAAC,OAAD;OAAK,WAAU;iBAAqB;OAAY,CAAA;MACzD,EAAK,cACF,kBAAC,GAAD;OAAO,MAAM;OAAW,MAAM;iBACzB,EAAK;OACF,CAAA;MAEP,EAAA,CAAA,EACR,EAAK,UAAU,kBAAC,OAAD;MAAK,WAAU;gBAAsB,EAAK;MAAa,CAAA,CACjE;;IACR,EAfI,EAeJ;IAEZ;EACA,CAAA"}
1
+ {"version":3,"file":"MDetailList-fDhVyhm7.js","names":[],"sources":["../src/components/display/MRating/MRating.tsx","../src/components/display/MDetailList/MDetailList.tsx"],"sourcesContent":["import {useState} from 'react'\nimport type {MRatingProps} from './MRating.types'\nimport {MStarFillIcon, MStarIcon} from '../../../icons'\nimport {cn} from '../../../utils/cn'\nimport './MRating.css'\n\n// Render an interactive star-based rating control.\nexport function MRating({\n value = 0,\n max = 5,\n color = 'warning',\n size = 'md',\n readOnly = false,\n onChange,\n className,\n ...rest\n}: MRatingProps) {\n const [hovered, setHovered] = useState<number | null>(null)\n const displayValue = hovered ?? value\n\n const handleClick = (index: number) => {\n if (readOnly) return\n onChange?.(index)\n }\n\n return (\n <div\n className={cn('rating', `color-${color}`, size, readOnly && 'read-only', className)}\n role=\"radiogroup\"\n aria-label=\"MRating\"\n onMouseLeave={() => setHovered(null)}\n {...rest}\n >\n {Array.from({length: max}, (_, i) => {\n const starIndex = i + 1\n const filled = displayValue >= starIndex\n return (\n <button\n key={i}\n type=\"button\"\n className=\"rating-star\"\n onClick={() => handleClick(starIndex)}\n onMouseEnter={() => !readOnly && setHovered(starIndex)}\n aria-label={`${starIndex} star${starIndex > 1 ? 's' : ''}`}\n tabIndex={readOnly ? -1 : 0}\n disabled={readOnly}\n >\n <span className=\"star-icon\" aria-hidden=\"true\">\n {filled ? <MStarFillIcon /> : <MStarIcon />}\n </span>\n </button>\n )\n })}\n </div>\n )\n}\n","import type {MSize} from '../../../theme'\nimport type {MDetailListProps} from './MDetailList.types'\nimport {cn} from '../../../utils/cn'\nimport {MInline, MStack} from '../../layout'\nimport {MLink, MText} from '../../typography'\nimport type {MTextSize} from '../../typography'\nimport './MDetailList.css'\n\n// Maps the list's outer size to the secondary-text size used for labels and helper text.\n// Labels sit one notch below the value so they read as metadata, not headline copy.\nconst LABEL_SIZE_MAP: Record<MSize, MTextSize> = {\n xs: 'xs',\n sm: 'xs',\n md: 'sm',\n lg: 'md',\n xl: 'md',\n}\n\nexport function MDetailList({\n items,\n size = 'md',\n bordered = true,\n emptyState = null,\n className,\n ...rest\n}: MDetailListProps) {\n if (!items.length) {\n return emptyState ? <div className={cn('detail-list', className)}>{emptyState}</div> : null\n }\n\n const labelSize = LABEL_SIZE_MAP[size]\n\n return (\n <div className={cn('detail-list', `size-${size}`, bordered && 'bordered', className)} {...rest}>\n {items.map((item) => {\n const key = item.key ?? item.label?.toString()\n const value =\n item.component || item.to || item.href ? (\n <MLink\n component={item.component}\n to={item.to}\n href={item.href}\n target={item.target}\n rel={item.rel}\n >\n {item.value}\n </MLink>\n ) : (\n item.value\n )\n\n return (\n <div key={key} className=\"detail-list-item\">\n <MInline justify={'between'} align={'start'}>\n <MStack>\n <MText size={labelSize} tone={'muted'}>\n {item.label}\n </MText>\n {value && <div className=\"detail-list-value\">{value}</div>}\n {item.helperText && (\n <MText size={labelSize} tone={'muted'}>\n {item.helperText}\n </MText>\n )}\n </MStack>\n {item.status && <div className=\"detail-list-status\">{item.status}</div>}\n </MInline>\n </div>\n )\n })}\n </div>\n )\n}\n"],"mappings":";;;;;;;;;AAOA,SAAgB,EAAQ,EACpB,WAAQ,GACR,SAAM,GACN,WAAQ,WACR,UAAO,MACP,cAAW,IACX,aACA,cACA,GAAG,KACU;CACb,IAAM,CAAC,GAAS,KAAc,EAAwB,KAAK,EACrD,IAAe,KAAW,GAE1B,KAAe,MAAkB;AAC/B,OACJ,IAAW,EAAM;;AAGrB,QACI,kBAAC,OAAD;EACI,WAAW,EAAG,UAAU,SAAS,KAAS,GAAM,KAAY,aAAa,EAAU;EACnF,MAAK;EACL,cAAW;EACX,oBAAoB,EAAW,KAAK;EACpC,GAAI;YAEH,MAAM,KAAK,EAAC,QAAQ,GAAI,GAAG,GAAG,MAAM;GACjC,IAAM,IAAY,IAAI,GAChB,IAAS,KAAgB;AAC/B,UACI,kBAAC,UAAD;IAEI,MAAK;IACL,WAAU;IACV,eAAe,EAAY,EAAU;IACrC,oBAAoB,CAAC,KAAY,EAAW,EAAU;IACtD,cAAY,GAAG,EAAU,OAAO,IAAY,IAAI,MAAM;IACtD,UAAU,IAAW,KAAK;IAC1B,UAAU;cAEV,kBAAC,QAAD;KAAM,WAAU;KAAY,eAAY;eAC1B,EAAT,IAAU,IAAoB,GAArB,EAAiB,CAAgB;KACxC,CAAA;IACF,EAZA,EAYA;IAEf;EACA,CAAA;;;;AC3Cd,IAAM,IAA2C;CAC7C,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACP;AAED,SAAgB,EAAY,EACxB,UACA,UAAO,MACP,cAAW,IACX,gBAAa,MACb,cACA,GAAG,KACc;AACjB,KAAI,CAAC,EAAM,OACP,QAAO,IAAa,kBAAC,OAAD;EAAK,WAAW,EAAG,eAAe,EAAU;YAAG;EAAiB,CAAA,GAAG;CAG3F,IAAM,IAAY,EAAe;AAEjC,QACI,kBAAC,OAAD;EAAK,WAAW,EAAG,eAAe,QAAQ,KAAQ,KAAY,YAAY,EAAU;EAAE,GAAI;YACrF,EAAM,KAAK,MAAS;GACjB,IAAM,IAAM,EAAK,OAAO,EAAK,OAAO,UAAU,EACxC,IACF,EAAK,aAAa,EAAK,MAAM,EAAK,OAC9B,kBAAC,GAAD;IACI,WAAW,EAAK;IAChB,IAAI,EAAK;IACT,MAAM,EAAK;IACX,QAAQ,EAAK;IACb,KAAK,EAAK;cAET,EAAK;IACF,CAAA,GAER,EAAK;AAGb,UACI,kBAAC,OAAD;IAAe,WAAU;cACrB,kBAAC,GAAD;KAAS,SAAS;KAAW,OAAO;eAApC,CACI,kBAAC,GAAD,EAAA,UAAA;MACI,kBAAC,GAAD;OAAO,MAAM;OAAW,MAAM;iBACzB,EAAK;OACF,CAAA;MACP,KAAS,kBAAC,OAAD;OAAK,WAAU;iBAAqB;OAAY,CAAA;MACzD,EAAK,cACF,kBAAC,GAAD;OAAO,MAAM;OAAW,MAAM;iBACzB,EAAK;OACF,CAAA;MAEP,EAAA,CAAA,EACR,EAAK,UAAU,kBAAC,OAAD;MAAK,WAAU;gBAAsB,EAAK;MAAa,CAAA,CACjE;;IACR,EAfI,EAeJ;IAEZ;EACA,CAAA"}
@@ -1,2 +1,2 @@
1
- const e=require(`./cn-CU5TNITO.cjs`),t=require(`./useKeyboardNav-HVG9JFD2.cjs`),n=require(`./MPopover-hDqrn317.cjs`);require(`./core-DBpQf3uY.cjs`);let r=require(`react`),i=require(`react/jsx-runtime`);function a(e){return e.props}function o(e){return!!e.type.__dropdownItem}function s(e){return!!e.type.__dropdownGroup}function c(e){let t=[];return r.Children.forEach(e,e=>{(0,r.isValidElement)(e)&&(o(e)?t.push(e):s(e)&&r.Children.forEach(a(e).children,e=>{(0,r.isValidElement)(e)&&o(e)&&t.push(e)}))}),t}function l({trigger:l,placement:u=`bottom-start`,closeOnSelect:d=!0,openOn:f=`click`,onOpenChange:p,isolateClick:m=!1,className:h,style:g,popoverClassName:_,popoverStyle:v,children:y}){let[b,x]=(0,r.useState)(!1),S=(0,r.useRef)(null),C=(0,r.useRef)(null),w=c(y),T=w.filter(e=>!a(e).disabled).length,E=(0,r.useCallback)(e=>{x(t=>{let n=typeof e==`function`?e(t):e;return p?.(n),n})},[p]),{activeIndex:D,setActiveIndex:O,onKeyDown:k}=t.t({itemCount:T,onSelect:(0,r.useCallback)(e=>{let t=0;for(let n of w){let r=a(n);if(!r.disabled){if(t===e){r.onClick?.();break}t++}}d&&E(!1)},[w,d,E]),onClose:()=>x(!1),isOpen:b}),A=e=>{m&&(e.stopPropagation(),e.preventDefault()),E(e=>!e)},j=e=>{(e.key===`ArrowDown`||e.key===`Enter`||e.key===` `)&&(e.preventDefault(),m&&e.stopPropagation(),E(!0)),b&&k(e)},M=0,N=e=>{if(!(0,r.isValidElement)(e))return e;if(o(e)){let t=a(e).disabled,n=t?-1:M++;return(0,r.cloneElement)(e,{_active:n===D,_onHover:t?void 0:()=>O(n),_onClick:()=>{t||d&&E(!1)}})}return s(e)?(0,r.cloneElement)(e,{children:r.Children.map(a(e).children,N)}):e},P=f===`hover`?{onMouseEnter:()=>{C.current&&clearTimeout(C.current),E(!0)},onMouseLeave:()=>{C.current=setTimeout(()=>E(!1),150)}}:{},F=m?e=>{e.stopPropagation(),e.preventDefault()}:void 0;return(0,i.jsxs)(`div`,{className:e.t(`dropdown menu anchor`,h),style:g,onClick:F,...P,children:[(0,i.jsx)(`div`,{ref:S,onClick:f===`click`?A:void 0,onKeyDown:j,role:`button`,tabIndex:0,className:`dropdown menu trigger`,children:l}),(0,i.jsx)(n.t,{open:b,anchorRef:S,onClose:()=>E(!1),placement:u,className:e.t(`dropdown menu popover`,_),style:v,children:(0,i.jsx)(`div`,{className:`dropdown menu list`,role:`menu`,...P,children:r.Children.map(y,N)})})]})}function u({icon:t,label:n,href:r,to:a,onClick:o,color:s,disabled:c=!1,active:l=!1,component:u,className:d,_active:f,_onHover:p,_onClick:m}){let h=f??l,g=(0,i.jsxs)(i.Fragment,{children:[t&&(0,i.jsx)(`span`,{className:`dropdown menu icon`,children:t}),(0,i.jsx)(`span`,{className:`dropdown menu label`,children:n})]}),_=e.t(`dropdown menu item`,h&&`active`,c&&`disabled`,s,d),v=e=>{if(c){e.preventDefault();return}o?.(),m?.()},y=u??(r||a?`a`:`button`),b=u?{...r?{href:r}:{},...a?{to:a}:{}}:r?{href:r}:a?{href:a}:{};return(0,i.jsx)(y,{className:_,role:`menuitem`,tabIndex:-1,onClick:v,onMouseEnter:p,"aria-disabled":c||void 0,...b,children:g})}u.__dropdownItem=!0;function d({label:e,children:t}){return(0,i.jsxs)(`div`,{className:`dropdown menu group`,role:`group`,children:[(0,i.jsx)(`div`,{className:`dropdown menu group-label`,children:e}),t]})}d.__dropdownGroup=!0;function f({className:t}){return(0,i.jsx)(`div`,{className:e.t(`dropdown menu divider`,t),role:`separator`})}Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return f}});
2
- //# sourceMappingURL=MDropdownMenu-hXaIMkAj.cjs.map
1
+ const e=require(`./cn-CU5TNITO.cjs`),t=require(`./useKeyboardNav-HVG9JFD2.cjs`),n=require(`./MPopover-CV-9MArH.cjs`);require(`./core-DBpQf3uY.cjs`);let r=require(`react`),i=require(`react/jsx-runtime`);function a(e){return e.props}function o(e){return!!e.type.__dropdownItem}function s(e){return!!e.type.__dropdownGroup}function c(e){let t=[];return r.Children.forEach(e,e=>{(0,r.isValidElement)(e)&&(o(e)?t.push(e):s(e)&&r.Children.forEach(a(e).children,e=>{(0,r.isValidElement)(e)&&o(e)&&t.push(e)}))}),t}function l({trigger:l,placement:u=`bottom-start`,closeOnSelect:d=!0,openOn:f=`click`,onOpenChange:p,isolateClick:m=!1,className:h,style:g,popoverClassName:_,popoverStyle:v,children:y}){let[b,x]=(0,r.useState)(!1),S=(0,r.useRef)(null),C=(0,r.useRef)(null),w=c(y),T=w.filter(e=>!a(e).disabled).length,E=(0,r.useCallback)(e=>{x(t=>{let n=typeof e==`function`?e(t):e;return p?.(n),n})},[p]),{activeIndex:D,setActiveIndex:O,onKeyDown:k}=t.t({itemCount:T,onSelect:(0,r.useCallback)(e=>{let t=0;for(let n of w){let r=a(n);if(!r.disabled){if(t===e){r.onClick?.();break}t++}}d&&E(!1)},[w,d,E]),onClose:()=>x(!1),isOpen:b}),A=e=>{m&&(e.stopPropagation(),e.preventDefault()),E(e=>!e)},j=e=>{(e.key===`ArrowDown`||e.key===`Enter`||e.key===` `)&&(e.preventDefault(),m&&e.stopPropagation(),E(!0)),b&&k(e)},M=0,N=e=>{if(!(0,r.isValidElement)(e))return e;if(o(e)){let t=a(e).disabled,n=t?-1:M++;return(0,r.cloneElement)(e,{_active:n===D,_onHover:t?void 0:()=>O(n),_onClick:()=>{t||d&&E(!1)}})}return s(e)?(0,r.cloneElement)(e,{children:r.Children.map(a(e).children,N)}):e},P=f===`hover`?{onMouseEnter:()=>{C.current&&clearTimeout(C.current),E(!0)},onMouseLeave:()=>{C.current=setTimeout(()=>E(!1),150)}}:{},F=m?e=>{e.stopPropagation(),e.preventDefault()}:void 0;return(0,i.jsxs)(`div`,{className:e.t(`dropdown menu anchor`,h),style:g,onClick:F,...P,children:[(0,i.jsx)(`div`,{ref:S,onClick:f===`click`?A:void 0,onKeyDown:j,role:`button`,tabIndex:0,className:`dropdown menu trigger`,children:l}),(0,i.jsx)(n.t,{open:b,anchorRef:S,onClose:()=>E(!1),placement:u,className:e.t(`dropdown menu popover`,_),style:v,children:(0,i.jsx)(`div`,{className:`dropdown menu list`,role:`menu`,...P,children:r.Children.map(y,N)})})]})}function u({icon:t,label:n,href:r,to:a,onClick:o,color:s,disabled:c=!1,active:l=!1,component:u,className:d,_active:f,_onHover:p,_onClick:m}){let h=f??l,g=(0,i.jsxs)(i.Fragment,{children:[t&&(0,i.jsx)(`span`,{className:`dropdown menu icon`,children:t}),(0,i.jsx)(`span`,{className:`dropdown menu label`,children:n})]}),_=e.t(`dropdown menu item`,h&&`active`,c&&`disabled`,s,d),v=e=>{if(c){e.preventDefault();return}o?.(),m?.()},y=u??(r||a?`a`:`button`),b=u?{...r?{href:r}:{},...a?{to:a}:{}}:r?{href:r}:a?{href:a}:{};return(0,i.jsx)(y,{className:_,role:`menuitem`,tabIndex:-1,onClick:v,onMouseEnter:p,"aria-disabled":c||void 0,...b,children:g})}u.__dropdownItem=!0;function d({label:e,children:t}){return(0,i.jsxs)(`div`,{className:`dropdown menu group`,role:`group`,children:[(0,i.jsx)(`div`,{className:`dropdown menu group-label`,children:e}),t]})}d.__dropdownGroup=!0;function f({className:t}){return(0,i.jsx)(`div`,{className:e.t(`dropdown menu divider`,t),role:`separator`})}Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return f}});
2
+ //# sourceMappingURL=MDropdownMenu-BvN5grK5.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MDropdownMenu-hXaIMkAj.cjs","names":[],"sources":["../src/components/overlays/MDropdownMenu/MDropdownMenu.tsx"],"sourcesContent":["import {useState, useRef, useCallback, Children, isValidElement, cloneElement} from 'react'\nimport type * as React from 'react'\nimport {MPopover} from '../../primitives'\nimport {useKeyboardNav} from '../../../utils/useKeyboardNav'\nimport {cn} from '../../../utils/cn'\nimport type {\n MDropdownMenuProps,\n MDropdownItemProps,\n MDropdownGroupProps,\n MDropdownDividerProps,\n} from './MDropdownMenu.types'\nimport './MDropdownMenu.css'\n\ntype AnyProps = Record<string, any>\n\nfunction getProps(el: React.ReactElement): AnyProps {\n return el.props as AnyProps\n}\n\nfunction isItem(child: React.ReactElement): boolean {\n return !!(child.type as any).__dropdownItem\n}\n\nfunction isGroup(child: React.ReactElement): boolean {\n return !!(child.type as any).__dropdownGroup\n}\n\n// Collect all MDropdownItem elements from children (including inside groups).\nfunction collectItems(children: React.ReactNode): React.ReactElement[] {\n const items: React.ReactElement[] = []\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return\n if (isItem(child)) {\n items.push(child)\n } else if (isGroup(child)) {\n Children.forEach(getProps(child).children, (gc: React.ReactNode) => {\n if (isValidElement(gc) && isItem(gc)) {\n items.push(gc)\n }\n })\n }\n })\n return items\n}\n\nexport function MDropdownMenu({\n trigger,\n placement = 'bottom-start',\n closeOnSelect = true,\n openOn = 'click',\n onOpenChange,\n isolateClick = false,\n className,\n style,\n popoverClassName,\n popoverStyle,\n children,\n}: MDropdownMenuProps) {\n const [open, setOpen] = useState(false)\n const anchorRef = useRef<HTMLDivElement>(null)\n const hoverTimeout = useRef<ReturnType<typeof setTimeout>>(null)\n\n const items = collectItems(children)\n const enabledCount = items.filter((i) => !getProps(i).disabled).length\n\n const setMenuOpen = useCallback(\n (next: boolean | ((prev: boolean) => boolean)) => {\n setOpen((prev) => {\n const resolved = typeof next === 'function' ? next(prev) : next\n onOpenChange?.(resolved)\n return resolved\n })\n },\n [onOpenChange]\n )\n\n const handleSelect = useCallback(\n (index: number) => {\n let enabledIdx = 0\n for (const item of items) {\n const p = getProps(item)\n if (p.disabled) continue\n if (enabledIdx === index) {\n p.onClick?.()\n break\n }\n enabledIdx++\n }\n if (closeOnSelect) setMenuOpen(false)\n },\n [items, closeOnSelect, setMenuOpen]\n )\n\n const {activeIndex, setActiveIndex, onKeyDown} = useKeyboardNav({\n itemCount: enabledCount,\n onSelect: handleSelect,\n onClose: () => setOpen(false),\n isOpen: open,\n })\n\n const handleTriggerClick = (e: React.MouseEvent) => {\n if (isolateClick) {\n e.stopPropagation()\n e.preventDefault()\n }\n setMenuOpen((o) => !o)\n }\n\n const handleTriggerKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n if (isolateClick) e.stopPropagation()\n setMenuOpen(true)\n }\n if (open) onKeyDown(e as any)\n }\n\n // Map active index back to flat child rendering with enabled-only tracking.\n let enabledIdx = 0\n const renderChild = (child: React.ReactNode): React.ReactNode => {\n if (!isValidElement(child)) return child\n\n if (isItem(child)) {\n const p = getProps(child)\n const isDisabled = p.disabled\n const idx = isDisabled ? -1 : enabledIdx++\n return cloneElement(child, {\n _active: idx === activeIndex,\n _onHover: isDisabled ? undefined : () => setActiveIndex(idx),\n _onClick: () => {\n if (isDisabled) return\n if (closeOnSelect) setMenuOpen(false)\n },\n } as AnyProps)\n }\n\n if (isGroup(child)) {\n return cloneElement(child, {\n children: Children.map(getProps(child).children, renderChild),\n } as AnyProps)\n }\n\n return child\n }\n\n const hoverHandlers =\n openOn === 'hover'\n ? {\n onMouseEnter: () => {\n if (hoverTimeout.current) clearTimeout(hoverTimeout.current)\n setMenuOpen(true)\n },\n onMouseLeave: () => {\n hoverTimeout.current = setTimeout(() => setMenuOpen(false), 150)\n },\n }\n : {}\n\n /**\n * When `isolateClick` is set, every click bubbling out of the menu\n * (trigger AND items) must be stopped — otherwise selecting an action\n * also fires the click handler on a clickable parent (Link, MCard with\n * onClick, MDataTable row link). Trigger click itself is handled by\n * `handleTriggerClick`; this wrapper catches the bubbled item clicks\n * before they leave the anchor. `preventDefault` is needed too — when the\n * dropdown is rendered inside an `<a href>` (MCard component={Link}),\n * stopping propagation alone does not block native link navigation.\n *\n * Caveat: MDropdownItem with `href` will not navigate while inside an\n * `isolateClick` menu — use programmatic navigation (onClick + navigate)\n * in those contexts instead.\n */\n const isolateAnchorClick = isolateClick\n ? (e: React.MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n }\n : undefined\n\n return (\n <div\n className={cn('dropdown menu anchor', className)}\n style={style}\n onClick={isolateAnchorClick}\n {...hoverHandlers}\n >\n <div\n ref={anchorRef}\n onClick={openOn === 'click' ? handleTriggerClick : undefined}\n onKeyDown={handleTriggerKeyDown}\n role=\"button\"\n tabIndex={0}\n className=\"dropdown menu trigger\"\n >\n {trigger}\n </div>\n <MPopover\n open={open}\n anchorRef={anchorRef}\n onClose={() => setMenuOpen(false)}\n placement={placement}\n className={cn('dropdown menu popover', popoverClassName)}\n style={popoverStyle}\n >\n <div className=\"dropdown menu list\" role=\"menu\" {...hoverHandlers}>\n {Children.map(children, renderChild)}\n </div>\n </MPopover>\n </div>\n )\n}\n\nexport function MDropdownItem({\n icon,\n label,\n href,\n to,\n onClick,\n color,\n disabled = false,\n active = false,\n component,\n className,\n _active,\n _onHover,\n _onClick,\n}: MDropdownItemProps & {_active?: boolean; _onHover?: () => void; _onClick?: () => void}) {\n const isHighlighted = _active ?? active\n\n const content = (\n <>\n {icon && <span className=\"dropdown menu icon\">{icon}</span>}\n <span className=\"dropdown menu label\">{label}</span>\n </>\n )\n\n const cls = cn('dropdown menu item', isHighlighted && 'active', disabled && 'disabled', color, className)\n\n const handleClick = (e: React.MouseEvent) => {\n if (disabled) {\n e.preventDefault()\n return\n }\n onClick?.()\n _onClick?.()\n }\n\n const Tag = component ?? (href || to ? 'a' : 'button')\n const linkProps = component ? {...(href ? {href} : {}), ...(to ? {to} : {})} : href ? {href} : to ? {href: to} : {}\n\n return (\n <Tag\n className={cls}\n role=\"menuitem\"\n tabIndex={-1}\n onClick={handleClick}\n onMouseEnter={_onHover}\n aria-disabled={disabled || undefined}\n {...linkProps}\n >\n {content}\n </Tag>\n )\n}\n;(MDropdownItem as any).__dropdownItem = true\n\nexport function MDropdownGroup({label, children}: MDropdownGroupProps) {\n return (\n <div className=\"dropdown menu group\" role=\"group\">\n <div className=\"dropdown menu group-label\">{label}</div>\n {children}\n </div>\n )\n}\n;(MDropdownGroup as any).__dropdownGroup = true\n\nexport function MDropdownDivider({className}: MDropdownDividerProps) {\n return <div className={cn('dropdown menu divider', className)} role=\"separator\" />\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MDropdownMenu-BvN5grK5.cjs","names":[],"sources":["../src/components/overlays/MDropdownMenu/MDropdownMenu.tsx"],"sourcesContent":["import {useState, useRef, useCallback, Children, isValidElement, cloneElement} from 'react'\nimport type * as React from 'react'\nimport {MPopover} from '../../primitives'\nimport {useKeyboardNav} from '../../../utils/useKeyboardNav'\nimport {cn} from '../../../utils/cn'\nimport type {\n MDropdownMenuProps,\n MDropdownItemProps,\n MDropdownGroupProps,\n MDropdownDividerProps,\n} from './MDropdownMenu.types'\nimport './MDropdownMenu.css'\n\ntype AnyProps = Record<string, any>\n\nfunction getProps(el: React.ReactElement): AnyProps {\n return el.props as AnyProps\n}\n\nfunction isItem(child: React.ReactElement): boolean {\n return !!(child.type as any).__dropdownItem\n}\n\nfunction isGroup(child: React.ReactElement): boolean {\n return !!(child.type as any).__dropdownGroup\n}\n\n// Collect all MDropdownItem elements from children (including inside groups).\nfunction collectItems(children: React.ReactNode): React.ReactElement[] {\n const items: React.ReactElement[] = []\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return\n if (isItem(child)) {\n items.push(child)\n } else if (isGroup(child)) {\n Children.forEach(getProps(child).children, (gc: React.ReactNode) => {\n if (isValidElement(gc) && isItem(gc)) {\n items.push(gc)\n }\n })\n }\n })\n return items\n}\n\nexport function MDropdownMenu({\n trigger,\n placement = 'bottom-start',\n closeOnSelect = true,\n openOn = 'click',\n onOpenChange,\n isolateClick = false,\n className,\n style,\n popoverClassName,\n popoverStyle,\n children,\n}: MDropdownMenuProps) {\n const [open, setOpen] = useState(false)\n const anchorRef = useRef<HTMLDivElement>(null)\n const hoverTimeout = useRef<ReturnType<typeof setTimeout>>(null)\n\n const items = collectItems(children)\n const enabledCount = items.filter((i) => !getProps(i).disabled).length\n\n const setMenuOpen = useCallback(\n (next: boolean | ((prev: boolean) => boolean)) => {\n setOpen((prev) => {\n const resolved = typeof next === 'function' ? next(prev) : next\n onOpenChange?.(resolved)\n return resolved\n })\n },\n [onOpenChange]\n )\n\n const handleSelect = useCallback(\n (index: number) => {\n let enabledIdx = 0\n for (const item of items) {\n const p = getProps(item)\n if (p.disabled) continue\n if (enabledIdx === index) {\n p.onClick?.()\n break\n }\n enabledIdx++\n }\n if (closeOnSelect) setMenuOpen(false)\n },\n [items, closeOnSelect, setMenuOpen]\n )\n\n const {activeIndex, setActiveIndex, onKeyDown} = useKeyboardNav({\n itemCount: enabledCount,\n onSelect: handleSelect,\n onClose: () => setOpen(false),\n isOpen: open,\n })\n\n const handleTriggerClick = (e: React.MouseEvent) => {\n if (isolateClick) {\n e.stopPropagation()\n e.preventDefault()\n }\n setMenuOpen((o) => !o)\n }\n\n const handleTriggerKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n if (isolateClick) e.stopPropagation()\n setMenuOpen(true)\n }\n if (open) onKeyDown(e as any)\n }\n\n // Map active index back to flat child rendering with enabled-only tracking.\n let enabledIdx = 0\n const renderChild = (child: React.ReactNode): React.ReactNode => {\n if (!isValidElement(child)) return child\n\n if (isItem(child)) {\n const p = getProps(child)\n const isDisabled = p.disabled\n const idx = isDisabled ? -1 : enabledIdx++\n return cloneElement(child, {\n _active: idx === activeIndex,\n _onHover: isDisabled ? undefined : () => setActiveIndex(idx),\n _onClick: () => {\n if (isDisabled) return\n if (closeOnSelect) setMenuOpen(false)\n },\n } as AnyProps)\n }\n\n if (isGroup(child)) {\n return cloneElement(child, {\n children: Children.map(getProps(child).children, renderChild),\n } as AnyProps)\n }\n\n return child\n }\n\n const hoverHandlers =\n openOn === 'hover'\n ? {\n onMouseEnter: () => {\n if (hoverTimeout.current) clearTimeout(hoverTimeout.current)\n setMenuOpen(true)\n },\n onMouseLeave: () => {\n hoverTimeout.current = setTimeout(() => setMenuOpen(false), 150)\n },\n }\n : {}\n\n /**\n * When `isolateClick` is set, every click bubbling out of the menu\n * (trigger AND items) must be stopped — otherwise selecting an action\n * also fires the click handler on a clickable parent (Link, MCard with\n * onClick, MDataTable row link). Trigger click itself is handled by\n * `handleTriggerClick`; this wrapper catches the bubbled item clicks\n * before they leave the anchor. `preventDefault` is needed too — when the\n * dropdown is rendered inside an `<a href>` (MCard component={Link}),\n * stopping propagation alone does not block native link navigation.\n *\n * Caveat: MDropdownItem with `href` will not navigate while inside an\n * `isolateClick` menu — use programmatic navigation (onClick + navigate)\n * in those contexts instead.\n */\n const isolateAnchorClick = isolateClick\n ? (e: React.MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n }\n : undefined\n\n return (\n <div\n className={cn('dropdown menu anchor', className)}\n style={style}\n onClick={isolateAnchorClick}\n {...hoverHandlers}\n >\n <div\n ref={anchorRef}\n onClick={openOn === 'click' ? handleTriggerClick : undefined}\n onKeyDown={handleTriggerKeyDown}\n role=\"button\"\n tabIndex={0}\n className=\"dropdown menu trigger\"\n >\n {trigger}\n </div>\n <MPopover\n open={open}\n anchorRef={anchorRef}\n onClose={() => setMenuOpen(false)}\n placement={placement}\n className={cn('dropdown menu popover', popoverClassName)}\n style={popoverStyle}\n >\n <div className=\"dropdown menu list\" role=\"menu\" {...hoverHandlers}>\n {Children.map(children, renderChild)}\n </div>\n </MPopover>\n </div>\n )\n}\n\nexport function MDropdownItem({\n icon,\n label,\n href,\n to,\n onClick,\n color,\n disabled = false,\n active = false,\n component,\n className,\n _active,\n _onHover,\n _onClick,\n}: MDropdownItemProps & {_active?: boolean; _onHover?: () => void; _onClick?: () => void}) {\n const isHighlighted = _active ?? active\n\n const content = (\n <>\n {icon && <span className=\"dropdown menu icon\">{icon}</span>}\n <span className=\"dropdown menu label\">{label}</span>\n </>\n )\n\n const cls = cn('dropdown menu item', isHighlighted && 'active', disabled && 'disabled', color, className)\n\n const handleClick = (e: React.MouseEvent) => {\n if (disabled) {\n e.preventDefault()\n return\n }\n onClick?.()\n _onClick?.()\n }\n\n const Tag = component ?? (href || to ? 'a' : 'button')\n const linkProps = component ? {...(href ? {href} : {}), ...(to ? {to} : {})} : href ? {href} : to ? {href: to} : {}\n\n return (\n <Tag\n className={cls}\n role=\"menuitem\"\n tabIndex={-1}\n onClick={handleClick}\n onMouseEnter={_onHover}\n aria-disabled={disabled || undefined}\n {...linkProps}\n >\n {content}\n </Tag>\n )\n}\n;(MDropdownItem as any).__dropdownItem = true\n\nexport function MDropdownGroup({label, children}: MDropdownGroupProps) {\n return (\n <div className=\"dropdown menu group\" role=\"group\">\n <div className=\"dropdown menu group-label\">{label}</div>\n {children}\n </div>\n )\n}\n;(MDropdownGroup as any).__dropdownGroup = true\n\nexport function MDropdownDivider({className}: MDropdownDividerProps) {\n return <div className={cn('dropdown menu divider', className)} role=\"separator\" />\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { t as e } from "./cn-YER3QsV1.js";
2
2
  import { t } from "./useKeyboardNav-iEXOdEMB.js";
3
- import { t as n } from "./MPopover-BRuwva-c.js";
3
+ import { t as n } from "./MPopover-C5aaGhma.js";
4
4
  import { Children as r, cloneElement as i, isValidElement as a, useCallback as o, useRef as s, useState as c } from "react";
5
5
  import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
6
6
  //#region src/components/overlays/MDropdownMenu/MDropdownMenu.tsx
@@ -154,4 +154,4 @@ function y({ className: t }) {
154
154
  //#endregion
155
155
  export { g as i, v as n, _ as r, y as t };
156
156
 
157
- //# sourceMappingURL=MDropdownMenu-CZmU3uku.js.map
157
+ //# sourceMappingURL=MDropdownMenu-CFoKJ7V6.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MDropdownMenu-CZmU3uku.js","names":[],"sources":["../src/components/overlays/MDropdownMenu/MDropdownMenu.tsx"],"sourcesContent":["import {useState, useRef, useCallback, Children, isValidElement, cloneElement} from 'react'\nimport type * as React from 'react'\nimport {MPopover} from '../../primitives'\nimport {useKeyboardNav} from '../../../utils/useKeyboardNav'\nimport {cn} from '../../../utils/cn'\nimport type {\n MDropdownMenuProps,\n MDropdownItemProps,\n MDropdownGroupProps,\n MDropdownDividerProps,\n} from './MDropdownMenu.types'\nimport './MDropdownMenu.css'\n\ntype AnyProps = Record<string, any>\n\nfunction getProps(el: React.ReactElement): AnyProps {\n return el.props as AnyProps\n}\n\nfunction isItem(child: React.ReactElement): boolean {\n return !!(child.type as any).__dropdownItem\n}\n\nfunction isGroup(child: React.ReactElement): boolean {\n return !!(child.type as any).__dropdownGroup\n}\n\n// Collect all MDropdownItem elements from children (including inside groups).\nfunction collectItems(children: React.ReactNode): React.ReactElement[] {\n const items: React.ReactElement[] = []\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return\n if (isItem(child)) {\n items.push(child)\n } else if (isGroup(child)) {\n Children.forEach(getProps(child).children, (gc: React.ReactNode) => {\n if (isValidElement(gc) && isItem(gc)) {\n items.push(gc)\n }\n })\n }\n })\n return items\n}\n\nexport function MDropdownMenu({\n trigger,\n placement = 'bottom-start',\n closeOnSelect = true,\n openOn = 'click',\n onOpenChange,\n isolateClick = false,\n className,\n style,\n popoverClassName,\n popoverStyle,\n children,\n}: MDropdownMenuProps) {\n const [open, setOpen] = useState(false)\n const anchorRef = useRef<HTMLDivElement>(null)\n const hoverTimeout = useRef<ReturnType<typeof setTimeout>>(null)\n\n const items = collectItems(children)\n const enabledCount = items.filter((i) => !getProps(i).disabled).length\n\n const setMenuOpen = useCallback(\n (next: boolean | ((prev: boolean) => boolean)) => {\n setOpen((prev) => {\n const resolved = typeof next === 'function' ? next(prev) : next\n onOpenChange?.(resolved)\n return resolved\n })\n },\n [onOpenChange]\n )\n\n const handleSelect = useCallback(\n (index: number) => {\n let enabledIdx = 0\n for (const item of items) {\n const p = getProps(item)\n if (p.disabled) continue\n if (enabledIdx === index) {\n p.onClick?.()\n break\n }\n enabledIdx++\n }\n if (closeOnSelect) setMenuOpen(false)\n },\n [items, closeOnSelect, setMenuOpen]\n )\n\n const {activeIndex, setActiveIndex, onKeyDown} = useKeyboardNav({\n itemCount: enabledCount,\n onSelect: handleSelect,\n onClose: () => setOpen(false),\n isOpen: open,\n })\n\n const handleTriggerClick = (e: React.MouseEvent) => {\n if (isolateClick) {\n e.stopPropagation()\n e.preventDefault()\n }\n setMenuOpen((o) => !o)\n }\n\n const handleTriggerKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n if (isolateClick) e.stopPropagation()\n setMenuOpen(true)\n }\n if (open) onKeyDown(e as any)\n }\n\n // Map active index back to flat child rendering with enabled-only tracking.\n let enabledIdx = 0\n const renderChild = (child: React.ReactNode): React.ReactNode => {\n if (!isValidElement(child)) return child\n\n if (isItem(child)) {\n const p = getProps(child)\n const isDisabled = p.disabled\n const idx = isDisabled ? -1 : enabledIdx++\n return cloneElement(child, {\n _active: idx === activeIndex,\n _onHover: isDisabled ? undefined : () => setActiveIndex(idx),\n _onClick: () => {\n if (isDisabled) return\n if (closeOnSelect) setMenuOpen(false)\n },\n } as AnyProps)\n }\n\n if (isGroup(child)) {\n return cloneElement(child, {\n children: Children.map(getProps(child).children, renderChild),\n } as AnyProps)\n }\n\n return child\n }\n\n const hoverHandlers =\n openOn === 'hover'\n ? {\n onMouseEnter: () => {\n if (hoverTimeout.current) clearTimeout(hoverTimeout.current)\n setMenuOpen(true)\n },\n onMouseLeave: () => {\n hoverTimeout.current = setTimeout(() => setMenuOpen(false), 150)\n },\n }\n : {}\n\n /**\n * When `isolateClick` is set, every click bubbling out of the menu\n * (trigger AND items) must be stopped — otherwise selecting an action\n * also fires the click handler on a clickable parent (Link, MCard with\n * onClick, MDataTable row link). Trigger click itself is handled by\n * `handleTriggerClick`; this wrapper catches the bubbled item clicks\n * before they leave the anchor. `preventDefault` is needed too — when the\n * dropdown is rendered inside an `<a href>` (MCard component={Link}),\n * stopping propagation alone does not block native link navigation.\n *\n * Caveat: MDropdownItem with `href` will not navigate while inside an\n * `isolateClick` menu — use programmatic navigation (onClick + navigate)\n * in those contexts instead.\n */\n const isolateAnchorClick = isolateClick\n ? (e: React.MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n }\n : undefined\n\n return (\n <div\n className={cn('dropdown menu anchor', className)}\n style={style}\n onClick={isolateAnchorClick}\n {...hoverHandlers}\n >\n <div\n ref={anchorRef}\n onClick={openOn === 'click' ? handleTriggerClick : undefined}\n onKeyDown={handleTriggerKeyDown}\n role=\"button\"\n tabIndex={0}\n className=\"dropdown menu trigger\"\n >\n {trigger}\n </div>\n <MPopover\n open={open}\n anchorRef={anchorRef}\n onClose={() => setMenuOpen(false)}\n placement={placement}\n className={cn('dropdown menu popover', popoverClassName)}\n style={popoverStyle}\n >\n <div className=\"dropdown menu list\" role=\"menu\" {...hoverHandlers}>\n {Children.map(children, renderChild)}\n </div>\n </MPopover>\n </div>\n )\n}\n\nexport function MDropdownItem({\n icon,\n label,\n href,\n to,\n onClick,\n color,\n disabled = false,\n active = false,\n component,\n className,\n _active,\n _onHover,\n _onClick,\n}: MDropdownItemProps & {_active?: boolean; _onHover?: () => void; _onClick?: () => void}) {\n const isHighlighted = _active ?? active\n\n const content = (\n <>\n {icon && <span className=\"dropdown menu icon\">{icon}</span>}\n <span className=\"dropdown menu label\">{label}</span>\n </>\n )\n\n const cls = cn('dropdown menu item', isHighlighted && 'active', disabled && 'disabled', color, className)\n\n const handleClick = (e: React.MouseEvent) => {\n if (disabled) {\n e.preventDefault()\n return\n }\n onClick?.()\n _onClick?.()\n }\n\n const Tag = component ?? (href || to ? 'a' : 'button')\n const linkProps = component ? {...(href ? {href} : {}), ...(to ? {to} : {})} : href ? {href} : to ? {href: to} : {}\n\n return (\n <Tag\n className={cls}\n role=\"menuitem\"\n tabIndex={-1}\n onClick={handleClick}\n onMouseEnter={_onHover}\n aria-disabled={disabled || undefined}\n {...linkProps}\n >\n {content}\n </Tag>\n )\n}\n;(MDropdownItem as any).__dropdownItem = true\n\nexport function MDropdownGroup({label, children}: MDropdownGroupProps) {\n return (\n <div className=\"dropdown menu group\" role=\"group\">\n <div className=\"dropdown menu group-label\">{label}</div>\n {children}\n </div>\n )\n}\n;(MDropdownGroup as any).__dropdownGroup = true\n\nexport function MDropdownDivider({className}: MDropdownDividerProps) {\n return <div className={cn('dropdown menu divider', className)} role=\"separator\" />\n}\n"],"mappings":";;;;;;AAeA,SAAS,EAAS,GAAkC;AAChD,QAAO,EAAG;;AAGd,SAAS,EAAO,GAAoC;AAChD,QAAO,CAAC,CAAE,EAAM,KAAa;;AAGjC,SAAS,EAAQ,GAAoC;AACjD,QAAO,CAAC,CAAE,EAAM,KAAa;;AAIjC,SAAS,EAAa,GAAiD;CACnE,IAAM,IAA8B,EAAE;AAatC,QAZA,EAAS,QAAQ,IAAW,MAAU;AAC7B,IAAe,EAAM,KACtB,EAAO,EAAM,GACb,EAAM,KAAK,EAAM,GACV,EAAQ,EAAM,IACrB,EAAS,QAAQ,EAAS,EAAM,CAAC,WAAW,MAAwB;AAChE,GAAI,EAAe,EAAG,IAAI,EAAO,EAAG,IAChC,EAAM,KAAK,EAAG;IAEpB;GAER,EACK;;AAGX,SAAgB,EAAc,EAC1B,YACA,eAAY,gBACZ,mBAAgB,IAChB,YAAS,SACT,iBACA,kBAAe,IACf,cACA,UACA,qBACA,iBACA,eACmB;CACnB,IAAM,CAAC,GAAM,KAAW,EAAS,GAAM,EACjC,IAAY,EAAuB,KAAK,EACxC,IAAe,EAAsC,KAAK,EAE1D,IAAQ,EAAa,EAAS,EAC9B,IAAe,EAAM,QAAQ,MAAM,CAAC,EAAS,EAAE,CAAC,SAAS,CAAC,QAE1D,IAAc,GACf,MAAiD;AAC9C,KAAS,MAAS;GACd,IAAM,IAAW,OAAO,KAAS,aAAa,EAAK,EAAK,GAAG;AAE3D,UADA,IAAe,EAAS,EACjB;IACT;IAEN,CAAC,EAAa,CACjB,EAmBK,EAAC,gBAAa,mBAAgB,iBAAa,EAAe;EAC5D,WAAW;EACX,UAnBiB,GAChB,MAAkB;GACf,IAAI,IAAa;AACjB,QAAK,IAAM,KAAQ,GAAO;IACtB,IAAM,IAAI,EAAS,EAAK;AACpB,WAAE,UACN;SAAI,MAAe,GAAO;AACtB,QAAE,WAAW;AACb;;AAEJ;;;AAEJ,GAAI,KAAe,EAAY,GAAM;KAEzC;GAAC;GAAO;GAAe;GAAY,CACtC;EAKG,eAAe,EAAQ,GAAM;EAC7B,QAAQ;EACX,CAAC,EAEI,KAAsB,MAAwB;AAKhD,EAJI,MACA,EAAE,iBAAiB,EACnB,EAAE,gBAAgB,GAEtB,GAAa,MAAM,CAAC,EAAE;IAGpB,KAAwB,MAA2B;AAMrD,GALI,EAAE,QAAQ,eAAe,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACxD,EAAE,gBAAgB,EACd,KAAc,EAAE,iBAAiB,EACrC,EAAY,GAAK,GAEjB,KAAM,EAAU,EAAS;IAI7B,IAAa,GACX,KAAe,MAA4C;AAC7D,MAAI,CAAC,EAAe,EAAM,CAAE,QAAO;AAEnC,MAAI,EAAO,EAAM,EAAE;GAEf,IAAM,IADI,EAAS,EAAM,CACJ,UACf,IAAM,IAAa,KAAK;AAC9B,UAAO,EAAa,GAAO;IACvB,SAAS,MAAQ;IACjB,UAAU,IAAa,KAAA,UAAkB,EAAe,EAAI;IAC5D,gBAAgB;AACR,UACA,KAAe,EAAY,GAAM;;IAE5C,CAAa;;AASlB,SANI,EAAQ,EAAM,GACP,EAAa,GAAO,EACvB,UAAU,EAAS,IAAI,EAAS,EAAM,CAAC,UAAU,EAAY,EAChE,CAAa,GAGX;IAGL,IACF,MAAW,UACL;EACI,oBAAoB;AAEhB,GADI,EAAa,WAAS,aAAa,EAAa,QAAQ,EAC5D,EAAY,GAAK;;EAErB,oBAAoB;AAChB,KAAa,UAAU,iBAAiB,EAAY,GAAM,EAAE,IAAI;;EAEvE,GACD,EAAE,EAgBN,IAAqB,KACpB,MAAwB;AAErB,EADA,EAAE,iBAAiB,EACnB,EAAE,gBAAgB;KAEtB,KAAA;AAEN,QACI,kBAAC,OAAD;EACI,WAAW,EAAG,wBAAwB,EAAU;EACzC;EACP,SAAS;EACT,GAAI;YAJR,CAMI,kBAAC,OAAD;GACI,KAAK;GACL,SAAS,MAAW,UAAU,IAAqB,KAAA;GACnD,WAAW;GACX,MAAK;GACL,UAAU;GACV,WAAU;aAET;GACC,CAAA,EACN,kBAAC,GAAD;GACU;GACK;GACX,eAAe,EAAY,GAAM;GACtB;GACX,WAAW,EAAG,yBAAyB,EAAiB;GACxD,OAAO;aAEP,kBAAC,OAAD;IAAK,WAAU;IAAqB,MAAK;IAAO,GAAI;cAC/C,EAAS,IAAI,GAAU,EAAY;IAClC,CAAA;GACC,CAAA,CACT;;;AAId,SAAgB,EAAc,EAC1B,SACA,UACA,SACA,OACA,YACA,UACA,cAAW,IACX,YAAS,IACT,cACA,cACA,YACA,aACA,eACuF;CACvF,IAAM,IAAgB,KAAW,GAE3B,IACF,kBAAA,GAAA,EAAA,UAAA,CACK,KAAQ,kBAAC,QAAD;EAAM,WAAU;YAAsB;EAAY,CAAA,EAC3D,kBAAC,QAAD;EAAM,WAAU;YAAuB;EAAa,CAAA,CACrD,EAAA,CAAA,EAGD,IAAM,EAAG,sBAAsB,KAAiB,UAAU,KAAY,YAAY,GAAO,EAAU,EAEnG,KAAe,MAAwB;AACzC,MAAI,GAAU;AACV,KAAE,gBAAgB;AAClB;;AAGJ,EADA,KAAW,EACX,KAAY;IAGV,IAAM,MAAc,KAAQ,IAAK,MAAM,WACvC,IAAY,IAAY;EAAC,GAAI,IAAO,EAAC,SAAK,GAAG,EAAE;EAAG,GAAI,IAAK,EAAC,OAAG,GAAG,EAAE;EAAE,GAAG,IAAO,EAAC,SAAK,GAAG,IAAK,EAAC,MAAM,GAAG,GAAG,EAAE;AAEnH,QACI,kBAAC,GAAD;EACI,WAAW;EACX,MAAK;EACL,UAAU;EACV,SAAS;EACT,cAAc;EACd,iBAAe,KAAY,KAAA;EAC3B,GAAI;YAEH;EACC,CAAA;;AAGb,EAAuB,iBAAiB;AAEzC,SAAgB,EAAe,EAAC,UAAO,eAAgC;AACnE,QACI,kBAAC,OAAD;EAAK,WAAU;EAAsB,MAAK;YAA1C,CACI,kBAAC,OAAD;GAAK,WAAU;aAA6B;GAAY,CAAA,EACvD,EACC;;;AAGb,EAAwB,kBAAkB;AAE3C,SAAgB,EAAiB,EAAC,gBAAmC;AACjE,QAAO,kBAAC,OAAD;EAAK,WAAW,EAAG,yBAAyB,EAAU;EAAE,MAAK;EAAc,CAAA"}
1
+ {"version":3,"file":"MDropdownMenu-CFoKJ7V6.js","names":[],"sources":["../src/components/overlays/MDropdownMenu/MDropdownMenu.tsx"],"sourcesContent":["import {useState, useRef, useCallback, Children, isValidElement, cloneElement} from 'react'\nimport type * as React from 'react'\nimport {MPopover} from '../../primitives'\nimport {useKeyboardNav} from '../../../utils/useKeyboardNav'\nimport {cn} from '../../../utils/cn'\nimport type {\n MDropdownMenuProps,\n MDropdownItemProps,\n MDropdownGroupProps,\n MDropdownDividerProps,\n} from './MDropdownMenu.types'\nimport './MDropdownMenu.css'\n\ntype AnyProps = Record<string, any>\n\nfunction getProps(el: React.ReactElement): AnyProps {\n return el.props as AnyProps\n}\n\nfunction isItem(child: React.ReactElement): boolean {\n return !!(child.type as any).__dropdownItem\n}\n\nfunction isGroup(child: React.ReactElement): boolean {\n return !!(child.type as any).__dropdownGroup\n}\n\n// Collect all MDropdownItem elements from children (including inside groups).\nfunction collectItems(children: React.ReactNode): React.ReactElement[] {\n const items: React.ReactElement[] = []\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return\n if (isItem(child)) {\n items.push(child)\n } else if (isGroup(child)) {\n Children.forEach(getProps(child).children, (gc: React.ReactNode) => {\n if (isValidElement(gc) && isItem(gc)) {\n items.push(gc)\n }\n })\n }\n })\n return items\n}\n\nexport function MDropdownMenu({\n trigger,\n placement = 'bottom-start',\n closeOnSelect = true,\n openOn = 'click',\n onOpenChange,\n isolateClick = false,\n className,\n style,\n popoverClassName,\n popoverStyle,\n children,\n}: MDropdownMenuProps) {\n const [open, setOpen] = useState(false)\n const anchorRef = useRef<HTMLDivElement>(null)\n const hoverTimeout = useRef<ReturnType<typeof setTimeout>>(null)\n\n const items = collectItems(children)\n const enabledCount = items.filter((i) => !getProps(i).disabled).length\n\n const setMenuOpen = useCallback(\n (next: boolean | ((prev: boolean) => boolean)) => {\n setOpen((prev) => {\n const resolved = typeof next === 'function' ? next(prev) : next\n onOpenChange?.(resolved)\n return resolved\n })\n },\n [onOpenChange]\n )\n\n const handleSelect = useCallback(\n (index: number) => {\n let enabledIdx = 0\n for (const item of items) {\n const p = getProps(item)\n if (p.disabled) continue\n if (enabledIdx === index) {\n p.onClick?.()\n break\n }\n enabledIdx++\n }\n if (closeOnSelect) setMenuOpen(false)\n },\n [items, closeOnSelect, setMenuOpen]\n )\n\n const {activeIndex, setActiveIndex, onKeyDown} = useKeyboardNav({\n itemCount: enabledCount,\n onSelect: handleSelect,\n onClose: () => setOpen(false),\n isOpen: open,\n })\n\n const handleTriggerClick = (e: React.MouseEvent) => {\n if (isolateClick) {\n e.stopPropagation()\n e.preventDefault()\n }\n setMenuOpen((o) => !o)\n }\n\n const handleTriggerKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n if (isolateClick) e.stopPropagation()\n setMenuOpen(true)\n }\n if (open) onKeyDown(e as any)\n }\n\n // Map active index back to flat child rendering with enabled-only tracking.\n let enabledIdx = 0\n const renderChild = (child: React.ReactNode): React.ReactNode => {\n if (!isValidElement(child)) return child\n\n if (isItem(child)) {\n const p = getProps(child)\n const isDisabled = p.disabled\n const idx = isDisabled ? -1 : enabledIdx++\n return cloneElement(child, {\n _active: idx === activeIndex,\n _onHover: isDisabled ? undefined : () => setActiveIndex(idx),\n _onClick: () => {\n if (isDisabled) return\n if (closeOnSelect) setMenuOpen(false)\n },\n } as AnyProps)\n }\n\n if (isGroup(child)) {\n return cloneElement(child, {\n children: Children.map(getProps(child).children, renderChild),\n } as AnyProps)\n }\n\n return child\n }\n\n const hoverHandlers =\n openOn === 'hover'\n ? {\n onMouseEnter: () => {\n if (hoverTimeout.current) clearTimeout(hoverTimeout.current)\n setMenuOpen(true)\n },\n onMouseLeave: () => {\n hoverTimeout.current = setTimeout(() => setMenuOpen(false), 150)\n },\n }\n : {}\n\n /**\n * When `isolateClick` is set, every click bubbling out of the menu\n * (trigger AND items) must be stopped — otherwise selecting an action\n * also fires the click handler on a clickable parent (Link, MCard with\n * onClick, MDataTable row link). Trigger click itself is handled by\n * `handleTriggerClick`; this wrapper catches the bubbled item clicks\n * before they leave the anchor. `preventDefault` is needed too — when the\n * dropdown is rendered inside an `<a href>` (MCard component={Link}),\n * stopping propagation alone does not block native link navigation.\n *\n * Caveat: MDropdownItem with `href` will not navigate while inside an\n * `isolateClick` menu — use programmatic navigation (onClick + navigate)\n * in those contexts instead.\n */\n const isolateAnchorClick = isolateClick\n ? (e: React.MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n }\n : undefined\n\n return (\n <div\n className={cn('dropdown menu anchor', className)}\n style={style}\n onClick={isolateAnchorClick}\n {...hoverHandlers}\n >\n <div\n ref={anchorRef}\n onClick={openOn === 'click' ? handleTriggerClick : undefined}\n onKeyDown={handleTriggerKeyDown}\n role=\"button\"\n tabIndex={0}\n className=\"dropdown menu trigger\"\n >\n {trigger}\n </div>\n <MPopover\n open={open}\n anchorRef={anchorRef}\n onClose={() => setMenuOpen(false)}\n placement={placement}\n className={cn('dropdown menu popover', popoverClassName)}\n style={popoverStyle}\n >\n <div className=\"dropdown menu list\" role=\"menu\" {...hoverHandlers}>\n {Children.map(children, renderChild)}\n </div>\n </MPopover>\n </div>\n )\n}\n\nexport function MDropdownItem({\n icon,\n label,\n href,\n to,\n onClick,\n color,\n disabled = false,\n active = false,\n component,\n className,\n _active,\n _onHover,\n _onClick,\n}: MDropdownItemProps & {_active?: boolean; _onHover?: () => void; _onClick?: () => void}) {\n const isHighlighted = _active ?? active\n\n const content = (\n <>\n {icon && <span className=\"dropdown menu icon\">{icon}</span>}\n <span className=\"dropdown menu label\">{label}</span>\n </>\n )\n\n const cls = cn('dropdown menu item', isHighlighted && 'active', disabled && 'disabled', color, className)\n\n const handleClick = (e: React.MouseEvent) => {\n if (disabled) {\n e.preventDefault()\n return\n }\n onClick?.()\n _onClick?.()\n }\n\n const Tag = component ?? (href || to ? 'a' : 'button')\n const linkProps = component ? {...(href ? {href} : {}), ...(to ? {to} : {})} : href ? {href} : to ? {href: to} : {}\n\n return (\n <Tag\n className={cls}\n role=\"menuitem\"\n tabIndex={-1}\n onClick={handleClick}\n onMouseEnter={_onHover}\n aria-disabled={disabled || undefined}\n {...linkProps}\n >\n {content}\n </Tag>\n )\n}\n;(MDropdownItem as any).__dropdownItem = true\n\nexport function MDropdownGroup({label, children}: MDropdownGroupProps) {\n return (\n <div className=\"dropdown menu group\" role=\"group\">\n <div className=\"dropdown menu group-label\">{label}</div>\n {children}\n </div>\n )\n}\n;(MDropdownGroup as any).__dropdownGroup = true\n\nexport function MDropdownDivider({className}: MDropdownDividerProps) {\n return <div className={cn('dropdown menu divider', className)} role=\"separator\" />\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require(`./icons-BfdQ45F2.cjs`),t=require(`./cn-CU5TNITO.cjs`),n=require(`./useGhostText-Dmkw3Am8.cjs`),r=require(`./useInteractionEffect-DFTdcWHl.cjs`),i=require(`./MButton-R08y1HCT.cjs`);require(`./core-DBpQf3uY.cjs`);let a=require(`react`),o=require(`react/jsx-runtime`);function s(e){return e==null?``:e.toString()}function c(e,t){let[n,r]=(0,a.useState)(()=>s(t)),i=e!==void 0;return{isControlled:i,currentValue:i?s(e):n,setCurrentValue:(0,a.useCallback)(e=>{i||r(e)},[i])}}var l=(0,a.forwardRef)(function({type:s=`text`,value:l,defaultValue:u,name:d,id:f,placeholder:p,disabled:m=!1,readOnly:h=!1,required:g=!1,autoFocus:_=!1,autoComplete:v,inputMode:y,variant:ee=`outlined`,size:te=`md`,color:b,fullWidth:ne=!1,rounded:re=!1,label:x,helperText:S,errorText:C,startIcon:w,endIcon:T,clearable:E=!1,error:D=!1,success:O=!1,maxLength:k,showCharCount:A=!1,onChange:j,onFocus:M,onBlur:N,onKeyDown:P,onClear:F,ghostOptions:I,ghostMinChars:ie=2,onGhostAccept:L,loading:R=!1,clickEffect:z=`ripple`,rippleColor:B,className:ae,style:oe,inputClassName:V,labelClassName:se},H){let[U,W]=(0,a.useState)(!1),G=(0,a.useRef)(null),{effectClassName:ce,effectLayer:le,handlePointerDown:ue}=r.t({effect:z,disabled:m||h,color:B}),{isControlled:de,currentValue:K,setCurrentValue:q}=c(l,u),J=n.t({options:I??[],value:K,minChars:ie}),Y=D||!!C,fe=K.length>0,X=Y?`color-error`:b?`color-${b}`:void 0,Z=(0,a.useCallback)(e=>{W(!0),M?.(e)},[M]),Q=(0,a.useCallback)(e=>{W(!1),N?.(e)},[N]),$=(0,a.useCallback)(e=>{q(e.target.value),j?.(e),J.reset()},[j,q,J.reset]),pe=(0,a.useCallback)(e=>{if(I&&J.hint&&J.onKeyDown(e)){let e=J.accept();q(e.value),L?.(e.value);let t=H?.current??G.current;t&&((Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,`value`)?.set)?.call(t,e.value),t.dispatchEvent(new Event(`input`,{bubbles:!0})));return}P?.(e)},[I,J,q,L,P,H]),me=(0,a.useCallback)(()=>{q(``);let e=H?.current??G.current;e&&((Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,`value`)?.set)?.call(e,``),e.dispatchEvent(new Event(`input`,{bubbles:!0}))),F?.(),e?.focus()},[F,H,q]),he=t.t(`container`,`field-${ee}`,`field-${te}`,U&&`focused`,Y&&`input-error`,O&&!Y&&`input-success`,X,m&&`disabled`,re&&`rounded`,ce);return(0,o.jsxs)(`div`,{className:t.t(`input`,X,ne&&`full-width`,ae),style:oe,children:[x&&(0,o.jsx)(`label`,{htmlFor:f,className:t.t(`field-label`,U&&`focused`,Y&&`error`,O&&!Y&&`success`,g&&`required`,se),children:x}),(0,o.jsxs)(`div`,{className:he,onPointerDown:ue,children:[le,w&&(0,o.jsx)(`span`,{className:`start-icon`,children:w}),I?(0,o.jsxs)(`div`,{className:`ghost-text-field`,children:[(0,o.jsx)(`input`,{ref:H??G,type:s,value:K,name:d,id:f,placeholder:p,disabled:m,readOnly:h,required:g,autoFocus:_,autoComplete:v??`off`,inputMode:y,maxLength:k,className:t.t(`field`,V),onChange:$,onFocus:Z,onBlur:Q,onKeyDown:pe,"aria-invalid":Y||void 0,"aria-describedby":C?`${f}-error`:S?`${f}-helper`:void 0}),U&&J.hint&&(0,o.jsxs)(`span`,{className:`ghost-text-overlay`,"aria-hidden":`true`,children:[(0,o.jsx)(`span`,{className:`ghost-text-typed`,children:K}),(0,o.jsx)(`span`,{className:`ghost-text-hint`,children:J.hint})]})]}):(0,o.jsx)(`input`,{ref:H??G,type:s,value:K,name:d,id:f,placeholder:p,disabled:m,readOnly:h,required:g,autoFocus:_,autoComplete:v,inputMode:y,maxLength:k,className:t.t(`field`,V),onChange:$,onFocus:Z,onBlur:Q,onKeyDown:P,"aria-invalid":Y||void 0,"aria-describedby":C?`${f}-error`:S?`${f}-helper`:void 0}),R&&(0,o.jsx)(i.r,{size:`sm`,color:b}),E&&fe&&!R&&!m&&(0,o.jsx)(`button`,{type:`button`,className:`clear-btn clear-btn-base`,onMouseDown:e=>e.preventDefault(),onClick:me,tabIndex:-1,"aria-label":`Clear input`,children:(0,o.jsx)(e.Ki,{})}),T&&!R&&(0,o.jsx)(`span`,{className:`end-icon`,children:T})]}),(C||S||A)&&(0,o.jsxs)(`div`,{className:`bottom-row`,children:[(0,o.jsxs)(`span`,{children:[C&&(0,o.jsx)(`span`,{id:f?`${f}-error`:void 0,className:`field-error`,role:`alert`,children:C}),!C&&S&&(0,o.jsx)(`span`,{id:f?`${f}-helper`:void 0,className:`field-helper`,children:S})]}),A&&k&&(0,o.jsxs)(`span`,{className:t.t(`char-count`,K.length>k&&`over`),children:[K.length,`/`,k]})]})]})});Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return l}});
2
- //# sourceMappingURL=MInput-BhTAfpYS.cjs.map
1
+ const e=require(`./icons-D675Im0B.cjs`),t=require(`./cn-CU5TNITO.cjs`),n=require(`./useGhostText-Dmkw3Am8.cjs`),r=require(`./useInteractionEffect-DFTdcWHl.cjs`),i=require(`./MButton-R08y1HCT.cjs`);require(`./core-DBpQf3uY.cjs`);let a=require(`react`),o=require(`react/jsx-runtime`);function s(e){return e==null?``:e.toString()}function c(e,t){let[n,r]=(0,a.useState)(()=>s(t)),i=e!==void 0;return{isControlled:i,currentValue:i?s(e):n,setCurrentValue:(0,a.useCallback)(e=>{i||r(e)},[i])}}var l=(0,a.forwardRef)(function({type:s=`text`,value:l,defaultValue:u,name:d,id:f,placeholder:p,disabled:m=!1,readOnly:h=!1,required:g=!1,autoFocus:_=!1,autoComplete:v,inputMode:y,variant:ee=`outlined`,size:te=`md`,color:b,fullWidth:ne=!1,rounded:re=!1,label:x,helperText:S,errorText:C,startIcon:w,endIcon:T,clearable:E=!1,error:D=!1,success:O=!1,maxLength:k,showCharCount:A=!1,onChange:j,onFocus:M,onBlur:N,onKeyDown:P,onClear:F,ghostOptions:I,ghostMinChars:ie=2,onGhostAccept:L,loading:R=!1,clickEffect:z=`ripple`,rippleColor:B,className:ae,style:oe,inputClassName:V,labelClassName:se},H){let[U,W]=(0,a.useState)(!1),G=(0,a.useRef)(null),{effectClassName:ce,effectLayer:le,handlePointerDown:ue}=r.t({effect:z,disabled:m||h,color:B}),{isControlled:de,currentValue:K,setCurrentValue:q}=c(l,u),J=n.t({options:I??[],value:K,minChars:ie}),Y=D||!!C,fe=K.length>0,X=Y?`color-error`:b?`color-${b}`:void 0,Z=(0,a.useCallback)(e=>{W(!0),M?.(e)},[M]),Q=(0,a.useCallback)(e=>{W(!1),N?.(e)},[N]),$=(0,a.useCallback)(e=>{q(e.target.value),j?.(e),J.reset()},[j,q,J.reset]),pe=(0,a.useCallback)(e=>{if(I&&J.hint&&J.onKeyDown(e)){let e=J.accept();q(e.value),L?.(e.value);let t=H?.current??G.current;t&&((Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,`value`)?.set)?.call(t,e.value),t.dispatchEvent(new Event(`input`,{bubbles:!0})));return}P?.(e)},[I,J,q,L,P,H]),me=(0,a.useCallback)(()=>{q(``);let e=H?.current??G.current;e&&((Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,`value`)?.set)?.call(e,``),e.dispatchEvent(new Event(`input`,{bubbles:!0}))),F?.(),e?.focus()},[F,H,q]),he=t.t(`container`,`field-${ee}`,`field-${te}`,U&&`focused`,Y&&`input-error`,O&&!Y&&`input-success`,X,m&&`disabled`,re&&`rounded`,ce);return(0,o.jsxs)(`div`,{className:t.t(`input`,X,ne&&`full-width`,ae),style:oe,children:[x&&(0,o.jsx)(`label`,{htmlFor:f,className:t.t(`field-label`,U&&`focused`,Y&&`error`,O&&!Y&&`success`,g&&`required`,se),children:x}),(0,o.jsxs)(`div`,{className:he,onPointerDown:ue,children:[le,w&&(0,o.jsx)(`span`,{className:`start-icon`,children:w}),I?(0,o.jsxs)(`div`,{className:`ghost-text-field`,children:[(0,o.jsx)(`input`,{ref:H??G,type:s,value:K,name:d,id:f,placeholder:p,disabled:m,readOnly:h,required:g,autoFocus:_,autoComplete:v??`off`,inputMode:y,maxLength:k,className:t.t(`field`,V),onChange:$,onFocus:Z,onBlur:Q,onKeyDown:pe,"aria-invalid":Y||void 0,"aria-describedby":C?`${f}-error`:S?`${f}-helper`:void 0}),U&&J.hint&&(0,o.jsxs)(`span`,{className:`ghost-text-overlay`,"aria-hidden":`true`,children:[(0,o.jsx)(`span`,{className:`ghost-text-typed`,children:K}),(0,o.jsx)(`span`,{className:`ghost-text-hint`,children:J.hint})]})]}):(0,o.jsx)(`input`,{ref:H??G,type:s,value:K,name:d,id:f,placeholder:p,disabled:m,readOnly:h,required:g,autoFocus:_,autoComplete:v,inputMode:y,maxLength:k,className:t.t(`field`,V),onChange:$,onFocus:Z,onBlur:Q,onKeyDown:P,"aria-invalid":Y||void 0,"aria-describedby":C?`${f}-error`:S?`${f}-helper`:void 0}),R&&(0,o.jsx)(i.r,{size:`sm`,color:b}),E&&fe&&!R&&!m&&(0,o.jsx)(`button`,{type:`button`,className:`clear-btn clear-btn-base`,onMouseDown:e=>e.preventDefault(),onClick:me,tabIndex:-1,"aria-label":`Clear input`,children:(0,o.jsx)(e.Xi,{})}),T&&!R&&(0,o.jsx)(`span`,{className:`end-icon`,children:T})]}),(C||S||A)&&(0,o.jsxs)(`div`,{className:`bottom-row`,children:[(0,o.jsxs)(`span`,{children:[C&&(0,o.jsx)(`span`,{id:f?`${f}-error`:void 0,className:`field-error`,role:`alert`,children:C}),!C&&S&&(0,o.jsx)(`span`,{id:f?`${f}-helper`:void 0,className:`field-helper`,children:S})]}),A&&k&&(0,o.jsxs)(`span`,{className:t.t(`char-count`,K.length>k&&`over`),children:[K.length,`/`,k]})]})]})});Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return l}});
2
+ //# sourceMappingURL=MInput-BpTlP8GE.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MInput-BhTAfpYS.cjs","names":[],"sources":["../src/utils/useControllableString.ts","../src/components/inputs/MInput/MInput.tsx"],"sourcesContent":["import {useCallback, useState} from 'react'\n\ntype ControllableStringLike = string | number | readonly string[] | null | undefined\n\n// Normalize mixed input values so text-like controls always work with strings.\nfunction normalizeStringValue(value: ControllableStringLike) {\n if (value === null || value === undefined) {\n return ''\n }\n\n return value.toString()\n}\n\n// Share controlled and uncontrolled string state logic between text-like primitives.\nexport function useControllableString(value: ControllableStringLike, defaultValue?: ControllableStringLike) {\n const [internalValue, setInternalValue] = useState(() => normalizeStringValue(defaultValue))\n const isControlled = value !== undefined\n const currentValue = isControlled ? normalizeStringValue(value) : internalValue\n\n const setCurrentValue = useCallback(\n (nextValue: string) => {\n if (!isControlled) {\n setInternalValue(nextValue)\n }\n },\n [isControlled]\n )\n\n return {\n isControlled,\n currentValue,\n setCurrentValue,\n }\n}\n","import {forwardRef, useCallback, useRef, useState} from 'react'\nimport type * as React from 'react'\nimport type {MInputProps} from './MInput.types'\nimport {cn} from '../../../utils/cn'\nimport {useControllableString} from '../../../utils/useControllableString'\nimport {useInteractionEffect} from '../../../utils/useInteractionEffect'\nimport {useGhostText} from '../../../utils/useGhostText'\nimport {MSpinner} from '../../feedback'\nimport {MCloseIcon} from '../../../icons'\nimport './MInput.css'\n\n// Render the base text input used by all specialized input wrappers.\nexport const MInput = forwardRef<HTMLInputElement, MInputProps>(function MInput(\n {\n type = 'text',\n value,\n defaultValue,\n name,\n id,\n placeholder,\n disabled = false,\n readOnly = false,\n required = false,\n autoFocus = false,\n autoComplete,\n inputMode,\n variant = 'outlined',\n size = 'md',\n color,\n fullWidth = false,\n rounded = false,\n label,\n helperText,\n errorText,\n startIcon,\n endIcon,\n clearable = false,\n error = false,\n success = false,\n maxLength,\n showCharCount = false,\n onChange,\n onFocus,\n onBlur,\n onKeyDown,\n onClear,\n ghostOptions,\n ghostMinChars = 2,\n onGhostAccept,\n loading = false,\n clickEffect = 'ripple',\n rippleColor,\n className,\n style,\n inputClassName,\n labelClassName,\n },\n ref\n) {\n const [focused, setFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const {effectClassName, effectLayer, handlePointerDown} = useInteractionEffect<HTMLDivElement>({\n effect: clickEffect,\n disabled: disabled || readOnly,\n color: rippleColor,\n })\n\n const {isControlled, currentValue, setCurrentValue} = useControllableString(value, defaultValue)\n const ghost = useGhostText({\n options: ghostOptions ?? [],\n value: currentValue,\n minChars: ghostMinChars,\n })\n const hasError = error || !!errorText\n const hasContent = currentValue.length > 0\n const resolvedColorClass = hasError ? 'color-error' : color ? `color-${color}` : undefined\n\n // Mirror focus state so the wrapper can style the input consistently.\n const handleFocus = useCallback(\n (event: React.FocusEvent<HTMLInputElement>) => {\n setFocused(true)\n onFocus?.(event)\n },\n [onFocus]\n )\n\n // Clear focus styles before delegating to the caller.\n const handleBlur = useCallback(\n (event: React.FocusEvent<HTMLInputElement>) => {\n setFocused(false)\n onBlur?.(event)\n },\n [onBlur]\n )\n\n // Keep uncontrolled usage working without blocking controlled integrations.\n const handleChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n setCurrentValue(event.target.value)\n onChange?.(event)\n ghost.reset()\n },\n [onChange, setCurrentValue, ghost.reset]\n )\n\n // Intercept keyboard events for ghost text acceptance before delegating.\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (ghostOptions && ghost.hint) {\n const accepted = ghost.onKeyDown(event)\n if (accepted) {\n const result = ghost.accept()\n setCurrentValue(result.value)\n onGhostAccept?.(result.value)\n // Fire synthetic change so controlled parents stay in sync.\n const input = (ref as React.RefObject<HTMLInputElement>)?.current ?? inputRef.current\n if (input) {\n const nativeSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set\n nativeSet?.call(input, result.value)\n input.dispatchEvent(new Event('input', {bubbles: true}))\n }\n return\n }\n }\n onKeyDown?.(event)\n },\n [ghostOptions, ghost, setCurrentValue, onGhostAccept, onKeyDown, ref]\n )\n\n // Reset the visible value while preserving focus for quick repeated input.\n const handleClear = useCallback(() => {\n setCurrentValue('')\n\n const input = (ref as React.RefObject<HTMLInputElement>)?.current ?? inputRef.current\n if (input) {\n const nativeSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set\n nativeSet?.call(input, '')\n input.dispatchEvent(new Event('input', {bubbles: true}))\n }\n\n onClear?.()\n input?.focus()\n }, [onClear, ref, setCurrentValue])\n\n const containerClasses = cn(\n 'container',\n `field-${variant}`,\n `field-${size}`,\n focused && 'focused',\n hasError && 'input-error',\n success && !hasError && 'input-success',\n resolvedColorClass,\n disabled && 'disabled',\n rounded && 'rounded',\n effectClassName\n )\n\n return (\n <div className={cn('input', resolvedColorClass, fullWidth && 'full-width', className)} style={style}>\n {label && (\n <label\n htmlFor={id}\n className={cn(\n 'field-label',\n focused && 'focused',\n hasError && 'error',\n success && !hasError && 'success',\n required && 'required',\n labelClassName\n )}\n >\n {label}\n </label>\n )}\n\n <div className={containerClasses} onPointerDown={handlePointerDown}>\n {effectLayer}\n {startIcon && <span className=\"start-icon\">{startIcon}</span>}\n\n {ghostOptions ? (\n <div className=\"ghost-text-field\">\n <input\n ref={ref ?? inputRef}\n type={type}\n value={currentValue}\n name={name}\n id={id}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n autoComplete={autoComplete ?? 'off'}\n inputMode={inputMode}\n maxLength={maxLength}\n className={cn('field', inputClassName)}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n aria-invalid={hasError || undefined}\n aria-describedby={errorText ? `${id}-error` : helperText ? `${id}-helper` : undefined}\n />\n {focused && ghost.hint && (\n <span className=\"ghost-text-overlay\" aria-hidden=\"true\">\n <span className=\"ghost-text-typed\">{currentValue}</span>\n <span className=\"ghost-text-hint\">{ghost.hint}</span>\n </span>\n )}\n </div>\n ) : (\n <input\n ref={ref ?? inputRef}\n type={type}\n value={currentValue}\n name={name}\n id={id}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n autoComplete={autoComplete}\n inputMode={inputMode}\n maxLength={maxLength}\n className={cn('field', inputClassName)}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={onKeyDown}\n aria-invalid={hasError || undefined}\n aria-describedby={errorText ? `${id}-error` : helperText ? `${id}-helper` : undefined}\n />\n )}\n\n {loading && <MSpinner size=\"sm\" color={color} />}\n\n {clearable && hasContent && !loading && !disabled && (\n <button\n type=\"button\"\n className=\"clear-btn clear-btn-base\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n tabIndex={-1}\n aria-label=\"Clear input\"\n >\n <MCloseIcon />\n </button>\n )}\n\n {endIcon && !loading && <span className=\"end-icon\">{endIcon}</span>}\n </div>\n\n {(errorText || helperText || showCharCount) && (\n <div className=\"bottom-row\">\n <span>\n {errorText && (\n <span id={id ? `${id}-error` : undefined} className=\"field-error\" role=\"alert\">\n {errorText}\n </span>\n )}\n {!errorText && helperText && (\n <span id={id ? `${id}-helper` : undefined} className=\"field-helper\">\n {helperText}\n </span>\n )}\n </span>\n {showCharCount && maxLength && (\n <span className={cn('char-count', currentValue.length > maxLength && 'over')}>\n {currentValue.length}/{maxLength}\n </span>\n )}\n </div>\n )}\n </div>\n )\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"MInput-BpTlP8GE.cjs","names":[],"sources":["../src/utils/useControllableString.ts","../src/components/inputs/MInput/MInput.tsx"],"sourcesContent":["import {useCallback, useState} from 'react'\n\ntype ControllableStringLike = string | number | readonly string[] | null | undefined\n\n// Normalize mixed input values so text-like controls always work with strings.\nfunction normalizeStringValue(value: ControllableStringLike) {\n if (value === null || value === undefined) {\n return ''\n }\n\n return value.toString()\n}\n\n// Share controlled and uncontrolled string state logic between text-like primitives.\nexport function useControllableString(value: ControllableStringLike, defaultValue?: ControllableStringLike) {\n const [internalValue, setInternalValue] = useState(() => normalizeStringValue(defaultValue))\n const isControlled = value !== undefined\n const currentValue = isControlled ? normalizeStringValue(value) : internalValue\n\n const setCurrentValue = useCallback(\n (nextValue: string) => {\n if (!isControlled) {\n setInternalValue(nextValue)\n }\n },\n [isControlled]\n )\n\n return {\n isControlled,\n currentValue,\n setCurrentValue,\n }\n}\n","import {forwardRef, useCallback, useRef, useState} from 'react'\nimport type * as React from 'react'\nimport type {MInputProps} from './MInput.types'\nimport {cn} from '../../../utils/cn'\nimport {useControllableString} from '../../../utils/useControllableString'\nimport {useInteractionEffect} from '../../../utils/useInteractionEffect'\nimport {useGhostText} from '../../../utils/useGhostText'\nimport {MSpinner} from '../../feedback'\nimport {MCloseIcon} from '../../../icons'\nimport './MInput.css'\n\n// Render the base text input used by all specialized input wrappers.\nexport const MInput = forwardRef<HTMLInputElement, MInputProps>(function MInput(\n {\n type = 'text',\n value,\n defaultValue,\n name,\n id,\n placeholder,\n disabled = false,\n readOnly = false,\n required = false,\n autoFocus = false,\n autoComplete,\n inputMode,\n variant = 'outlined',\n size = 'md',\n color,\n fullWidth = false,\n rounded = false,\n label,\n helperText,\n errorText,\n startIcon,\n endIcon,\n clearable = false,\n error = false,\n success = false,\n maxLength,\n showCharCount = false,\n onChange,\n onFocus,\n onBlur,\n onKeyDown,\n onClear,\n ghostOptions,\n ghostMinChars = 2,\n onGhostAccept,\n loading = false,\n clickEffect = 'ripple',\n rippleColor,\n className,\n style,\n inputClassName,\n labelClassName,\n },\n ref\n) {\n const [focused, setFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const {effectClassName, effectLayer, handlePointerDown} = useInteractionEffect<HTMLDivElement>({\n effect: clickEffect,\n disabled: disabled || readOnly,\n color: rippleColor,\n })\n\n const {isControlled, currentValue, setCurrentValue} = useControllableString(value, defaultValue)\n const ghost = useGhostText({\n options: ghostOptions ?? [],\n value: currentValue,\n minChars: ghostMinChars,\n })\n const hasError = error || !!errorText\n const hasContent = currentValue.length > 0\n const resolvedColorClass = hasError ? 'color-error' : color ? `color-${color}` : undefined\n\n // Mirror focus state so the wrapper can style the input consistently.\n const handleFocus = useCallback(\n (event: React.FocusEvent<HTMLInputElement>) => {\n setFocused(true)\n onFocus?.(event)\n },\n [onFocus]\n )\n\n // Clear focus styles before delegating to the caller.\n const handleBlur = useCallback(\n (event: React.FocusEvent<HTMLInputElement>) => {\n setFocused(false)\n onBlur?.(event)\n },\n [onBlur]\n )\n\n // Keep uncontrolled usage working without blocking controlled integrations.\n const handleChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n setCurrentValue(event.target.value)\n onChange?.(event)\n ghost.reset()\n },\n [onChange, setCurrentValue, ghost.reset]\n )\n\n // Intercept keyboard events for ghost text acceptance before delegating.\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (ghostOptions && ghost.hint) {\n const accepted = ghost.onKeyDown(event)\n if (accepted) {\n const result = ghost.accept()\n setCurrentValue(result.value)\n onGhostAccept?.(result.value)\n // Fire synthetic change so controlled parents stay in sync.\n const input = (ref as React.RefObject<HTMLInputElement>)?.current ?? inputRef.current\n if (input) {\n const nativeSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set\n nativeSet?.call(input, result.value)\n input.dispatchEvent(new Event('input', {bubbles: true}))\n }\n return\n }\n }\n onKeyDown?.(event)\n },\n [ghostOptions, ghost, setCurrentValue, onGhostAccept, onKeyDown, ref]\n )\n\n // Reset the visible value while preserving focus for quick repeated input.\n const handleClear = useCallback(() => {\n setCurrentValue('')\n\n const input = (ref as React.RefObject<HTMLInputElement>)?.current ?? inputRef.current\n if (input) {\n const nativeSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set\n nativeSet?.call(input, '')\n input.dispatchEvent(new Event('input', {bubbles: true}))\n }\n\n onClear?.()\n input?.focus()\n }, [onClear, ref, setCurrentValue])\n\n const containerClasses = cn(\n 'container',\n `field-${variant}`,\n `field-${size}`,\n focused && 'focused',\n hasError && 'input-error',\n success && !hasError && 'input-success',\n resolvedColorClass,\n disabled && 'disabled',\n rounded && 'rounded',\n effectClassName\n )\n\n return (\n <div className={cn('input', resolvedColorClass, fullWidth && 'full-width', className)} style={style}>\n {label && (\n <label\n htmlFor={id}\n className={cn(\n 'field-label',\n focused && 'focused',\n hasError && 'error',\n success && !hasError && 'success',\n required && 'required',\n labelClassName\n )}\n >\n {label}\n </label>\n )}\n\n <div className={containerClasses} onPointerDown={handlePointerDown}>\n {effectLayer}\n {startIcon && <span className=\"start-icon\">{startIcon}</span>}\n\n {ghostOptions ? (\n <div className=\"ghost-text-field\">\n <input\n ref={ref ?? inputRef}\n type={type}\n value={currentValue}\n name={name}\n id={id}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n autoComplete={autoComplete ?? 'off'}\n inputMode={inputMode}\n maxLength={maxLength}\n className={cn('field', inputClassName)}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n aria-invalid={hasError || undefined}\n aria-describedby={errorText ? `${id}-error` : helperText ? `${id}-helper` : undefined}\n />\n {focused && ghost.hint && (\n <span className=\"ghost-text-overlay\" aria-hidden=\"true\">\n <span className=\"ghost-text-typed\">{currentValue}</span>\n <span className=\"ghost-text-hint\">{ghost.hint}</span>\n </span>\n )}\n </div>\n ) : (\n <input\n ref={ref ?? inputRef}\n type={type}\n value={currentValue}\n name={name}\n id={id}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n autoComplete={autoComplete}\n inputMode={inputMode}\n maxLength={maxLength}\n className={cn('field', inputClassName)}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={onKeyDown}\n aria-invalid={hasError || undefined}\n aria-describedby={errorText ? `${id}-error` : helperText ? `${id}-helper` : undefined}\n />\n )}\n\n {loading && <MSpinner size=\"sm\" color={color} />}\n\n {clearable && hasContent && !loading && !disabled && (\n <button\n type=\"button\"\n className=\"clear-btn clear-btn-base\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n tabIndex={-1}\n aria-label=\"Clear input\"\n >\n <MCloseIcon />\n </button>\n )}\n\n {endIcon && !loading && <span className=\"end-icon\">{endIcon}</span>}\n </div>\n\n {(errorText || helperText || showCharCount) && (\n <div className=\"bottom-row\">\n <span>\n {errorText && (\n <span id={id ? `${id}-error` : undefined} className=\"field-error\" role=\"alert\">\n {errorText}\n </span>\n )}\n {!errorText && helperText && (\n <span id={id ? `${id}-helper` : undefined} className=\"field-helper\">\n {helperText}\n </span>\n )}\n </span>\n {showCharCount && maxLength && (\n <span className={cn('char-count', currentValue.length > maxLength && 'over')}>\n {currentValue.length}/{maxLength}\n </span>\n )}\n </div>\n )}\n </div>\n )\n})\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Ki as e } from "./icons-DLP-Rs6z.js";
1
+ import { Xi as e } from "./icons-CBMl-kOM.js";
2
2
  import { t } from "./cn-YER3QsV1.js";
3
3
  import { t as n } from "./useGhostText-DG0bzcao.js";
4
4
  import { t as r } from "./useInteractionEffect-DtpbVd77.js";
@@ -184,4 +184,4 @@ var f = a(function({ type: a = "text", value: u, defaultValue: f, name: p, id: m
184
184
  //#endregion
185
185
  export { d as n, f as t };
186
186
 
187
- //# sourceMappingURL=MInput-CgtX0fUN.js.map
187
+ //# sourceMappingURL=MInput-C8ObGzQk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MInput-CgtX0fUN.js","names":[],"sources":["../src/utils/useControllableString.ts","../src/components/inputs/MInput/MInput.tsx"],"sourcesContent":["import {useCallback, useState} from 'react'\n\ntype ControllableStringLike = string | number | readonly string[] | null | undefined\n\n// Normalize mixed input values so text-like controls always work with strings.\nfunction normalizeStringValue(value: ControllableStringLike) {\n if (value === null || value === undefined) {\n return ''\n }\n\n return value.toString()\n}\n\n// Share controlled and uncontrolled string state logic between text-like primitives.\nexport function useControllableString(value: ControllableStringLike, defaultValue?: ControllableStringLike) {\n const [internalValue, setInternalValue] = useState(() => normalizeStringValue(defaultValue))\n const isControlled = value !== undefined\n const currentValue = isControlled ? normalizeStringValue(value) : internalValue\n\n const setCurrentValue = useCallback(\n (nextValue: string) => {\n if (!isControlled) {\n setInternalValue(nextValue)\n }\n },\n [isControlled]\n )\n\n return {\n isControlled,\n currentValue,\n setCurrentValue,\n }\n}\n","import {forwardRef, useCallback, useRef, useState} from 'react'\nimport type * as React from 'react'\nimport type {MInputProps} from './MInput.types'\nimport {cn} from '../../../utils/cn'\nimport {useControllableString} from '../../../utils/useControllableString'\nimport {useInteractionEffect} from '../../../utils/useInteractionEffect'\nimport {useGhostText} from '../../../utils/useGhostText'\nimport {MSpinner} from '../../feedback'\nimport {MCloseIcon} from '../../../icons'\nimport './MInput.css'\n\n// Render the base text input used by all specialized input wrappers.\nexport const MInput = forwardRef<HTMLInputElement, MInputProps>(function MInput(\n {\n type = 'text',\n value,\n defaultValue,\n name,\n id,\n placeholder,\n disabled = false,\n readOnly = false,\n required = false,\n autoFocus = false,\n autoComplete,\n inputMode,\n variant = 'outlined',\n size = 'md',\n color,\n fullWidth = false,\n rounded = false,\n label,\n helperText,\n errorText,\n startIcon,\n endIcon,\n clearable = false,\n error = false,\n success = false,\n maxLength,\n showCharCount = false,\n onChange,\n onFocus,\n onBlur,\n onKeyDown,\n onClear,\n ghostOptions,\n ghostMinChars = 2,\n onGhostAccept,\n loading = false,\n clickEffect = 'ripple',\n rippleColor,\n className,\n style,\n inputClassName,\n labelClassName,\n },\n ref\n) {\n const [focused, setFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const {effectClassName, effectLayer, handlePointerDown} = useInteractionEffect<HTMLDivElement>({\n effect: clickEffect,\n disabled: disabled || readOnly,\n color: rippleColor,\n })\n\n const {isControlled, currentValue, setCurrentValue} = useControllableString(value, defaultValue)\n const ghost = useGhostText({\n options: ghostOptions ?? [],\n value: currentValue,\n minChars: ghostMinChars,\n })\n const hasError = error || !!errorText\n const hasContent = currentValue.length > 0\n const resolvedColorClass = hasError ? 'color-error' : color ? `color-${color}` : undefined\n\n // Mirror focus state so the wrapper can style the input consistently.\n const handleFocus = useCallback(\n (event: React.FocusEvent<HTMLInputElement>) => {\n setFocused(true)\n onFocus?.(event)\n },\n [onFocus]\n )\n\n // Clear focus styles before delegating to the caller.\n const handleBlur = useCallback(\n (event: React.FocusEvent<HTMLInputElement>) => {\n setFocused(false)\n onBlur?.(event)\n },\n [onBlur]\n )\n\n // Keep uncontrolled usage working without blocking controlled integrations.\n const handleChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n setCurrentValue(event.target.value)\n onChange?.(event)\n ghost.reset()\n },\n [onChange, setCurrentValue, ghost.reset]\n )\n\n // Intercept keyboard events for ghost text acceptance before delegating.\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (ghostOptions && ghost.hint) {\n const accepted = ghost.onKeyDown(event)\n if (accepted) {\n const result = ghost.accept()\n setCurrentValue(result.value)\n onGhostAccept?.(result.value)\n // Fire synthetic change so controlled parents stay in sync.\n const input = (ref as React.RefObject<HTMLInputElement>)?.current ?? inputRef.current\n if (input) {\n const nativeSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set\n nativeSet?.call(input, result.value)\n input.dispatchEvent(new Event('input', {bubbles: true}))\n }\n return\n }\n }\n onKeyDown?.(event)\n },\n [ghostOptions, ghost, setCurrentValue, onGhostAccept, onKeyDown, ref]\n )\n\n // Reset the visible value while preserving focus for quick repeated input.\n const handleClear = useCallback(() => {\n setCurrentValue('')\n\n const input = (ref as React.RefObject<HTMLInputElement>)?.current ?? inputRef.current\n if (input) {\n const nativeSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set\n nativeSet?.call(input, '')\n input.dispatchEvent(new Event('input', {bubbles: true}))\n }\n\n onClear?.()\n input?.focus()\n }, [onClear, ref, setCurrentValue])\n\n const containerClasses = cn(\n 'container',\n `field-${variant}`,\n `field-${size}`,\n focused && 'focused',\n hasError && 'input-error',\n success && !hasError && 'input-success',\n resolvedColorClass,\n disabled && 'disabled',\n rounded && 'rounded',\n effectClassName\n )\n\n return (\n <div className={cn('input', resolvedColorClass, fullWidth && 'full-width', className)} style={style}>\n {label && (\n <label\n htmlFor={id}\n className={cn(\n 'field-label',\n focused && 'focused',\n hasError && 'error',\n success && !hasError && 'success',\n required && 'required',\n labelClassName\n )}\n >\n {label}\n </label>\n )}\n\n <div className={containerClasses} onPointerDown={handlePointerDown}>\n {effectLayer}\n {startIcon && <span className=\"start-icon\">{startIcon}</span>}\n\n {ghostOptions ? (\n <div className=\"ghost-text-field\">\n <input\n ref={ref ?? inputRef}\n type={type}\n value={currentValue}\n name={name}\n id={id}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n autoComplete={autoComplete ?? 'off'}\n inputMode={inputMode}\n maxLength={maxLength}\n className={cn('field', inputClassName)}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n aria-invalid={hasError || undefined}\n aria-describedby={errorText ? `${id}-error` : helperText ? `${id}-helper` : undefined}\n />\n {focused && ghost.hint && (\n <span className=\"ghost-text-overlay\" aria-hidden=\"true\">\n <span className=\"ghost-text-typed\">{currentValue}</span>\n <span className=\"ghost-text-hint\">{ghost.hint}</span>\n </span>\n )}\n </div>\n ) : (\n <input\n ref={ref ?? inputRef}\n type={type}\n value={currentValue}\n name={name}\n id={id}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n autoComplete={autoComplete}\n inputMode={inputMode}\n maxLength={maxLength}\n className={cn('field', inputClassName)}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={onKeyDown}\n aria-invalid={hasError || undefined}\n aria-describedby={errorText ? `${id}-error` : helperText ? `${id}-helper` : undefined}\n />\n )}\n\n {loading && <MSpinner size=\"sm\" color={color} />}\n\n {clearable && hasContent && !loading && !disabled && (\n <button\n type=\"button\"\n className=\"clear-btn clear-btn-base\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n tabIndex={-1}\n aria-label=\"Clear input\"\n >\n <MCloseIcon />\n </button>\n )}\n\n {endIcon && !loading && <span className=\"end-icon\">{endIcon}</span>}\n </div>\n\n {(errorText || helperText || showCharCount) && (\n <div className=\"bottom-row\">\n <span>\n {errorText && (\n <span id={id ? `${id}-error` : undefined} className=\"field-error\" role=\"alert\">\n {errorText}\n </span>\n )}\n {!errorText && helperText && (\n <span id={id ? `${id}-helper` : undefined} className=\"field-helper\">\n {helperText}\n </span>\n )}\n </span>\n {showCharCount && maxLength && (\n <span className={cn('char-count', currentValue.length > maxLength && 'over')}>\n {currentValue.length}/{maxLength}\n </span>\n )}\n </div>\n )}\n </div>\n )\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"MInput-C8ObGzQk.js","names":[],"sources":["../src/utils/useControllableString.ts","../src/components/inputs/MInput/MInput.tsx"],"sourcesContent":["import {useCallback, useState} from 'react'\n\ntype ControllableStringLike = string | number | readonly string[] | null | undefined\n\n// Normalize mixed input values so text-like controls always work with strings.\nfunction normalizeStringValue(value: ControllableStringLike) {\n if (value === null || value === undefined) {\n return ''\n }\n\n return value.toString()\n}\n\n// Share controlled and uncontrolled string state logic between text-like primitives.\nexport function useControllableString(value: ControllableStringLike, defaultValue?: ControllableStringLike) {\n const [internalValue, setInternalValue] = useState(() => normalizeStringValue(defaultValue))\n const isControlled = value !== undefined\n const currentValue = isControlled ? normalizeStringValue(value) : internalValue\n\n const setCurrentValue = useCallback(\n (nextValue: string) => {\n if (!isControlled) {\n setInternalValue(nextValue)\n }\n },\n [isControlled]\n )\n\n return {\n isControlled,\n currentValue,\n setCurrentValue,\n }\n}\n","import {forwardRef, useCallback, useRef, useState} from 'react'\nimport type * as React from 'react'\nimport type {MInputProps} from './MInput.types'\nimport {cn} from '../../../utils/cn'\nimport {useControllableString} from '../../../utils/useControllableString'\nimport {useInteractionEffect} from '../../../utils/useInteractionEffect'\nimport {useGhostText} from '../../../utils/useGhostText'\nimport {MSpinner} from '../../feedback'\nimport {MCloseIcon} from '../../../icons'\nimport './MInput.css'\n\n// Render the base text input used by all specialized input wrappers.\nexport const MInput = forwardRef<HTMLInputElement, MInputProps>(function MInput(\n {\n type = 'text',\n value,\n defaultValue,\n name,\n id,\n placeholder,\n disabled = false,\n readOnly = false,\n required = false,\n autoFocus = false,\n autoComplete,\n inputMode,\n variant = 'outlined',\n size = 'md',\n color,\n fullWidth = false,\n rounded = false,\n label,\n helperText,\n errorText,\n startIcon,\n endIcon,\n clearable = false,\n error = false,\n success = false,\n maxLength,\n showCharCount = false,\n onChange,\n onFocus,\n onBlur,\n onKeyDown,\n onClear,\n ghostOptions,\n ghostMinChars = 2,\n onGhostAccept,\n loading = false,\n clickEffect = 'ripple',\n rippleColor,\n className,\n style,\n inputClassName,\n labelClassName,\n },\n ref\n) {\n const [focused, setFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const {effectClassName, effectLayer, handlePointerDown} = useInteractionEffect<HTMLDivElement>({\n effect: clickEffect,\n disabled: disabled || readOnly,\n color: rippleColor,\n })\n\n const {isControlled, currentValue, setCurrentValue} = useControllableString(value, defaultValue)\n const ghost = useGhostText({\n options: ghostOptions ?? [],\n value: currentValue,\n minChars: ghostMinChars,\n })\n const hasError = error || !!errorText\n const hasContent = currentValue.length > 0\n const resolvedColorClass = hasError ? 'color-error' : color ? `color-${color}` : undefined\n\n // Mirror focus state so the wrapper can style the input consistently.\n const handleFocus = useCallback(\n (event: React.FocusEvent<HTMLInputElement>) => {\n setFocused(true)\n onFocus?.(event)\n },\n [onFocus]\n )\n\n // Clear focus styles before delegating to the caller.\n const handleBlur = useCallback(\n (event: React.FocusEvent<HTMLInputElement>) => {\n setFocused(false)\n onBlur?.(event)\n },\n [onBlur]\n )\n\n // Keep uncontrolled usage working without blocking controlled integrations.\n const handleChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n setCurrentValue(event.target.value)\n onChange?.(event)\n ghost.reset()\n },\n [onChange, setCurrentValue, ghost.reset]\n )\n\n // Intercept keyboard events for ghost text acceptance before delegating.\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (ghostOptions && ghost.hint) {\n const accepted = ghost.onKeyDown(event)\n if (accepted) {\n const result = ghost.accept()\n setCurrentValue(result.value)\n onGhostAccept?.(result.value)\n // Fire synthetic change so controlled parents stay in sync.\n const input = (ref as React.RefObject<HTMLInputElement>)?.current ?? inputRef.current\n if (input) {\n const nativeSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set\n nativeSet?.call(input, result.value)\n input.dispatchEvent(new Event('input', {bubbles: true}))\n }\n return\n }\n }\n onKeyDown?.(event)\n },\n [ghostOptions, ghost, setCurrentValue, onGhostAccept, onKeyDown, ref]\n )\n\n // Reset the visible value while preserving focus for quick repeated input.\n const handleClear = useCallback(() => {\n setCurrentValue('')\n\n const input = (ref as React.RefObject<HTMLInputElement>)?.current ?? inputRef.current\n if (input) {\n const nativeSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set\n nativeSet?.call(input, '')\n input.dispatchEvent(new Event('input', {bubbles: true}))\n }\n\n onClear?.()\n input?.focus()\n }, [onClear, ref, setCurrentValue])\n\n const containerClasses = cn(\n 'container',\n `field-${variant}`,\n `field-${size}`,\n focused && 'focused',\n hasError && 'input-error',\n success && !hasError && 'input-success',\n resolvedColorClass,\n disabled && 'disabled',\n rounded && 'rounded',\n effectClassName\n )\n\n return (\n <div className={cn('input', resolvedColorClass, fullWidth && 'full-width', className)} style={style}>\n {label && (\n <label\n htmlFor={id}\n className={cn(\n 'field-label',\n focused && 'focused',\n hasError && 'error',\n success && !hasError && 'success',\n required && 'required',\n labelClassName\n )}\n >\n {label}\n </label>\n )}\n\n <div className={containerClasses} onPointerDown={handlePointerDown}>\n {effectLayer}\n {startIcon && <span className=\"start-icon\">{startIcon}</span>}\n\n {ghostOptions ? (\n <div className=\"ghost-text-field\">\n <input\n ref={ref ?? inputRef}\n type={type}\n value={currentValue}\n name={name}\n id={id}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n autoComplete={autoComplete ?? 'off'}\n inputMode={inputMode}\n maxLength={maxLength}\n className={cn('field', inputClassName)}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n aria-invalid={hasError || undefined}\n aria-describedby={errorText ? `${id}-error` : helperText ? `${id}-helper` : undefined}\n />\n {focused && ghost.hint && (\n <span className=\"ghost-text-overlay\" aria-hidden=\"true\">\n <span className=\"ghost-text-typed\">{currentValue}</span>\n <span className=\"ghost-text-hint\">{ghost.hint}</span>\n </span>\n )}\n </div>\n ) : (\n <input\n ref={ref ?? inputRef}\n type={type}\n value={currentValue}\n name={name}\n id={id}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n autoComplete={autoComplete}\n inputMode={inputMode}\n maxLength={maxLength}\n className={cn('field', inputClassName)}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={onKeyDown}\n aria-invalid={hasError || undefined}\n aria-describedby={errorText ? `${id}-error` : helperText ? `${id}-helper` : undefined}\n />\n )}\n\n {loading && <MSpinner size=\"sm\" color={color} />}\n\n {clearable && hasContent && !loading && !disabled && (\n <button\n type=\"button\"\n className=\"clear-btn clear-btn-base\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n tabIndex={-1}\n aria-label=\"Clear input\"\n >\n <MCloseIcon />\n </button>\n )}\n\n {endIcon && !loading && <span className=\"end-icon\">{endIcon}</span>}\n </div>\n\n {(errorText || helperText || showCharCount) && (\n <div className=\"bottom-row\">\n <span>\n {errorText && (\n <span id={id ? `${id}-error` : undefined} className=\"field-error\" role=\"alert\">\n {errorText}\n </span>\n )}\n {!errorText && helperText && (\n <span id={id ? `${id}-helper` : undefined} className=\"field-helper\">\n {helperText}\n </span>\n )}\n </span>\n {showCharCount && maxLength && (\n <span className={cn('char-count', currentValue.length > maxLength && 'over')}>\n {currentValue.length}/{maxLength}\n </span>\n )}\n </div>\n )}\n </div>\n )\n})\n"],"mappings":"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"}