@dashadmin/dash-components 1.3.25 → 1.3.26

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 (111) hide show
  1. package/dist/components/AuditLog/AuditLog.js +345 -1
  2. package/dist/components/AuditLog/index.js +4 -1
  3. package/dist/components/AutoCompleteArrayInput/AutoCompleteCheckBoxInput.js +630 -3
  4. package/dist/components/AutoCompleteArrayInput/AutocompleteCheckBoxArrayInput.js +53 -1
  5. package/dist/components/AutoCompleteArrayInputAutoSearch/AutoCompleteCheckBoxInput.js +647 -3
  6. package/dist/components/AutoCompleteArrayInputAutoSearch/AutocompleteCheckBoxArrayInput.js +53 -1
  7. package/dist/components/Json/Json.js +235 -1
  8. package/dist/components/JsonColorSelector/JsonColorSelector.js +1172 -1
  9. package/dist/components/JsonColorSelector/JsonColorSelectorEnhanced.js +863 -2
  10. package/dist/components/JsonColorSelector/JsonCssVarValues.js +738 -1
  11. package/dist/components/JsonColorSelector/components/ColorEditDialog.js +426 -1
  12. package/dist/components/JsonColorSelector/components/ColorPaletteItem.js +75 -1
  13. package/dist/components/JsonColorSelector/components/ImageColorExtractor.js +283 -1
  14. package/dist/components/JsonColorSelector/helpers/functions.js +101 -1
  15. package/dist/components/JsonColorSelector/useAsyncColorThief.js +105 -1
  16. package/dist/components/ListActive/ListActive.js +126 -1
  17. package/dist/components/ListActive/ListBoolean.js +124 -1
  18. package/dist/components/NotificationPreferences/NotificationPreferences.js +317 -1
  19. package/dist/components/NotificationPreferences/index.js +7 -1
  20. package/dist/components/SearchableSelects/RASearchableSelect.js +236 -1
  21. package/dist/components/SearchableSelects/RASearchableSelectCheckboxes.js +479 -1
  22. package/dist/components/SearchableSelects/RASearchableSelectChips.js +465 -1
  23. package/dist/components/SearchableSelects/RASearchableSelectChipsRecordContext.js +295 -1
  24. package/dist/components/SearchableSelects/SearchableSelect.js +202 -1
  25. package/dist/components/SearchableSelects/SearchableSelectCheckboxes.js +290 -1
  26. package/dist/components/SortableDataGrid/SortableDataGrid.js +72 -1
  27. package/dist/components/SortableDataGrid/SortableDataGridBody.js +167 -1
  28. package/dist/components/SortableDataGrid/SortableDataGridHeader.js +109 -1
  29. package/dist/components/SortableDataGrid/SortableDataGridRow.js +283 -1
  30. package/dist/components/Upload/SingleImageUploader.js +40 -1
  31. package/dist/components/custom/PackageCopyMethod.js +78 -1
  32. package/dist/components/custom/PackageRadioButtonGroup.js +45 -1
  33. package/dist/components/dialog/Basic.js +8 -1
  34. package/dist/components/dialog/Correct.js +14 -1
  35. package/dist/components/dialog/Error.js +14 -1
  36. package/dist/components/dialog/Info.js +14 -1
  37. package/dist/components/dialog/InfoV2.js +21 -1
  38. package/dist/components/dialog/NotFound.js +14 -1
  39. package/dist/components/dialog/QuickSearch.js +117 -1
  40. package/dist/components/notifications/NotificationsCenter.js +597 -1
  41. package/dist/components/notifications/index.js +24 -1
  42. package/dist/components/tables/PaginationComponent.js +36 -1
  43. package/dist/components/theme/AppLoadingFallback.js +38 -2
  44. package/dist/components/theme/ErrorBoundary.js +52 -1
  45. package/dist/components/theme/InitialLoader.js +13 -1
  46. package/dist/components/theme/NotFound.js +136 -1
  47. package/dist/components/theme/NotResults.js +38 -1
  48. package/dist/hooks/useDraggable.js +6 -1
  49. package/dist/hooks/useNotifications.js +8 -1
  50. package/dist/hooks/useQuickSearch.js +26 -1
  51. package/dist/index.js +66 -5567
  52. package/dist/utils/setNativeValue.js +17 -1
  53. package/package.json +149 -132
  54. package/src/components/AuditLog/AuditLog.tsx +476 -0
  55. package/src/components/AuditLog/index.ts +2 -0
  56. package/src/components/AutoCompleteArrayInput/AutoCompleteCheckBoxInput.tsx +917 -0
  57. package/src/components/AutoCompleteArrayInput/AutocompleteCheckBoxArrayInput.tsx +39 -0
  58. package/src/components/AutoCompleteArrayInputAutoSearch/AutoCompleteCheckBoxInput.tsx +916 -0
  59. package/src/components/AutoCompleteArrayInputAutoSearch/AutocompleteCheckBoxArrayInput.tsx +44 -0
  60. package/src/components/Json/Json.tsx +312 -0
  61. package/src/components/JsonColorSelector/JsonColorSelector.tsx +1435 -0
  62. package/src/components/JsonColorSelector/JsonColorSelectorEnhanced.tsx +1029 -0
  63. package/src/components/JsonColorSelector/JsonCssVarValues.tsx +863 -0
  64. package/src/components/JsonColorSelector/components/ColorEditDialog.tsx +491 -0
  65. package/src/components/JsonColorSelector/components/ColorPaletteItem.tsx +80 -0
  66. package/src/components/JsonColorSelector/components/ImageColorExtractor.tsx +328 -0
  67. package/src/components/JsonColorSelector/helpers/functions.tsx +123 -0
  68. package/src/components/JsonColorSelector/interfaces/interfaces.tsx +22 -0
  69. package/src/components/JsonColorSelector/useAsyncColorThief.tsx +97 -0
  70. package/src/components/ListActive/ListActive.tsx +106 -0
  71. package/src/components/ListActive/ListBoolean.tsx +96 -0
  72. package/src/components/NotificationPreferences/NotificationPreferences.tsx +463 -0
  73. package/src/components/NotificationPreferences/index.tsx +2 -0
  74. package/src/components/SearchableSelects/RASearchableSelect.tsx +300 -0
  75. package/src/components/SearchableSelects/RASearchableSelectCheckboxes.tsx +604 -0
  76. package/src/components/SearchableSelects/RASearchableSelectChips.tsx +558 -0
  77. package/src/components/SearchableSelects/RASearchableSelectChipsRecordContext.tsx +362 -0
  78. package/src/components/SearchableSelects/SearchableSelect.tsx +321 -0
  79. package/src/components/SearchableSelects/SearchableSelectCheckboxes.tsx +355 -0
  80. package/src/components/SortableDataGrid/SortableDataGrid.tsx +56 -0
  81. package/src/components/SortableDataGrid/SortableDataGridBody.tsx +175 -0
  82. package/src/components/SortableDataGrid/SortableDataGridHeader.tsx +171 -0
  83. package/src/components/SortableDataGrid/SortableDataGridRow.tsx +247 -0
  84. package/src/components/Upload/SingleImageUploader.tsx +55 -0
  85. package/src/components/custom/PackageCopyMethod.tsx +109 -0
  86. package/src/components/custom/PackageRadioButtonGroup.tsx +47 -0
  87. package/src/components/dialog/Basic.tsx +11 -0
  88. package/src/components/dialog/Correct.tsx +16 -0
  89. package/src/components/dialog/Error.tsx +15 -0
  90. package/src/components/dialog/Info.tsx +15 -0
  91. package/src/components/dialog/InfoV2.tsx +35 -0
  92. package/src/components/dialog/NotFound.tsx +18 -0
  93. package/src/components/dialog/QuickSearch.tsx +115 -0
  94. package/src/components/notifications/NotificationsCenter.tsx +792 -0
  95. package/src/components/notifications/index.ts +42 -0
  96. package/src/components/tables/PaginationComponent.tsx +17 -0
  97. package/src/components/theme/AppLoadingFallback.tsx +42 -0
  98. package/src/components/theme/ErrorBoundary.tsx +57 -0
  99. package/src/components/theme/InitialLoader.tsx +16 -0
  100. package/src/components/theme/NotFound.tsx +124 -0
  101. package/src/components/theme/NotResults.tsx +54 -0
  102. package/src/hooks/useDraggable.ts +11 -0
  103. package/src/hooks/useNotifications.ts +14 -0
  104. package/src/hooks/useQuickSearch.tsx +29 -0
  105. package/src/index.tsx +77 -0
  106. package/src/utils/setNativeValue.tsx +23 -0
  107. package/dist/color-thief-CTwGFhOB.js +0 -272
  108. /package/{dist → src}/components/AutoCompleteArrayInputAutoSearch/AutocompleteCheckBoxArrayAutoSearch.tsx.wip +0 -0
  109. /package/{dist → src}/components/JsonColorSelector/JsonColorSelector.tsx.bkup +0 -0
  110. /package/{dist → src}/components/SortableDataGrid/README.md +0 -0
  111. /package/{dist → src}/styles/index.less +0 -0
@@ -1,2 +1,863 @@
1
- import{Fragment as xe,jsx as t,jsxs as c}from"react/jsx-runtime";import{useRecordContext as Oe}from"react-admin";import{useFormContext as $e}from"react-hook-form";import{Box as a,Button as T,IconButton as ue,TextField as Ne,Typography as C,Chip as R,InputAdornment as K,FormControl as je,InputLabel as We,Select as _e,MenuItem as me,Pagination as Ue,Card as Ge,Link as U}from"@mui/material";import pe from"@mui/icons-material/Add";import He from"@mui/icons-material/Edit";import Je from"@mui/icons-material/Preview";import qe from"@mui/icons-material/Search";import ge from"@mui/icons-material/Clear";import Ye from"@mui/icons-material/FilterList";import Qe from"@mui/icons-material/Download";import Xe from"@mui/icons-material/Upload";import{useState as u,useEffect as M,useRef as G,useCallback as b,useMemo as fe}from"react";import{extractAvailableModes as Ze,getContrastColor as et,getModeIcon as H,parseColorKey as J}from"./helpers/functions";import tt from"./components/ImageColorExtractor";import ot from"./components/ColorEditDialog";import{updateDomCssVariables as he}from"@dashadmin/dash-utils";import{AuthPersistenceService as nt}from"@dashadmin/dash-auth";const q=!1,rt=!1,Rt={"primary-color":"Primary Color","secondary-color":"Secondary Color","highlight-color":"Highlight Color","contrast-color":"Contrast Color"},st=({pair:m,onEdit:P,onDelete:v})=>{const O=et(m.value),{baseChips:f,mode:y}=J(m.key),E=H(y);return c(Ge,{onClick:()=>P(m),elevation:1,sx:{width:"100%",display:"flex",alignItems:"stretch",cursor:"pointer",transition:"all 0.2s ease-in-out","&:hover":{transform:"translateY(-2px)",boxShadow:3},borderRadius:2,overflow:"hidden",position:"relative",height:80,backgroundColor:"background.paper"},children:[t(a,{sx:{width:80,backgroundColor:m.value,flexShrink:0,display:"flex",alignItems:"center",justifyContent:"center",position:"relative"},children:t(a,{sx:{position:"absolute",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(0,0,0,0.3)",opacity:0,transition:"opacity 0.2s","&:hover":{opacity:1},display:"flex",alignItems:"center",justifyContent:"center"},children:t(He,{sx:{color:"#fff"}})})}),c(a,{sx:{flexGrow:1,p:1.5,display:"flex",flexDirection:"column",justifyContent:"space-between",overflow:"hidden"},children:[c(a,{sx:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",mb:.5},children:[t(C,{variant:"caption",sx:{fontFamily:"monospace",fontWeight:"bold",color:"text.secondary"},children:m.value}),y&&t(R,{label:y,size:"small",icon:t("span",{style:{marginLeft:6,fontSize:"0.8rem"},children:E}),sx:{height:18,fontSize:"0.65rem","& .MuiChip-label":{padding:"0 6px"}}})]}),t(a,{sx:{display:"flex",flexWrap:"wrap",gap:.5},children:f.map((p,S)=>t(R,{label:p,size:"small",variant:"outlined",sx:{height:20,fontSize:"0.7rem",maxWidth:"100%","& .MuiChip-label":{padding:"0 6px",overflow:"hidden",textOverflow:"ellipsis"}}},S))})]})]})},ye=m=>{const{method:P,attribute:v,resourceConfig:O}=m,f=Oe(),{setValue:y,getValues:E}=$e(),p=v.attribute,S=p.startsWith("settings."),V=S?p.split(".").slice(1).join("."):p,[i,k]=u([]),[x,$]=u(""),[h,N]=u(""),[D,Y]=u(!0),[Q,X]=u(!0),[Ce,j]=u(!1),[be,W]=u(null),[ve,Se]=u([]),[A,I]=u(1),[w]=u(50),[F,Z]=u(!q),ee=G(null),te=G(null),it=G(new Map),L=b(e=>{window.dispatchEvent(new MessageEvent("auto-admin-loading-state",{data:e}))},[]),Ie=b(e=>{Se(e)},[]),we=fe(()=>Ze(i),[i]),g=fe(()=>{let e=i;return x.trim()&&(e=e.filter(o=>o.key.toLowerCase().includes(x.toLowerCase()))),h&&(e=e.filter(o=>{const{mode:r}=J(o.key);return r===h})),e},[i,x,h]),Ee=b(()=>{try{const e=Ae(i),o=new Blob([e],{type:"text/css"}),r=URL.createObjectURL(o),n=document.createElement("a");n.href=r,n.download="color-variables.css",document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(r),console.log("CSS variables exported successfully")}catch(e){console.error("Error exporting CSS variables:",e)}},[i]),Pe=b(()=>{ee.current?.click()},[]),ke=b(e=>{const o=e.target.files?.[0];if(!o)return;const r=new FileReader;r.onload=n=>{try{const s=n.target?.result,l=Le(s);if(l.length>0){const d=Te(i,l);k(d),z(d),console.log(`Imported ${l.length} color variables from CSS`)}else console.warn("No valid CSS variables found in the imported file")}catch(s){console.error("Error importing CSS file:",s)}},r.readAsText(o),e.target.value=""},[i]),Ae=e=>{const o=["/* Color Variables - Generated by JsonColorSelector */","/* Import this file or copy these variables to your CSS */","",":root {"],r=e.reduce((n,s)=>{if(!s.key.trim())return n;const{mode:l}=J(s.key),d=l||"default";return n[d]||(n[d]=[]),n[d].push(s),n},{});return Object.entries(r).forEach(([n,s])=>{s.length>0&&(o.push(` /* ${n} mode colors */`),s.forEach(l=>{const d=l.key.startsWith("--")?l.key:`--${l.key}`;o.push(` ${d}: ${l.value};`)}),o.push(""))}),o.push("}"),o.push(""),o.push("/* Usage example: */"),o.push("/* .my-element { background-color: var(--primary-color); } */"),o.join(`
2
- `)},Le=e=>{const o=[],r=e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\s+/g," ").trim(),n=/--([^:]+):\s*([^;]+);/g;let s;for(;(s=n.exec(r))!==null;){const[,l,d]=s,B=l.trim(),de=d.trim();Be(de)&&o.push({key:B,value:de,id:_()})}return o},Be=e=>[/^#[0-9a-fA-F]{3,8}$/,/^rgb\(/i,/^rgba\(/i,/^hsl\(/i,/^hsla\(/i,/^(red|blue|green|yellow|purple|orange|pink|brown|black|white|gray|grey)$/i].some(r=>r.test(e.trim())),Te=(e,o)=>{const r=[...e];return o.forEach(n=>{const s=r.findIndex(l=>l.key===n.key);s>=0?r[s]={...r[s],value:n.value}:r.push(n)}),r},Re=e=>{$(e.target.value),I(1)},oe=()=>{$(""),I(1)},Me=e=>{N(e.target.value),I(1)},ne=()=>{N(""),I(1)};M(()=>{(async()=>{Y(!0),L(!0);try{let o={},r={};try{r=v?.default_value||{}}catch{r={}}if(S&&f?.settings){const s=f.settings||{};o={...r,...re(s,V)}}else f?.[p]?o={...r,...f[p]}:o=r;const n=Object.entries(o).map(([s,l])=>({key:s,value:String(l),id:_()}));k(n),n.length>50&&await new Promise(s=>setTimeout(s,100))}catch(o){console.error("Error loading initial data:",o)}finally{Y(!1)}})()},[f,p]),M(()=>{!D&&i.length>=0&&(X(!0),requestAnimationFrame(()=>{requestAnimationFrame(()=>{X(!1),L(!1)})}))},[D,i.length,L]),M(()=>()=>{te.current&&clearTimeout(te.current),L(!1)},[L]);const re=(e,o)=>o?o.split(".").reduce((n,s)=>n&&n[s]!==void 0?n[s]:{},e):e,Ve=(e,o,r)=>{if(!o)return r;const n=o.split("."),s=n.pop(),l=n.reduce((d,B)=>(d[B]===void 0&&(d[B]={}),d[B]),e);return s&&(l[s]=r),e},_=()=>Math.random().toString(36).substring(2,11),se=()=>{const e={key:"",value:"#000000",id:_()};W(e),j(!0)},De=e=>{W(e),j(!0)},Fe=e=>{const o=i.findIndex(n=>n.id===e.id);let r;o>=0?r=i.map(n=>n.id===e.id?e:n):r=[...i,e],k(r),z(r),ie(e.key,e.value)},ae=e=>{const o=i.filter(r=>r.id!==e);k(o),z(o)},ze=e=>{k(e),z(e)},ie=b((e,o)=>{e.trim()&&requestAnimationFrame(()=>{const r=document.documentElement.getAttribute("data-theme")||"",n=r?`--${r}`:"";if(n&&e.endsWith(n)){const s=e.slice(0,-n.length);document.documentElement.style.setProperty(`--${s}`,o),document.documentElement.style.setProperty(`--${s}${n}`,o)}else{const s=e.startsWith("--")?e:`--${e}`;document.documentElement.style.setProperty(s,o)}})},[]),lt=e=>{const r=`--${document.documentElement.getAttribute("data-theme")}`;requestAnimationFrame(()=>{Object.entries(e).forEach(([n,s])=>{if(n.endsWith(r)){const l=n.slice(0,-r.length);document.documentElement.style.setProperty(`--${l}`,String(s))}})})},Ke=b(e=>{const o=i.reduce((r,n)=>(n.key.trim()&&(r[n.key]=n.value),r),{});he(e,o,ce())},[i]),le=b(()=>{try{let e={};if(S){const o=E("settings")||{};e=re(o,V)||{}}else e=E(p)||{};return e}catch(e){return console.error("Error syncing pairs from form values:",e),{}}},[E,S,V,p]),ce=()=>{const e=nt.getTenantSettings();return e?e?.values||{}:{}};M(()=>{const e=o=>{console.log("Theme switch event received:",o.detail.mode);const r=le();console.log("Current colors from form:",r),he(o.detail.mode,r,ce())};return window.addEventListener("dash-theme-mode-switched",e),()=>{window.removeEventListener("dash-theme-mode-switched",e)}},[le]);const z=e=>{const o=e.reduce((r,n)=>(n.key.trim()&&(r[n.key]=n.value),r),{});if(S){const r=E("settings")||{},n=Ve({...r},V,o);y("settings",n,{shouldDirty:!0})}else y(p,o,{shouldDirty:!0})};return D||Q?t(a,{sx:{mt:1,mb:2,display:"flex",justifyContent:"center",alignItems:"center",minHeight:200},children:t(C,{variant:"body2",color:"textSecondary",children:D?"Loading color settings...":"Rendering colors..."})}):c(a,{sx:{mt:1,mb:2},children:[t(C,{variant:"subtitle1",gutterBottom:!0,children:v.label||"Color Palette"}),t("input",{type:"file",ref:ee,accept:".css",style:{display:"none"},onChange:ke}),t(tt,{onColorsExtracted:Ie,onColorsUpdate:ze,existingPairs:i}),c(a,{sx:{mb:3,display:"flex",gap:2,alignItems:"flex-end"},children:[t(Ne,{fullWidth:!0,size:"small",placeholder:"Search colors by name...",value:x,onChange:Re,InputProps:{startAdornment:t(K,{position:"start",children:t(qe,{})}),endAdornment:x&&t(K,{position:"end",children:t(ue,{size:"small",onClick:oe,edge:"end",children:t(ge,{})})})}}),c(je,{size:"small",sx:{minWidth:150},children:[t(We,{children:"Mode"}),c(_e,{value:h,label:"Mode",onChange:Me,startAdornment:t(K,{position:"start",children:t(Ye,{fontSize:"small"})}),endAdornment:h&&t(K,{position:"end",children:t(ue,{size:"small",onClick:ne,edge:"end",sx:{mr:1},children:t(ge,{fontSize:"small"})})}),children:[t(me,{value:"",children:t("em",{children:"All Modes"})}),we.map(e=>t(me,{value:e,children:c(a,{sx:{display:"flex",alignItems:"center",gap:1},children:[t("span",{children:H(e)}),t("span",{children:e})]})},e))]})]})]}),c(a,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between",mb:3,flexWrap:"wrap",gap:1},children:[c(a,{sx:{display:"flex",gap:1,flexWrap:"wrap"},children:[t(T,{startIcon:t(Je,{}),variant:"contained",size:"small",onClick:()=>Ke(document.documentElement.getAttribute("data-theme")),color:"primary",children:"Preview Colors"}),t(T,{startIcon:t(Qe,{}),variant:"outlined",size:"small",onClick:Ee,color:"secondary",disabled:i.length===0,children:"Export CSS"}),t(T,{startIcon:t(Xe,{}),variant:"outlined",size:"small",onClick:Pe,color:"secondary",children:"Import CSS"})]}),t(T,{startIcon:t(pe,{}),variant:"outlined",size:"small",onClick:se,children:"Add Color"})]}),(x||h)&&c(a,{sx:{mb:2,display:"flex",alignItems:"center",gap:1,flexWrap:"wrap"},children:[t(R,{label:`${g.length} of ${i.length} colors`,size:"small",variant:"outlined"}),h&&t(R,{label:`Mode: ${h}`,size:"small",variant:"filled",color:"primary",onDelete:ne,avatar:t("span",{style:{paddingLeft:6},children:H(h)})}),x&&t(R,{label:`Search: "${x}"`,size:"small",variant:"filled",color:"secondary",onDelete:oe})]}),t(a,{sx:{flexGrow:1,my:2},children:Q?t(a,{sx:{display:"flex",justifyContent:"center",p:4,alignItems:"center",flexDirection:"column",gap:2},children:t(C,{children:"Rendering Grid..."})}):g.length>0?c(xe,{children:[t(a,{sx:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(300px, 1fr))",gap:2,width:"100%"},children:(F?g:g.slice((A-1)*w,A*w)).map(e=>t(a,{sx:{minWidth:0},children:t(st,{pair:e,onEdit:De,onDelete:ae})},e.id))}),q&&!F&&g.length>w&&c(a,{sx:{mt:4,display:"flex",flexDirection:"column",alignItems:"center",gap:1},children:[t(Ue,{count:Math.ceil(g.length/w),page:A,onChange:(e,o)=>I(o),color:"primary",size:"large",showFirstButton:!0,showLastButton:!0}),rt&&t(U,{component:"button",variant:"body2",underline:"always",onClick:()=>Z(!0),sx:{mt:.5,fontSize:"0.8rem",cursor:"pointer"},children:"Show all"})]}),t(C,{variant:"caption",sx:{display:"block",textAlign:"center",mt:2,color:"text.secondary"},children:F?`Showing all ${g.length} colors`:`Showing ${Math.min((A-1)*w+1,g.length)} - ${Math.min(A*w,g.length)} of ${g.length} colors`}),q&&F&&g.length>w&&t(a,{sx:{display:"flex",justifyContent:"center",mt:1},children:t(U,{component:"button",variant:"body2",underline:"always",onClick:()=>{Z(!1),I(1)},sx:{fontSize:"0.8rem",cursor:"pointer"},children:"Show paginated"})})]}):c(a,{sx:{p:4,textAlign:"center",bgcolor:"background.paper",borderRadius:1,border:"1px dashed #ccc"},children:[t(C,{color:"textSecondary",children:"No colors found using current filters."}),t(a,{sx:{mt:1},children:t(U,{component:"button",variant:"body2",onClick:()=>{$(""),N(""),I(1)},children:"Clear filters"})})]})}),i.length===0&&c(a,{sx:{textAlign:"center",py:4},children:[t(C,{variant:"body2",color:"textSecondary",gutterBottom:!0,children:"No colors in your palette yet"}),t(T,{startIcon:t(pe,{}),variant:"contained",onClick:se,children:"Add Your First Color"})]}),t(ot,{open:Ce,pair:be,onClose:()=>{j(!1),W(null)},onSave:Fe,onDelete:ae,existingKeys:i.map(e=>e.key),updateSingleDomColor:ie,extractedColors:ve})]})},at=({method:m,attribute:P,resourceConfig:v})=>{const[O,f]=u(!0);if(M(()=>{window.dispatchEvent(new MessageEvent("auto-admin-loading-state",{data:!0}));const y=setTimeout(()=>{f(!1)},50);return()=>{clearTimeout(y),window.dispatchEvent(new MessageEvent("auto-admin-loading-state",{data:!1}))}},[]),O)return t(a,{sx:{display:"flex",justifyContent:"center",alignItems:"center",minHeight:100},children:t(C,{variant:"body2",color:"textSecondary",children:"Initializing color palette..."})});switch(m){case"edit":return t(ye,{attribute:P,method:m,resourceConfig:v});case"create":return t(ye,{attribute:P,method:m,resourceConfig:v});default:return t(xe,{children:"Not implemented"})}};var Mt=at;export{ye as JsonEdit,Mt as default};
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
40
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
41
+ import { useRecordContext } from "react-admin";
42
+ import { useFormContext } from "react-hook-form";
43
+ import {
44
+ Box,
45
+ Button,
46
+ IconButton,
47
+ TextField,
48
+ Typography,
49
+ Chip,
50
+ InputAdornment,
51
+ FormControl,
52
+ InputLabel,
53
+ Select,
54
+ MenuItem,
55
+ Pagination,
56
+ Card,
57
+ Link
58
+ } from "@mui/material";
59
+ import AddIcon from "@mui/icons-material/Add";
60
+ import EditIcon from "@mui/icons-material/Edit";
61
+ import PreviewIcon from "@mui/icons-material/Preview";
62
+ import SearchIcon from "@mui/icons-material/Search";
63
+ import ClearIcon from "@mui/icons-material/Clear";
64
+ import FilterListIcon from "@mui/icons-material/FilterList";
65
+ import DownloadIcon from "@mui/icons-material/Download";
66
+ import UploadIcon from "@mui/icons-material/Upload";
67
+ import { useState, useEffect, useRef, useCallback, useMemo } from "react";
68
+ import { extractAvailableModes, getContrastColor, getModeIcon, parseColorKey } from "./helpers/functions";
69
+ import ImageColorExtractor from "./components/ImageColorExtractor";
70
+ import ColorEditDialog from "./components/ColorEditDialog";
71
+ import { updateDomCssVariables } from "dash-utils";
72
+ import { AuthPersistenceService } from "dash-auth";
73
+ const JSON_COLOR_SELECTOR_PAGINATION_ENABLED = false;
74
+ const JSON_COLOR_SELECTOR_PAGINATION_SHOW_ALL = false;
75
+ const DEFAULT_COLOR_MAPPINGS = {
76
+ "primary-color": "Primary Color",
77
+ "secondary-color": "Secondary Color",
78
+ "highlight-color": "Highlight Color",
79
+ "contrast-color": "Contrast Color"
80
+ };
81
+ const LocalColorPaletteItem = ({ pair, onEdit, onDelete }) => {
82
+ const textColor = getContrastColor(pair.value);
83
+ const { baseChips, mode } = parseColorKey(pair.key);
84
+ const modeIcon = getModeIcon(mode);
85
+ return /* @__PURE__ */ jsxs(
86
+ Card,
87
+ {
88
+ onClick: () => onEdit(pair),
89
+ elevation: 1,
90
+ sx: {
91
+ width: "100%",
92
+ display: "flex",
93
+ alignItems: "stretch",
94
+ // Ensure stretch for full height
95
+ cursor: "pointer",
96
+ transition: "all 0.2s ease-in-out",
97
+ "&:hover": {
98
+ transform: "translateY(-2px)",
99
+ boxShadow: 3
100
+ },
101
+ borderRadius: 2,
102
+ overflow: "hidden",
103
+ position: "relative",
104
+ height: 80,
105
+ // Fixed height for consistency
106
+ backgroundColor: "background.paper"
107
+ },
108
+ children: [
109
+ /* @__PURE__ */ jsx(
110
+ Box,
111
+ {
112
+ sx: {
113
+ width: 80,
114
+ // Fixed square width
115
+ backgroundColor: pair.value,
116
+ flexShrink: 0,
117
+ display: "flex",
118
+ alignItems: "center",
119
+ justifyContent: "center",
120
+ position: "relative"
121
+ },
122
+ children: /* @__PURE__ */ jsx(
123
+ Box,
124
+ {
125
+ sx: {
126
+ position: "absolute",
127
+ top: 0,
128
+ left: 0,
129
+ right: 0,
130
+ bottom: 0,
131
+ backgroundColor: "rgba(0,0,0,0.3)",
132
+ opacity: 0,
133
+ transition: "opacity 0.2s",
134
+ "&:hover": { opacity: 1 },
135
+ display: "flex",
136
+ alignItems: "center",
137
+ justifyContent: "center"
138
+ },
139
+ children: /* @__PURE__ */ jsx(EditIcon, { sx: { color: "#fff" } })
140
+ }
141
+ )
142
+ }
143
+ ),
144
+ /* @__PURE__ */ jsxs(Box, { sx: {
145
+ flexGrow: 1,
146
+ p: 1.5,
147
+ display: "flex",
148
+ flexDirection: "column",
149
+ justifyContent: "space-between",
150
+ overflow: "hidden"
151
+ }, children: [
152
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "flex-start", justifyContent: "space-between", mb: 0.5 }, children: [
153
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", sx: { fontFamily: "monospace", fontWeight: "bold", color: "text.secondary" }, children: pair.value }),
154
+ mode && /* @__PURE__ */ jsx(
155
+ Chip,
156
+ {
157
+ label: mode,
158
+ size: "small",
159
+ icon: /* @__PURE__ */ jsx("span", { style: { marginLeft: 6, fontSize: "0.8rem" }, children: modeIcon }),
160
+ sx: {
161
+ height: 18,
162
+ fontSize: "0.65rem",
163
+ "& .MuiChip-label": { padding: "0 6px" }
164
+ }
165
+ }
166
+ )
167
+ ] }),
168
+ /* @__PURE__ */ jsx(Box, { sx: { display: "flex", flexWrap: "wrap", gap: 0.5 }, children: baseChips.map((chip, index) => /* @__PURE__ */ jsx(
169
+ Chip,
170
+ {
171
+ label: chip,
172
+ size: "small",
173
+ variant: "outlined",
174
+ sx: {
175
+ height: 20,
176
+ fontSize: "0.7rem",
177
+ maxWidth: "100%",
178
+ "& .MuiChip-label": {
179
+ padding: "0 6px",
180
+ overflow: "hidden",
181
+ textOverflow: "ellipsis"
182
+ }
183
+ }
184
+ },
185
+ index
186
+ )) })
187
+ ] })
188
+ ]
189
+ }
190
+ );
191
+ };
192
+ const JsonEdit = (props) => {
193
+ const { method, attribute, resourceConfig } = props;
194
+ const record = useRecordContext();
195
+ const { setValue, getValues } = useFormContext();
196
+ const attributePath = attribute.attribute;
197
+ const isNestedSetting = attributePath.startsWith("settings.");
198
+ const settingsPath = isNestedSetting ? attributePath.split(".").slice(1).join(".") : attributePath;
199
+ const [pairs, setPairs] = useState([]);
200
+ const [searchTerm, setSearchTerm] = useState("");
201
+ const [selectedMode, setSelectedMode] = useState("");
202
+ const [isLoading, setIsLoading] = useState(true);
203
+ const [isRendering, setIsRendering] = useState(true);
204
+ const [editDialogOpen, setEditDialogOpen] = useState(false);
205
+ const [editingPair, setEditingPair] = useState(null);
206
+ const [extractedColors, setExtractedColors] = useState([]);
207
+ const [page, setPage] = useState(1);
208
+ const [pageSize] = useState(50);
209
+ const [showAll, setShowAll] = useState(!JSON_COLOR_SELECTOR_PAGINATION_ENABLED);
210
+ const fileInputRef = useRef(null);
211
+ const throttleTimeoutRef = useRef(null);
212
+ const pendingUpdatesRef = useRef(/* @__PURE__ */ new Map());
213
+ const dispatchLoadingEvent = useCallback((loading) => {
214
+ window.dispatchEvent(new MessageEvent("auto-admin-loading-state", { data: loading }));
215
+ }, []);
216
+ const handleColorsExtracted = useCallback((colors) => {
217
+ setExtractedColors(colors);
218
+ }, []);
219
+ const availableModes = useMemo(() => {
220
+ return extractAvailableModes(pairs);
221
+ }, [pairs]);
222
+ const filteredPairs = useMemo(() => {
223
+ let filtered = pairs;
224
+ if (searchTerm.trim()) {
225
+ filtered = filtered.filter(
226
+ (pair) => pair.key.toLowerCase().includes(searchTerm.toLowerCase())
227
+ );
228
+ }
229
+ if (selectedMode) {
230
+ filtered = filtered.filter((pair) => {
231
+ const { mode } = parseColorKey(pair.key);
232
+ return mode === selectedMode;
233
+ });
234
+ }
235
+ return filtered;
236
+ }, [pairs, searchTerm, selectedMode]);
237
+ const handleExportCSS = useCallback(() => {
238
+ try {
239
+ const cssContent = generateCSSContent(pairs);
240
+ const blob = new Blob([cssContent], { type: "text/css" });
241
+ const url = URL.createObjectURL(blob);
242
+ const link = document.createElement("a");
243
+ link.href = url;
244
+ link.download = "color-variables.css";
245
+ document.body.appendChild(link);
246
+ link.click();
247
+ document.body.removeChild(link);
248
+ URL.revokeObjectURL(url);
249
+ console.log("CSS variables exported successfully");
250
+ } catch (error) {
251
+ console.error("Error exporting CSS variables:", error);
252
+ }
253
+ }, [pairs]);
254
+ const handleImportCSS = useCallback(() => {
255
+ var _a;
256
+ (_a = fileInputRef.current) == null ? void 0 : _a.click();
257
+ }, []);
258
+ const handleFileSelect = useCallback((event) => {
259
+ var _a;
260
+ const file = (_a = event.target.files) == null ? void 0 : _a[0];
261
+ if (!file) return;
262
+ const reader = new FileReader();
263
+ reader.onload = (e) => {
264
+ var _a2;
265
+ try {
266
+ const cssContent = (_a2 = e.target) == null ? void 0 : _a2.result;
267
+ const importedPairs = parseCSSContent(cssContent);
268
+ if (importedPairs.length > 0) {
269
+ const mergedPairs = mergePairs(pairs, importedPairs);
270
+ setPairs(mergedPairs);
271
+ updateFormValue(mergedPairs);
272
+ console.log(`Imported ${importedPairs.length} color variables from CSS`);
273
+ } else {
274
+ console.warn("No valid CSS variables found in the imported file");
275
+ }
276
+ } catch (error) {
277
+ console.error("Error importing CSS file:", error);
278
+ }
279
+ };
280
+ reader.readAsText(file);
281
+ event.target.value = "";
282
+ }, [pairs]);
283
+ const generateCSSContent = (colorPairs) => {
284
+ const cssLines = [
285
+ "/* Color Variables - Generated by JsonColorSelector */",
286
+ "/* Import this file or copy these variables to your CSS */",
287
+ "",
288
+ ":root {"
289
+ ];
290
+ const groupedPairs = colorPairs.reduce((acc, pair) => {
291
+ if (!pair.key.trim()) return acc;
292
+ const { mode } = parseColorKey(pair.key);
293
+ const groupKey = mode || "default";
294
+ if (!acc[groupKey]) {
295
+ acc[groupKey] = [];
296
+ }
297
+ acc[groupKey].push(pair);
298
+ return acc;
299
+ }, {});
300
+ Object.entries(groupedPairs).forEach(([mode, modePairs]) => {
301
+ if (modePairs.length > 0) {
302
+ cssLines.push(` /* ${mode} mode colors */`);
303
+ modePairs.forEach((pair) => {
304
+ const cssVarName = pair.key.startsWith("--") ? pair.key : `--${pair.key}`;
305
+ cssLines.push(` ${cssVarName}: ${pair.value};`);
306
+ });
307
+ cssLines.push("");
308
+ }
309
+ });
310
+ cssLines.push("}");
311
+ cssLines.push("");
312
+ cssLines.push("/* Usage example: */");
313
+ cssLines.push("/* .my-element { background-color: var(--primary-color); } */");
314
+ return cssLines.join("\n");
315
+ };
316
+ const parseCSSContent = (cssContent) => {
317
+ const pairs2 = [];
318
+ const cleanCSS = cssContent.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").trim();
319
+ const variableRegex = /--([^:]+):\s*([^;]+);/g;
320
+ let match;
321
+ while ((match = variableRegex.exec(cleanCSS)) !== null) {
322
+ const [, name, value] = match;
323
+ const cleanName = name.trim();
324
+ const cleanValue = value.trim();
325
+ if (isColorValue(cleanValue)) {
326
+ pairs2.push({
327
+ key: cleanName,
328
+ value: cleanValue,
329
+ id: generateId()
330
+ });
331
+ }
332
+ }
333
+ return pairs2;
334
+ };
335
+ const isColorValue = (value) => {
336
+ const colorPatterns = [
337
+ /^#[0-9a-fA-F]{3,8}$/,
338
+ // Hex colors
339
+ /^rgb\(/i,
340
+ // RGB colors
341
+ /^rgba\(/i,
342
+ // RGBA colors
343
+ /^hsl\(/i,
344
+ // HSL colors
345
+ /^hsla\(/i,
346
+ // HSLA colors
347
+ /^(red|blue|green|yellow|purple|orange|pink|brown|black|white|gray|grey)$/i
348
+ // Named colors
349
+ ];
350
+ return colorPatterns.some((pattern) => pattern.test(value.trim()));
351
+ };
352
+ const mergePairs = (existingPairs, importedPairs) => {
353
+ const merged = [...existingPairs];
354
+ importedPairs.forEach((importedPair) => {
355
+ const existingIndex = merged.findIndex((pair) => pair.key === importedPair.key);
356
+ if (existingIndex >= 0) {
357
+ merged[existingIndex] = __spreadProps(__spreadValues({}, merged[existingIndex]), { value: importedPair.value });
358
+ } else {
359
+ merged.push(importedPair);
360
+ }
361
+ });
362
+ return merged;
363
+ };
364
+ const handleSearchChange = (event) => {
365
+ setSearchTerm(event.target.value);
366
+ setPage(1);
367
+ };
368
+ const handleClearSearch = () => {
369
+ setSearchTerm("");
370
+ setPage(1);
371
+ };
372
+ const handleModeChange = (event) => {
373
+ setSelectedMode(event.target.value);
374
+ setPage(1);
375
+ };
376
+ const handleClearMode = () => {
377
+ setSelectedMode("");
378
+ setPage(1);
379
+ };
380
+ useEffect(() => {
381
+ const loadInitialData = () => __async(null, null, function* () {
382
+ setIsLoading(true);
383
+ dispatchLoadingEvent(true);
384
+ try {
385
+ let initialValue = {};
386
+ let defaultValues = {};
387
+ try {
388
+ defaultValues = (attribute == null ? void 0 : attribute.default_value) || {};
389
+ } catch (e) {
390
+ defaultValues = {};
391
+ }
392
+ if (isNestedSetting && (record == null ? void 0 : record.settings)) {
393
+ const settings = record.settings || {};
394
+ initialValue = __spreadValues(__spreadValues({}, defaultValues), getNestedValue(settings, settingsPath));
395
+ } else if (record == null ? void 0 : record[attributePath]) {
396
+ initialValue = __spreadValues(__spreadValues({}, defaultValues), record[attributePath]);
397
+ } else {
398
+ initialValue = defaultValues;
399
+ }
400
+ const initialPairs = Object.entries(initialValue).map(([key, value]) => ({
401
+ key,
402
+ value: String(value),
403
+ id: generateId()
404
+ }));
405
+ setPairs(initialPairs);
406
+ if (initialPairs.length > 50) {
407
+ yield new Promise((resolve) => setTimeout(resolve, 100));
408
+ }
409
+ } catch (error) {
410
+ console.error("Error loading initial data:", error);
411
+ } finally {
412
+ setIsLoading(false);
413
+ }
414
+ });
415
+ loadInitialData();
416
+ }, [record, attributePath]);
417
+ useEffect(() => {
418
+ if (!isLoading && pairs.length >= 0) {
419
+ setIsRendering(true);
420
+ requestAnimationFrame(() => {
421
+ requestAnimationFrame(() => {
422
+ setIsRendering(false);
423
+ dispatchLoadingEvent(false);
424
+ });
425
+ });
426
+ }
427
+ }, [isLoading, pairs.length, dispatchLoadingEvent]);
428
+ useEffect(() => {
429
+ return () => {
430
+ if (throttleTimeoutRef.current) {
431
+ clearTimeout(throttleTimeoutRef.current);
432
+ }
433
+ dispatchLoadingEvent(false);
434
+ };
435
+ }, [dispatchLoadingEvent]);
436
+ const getNestedValue = (obj, path) => {
437
+ if (!path) return obj;
438
+ const keys = path.split(".");
439
+ return keys.reduce((o, key) => o && o[key] !== void 0 ? o[key] : {}, obj);
440
+ };
441
+ const setNestedValue = (obj, path, value) => {
442
+ if (!path) return value;
443
+ const keys = path.split(".");
444
+ const lastKey = keys.pop();
445
+ const lastObj = keys.reduce((o, key) => {
446
+ if (o[key] === void 0) o[key] = {};
447
+ return o[key];
448
+ }, obj);
449
+ if (lastKey) {
450
+ lastObj[lastKey] = value;
451
+ }
452
+ return obj;
453
+ };
454
+ const generateId = () => {
455
+ return Math.random().toString(36).substring(2, 11);
456
+ };
457
+ const addPair = () => {
458
+ const newPair = { key: "", value: "#000000", id: generateId() };
459
+ setEditingPair(newPair);
460
+ setEditDialogOpen(true);
461
+ };
462
+ const handleEditPair = (pair) => {
463
+ setEditingPair(pair);
464
+ setEditDialogOpen(true);
465
+ };
466
+ const handleSavePair = (editedPair) => {
467
+ const existingIndex = pairs.findIndex((p) => p.id === editedPair.id);
468
+ let updatedPairs;
469
+ if (existingIndex >= 0) {
470
+ updatedPairs = pairs.map((p) => p.id === editedPair.id ? editedPair : p);
471
+ } else {
472
+ updatedPairs = [...pairs, editedPair];
473
+ }
474
+ setPairs(updatedPairs);
475
+ updateFormValue(updatedPairs);
476
+ updateSingleDomColor(editedPair.key, editedPair.value);
477
+ };
478
+ const handleDeletePair = (id) => {
479
+ const updatedPairs = pairs.filter((pair) => pair.id !== id);
480
+ setPairs(updatedPairs);
481
+ updateFormValue(updatedPairs);
482
+ };
483
+ const handleColorsUpdate = (newPairs) => {
484
+ setPairs(newPairs);
485
+ updateFormValue(newPairs);
486
+ };
487
+ const updateSingleDomColor = useCallback((key, color) => {
488
+ if (!key.trim()) return;
489
+ requestAnimationFrame(() => {
490
+ const currentTheme = document.documentElement.getAttribute("data-theme") || "";
491
+ const themeSuffix = currentTheme ? `--${currentTheme}` : "";
492
+ if (themeSuffix && key.endsWith(themeSuffix)) {
493
+ const baseKey = key.slice(0, -themeSuffix.length);
494
+ document.documentElement.style.setProperty(`--${baseKey}`, color);
495
+ document.documentElement.style.setProperty(`--${baseKey}${themeSuffix}`, color);
496
+ } else {
497
+ const varName = key.startsWith("--") ? key : `--${key}`;
498
+ document.documentElement.style.setProperty(varName, color);
499
+ }
500
+ });
501
+ }, []);
502
+ const updateDomColors = (colors) => {
503
+ const currentTheme = document.documentElement.getAttribute("data-theme");
504
+ const themeSuffix = `--${currentTheme}`;
505
+ requestAnimationFrame(() => {
506
+ Object.entries(colors).forEach(([key, value]) => {
507
+ if (key.endsWith(themeSuffix)) {
508
+ const baseKey = key.slice(0, -themeSuffix.length);
509
+ document.documentElement.style.setProperty(`--${baseKey}`, String(value));
510
+ }
511
+ });
512
+ });
513
+ };
514
+ const handlePreview = useCallback((m) => {
515
+ const colorsObj = pairs.reduce((acc, pair) => {
516
+ if (pair.key.trim()) {
517
+ acc[pair.key] = pair.value;
518
+ }
519
+ return acc;
520
+ }, {});
521
+ updateDomCssVariables(m, colorsObj, getTenantSettingsValues());
522
+ }, [pairs]);
523
+ const syncPairsFromForm = useCallback(() => {
524
+ try {
525
+ let currentFormValue = {};
526
+ if (isNestedSetting) {
527
+ const currentSettings = getValues("settings") || {};
528
+ currentFormValue = getNestedValue(currentSettings, settingsPath) || {};
529
+ } else {
530
+ currentFormValue = getValues(attributePath) || {};
531
+ }
532
+ return currentFormValue;
533
+ } catch (error) {
534
+ console.error("Error syncing pairs from form values:", error);
535
+ return {};
536
+ }
537
+ }, [getValues, isNestedSetting, settingsPath, attributePath]);
538
+ const getTenantSettingsValues = () => {
539
+ const persistedTenantSettings = AuthPersistenceService.getTenantSettings();
540
+ if (persistedTenantSettings) {
541
+ return (persistedTenantSettings == null ? void 0 : persistedTenantSettings.values) || {};
542
+ }
543
+ return {};
544
+ };
545
+ useEffect(() => {
546
+ const handleThemeSwitch = (event) => {
547
+ console.log("Theme switch event received:", event.detail.mode);
548
+ const currentColors = syncPairsFromForm();
549
+ console.log("Current colors from form:", currentColors);
550
+ updateDomCssVariables(event.detail.mode, currentColors, getTenantSettingsValues());
551
+ };
552
+ window.addEventListener("dash-theme-mode-switched", handleThemeSwitch);
553
+ return () => {
554
+ window.removeEventListener("dash-theme-mode-switched", handleThemeSwitch);
555
+ };
556
+ }, [syncPairsFromForm]);
557
+ const updateFormValue = (currentPairs) => {
558
+ const obj = currentPairs.reduce((acc, pair) => {
559
+ if (pair.key.trim()) {
560
+ acc[pair.key] = pair.value;
561
+ }
562
+ return acc;
563
+ }, {});
564
+ if (isNestedSetting) {
565
+ const currentSettings = getValues("settings") || {};
566
+ const updatedSettings = setNestedValue(__spreadValues({}, currentSettings), settingsPath, obj);
567
+ setValue("settings", updatedSettings, { shouldDirty: true });
568
+ } else {
569
+ setValue(attributePath, obj, { shouldDirty: true });
570
+ }
571
+ };
572
+ if (isLoading || isRendering) {
573
+ return /* @__PURE__ */ jsx(Box, { sx: { mt: 1, mb: 2, display: "flex", justifyContent: "center", alignItems: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: isLoading ? "Loading color settings..." : "Rendering colors..." }) });
574
+ }
575
+ return /* @__PURE__ */ jsxs(Box, { sx: { mt: 1, mb: 2 }, children: [
576
+ /* @__PURE__ */ jsx(Typography, { variant: "subtitle1", gutterBottom: true, children: attribute.label || "Color Palette" }),
577
+ /* @__PURE__ */ jsx(
578
+ "input",
579
+ {
580
+ type: "file",
581
+ ref: fileInputRef,
582
+ accept: ".css",
583
+ style: { display: "none" },
584
+ onChange: handleFileSelect
585
+ }
586
+ ),
587
+ /* @__PURE__ */ jsx(
588
+ ImageColorExtractor,
589
+ {
590
+ onColorsExtracted: handleColorsExtracted,
591
+ onColorsUpdate: handleColorsUpdate,
592
+ existingPairs: pairs
593
+ }
594
+ ),
595
+ /* @__PURE__ */ jsxs(Box, { sx: { mb: 3, display: "flex", gap: 2, alignItems: "flex-end" }, children: [
596
+ /* @__PURE__ */ jsx(
597
+ TextField,
598
+ {
599
+ fullWidth: true,
600
+ size: "small",
601
+ placeholder: "Search colors by name...",
602
+ value: searchTerm,
603
+ onChange: handleSearchChange,
604
+ InputProps: {
605
+ startAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "start", children: /* @__PURE__ */ jsx(SearchIcon, {}) }),
606
+ endAdornment: searchTerm && /* @__PURE__ */ jsx(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx(
607
+ IconButton,
608
+ {
609
+ size: "small",
610
+ onClick: handleClearSearch,
611
+ edge: "end",
612
+ children: /* @__PURE__ */ jsx(ClearIcon, {})
613
+ }
614
+ ) })
615
+ }
616
+ }
617
+ ),
618
+ /* @__PURE__ */ jsxs(FormControl, { size: "small", sx: { minWidth: 150 }, children: [
619
+ /* @__PURE__ */ jsx(InputLabel, { children: "Mode" }),
620
+ /* @__PURE__ */ jsxs(
621
+ Select,
622
+ {
623
+ value: selectedMode,
624
+ label: "Mode",
625
+ onChange: handleModeChange,
626
+ startAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "start", children: /* @__PURE__ */ jsx(FilterListIcon, { fontSize: "small" }) }),
627
+ endAdornment: selectedMode && /* @__PURE__ */ jsx(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx(
628
+ IconButton,
629
+ {
630
+ size: "small",
631
+ onClick: handleClearMode,
632
+ edge: "end",
633
+ sx: { mr: 1 },
634
+ children: /* @__PURE__ */ jsx(ClearIcon, { fontSize: "small" })
635
+ }
636
+ ) }),
637
+ children: [
638
+ /* @__PURE__ */ jsx(MenuItem, { value: "", children: /* @__PURE__ */ jsx("em", { children: "All Modes" }) }),
639
+ availableModes.map((mode) => /* @__PURE__ */ jsx(MenuItem, { value: mode, children: /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
640
+ /* @__PURE__ */ jsx("span", { children: getModeIcon(mode) }),
641
+ /* @__PURE__ */ jsx("span", { children: mode })
642
+ ] }) }, mode))
643
+ ]
644
+ }
645
+ )
646
+ ] })
647
+ ] }),
648
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 3, flexWrap: "wrap", gap: 1 }, children: [
649
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", gap: 1, flexWrap: "wrap" }, children: [
650
+ /* @__PURE__ */ jsx(
651
+ Button,
652
+ {
653
+ startIcon: /* @__PURE__ */ jsx(PreviewIcon, {}),
654
+ variant: "contained",
655
+ size: "small",
656
+ onClick: () => handlePreview(document.documentElement.getAttribute("data-theme")),
657
+ color: "primary",
658
+ children: "Preview Colors"
659
+ }
660
+ ),
661
+ /* @__PURE__ */ jsx(
662
+ Button,
663
+ {
664
+ startIcon: /* @__PURE__ */ jsx(DownloadIcon, {}),
665
+ variant: "outlined",
666
+ size: "small",
667
+ onClick: handleExportCSS,
668
+ color: "secondary",
669
+ disabled: pairs.length === 0,
670
+ children: "Export CSS"
671
+ }
672
+ ),
673
+ /* @__PURE__ */ jsx(
674
+ Button,
675
+ {
676
+ startIcon: /* @__PURE__ */ jsx(UploadIcon, {}),
677
+ variant: "outlined",
678
+ size: "small",
679
+ onClick: handleImportCSS,
680
+ color: "secondary",
681
+ children: "Import CSS"
682
+ }
683
+ )
684
+ ] }),
685
+ /* @__PURE__ */ jsx(
686
+ Button,
687
+ {
688
+ startIcon: /* @__PURE__ */ jsx(AddIcon, {}),
689
+ variant: "outlined",
690
+ size: "small",
691
+ onClick: addPair,
692
+ children: "Add Color"
693
+ }
694
+ )
695
+ ] }),
696
+ (searchTerm || selectedMode) && /* @__PURE__ */ jsxs(Box, { sx: { mb: 2, display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap" }, children: [
697
+ /* @__PURE__ */ jsx(
698
+ Chip,
699
+ {
700
+ label: `${filteredPairs.length} of ${pairs.length} colors`,
701
+ size: "small",
702
+ variant: "outlined"
703
+ }
704
+ ),
705
+ selectedMode && /* @__PURE__ */ jsx(
706
+ Chip,
707
+ {
708
+ label: `Mode: ${selectedMode}`,
709
+ size: "small",
710
+ variant: "filled",
711
+ color: "primary",
712
+ onDelete: handleClearMode,
713
+ avatar: /* @__PURE__ */ jsx("span", { style: { paddingLeft: 6 }, children: getModeIcon(selectedMode) })
714
+ }
715
+ ),
716
+ searchTerm && /* @__PURE__ */ jsx(
717
+ Chip,
718
+ {
719
+ label: `Search: "${searchTerm}"`,
720
+ size: "small",
721
+ variant: "filled",
722
+ color: "secondary",
723
+ onDelete: handleClearSearch
724
+ }
725
+ )
726
+ ] }),
727
+ /* @__PURE__ */ jsx(Box, { sx: { flexGrow: 1, my: 2 }, children: isRendering ? /* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "center", p: 4, alignItems: "center", flexDirection: "column", gap: 2 }, children: /* @__PURE__ */ jsx(Typography, { children: "Rendering Grid..." }) }) : filteredPairs.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
728
+ /* @__PURE__ */ jsx(Box, { sx: {
729
+ display: "grid",
730
+ gridTemplateColumns: "repeat(auto-fill, minmax(300px, 1fr))",
731
+ gap: 2,
732
+ width: "100%"
733
+ }, children: (showAll ? filteredPairs : filteredPairs.slice((page - 1) * pageSize, page * pageSize)).map((pair) => /* @__PURE__ */ jsx(Box, { sx: { minWidth: 0 }, children: /* @__PURE__ */ jsx(
734
+ LocalColorPaletteItem,
735
+ {
736
+ pair,
737
+ onEdit: handleEditPair,
738
+ onDelete: handleDeletePair
739
+ }
740
+ ) }, pair.id)) }),
741
+ JSON_COLOR_SELECTOR_PAGINATION_ENABLED && !showAll && filteredPairs.length > pageSize && /* @__PURE__ */ jsxs(Box, { sx: { mt: 4, display: "flex", flexDirection: "column", alignItems: "center", gap: 1 }, children: [
742
+ /* @__PURE__ */ jsx(
743
+ Pagination,
744
+ {
745
+ count: Math.ceil(filteredPairs.length / pageSize),
746
+ page,
747
+ onChange: (_, value) => setPage(value),
748
+ color: "primary",
749
+ size: "large",
750
+ showFirstButton: true,
751
+ showLastButton: true
752
+ }
753
+ ),
754
+ JSON_COLOR_SELECTOR_PAGINATION_SHOW_ALL && /* @__PURE__ */ jsx(
755
+ Link,
756
+ {
757
+ component: "button",
758
+ variant: "body2",
759
+ underline: "always",
760
+ onClick: () => setShowAll(true),
761
+ sx: { mt: 0.5, fontSize: "0.8rem", cursor: "pointer" },
762
+ children: "Show all"
763
+ }
764
+ )
765
+ ] }),
766
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", sx: { display: "block", textAlign: "center", mt: 2, color: "text.secondary" }, children: showAll ? `Showing all ${filteredPairs.length} colors` : `Showing ${Math.min((page - 1) * pageSize + 1, filteredPairs.length)} - ${Math.min(page * pageSize, filteredPairs.length)} of ${filteredPairs.length} colors` }),
767
+ JSON_COLOR_SELECTOR_PAGINATION_ENABLED && showAll && filteredPairs.length > pageSize && /* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "center", mt: 1 }, children: /* @__PURE__ */ jsx(
768
+ Link,
769
+ {
770
+ component: "button",
771
+ variant: "body2",
772
+ underline: "always",
773
+ onClick: () => {
774
+ setShowAll(false);
775
+ setPage(1);
776
+ },
777
+ sx: { fontSize: "0.8rem", cursor: "pointer" },
778
+ children: "Show paginated"
779
+ }
780
+ ) })
781
+ ] }) : /* @__PURE__ */ jsxs(Box, { sx: {
782
+ p: 4,
783
+ textAlign: "center",
784
+ bgcolor: "background.paper",
785
+ borderRadius: 1,
786
+ border: "1px dashed #ccc"
787
+ }, children: [
788
+ /* @__PURE__ */ jsx(Typography, { color: "textSecondary", children: "No colors found using current filters." }),
789
+ /* @__PURE__ */ jsx(Box, { sx: { mt: 1 }, children: /* @__PURE__ */ jsx(
790
+ Link,
791
+ {
792
+ component: "button",
793
+ variant: "body2",
794
+ onClick: () => {
795
+ setSearchTerm("");
796
+ setSelectedMode("");
797
+ setPage(1);
798
+ },
799
+ children: "Clear filters"
800
+ }
801
+ ) })
802
+ ] }) }),
803
+ pairs.length === 0 && /* @__PURE__ */ jsxs(Box, { sx: { textAlign: "center", py: 4 }, children: [
804
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", gutterBottom: true, children: "No colors in your palette yet" }),
805
+ /* @__PURE__ */ jsx(
806
+ Button,
807
+ {
808
+ startIcon: /* @__PURE__ */ jsx(AddIcon, {}),
809
+ variant: "contained",
810
+ onClick: addPair,
811
+ children: "Add Your First Color"
812
+ }
813
+ )
814
+ ] }),
815
+ /* @__PURE__ */ jsx(
816
+ ColorEditDialog,
817
+ {
818
+ open: editDialogOpen,
819
+ pair: editingPair,
820
+ onClose: () => {
821
+ setEditDialogOpen(false);
822
+ setEditingPair(null);
823
+ },
824
+ onSave: handleSavePair,
825
+ onDelete: handleDeletePair,
826
+ existingKeys: pairs.map((p) => p.key),
827
+ updateSingleDomColor,
828
+ extractedColors
829
+ }
830
+ )
831
+ ] });
832
+ };
833
+ const JsonColorSelector = ({ method, attribute, resourceConfig }) => {
834
+ const [componentLoading, setComponentLoading] = useState(true);
835
+ useEffect(() => {
836
+ window.dispatchEvent(new MessageEvent("auto-admin-loading-state", { data: true }));
837
+ const timer = setTimeout(() => {
838
+ setComponentLoading(false);
839
+ }, 50);
840
+ return () => {
841
+ clearTimeout(timer);
842
+ window.dispatchEvent(new MessageEvent("auto-admin-loading-state", { data: false }));
843
+ };
844
+ }, []);
845
+ if (componentLoading) {
846
+ return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", minHeight: 100 }, children: /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: "Initializing color palette..." }) });
847
+ }
848
+ switch (method) {
849
+ case "edit":
850
+ return /* @__PURE__ */ jsx(JsonEdit, { attribute, method, resourceConfig });
851
+ case "create":
852
+ return /* @__PURE__ */ jsx(JsonEdit, { attribute, method, resourceConfig });
853
+ case "view":
854
+ case "list":
855
+ default:
856
+ return /* @__PURE__ */ jsx(Fragment, { children: "Not implemented" });
857
+ }
858
+ };
859
+ var JsonColorSelectorEnhanced_default = JsonColorSelector;
860
+ export {
861
+ JsonEdit,
862
+ JsonColorSelectorEnhanced_default as default
863
+ };