@livx.cc/bare-v3 0.1.0-alpha.146 → 0.1.0-alpha.148
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var E=typeof HTMLElement==="function"?HTMLElement:class{};function g(e,n){if(typeof customElements>"u"||customElements.get?.(e))return;try{customElements.define(e,n)}catch(r){console.warn(`bare-v3: ${e} was not registered`,r)}}class m extends E{#e=null;#n=null;#t=null;target(){return this}connectedCallback(){let e=this.ownerDocument;if(e.readyState==="loading"){e.addEventListener("DOMContentLoaded",()=>{if(this.isConnected)this.#r()},{once:!0});return}this.#r()}disconnectedCallback(){this.#a(),this.#t?.disconnect(),this.#t=null}#r(){if(this.#e)return;let e=this.target();if(e!==this&&!this.#t)this.#t=new MutationObserver(()=>{if(this.target()!==this.#n)this.#a(),this.#r()}),this.#t.observe(this,{childList:!0});if(!e)return;this.#e=new AbortController,this.#n=e,this.mount(e,this.#e.signal)}#a(){this.#e?.abort(),this.#e=null,this.#n=null}}var T=Symbol.for("bare-v3.styles");function v(e,n,r){if(!e?.head||e.getElementById(n))return;let s=e[T]??=new Set;if(s.has(n))return;let a=e.defaultView;if(a&&"adoptedStyleSheets"in e&&"replaceSync"in a.CSSStyleSheet.prototype){let i=new a.CSSStyleSheet;i.replaceSync(r),e.adoptedStyleSheets=[...e.adoptedStyleSheets,i],s.add(n);return}let o=e.createElement("style");o.id=n,o.textContent=r,e.head.append(o)}function p(e){if(!Number.isFinite(e)||e<0)return"--:--";let n=Math.floor(e),r=Math.floor(n/3600),s=Math.floor(n/60)%60,a=(o)=>String(o).padStart(2,"0");return r?`${r}:${a(s)}:${a(n%60)}`:`${s}:${a(n%60)}`}var w="b3-audio-player-style",M=`
|
|
2
|
-
b3-audio-player{container-type:inline-size;display:flex;align-items:center;gap:.25rem;min-inline-size:0;font-variant-numeric:tabular-nums;}
|
|
2
|
+
b3-audio-player{container-type:inline-size;inline-size:100%;display:flex;align-items:center;gap:.25rem;min-inline-size:0;font-variant-numeric:tabular-nums;}
|
|
3
3
|
b3-audio-player > audio{display:none;}
|
|
4
4
|
b3-audio-player:not(:defined) > audio{display:block;inline-size:100%;}
|
|
5
5
|
b3-audio-player button{flex:none;display:inline-flex;align-items:center;justify-content:center;
|
|
@@ -10,5 +10,6 @@ b3-audio-player button:focus-visible,b3-audio-player input:focus-visible{outline
|
|
|
10
10
|
b3-audio-player svg{inline-size:1.25rem;block-size:1.25rem;fill:currentColor;}
|
|
11
11
|
b3-audio-player [data-b3-part="time"]{flex:none;font-size:.8125em;color:var(--b3-color-muted,#5d6b60);white-space:nowrap;}
|
|
12
12
|
b3-audio-player input[type=range]{flex:1;min-inline-size:3rem;margin:0;accent-color:var(--b3-color-accent,#276bdd);cursor:pointer;}
|
|
13
|
-
@container (max-width:22rem){[data-b3-part="rate"]
|
|
14
|
-
|
|
13
|
+
@container (max-width:22rem){[data-b3-part="rate"]{display:none;} b3-audio-player button{min-inline-size:2.25rem;}}
|
|
14
|
+
@container (max-width:14rem){[data-b3-part="back"],[data-b3-part="fwd"]{display:none;}}
|
|
15
|
+
`,f={play:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8 5v14l11-7z"/></svg>',pause:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 5h4v14H7zm6 0h4v14h-4z"/></svg>'},y=[1,1.25,1.5,2,0.75];class S extends m{get skip(){return Number(this.getAttribute("skip"))||15}target(){return this.querySelector(":scope > audio")}mount(e,n){v(this.ownerDocument,w,M);for(let t of this.querySelectorAll(":scope > [data-b3-part]"))t.remove();let r=this.skip,s=`<button type="button" data-b3-part="back" aria-label="Back ${r} seconds">−${r}</button><button type="button" data-b3-part="play" aria-label="Play">${f.play}</button><button type="button" data-b3-part="fwd" aria-label="Forward ${r} seconds">+${r}</button><input type="range" data-b3-part="seek" min="0" max="0" step="0.1" value="0" aria-label="Seek"><span data-b3-part="time"></span>`+'<button type="button" data-b3-part="rate" aria-label="Playback speed">1×</button>';e.insertAdjacentHTML("afterend",s);let a=(t)=>this.querySelector(`:scope > [data-b3-part="${t}"]`),o=a("play"),i=a("seek"),k=a("time"),h=a("rate"),u=!1,d=()=>{let{duration:t,currentTime:c}=e;if(Number.isFinite(t))i.max=String(t);if(!u)i.value=String(c);i.setAttribute("aria-valuetext",`${p(c)} of ${p(t)}`),k.textContent=`${p(u?Number(i.value):c)} / ${p(t)}`,o.innerHTML=e.paused?f.play:f.pause,o.setAttribute("aria-label",e.paused?"Play":"Pause"),h.textContent=`${e.playbackRate}×`},l=(t,c,x)=>t.addEventListener(c,x,{signal:n});for(let t of["timeupdate","durationchange","loadedmetadata","play","pause","ended","ratechange","emptied","seeked"])l(e,t,d);let b=(t)=>{e.currentTime=Math.max(0,Math.min(t,Number.isFinite(e.duration)?e.duration:t))};l(o,"click",()=>{if(e.paused)e.play().catch((t)=>this.dispatchEvent(new CustomEvent("b3-error",{detail:t,bubbles:!0})));else e.pause()}),l(a("back"),"click",()=>b(e.currentTime-r)),l(a("fwd"),"click",()=>b(e.currentTime+r)),l(h,"click",()=>{e.playbackRate=y[(y.indexOf(e.playbackRate)+1)%y.length]}),l(i,"input",()=>{u=!0,d()}),l(i,"change",()=>{u=!1,b(Number(i.value))}),n.addEventListener("abort",()=>{for(let t of this.querySelectorAll(":scope > [data-b3-part]"))t.remove()},{once:!0}),d()}}g("b3-audio-player",S);export{S as B3AudioPlayer,p as clock};
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* detail carries the full, plain `columns` after every user edit plus the `action` that made it.
|
|
7
7
|
* `#tag` and `@mention` words in a title or description become filter labels; a trailing run of
|
|
8
8
|
* them is shown as labels instead of title text. `search` narrows the cards to those whose text (comments included) holds every word typed;
|
|
9
|
-
* `addCard()` starts a new card in the `default-column
|
|
9
|
+
* `addCard()` starts a new card in the `default-column`, at its end — or on top (under any starred cards) in a `top-columns` column (comma-separated names/ids). Starred cards stay above the rest of their column. Opt-in entry: `@livx.cc/bare-v3/components/board`.
|
|
10
10
|
*/
|
|
11
11
|
import { Base } from './base';
|
|
12
12
|
/** Ids are kept as given (a number stays a number); missing ones are generated as strings. */
|
|
@@ -175,8 +175,12 @@ export declare class B3Board extends Base {
|
|
|
175
175
|
/** The column `addCard()` adds to when given none (`default-column`): an id, or a name (case-insensitive); else the first. */
|
|
176
176
|
get defaultColumn(): string;
|
|
177
177
|
set defaultColumn(value: string);
|
|
178
|
+
/** Columns whose new cards go on top (`top-columns`): comma-separated ids or names (case-insensitive). */
|
|
179
|
+
get topColumns(): string;
|
|
180
|
+
set topColumns(value: string);
|
|
181
|
+
/** @internal */ onTop(column: BoardColumn): boolean;
|
|
178
182
|
/**
|
|
179
|
-
* Start a new card, its title editor focused and in view, at the end of `column` (an id or name) or the default
|
|
183
|
+
* Start a new card, its title editor focused and in view, at the end (or top, `top-columns`) of `column` (an id or name) or the default
|
|
180
184
|
* column. Reported by `b3-change` once it has a title. False when readonly or there is no such column.
|
|
181
185
|
*/
|
|
182
186
|
addCard(column?: BoardId): boolean;
|
package/dist/components/board.js
CHANGED
|
@@ -335,8 +335,8 @@ b3-board [data-b3-drop="before"]{box-shadow:0 -3px 0 -1px var(--b3-color-accent)
|
|
|
335
335
|
</template>
|
|
336
336
|
<button type="button" class="b3-board-link b3-board-add" b3x-show="!readonly" b3x-on:click="addColumn()">${st}<span>Add column</span></button>
|
|
337
337
|
</div>
|
|
338
|
-
<span class="b3-visually-hidden" role="status" b3x-text="announcement"></span>`;class pi extends Pe{static observedAttributes=["readonly","search","link-schemes","searchable","expand-in"];#t=null;#e=null;#n=null;#l=null;#o=null;#i=!1;#c=null;#m=null;#r=null;#g=!1;#v=null;#S=0;#w=Math.random().toString(36).slice(2,8);#y=!1;#A=[];#d={past:[],future:[],now:null,key:"",at:0};#h=!1;get columns(){let e=lr(this.#e?.columns??this.#n??[]),t=this.#e?.editing;if(t?.fresh)si(e,t);return e}set columns(e){let t=cr(lr(e));if(!this.#e){this.#n=t;return}this.#p();let r=this.#j();if(r)this.#F(r);let n=this.#e;if(n.editing?.fresh)ga(n.columns,t,n.editing);if(n.columns=t,n.editing&&!this.#a(n.editing.id))n.editing=null;if(!this.#h)this.#d={past:[],future:[],now:null,key:"",at:0};this.#d.now=this.columns}undo(){return this.#_(-1)}openSearch(){if(!this.#e?.searchable)return!1;return this.#e.openSearch(),!0}redo(){return this.#_(1)}get canUndo(){return!this.readonly&&(this.#d.past.length>0||!!this.#e?.editing)}get canRedo(){return!this.readonly&&this.#d.future.length>0}#_(e){let t=this.#e;if(!t||this.readonly)return!1;t.settle();let r=this.#d,i=(e<0?r.past:r.future).pop();if(!i||!r.now)return!1;(e<0?r.future:r.past).push(r.now),r.key="";let a=new Map(t.columns.flatMap((o)=>o.cards.map((l)=>[String(l.id),l.expanded]))),s=cr(lr(i));for(let o of s)for(let l of o.cards){let c=a.get(String(l.id));if(a.has(String(l.id)))if(c===void 0)delete l.expanded;else l.expanded=c}return this.#p(),t.columns=s,r.now=this.columns,this.#s(e<0?"Undone":"Redone"),this.#E({type:e<0?"undo":"redo"}),!0}#E(e){this.#h=!0;try{this.dispatchEvent(new CustomEvent("b3-change",{bubbles:!0,detail:{columns:this.columns,action:e}}))}finally{this.#h=!1}}get filter(){return[...this.#e?.filter??this.#l??[]]}set filter(e){let t=[...e??[]].map((r)=>String(r).toLowerCase());if(this.#e){if(t.join(" ")!==this.#e.filter.join(" "))this.#e.kept=[];this.#e.filter=t}else this.#l=t}get search(){return this.#e?.search??this.#o??""}set search(e){let t=String(e??"");if(this.#e){if(t!==this.#e.search)this.#e.kept=[];this.#e.search=t}else this.#o=t}get defaultColumn(){return this.getAttribute("default-column")??""}set defaultColumn(e){if(e)this.setAttribute("default-column",String(e));else this.removeAttribute("default-column")}addCard(e){let t=this.#e;if(!t||this.readonly)return!1;let r=e??this.defaultColumn,n=String(r).trim().toLowerCase(),i=r!==""&&(t.columns.find((a)=>x(a.id,r))??t.columns.find((a)=>String(a.name??"").trim().toLowerCase()===n))||(e===void 0?t.columns[0]:void 0);if(!i)return!1;return t.addCard(i),!0}get upload(){return this.#v}set upload(e){this.#v=typeof e==="function"?e:null}get readonly(){return this.hasAttribute("readonly")}set readonly(e){this.toggleAttribute("readonly",!!e)}connectedCallback(){for(let t of["columns","filter","search","defaultColumn","readonly","upload"]){if(!Object.hasOwn(this,t))continue;let r=this[t];delete this[t],this[t]=r}let e=this.ownerDocument;if(!this.#t&&e.readyState==="loading"){if(!this.#i)this.#i=!0,e.addEventListener("DOMContentLoaded",()=>{if(this.#i=!1,this.isConnected)this.connectedCallback()},{once:!0});return}if($e(e,Sa,Aa),ni(),!this.#t){let t=this.querySelector(':scope > script[type="application/json"]'),r=this.#n;if(!r&&t)try{r=cr(JSON.parse(t.textContent||"[]"))}catch(n){console.warn("b3-board: ignoring unreadable JSON data",n)}this.#t=e.createElement("div"),this.#t.className="b3-board-ui",this.append(this.#t),this.#e=ti(this.#t,Ia,this.#C(r??[],this.#l??[],this.#o??this.getAttribute("search")??"")),this.#n=this.#l=this.#o=null,this.#d.now=this.columns}else if(this.#t.parentNode!==this)this.append(this.#t);this.#m=new MutationObserver(()=>{if(this.#t&&this.#t.parentNode!==this)this.append(this.#t)}),this.#m.observe(this,{childList:!0}),this.#K(),mr(this,this.#c.signal,{role:"region"})}disconnectedCallback(){this.#p(),this.#c?.abort(),this.#c=null,this.#$(),this.#m?.disconnect(),this.#m=null}attributeChangedCallback(e,t,r){if(e==="search")return void(this.search=r??"");if(!this.#e)return;if(e==="link-schemes")return void(this.#e.schemes=li(r));if(e==="searchable")return void(this.#e.searchable=r!==null);if(e==="expand-in")return void(this.#e.expandIn=ci(r));if(this.#e.readonly=this.readonly,this.#e.viewed={},this.readonly)this.#p(),this.#e.editing=null}#a(e){for(let t of this.#e?.columns??[]){if(x(t.id,e))return t;for(let r of t.cards)if(x(r.id,e)||C(r).some((n)=>x(n.id,e)))return r}return null}#b(e){let t="card"in e&&e.card!=null&&e.type!=="toggle"&&e.type!=="remove"?this.#a(e.card):null;if(t){if(t.updated=new Date().toISOString(),e.type==="add")t.created=t.updated}let r=this.#d,n=Date.now();if(e.type!=="toggle"){let i=e.type==="edit"?JSON.stringify([e.card,e.column,e.field,e.subtask]):"";if(r.now&&!(i&&i===r.key&&n-r.at<1000)){if(r.past.push(r.now),r.past.length>100)r.past.shift()}r.future=[],r.key=i,r.at=n}r.now=this.columns,this.#E(e)}#C(e,t,r){let n=this,i=(o)=>this.#b(o),a=(o)=>{for(let l of s.columns){let c=l.cards.findIndex((d)=>x(d.id,o));if(c>=0)return{column:l,index:c,card:l.cards[c]}}return null},s=ei({columns:e,filter:t,search:r,kept:[],editing:null,announcement:"",readonly:n.readonly,searchable:n.hasAttribute("searchable"),expandIn:ci(n.getAttribute("expand-in")),searching:!1,schemes:li(n.getAttribute("link-schemes")),viewed:{},selected:null,tokensOf:at,subtasksOf:C,commentsOf:V,hits:oi,said(o){return V(o).some((l)=>oi(s.search,l))},now:Date.now(),ago(o){return ma(o,s.now)},label(o){let l=String(o??"");return l.replace(ba,"").trim()||l},pressed(o){return String(s.filter.includes(o))},mention(o){return o.startsWith("@")?"":null},starred(o){return String(!!o.starred)},hasDetails(o){return!!(o.description||C(o).length||V(o).length)},complete(o){let l=C(o).length;return l>0&&s.done(o)===l},preview(o){let l=String(o.description??"");return l.split(`
|
|
339
|
-
`).map((d)=>di(d,s.schemes)).find((d)=>d.trim())?.trim()??(fr(l,s.schemes).some((d)=>typeof d!=="string"&&d.image)?"Image":"")},plain(o){return di(s.label(o),s.schemes)},rich(o,l){ka(o,String(l??""),s.schemes)},keyText(o,l,c,d){if(o.target!==o.currentTarget||o.key!=="Enter"&&o.key!==" ")return;o.preventDefault(),o.stopPropagation(),s.edit(l,c,d)},isOpen(o){let l=s.viewed[String(o.id)];return s.readonly&&l!==void 0?l:o.expanded??(s.hasDetails(o)&&dr(s.expandIn,s.columns.find((c)=>c.cards.some((d)=>x(d.id,o.id)))))},expanded(o){return String(s.isOpen(o))},isSelected(o){return x(s.selected,o.id)},isEditing(o,l){return!!s.editing&&s.editing.field===o&&s.editing.id===l},focusEditor(o){queueMicrotask(()=>n.#T(o))},blurEditor(o,l){if(s.isEditing(o,l))s.commit()},tokens(){let o=new Set;for(let l of s.columns)for(let c of l.cards)for(let d of at(c))o.add(d);return[...o].sort()},visible(o){let l=bi(s.search);if(!s.filter.length&&!l.length)return o.cards;let c=s.editing&&n.#a(s.editing.id);return o.cards.filter((d)=>{if(d===c||s.kept.some((b)=>x(d.id,b)))return!0;let u=at(d),f=l.length?ya(d):"";return s.filter.every((b)=>u.includes(b))&&l.every((b)=>f.includes(b))})},count(o){let l=s.visible(o).length;return l===o.cards.length?String(l):`${l}/${o.cards.length}`},done(o){return C(o).filter((l)=>l.done).length},disclosable(o){return!!(s.hasDetails(o)||!s.readonly)},toggleFilter(o){s.kept=[],s.filter=s.filter.includes(o)?s.filter.filter((l)=>l!==o):[...s.filter,o]},setFilter(o){s.kept=[],s.filter=o},searchShown(){return s.searching||!!s.search},openSearch(){s.searching=!0;let o=n.querySelector(".b3-board-search-input");if(!o)return;o.hidden=!1,o.closest(".b3-board-filters").hidden=!1,o.focus(),o.select()},typeSearch(o){n.search=o.target.value},keySearch(o){if(o.isComposing||o.keyCode===229)return;if(o.key!=="Escape"&&o.key!=="Enter")return;o.preventDefault(),o.stopPropagation();let l=o.target;if(o.key==="Escape")l.value="",n.search="";l.blur()},blurSearch(){s.searching=!1},toggleStar(o){if(s.readonly)return;if(s.editing)s.commit();let l=a(o.id),c=l?.card;if(!l||!c)return;if(c.starred)delete c.starred;else c.starred=!0;l.column.cards=hi(l.column.cards);let d=!!c.starred;s.announcement=`${c.title??""} ${d?"starred":"unstarred"}`,i({type:"star",card:c.id,starred:d}),n.#B(c.id)},toggle(o){if(s.readonly){s.viewed={...s.viewed,[String(o.id)]:!s.isOpen(o)};return}o.expanded=!s.isOpen(o),i({type:"toggle",card:o.id,expanded:o.expanded})},edit(o,l,c,d=!1,u=!1,f=!1){if(s.readonly||n.#r?.started)return;if(s.editing&&!s.isEditing(o,l))s.commit();s.editing={field:o,id:l,draft:c??"",fresh:d,opened:u,atEnd:f},n.#O()},addDetails(o,l=!1){if(s.readonly)return;let c=!s.isOpen(o);o.expanded=!0,s.edit("description",o.id,String(o.description??""),!1,c,l)},keyEditor(o,l){if(o.stopPropagation(),o.key==="Escape")o.preventDefault(),s.cancel();else if(o.key==="Enter"&&!(l&&o.shiftKey)&&!o.isComposing)o.preventDefault(),s.commit(!0);else if(o.key==="Tab"&&!o.altKey&&!o.metaKey&&!o.ctrlKey&&!o.isComposing&&!n.hasAttribute("compact")){let c=s.editing,d=c?.field==="title"&&!o.shiftKey?"description":c?.field==="description"&&o.shiftKey?"title":null;if(!d)return;o.preventDefault(),s.commit();let u=n.#a(c.id);if(!u||s.readonly)return;if(d==="description")s.addDetails(u,!0);else s.edit("title",u.id,String(u.title??""))}},pasteEditor(o,l,c){let d=[...o.clipboardData?.files??[]].filter((u)=>u.type.startsWith("image/"));if(s.readonly||!n.upload||!["title","description","comment"].includes(l)||!d.length)return;if(o.clipboardData?.getData("text/plain").trim())return;o.preventDefault();for(let u of d)n.#u(c,u,l==="title"?null:o.target,l==="comment"?"comment":"description")},cancel(){let o=s.editing;if(s.editing=null,o?.fresh)s.discard(o);if(o?.opened)s.close(o);n.#P(o)},close(o){let l=n.#a(o.id);if(l&&!s.hasDetails(l))l.expanded=!1},commit(o=!1){let l=s.editing;if(!l)return;if(s.editing=null,s.readonly)return;let c=l.field==="description"||l.field==="comment"?l.draft.trim():l.draft.replace(/\s+/g," ").trim(),d=n.#a(l.id);if(!d)return;if(!c&&l.fresh)return s.discard(l);if(!c&&l.opened)s.close(l);let u=null;if(l.field==="comment"){let b=d;if(c){let p={id:Ne(),at:new Date().toISOString(),by:n.getAttribute("author")||"you",text:c};b.comments=[...V(b),p],u={type:"comment",card:b.id,comment:p.id,op:"add"}}}else if(l.field==="name"){let b=d;if(c&&c!==b.name)b.name=c,u={type:"edit",column:b.id,field:"name"};if(l.fresh)u={type:"add",column:b.id}}else if(l.field==="subtask"){let b=d,p=C(b).find((h)=>x(h.id,l.id));if(!c)return s.removeSubtask(b,p);if(c!==p.title)p.title=c,u={type:"edit",card:b.id,field:"subtask",subtask:p.id};if(l.fresh)u={type:"subtask",card:b.id,subtask:p.id,op:"add"}}else{let b=d,p=l.field;if((c||p==="description")&&c!==(b[p]??""))b[p]=c,u={type:"edit",card:b.id,field:p};if(l.fresh)u={type:"add",card:b.id,column:a(b.id).column.id},s.kept=[...s.kept,b.id]}if(u)i(u);let f=n.#a(l.id)??d;if(l.fresh&&l.field==="subtask"&&o)s.addSubtask(f);else if(l.fresh&&l.field==="title"&&o&&!n.hasAttribute("compact"))s.addDetails(f,!0);else n.#P(l)},discard(o){si(s.columns,o)},settle(){if(s.editing)s.commit()},addCard(o){if(s.readonly)return;s.settle();let l={id:Ne(),title:""};o.cards.push(l)
|
|
338
|
+
<span class="b3-visually-hidden" role="status" b3x-text="announcement"></span>`;class pi extends Pe{static observedAttributes=["readonly","search","link-schemes","searchable","expand-in"];#t=null;#e=null;#n=null;#l=null;#o=null;#i=!1;#c=null;#m=null;#r=null;#g=!1;#v=null;#S=0;#w=Math.random().toString(36).slice(2,8);#y=!1;#A=[];#d={past:[],future:[],now:null,key:"",at:0};#h=!1;get columns(){let e=lr(this.#e?.columns??this.#n??[]),t=this.#e?.editing;if(t?.fresh)si(e,t);return e}set columns(e){let t=cr(lr(e));if(!this.#e){this.#n=t;return}this.#p();let r=this.#j();if(r)this.#F(r);let n=this.#e;if(n.editing?.fresh)ga(n.columns,t,n.editing);if(n.columns=t,n.editing&&!this.#a(n.editing.id))n.editing=null;if(!this.#h)this.#d={past:[],future:[],now:null,key:"",at:0};this.#d.now=this.columns}undo(){return this.#_(-1)}openSearch(){if(!this.#e?.searchable)return!1;return this.#e.openSearch(),!0}redo(){return this.#_(1)}get canUndo(){return!this.readonly&&(this.#d.past.length>0||!!this.#e?.editing)}get canRedo(){return!this.readonly&&this.#d.future.length>0}#_(e){let t=this.#e;if(!t||this.readonly)return!1;t.settle();let r=this.#d,i=(e<0?r.past:r.future).pop();if(!i||!r.now)return!1;(e<0?r.future:r.past).push(r.now),r.key="";let a=new Map(t.columns.flatMap((o)=>o.cards.map((l)=>[String(l.id),l.expanded]))),s=cr(lr(i));for(let o of s)for(let l of o.cards){let c=a.get(String(l.id));if(a.has(String(l.id)))if(c===void 0)delete l.expanded;else l.expanded=c}return this.#p(),t.columns=s,r.now=this.columns,this.#s(e<0?"Undone":"Redone"),this.#E({type:e<0?"undo":"redo"}),!0}#E(e){this.#h=!0;try{this.dispatchEvent(new CustomEvent("b3-change",{bubbles:!0,detail:{columns:this.columns,action:e}}))}finally{this.#h=!1}}get filter(){return[...this.#e?.filter??this.#l??[]]}set filter(e){let t=[...e??[]].map((r)=>String(r).toLowerCase());if(this.#e){if(t.join(" ")!==this.#e.filter.join(" "))this.#e.kept=[];this.#e.filter=t}else this.#l=t}get search(){return this.#e?.search??this.#o??""}set search(e){let t=String(e??"");if(this.#e){if(t!==this.#e.search)this.#e.kept=[];this.#e.search=t}else this.#o=t}get defaultColumn(){return this.getAttribute("default-column")??""}set defaultColumn(e){if(e)this.setAttribute("default-column",String(e));else this.removeAttribute("default-column")}get topColumns(){return this.getAttribute("top-columns")??""}set topColumns(e){if(e)this.setAttribute("top-columns",String(e));else this.removeAttribute("top-columns")}onTop(e){return this.topColumns.split(",").map((t)=>t.trim().toLowerCase()).filter(Boolean).some((t)=>x(e.id,t)||String(e.name??"").trim().toLowerCase()===t)}addCard(e){let t=this.#e;if(!t||this.readonly)return!1;let r=e??this.defaultColumn,n=String(r).trim().toLowerCase(),i=r!==""&&(t.columns.find((a)=>x(a.id,r))??t.columns.find((a)=>String(a.name??"").trim().toLowerCase()===n))||(e===void 0?t.columns[0]:void 0);if(!i)return!1;return t.addCard(i),!0}get upload(){return this.#v}set upload(e){this.#v=typeof e==="function"?e:null}get readonly(){return this.hasAttribute("readonly")}set readonly(e){this.toggleAttribute("readonly",!!e)}connectedCallback(){for(let t of["columns","filter","search","defaultColumn","readonly","upload"]){if(!Object.hasOwn(this,t))continue;let r=this[t];delete this[t],this[t]=r}let e=this.ownerDocument;if(!this.#t&&e.readyState==="loading"){if(!this.#i)this.#i=!0,e.addEventListener("DOMContentLoaded",()=>{if(this.#i=!1,this.isConnected)this.connectedCallback()},{once:!0});return}if($e(e,Sa,Aa),ni(),!this.#t){let t=this.querySelector(':scope > script[type="application/json"]'),r=this.#n;if(!r&&t)try{r=cr(JSON.parse(t.textContent||"[]"))}catch(n){console.warn("b3-board: ignoring unreadable JSON data",n)}this.#t=e.createElement("div"),this.#t.className="b3-board-ui",this.append(this.#t),this.#e=ti(this.#t,Ia,this.#C(r??[],this.#l??[],this.#o??this.getAttribute("search")??"")),this.#n=this.#l=this.#o=null,this.#d.now=this.columns}else if(this.#t.parentNode!==this)this.append(this.#t);this.#m=new MutationObserver(()=>{if(this.#t&&this.#t.parentNode!==this)this.append(this.#t)}),this.#m.observe(this,{childList:!0}),this.#K(),mr(this,this.#c.signal,{role:"region"})}disconnectedCallback(){this.#p(),this.#c?.abort(),this.#c=null,this.#$(),this.#m?.disconnect(),this.#m=null}attributeChangedCallback(e,t,r){if(e==="search")return void(this.search=r??"");if(!this.#e)return;if(e==="link-schemes")return void(this.#e.schemes=li(r));if(e==="searchable")return void(this.#e.searchable=r!==null);if(e==="expand-in")return void(this.#e.expandIn=ci(r));if(this.#e.readonly=this.readonly,this.#e.viewed={},this.readonly)this.#p(),this.#e.editing=null}#a(e){for(let t of this.#e?.columns??[]){if(x(t.id,e))return t;for(let r of t.cards)if(x(r.id,e)||C(r).some((n)=>x(n.id,e)))return r}return null}#b(e){let t="card"in e&&e.card!=null&&e.type!=="toggle"&&e.type!=="remove"?this.#a(e.card):null;if(t){if(t.updated=new Date().toISOString(),e.type==="add")t.created=t.updated}let r=this.#d,n=Date.now();if(e.type!=="toggle"){let i=e.type==="edit"?JSON.stringify([e.card,e.column,e.field,e.subtask]):"";if(r.now&&!(i&&i===r.key&&n-r.at<1000)){if(r.past.push(r.now),r.past.length>100)r.past.shift()}r.future=[],r.key=i,r.at=n}r.now=this.columns,this.#E(e)}#C(e,t,r){let n=this,i=(o)=>this.#b(o),a=(o)=>{for(let l of s.columns){let c=l.cards.findIndex((d)=>x(d.id,o));if(c>=0)return{column:l,index:c,card:l.cards[c]}}return null},s=ei({columns:e,filter:t,search:r,kept:[],editing:null,announcement:"",readonly:n.readonly,searchable:n.hasAttribute("searchable"),expandIn:ci(n.getAttribute("expand-in")),searching:!1,schemes:li(n.getAttribute("link-schemes")),viewed:{},selected:null,tokensOf:at,subtasksOf:C,commentsOf:V,hits:oi,said(o){return V(o).some((l)=>oi(s.search,l))},now:Date.now(),ago(o){return ma(o,s.now)},label(o){let l=String(o??"");return l.replace(ba,"").trim()||l},pressed(o){return String(s.filter.includes(o))},mention(o){return o.startsWith("@")?"":null},starred(o){return String(!!o.starred)},hasDetails(o){return!!(o.description||C(o).length||V(o).length)},complete(o){let l=C(o).length;return l>0&&s.done(o)===l},preview(o){let l=String(o.description??"");return l.split(`
|
|
339
|
+
`).map((d)=>di(d,s.schemes)).find((d)=>d.trim())?.trim()??(fr(l,s.schemes).some((d)=>typeof d!=="string"&&d.image)?"Image":"")},plain(o){return di(s.label(o),s.schemes)},rich(o,l){ka(o,String(l??""),s.schemes)},keyText(o,l,c,d){if(o.target!==o.currentTarget||o.key!=="Enter"&&o.key!==" ")return;o.preventDefault(),o.stopPropagation(),s.edit(l,c,d)},isOpen(o){let l=s.viewed[String(o.id)];return s.readonly&&l!==void 0?l:o.expanded??(s.hasDetails(o)&&dr(s.expandIn,s.columns.find((c)=>c.cards.some((d)=>x(d.id,o.id)))))},expanded(o){return String(s.isOpen(o))},isSelected(o){return x(s.selected,o.id)},isEditing(o,l){return!!s.editing&&s.editing.field===o&&s.editing.id===l},focusEditor(o){queueMicrotask(()=>n.#T(o))},blurEditor(o,l){if(s.isEditing(o,l))s.commit()},tokens(){let o=new Set;for(let l of s.columns)for(let c of l.cards)for(let d of at(c))o.add(d);return[...o].sort()},visible(o){let l=bi(s.search);if(!s.filter.length&&!l.length)return o.cards;let c=s.editing&&n.#a(s.editing.id);return o.cards.filter((d)=>{if(d===c||s.kept.some((b)=>x(d.id,b)))return!0;let u=at(d),f=l.length?ya(d):"";return s.filter.every((b)=>u.includes(b))&&l.every((b)=>f.includes(b))})},count(o){let l=s.visible(o).length;return l===o.cards.length?String(l):`${l}/${o.cards.length}`},done(o){return C(o).filter((l)=>l.done).length},disclosable(o){return!!(s.hasDetails(o)||!s.readonly)},toggleFilter(o){s.kept=[],s.filter=s.filter.includes(o)?s.filter.filter((l)=>l!==o):[...s.filter,o]},setFilter(o){s.kept=[],s.filter=o},searchShown(){return s.searching||!!s.search},openSearch(){s.searching=!0;let o=n.querySelector(".b3-board-search-input");if(!o)return;o.hidden=!1,o.closest(".b3-board-filters").hidden=!1,o.focus(),o.select()},typeSearch(o){n.search=o.target.value},keySearch(o){if(o.isComposing||o.keyCode===229)return;if(o.key!=="Escape"&&o.key!=="Enter")return;o.preventDefault(),o.stopPropagation();let l=o.target;if(o.key==="Escape")l.value="",n.search="";l.blur()},blurSearch(){s.searching=!1},toggleStar(o){if(s.readonly)return;if(s.editing)s.commit();let l=a(o.id),c=l?.card;if(!l||!c)return;if(c.starred)delete c.starred;else c.starred=!0;l.column.cards=hi(l.column.cards);let d=!!c.starred;s.announcement=`${c.title??""} ${d?"starred":"unstarred"}`,i({type:"star",card:c.id,starred:d}),n.#B(c.id)},toggle(o){if(s.readonly){s.viewed={...s.viewed,[String(o.id)]:!s.isOpen(o)};return}o.expanded=!s.isOpen(o),i({type:"toggle",card:o.id,expanded:o.expanded})},edit(o,l,c,d=!1,u=!1,f=!1){if(s.readonly||n.#r?.started)return;if(s.editing&&!s.isEditing(o,l))s.commit();s.editing={field:o,id:l,draft:c??"",fresh:d,opened:u,atEnd:f},n.#O()},addDetails(o,l=!1){if(s.readonly)return;let c=!s.isOpen(o);o.expanded=!0,s.edit("description",o.id,String(o.description??""),!1,c,l)},keyEditor(o,l){if(o.stopPropagation(),o.key==="Escape")o.preventDefault(),s.cancel();else if(o.key==="Enter"&&!(l&&o.shiftKey)&&!o.isComposing)o.preventDefault(),s.commit(!0);else if(o.key==="Tab"&&!o.altKey&&!o.metaKey&&!o.ctrlKey&&!o.isComposing&&!n.hasAttribute("compact")){let c=s.editing,d=c?.field==="title"&&!o.shiftKey?"description":c?.field==="description"&&o.shiftKey?"title":null;if(!d)return;o.preventDefault(),s.commit();let u=n.#a(c.id);if(!u||s.readonly)return;if(d==="description")s.addDetails(u,!0);else s.edit("title",u.id,String(u.title??""))}},pasteEditor(o,l,c){let d=[...o.clipboardData?.files??[]].filter((u)=>u.type.startsWith("image/"));if(s.readonly||!n.upload||!["title","description","comment"].includes(l)||!d.length)return;if(o.clipboardData?.getData("text/plain").trim())return;o.preventDefault();for(let u of d)n.#u(c,u,l==="title"?null:o.target,l==="comment"?"comment":"description")},cancel(){let o=s.editing;if(s.editing=null,o?.fresh)s.discard(o);if(o?.opened)s.close(o);n.#P(o)},close(o){let l=n.#a(o.id);if(l&&!s.hasDetails(l))l.expanded=!1},commit(o=!1){let l=s.editing;if(!l)return;if(s.editing=null,s.readonly)return;let c=l.field==="description"||l.field==="comment"?l.draft.trim():l.draft.replace(/\s+/g," ").trim(),d=n.#a(l.id);if(!d)return;if(!c&&l.fresh)return s.discard(l);if(!c&&l.opened)s.close(l);let u=null;if(l.field==="comment"){let b=d;if(c){let p={id:Ne(),at:new Date().toISOString(),by:n.getAttribute("author")||"you",text:c};b.comments=[...V(b),p],u={type:"comment",card:b.id,comment:p.id,op:"add"}}}else if(l.field==="name"){let b=d;if(c&&c!==b.name)b.name=c,u={type:"edit",column:b.id,field:"name"};if(l.fresh)u={type:"add",column:b.id}}else if(l.field==="subtask"){let b=d,p=C(b).find((h)=>x(h.id,l.id));if(!c)return s.removeSubtask(b,p);if(c!==p.title)p.title=c,u={type:"edit",card:b.id,field:"subtask",subtask:p.id};if(l.fresh)u={type:"subtask",card:b.id,subtask:p.id,op:"add"}}else{let b=d,p=l.field;if((c||p==="description")&&c!==(b[p]??""))b[p]=c,u={type:"edit",card:b.id,field:p};if(l.fresh)u={type:"add",card:b.id,column:a(b.id).column.id},s.kept=[...s.kept,b.id]}if(u)i(u);let f=n.#a(l.id)??d;if(l.fresh&&l.field==="subtask"&&o)s.addSubtask(f);else if(l.fresh&&l.field==="title"&&o&&!n.hasAttribute("compact"))s.addDetails(f,!0);else n.#P(l)},discard(o){si(s.columns,o)},settle(){if(s.editing)s.commit()},addCard(o){if(s.readonly)return;s.settle();let l={id:Ne(),title:""};if(n.onTop(o)){let c=o.cards.findIndex((d)=>!d.starred);o.cards.splice(c<0?o.cards.length:c,0,l)}else o.cards.push(l);s.edit("title",l.id,"",!0)},addColumn(){if(s.readonly)return;s.settle();let o={id:Ne(),name:"",cards:[]};s.columns.push(o),s.edit("name",o.id,"",!0)},addSubtask(o){if(s.readonly)return;s.settle();let l={id:Ne(),title:"",done:!1};if(o.expanded=!0,!Array.isArray(o.subtasks))o.subtasks=[];o.subtasks.push(l),s.edit("subtask",l.id,"",!0)},removeCard(o,l){if(s.readonly)return;o.cards=o.cards.filter((c)=>c!==l),i({type:"remove",card:l.id,column:o.id})},removeColumn(o){if(s.readonly)return;s.columns=s.columns.filter((l)=>l!==o),i({type:"remove",column:o.id})},removeSubtask(o,l){if(s.readonly)return;o.subtasks=C(o).filter((c)=>c!==l),i({type:"subtask",card:o.id,subtask:l.id,op:"remove"})},removeComment(o,l){if(s.readonly)return;o.comments=V(o).filter((c)=>c!==l),i({type:"comment",card:o.id,comment:l.id,op:"remove"})},check(o,l,c){if(s.readonly)return;l.done=c,i({type:"check",card:o.id,subtask:l.id,done:c})},keyTags(o){n.#q(o)},keyCard(o,l){if(o.target!==o.currentTarget)return;if(o.key==="Enter")return o.preventDefault(),s.edit("title",l.id,l.title);if(o.metaKey||o.ctrlKey)return;if(!o.altKey)return void n.#M(o,l);if(s.readonly)return;let c=a(l.id);if(!c)return;let d=getComputedStyle(n).direction==="rtl",u={ArrowUp:-1,ArrowDown:1,ArrowLeft:d?1:-1,ArrowRight:d?-1:1}[o.key];if(!u)return;if(o.preventDefault(),o.key==="ArrowUp"||o.key==="ArrowDown"){let b=s.visible(c.column),p=b[b.indexOf(c.card)+u];if(p&&!p.starred===!l.starred)n.moveCard(l.id,c.column.id,c.column.cards.indexOf(p));else n.#D(o.currentTarget,u,!p?u<0?"Already first":"Already last":l.starred?"Starred cards stay above the others — unstar it to move it lower":"Starred cards stay on top — star it to move it among them");return}let f=s.columns[s.columns.indexOf(c.column)+u];if(f)n.moveCard(l.id,f.id,Math.min(c.index,f.cards.length));else n.#D(o.currentTarget,0,"No column there")},keySubtask(o,l,c){s.keyText(o,"subtask",c.id,c.title);let d=o.key==="ArrowUp"?-1:o.key==="ArrowDown"?1:0;if(!o.altKey||!d||s.readonly)return;o.preventDefault(),o.stopPropagation(),n.#k(l,c.id,C(l).indexOf(c)+d)},keyColumn(o,l){if(o.metaKey||o.ctrlKey||o.shiftKey)return;let c=getComputedStyle(n).direction==="rtl",d=o.key==="ArrowLeft"?c?1:-1:o.key==="ArrowRight"?c?-1:1:0;if(!o.altKey){let f=o.currentTarget.closest(".b3-board-column"),b=[...n.querySelectorAll(".b3-board-column")],p=o.key==="ArrowDown"?f.querySelector(".b3-board-card"):d?b[b.indexOf(f)+d]?.querySelector(".b3-board-column-name"):void 0;if(p===void 0)return;if(o.preventDefault(),p)n.#x(p);return}if(!d||s.readonly)return;o.preventDefault();let u=s.columns.indexOf(l)+d;if(u>=0&&u<s.columns.length)n.moveColumn(l.id,u)}});return s}async#u(e,t,r,n="description"){let i=this.#e,a=()=>i.editing?.field===n&&x(i.editing.id,e)?i.editing:null,s=`![Uploading image ${this.#w}-${++this.#S}…]()`,o="",l=a();if(l&&r){let{selectionStart:y,selectionEnd:k}=r;o=y&&r.value[y-1]!==`
|
|
340
340
|
`?`
|
|
341
341
|
${s}`:s,l.draft=r.value=r.value.slice(0,y)+o+r.value.slice(k),r.setSelectionRange(y+o.length,y+o.length),this.#f(r)}let c=i.columns.find((y)=>y.cards.some((k)=>x(k.id,e))),d=null;try{d=await this.#v?.(t,{card:e,column:c?.id})}catch(y){console.warn("b3-board: image upload failed",y)}let u=d?`.replace(/[\s()]/g,(y)=>`%${y.charCodeAt(0).toString(16).toUpperCase().padStart(2,"0")}`)})`:"";if(!u)this.#s("Image not added");while(this.#y)await new Promise((y)=>this.#A.push(y));let f=(y)=>{if(!o)return null;let k=y.indexOf(o),O=k>=0?k:y.indexOf(s);if(O<0)return null;let j=k>=0?o:s;return[O,O+j.length,u?j.replace(s,u):""]},b=(y)=>{if(!o)return u?y.trim()?`${y.replace(/\s+$/,"")}
|
|
342
342
|
${u}`:u:y;let k=f(y);return k?y.slice(0,k[0])+k[2]+y.slice(k[1]):y},p=a();if(p){let y=this.querySelector("textarea.b3-board-editor"),k=y?.value===p.draft&&f(y.value);if(y&&k){let[O,j,lt]=k,{selectionStart:mi,selectionEnd:gi,selectionDirection:yi}=y,hr=(Be)=>Be>=j?Be+lt.length-(j-O):Be>O?O+lt.length:Be;y.setRangeText(lt,O,j),y.setSelectionRange(hr(mi),hr(gi),yi??void 0),p.draft=y.value,this.#f(y)}else if(b(p.draft)!==p.draft)p.draft=b(p.draft);else if(u)this.#s("Image not added");return}if(n==="comment"){let y=i.columns.flatMap((O)=>O.cards).find((O)=>V(O).some((j)=>String(j.text??"").includes(s))),k=y&&V(y).find((O)=>String(O.text??"").includes(s));if(!y||!k||this.readonly){if(u)this.#s("Image not added");return}k.text=b(String(k.text)).trim(),this.#b({type:"edit",card:y.id,field:"comment",comment:k.id});return}let h=this.#a(e);if(o&&!String(h?.description??"").includes(s))h=i.columns.flatMap((y)=>y.cards).find((y)=>String(y.description??"").includes(s))??h;let m=String(h?.description??""),g=b(m).trim();if(!h||this.readonly||g===m.trim()){if(u)this.#s("Image not added");return}h.description=g,h.expanded=!0,this.#b({type:"edit",card:h.id,field:"description"});let S=h.id;requestAnimationFrame(()=>this.#f(this.querySelector(`[data-card="${CSS.escape(String(S))}"]`)))}#f(e){requestAnimationFrame(()=>e?.isConnected&&e.scrollIntoView({block:"nearest",inline:"nearest"}))}#s(e){let t=this.#e;t.announcement="",requestAnimationFrame(()=>{if(!t.announcement)t.announcement=e})}moveCard(e,t,r){let n=this.#e;if(!n||this.readonly)return!1;let i=n.columns.find((u)=>u.cards.some((f)=>x(f.id,e))),a=n.columns.find((u)=>x(u.id,t));if(!i||!a)return!1;let s=i.cards.findIndex((u)=>x(u.id,e)),[o]=i.cards.splice(s,1),l=a.cards.filter((u)=>u.starred).length,c=Math.max(0,Math.min(a.cards.length,r)),d=o.starred?Math.min(c,l):Math.max(c,l);if(a.cards.splice(d,0,o),i===a&&s===d)return!1;if(dr(n.expandIn,i)!==dr(n.expandIn,a))delete o.expanded;return n.announcement=`${o.title??""} moved to ${a.name??""}, position ${d+1} of ${a.cards.length}`,this.#b({type:"move",card:o.id,from:i.id,to:a.id,index:d}),this.#B(o.id),!0}moveColumn(e,t){let r=this.#e;if(!r||this.readonly)return!1;let n=r.columns.findIndex((s)=>x(s.id,e));if(n<0)return!1;let[i]=r.columns.splice(n,1),a=Math.max(0,Math.min(r.columns.length,t));if(r.columns.splice(a,0,i),n===a)return!1;return r.announcement=`${i.name??""} moved to position ${a+1} of ${r.columns.length}`,this.#b({type:"reorder",column:i.id,index:a}),queueMicrotask(()=>this.querySelector(`[data-column="${CSS.escape(String(i.id))}"] .b3-board-column-name`)?.focus()),!0}#k(e,t,r){let n=this.#e,i=C(e),a=i.findIndex((l)=>x(l.id,t));if(!n||this.readonly||a<0)return!1;let s=Math.max(0,Math.min(i.length-1,r));if(a===s)return!1;let[o]=i.splice(a,1);return i.splice(s,0,o),n.announcement=`${o.title??""} moved to position ${s+1} of ${i.length}`,this.#b({type:"subtask",card:e.id,subtask:o.id,op:"move",index:s}),requestAnimationFrame(()=>this.querySelector(`[data-subtask="${CSS.escape(String(o.id))}"] .b3-board-title`)?.focus()),!0}#T(e){if(!e.isConnected)return;if(e.focus({preventScroll:!0}),this.#e?.editing?.atEnd)e.setSelectionRange(e.value.length,e.value.length);else e.select();let t=e.closest(".b3-board-card-head")?e.closest(".b3-board-card"):e.closest(".b3-board-column-header")?e.closest(".b3-board-column"):e.parentElement?.matches(".b3-board-body")?e.parentElement:e,r=()=>t.scrollIntoView({block:"nearest",inline:"nearest"});requestAnimationFrame(r);let n=this.ownerDocument.defaultView;if(!n)return;let i=new AbortController,a=()=>({height:n.visualViewport?.height??n.innerHeight,scale:n.visualViewport?.scale??1}),s=a(),o=()=>{if(!e.isConnected||this.ownerDocument.activeElement!==e)return i.abort();let l=a(),c=l.scale===s.scale&&l.height<s.height;if(s=l,!c)return;if(r(),t!==e)e.scrollIntoView({block:"nearest",inline:"nearest"})};for(let l of[n,n.visualViewport])l?.addEventListener("resize",o,{signal:i.signal});e.addEventListener("blur",()=>i.abort(),{signal:i.signal,once:!0})}#O(){let e=this.ownerDocument,t=e.activeElement;if(!e.defaultView?.matchMedia("(pointer: coarse)").matches||t?.matches("textarea, input"))return;let r=this.#t?.querySelector(":scope > .b3-board-holder");if(!r)r=e.createElement("textarea"),r.className="b3-board-holder",r.tabIndex=-1,r.setAttribute("aria-hidden","true"),this.#t?.append(r);r.focus({preventScroll:!0}),requestAnimationFrame(()=>requestAnimationFrame(()=>{if(e.activeElement===r)r.blur()}))}#x(e){e.focus({preventScroll:!0}),e.scrollIntoView({block:"nearest",inline:"nearest"})}#M(e,t){let r=this.#e,n=e.currentTarget,i=(c)=>[...c.querySelectorAll(".b3-board-cards > .b3-board-card")],a=n.closest(".b3-board-column"),s=i(a),o=s.indexOf(n),l;switch(e.key){case"ArrowUp":if(l=s[o-1],!l&&this.#U())return void e.preventDefault();break;case"ArrowDown":l=s[o+1];break;case"Home":l=s[0];break;case"End":l=s.at(-1);break;case"ArrowLeft":case"ArrowRight":{let c=[...this.querySelectorAll(".b3-board-column")],d=e.key==="ArrowLeft"!==(getComputedStyle(this).direction==="rtl")?-1:1;for(let u=c.indexOf(a)+d;u>=0&&u<c.length&&!l;u+=d){let f=i(c[u]);l=f[Math.min(o,f.length-1)]}break}case" ":if(e.preventDefault(),!this.hasAttribute("compact")&&r.disclosable(t))r.toggle(t);return;case"Delete":case"Backspace":{if(r.readonly||e.shiftKey)return;e.preventDefault();let c=(s[o+1]??s[o-1])?.dataset.card;n.querySelector(":scope > .b3-board-card-head .b3-board-remove")?.click(),requestAnimationFrame(()=>{if(n.isConnected)return;let d=c!==void 0&&this.querySelector(`[data-card="${CSS.escape(c)}"]`),u=this.querySelector(`[data-column="${CSS.escape(a.dataset.column??"")}"] .b3-board-column-name`),f=d||u;if(f)this.#x(f)});return}default:return}if(e.preventDefault(),l)this.#x(l)}#U(){let e=[...this.querySelectorAll(".b3-board-filters > .b3-board-chip")],t=e.find((r)=>r.textContent===this.#L)??e[0];return t?.focus(),!!t}#L=null;#q(e){let t=e.target;if(!t.matches(".b3-board-chip")||e.altKey||e.metaKey||e.ctrlKey)return;let r=[...this.querySelectorAll(".b3-board-filters > .b3-board-chip")],n=r.indexOf(t);if(this.#L=t.textContent,e.key==="ArrowDown"||e.key==="Escape"){e.preventDefault(),this.focusCard();return}if(e.key===" "||e.key==="Enter"){if(e.preventDefault(),!e.repeat)t.click();return}if(e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;e.preventDefault();let i=e.key==="ArrowLeft"!==(getComputedStyle(this).direction==="rtl")?-1:1,a=r[n+i];if(a)this.#L=a.textContent,a.focus()}focusCard(e){let t=(n)=>n!=null&&this.querySelector(`.b3-board-cards > [data-card="${CSS.escape(String(n))}"]`),r=t(e)||t(this.#e?.selected)||this.querySelector(".b3-board-cards > .b3-board-card");if(!r)return!1;return this.#x(r),!0}shortcuts=[];showShortcuts(e=!0){let t=this.#t;if(!t)return!1;let r=t.querySelector(":scope > .b3-board-keys");if(!e){if(r)this.focusCard(),r.remove();return!0}if(r)return!0;let n=/Mac|iP(hone|ad|od)/.test(this.ownerDocument.defaultView?.navigator.platform??""),i=n?"⌥":"Alt+",a=n?"⌘":"Ctrl+",s=[["↑ ↓","Previous / next card"],["↑ (top card)","Filter tags: ← → pick, Space toggle, ↓ back"],["← →","Card in the next column"],["Home End","First / last card"],["Space","Expand / collapse"],["Enter","Edit the title"],...this.readonly?[]:[[`${i}↑ ${i}↓`,"Move the card up / down"],[`${i}← ${i}→`,"Move the card to the next column"],["Tab ⇧Tab","Editing: title ⇄ details"],["Delete","Delete the card (press twice)"],[`${a}Z ${n?"⇧⌘Z":"Ctrl+Y"}`,"Undo / redo"]],...this.shortcuts,["Esc","Cancel / close"],["?","This list"]];r=this.ownerDocument.createElement("div"),r.className="b3-board-keys",r.tabIndex=-1,r.setAttribute("role","dialog"),r.setAttribute("aria-label","Keyboard shortcuts");let o=this.ownerDocument.createElement("dl");for(let[l,c]of s){let d=this.ownerDocument.createElement("div"),u=this.ownerDocument.createElement("dt"),f=this.ownerDocument.createElement("dd");for(let b of l.split(" ")){let p=this.ownerDocument.createElement("kbd");p.textContent=b,u.append(p)}f.textContent=c,d.append(u,f),o.append(d)}return r.append(o),r.addEventListener("keydown",(l)=>{if(l.key!=="Escape"&&l.key!=="?")return;l.preventDefault(),l.stopPropagation(),this.showShortcuts(!1)}),r.addEventListener("focusout",(l)=>{if(!r.contains(l.relatedTarget))queueMicrotask(()=>r.remove())}),t.append(r),r.focus({preventScroll:!0}),!0}#j(){let e=this.ownerDocument.activeElement;if(!e?.matches(".b3-board-card")||!this.contains(e))return null;let t=e.closest(".b3-board-column");return{id:e.dataset.card,column:t.dataset.column,index:[...t.querySelectorAll(".b3-board-cards > .b3-board-card")].indexOf(e)}}#F(e){requestAnimationFrame(()=>{let t=this.ownerDocument.activeElement;if(t&&t!==this.ownerDocument.body&&t.isConnected)return;let r=[...this.querySelectorAll(`[data-column="${CSS.escape(e.column)}"] .b3-board-cards > .b3-board-card`)];(this.querySelector(`[data-card="${CSS.escape(e.id)}"]`)??r[Math.min(e.index,r.length-1)])?.focus({preventScroll:!0})})}#D(e,t,r){e.style.setProperty("--b3-board-bump",String(t)),e.removeAttribute("data-b3-bump"),e.offsetWidth,e.setAttribute("data-b3-bump",""),e.addEventListener("animationend",()=>e.removeAttribute("data-b3-bump"),{once:!0}),this.#s(r)}#N(){let e=this.ownerDocument,t=e.activeElement;if(!this.#I||!this.#e?.selected||t&&t!==e.body&&t!==e.documentElement)return;this.querySelector(`.b3-board-cards > [data-card="${CSS.escape(String(this.#e.selected))}"]`)?.focus({preventScroll:!0})}#B(e){requestAnimationFrame(()=>this.querySelector(`[data-card="${CSS.escape(String(e))}"]`)?.focus({preventScroll:!1}))}#P(e){if(!e)return;let t=CSS.escape(String(e.id));requestAnimationFrame(()=>{if(this.contains(this.ownerDocument.activeElement)&&this.ownerDocument.activeElement!==this.ownerDocument.body)return;let r=e.field==="name"?`[data-column="${t}"] .b3-board-column-name`:e.field==="subtask"?null:`[data-card="${t}"]`;if(r)this.querySelector(r)?.focus({preventScroll:!0})})}#I=!1;#K(){this.#c?.abort(),this.#c=new AbortController;let e=this.#c.signal,t=this.ownerDocument.defaultView,r=t.setInterval(()=>{if(this.#e)this.#e.now=Date.now()},60000);e.addEventListener("abort",()=>t.clearInterval(r)),this.addEventListener("pointerdown",(a)=>this.#Y(a),{signal:e}),this.addEventListener("mousedown",(a)=>{if(this.#e?.editing&&a.target.closest?.(".b3-board-actions > button, .b3-board-star")&&this.contains(this.ownerDocument.activeElement))a.preventDefault()},{signal:e,capture:!0}),t.addEventListener("pointermove",(a)=>this.#J(a),{signal:e}),t.addEventListener("pointerup",(a)=>this.#G(a),{signal:e}),t.addEventListener("pointercancel",(a)=>{if(a.pointerId===this.#r?.pointerId)this.#p()},{signal:e}),t.addEventListener("keydown",(a)=>{if(a.key==="Escape"&&this.#r?.started)a.preventDefault(),this.#p()},{signal:e}),this.addEventListener("touchmove",(a)=>{if(this.#r?.started)a.preventDefault()},{signal:e,passive:!1}),this.addEventListener("contextmenu",(a)=>{if(this.#r)a.preventDefault()},{signal:e}),this.addEventListener("focusin",(a)=>{let s=a.target,o=s.parentElement;if(!o?.matches(".b3-board-filters"))return;o.style.scrollPaddingInlineEnd=`${o.querySelector(":scope > .b3-board-search")?.offsetWidth??0}px`,s.scrollIntoView({inline:"nearest",block:"nearest"})},{signal:e}),this.addEventListener("focusin",(a)=>{this.#I=!0;let s=a.target.closest?.(".b3-board-card");if(s&&this.#e&&this.contains(s))this.#e.selected=s.dataset.card??null},{signal:e}),this.addEventListener("focusout",(a)=>{let s=a.relatedTarget;if(s&&!this.contains(s)){this.#I=!1;return}if(!s)requestAnimationFrame(()=>requestAnimationFrame(()=>this.#N()))},{signal:e}),t.addEventListener("focus",()=>queueMicrotask(()=>this.#N()),{signal:e}),this.addEventListener("click",(a)=>{let s=this.ownerDocument.getSelection(),o=a.target;if(!this.#g&&s&&!s.isCollapsed&&(o.contains(s.anchorNode)||s.containsNode(o,!0))&&!o.closest?.("button, .b3-board-grip, .b3-board-card-head>.b3-board-title")){a.preventDefault(),a.stopImmediatePropagation();return}if(!this.#g)return;this.#g=!1,a.preventDefault(),a.stopImmediatePropagation()},{signal:e,capture:!0}),this.addEventListener("keydown",(a)=>{if(a.key!=="?"||a.defaultPrevented||a.metaKey||a.ctrlKey||a.altKey||a.isComposing)return;if(a.target.closest?.('input, textarea, select, [contenteditable]:not([contenteditable="false"]), .b3-board-keys'))return;a.preventDefault(),this.showShortcuts()},{signal:e}),this.addEventListener("keydown",(a)=>{if(a.defaultPrevented||a.altKey||!(a.metaKey||a.ctrlKey))return;if(a.target.closest?.('input, textarea, select, [contenteditable]:not([contenteditable="false"])'))return;let s=a.key.toLowerCase(),o=s==="y"||s==="z"&&a.shiftKey;if(s!=="z"&&s!=="y")return;if(a.preventDefault(),o)this.redo();else this.undo()},{signal:e});let n=(a)=>this.#V(a);this.addEventListener("click",n,{signal:e,capture:!0}),this.addEventListener("auxclick",(a)=>{if(a.button===1)n(a)},{signal:e,capture:!0});let i=()=>this.#$();this.addEventListener("compositionstart",()=>{this.#y=!0},{signal:e}),this.addEventListener("compositionend",i,{signal:e}),this.addEventListener("focusout",i,{signal:e})}#$(){this.#y=!1;for(let e of this.#A.splice(0))e()}#V(e){let t=e.target.closest?.("a.b3-board-ref");if(!t||!this.contains(t))return;e.stopPropagation();let r=(c)=>t.closest(c),n=this.#e?.columns.find((c)=>x(c.id,r("[data-column]")?.dataset.column)),i=n?.cards.find((c)=>x(c.id,r("[data-card]")?.dataset.card)),a=i&&C(i).find((c)=>x(c.id,r("[data-subtask]")?.dataset.subtask)),s={href:t.dataset.href??"",text:t.textContent??"",file:t.hasAttribute("data-file"),newTab:e.metaKey||e.ctrlKey||e.shiftKey||e.button===1,card:i?.id,column:n?.id};if(a)s.subtask=a.id;let o=t.querySelector("img");if(o&&!s.newTab&&e.type==="click"){e.preventDefault(),this.#W(t,o,s);return}if(!t.dispatchEvent(new CustomEvent("b3-link",{bubbles:!0,cancelable:!0,detail:s}))||s.file)e.preventDefault()}#W(e,t,r){let n=this.ownerDocument;n.body.querySelector(":scope > .b3-board-lightbox")?.dispatchEvent(new CustomEvent("b3-close")),ar();let i=n.createElement("b3-image-viewer");i.className="b3-board-lightbox",i.setAttribute("alt",t.alt||"Image"),i.setAttribute("role","dialog"),i.setAttribute("aria-modal","true");let a=n.createElement("img");a.src=t.currentSrc||t.src,a.alt=t.alt;let s=n.createElement("button");s.type="button",s.className="b3-board-lightbox-open",s.textContent="Open",i.append(a,s);let o=n.activeElement,l=[...n.body.children].filter((d)=>d instanceof HTMLElement&&!d.inert),c=()=>{i.remove();for(let d of l)d.inert=!1;if(e.isConnected)e.focus({preventScroll:!0});else o?.focus?.({preventScroll:!0})};i.addEventListener("b3-close",c),i.addEventListener("click",(d)=>{if(d.target===i)c()}),s.addEventListener("pointerdown",(d)=>d.stopPropagation()),s.addEventListener("click",(d)=>{if(d.stopPropagation(),c(),e.dispatchEvent(new CustomEvent("b3-link",{bubbles:!0,cancelable:!0,detail:{...r}}))&&!r.file)this.ownerDocument.defaultView?.open(r.href,"_blank","noopener")}),n.body.append(i);for(let d of l)d.inert=!0;i.setAttribute("open",""),i.focus({preventScroll:!0})}#Y(e){if(this.readonly||this.#r||!e.isPrimary||e.button!==0||this.#e?.editing)return;let t=e.target,r=t.closest(".b3-board-subtask-grip")?.closest(".b3-board-subtask"),n;if(r)n={kind:"subtask",id:r.dataset.subtask,card:r.closest(".b3-board-card").dataset.card,node:r,pointerId:e.pointerId,x:e.clientX,y:e.clientY,started:!1,hold:0};else{if(t.closest("input, textarea, select, a, .b3-board-quiet, .b3-board-chip, .b3-board-link, .b3-board-toggle, .b3-board-description"))return;let i=t.closest(".b3-board-grip, .b3-board-card-head>.b3-board-title")?t.closest(".b3-board-card"):null;if(!i&&t.closest(".b3-board-card"))return;let a=!i&&t.closest(".b3-board-column-header")?t.closest(".b3-board-column"):null,s=i??a;if(!s)return;n={kind:i?"card":"column",id:i?i.dataset.card:a.dataset.column,node:s,pointerId:e.pointerId,x:e.clientX,y:e.clientY,started:!1,hold:0}}if(!this.contains(n.node))return;if(this.#r=n,e.pointerType!=="mouse")n.hold=window.setTimeout(()=>{if(this.#r===n)this.#R(e.clientX,e.clientY)},pa)}#R(e,t){let r=this.#r;r.started=!0;let n=r.node.getBoundingClientRect(),i=r.node.cloneNode(!0);i.classList.add("b3-board-ghost"),i.removeAttribute("data-b3-dragging");for(let s of[i,...i.querySelectorAll("[id]")])s.removeAttribute("id");i.setAttribute("aria-hidden","true"),Object.assign(i.style,{inlineSize:`${n.width}px`,left:`${n.left}px`,top:`${n.top}px`}),r.dx=e-n.left,r.dy=t-n.top,r.ghost=i,this.#t.append(i),r.node.setAttribute("data-b3-dragging",""),this.ownerDocument.getSelection()?.removeAllRanges(),r.px=e,r.py=t;let a=()=>{if(this.#r!==r)return;this.#Z(r.px,r.py),this.#X(this.#H(r.px,r.py)),r.frame=requestAnimationFrame(a)};r.frame=requestAnimationFrame(a)}#J(e){let t=this.#r;if(!t||e.pointerId!==t.pointerId)return;if(!t.started){let r=Math.hypot(e.clientX-t.x,e.clientY-t.y);if(e.pointerType!=="mouse"){if(r>8)this.#p();return}if(r<5)return;this.#R(e.clientX,e.clientY)}e.preventDefault(),t.ghost.style.left=`${e.clientX-t.dx}px`,t.ghost.style.top=`${e.clientY-t.dy}px`,t.px=e.clientX,t.py=e.clientY}#G(e){let t=this.#r;if(!t||e.pointerId!==t.pointerId)return;if(!t.started)return this.#p();let r=this.#H(e.clientX,e.clientY);if(this.#p(),this.#g=!0,setTimeout(()=>{this.#g=!1},0),!r)return;let n=this.#e;if(t.kind==="card"){let i=n.columns.find((l)=>x(l.id,r.column)),a=n.columns.find((l)=>l.cards.some((c)=>x(c.id,t.id))),s=r.before?i.cards.findIndex((l)=>x(l.id,r.before)):i.cards.length,o=a.cards.findIndex((l)=>x(l.id,t.id));if(a===i&&o<s)s-=1;this.moveCard(t.id,i.id,s)}else if(t.kind==="subtask"){let i=this.#a(t.card);if(!i)return;let a=C(i),s=r.before?a.findIndex((o)=>x(o.id,r.before)):a.length;if(a.findIndex((o)=>x(o.id,t.id))<s)s-=1;this.#k(i,t.id,s)}else{let i=r.before?n.columns.findIndex((s)=>x(s.id,r.before)):n.columns.length;if(n.columns.findIndex((s)=>x(s.id,t.id))<i)i-=1;this.moveColumn(t.id,i)}}#H(e,t){let r=this.#r,n=this.ownerDocument.elementFromPoint(e,t);if(!n||!this.contains(n))return null;if(r.kind==="card"){let l=this.#z(e,n);if(!l)return null;let c=l.querySelector(".b3-board-cards"),d=[...c.querySelectorAll(":scope > .b3-board-card:not([data-b3-dragging])")],u=d.find((b)=>{let p=b.getBoundingClientRect();return t<p.top+p.height/2}),f=(b)=>!!(b!=null&&this.#a(b)?.starred);if(f(u?.dataset.card)!==f(r.id)&&(u||f(r.id)))u=d.find((b)=>!f(b.dataset.card));return{column:l.dataset.column,before:u?.dataset.card??null,list:c}}if(r.kind==="subtask"){let l=r.node.parentElement;return{column:"",before:[...l.querySelectorAll(":scope > .b3-board-subtask:not([data-b3-dragging])")].find((u)=>{let f=u.getBoundingClientRect();return t<f.top+f.height/2})?.dataset.subtask??null,list:l}}let i=this.querySelector(".b3-board-columns"),a=[...i.querySelectorAll(":scope > .b3-board-column:not([data-b3-dragging])")],s=getComputedStyle(this).direction==="rtl";return{column:"",before:a.find((l)=>{let c=l.getBoundingClientRect();return s?e>c.left+c.width/2:e<c.left+c.width/2})?.dataset.column??null,list:i}}#X(e){for(let n of this.querySelectorAll("[data-b3-drop]"))n.removeAttribute("data-b3-drop");if(!e)return;let t=`[data-${this.#r.kind}="${CSS.escape(e.before??"")}"]`,r=e.before?e.list.querySelector(t):null;(r??e.list).setAttribute("data-b3-drop",r?"before":"end")}#z(e,t){return t?.closest(".b3-board-column")??[...this.querySelectorAll(".b3-board-column")].find((r)=>{let n=r.getBoundingClientRect();return e>=n.left&&e<=n.right})}#Z(e,t){let r=(s,o,l)=>s<o+40?-12:s>l-40?12:0,n=this.querySelector(".b3-board-columns");if(n){let s=n.getBoundingClientRect();n.scrollLeft+=r(e,s.left,s.right)}let i=this.#r?.kind==="card"?this.#z(e,this.ownerDocument.elementFromPoint(e,t))?.querySelector(".b3-board-cards"):null;if(i&&i.scrollHeight>i.clientHeight){let s=i.getBoundingClientRect();i.scrollTop+=r(t,s.top,s.bottom)}let a=this.ownerDocument.defaultView;a.scrollBy(0,r(t,0,a.innerHeight))}#p(){let e=this.#r;if(!e)return;this.#r=null,clearTimeout(e.hold),cancelAnimationFrame(e.frame??0),e.ghost?.remove(),e.node.removeAttribute("data-b3-dragging");for(let t of this.querySelectorAll("[data-b3-drop]"))t.removeAttribute("data-b3-drop")}}pr("b3-board",pi);export{pi as B3Board};
|
package/dist/manifest.json
CHANGED
|
@@ -17,10 +17,14 @@ Always author the `<audio>` yourself: it is the degraded experience and stays th
|
|
|
17
17
|
Set `audio.src`, `audio.currentTime`, call `audio.play()` from your code — the controls follow.
|
|
18
18
|
A replaced `<audio>` child is re-mounted.
|
|
19
19
|
|
|
20
|
+
The element is a size container (it fills its line; the controls fold by its own width). As a
|
|
21
|
+
grid item, give the track a size (`grid-template-columns: minmax(0, 1fr)`): an `auto` track
|
|
22
|
+
sizes a container to zero.
|
|
23
|
+
|
|
20
24
|
| Attribute | Meaning |
|
|
21
25
|
| --- | --- |
|
|
22
26
|
| `skip` | Seconds the back/forward buttons move (default 15). |
|
|
23
27
|
|
|
24
|
-
Events: `b3-error` (bubbles) when `play()` is refused.
|
|
25
|
-
|
|
28
|
+
Events: `b3-error` (bubbles) when `play()` is refused. Narrow (a phone bar) drops speed under ~22rem
|
|
29
|
+
and skip under ~14rem; play, seek and time always stay. `clock(seconds)` (m:ss / h:mm:ss) is exported for matching
|
|
26
30
|
timestamps elsewhere on the page.
|
package/dist/references/board.md
CHANGED
|
@@ -120,6 +120,8 @@ typed, and a `b3-change` listener receives `CustomEvent<BoardChangeDetail>` (`b3
|
|
|
120
120
|
does; it is reported once named. With no argument it uses `default-column` (`board.defaultColumn`, an
|
|
121
121
|
id or name), else the first column. Returns false when readonly or the column does not exist. Wire it
|
|
122
122
|
to the host's own shortcut, e.g. `default-column="TODO"` and N.
|
|
123
|
+
- **Newest on top**: `top-columns="Backlog,Done"` (`board.topColumns`, ids or names) — a new card there
|
|
124
|
+
(addCard or the column's +) starts on top, under any starred cards.
|
|
123
125
|
- **Links**: `[text](target)` and bare `http(s)://` URLs in a title, description or subtask render as
|
|
124
126
|
links, built as DOM nodes (never as HTML). Only http, https, mailto, paths and the schemes named in the
|
|
125
127
|
`link-schemes` attribute (e.g. `link-schemes="bare"` for `bare://…`; space or comma separated) link; any other scheme,
|
|
@@ -158,7 +160,7 @@ typed, and a `b3-change` listener receives `CustomEvent<BoardChangeDetail>` (`b3
|
|
|
158
160
|
|
|
159
161
|
## Attributes and styling
|
|
160
162
|
|
|
161
|
-
- `search`, `searchable`, `default-column`, `link-schemes`: see Search, Add and Links above.
|
|
163
|
+
- `search`, `searchable`, `default-column`, `top-columns`, `link-schemes`: see Search, Add and Links above.
|
|
162
164
|
- `expand-in="Doing"`: column names (comma separated, any case) whose cards with details show them open by default.
|
|
163
165
|
A card's own `expanded` (`true` or `false`) still wins; moving a card into or out of such a column clears it, so it
|
|
164
166
|
takes the new column's default.
|