fix(home): remove confirmation is now a centered modal popup
CI / test (push) Has been cancelled

The inline-expand version (within the bottom sheet) was awkward — the
sheet's content shifted around and the destructive button visually
inherited the same layout as Save. Switched to a centered overlay modal
teleported to <body>:

  - Backdrop with semi-transparent dark + subtle blur, click-to-cancel.
  - Card scales up slightly on enter, fades out on leave.
  - Two-button row: Cancel (neutral) and Yes, remove (red).
  - alertdialog role for screen readers.

The Remove button stays in the sheet so the entry point is unchanged;
only the confirmation surface moves out of the sheet's flow.

Tests updated for <Teleport>: HomeView.test.ts queries document
directly for the modal (it lives outside the wrapper's tree). New
case for backdrop-click cancel.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 16:25:11 -04:00
parent e4f811581a
commit a1a4537c83
12 changed files with 131 additions and 58 deletions
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{_ as e,d as t,f as n,g as r,j as i,k as a,m as o,pt as s,s as c,t as l,u,v as d,z as f}from"./_plugin-vue_export-helper-DRLwVS0w.js";import{n as p,t as m}from"./BaseBottomSheet-C-CffjbC.js";var h={class:`device-picker__list`},g=[`checked`,`onChange`],_={class:`device-picker__name`},v={class:`device-picker__orientation`},y=l(d({__name:`DevicePicker`,props:{modelValue:{type:Boolean},devices:{},selected:{},uploading:{type:Boolean}},emits:[`update:modelValue`,`update:selected`,`confirm`],setup(l,{emit:d}){let y=l,b=d;function x(e){y.selected.includes(e)?b(`update:selected`,y.selected.filter(t=>t!==e)):b(`update:selected`,[...y.selected,e])}let S=u(()=>{let e=y.selected.length;return e===0?`Add to frame`:`Add to ${e} frame${e>1?`s`:``}`});return(u,d)=>(a(),n(m,{"model-value":l.modelValue,label:`Choose frames`,"onUpdate:modelValue":d[1]||=e=>u.$emit(`update:modelValue`,e)},{default:f(()=>[d[2]||=t(`h2`,{class:`device-picker__title`},`Add to frames`,-1),d[3]||=t(`p`,{class:`device-picker__sub`},`Choose which frames will show this photo.`,-1),t(`div`,h,[(a(!0),o(c,null,i(l.devices,e=>(a(),o(`label`,{key:e.id,class:`device-picker__row`},[t(`input`,{type:`checkbox`,class:`device-picker__check`,checked:l.selected.includes(e.id),onChange:t=>x(e.id)},null,40,g),t(`span`,_,s(e.name),1),t(`span`,v,s(e.orientation),1)]))),128))]),e(p,{variant:`primary`,class:`device-picker__confirm`,disabled:l.selected.length===0||l.uploading,onClick:d[0]||=e=>u.$emit(`confirm`)},{default:f(()=>[r(s(l.uploading?`Uploading…`:S.value),1)]),_:1},8,[`disabled`])]),_:1},8,[`model-value`]))}}),[[`__scopeId`,`data-v-a6466fa5`]]);export{y as t};
import{_ as e,d as t,f as n,g as r,j as i,k as a,m as o,pt as s,s as c,t as l,u,v as d,z as f}from"./_plugin-vue_export-helper-DRLwVS0w.js";import{n as p,t as m}from"./BaseBottomSheet-BPaL7SoR.js";var h={class:`device-picker__list`},g=[`checked`,`onChange`],_={class:`device-picker__name`},v={class:`device-picker__orientation`},y=l(d({__name:`DevicePicker`,props:{modelValue:{type:Boolean},devices:{},selected:{},uploading:{type:Boolean}},emits:[`update:modelValue`,`update:selected`,`confirm`],setup(l,{emit:d}){let y=l,b=d;function x(e){y.selected.includes(e)?b(`update:selected`,y.selected.filter(t=>t!==e)):b(`update:selected`,[...y.selected,e])}let S=u(()=>{let e=y.selected.length;return e===0?`Add to frame`:`Add to ${e} frame${e>1?`s`:``}`});return(u,d)=>(a(),n(m,{"model-value":l.modelValue,label:`Choose frames`,"onUpdate:modelValue":d[1]||=e=>u.$emit(`update:modelValue`,e)},{default:f(()=>[d[2]||=t(`h2`,{class:`device-picker__title`},`Add to frames`,-1),d[3]||=t(`p`,{class:`device-picker__sub`},`Choose which frames will show this photo.`,-1),t(`div`,h,[(a(!0),o(c,null,i(l.devices,e=>(a(),o(`label`,{key:e.id,class:`device-picker__row`},[t(`input`,{type:`checkbox`,class:`device-picker__check`,checked:l.selected.includes(e.id),onChange:t=>x(e.id)},null,40,g),t(`span`,_,s(e.name),1),t(`span`,v,s(e.orientation),1)]))),128))]),e(p,{variant:`primary`,class:`device-picker__confirm`,disabled:l.selected.length===0||l.uploading,onClick:d[0]||=e=>u.$emit(`confirm`)},{default:f(()=>[r(s(l.uploading?`Uploading…`:S.value),1)]),_:1},8,[`disabled`])]),_:1},8,[`model-value`]))}}),[[`__scopeId`,`data-v-a6466fa5`]]);export{y as t};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{K as e,d as t,dt as n,ft as r,j as i,k as a,m as o,p as s,pt as c,s as l,t as u,u as d,v as f}from"./_plugin-vue_export-helper-DRLwVS0w.js";import{n as p,r as m,t as h}from"./index-CPVhLfHG.js";var g={class:`settings`},_={class:`settings__section`},v={class:`theme-grid`,role:`radiogroup`,"aria-label":`Choose theme`},y=[`aria-checked`,`aria-label`,`onClick`],b={class:`theme-swatch__label`},x={key:0,class:`theme-swatch__check`,"aria-hidden":`true`},S={class:`settings__section`},C={class:`settings__row`},w={class:`settings__row-value`},T=u(f({__name:`SettingsView`,setup(u){let f=m(),{saveTheme:T}=p(),E=d(()=>f.user?.theme??`warm-craft`);function D(e){T(e)}return(u,d)=>(a(),o(`main`,g,[d[5]||=t(`h1`,{class:`settings__title`},`Settings`,-1),t(`section`,_,[d[1]||=t(`h2`,{class:`settings__section-title`},`Theme`,-1),t(`div`,v,[(a(!0),o(l,null,i(e(h),e=>(a(),o(`button`,{key:e.id,type:`button`,role:`radio`,"aria-checked":E.value===e.id,"aria-label":e.label,class:n([`theme-swatch`,{"theme-swatch--active":E.value===e.id}]),style:r({"--swatch-bg":e.bg,"--swatch-primary":e.primary,"--swatch-text":e.text}),onClick:t=>D(e.id)},[d[0]||=t(`span`,{class:`theme-swatch__preview`,"aria-hidden":`true`},[t(`span`,{class:`theme-swatch__bar`}),t(`span`,{class:`theme-swatch__dot`})],-1),t(`span`,b,c(e.label),1),E.value===e.id?(a(),o(`span`,x,``)):s(``,!0)],14,y))),128))])]),t(`section`,S,[d[3]||=t(`h2`,{class:`settings__section-title`},`Account`,-1),t(`div`,C,[d[2]||=t(`span`,{class:`settings__row-label`},`Signed in as`,-1),t(`span`,w,c(e(f).user?.email),1)]),d[4]||=t(`a`,{href:`/logout`,class:`settings__logout`},`Sign out`,-1)])]))}}),[[`__scopeId`,`data-v-76ec3881`]]);export{T as default};
import{K as e,d as t,dt as n,ft as r,j as i,k as a,m as o,p as s,pt as c,s as l,t as u,u as d,v as f}from"./_plugin-vue_export-helper-DRLwVS0w.js";import{n as p,r as m,t as h}from"./index-BojlVxcP.js";var g={class:`settings`},_={class:`settings__section`},v={class:`theme-grid`,role:`radiogroup`,"aria-label":`Choose theme`},y=[`aria-checked`,`aria-label`,`onClick`],b={class:`theme-swatch__label`},x={key:0,class:`theme-swatch__check`,"aria-hidden":`true`},S={class:`settings__section`},C={class:`settings__row`},w={class:`settings__row-value`},T=u(f({__name:`SettingsView`,setup(u){let f=m(),{saveTheme:T}=p(),E=d(()=>f.user?.theme??`warm-craft`);function D(e){T(e)}return(u,d)=>(a(),o(`main`,g,[d[5]||=t(`h1`,{class:`settings__title`},`Settings`,-1),t(`section`,_,[d[1]||=t(`h2`,{class:`settings__section-title`},`Theme`,-1),t(`div`,v,[(a(!0),o(l,null,i(e(h),e=>(a(),o(`button`,{key:e.id,type:`button`,role:`radio`,"aria-checked":E.value===e.id,"aria-label":e.label,class:n([`theme-swatch`,{"theme-swatch--active":E.value===e.id}]),style:r({"--swatch-bg":e.bg,"--swatch-primary":e.primary,"--swatch-text":e.text}),onClick:t=>D(e.id)},[d[0]||=t(`span`,{class:`theme-swatch__preview`,"aria-hidden":`true`},[t(`span`,{class:`theme-swatch__bar`}),t(`span`,{class:`theme-swatch__dot`})],-1),t(`span`,b,c(e.label),1),E.value===e.id?(a(),o(`span`,x,``)):s(``,!0)],14,y))),128))])]),t(`section`,S,[d[3]||=t(`h2`,{class:`settings__section-title`},`Account`,-1),t(`div`,C,[d[2]||=t(`span`,{class:`settings__row-label`},`Signed in as`,-1),t(`span`,w,c(e(f).user?.email),1)]),d[4]||=t(`a`,{href:`/logout`,class:`settings__logout`},`Sign out`,-1)])]))}}),[[`__scopeId`,`data-v-76ec3881`]]);export{T as default};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -14,7 +14,7 @@
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="pictureFrame" />
<script type="module" crossorigin src="/build/assets/index-CPVhLfHG.js"></script>
<script type="module" crossorigin src="/build/assets/index-BojlVxcP.js"></script>
<link rel="modulepreload" crossorigin href="/build/assets/_plugin-vue_export-helper-DRLwVS0w.js">
<link rel="stylesheet" crossorigin href="/build/assets/index-BlLBHR1q.css">
</head>