efficient-web-builder 5.0.0 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.0.2 - 2026-10-12
4
+
5
+ - **The copy box bar no longer offers the three word styles.** Highlight,
6
+ Bold and Quiet were dropped from the toolbar by the owner on 2026-10-02,
7
+ but the website editor still drew them on every copy box and list row
8
+ (the Ticker items too). `SHOP_COPY_FIELD_TOOLS` and `shopMarkupTools()`
9
+ now list only the grammar's own marks: Bold, Italic and Strikethrough,
10
+ then Clear formatting.
11
+ - **Saved word-style copy is unchanged.** `@@`, `++` and `^^` still read and
12
+ still paint (`WORD_STYLE_RULES` stays in `SHOP_MARKUP`), and
13
+ `WORD_STYLE_TOOLS`, `applyShopMark` and `shopMarkedAt` are still exported.
14
+ The dead Quiet glyph in `MarkupToolbar` is gone.
15
+
16
+ ## 5.0.1 - 2026-10-11
17
+
18
+ - **A custom face's Style box is read as it is seen.** For a text part whose
19
+ face is outside the site styles, the closed Style box shows "Custom" while
20
+ its list's first row is "No style". A screen reader read the row's label, so
21
+ the box was seen as "Custom" and heard as "No style". It is "Custom" for
22
+ both now (`PartStyleSelect` hands `FieldSelect` a `valueText`). Nothing
23
+ changes on screen.
24
+ - Takes effect with efficient-easel 2.1.0 and efficient-shell 4.180.0. The
25
+ peer ranges are unchanged (`^2.0.0`, `^4.171.0`): with an older easel or
26
+ shell the option's label is still what is read.
27
+
3
28
  ## 5.0.0 - 2026-10-11
4
29
 
5
30
  - **Breaking: efficient-easel ^2.0.0 and efficient-shell ^4.171.0** (peers;
package/README.md CHANGED
@@ -45,27 +45,43 @@ Comments that name a file say `lib/puck/controls`; read them from `src/`.
45
45
 
46
46
  ## How the storefront uses it
47
47
 
48
- The storefront compiles these sources: its commerce and service blocks are
49
- written with the builder's control builders and passes, so it needs the source,
50
- not a bundle. It keeps a **vendored copy** of this repository's `src/` at
51
- `packages/web-builder/src`, pinned to a commit here, and resolves `@/…` in its
52
- own tree first and in the copy second.
53
-
54
- - A change to the builder is made HERE. The storefront then moves its pin
55
- (`node scripts/sync-web-builder.mjs <ref>` there), in a pull request that
56
- runs the storefront's whole suite over the new copy.
57
- - The copy is never edited in place: the storefront's check fails when that
58
- folder is not byte-for-byte the `src/` tree of the pinned commit.
48
+ The storefront installs this repository's npm package, like any host, at one
49
+ exact version in its `package.json` (efficient-storefront `doc/adr/0011`,
50
+ 2026-10-11). Its commerce and service blocks are written with the builder's
51
+ control builders and passes, which they import by path: there `@/…` resolves in
52
+ the storefront's own tree first, then in its blocks, then in
53
+ `node_modules/efficient-web-builder/dist`.
54
+
55
+ - **A change to the builder is made HERE and reaches the storefront as a
56
+ release.** Merge it, cut a GitHub Release `vX.Y.Z` (which publishes to npm),
57
+ move efficient-storefront-blocks to that release, then open one storefront
58
+ pull request that moves the version in its `package.json` and its blocks pin
59
+ together. The storefront's check fails while it and the blocks' repository
60
+ install two different builders.
61
+ - **To try a branch against the storefront's suite before a release**, install
62
+ its build there as a tarball:
63
+
64
+ ```bash
65
+ pnpm run build && pnpm pack --pack-destination /tmp/builder-trial
66
+ # in an efficient-storefront worktree
67
+ pnpm add "efficient-web-builder@file:/tmp/builder-trial/efficient-web-builder-<version>.tgz"
68
+ just check
69
+ ```
70
+
71
+ Exactly one storefront guard fails on a trial, the one that will not let an
72
+ unreleased builder merge.
73
+ - **What a host receives is compiled.** A function's own name is a letter in
74
+ `dist/`, so a host's test cannot find a component by that name: it imports
75
+ the component and compares, or asks what it draws. Export what a host has to
76
+ be able to find.
59
77
 
60
78
  So this repository's CI proves the builder stands alone, and the storefront's
61
- proves it still does what it did. Most of the builder's behavioural guards live
62
- in the storefront for now, because they run the editor assembled with a host.
63
-
64
- The copy is on its way out ([`doc/adr/0002`](doc/adr/0002-published-from-here-compiled.md)).
65
- Some 280 of the storefront's guards read these sources by path, and the package
66
- below carries no source. Once the guards that are the builder's alone live
67
- here, the storefront installs the package like any host and deletes
68
- `packages/web-builder`.
79
+ proves it still does what it did, on the package. The guards that run the
80
+ editor assembled with a host stay in the host's repository.
81
+
82
+ From 2026-10-07 to 2026-10-11 the storefront kept a vendored copy of `src/`
83
+ instead, pinned to a commit here ([`doc/adr/0001`](doc/adr/0001-extracted-from-the-storefront.md),
84
+ [`doc/adr/0002`](doc/adr/0002-published-from-here-compiled.md)).
69
85
 
70
86
  ## Published as `efficient-web-builder`
71
87
 
@@ -1 +1 @@
1
- "use client";import{jsx as t,jsxs as r,Fragment as O}from"react/jsx-runtime";import{useEffect as M,useId as _e,useRef as J,useState as Q}from"react";import{PartResetDot as fe}from"./PartResetDot.js";import{FieldSelect as pe,InspectorField as $e}from"efficient-easel/fields";import{SettingsField as me,SettingsGroup as Ae}from"efficient-easel/panel";import{InspectorUpLevel as G}from"efficient-easel/chrome";import{StylesIcon as Le,TextColorIcon as ze,TypeIcon as he}from"efficient-easel/icons";import{useEasel as Be}from"efficient-easel/easel";import{Tooltip as De}from"efficient-shell/ui";import{PartInkControl as Ve}from"./PartInkControl.js";import{PartTextBox as Me}from"./PartTextBox.js";import ye from"./UiIcon.js";import{usePreviewHeader as Ge}from"./PreviewHeaderContext.js";import{usePartStyle as We}from"./PreviewPartStyleContext.js";import{readHidable as W,textFieldOffPage as je}from"../lib/puck/controls.js";import{TEXT_FIELD_MARKER as He}from"../lib/puck/field-markers.js";import{useSectionOps as Ue}from"../lib/puck/use-section-ops.js";import{FONT_OPTIONS as Ke,FONT_ROLES as Z,FONT_ROLE_LABELS as ee,fontOption as _}from"../lib/fonts.js";import{isMultilineKind as Xe,partPlaceholder as Ye,typeInPlaceKind as qe}from"../lib/puck/part-text.js";import{partRowField as Je}from"../lib/puck/part-row-field.js";import{decodePartKey as Qe,partPropsWithRowValue as Ze,partRowValue as et}from"../lib/puck/part-rows.js";import{PART_WIDTH_MAX as tt,propsWithPartStyleValue as te,propsWithoutPartStyle as nt,readPartStyle as ge}from"../lib/puck/part-styles.js";import{partInks as ot}from"../lib/puck/part-inks.js";import{styleKeyForPart as st,TEXT_KIND_LABELS as lt}from"../lib/sections/section-text-kinds.js";import{commitPartText as rt}from"../lib/puck/part-typing.js";import{useEditorHost as it}from"../lib/editor-host.js";import{SOURCE_LINES as at,SOURCE_ACTIONS as ct,SOURCE_ACTION_LABEL as dt,partSourceOf as ut,sourceSlugOf as be}from"../lib/puck/source-bound-parts.js";import{encodePartId as ft,holdsAuthoredText as pt}from"../lib/puck/text-parts.js";import{regionsForSection as mt}from"../lib/sections/section-text-regions.js";import{textRegionOfPartKey as ht}from"../lib/sections/text-regions.js";const yt={400:"Regular",500:"Medium",600:"Semibold",700:"Bold"},Se=[{key:"font",label:"Font",group:"Style"},{key:"color",label:"Color",group:"Style"}],gt=[...new Set(Se.map(e=>e.group))],bt={font:t(he,{}),color:t(ze,{})};function $(e){return e.kind==="role"?ee[e.role]:e.kind==="custom"?"Custom":null}const St=e=>e.kind==="role"?`role:${e.role}`:e.kind;function xt(e){const n=e.role;return n&&Z.includes(n)?{kind:"role",role:n}:null}function Nt(e,n){if(!e)return{kind:"unread"};const{faceRole:s,base:l}=e;if(n[s]===l.fontKey)return{kind:"role",role:s};const a=Object.keys(n).filter(c=>n[c]===l.fontKey);return a.length===1?{kind:"role",role:a[0]}:{kind:"custom"}}function ne(e,n,s,l){return xt(ge(e,n))??Nt(s,l)}function un(e,n,s,l){return $(ne(e,n,s,l))}function oe(e,n){if(!e.length)return null;const s=n(e[0]);return e.every(l=>n(l)===s)?s:null}function vt(e){return Object.values(e).filter(n=>n!==void 0).length}function Pt(e,n){const s=e.style[n];return n==="color"?s??"":s!==void 0?String(s):e.base.fontKey}function kt({face:e,base:n,onPick:s}){const[l,a]=Q(!1),c=J(null),h=J(null),y=_e();M(()=>{if(!l)return;const i=T=>{c.current&&!c.current.contains(T.target)&&a(!1)};return document.addEventListener("mousedown",i),()=>document.removeEventListener("mousedown",i)},[l]);const u=e.kind==="role"?e.role:null,v=i=>{s(i),a(!1),h.current?.focus()};return r("div",{className:"sf-part-style-pick",ref:c,children:[r("button",{ref:h,type:"button",className:"sf-part-style-trigger","aria-expanded":l,"aria-controls":y,"aria-label":`Follows ${$(e)??"no style"} — change`,onClick:()=>a(i=>!i),onKeyDown:i=>{i.key==="Escape"&&l&&(i.preventDefault(),a(!1))},children:[t("span",{className:"sf-part-style-name",style:{fontFamily:n?.fontKey?`var(${_(n.fontKey)?.cssVar})`:void 0,fontWeight:n?.weight},children:$(e)}),t("span",{className:"sf-part-style-sign","aria-hidden":"true"})]}),l&&r("div",{className:"sf-multi-menu sf-part-style-menu",id:y,role:"listbox",onKeyDown:i=>{i.key==="Escape"&&(i.preventDefault(),a(!1),h.current?.focus())},children:[r("button",{type:"button",role:"option","aria-selected":u===null,className:`sf-part-style-option${u===null?" is-on":""}`,onClick:()=>v(null),children:[t("span",{className:"sf-part-style-option-name",children:"No style"}),t("span",{className:"sf-note",children:"Section’s own"})]}),Z.map(i=>t("button",{type:"button",role:"option","aria-selected":u===i,className:`sf-part-style-option${u===i?" is-on":""}`,onClick:()=>v(i),children:t("span",{className:"sf-part-style-option-name",style:{fontFamily:`var(--font-role-${i})`},children:ee[i]})},i))]})]})}const j="";function wt({face:e,base:n,onPick:s}){const l=e.kind==="role"?e.role:j,a=[{label:"No style",value:j},...Z.map(c=>({label:ee[c],value:c}))];return t(pe,{ariaLabel:"Style",value:l,options:a,inline:!0,onChange:c=>s(c===j?null:c),renderOption:c=>c.value===j?r(O,{children:[t("span",{className:"es-fsel-label sf-part-style-keep",children:c.label}),t("span",{className:"sf-part-style-aside","aria-hidden":"true",children:"Section’s own"})]}):t("span",{className:"es-fsel-label",style:{fontFamily:`var(--font-role-${c.value})`},children:c.label}),renderValue:()=>t("span",{style:{fontFamily:n?.fontKey?`var(${_(n.fontKey)?.cssVar})`:void 0,fontWeight:n?.weight},children:$(e)})})}function Tt({parts:e,onEditStyle:n,onClearAll:s,onFollowStyle:l,kindLabel:a}){const h=oe(e,T=>St(T.face))?e[0].face:null,y=h?$(h):null,u=h&&h.kind!=="unread"?e[0].base:null,v=e.reduce((T,A)=>T+vt(A.style),0),i=u?_(u.fontKey)?.label:void 0;return r("div",{className:`sf-part-style${v?" has-overrides":""}`,children:[t("div",{className:"sf-part-style-caption",children:"Style"}),e.length>1&&r("div",{className:"sf-part-style-count",children:[e.length," selected"]}),e.length===1&&a&&r("div",{className:"sf-part-style-count",children:[a," · every row"]}),y&&u?r(O,{children:[l&&h?t(kt,{face:h,base:u,onPick:l}):t("div",{className:"sf-part-style-name",style:{fontFamily:i?`var(${_(u.fontKey)?.cssVar})`:void 0,fontWeight:u.weight},children:y}),t("div",{className:"sf-part-style-meta",children:[i,`${Math.round(u.sizePx)} px`,yt[u.weight]].filter(Boolean).join(" · ")})]}):t("div",{className:"sf-part-style-name",children:"Mixed styles"}),r("div",{className:"sf-part-style-top",children:[y?v?r(O,{children:[r("span",{className:"sf-part-chip",children:[v," changed"]}),t("button",{type:"button",className:"sf-part-link",onClick:s,children:"Clear"})]}):t("span",{className:"sf-part-style-state",children:"This text follows the site style."}):t("span",{className:"sf-part-style-state",children:"Changes apply to all selected."}),t("span",{className:"sf-part-style-gap"}),y&&n&&t("button",{type:"button",className:"sf-part-link",onClick:n,children:"Edit"})]})]})}function Et({sectionName:e,onBack:n,textEditor:s,styleRow:l,children:a}){return r("div",{className:"sf-part-panel",children:[t(G,{inline:!0,name:e,onSelect:n}),s,l,a]})}function xe({source:e,slug:n}){const s=it(),l=ct[e],a=!l.needsSlug||!!n;return t("div",{className:"sf-note sf-note--source",children:r("p",{className:"es-field-hint sf-hint-keep",children:[at[e],a?r(O,{children:[" ",t("button",{type:"button",className:"sf-source-open",onClick:()=>{l.type==="storefront-editor:open-menus"?s.send(l.type):n&&s.send(l.type,{slug:n})},children:dt})]}):null]})})}const Ne=4,Rt=120;function Ct({region:e,sizePx:n,face:s,base:l,onFollowStyle:a,source:c,slug:h,onBack:y}){const u=e.follows;return r("div",{className:"sf-note",children:[t("p",{children:t("strong",{children:e.label})}),r("p",{children:["Its size follows Site styles ▸ ",u,n?` — ${Math.round(n)}px right now`:"","."]}),a?t(O,{children:t(me,{label:"Style",icon:t(Le,{}),hint:r(O,{children:["Every ",e.label.toLowerCase()," in this section follows it. The face and the size change; the letter case is the section’s own and stays as it is."]}),children:t(wt,{face:s,base:l,onPick:a})})}):t("p",{className:"es-field-hint sf-hint-keep",children:"Only the size follows a site style. This section sets its own font, weight and letter case."}),c?t(xe,{source:c,slug:h}):null,t(G,{inline:!0,name:"Page",onSelect:y})]})}function Ft({onBack:e}){return r("div",{className:"sf-note",children:[t("p",{children:t("strong",{children:"This part is no longer here."})}),t("p",{children:"The section it belonged to has been changed or removed."}),t(G,{inline:!0,name:"Page",onSelect:e})]})}function Ot({onBack:e,partId:n,why:s}){return r("div",{className:"sf-note",children:[t("p",{children:t("strong",{children:"This part's settings did not open."})}),t("p",{children:"The words are still on your page and nothing has been lost. The editor could not work out which control belongs to them, which is a fault on our side. Go back and click the section to open its settings instead."}),t("p",{className:"sf-note-detail",children:r("code",{children:[n," — ",s]})}),t(G,{inline:!0,name:"Page",onSelect:e})]})}function It({nodeId:e,propKey:n,onBack:s,onEditStyle:l}){const{getItemById:a,getSelectorForId:c,config:h}=Be(o=>o),y=Ue(),{partStyle:u}=We(),{fonts:v}=Ge(),[i,T]=Q({}),A=J(null),g=a(e),S=c(e),se=g?h.components[g.type]:void 0,{key:E,row:P}=Qe(n),le=se?.fields?.[E],k=P?Je(le,P):le,I=ft(e,n),p=g?.props??{},w=qe(k),ve=je(k),Pe=pt(k),H=g?ut(g.type):null,U=P?et(p[E],P):p[E],re=!!P&&!(Array.isArray(p[E])&&P.index<p[E].length);M(()=>{A.current?.querySelector(".es-copy [contenteditable='true'], .es-copy textarea, .sf-copybox textarea, .sf-copybox input")?.focus()},[I]);const[K,ie]=Q(0);M(()=>ie(0),[I]);const X=!!g&&!re&&(!S||!k);M(()=>{if(!X||K>=Ne)return;const o=setTimeout(()=>ie(d=>d+1),Rt);return()=>clearTimeout(o)},[X,K]);const ke=X&&K<Ne;if(!g||re)return t(Ft,{onBack:s});const L=mt(g.type),ae=L?ht(L,n):null;if(L&&ae){const o=u?.partId===I?u:null,d=L[ae],m=d.writable===!0&&!!S,b=f=>{S&&y.replaceComponent(S.zone,S.index,{...g,props:te(p,n,"role",f)})};return t(Ct,{region:d,sizePx:o?.base.sizePx??null,face:ne(p,n,o,v),base:o?.base??null,onFollowStyle:m?b:void 0,source:H,slug:be(p),onBack:s})}if(!S||!k)return ke?t("div",{className:"sf-note","aria-busy":"true"}):t(Ot,{onBack:s,partId:I,why:S?"no field":"no selector"});const z=o=>{y.replaceComponent(S.zone,S.index,{...g,props:o})},Y=o=>{if(W(o).hidden!==W(U).hidden||!w){const m=P?Ze(p,E,P,o):{...p,[E]:o};m&&z(m);return}rt({node:g,propKey:n,kind:w,zone:S.zone,index:S.index},W(o).text,y.replaceComponent)},we=U,B=st(g?.type,n),Te=ge(p,B),D=u?.partId===I?u:null,x=[{partKey:B,face:ne(p,B,D,v),sizeGroup:D?.sizeGroup??null,base:D?.base??_t,style:Te}],Ee=oe(x,o=>o.sizeGroup),ce=ot(D?.inks),V=(o,d)=>{let m=p;for(const b of x)m=te(m,b.partKey,o,d);z(m)},Re=o=>V("role",o),Ce=()=>{let o=p;for(const d of x)o=nt(o,d.partKey);z(o)},Fe=o=>{let d=p;for(const m of x)for(const[b,f]of Object.entries(o))d=te(d,m.partKey,b,f??null);z(d)},Oe=(o,d)=>{const m=x.some(N=>N.style[o]!==void 0),b=oe(x,N=>Pt(N,o)),f=b===null,F=`sf-part-${e}-${n}-${o}`;return o==="color"?t(Ve,{value:f?null:String(b),label:d,colors:ce,onChange:N=>V("color",N)},o):t(me,{label:d,icon:bt[o],className:"sf-part-field",changed:m,htmlFor:F,action:m?t(fe,{label:d,onClear:()=>V(o,null)}):void 0,children:o==="font"?t(pe,{id:F,ariaLabel:d,value:!f&&_(String(b))?String(b):void 0,placeholder:f?"Mixed":"Site style",options:Ke.map(N=>({label:N.label,value:N.key})),onChange:N=>V("font",N||null)}):null},o)},de=w==="text"||w==="textarea",{text:ue,hidden:R}=W(U),C=k?.[He]?.label??n,Ie=r("div",{className:"sf-field-head",children:[t(he,{}),t("span",{className:"sf-field-label sf-field-label--inline",children:C}),de&&t(De,{content:R?`Show ${C} on the slide`:`Hide ${C} on the slide`,children:t("button",{type:"button",className:"sf-field-eye","aria-pressed":R,"aria-label":R?`Show ${C} on the slide`:`Hide ${C} on the slide`,onClick:()=>Y({text:ue,hidden:!R}),children:R?t(ye,{name:"eye-off",size:14}):t(ye,{name:"eye",size:14})})})]}),q=!ve&&Pe;return r(Et,{sectionName:se?.label??g.type,onBack:s,textEditor:r("div",{ref:A,className:"sf-part-text",children:[w?t(Me,{text:ue,onTextChange:o=>Y(de?{text:o,hidden:R}:o),multiline:Xe(w),markup:w!=="plainText",styled:q,style:x[0].style,base:x[0].base,setValue:Fe,colors:ce.map(o=>({name:o.key,label:o.name,value:o.value})),placeholder:Ye(k),ariaLabel:C,head:Ie}):t($e,{field:k,name:n,value:we,onChange:Y,id:`sf-part-${e}-${n}`}),q&&w&&Ee===null&&t("p",{className:"es-field-hint sf-hint-keep",children:"Fixed size — the site’s Text setting doesn’t resize this."})]}),children:[H&&t(xe,{source:H,slug:be(p)}),q&&gt.map(o=>{const d=Se.filter(f=>f.group===o),m=d.filter(f=>x.some(F=>F.style[f.key]!==void 0)).length,b=`sf-part-g-${e}-${n}-${o.replace(/\W+/g,"-")}`;return r(Ae,{id:b,title:o,open:i[o]!==!0,onToggle:f=>T(F=>({...F,[o]:!f})),count:m,children:[t(Tt,{parts:x,onEditStyle:l,onClearAll:Ce,onFollowStyle:Re,kindLabel:lt[B]}),d.map(f=>Oe(f.key,f.label))]},o)})]})}const _t={fontKey:"",sizePx:16,weight:400,lineRatio:1.4,letterEm:0,align:"left",case:"none",paddingPx:0,widthPx:tt};export{Se as PART_FIELDS,Et as PartPanelBody,fe as PartResetDot,xe as PartSourceNote,Tt as PartStyleCard,wt as PartStyleSelect,It as default,ne as partFace,un as partStyleName};
1
+ "use client";import{jsx as t,jsxs as r,Fragment as O}from"react/jsx-runtime";import{useEffect as M,useId as _e,useRef as J,useState as Q}from"react";import{PartResetDot as fe}from"./PartResetDot.js";import{FieldSelect as pe,InspectorField as $e}from"efficient-easel/fields";import{SettingsField as me,SettingsGroup as Ae}from"efficient-easel/panel";import{InspectorUpLevel as G}from"efficient-easel/chrome";import{StylesIcon as Le,TextColorIcon as ze,TypeIcon as he}from"efficient-easel/icons";import{useEasel as Be}from"efficient-easel/easel";import{Tooltip as De}from"efficient-shell/ui";import{PartInkControl as Ve}from"./PartInkControl.js";import{PartTextBox as Me}from"./PartTextBox.js";import ye from"./UiIcon.js";import{usePreviewHeader as Ge}from"./PreviewHeaderContext.js";import{usePartStyle as We}from"./PreviewPartStyleContext.js";import{readHidable as W,textFieldOffPage as je}from"../lib/puck/controls.js";import{TEXT_FIELD_MARKER as He}from"../lib/puck/field-markers.js";import{useSectionOps as Ue}from"../lib/puck/use-section-ops.js";import{FONT_OPTIONS as Ke,FONT_ROLES as Z,FONT_ROLE_LABELS as ee,fontOption as $}from"../lib/fonts.js";import{isMultilineKind as Xe,partPlaceholder as Ye,typeInPlaceKind as qe}from"../lib/puck/part-text.js";import{partRowField as Je}from"../lib/puck/part-row-field.js";import{decodePartKey as Qe,partPropsWithRowValue as Ze,partRowValue as et}from"../lib/puck/part-rows.js";import{PART_WIDTH_MAX as tt,propsWithPartStyleValue as te,propsWithoutPartStyle as nt,readPartStyle as ge}from"../lib/puck/part-styles.js";import{partInks as ot}from"../lib/puck/part-inks.js";import{styleKeyForPart as st,TEXT_KIND_LABELS as lt}from"../lib/sections/section-text-kinds.js";import{commitPartText as rt}from"../lib/puck/part-typing.js";import{useEditorHost as it}from"../lib/editor-host.js";import{SOURCE_LINES as at,SOURCE_ACTIONS as ct,SOURCE_ACTION_LABEL as dt,partSourceOf as ut,sourceSlugOf as be}from"../lib/puck/source-bound-parts.js";import{encodePartId as ft,holdsAuthoredText as pt}from"../lib/puck/text-parts.js";import{regionsForSection as mt}from"../lib/sections/section-text-regions.js";import{textRegionOfPartKey as ht}from"../lib/sections/text-regions.js";const yt={400:"Regular",500:"Medium",600:"Semibold",700:"Bold"},Se=[{key:"font",label:"Font",group:"Style"},{key:"color",label:"Color",group:"Style"}],gt=[...new Set(Se.map(e=>e.group))],bt={font:t(he,{}),color:t(ze,{})};function I(e){return e.kind==="role"?ee[e.role]:e.kind==="custom"?"Custom":null}const St=e=>e.kind==="role"?`role:${e.role}`:e.kind;function xt(e){const n=e.role;return n&&Z.includes(n)?{kind:"role",role:n}:null}function vt(e,n){if(!e)return{kind:"unread"};const{faceRole:s,base:l}=e;if(n[s]===l.fontKey)return{kind:"role",role:s};const c=Object.keys(n).filter(i=>n[i]===l.fontKey);return c.length===1?{kind:"role",role:c[0]}:{kind:"custom"}}function ne(e,n,s,l){return xt(ge(e,n))??vt(s,l)}function un(e,n,s,l){return I(ne(e,n,s,l))}function oe(e,n){if(!e.length)return null;const s=n(e[0]);return e.every(l=>n(l)===s)?s:null}function Nt(e){return Object.values(e).filter(n=>n!==void 0).length}function Pt(e,n){const s=e.style[n];return n==="color"?s??"":s!==void 0?String(s):e.base.fontKey}function kt({face:e,base:n,onPick:s}){const[l,c]=Q(!1),i=J(null),h=J(null),y=_e();M(()=>{if(!l)return;const a=T=>{i.current&&!i.current.contains(T.target)&&c(!1)};return document.addEventListener("mousedown",a),()=>document.removeEventListener("mousedown",a)},[l]);const u=e.kind==="role"?e.role:null,N=a=>{s(a),c(!1),h.current?.focus()};return r("div",{className:"sf-part-style-pick",ref:i,children:[r("button",{ref:h,type:"button",className:"sf-part-style-trigger","aria-expanded":l,"aria-controls":y,"aria-label":`Follows ${I(e)??"no style"} — change`,onClick:()=>c(a=>!a),onKeyDown:a=>{a.key==="Escape"&&l&&(a.preventDefault(),c(!1))},children:[t("span",{className:"sf-part-style-name",style:{fontFamily:n?.fontKey?`var(${$(n.fontKey)?.cssVar})`:void 0,fontWeight:n?.weight},children:I(e)}),t("span",{className:"sf-part-style-sign","aria-hidden":"true"})]}),l&&r("div",{className:"sf-multi-menu sf-part-style-menu",id:y,role:"listbox",onKeyDown:a=>{a.key==="Escape"&&(a.preventDefault(),c(!1),h.current?.focus())},children:[r("button",{type:"button",role:"option","aria-selected":u===null,className:`sf-part-style-option${u===null?" is-on":""}`,onClick:()=>N(null),children:[t("span",{className:"sf-part-style-option-name",children:"No style"}),t("span",{className:"sf-note",children:"Section’s own"})]}),Z.map(a=>t("button",{type:"button",role:"option","aria-selected":u===a,className:`sf-part-style-option${u===a?" is-on":""}`,onClick:()=>N(a),children:t("span",{className:"sf-part-style-option-name",style:{fontFamily:`var(--font-role-${a})`},children:ee[a]})},a))]})]})}const j="";function wt({face:e,base:n,onPick:s}){const l=e.kind==="role"?e.role:j,c=[{label:"No style",value:j},...Z.map(i=>({label:ee[i],value:i}))];return t(pe,{ariaLabel:"Style",value:l,options:c,inline:!0,onChange:i=>s(i===j?null:i),renderOption:i=>i.value===j?r(O,{children:[t("span",{className:"es-fsel-label sf-part-style-keep",children:i.label}),t("span",{className:"sf-part-style-aside","aria-hidden":"true",children:"Section’s own"})]}):t("span",{className:"es-fsel-label",style:{fontFamily:`var(--font-role-${i.value})`},children:i.label}),renderValue:()=>t("span",{style:{fontFamily:n?.fontKey?`var(${$(n.fontKey)?.cssVar})`:void 0,fontWeight:n?.weight},children:I(e)}),valueText:i=>I(e)??i?.label??""})}function Tt({parts:e,onEditStyle:n,onClearAll:s,onFollowStyle:l,kindLabel:c}){const h=oe(e,T=>St(T.face))?e[0].face:null,y=h?I(h):null,u=h&&h.kind!=="unread"?e[0].base:null,N=e.reduce((T,A)=>T+Nt(A.style),0),a=u?$(u.fontKey)?.label:void 0;return r("div",{className:`sf-part-style${N?" has-overrides":""}`,children:[t("div",{className:"sf-part-style-caption",children:"Style"}),e.length>1&&r("div",{className:"sf-part-style-count",children:[e.length," selected"]}),e.length===1&&c&&r("div",{className:"sf-part-style-count",children:[c," · every row"]}),y&&u?r(O,{children:[l&&h?t(kt,{face:h,base:u,onPick:l}):t("div",{className:"sf-part-style-name",style:{fontFamily:a?`var(${$(u.fontKey)?.cssVar})`:void 0,fontWeight:u.weight},children:y}),t("div",{className:"sf-part-style-meta",children:[a,`${Math.round(u.sizePx)} px`,yt[u.weight]].filter(Boolean).join(" · ")})]}):t("div",{className:"sf-part-style-name",children:"Mixed styles"}),r("div",{className:"sf-part-style-top",children:[y?N?r(O,{children:[r("span",{className:"sf-part-chip",children:[N," changed"]}),t("button",{type:"button",className:"sf-part-link",onClick:s,children:"Clear"})]}):t("span",{className:"sf-part-style-state",children:"This text follows the site style."}):t("span",{className:"sf-part-style-state",children:"Changes apply to all selected."}),t("span",{className:"sf-part-style-gap"}),y&&n&&t("button",{type:"button",className:"sf-part-link",onClick:n,children:"Edit"})]})]})}function Et({sectionName:e,onBack:n,textEditor:s,styleRow:l,children:c}){return r("div",{className:"sf-part-panel",children:[t(G,{inline:!0,name:e,onSelect:n}),s,l,c]})}function xe({source:e,slug:n}){const s=it(),l=ct[e],c=!l.needsSlug||!!n;return t("div",{className:"sf-note sf-note--source",children:r("p",{className:"es-field-hint sf-hint-keep",children:[at[e],c?r(O,{children:[" ",t("button",{type:"button",className:"sf-source-open",onClick:()=>{l.type==="storefront-editor:open-menus"?s.send(l.type):n&&s.send(l.type,{slug:n})},children:dt})]}):null]})})}const ve=4,Rt=120;function Ct({region:e,sizePx:n,face:s,base:l,onFollowStyle:c,source:i,slug:h,onBack:y}){const u=e.follows;return r("div",{className:"sf-note",children:[t("p",{children:t("strong",{children:e.label})}),r("p",{children:["Its size follows Site styles ▸ ",u,n?` — ${Math.round(n)}px right now`:"","."]}),c?t(O,{children:t(me,{label:"Style",icon:t(Le,{}),hint:r(O,{children:["Every ",e.label.toLowerCase()," in this section follows it. The face and the size change; the letter case is the section’s own and stays as it is."]}),children:t(wt,{face:s,base:l,onPick:c})})}):t("p",{className:"es-field-hint sf-hint-keep",children:"Only the size follows a site style. This section sets its own font, weight and letter case."}),i?t(xe,{source:i,slug:h}):null,t(G,{inline:!0,name:"Page",onSelect:y})]})}function Ft({onBack:e}){return r("div",{className:"sf-note",children:[t("p",{children:t("strong",{children:"This part is no longer here."})}),t("p",{children:"The section it belonged to has been changed or removed."}),t(G,{inline:!0,name:"Page",onSelect:e})]})}function Ot({onBack:e,partId:n,why:s}){return r("div",{className:"sf-note",children:[t("p",{children:t("strong",{children:"This part's settings did not open."})}),t("p",{children:"The words are still on your page and nothing has been lost. The editor could not work out which control belongs to them, which is a fault on our side. Go back and click the section to open its settings instead."}),t("p",{className:"sf-note-detail",children:r("code",{children:[n," — ",s]})}),t(G,{inline:!0,name:"Page",onSelect:e})]})}function It({nodeId:e,propKey:n,onBack:s,onEditStyle:l}){const{getItemById:c,getSelectorForId:i,config:h}=Be(o=>o),y=Ue(),{partStyle:u}=We(),{fonts:N}=Ge(),[a,T]=Q({}),A=J(null),g=c(e),S=i(e),se=g?h.components[g.type]:void 0,{key:E,row:P}=Qe(n),le=se?.fields?.[E],k=P?Je(le,P):le,_=ft(e,n),p=g?.props??{},w=qe(k),Ne=je(k),Pe=pt(k),H=g?ut(g.type):null,U=P?et(p[E],P):p[E],re=!!P&&!(Array.isArray(p[E])&&P.index<p[E].length);M(()=>{A.current?.querySelector(".es-copy [contenteditable='true'], .es-copy textarea, .sf-copybox textarea, .sf-copybox input")?.focus()},[_]);const[K,ie]=Q(0);M(()=>ie(0),[_]);const X=!!g&&!re&&(!S||!k);M(()=>{if(!X||K>=ve)return;const o=setTimeout(()=>ie(d=>d+1),Rt);return()=>clearTimeout(o)},[X,K]);const ke=X&&K<ve;if(!g||re)return t(Ft,{onBack:s});const L=mt(g.type),ae=L?ht(L,n):null;if(L&&ae){const o=u?.partId===_?u:null,d=L[ae],m=d.writable===!0&&!!S,b=f=>{S&&y.replaceComponent(S.zone,S.index,{...g,props:te(p,n,"role",f)})};return t(Ct,{region:d,sizePx:o?.base.sizePx??null,face:ne(p,n,o,N),base:o?.base??null,onFollowStyle:m?b:void 0,source:H,slug:be(p),onBack:s})}if(!S||!k)return ke?t("div",{className:"sf-note","aria-busy":"true"}):t(Ot,{onBack:s,partId:_,why:S?"no field":"no selector"});const z=o=>{y.replaceComponent(S.zone,S.index,{...g,props:o})},Y=o=>{if(W(o).hidden!==W(U).hidden||!w){const m=P?Ze(p,E,P,o):{...p,[E]:o};m&&z(m);return}rt({node:g,propKey:n,kind:w,zone:S.zone,index:S.index},W(o).text,y.replaceComponent)},we=U,B=st(g?.type,n),Te=ge(p,B),D=u?.partId===_?u:null,x=[{partKey:B,face:ne(p,B,D,N),sizeGroup:D?.sizeGroup??null,base:D?.base??_t,style:Te}],Ee=oe(x,o=>o.sizeGroup),ce=ot(D?.inks),V=(o,d)=>{let m=p;for(const b of x)m=te(m,b.partKey,o,d);z(m)},Re=o=>V("role",o),Ce=()=>{let o=p;for(const d of x)o=nt(o,d.partKey);z(o)},Fe=o=>{let d=p;for(const m of x)for(const[b,f]of Object.entries(o))d=te(d,m.partKey,b,f??null);z(d)},Oe=(o,d)=>{const m=x.some(v=>v.style[o]!==void 0),b=oe(x,v=>Pt(v,o)),f=b===null,F=`sf-part-${e}-${n}-${o}`;return o==="color"?t(Ve,{value:f?null:String(b),label:d,colors:ce,onChange:v=>V("color",v)},o):t(me,{label:d,icon:bt[o],className:"sf-part-field",changed:m,htmlFor:F,action:m?t(fe,{label:d,onClear:()=>V(o,null)}):void 0,children:o==="font"?t(pe,{id:F,ariaLabel:d,value:!f&&$(String(b))?String(b):void 0,placeholder:f?"Mixed":"Site style",options:Ke.map(v=>({label:v.label,value:v.key})),onChange:v=>V("font",v||null)}):null},o)},de=w==="text"||w==="textarea",{text:ue,hidden:R}=W(U),C=k?.[He]?.label??n,Ie=r("div",{className:"sf-field-head",children:[t(he,{}),t("span",{className:"sf-field-label sf-field-label--inline",children:C}),de&&t(De,{content:R?`Show ${C} on the slide`:`Hide ${C} on the slide`,children:t("button",{type:"button",className:"sf-field-eye","aria-pressed":R,"aria-label":R?`Show ${C} on the slide`:`Hide ${C} on the slide`,onClick:()=>Y({text:ue,hidden:!R}),children:R?t(ye,{name:"eye-off",size:14}):t(ye,{name:"eye",size:14})})})]}),q=!Ne&&Pe;return r(Et,{sectionName:se?.label??g.type,onBack:s,textEditor:r("div",{ref:A,className:"sf-part-text",children:[w?t(Me,{text:ue,onTextChange:o=>Y(de?{text:o,hidden:R}:o),multiline:Xe(w),markup:w!=="plainText",styled:q,style:x[0].style,base:x[0].base,setValue:Fe,colors:ce.map(o=>({name:o.key,label:o.name,value:o.value})),placeholder:Ye(k),ariaLabel:C,head:Ie}):t($e,{field:k,name:n,value:we,onChange:Y,id:`sf-part-${e}-${n}`}),q&&w&&Ee===null&&t("p",{className:"es-field-hint sf-hint-keep",children:"Fixed size — the site’s Text setting doesn’t resize this."})]}),children:[H&&t(xe,{source:H,slug:be(p)}),q&&gt.map(o=>{const d=Se.filter(f=>f.group===o),m=d.filter(f=>x.some(F=>F.style[f.key]!==void 0)).length,b=`sf-part-g-${e}-${n}-${o.replace(/\W+/g,"-")}`;return r(Ae,{id:b,title:o,open:a[o]!==!0,onToggle:f=>T(F=>({...F,[o]:!f})),count:m,children:[t(Tt,{parts:x,onEditStyle:l,onClearAll:Ce,onFollowStyle:Re,kindLabel:lt[B]}),d.map(f=>Oe(f.key,f.label))]},o)})]})}const _t={fontKey:"",sizePx:16,weight:400,lineRatio:1.4,letterEm:0,align:"left",case:"none",paddingPx:0,widthPx:tt};export{Se as PART_FIELDS,Et as PartPanelBody,fe as PartResetDot,xe as PartSourceNote,Tt as PartStyleCard,wt as PartStyleSelect,It as default,ne as partFace,un as partStyleName};
@@ -1,2 +1,2 @@
1
- import{applyMark as q,markupTools as w,MARKUP_TOOLS as C,COPY_FIELD_TOOLS as $,STOREFRONT_MARKUP as j,tokenizeInline as B,stripInline as H,isSafeLinkHref as z}from"efficient-easel/markup";import{applyMark as g,markedAt as k,markupTools as R,MARKUP_TOOLS as m,parseMarkup as L,RETIRED_MARKS as d,STOREFRONT_MARKUP as a,tokenizeInline as M}from"efficient-easel/markup";import{WORD_STYLES as u,WORD_STYLE_LABELS as r,WORD_STYLE_MARKS as o}from"./word-styles.js";const f=u.map(e=>({open:o[e].delimiter,close:o[e].delimiter,kind:o[e].kind})),h=[{style:o.highlight.kind,label:r.highlight,title:`${r.highlight} word style`},{style:o.strong.kind,label:r.strong,title:`${r.strong} word style`},{style:o.quiet.kind,label:r.quiet,title:`${r.quiet} word style`}],Y=new Set(f.map(e=>e.open)),c=[...a.filter(e=>!Y.has(e.open)),...f];function W(e){return M(e,c)}function y(e){return e.bullet?"- ":e.number!=null?`${e.number}. `:""}function A(e){return L(typeof e=="string"?e:"",c)}const x=["quiet"],S=[...m.map(e=>e.style).filter(e=>!x.includes(e)&&!d.includes(e)),...h.map(e=>e.style)].filter(e=>c.some(n=>n.kind===e));function b(){return[...R(S),...h].filter(e=>S.includes(e.style))}const _=Object.fromEntries(u.map(e=>[o[e].kind,o[e].delimiter]));function I(e,n,i,l){const t=_[l];if(!t)return g(e,n,i,l);const s=e.slice(n,i),E=e.slice(Math.max(0,n-t.length),n),T=e.slice(i,i+t.length);if(E===t&&T===t)return{text:e.slice(0,n-t.length)+s+e.slice(i+t.length),selectionStart:n-t.length,selectionEnd:n-t.length+s.length};const p=s||"styled text";return{text:e.slice(0,n)+t+p+t+e.slice(i),selectionStart:n+t.length,selectionEnd:n+t.length+p.length}}function K(e,n,i,l){const t=_[l];return t?n>=t.length&&e.slice(n-t.length,n)===t&&e.slice(i,i+t.length)===t:k(e,n,i,l)}function F(e){return A(e).map(n=>y(n)+O(n.children)).join(`
2
- `)}function O(e){return e.map(n=>n.kind==="text"?n.text:O(n.children)).join("")}export{$ as COPY_FIELD_TOOLS,C as MARKUP_TOOLS,S as SHOP_COPY_FIELD_TOOLS,c as SHOP_MARKUP,j as STOREFRONT_MARKUP,f as WORD_STYLE_RULES,h as WORD_STYLE_TOOLS,q as applyMark,I as applyShopMark,z as isSafeLinkHref,y as linePrefix,w as markupTools,K as shopMarkedAt,b as shopMarkupTools,A as storefrontLines,W as storefrontTokens,H as stripInline,F as stripMarkup,B as tokenizeInline};
1
+ import{applyMark as w,markupTools as C,MARKUP_TOOLS as N,COPY_FIELD_TOOLS as $,STOREFRONT_MARKUP as j,tokenizeInline as q,stripInline as H,isSafeLinkHref as z}from"efficient-easel/markup";import{applyMark as g,markedAt as k,markupTools as E,MARKUP_TOOLS as T,parseMarkup as m,RETIRED_MARKS as R,STOREFRONT_MARKUP as L,tokenizeInline as d}from"efficient-easel/markup";import{WORD_STYLES as u,WORD_STYLE_LABELS as r,WORD_STYLE_MARKS as o}from"./word-styles.js";const f=u.map(e=>({open:o[e].delimiter,close:o[e].delimiter,kind:o[e].kind})),Y=[{style:o.highlight.kind,label:r.highlight,title:`${r.highlight} word style`},{style:o.strong.kind,label:r.strong,title:`${r.strong} word style`},{style:o.quiet.kind,label:r.quiet,title:`${r.quiet} word style`}],a=new Set(f.map(e=>e.open)),p=[...L.filter(e=>!a.has(e.open)),...f];function D(e){return d(e,p)}function M(e){return e.bullet?"- ":e.number!=null?`${e.number}. `:""}function x(e){return m(typeof e=="string"?e:"",p)}const y=T.map(e=>e.style).filter(e=>!R.includes(e)).filter(e=>p.some(n=>n.kind===e));function b(){return E(y)}const h=Object.fromEntries(u.map(e=>[o[e].kind,o[e].delimiter]));function K(e,n,i,l){const t=h[l];if(!t)return g(e,n,i,l);const s=e.slice(n,i),O=e.slice(Math.max(0,n-t.length),n),_=e.slice(i,i+t.length);if(O===t&&_===t)return{text:e.slice(0,n-t.length)+s+e.slice(i+t.length),selectionStart:n-t.length,selectionEnd:n-t.length+s.length};const c=s||"styled text";return{text:e.slice(0,n)+t+c+t+e.slice(i),selectionStart:n+t.length,selectionEnd:n+t.length+c.length}}function W(e,n,i,l){const t=h[l];return t?n>=t.length&&e.slice(n-t.length,n)===t&&e.slice(i,i+t.length)===t:k(e,n,i,l)}function F(e){return x(e).map(n=>M(n)+S(n.children)).join(`
2
+ `)}function S(e){return e.map(n=>n.kind==="text"?n.text:S(n.children)).join("")}export{$ as COPY_FIELD_TOOLS,N as MARKUP_TOOLS,y as SHOP_COPY_FIELD_TOOLS,p as SHOP_MARKUP,j as STOREFRONT_MARKUP,f as WORD_STYLE_RULES,Y as WORD_STYLE_TOOLS,w as applyMark,K as applyShopMark,z as isSafeLinkHref,M as linePrefix,C as markupTools,W as shopMarkedAt,b as shopMarkupTools,x as storefrontLines,D as storefrontTokens,H as stripInline,F as stripMarkup,q as tokenizeInline};
@@ -1 +1 @@
1
- import{jsx as e,Fragment as u,jsxs as p}from"react/jsx-runtime";import{useEffect as g,useState as M}from"react";import{MarkBar as S,markSelection as E,useCaretEdit as L}from"efficient-easel/copy";import{RevertIcon as v}from"efficient-easel/icons";import{IconButton as b,Tooltip as j}from"efficient-shell/ui";import{applyShopMark as z,shopMarkedAt as A,shopMarkupTools as T,stripMarkup as C}from"../markup.js";function H({style:t}){const n=r=>e("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.9,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:r});switch(t){case"bold":return n(e("path",{d:"M7 5h6.5a3.5 3.5 0 0 1 0 7H7zm0 7h7.5a3.5 3.5 0 0 1 0 7H7z"}));case"italic":return n(p(u,{children:[e("line",{x1:"10",y1:"5",x2:"19",y2:"5"}),e("line",{x1:"5",y1:"19",x2:"14",y2:"19"}),e("line",{x1:"14",y1:"5",x2:"10",y2:"19"})]}));case"strike":return n(p(u,{children:[e("path",{d:"M16.5 6.5A4.2 4.2 0 0 0 12.7 4.7C10 4.7 8.4 6 8.4 7.9c0 1.6 1.2 2.5 3.4 3.1"}),e("path",{d:"M7.6 17.4A4.4 4.4 0 0 0 11.7 19.3c2.8 0 4.5-1.4 4.5-3.4 0-1-.4-1.8-1.2-2.4"}),e("line",{x1:"4",y1:"12",x2:"20",y2:"12"})]}));case"highlight":return n(p(u,{children:[e("path",{d:"M14.5 4.5l5 5-8 8H6.5v-5z"}),e("line",{x1:"4",y1:"21",x2:"20",y2:"21"})]}));case"quiet":return n(p(u,{children:[e("path",{d:"M12 4.5l5.5 7.5L12 19.5 6.5 12z"}),e("line",{x1:"9.4",y1:"12",x2:"14.6",y2:"12"})]}));default:return null}}const _=["bold","italic","strike","highlight"],D=Object.fromEntries(_.map(t=>[t,e(H,{style:t},t)])),y="Clear formatting";function B(t,n,r){return E(t,n,r,z)}function F(t){const[n,r]=M(null);return g(()=>{const o=t.current?.ownerDocument??(typeof document>"u"?null:document);if(!o)return;const a=()=>{const s=t.current;if(!s||o.activeElement!==s)return;const i=s.selectionStart??s.value.length,d=s.selectionEnd??i;r(c=>c&&c.start===i&&c.end===d?c:{start:i,end:d})};return o.addEventListener("selectionchange",a),()=>o.removeEventListener("selectionchange",a)},[t]),[n,r]}function I({target:t,value:n,onChange:r,disabled:o=!1,label:a="Formatting"}){const s=L({target:t,onChange:r}),[i,d]=F(t),c=l=>s(k=>{const h=B(n,l,k);return d({start:h.selectionStart,end:h.selectionEnd}),h}),m=T(),f={};if(i)for(const l of m)f[l.style]=A(n,i.start,i.end,l.style);const x=C(n);return e(S,{tools:m,onApply:c,pressed:f,disabled:o,glyphs:D,ariaLabel:a,actions:e("span",{className:"sf-markup-clear",children:e(j,{content:y,children:e(b,{size:"sm",onMouseDown:l=>l.preventDefault(),onClick:()=>r(x),disabled:o||x===n,"aria-label":y,children:e(v,{size:14})})})})})}var P=I;export{I as MarkupToolbar,P as default,B as markSelection};
1
+ import{jsx as e,Fragment as p,jsxs as h}from"react/jsx-runtime";import{useEffect as g,useState as M}from"react";import{MarkBar as S,markSelection as E,useCaretEdit as v}from"efficient-easel/copy";import{RevertIcon as L}from"efficient-easel/icons";import{IconButton as b,Tooltip as j}from"efficient-shell/ui";import{applyShopMark as A,shopMarkedAt as T,shopMarkupTools as z,stripMarkup as C}from"../markup.js";function H({style:t}){const n=r=>e("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.9,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:r});switch(t){case"bold":return n(e("path",{d:"M7 5h6.5a3.5 3.5 0 0 1 0 7H7zm0 7h7.5a3.5 3.5 0 0 1 0 7H7z"}));case"italic":return n(h(p,{children:[e("line",{x1:"10",y1:"5",x2:"19",y2:"5"}),e("line",{x1:"5",y1:"19",x2:"14",y2:"19"}),e("line",{x1:"14",y1:"5",x2:"10",y2:"19"})]}));case"strike":return n(h(p,{children:[e("path",{d:"M16.5 6.5A4.2 4.2 0 0 0 12.7 4.7C10 4.7 8.4 6 8.4 7.9c0 1.6 1.2 2.5 3.4 3.1"}),e("path",{d:"M7.6 17.4A4.4 4.4 0 0 0 11.7 19.3c2.8 0 4.5-1.4 4.5-3.4 0-1-.4-1.8-1.2-2.4"}),e("line",{x1:"4",y1:"12",x2:"20",y2:"12"})]}));case"highlight":return n(h(p,{children:[e("path",{d:"M14.5 4.5l5 5-8 8H6.5v-5z"}),e("line",{x1:"4",y1:"21",x2:"20",y2:"21"})]}));default:return null}}const _=["bold","italic","strike","highlight"],D=Object.fromEntries(_.map(t=>[t,e(H,{style:t},t)])),k="Clear formatting";function B(t,n,r){return E(t,n,r,A)}function F(t){const[n,r]=M(null);return g(()=>{const o=t.current?.ownerDocument??(typeof document>"u"?null:document);if(!o)return;const a=()=>{const s=t.current;if(!s||o.activeElement!==s)return;const i=s.selectionStart??s.value.length,d=s.selectionEnd??i;r(c=>c&&c.start===i&&c.end===d?c:{start:i,end:d})};return o.addEventListener("selectionchange",a),()=>o.removeEventListener("selectionchange",a)},[t]),[n,r]}function I({target:t,value:n,onChange:r,disabled:o=!1,label:a="Formatting"}){const s=v({target:t,onChange:r}),[i,d]=F(t),c=l=>s(y=>{const u=B(n,l,y);return d({start:u.selectionStart,end:u.selectionEnd}),u}),m=z(),f={};if(i)for(const l of m)f[l.style]=T(n,i.start,i.end,l.style);const x=C(n);return e(S,{tools:m,onApply:c,pressed:f,disabled:o,glyphs:D,ariaLabel:a,actions:e("span",{className:"sf-markup-clear",children:e(j,{content:k,children:e(b,{size:"sm",onMouseDown:l=>l.preventDefault(),onClick:()=>r(x),disabled:o||x===n,"aria-label":k,children:e(L,{size:14})})})})})}var P=I;export{I as MarkupToolbar,P as default,B as markSelection};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "efficient-web-builder",
3
- "version": "5.0.0",
3
+ "version": "5.0.2",
4
4
  "description": "The EFFICIENT website builder: the website editor, the general sections and the renderer that draws them, compiled. Hostable by any EFFICIENT product; nothing here imports a host.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Efficient Pty Ltd",
@@ -58,8 +58,8 @@
58
58
  "@types/node": "^20",
59
59
  "@types/react": "^19",
60
60
  "@types/react-dom": "^19",
61
- "efficient-easel": "^2.0.0",
62
- "efficient-shell": "^4.171.0",
61
+ "efficient-easel": "^2.1.0",
62
+ "efficient-shell": "^4.180.0",
63
63
  "esbuild": "^0.28.0",
64
64
  "happy-dom": "^20.14.5",
65
65
  "isomorphic-dompurify": "^3.18.0",