feat: replace delete ✕ with pi pi-trash + inline confirmation (matches ComfyUI assets pattern)
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+2
-2
@@ -1,4 +1,4 @@
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["immac_style_mixer/StyleMixerPanel-DxBlfZqC.js","immac_style_mixer/vendor-DPfS0z4g.js"])))=>i.map(i=>d[i]);
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["immac_style_mixer/StyleMixerPanel-317gZSvY.js","immac_style_mixer/vendor-DPfS0z4g.js"])))=>i.map(i=>d[i]);
|
||||
import{r as v,a as R,R as h}from"./vendor-DPfS0z4g.js";const g="modulepreload",b=function(t){return"/"+t},f={},I=function(e,n,o){let l=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const r=document.querySelector("meta[property=csp-nonce]"),i=(r==null?void 0:r.nonce)||(r==null?void 0:r.getAttribute("nonce"));l=Promise.allSettled(n.map(a=>{if(a=b(a),a in f)return;f[a]=!0;const d=a.endsWith(".css"),_=d?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${a}"]${_}`))return;const s=document.createElement("link");if(s.rel=d?"stylesheet":g,d||(s.as="script"),s.crossOrigin="",s.href=a,i&&s.setAttribute("nonce",i),document.head.appendChild(s),d)return new Promise((E,S)=>{s.addEventListener("load",E),s.addEventListener("error",()=>S(new Error(`Unable to preload CSS for ${a}`)))})}))}function c(r){const i=new Event("vite:preloadError",{cancelable:!0});if(i.payload=r,window.dispatchEvent(i),!i.defaultPrevented)throw r}return l.then(r=>{for(const i of r||[])i.status==="rejected"&&c(i.reason);return e().catch(c)})};var x={exports:{}},m={};/**
|
||||
* @license React
|
||||
* react-jsx-runtime.production.min.js
|
||||
@@ -7,4 +7,4 @@ import{r as v,a as R,R as h}from"./vendor-DPfS0z4g.js";const g="modulepreload",b
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var P=v,j=Symbol.for("react.element"),k=Symbol.for("react.fragment"),O=Object.prototype.hasOwnProperty,L=P.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,C={key:!0,ref:!0,__self:!0,__source:!0};function w(t,e,n){var o,l={},c=null,r=null;n!==void 0&&(c=""+n),e.key!==void 0&&(c=""+e.key),e.ref!==void 0&&(r=e.ref);for(o in e)O.call(e,o)&&!C.hasOwnProperty(o)&&(l[o]=e[o]);if(t&&t.defaultProps)for(o in e=t.defaultProps,e)l[o]===void 0&&(l[o]=e[o]);return{$$typeof:j,type:t,key:c,ref:r,props:l,_owner:L.current}}m.Fragment=k;m.jsx=w;m.jsxs=w;x.exports=m;var u=x.exports,p={},y=R;p.createRoot=y.createRoot,p.hydrateRoot=y.hydrateRoot;const T=h.lazy(()=>I(()=>import("./StyleMixerPanel-DxBlfZqC.js"),__vite__mapDeps([0,1])));function U(){return new Promise(t=>{function e(){if(window.app){t();return}const n=setInterval(()=>{window.app&&(clearInterval(n),t())},50);setTimeout(()=>{clearInterval(n),console.error("[ImmacStyleMixer] Timeout waiting for ComfyUI app"),t()},5e3)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e()})}async function M(){if(await U(),!window.app){console.error("[ImmacStyleMixer] ComfyUI app not available");return}window.app.extensionManager.registerSidebarTab({id:"immac-style-mixer",icon:"pi pi-palette",title:"Style Mixer",tooltip:"Immac Style Mixer",type:"custom",render:t=>{const e=document.createElement("div");e.id="immac-style-mixer-root",e.style.position="absolute",e.style.inset="0",e.style.overflow="hidden",t.style.position="relative",t.style.height="100%",t.appendChild(e),p.createRoot(e).render(u.jsx(h.StrictMode,{children:u.jsx(v.Suspense,{fallback:u.jsx("div",{style:{padding:"1rem"},children:"Loading…"}),children:u.jsx(T,{})})}))}}),window.app.registerExtension({name:"ImmacStyleMixer"})}M().catch(console.error);export{u as j};
|
||||
*/var P=v,j=Symbol.for("react.element"),k=Symbol.for("react.fragment"),O=Object.prototype.hasOwnProperty,L=P.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,C={key:!0,ref:!0,__self:!0,__source:!0};function w(t,e,n){var o,l={},c=null,r=null;n!==void 0&&(c=""+n),e.key!==void 0&&(c=""+e.key),e.ref!==void 0&&(r=e.ref);for(o in e)O.call(e,o)&&!C.hasOwnProperty(o)&&(l[o]=e[o]);if(t&&t.defaultProps)for(o in e=t.defaultProps,e)l[o]===void 0&&(l[o]=e[o]);return{$$typeof:j,type:t,key:c,ref:r,props:l,_owner:L.current}}m.Fragment=k;m.jsx=w;m.jsxs=w;x.exports=m;var u=x.exports,p={},y=R;p.createRoot=y.createRoot,p.hydrateRoot=y.hydrateRoot;const T=h.lazy(()=>I(()=>import("./StyleMixerPanel-317gZSvY.js"),__vite__mapDeps([0,1])));function U(){return new Promise(t=>{function e(){if(window.app){t();return}const n=setInterval(()=>{window.app&&(clearInterval(n),t())},50);setTimeout(()=>{clearInterval(n),console.error("[ImmacStyleMixer] Timeout waiting for ComfyUI app"),t()},5e3)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e()})}async function M(){if(await U(),!window.app){console.error("[ImmacStyleMixer] ComfyUI app not available");return}window.app.extensionManager.registerSidebarTab({id:"immac-style-mixer",icon:"pi pi-palette",title:"Style Mixer",tooltip:"Immac Style Mixer",type:"custom",render:t=>{const e=document.createElement("div");e.id="immac-style-mixer-root",e.style.position="absolute",e.style.inset="0",e.style.overflow="hidden",t.style.position="relative",t.style.height="100%",t.appendChild(e),p.createRoot(e).render(u.jsx(h.StrictMode,{children:u.jsx(v.Suspense,{fallback:u.jsx("div",{style:{padding:"1rem"},children:"Loading…"}),children:u.jsx(T,{})})}))}}),window.app.registerExtension({name:"ImmacStyleMixer"})}M().catch(console.error);export{u as j};
|
||||
|
||||
@@ -17,6 +17,7 @@ export default function MixCard({ mix, styles, isActive, onActivate, onUpdate, o
|
||||
const [nameInput, setNameInput] = useState(mix.name)
|
||||
const [uploading, setUploading] = useState(false)
|
||||
const [lightboxOpen, setLightboxOpen] = useState(false)
|
||||
const [pendingDelete, setPendingDelete] = useState(false)
|
||||
const fileRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
async function handleImageFile(file: File) {
|
||||
@@ -104,9 +105,29 @@ export default function MixCard({ mix, styles, isActive, onActivate, onUpdate, o
|
||||
>
|
||||
<i className={mix.favorite ? 'pi pi-bookmark-fill' : 'pi pi-bookmark'} />
|
||||
</button>
|
||||
<button title="Delete mix" onClick={onDelete} style={{ ...iconBtn, color: '#e55' }}>
|
||||
✕
|
||||
</button>
|
||||
{pendingDelete ? (
|
||||
<>
|
||||
<span style={{ fontSize: 11, color: 'var(--p-text-muted-color, #888)', whiteSpace: 'nowrap' }}>Delete?</span>
|
||||
<button
|
||||
title="Cancel"
|
||||
onClick={() => setPendingDelete(false)}
|
||||
style={{ ...iconBtn, fontSize: 11, color: 'var(--p-text-muted-color, #888)' }}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
title="Confirm delete"
|
||||
onClick={onDelete}
|
||||
style={{ ...iconBtn, color: '#e55' }}
|
||||
>
|
||||
<i className="pi pi-trash" />
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<button title="Delete mix" onClick={() => setPendingDelete(true)} style={{ ...iconBtn, color: 'var(--p-text-muted-color, #888)' }}>
|
||||
<i className="pi pi-trash" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Cover image */}
|
||||
|
||||
@@ -16,6 +16,7 @@ export default function StyleCard({ style, onUpdate, onDelete }: Props) {
|
||||
const [valueInput, setValueInput] = useState(style.value)
|
||||
const [uploading, setUploading] = useState(false)
|
||||
const [lightboxOpen, setLightboxOpen] = useState(false)
|
||||
const [pendingDelete, setPendingDelete] = useState(false)
|
||||
const fileRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
function commitName() {
|
||||
@@ -56,19 +57,39 @@ export default function StyleCard({ style, onUpdate, onDelete }: Props) {
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
{/* Favorite + Delete row */}
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<button
|
||||
title={style.favorite ? 'Remove bookmark' : 'Bookmark'}
|
||||
onClick={() => onUpdate({ ...style, favorite: !style.favorite })}
|
||||
style={iconBtn}
|
||||
>
|
||||
<i className={style.favorite ? 'pi pi-bookmark-fill' : 'pi pi-bookmark'} />
|
||||
</button>
|
||||
<button title="Delete style" onClick={onDelete} style={{ ...iconBtn, color: '#e55' }}>
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
{/* Bookmark + Delete row */}
|
||||
{pendingDelete ? (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
|
||||
<span style={{ flex: 1, fontSize: 11, color: 'var(--p-text-muted-color, #888)' }}>Delete style?</span>
|
||||
<button
|
||||
title="Cancel"
|
||||
onClick={() => setPendingDelete(false)}
|
||||
style={{ ...iconBtn, fontSize: 12, color: 'var(--p-text-muted-color, #888)' }}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
title="Confirm delete"
|
||||
onClick={onDelete}
|
||||
style={{ ...iconBtn, fontSize: 12, color: '#e55', fontWeight: 600 }}
|
||||
>
|
||||
<i className="pi pi-trash" />
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<button
|
||||
title={style.favorite ? 'Remove bookmark' : 'Bookmark'}
|
||||
onClick={() => onUpdate({ ...style, favorite: !style.favorite })}
|
||||
style={iconBtn}
|
||||
>
|
||||
<i className={style.favorite ? 'pi pi-bookmark-fill' : 'pi pi-bookmark'} />
|
||||
</button>
|
||||
<button title="Delete style" onClick={() => setPendingDelete(true)} style={{ ...iconBtn, color: 'var(--p-text-muted-color, #888)' }}>
|
||||
<i className="pi pi-trash" />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Image area */}
|
||||
<div style={{ position: 'relative', width: '100%', paddingBottom: '100%' }}>
|
||||
|
||||
Reference in New Issue
Block a user