@thebase/ui 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +49 -8
  3. package/bin/create-baseui-app.mjs +268 -0
  4. package/dist/baseui.esm.js +1 -1
  5. package/dist/baseui.min.js +1 -1
  6. package/dist/baseui.registry.json +2 -2
  7. package/dist/runtime/block-N5MIBOMO.js +1 -0
  8. package/dist/runtime/chunk-23NN352E.js +1 -0
  9. package/dist/runtime/chunk-6X7NT7KH.js +2 -0
  10. package/dist/runtime/chunk-7R5G6FRT.js +1 -0
  11. package/dist/runtime/chunk-7R75J74M.js +1 -0
  12. package/dist/runtime/chunk-EAFZBBCI.js +10 -0
  13. package/dist/runtime/chunk-GF2LJCG5.js +1 -0
  14. package/dist/runtime/chunk-HKUJH2VC.js +1 -0
  15. package/dist/runtime/chunk-KX3KYRT7.js +1 -0
  16. package/dist/runtime/chunk-MAWHENWJ.js +1 -0
  17. package/dist/runtime/chunk-OESZ7FEN.js +1 -0
  18. package/dist/runtime/chunk-P3WV3MLS.js +35 -0
  19. package/dist/runtime/chunk-SGGMD6DA.js +5 -0
  20. package/dist/runtime/chunk-URTGZHMG.js +3 -0
  21. package/dist/runtime/chunk-XLIC2WFB.js +1 -0
  22. package/dist/runtime/clipboard-6EHVQ6GB.js +4 -0
  23. package/dist/runtime/commonmark-FAT3C7WA.js +1 -0
  24. package/dist/runtime/core-IEFFKRMW.js +1 -0
  25. package/dist/runtime/cursor-3BFXMKNC.js +1 -0
  26. package/dist/runtime/diff-ALMDXB3Z.js +1 -0
  27. package/dist/runtime/gfm-JUXF3E6O.js +5 -0
  28. package/dist/runtime/history-OU6CQBOY.js +1 -0
  29. package/dist/runtime/indent-RP5Y5HNK.js +1 -0
  30. package/dist/runtime/lib-TTIE4EGJ.js +1 -0
  31. package/dist/runtime/listener-JBODN3BE.js +1 -0
  32. package/dist/runtime/marked.min.js +69 -0
  33. package/dist/runtime/mermaid.esm.min.mjs +3593 -0
  34. package/dist/runtime/milkdown-editor.js +1 -0
  35. package/dist/runtime/prosemirror-text-editor.js +1 -0
  36. package/dist/runtime/slash-I56NP4SS.js +1 -0
  37. package/dist/runtime/streaming-WPAF6YN6.js +3 -0
  38. package/dist/runtime/tooltip-XDWVKIO5.js +1 -0
  39. package/dist/runtime/upload-MYBCHYBD.js +1 -0
  40. package/dist/runtime/y-webrtc-WDTQEBWZ.js +1 -0
  41. package/dist/runtime/yjs-SRZJJJEG.js +1 -0
  42. package/docs/blocks.md +4 -2
  43. package/docs/icons.md +4 -2
  44. package/docs/installation.md +36 -28
  45. package/docs/owl-components.md +7 -5
  46. package/docs/theming.md +2 -2
  47. package/docs/usage-guide.md +64 -60
  48. package/package.json +6 -1
@@ -0,0 +1 @@
1
+ import"./chunk-23NN352E.js";async function le({root:e,value:o="",onChange:t,collaborative:r=!1,room:s="baseui-markdown",password:i,signaling:m,user:w}={}){if(!e)throw new Error("BaseUI markdown editor: missing root element.");let[C,M,T,U,D,F,I,N,W,x,K,O,R,_]=await Promise.all([import("./core-IEFFKRMW.js"),import("./commonmark-FAT3C7WA.js"),import("./gfm-JUXF3E6O.js"),import("./history-OU6CQBOY.js"),import("./clipboard-6EHVQ6GB.js"),import("./cursor-3BFXMKNC.js"),import("./indent-RP5Y5HNK.js"),import("./upload-MYBCHYBD.js"),import("./block-N5MIBOMO.js"),import("./tooltip-XDWVKIO5.js"),import("./slash-I56NP4SS.js"),import("./streaming-WPAF6YN6.js"),import("./diff-ALMDXB3Z.js"),import("./listener-JBODN3BE.js")]),{Editor:j,defaultValueCtx:L,rootCtx:V}=C,{commonmark:q}=M,{gfm:z}=T,{history:G}=U,{clipboard:H}=D,{cursor:J}=F,{indent:Q}=I,{upload:X}=N,{block:Y,BlockProvider:h}=W,{tooltipFactory:Z,TooltipProvider:$}=x,{slashFactory:ee,SlashProvider:te}=K,{streaming:oe}=O,{diff:re}=R,{listener:ne,listenerCtx:se}=_,v=Z("BASEUI_MARKDOWN"),S=ee("BASEUI_MARKDOWN"),a=[],c=j.make().config(n=>{n.set(V,e),n.set(L,String(o??"")),n.set(v.key,ae(e,$)),n.set(S.key,ce(e,te)),n.get(se).markdownUpdated((f,l,d)=>{l!==d&&t?.(l,d,f)})}).use(q).use(z).use(H).use(J).use(Q).use(X).use(Y).use(v).use(S).use(oe).use(re).use(ne);if(r){let[{Doc:n},{WebrtcProvider:f},l]=await Promise.all([import("./yjs-SRZJJJEG.js"),import("./y-webrtc-WDTQEBWZ.js"),import("./lib-TTIE4EGJ.js")]),{collab:d,collabServiceCtx:ie}=l,u=new n,g={};i&&(g.password=i),Array.isArray(m)&&m.length&&(g.signaling=m);let p=new f(s,u,g),P=w&&typeof w=="object"?w:{};p.awareness?.setLocalStateField("user",{name:P.name||"Anonymous",color:P.color||"#2563eb",...P}),c.use(d),a.push(()=>p.destroy?.(),()=>u.destroy());let b=await c.create();return b.action(A=>{E(A,e,h,a),A.get(ie).bindDoc(u).setAwareness(p.awareness).applyTemplate(String(o??"")).connect()}),{editor:b,provider:p,doc:u,destroy:()=>B(b,a)}}c.use(G);let y=await c.create();return y.action(n=>E(n,e,h,a)),{editor:y,provider:null,doc:null,destroy:()=>B(y,a)}}function k(e,o=""){let t=document.createElement("div");return t.className=e,t.textContent=o,t.setAttribute("aria-hidden","true"),t}function ae(e,o){return{view:t=>{let r=new o({root:e,content:k("baseui-markdown-editor-tooltip","Markdown tools")});return r.update(t),{update:(s,i)=>r.update(s,i),destroy:()=>r.destroy()}}}}function ce(e,o){return{view:t=>{let r=new o({root:e,content:k("baseui-markdown-editor-slash","Type Markdown syntax")});return r.update(t),{update:(s,i)=>r.update(s,i),destroy:()=>r.destroy()}}}}function E(e,o,t,r){let s=new t({ctx:e,root:o,content:k("baseui-markdown-editor-block-handle","::")});s.update(),r.push(()=>s.destroy())}function B(e,o){for(let t of o)t();e.destroy()}export{le as createMilkdownMarkdownEditor};
@@ -0,0 +1 @@
1
+ import{d as Z}from"./chunk-6X7NT7KH.js";import{d as ee,g as te,h as oe,k as H,l as E,m as ne}from"./chunk-KX3KYRT7.js";import"./chunk-XLIC2WFB.js";import{da as J}from"./chunk-SGGMD6DA.js";import{a as X,b as j,c as K,d as _,e as V,f as L,g as S}from"./chunk-7R5G6FRT.js";import{a as Y,b as v,c as D}from"./chunk-HKUJH2VC.js";import{D as w,E as W,F as R,G as y,H as d,I as G,J as T,K as A,O as Q,f as z,g as B,h as N,w as $,x as F}from"./chunk-EAFZBBCI.js";import"./chunk-23NN352E.js";var n=new z({nodes:{doc:{content:"block+"},paragraph:{content:"inline*",group:"block",parseDOM:[{tag:"p"}],toDOM:()=>["p",0]},blockquote:{content:"block+",group:"block",parseDOM:[{tag:"blockquote"}],toDOM:()=>["blockquote",0]},heading:{attrs:{level:{default:1}},content:"inline*",group:"block",defining:!0,parseDOM:[1,2].map(e=>({tag:`h${e}`,attrs:{level:e}})),toDOM:e=>[`h${e.attrs.level}`,0]},code_block:{content:"text*",group:"block",code:!0,defining:!0,marks:"",parseDOM:[{tag:"pre",preserveWhitespace:"full"}],toDOM:()=>["pre",["code",0]]},text:{group:"inline"},hard_break:{inline:!0,group:"inline",selectable:!1,parseDOM:[{tag:"br"}],toDOM:()=>["br"]},bullet_list:j,ordered_list:X,list_item:K},marks:{strong:{parseDOM:[{tag:"strong"},{tag:"b",getAttrs:e=>e.style.fontWeight!=="normal"&&null}],toDOM:()=>["strong",0]},em:{parseDOM:[{tag:"i"},{tag:"em"},{style:"font-style=italic"}],toDOM:()=>["em",0]},code:{parseDOM:[{tag:"code"}],toDOM:()=>["code",0]},link:{attrs:{href:{},title:{default:null}},inclusive:!1,parseDOM:[{tag:"a[href]",getAttrs:e=>({href:e.getAttribute("href"),title:e.getAttribute("title")})}],toDOM:e=>["a",{href:e.attrs.href,title:e.attrs.title,rel:"noreferrer noopener"},0]}}}),ae=[[{name:"bold",label:"B",title:"Bold",command:d(n.marks.strong),active:e=>h(e,n.marks.strong)},{name:"italic",label:"I",title:"Italic",command:d(n.marks.em),active:e=>h(e,n.marks.em)},{name:"code",label:"</>",title:"Code",command:d(n.marks.code),active:e=>h(e,n.marks.code)}],[{name:"paragraph",label:"P",title:"Paragraph",command:y(n.nodes.paragraph),active:e=>f(e,n.nodes.paragraph)},{name:"h1",label:"H1",title:"Heading 1",command:y(n.nodes.heading,{level:1}),active:e=>f(e,n.nodes.heading,{level:1})},{name:"h2",label:"H2",title:"Heading 2",command:y(n.nodes.heading,{level:2}),active:e=>f(e,n.nodes.heading,{level:2})},{name:"quote",label:"Q",title:"Quote",command:R(n.nodes.blockquote),active:e=>f(e,n.nodes.blockquote)}],[{name:"bullet-list",label:"*",title:"Bullet list",command:_(n.nodes.bullet_list),active:e=>f(e,n.nodes.bullet_list)},{name:"ordered-list",label:"1.",title:"Numbered list",command:_(n.nodes.ordered_list),active:e=>f(e,n.nodes.ordered_list)},{name:"link",label:"A",title:"Link",command:me,active:e=>h(e,n.marks.link)}]];function Oe({root:e,value:t="",onChange:o,collaborative:r=!1,room:s="baseui-text-editor",password:i,signaling:g,user:ie,placeholder:b}={}){if(!e)throw new Error("BaseUI text editor: missing root element.");e.replaceChildren();let m=document.createElement("div");m.className="baseui-text-editor-toolbar",m.setAttribute("role","toolbar"),m.setAttribute("aria-label","Text formatting");let k=document.createElement("div");k.className="baseui-text-editor-surface",b&&k.setAttribute("data-placeholder",b),e.append(m,k);let P=[],q=re(t),u=null,p=null,M="",x=[A({"Mod-b":d(n.marks.strong),"Mod-i":d(n.marks.em),"Mod-z":r?H:v,"Mod-y":r?E:D,"Shift-Mod-z":r?E:D,Enter:G(V(n.nodes.list_item),T.Enter),Tab:S(n.nodes.list_item),"Shift-Tab":L(n.nodes.list_item),"Mod-]":S(n.nodes.list_item),"Mod-[":L(n.nodes.list_item),"Shift-Enter":W,"Alt-ArrowUp":w}),A(T),pe(b)];if(r){p=new J;let l=p.getXmlFragment("prosemirror");l.length===0&&te(q,l);let c={};i&&(c.password=i),Array.isArray(g)&&g.length&&(c.signaling=g),u=new Z(s,p,c),u.awareness?.setLocalStateField("user",ce(ie)),x.push(ee(l),oe(u.awareness),ne()),P.push(()=>u.destroy?.(),()=>p.destroy())}else x.push(Y());let a;return a=new Q(k,{state:$.create({doc:r?void 0:q,schema:n,plugins:x}),dispatchTransaction(l){if(!a)return;let c=a.state.apply(l);a.updateState(c),se(m,a);let O=U(a.state.doc),le=O!==M;if(I(e,a,b),le){let de=M;M=O,o?.(O,de,{view:a,provider:u,doc:p})}}}),M=U(a.state.doc),ue(m,a,r?{undo:H,redo:E}:{undo:v,redo:D}),I(e,a,b),{view:a,provider:u,doc:p,focus:()=>a.focus(),getHTML:()=>U(a.state.doc),setHTML:l=>{let c=re(l);a.dispatch(a.state.tr.replaceWith(0,a.state.doc.content.size,c.content))},destroy:()=>{for(let l of P)l();a.destroy(),e.replaceChildren()}}}function re(e){let t=document.createElement("div");return t.innerHTML=String(e||"").trim()||"<p></p>",B.fromSchema(n).parse(t)}function U(e){let t=N.fromSchema(n).serializeFragment(e.content),o=document.createElement("div");return o.append(t),o.innerHTML}function ce(e){let t=e&&typeof e=="object"?e:{};return{name:t.name||"Anonymous",color:t.color||"#2563eb",...t}}function h(e,t){let{from:o,$from:r,to:s,empty:i}=e.selection;return i?!!t.isInSet(e.storedMarks||r.marks()):e.doc.rangeHasMark(o,s,t)}function f(e,t,o={}){let{$from:r,to:s,node:i}=e.selection;return i?i.hasMarkup(t,o):s<=r.end()&&r.parent.hasMarkup(t,o)}function me(e,t){if(h(e,n.marks.link))return d(n.marks.link)(e,t);if(!t)return!0;let o=e.selection.$from.marks().find(s=>s.type===n.marks.link),r=window.prompt("Enter link URL",o?.attrs.href||"");return r?d(n.marks.link,{href:r})(e,t):!1}function ue(e,t,o){e.replaceChildren(),e._baseuiTextEditorUndo=o.undo,e._baseuiTextEditorRedo=o.redo;for(let s of ae){let i=document.createElement("div");i.className="baseui-text-editor-toolbar-group";for(let g of s)i.append(C(g,t));e.append(i)}let r=document.createElement("div");r.className="baseui-text-editor-toolbar-group",r.append(C({name:"undo",label:"Undo",title:"Undo",command:o.undo},t),C({name:"redo",label:"Redo",title:"Redo",command:o.redo},t)),e.append(r),se(e,t)}function C(e,t){let o=document.createElement("button");return o.type="button",o.className="baseui-text-editor-button",o.dataset.command=e.name,o.title=e.title,o.setAttribute("aria-label",e.title),o.textContent=e.label,o.addEventListener("mousedown",r=>{r.preventDefault(),e.command(t.state,t.dispatch,t),t.focus()}),o}function se(e,t){for(let o of ae)for(let r of o){let s=e.querySelector(`[data-command="${r.name}"]`);s&&(s.setAttribute("aria-pressed",r.active?.(t.state)?"true":"false"),s.disabled=!r.command(t.state,null,t))}for(let o of["undo","redo"]){let r=e.querySelector(`[data-command="${o}"]`),s=o==="undo"?e._baseuiTextEditorUndo:e._baseuiTextEditorRedo;r&&(r.disabled=!s(t.state,null,t))}}function pe(e){return new F({view(t){return{update:()=>I(t.dom.closest(".baseui-text-editor-shell"),t,e)}}})}function I(e,t,o){if(!e)return;let r=t.state.doc.childCount===1&&t.state.doc.firstChild?.type===n.nodes.paragraph&&t.state.doc.firstChild.content.size===0;e.classList.toggle("baseui-text-editor-empty",!!(o&&r)),o&&t.dom.setAttribute("data-placeholder",o)}export{Oe as createProseMirrorTextEditor};
@@ -0,0 +1 @@
1
+ import{b as E,d as F,e as I}from"./chunk-MAWHENWJ.js";import{a as _}from"./chunk-OESZ7FEN.js";import{e as N,g as T}from"./chunk-GF2LJCG5.js";import{G as B,N as M}from"./chunk-P3WV3MLS.js";import{t as O,x as H,y as A}from"./chunk-EAFZBBCI.js";import{f as s,g as a,h as i}from"./chunk-23NN352E.js";function D(o){let t=T({},`${o}_SLASH_SPEC`),e=N(m=>{let h=m.get(t.key);return new H({key:new A(`${o}_SLASH`),...h})}),n=[t,e];return n.key=t.key,n.pluginKey=e.key,t.meta={package:"@milkdown/plugin-slash",displayName:`Ctx<slashSpec>|${o}`},e.meta={package:"@milkdown/plugin-slash",displayName:`Prose<slash>|${o}`},n}var c,f,u,p,g,r,y,l,S,x,k,R,G=(R=class{constructor(o){a(this,c);a(this,f);a(this,u);a(this,p);a(this,g);a(this,r);a(this,y);a(this,l);a(this,S);a(this,x);a(this,k);i(this,c,!1),this.onShow=()=>{},this.onHide=()=>{},i(this,x,(t,e)=>{let{state:n,composing:m}=t,{selection:h,doc:w}=n,{ranges:$}=h,P=Math.min(...$.map(d=>d.$from.pos)),C=Math.max(...$.map(d=>d.$to.pos)),b=e&&e.doc.eq(w)&&e.selection.eq(h);if(s(this,c)||((s(this,p)??t.dom.parentElement??document.body).appendChild(this.element),i(this,c,!0)),!(m||b)){if(!s(this,y).call(this,t,e)){this.hide();return}I({getBoundingClientRect:()=>B(t,P,C)},this.element,{placement:"bottom-start",middleware:[F(),E(s(this,S)),...s(this,f)],...s(this,u)}).then(({x:d,y:U})=>{Object.assign(this.element.style,{left:`${d}px`,top:`${U}px`})}).catch(console.error),this.show()}}),i(this,k,t=>{let e=this.getContent(t);if(!e)return!1;let n=e.at(-1);return n?Array.isArray(s(this,r))?s(this,r).includes(n):s(this,r)===n:!1}),this.update=(t,e)=>{s(this,l).call(this,t,e)},this.getContent=(t,e=n=>n.type.name==="paragraph")=>{let{selection:n}=t.state,{empty:m,$from:h}=n,w=t.state.selection instanceof O;if(typeof document>"u")return;let $=this.element.contains(document.activeElement),P=!t.hasFocus()&&!$,C=!t.editable,b=!M(e)(t.state.selection);if(!(P||C||!m||!w||b))return h.parent.textBetween(Math.max(0,h.parentOffset-500),h.parentOffset,void 0,"\uFFFC")},this.destroy=()=>{s(this,l).cancel()},this.show=()=>{this.element.dataset.show="true",this.onShow()},this.hide=()=>{this.element.dataset.show="false",this.onHide()},this.element=o.content,i(this,g,o.debounce??200),i(this,y,o.shouldShow??s(this,k)),i(this,r,o.trigger??"/"),i(this,S,o.offset),i(this,f,o.middleware??[]),i(this,u,o.floatingUIOptions??{}),i(this,p,o.root),i(this,l,_(s(this,x),s(this,g)))}},c=new WeakMap,f=new WeakMap,u=new WeakMap,p=new WeakMap,g=new WeakMap,r=new WeakMap,y=new WeakMap,l=new WeakMap,S=new WeakMap,x=new WeakMap,k=new WeakMap,R);export{G as SlashProvider,D as slashFactory};
@@ -0,0 +1,3 @@
1
+ import{a as I,h as B}from"./chunk-7R75J74M.js";import{a as C,e as N,g as x}from"./chunk-GF2LJCG5.js";import{la as D,va as w}from"./chunk-P3WV3MLS.js";import{a as p,c as P,x as z,y as A}from"./chunk-EAFZBBCI.js";import"./chunk-23NN352E.js";function h(t,e){return Object.assign(t,{meta:{package:"@milkdown/plugin-streaming",...e}}),t}var y=x({throttleMs:100,scrollFollow:!0,diffReviewOnEnd:!1,ignoreAttrs:{heading:["id"]}},"streamingConfig");h(y,{displayName:"Ctx<streamingConfig>",group:"Streaming"});function G(t,e,n){let r=t.get(w)(n);if(!r)return{tr:e,newDoc:null};let i=t.get(y.key).ignoreAttrs,s=I(e.doc,r,i?{ignoreAttrs:i}:void 0);for(let o=s.length-1;o>=0;o--){let l=s[o],a=r.slice(l.fromB,l.toB);e=e.replace(l.fromA,l.toA,a)}return{tr:e,newDoc:r}}function q(t){if(t.parent.type.spec.code)return{type:"plain-text",preserveNewlines:!0};for(let e=t.depth;e>0;e--)if(t.node(e).type.name==="table")return{type:"plain-text",preserveNewlines:!1};return t.depth>=1?{type:"split-block"}:{type:"block"}}function F(t){if(t.childCount===0)return t;let e=t.lastChild;return e.type.name==="paragraph"&&e.content.size===0?t.cut(0,t.size-e.nodeSize):t}function H(t,e,n){let{insertPos:r,currentEndPos:i}=n,s=n.buffer.replace(/\r\n?/g,`
2
+ `);if(!s)return{tr:e,applied:!1,insertEndPos:i};let o=e.doc.content.size,l=Math.max(0,Math.min(r,o)),a=Math.max(l,Math.min(i,o)),u=e.doc.resolve(l),d=(t.get(y.key).insertStrategy??q)(u),m={ctx:t,tr:e,buffer:s,from:l,to:a,resolved:u};switch(d.type){case"plain-text":return J(m,d.preserveNewlines??!1);case"split-block":return U(m);case"block":return V(m)}}function J({tr:t,buffer:e,from:n,to:r},i){let s=i?e:e.replace(/\n/g," "),o=t.doc.type.schema.text(s);return t=t.replaceWith(n,r,o),{tr:t,applied:!0,insertEndPos:n+s.length}}var Q=/[*_~`[\\<]/;function E(t,e,n){if(!n)return p.empty;if(!Q.test(n))return p.from(e.text(n));let r=t.get(w)(n)?.firstChild;if(r?.type.name!=="paragraph"||r.content.size===0)return p.from(e.text(n));let i=!1;if(r.content.forEach(a=>{(!a.isText||a.marks.length>0)&&(i=!0)}),!i)return p.from(e.text(n));let s=r.content,o=/^\s+/.exec(n)?.[0];o&&((s.firstChild?.isText?s.firstChild.text??"":"").startsWith(o)||(s=p.from(e.text(o)).append(s)));let l=/\s+$/.exec(n)?.[0];return l&&((s.lastChild?.isText?s.lastChild.text??"":"").endsWith(l)||(s=s.append(p.from(e.text(l))))),s}function U({ctx:t,tr:e,buffer:n,from:r,to:i,resolved:s}){let o=e.doc.type.schema,l=n.indexOf(`
3
+ `);if(l<0){let f=E(t,o,n);return e=e.replaceWith(r,i,f),{tr:e,applied:!0,insertEndPos:r+f.size}}let a=n.substring(0,l),u=n.substring(l+1),d=t.get(w),m=u.trim()?d(u):null,b=m?F(m.content):p.empty;if(b.childCount===0){let f=E(t,o,n.replace(/\n/g," "));return e=e.replaceWith(r,i,f),{tr:e,applied:!0,insertEndPos:r+f.size}}let g=s.depth,S=E(t,o,a);for(let f=g;f>0;f--)S=p.from(s.node(f).copy(S));let T=S.append(b),$=new P(T,g,0),L=e.doc.content.size,v=e.doc.resolve(Math.min(i,L)),M=i;g>0&&v.depth===g&&v.parentOffset===v.parent.content.size&&(M=v.after(g)),e=e.replace(r,M,$);let j=T.size-g;return{tr:e,applied:!0,insertEndPos:r+j}}function V({ctx:t,tr:e,buffer:n,from:r,to:i}){let s=t.get(w)(n);if(!s)return{tr:e,applied:!1,insertEndPos:i};let o=F(s.content);return o.size===0?{tr:e,applied:!1,insertEndPos:i}:(e=e.replace(r,i,new P(o,0,0)),{tr:e,applied:!0,insertEndPos:r+o.size})}function k(t,e,n){if(n.insertPos!=null){let r=n.insertPos,i=H(t,e,{buffer:n.buffer,insertPos:r,currentEndPos:n.insertEndPos??r});return{tr:i.tr,newDoc:i.applied?i.tr.doc:null,insertEndPos:i.insertEndPos}}return G(t,e,n.buffer)}var c=new A("MILKDOWN_STREAMING");function X(t,e){if(!t&&e?.type!=="start")return null;if(!e)return t;switch(e.type){case"start":return{buffer:"",originalDoc:e.originalDoc,active:!0,lastApplyTime:e.lastApplyTime,insertPos:e.insertPos??null,insertEndPos:e.insertEndPos??e.insertPos??null};case"push":return t?{...t,buffer:t.buffer+e.token}:null;case"apply":return t?{...t,lastApplyTime:e.lastApplyTime,insertEndPos:e.insertEndPos??t.insertEndPos}:null;case"end":case"abort":return null;default:return t}}var O=N(t=>{let e=t.get(y.key);return new z({key:c,state:{init:()=>null,apply(n,r){return X(r,n.getMeta(c))}},filterTransaction(n,r){return!c.getState(r)?.active||n.getMeta(c)?!0:!n.docChanged},view(){return Y(t,e)}})});h(O,{displayName:"Prose<streaming>",group:"Streaming"});function Y(t,e){let n=null,r=-1,i=null;function s(){if(!i)return;let l=c.getState(i.state);if(!l?.active||l.buffer.length===r)return;r=l.buffer.length;let a=k(t,i.state.tr,l);if(!a.newDoc)return;let u=a.tr;!u.docChanged&&a.insertEndPos==null||(u=u.setMeta(c,{type:"apply",lastApplyTime:Date.now(),insertEndPos:a.insertEndPos}),e.scrollFollow&&(u=u.scrollIntoView()),i.dispatch(u))}function o(){n!=null&&clearTimeout(n),n=setTimeout(s,e.throttleMs)}return{update(l){i=l;let a=c.getState(l.state);if(!a?.active){n!=null&&(clearTimeout(n),n=null),r=-1;return}a.buffer.length!==r&&(Date.now()-a.lastApplyTime>=e.throttleMs?s():o())},destroy(){n!=null&&(clearTimeout(n),n=null),i=null}}}var R=C("StartStreaming",()=>t=>(e,n)=>{if(c.getState(e)?.active)return!1;if(n){let r,i;if(t?.insertAt!=null)if(t.insertAt==="selection"){if(r=e.selection.from,i=e.selection.to,e.selection.empty){let s=e.doc.resolve(r);s.parent.isTextblock&&!s.parent.type.spec.code&&s.parent.content.size===0&&s.depth===1&&(r=s.before(s.depth),i=s.after(s.depth))}}else{let s=t.insertAt==="cursor"?e.selection.head:t.insertAt;if(!Number.isFinite(s))return!1;r=Math.max(0,Math.min(Math.round(s),e.doc.content.size));let o=e.doc.resolve(r);o.parent.isTextblock&&!o.parent.type.spec.code&&o.parent.content.size===0&&o.depth===1&&(r=o.before(o.depth),i=o.after(o.depth))}n(e.tr.setMeta(c,{type:"start",originalDoc:e.doc,insertPos:r,insertEndPos:i,lastApplyTime:Date.now()}))}return!0});h(R,{displayName:"Command<startStreaming>",group:"Streaming"});var W=C("PushChunk",()=>t=>(e,n)=>t==null||!c.getState(e)?.active?!1:(n&&n(e.tr.setMeta(c,{type:"push",token:t})),!0));h(W,{displayName:"Command<pushChunk>",group:"Streaming"});var K=C("EndStreaming",t=>e=>(n,r)=>{let i=c.getState(n);if(!i?.active)return!1;if(r){let s=t.get(y.key),o=e?.diffReview??s.diffReviewOnEnd,l=k(t,n.tr,i),a=l.tr;if(a=a.setMeta(c,{type:"end"}),o&&l.newDoc){let u=a.doc;a=a.replace(0,a.doc.content.size,new P(i.originalDoc.content,0,0)),r(a);try{t.get(D).call(B.key,u)}catch(d){console.warn("[milkdown/streaming] diff review handoff skipped:",d)}return!0}r(a)}return!0});h(K,{displayName:"Command<endStreaming>",group:"Streaming"});var _=C("AbortStreaming",t=>e=>(n,r)=>{let i=c.getState(n);if(!i?.active)return!1;if(r){let s=e?.keep??!1,o=n.tr;s?o=k(t,o,i).tr:o=o.replace(0,n.doc.content.size,new P(i.originalDoc.content,0,0)),o=o.setMeta(c,{type:"abort"}),r(o)}return!0});h(_,{displayName:"Command<abortStreaming>",group:"Streaming"});var ie=[y,O,R,W,K,_];export{_ as abortStreamingCmd,X as applyStreamingAction,q as defaultInsertStrategy,K as endStreamingCmd,W as pushChunkCmd,R as startStreamingCmd,ie as streaming,y as streamingConfig,O as streamingPlugin,c as streamingPluginKey};
@@ -0,0 +1 @@
1
+ import{a as I,b as K,c as L,d as N,e as j}from"./chunk-MAWHENWJ.js";import{b as A}from"./chunk-OESZ7FEN.js";import{e as R,g as q}from"./chunk-GF2LJCG5.js";import{G as M}from"./chunk-P3WV3MLS.js";import{t as B,x as F,y as H}from"./chunk-EAFZBBCI.js";import{f as e,g as i,h as s}from"./chunk-23NN352E.js";var g,y,x,m,d,p,l,k,P,u,a,f,$,w,z,X=(z=class{constructor(n){i(this,g);i(this,y);i(this,x);i(this,m);i(this,d);i(this,p);i(this,l);i(this,k);i(this,P);i(this,u);i(this,a);i(this,f);i(this,$);i(this,w);s(this,p,!1),this.onShow=()=>{},this.onHide=()=>{},s(this,a,t=>{j(t,this.element,{placement:e(this,m).placement??"top",middleware:[N(),K(e(this,k)),L(e(this,P)),...e(this,x)],...e(this,m)}).then(({x:o,y:h})=>{Object.assign(this.element.style,{left:`${o}px`,top:`${h}px`})}).catch(console.error)}),s(this,f,t=>e(this,d)!==t.dom.parentElement),s(this,$,(t,o)=>{var _;let{state:h,composing:c}=t,{selection:r,doc:O}=h,{ranges:T}=r,E=Math.min(...T.map(C=>C.$from.pos)),S=Math.max(...T.map(C=>C.$to.pos)),U=o&&o.doc.eq(O)&&o.selection.eq(r);if(e(this,p)||((e(this,d)??t.dom.parentElement??document.body).appendChild(this.element),s(this,p,!0)),c||U)return;if((_=e(this,l))==null||_.call(this),s(this,l,void 0),!e(this,y).call(this,t,o)){this.hide();return}let b={getBoundingClientRect:()=>M(t,E,S),contextElement:t.dom};e(this,f).call(this,t)?s(this,l,I(b,this.element,()=>e(this,a).call(this,b))):e(this,a).call(this,b),this.show()}),this.update=(t,o)=>{e(this,u).call(this,t,o)},s(this,w,t=>{let{doc:o,selection:h}=t.state,{empty:c,from:r,to:O}=h,T=!o.textBetween(r,O).length&&t.state.selection instanceof B,E=this.element.contains(document.activeElement),S=!t.hasFocus()&&!E,U=!t.editable;return!(S||c||T||U)}),this.destroy=()=>{var t;(t=e(this,l))==null||t.call(this),e(this,u).cancel()},this.show=(t,o)=>{var h;if(this.element.dataset.show="true",t){(h=e(this,l))==null||h.call(this),s(this,l,void 0);let c={...t,contextElement:o?.dom};o&&e(this,f).call(this,o)?s(this,l,I(c,this.element,()=>e(this,a).call(this,c))):e(this,a).call(this,c)}this.onShow()},this.hide=()=>{this.element.dataset.show!=="false"&&(this.element.dataset.show="false",this.onHide())},this.element=n.content,s(this,g,n.debounce??200),s(this,y,n.shouldShow??e(this,w)),s(this,k,n.offset),s(this,P,n.shift),s(this,x,n.middleware??[]),s(this,m,n.floatingUIOptions??{}),s(this,d,n.root),this.element.dataset.show="false",s(this,u,A(e(this,$),e(this,g)))}},g=new WeakMap,y=new WeakMap,x=new WeakMap,m=new WeakMap,d=new WeakMap,p=new WeakMap,l=new WeakMap,k=new WeakMap,P=new WeakMap,u=new WeakMap,a=new WeakMap,f=new WeakMap,$=new WeakMap,w=new WeakMap,z);function Y(n){let t=q({},`${n}_TOOLTIP_SPEC`),o=R(c=>{let r=c.get(t.key);return new F({key:new H(`${n}_TOOLTIP`),...r})}),h=[t,o];return h.key=t.key,h.pluginKey=o.key,t.meta={package:"@milkdown/plugin-tooltip",displayName:`Ctx<tooltipSpec>|${n}`},o.meta={package:"@milkdown/plugin-tooltip",displayName:`Prose<tooltip>|${n}`},h}export{X as TooltipProvider,Y as tooltipFactory};
@@ -0,0 +1 @@
1
+ import{e as U,g as F}from"./chunk-GF2LJCG5.js";import{b as y,fa as b}from"./chunk-P3WV3MLS.js";import{M as k,N as C,x as D,y as P}from"./chunk-EAFZBBCI.js";import"./chunk-23NN352E.js";function A(o){return new Promise(i=>{let n=new FileReader;n.addEventListener("load",()=>{i({alt:o.name,src:n.result})},!1),n.readAsDataURL(o)})}var E=async(o,i)=>{let n=[];for(let e=0;e<o.length;e++){let t=o.item(e);t&&t.type.includes("image")&&n.push(t)}let{image:d}=i.nodes;if(!d)throw y("image");return(await Promise.all(n.map(e=>A(e)))).map(({alt:e,src:t})=>d.createAndFill({src:t,alt:e}))},p=F({uploader:E,enableHtmlFileUploader:!1,uploadWidgetFactory:(o,i)=>{let n=document.createElement("span");return n.textContent="Upload in progress...",k.widget(o,n,i)}},"uploadConfig");p.meta={package:"@milkdown/plugin-upload",displayName:"Ctx<uploadConfig>"};var w=U(o=>{let i=new P("MILKDOWN_UPLOAD"),n=(e,t)=>{let a=i.getState(e);if(!a)return-1;let r=a.find(void 0,void 0,s=>s.id===t);return r.length?r[0]?.from??-1:-1},d=(e,t,a)=>{if(!a||a.length<=0)return!1;let r=Symbol("upload symbol"),s=o.get(b),{uploader:l,getInsertPos:f}=o.get(p.key),{tr:c}=e.state,g=t instanceof DragEvent?e.posAtCoords({left:t.clientX,top:t.clientY})?.pos??c.selection.from:c.selection.from,h=typeof f=="function"?f(t,o,g):g;return e.dispatch(c.setMeta(i,{add:{id:r,pos:h}})),l(a,s,o,h).then(u=>{let m=n(e.state,r);m<0||e.dispatch(e.state.tr.replaceWith(m,m,u).setMeta(i,{remove:{id:r}}))}).catch(u=>{console.error(u)}),!0};return new D({key:i,state:{init(){return C.empty},apply(e,t){let a=t.map(e.mapping,e.doc),r=e.getMeta(this);if(!r)return a;if(r.add){let{uploadWidgetFactory:s}=o.get(p.key),l=s(r.add.pos,{id:r.add.id});return a.add(e.doc,[l])}if(r.remove){let s=a.find(void 0,void 0,l=>l.id===r.remove.id);return a.remove(s)}return a}},props:{decorations(e){return this.getState(e)},handlePaste:(e,t)=>{let{enableHtmlFileUploader:a}=o.get(p.key);return!(t instanceof ClipboardEvent)||!a&&t.clipboardData?.getData("text/html")?!1:d(e,t,t.clipboardData?.files)},handleDrop:(e,t)=>t instanceof DragEvent?d(e,t,t.dataTransfer?.files):!1}})});w.meta={package:"@milkdown/plugin-upload",displayName:"Prose<upload>"};var W=[p,w];export{E as defaultUploader,A as readImageAsBase64,W as upload,p as uploadConfig,w as uploadPlugin};
@@ -0,0 +1 @@
1
+ import{a,b,c,d}from"./chunk-6X7NT7KH.js";import"./chunk-XLIC2WFB.js";import"./chunk-SGGMD6DA.js";import"./chunk-23NN352E.js";export{b as Room,c as SignalingConn,a as WebrtcConn,d as WebrtcProvider};
@@ -0,0 +1 @@
1
+ import{$ as d,$a as da,Aa as E,Ab as Ea,Ba as F,Bb as Fa,Ca as G,Cb as Ga,Da as H,Db as Ha,Ea as I,Eb as Ia,Fa as J,Fb as Ja,Ga as K,Gb as Ka,Ha as L,Hb as La,Ia as M,Ib as Ma,Ja as N,Jb as Na,Ka as O,Kb as Oa,La as P,Lb as Pa,Ma as Q,Mb as Qa,Na as R,Nb as Ra,Oa as S,Ob as Sa,Pa as T,Pb as Ta,Qa as U,Qb as Ua,Ra as V,Rb as Va,Sa as W,Sb as Wa,Ta as X,Ua as Y,Va as Z,Wa as _,Xa as $,Y as a,Ya as aa,Z as b,Za as ba,_ as c,_a as ca,aa as e,ab as ea,ba as f,bb as fa,ca as g,cb as ga,da as h,db as ha,ea as i,eb as ia,fa as j,fb as ja,ga as k,gb as ka,ha as l,hb as la,ia as m,ib as ma,ja as n,jb as na,ka as o,kb as oa,la as p,lb as pa,ma as q,mb as qa,na as r,nb as ra,oa as s,ob as sa,pa as t,pb as ta,qa as u,qb as ua,ra as v,rb as va,sa as w,sb as wa,ta as x,tb as xa,ua as y,ub as ya,va as z,vb as za,wa as A,wb as Aa,xa as B,xb as Ba,ya as C,yb as Ca,za as D,zb as Da}from"./chunk-SGGMD6DA.js";import"./chunk-23NN352E.js";export{E as AbsolutePosition,a as AbstractConnector,Ka as AbstractStruct,ua as AbstractType,za as Array,Sa as ContentAny,Ma as ContentBinary,Na as ContentDeleted,Oa as ContentDoc,Pa as ContentEmbed,Qa as ContentFormat,Ra as ContentJSON,Ta as ContentString,Ua as ContentType,h as Doc,La as GC,u as ID,Va as Item,Ba as Map,A as PermanentUserData,B as RelativePosition,Wa as Skip,K as Snapshot,Ea as Text,_ as Transaction,ba as UndoManager,i as UpdateDecoderV1,j as UpdateDecoderV2,k as UpdateEncoderV1,l as UpdateEncoderV2,Ga as XmlElement,Fa as XmlFragment,Ia as XmlHook,Ja as XmlText,ya as YArrayEvent,sa as YEvent,Aa as YMapEvent,Da as YTextEvent,Ha as YXmlEvent,p as applyUpdate,o as applyUpdateV2,Ca as cleanupYTextFormatting,v as compareIDs,J as compareRelativePositions,qa as convertUpdateFormatV1ToV2,ra as convertUpdateFormatV2ToV1,I as createAbsolutePositionFromRelativePosition,e as createDeleteSet,f as createDeleteSetFromStructStore,T as createDocFromSnapshot,w as createID,D as createRelativePositionFromJSON,F as createRelativePositionFromTypeIndex,Q as createSnapshot,H as decodeRelativePosition,P as decodeSnapshot,O as decodeSnapshotV2,s as decodeStateVector,ea as decodeUpdate,fa as decodeUpdateV2,na as diffUpdate,ma as diffUpdateV2,R as emptySnapshot,G as encodeRelativePosition,N as encodeSnapshot,M as encodeSnapshotV2,r as encodeStateAsUpdate,q as encodeStateAsUpdateV2,t as encodeStateVector,ia as encodeStateVectorFromUpdate,ha as encodeStateVectorFromUpdateV2,g as equalDeleteSets,L as equalSnapshots,W as findIndexSS,x as findRootTypeKey,X as getItem,Z as getItemCleanEnd,Y as getItemCleanStart,V as getState,ta as getTypeChildren,c as isDeleted,y as isParentOf,b as iterateDeletedStructs,z as logType,ca as logUpdate,da as logUpdateV2,d as mergeDeleteSets,ga as mergeUpdates,la as mergeUpdatesV2,oa as obfuscateUpdate,pa as obfuscateUpdateV2,ka as parseUpdateMeta,ja as parseUpdateMetaV2,n as readUpdate,m as readUpdateV2,C as relativePositionToJSON,S as snapshot,U as snapshotContainsUpdate,aa as transact,$ as tryGc,va as typeListToArraySnapshot,xa as typeMapGetAllSnapshot,wa as typeMapGetSnapshot};
package/docs/blocks.md CHANGED
@@ -9,10 +9,12 @@ Block navigation icons must use BaseUI's built-in Lucide icon component, for exa
9
9
  Blocks are not standalone runtime components. Paste the markup and load the normal BaseUI assets:
10
10
 
11
11
  ```html
12
- <link rel="stylesheet" href="/dist/baseui.min.css">
13
- <script src="/dist/baseui.min.js" defer></script>
12
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.css">
13
+ <script src="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.js" defer></script>
14
14
  ```
15
15
 
16
+ `https://unpkg.com/@thebase/ui@latest/dist/...` mirrors the same files as an alternative CDN if jsDelivr is unreachable. Pin an exact version (e.g. `@0.0.4`) instead of `@latest` for production. Blocks are static markup, so they only need the static `b-ui` runtime above — see [Usage Guide](usage-guide.md) if the surrounding page is itself an Owl app and you'd rather compose the equivalent layout from [Pure Owl Components](owl-components.md).
17
+
16
18
  Use `b-block` to select the block style:
17
19
 
18
20
  ```html
package/docs/icons.md CHANGED
@@ -18,10 +18,12 @@ BaseUI ships the full Lucide icon set as a built-in CDN-ready icon library. Icon
18
18
  Load the normal BaseUI assets. No separate icon script is required.
19
19
 
20
20
  ```html
21
- <link rel="stylesheet" href="/dist/baseui.min.css">
22
- <script src="/dist/baseui.min.js" defer></script>
21
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.css">
22
+ <script src="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.js" defer></script>
23
23
  ```
24
24
 
25
+ `https://unpkg.com/@thebase/ui@latest/dist/...` mirrors the same files as an alternative CDN if jsDelivr is unreachable. Pin an exact version (e.g. `@0.0.4`) instead of `@latest` for production. `b-icon` also works with the [pure Owl `Icon` component](components/icon.md) — the recommended API in an Owl app; the classic script above is for pages using the static `b-ui` API.
26
+
25
27
  The build publishes every Lucide SVG to `dist/icons/lucide/` and writes the generated icon manifest to `dist/icons/lucide.json`.
26
28
 
27
29
  ## Markup
@@ -2,16 +2,48 @@
2
2
 
3
3
  See the [Usage Guide](usage-guide.md) for the end-to-end integration path (choosing an API, install, theming, verification). This page covers install mechanics only.
4
4
 
5
- BaseUI is distributed as one CSS file and one JavaScript file for browser use. `dist/baseui.min.js` is fully self-contained: Bootstrap's JS bundle (Popper.js included) and the Owl runtime are embedded ahead of BaseUI's own code, in load order (Bootstrap, then Owl, then BaseUI) — nothing else needs to load first.
5
+ BaseUI is distributed as one CSS file and one JavaScript file for browser use. `dist/baseui.min.js` is fully self-contained: Bootstrap's JS bundle (Popper.js included) and the Owl runtime are embedded ahead of BaseUI's own code, in load order (Bootstrap, then Owl, then BaseUI) — nothing else needs to load first. Both install paths below load this same file; the pure Owl component API is the recommended way to consume BaseUI in an Owl app, with the static `b-ui` markup API available as a lighter-weight alternative for non-Owl pages.
6
+
7
+ The snippets below use the `@latest` tag for readability. Pin an exact version instead (e.g. `@0.0.4`) for any production page — `@latest` can silently change what your page loads the moment a new version is published.
8
+
9
+ ## Pure Owl component install (recommended)
10
+
11
+ If you're building your own Owl app and want to import BaseUI components as real Owl component classes (`<Button/>`, `<Card/>`, `<Tabs/>`, ...) instead of `b-ui` markup, it's the same one file as the static install, just accessed through an import map:
12
+
13
+ ```html
14
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.css">
15
+ <script type="importmap">
16
+ {
17
+ "imports": {
18
+ "@base/owl": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.esm.js",
19
+ "@base/component": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.esm.js",
20
+ "@base/theme": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.esm.js",
21
+ "@base/templates": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.templates.xml"
22
+ }
23
+ }
24
+ </script>
25
+ ```
26
+
27
+ `https://unpkg.com/@thebase/ui@latest/dist/...` mirrors the same files if jsDelivr is unreachable — swap the host in each URL above.
28
+
29
+ `@base/owl`, `@base/component`, and `@base/theme` all resolve to the exact same `dist/baseui.esm.js` module — the browser fetches and evaluates it once, so `Component`/`mount`/`xml` from `@base/owl` and `Button`/`Card`/... from `@base/component` are guaranteed to be the same runtime identity (no separate script needs to load first to set up a shared global). Your own app code should still import Owl from `@base/owl`, never install or import `@odoo/owl` directly — that's what keeps a `class Root extends Component` you write instanceof-compatible with BaseUI's own components. `@base/templates` maps to the templates XML — not a JS module, so resolve it with `import.meta.resolve("@base/templates")` and `fetch()` the result rather than `import`ing it.
30
+
31
+ For npm/bundler usage, everything (Owl framework, component classes, theme helper) is exported from the one `@thebase/ui` package entry: `import { Component, mount, xml, Button, Card, createThemeController } from "@thebase/ui";` — plus `@thebase/ui/dist/baseui.templates.xml` (component templates — fetch or load them before mounting). Note that importing the main entry always runs its `autoMount()` side effect (it scans the DOM for `[b-ui]`/`[b-icon]` markers on `DOMContentLoaded`) — harmless if your page has none, but worth knowing if you specifically wanted a side-effect-free import.
32
+
33
+ See [Pure Owl Components](owl-components.md) for the full loading contract, a worked example, and common mistakes.
34
+
35
+ ## Static `b-ui` install (alternative)
36
+
37
+ For static HTML, a server-rendered page, or a Base HUB website page that has no Owl runtime of its own, load the same bundle as plain CSS + a classic `<script>` tag instead of an import map:
6
38
 
7
39
  ```html
8
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.min.css">
9
- <script src="https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.min.js" defer></script>
40
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.css">
41
+ <script src="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.js" defer></script>
10
42
  ```
11
43
 
12
44
  Bootstrap 5 is the bundled baseline CSS framework, and its JS bundle now drives BaseUI's interactive components directly.
13
45
 
14
- `@thebase/ui` is published on npm, so [unpkg](https://unpkg.com/@thebase/ui@0.0.1/) mirrors the same files as an alternative CDN (`https://unpkg.com/@thebase/ui@0.0.1/dist/baseui.min.css` / `baseui.min.js`) if jsDelivr is unreachable in your environment.
46
+ `@thebase/ui` is published on npm, so [unpkg](https://unpkg.com/@thebase/ui@latest/) mirrors the same files as an alternative CDN (`https://unpkg.com/@thebase/ui@latest/dist/baseui.min.css` / `baseui.min.js`) if jsDelivr is unreachable in your environment. Pin an exact version (e.g. `@0.0.4`) instead of `@latest` for production.
15
47
 
16
48
  For npm/self-hosted usage:
17
49
 
@@ -52,27 +84,3 @@ Production pages should use pinned version URLs. `latest` is for demos and exper
52
84
  BaseUI intentionally keeps Bootstrap bundled for the browser build, both CSS and JS. Bootstrap's JS bundle and the Owl runtime are embedded directly into `dist/baseui.min.js`/`baseui.esm.js` — in that load order — along with every pure Owl component class and the theme helper, so both the static API and the pure Owl API install with one stylesheet and one script/import: there is no more separate `baseui.owl.*`/`baseui.components.esm.js`/`baseui.theme.esm.js` file to keep in load order. Bootstrap's JS instances (`bootstrap.Modal`, `Dropdown`, `Collapse`, `Tab`, `Toast`, `Carousel`, `Tooltip`, `Popover`, `Alert`) drive the components that map to them, wrapped by BaseUI's own `.behavior.js`/`runtime/*.js` helpers so both the static and pure-Owl APIs share identical ARIA/keyboard/event behavior.
53
85
 
54
86
  Release checks enforce runtime dependency, peer dependency, scoped CSS selector, and CDN file-size budgets through `npm run lint` and `npm run build`.
55
-
56
- ## Pure Owl component install
57
-
58
- If you're building your own Owl app and want to import BaseUI components as real Owl component classes (`<Button/>`, `<Card/>`, `<Tabs/>`, ...) instead of `b-ui` markup, it's the same one file as the static install, just accessed through an import map:
59
-
60
- ```html
61
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.min.css">
62
- <script type="importmap">
63
- {
64
- "imports": {
65
- "@base/owl": "https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.esm.js",
66
- "@base/component": "https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.esm.js",
67
- "@base/theme": "https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.esm.js",
68
- "@base/templates": "https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.templates.xml"
69
- }
70
- }
71
- </script>
72
- ```
73
-
74
- `@base/owl`, `@base/component`, and `@base/theme` all resolve to the exact same `dist/baseui.esm.js` module — the browser fetches and evaluates it once, so `Component`/`mount`/`xml` from `@base/owl` and `Button`/`Card`/... from `@base/component` are guaranteed to be the same runtime identity (no separate script needs to load first to set up a shared global). Your own app code should still import Owl from `@base/owl`, never install or import `@odoo/owl` directly — that's what keeps a `class Root extends Component` you write instanceof-compatible with BaseUI's own components. `@base/templates` maps to the templates XML — not a JS module, so resolve it with `import.meta.resolve("@base/templates")` and `fetch()` the result rather than `import`ing it.
75
-
76
- For npm/bundler usage, everything (Owl framework, component classes, theme helper) is exported from the one `@thebase/ui` package entry: `import { Component, mount, xml, Button, Card, createThemeController } from "@thebase/ui";` — plus `@thebase/ui/dist/baseui.templates.xml` (component templates — fetch or load them before mounting). Note that importing the main entry always runs its `autoMount()` side effect (it scans the DOM for `[b-ui]`/`[b-icon]` markers on `DOMContentLoaded`) — harmless if your page has none, but worth knowing if you specifically wanted a side-effect-free import.
77
-
78
- See [Pure Owl Components](owl-components.md) for the full loading contract, a worked example, and common mistakes.
@@ -21,14 +21,14 @@ Everything — the static `b-ui` runtime, the Owl framework, every pure Owl comp
21
21
  ## Browser (import map) usage
22
22
 
23
23
  ```html
24
- <link rel="stylesheet" href="/dist/baseui.min.css">
24
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.css">
25
25
  <script type="importmap">
26
26
  {
27
27
  "imports": {
28
- "@base/owl": "/dist/baseui.esm.js",
29
- "@base/component": "/dist/baseui.esm.js",
30
- "@base/theme": "/dist/baseui.esm.js",
31
- "@base/templates": "/dist/baseui.templates.xml"
28
+ "@base/owl": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.esm.js",
29
+ "@base/component": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.esm.js",
30
+ "@base/theme": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.esm.js",
31
+ "@base/templates": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.templates.xml"
32
32
  }
33
33
  }
34
34
  </script>
@@ -55,6 +55,8 @@ Everything — the static `b-ui` runtime, the Owl framework, every pure Owl comp
55
55
  </script>
56
56
  ```
57
57
 
58
+ `https://unpkg.com/@thebase/ui@latest/dist/...` mirrors the same files as an alternative CDN if jsDelivr is unreachable — swap the host in each URL above. For a self-hosted build, replace the CDN host with your own served path (e.g. `/dist/baseui.esm.js`). These snippets use `@latest` for readability; pin an exact version (e.g. `@0.0.4`) in production so a new release can't change what your page loads.
59
+
58
60
  No `@odoo/owl` import appears anywhere in that snippet — `@base/owl` is the only Owl entry point BaseUI components and consumer apps need. Because `@base/owl`, `@base/component`, and `@base/theme` all point at the exact same `dist/baseui.esm.js` URL, the browser fetches and evaluates it once and every key shares the same module instance — no separate classic `<script>` needs to load first to set up a shared global.
59
61
 
60
62
  ## npm / bundler usage
package/docs/theming.md CHANGED
@@ -21,7 +21,7 @@ For a reusable theme toggle with persistence, URL override, button-label sync, a
21
21
  <script type="importmap">
22
22
  {
23
23
  "imports": {
24
- "@base/theme": "/dist/baseui.esm.js"
24
+ "@base/theme": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.esm.js"
25
25
  }
26
26
  }
27
27
  </script>
@@ -38,7 +38,7 @@ For a reusable theme toggle with persistence, URL override, button-label sync, a
38
38
  </script>
39
39
  ```
40
40
 
41
- Npm/bundler consumers can import the same API from `@thebase/ui`.
41
+ `https://unpkg.com/@thebase/ui@latest/dist/baseui.esm.js` mirrors the same file as an alternative CDN if jsDelivr is unreachable. Pin an exact version (e.g. `@0.0.4`) instead of `@latest` for production. Npm/bundler consumers can import the same API from `@thebase/ui`.
42
42
 
43
43
  For a ready-made icon button, use the BaseUI component instead of wiring your own click handler:
44
44
 
@@ -6,7 +6,7 @@ Audience: engineers and AI coding agents integrating `@thebase/ui` into a projec
6
6
 
7
7
  ## Quick start (copy-paste, works as-is)
8
8
 
9
- Save this as an `.html` file and open it — no build step, no server required. It installs BaseUI from the pinned CDN and renders a button, an input, and a card.
9
+ Save this as an `.html` file and open it — no build step, no server required. It installs BaseUI from the pinned CDN and renders a button, an input, and a card using the static `b-ui` markup API (the zero-build alternative). If you're building an Owl app, skip straight to the [pure Owl install](#2-install-pure-owl-api--recommended) below — it's the recommended way to consume BaseUI.
10
10
 
11
11
  ```html
12
12
  <!doctype html>
@@ -14,8 +14,8 @@ Save this as an `.html` file and open it — no build step, no server required.
14
14
  <head>
15
15
  <meta charset="utf-8">
16
16
  <title>BaseUI quick start</title>
17
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.min.css">
18
- <script src="https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.min.js" defer></script>
17
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.css">
18
+ <script src="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.js" defer></script>
19
19
  </head>
20
20
  <body>
21
21
  <div b-ui="card" style="max-width: 24rem; margin: 2rem auto;">
@@ -32,30 +32,79 @@ Save this as an `.html` file and open it — no build step, no server required.
32
32
  </html>
33
33
  ```
34
34
 
35
- `https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/...` is the real, pinned jsDelivr URL for the published `@thebase/ui` npm package — swap the version segment when you upgrade. See [Installation](installation.md) for jsDelivr/unpkg/npm/self-hosted paths.
35
+ `https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/...` is the real jsDelivr URL for the published `@thebase/ui` npm package's `latest` tag, used here for a copy-paste-and-go quick start. Pin an exact version instead (e.g. `@0.0.4`) for production, so a new release can't change what your page loads. See [Installation](installation.md) for jsDelivr/unpkg/npm/self-hosted paths.
36
36
 
37
- The static bundle calls `BaseUI.mountAll()` automatically on `DOMContentLoaded`, so initial `[b-ui]` and `[b-icon]` markup mounts without an extra script. Call `BaseUI.mountAll(root)` yourself only after injecting new markup or when mounting a specific fragment. If the consumer is itself an Owl app, skip to [step 3](#3-install-pure-owl-api--only-if-the-consumer-is-an-owl-app).
37
+ The static bundle calls `BaseUI.mountAll()` automatically on `DOMContentLoaded`, so initial `[b-ui]` and `[b-icon]` markup mounts without an extra script. Call `BaseUI.mountAll(root)` yourself only after injecting new markup or when mounting a specific fragment. If the consumer is itself an Owl app, use [step 2](#2-install-pure-owl-api--recommended) instead — that's the recommended path.
38
38
 
39
39
  ## 1. Decide which API you need
40
40
 
41
41
  | You are building... | Use | Install | Full reference |
42
42
  | --- | --- | --- | --- |
43
- | Static HTML, a server-rendered page, or a Base HUB website page | The static `b-ui` markup API | One CSS file + one `<script>` tag | [Installation](installation.md) |
44
- | Your own Owl app that wants `<Button/>`, `<Card/>`, `<Dialog/>` as real component classes | The pure Owl component API | CSS + the same `baseui.min.js`/`baseui.esm.js` (via `@base/owl`/`@base/component` import-map keys or a plain npm import) + `dist/baseui.templates.xml` | [Pure Owl Components](owl-components.md) |
43
+ | Your own Owl app that wants `<Button/>`, `<Card/>`, `<Dialog/>` as real component classes | The pure Owl component API (recommended) | CSS + the same `baseui.min.js`/`baseui.esm.js` (via `@base/owl`/`@base/component` import-map keys or a plain npm import) + `dist/baseui.templates.xml` | [Pure Owl Components](owl-components.md) |
44
+ | Static HTML, a server-rendered page, or a Base HUB website page with no Owl runtime | The static `b-ui` markup API (alternative) | One CSS file + one `<script>` tag | [Installation](installation.md) |
45
45
 
46
- Both APIs come from the same package and the same CSS file, and can be mixed on one page. Most consumer projects only need the static API — reach for the pure Owl API only when the consuming app is itself an Owl app.
46
+ Both APIs come from the same package and the same CSS file, and can be mixed on one page. Prefer the pure Owl component API by default — real component classes, props, and slots compose more predictably than markup attributes. Reach for the static API only when the target page has no Owl runtime of its own (plain HTML, server-rendered templates, a Base HUB website page) and adding one isn't worthwhile just to use BaseUI.
47
47
 
48
- **[VERIFY]** Before choosing, confirm whether the target project already runs Owl (check for `@odoo/owl` or `@base/owl` in its `package.json`). Do not add the pure Owl API to a project that has no Owl runtime of its own — that's what the static API is for.
48
+ **[VERIFY]** Before choosing, confirm whether the target project already runs Owl (check for `@odoo/owl` or `@base/owl` in its `package.json`), or whether it's a plain page you'd rather not add a component-mount step to. Use the static API for the latter.
49
49
 
50
- ## 2. Install (static `b-ui` API — the common case)
50
+ ## 2. Install (pure Owl API — recommended)
51
+
52
+ ```html
53
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.css">
54
+ <script type="importmap">
55
+ {
56
+ "imports": {
57
+ "@base/owl": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.esm.js",
58
+ "@base/component": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.esm.js",
59
+ "@base/theme": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.esm.js",
60
+ "@base/templates": "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.templates.xml"
61
+ }
62
+ }
63
+ </script>
64
+ ```
65
+
66
+ `https://unpkg.com/@thebase/ui@latest/dist/...` mirrors the same files as an alternative CDN if jsDelivr is unreachable — swap the host in each URL above. Pin an exact version (e.g. `@0.0.4`) instead of `@latest` for production.
67
+
68
+ ```html
69
+ <script type="module">
70
+ import { Component, mount, xml } from "@base/owl";
71
+ import { Button, Card, CardBody, CardHeader, CardTitle } from "@base/component";
72
+
73
+ const templates = await fetch(import.meta.resolve("@base/templates")).then((r) => r.text());
74
+
75
+ class Root extends Component {
76
+ static components = { Button, Card, CardBody, CardHeader, CardTitle };
77
+ static template = xml`
78
+ <Card>
79
+ <CardHeader><CardTitle>Hello</CardTitle></CardHeader>
80
+ <CardBody>
81
+ <Button variant="'default'" label="'Save'" onClick="() => console.log('saved')"/>
82
+ </CardBody>
83
+ </Card>`;
84
+ }
85
+
86
+ await mount(Root, document.getElementById("app"), { templates });
87
+ </script>
88
+ ```
89
+
90
+ `@base/owl`, `@base/component`, and `@base/theme` all resolve to the exact same `dist/baseui.esm.js` — the one file this whole guide installs for the static API too. For npm/bundler usage, skip the import map entirely and import everything straight from `@thebase/ui` (plus `@thebase/ui/dist/baseui.templates.xml` as a fetch target) — see [Pure Owl Components](owl-components.md#npm--bundler-usage).
91
+
92
+ Two rules that account for most integration failures — see [Pure Owl Components](owl-components.md#common-mistakes) for the worked example:
93
+
94
+ 1. `dist/baseui.templates.xml` must be loaded and passed to `mount()` before any BaseUI tag renders.
95
+ 2. Import Owl itself from `@base/owl`, never `@odoo/owl` — otherwise the consumer's `Component` class and BaseUI's are different runtime identities and mounting throws.
96
+
97
+ ## 3. Install (static `b-ui` API — alternative, no Owl runtime needed)
51
98
 
52
99
  **Option A — CDN (static HTML, no build step):**
53
100
 
54
101
  ```html
55
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.min.css">
56
- <script src="https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.min.js" defer></script>
102
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.css">
103
+ <script src="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.js" defer></script>
57
104
  ```
58
105
 
106
+ `https://unpkg.com/@thebase/ui@latest/dist/...` mirrors the same files as an alternative CDN if jsDelivr is unreachable. Pin an exact version (e.g. `@0.0.4`) instead of `@latest` for production.
107
+
59
108
  **Option B — npm (bundler-based apps: Vite, webpack, etc.):**
60
109
 
61
110
  ```sh
@@ -71,7 +120,7 @@ import "@thebase/ui"; // side-effect import: registers window.BaseUI and auto-mo
71
120
 
72
121
  Rule that applies to both options:
73
122
 
74
- - Production pages must use a pinned version path (`/baseui/1.1.0/...`), never `/latest/`.
123
+ - Production pages must use a pinned version (e.g. `@thebase/ui@0.0.4`), never `@latest`.
75
124
 
76
125
  Mount markup:
77
126
 
@@ -113,51 +162,6 @@ Copy-paste starting points for the components you'll reach for first. Every comp
113
162
  <span b-icon="search"></span>
114
163
  ```
115
164
 
116
- ## 3. Install (pure Owl API — only if the consumer is an Owl app)
117
-
118
- ```html
119
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.min.css">
120
- <script type="importmap">
121
- {
122
- "imports": {
123
- "@base/owl": "https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.esm.js",
124
- "@base/component": "https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.esm.js",
125
- "@base/theme": "https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.esm.js",
126
- "@base/templates": "https://cdn.jsdelivr.net/npm/@thebase/ui@0.0.1/dist/baseui.templates.xml"
127
- }
128
- }
129
- </script>
130
- ```
131
-
132
- ```html
133
- <script type="module">
134
- import { Component, mount, xml } from "@base/owl";
135
- import { Button, Card, CardBody, CardHeader, CardTitle } from "@base/component";
136
-
137
- const templates = await fetch(import.meta.resolve("@base/templates")).then((r) => r.text());
138
-
139
- class Root extends Component {
140
- static components = { Button, Card, CardBody, CardHeader, CardTitle };
141
- static template = xml`
142
- <Card>
143
- <CardHeader><CardTitle>Hello</CardTitle></CardHeader>
144
- <CardBody>
145
- <Button variant="'default'" label="'Save'" onClick="() => console.log('saved')"/>
146
- </CardBody>
147
- </Card>`;
148
- }
149
-
150
- await mount(Root, document.getElementById("app"), { templates });
151
- </script>
152
- ```
153
-
154
- `@base/owl`, `@base/component`, and `@base/theme` all resolve to the exact same `dist/baseui.esm.js` — the one file this whole guide installs for the static API too. For npm/bundler usage, skip the import map entirely and import everything straight from `@thebase/ui` (plus `@thebase/ui/dist/baseui.templates.xml` as a fetch target) — see [Pure Owl Components](owl-components.md#npm--bundler-usage).
155
-
156
- Two rules that account for most integration failures — see [Pure Owl Components](owl-components.md#common-mistakes) for the worked example:
157
-
158
- 1. `dist/baseui.templates.xml` must be loaded and passed to `mount()` before any BaseUI tag renders.
159
- 2. Import Owl itself from `@base/owl`, never `@odoo/owl` — otherwise the consumer's `Component` class and BaseUI's are different runtime identities and mounting throws.
160
-
161
165
  ## 4. Theme the install
162
166
 
163
167
  ```html
@@ -205,7 +209,7 @@ For common layouts (dashboard shells, sidebars, login/signup forms, charts), cop
205
209
  - [ ] Only `baseui.min.css` + `baseui.min.js` (or `baseui.esm.js`) are loaded — no separate `baseui.owl.*`/`bootstrap.bundle.min.js`/`baseui.components.esm.js` files needed, for either API.
206
210
  - [ ] `BaseUI.version` returns the expected pinned version in the browser console.
207
211
  - [ ] Initial static markup mounts without an extra call; injected markup mounts after `BaseUI.mountAll(root)`.
208
- - [ ] Pure Owl components render with no console errors (a missing-template error means step 3's `dist/baseui.templates.xml` load is missing or unawaited).
212
+ - [ ] Pure Owl components render with no console errors (a missing-template error means step 2's `dist/baseui.templates.xml` load is missing or unawaited).
209
213
  - [ ] Toggling `b-theme` actually changes rendered colors (a no-op usually means CSS custom properties are being overridden by the consumer's own stylesheet loaded after `baseui.min.css`).
210
214
  - [ ] Look up the specific component in [`docs/components/`](components/) for its attributes, events, and accessibility notes before wiring it up.
211
215
 
@@ -227,7 +231,7 @@ For common layouts (dashboard shells, sidebars, login/signup forms, charts), cop
227
231
  - Using `/latest/` CDN paths in production instead of a pinned version.
228
232
  - Assuming auto-mount watches the DOM forever — it does not; call `BaseUI.mountAll(root)` after injecting new `[b-ui]` markup client-side (e.g. from a fetched partial).
229
233
  - Mixing `@odoo/owl` imports into a project that also imports `@thebase/ui` — always go through `@base/owl`.
230
- - Expecting `BaseUI.mountAll()` to pick up Owl component tags (`<Button/>`) — it only mounts static `[b-ui]` markers; pure Owl components are registered and mounted through your own app's `static components` + `mount()`, per step 3.
234
+ - Expecting `BaseUI.mountAll()` to pick up Owl component tags (`<Button/>`) — it only mounts static `[b-ui]` markers; pure Owl components are registered and mounted through your own app's `static components` + `mount()`, per step 2.
231
235
 
232
236
  ## Related docs
233
237
 
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "@thebase/ui",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "CDN-installable Owl and Bootstrap 5 UI component library.",
5
5
  "type": "module",
6
6
  "main": "./dist/baseui.min.js",
7
+ "bin": {
8
+ "create-baseui-app": "./bin/create-baseui-app.mjs"
9
+ },
7
10
  "module": "./dist/baseui.esm.js",
8
11
  "style": "./dist/baseui.min.css",
9
12
  "types": "./dist/types/index.d.ts",
@@ -20,6 +23,7 @@
20
23
  "./dist/baseui.templates.xml": "./dist/baseui.templates.xml"
21
24
  },
22
25
  "files": [
26
+ "bin/create-baseui-app.mjs",
23
27
  "dist/baseui.min.css",
24
28
  "dist/baseui.esm.js",
25
29
  "dist/baseui.min.js",
@@ -27,6 +31,7 @@
27
31
  "dist/baseui.templates.xml",
28
32
  "dist/icons",
29
33
  "dist/baseui.registry.json",
34
+ "dist/runtime",
30
35
  "dist/themes",
31
36
  "dist/types",
32
37
  "docs/*.md",