@scattered-light/loomiere-mojave 0.25.0 → 0.41.0

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 (45) hide show
  1. package/dist/exports/AGENTS.md +1 -1
  2. package/dist/exports/base-ui.css +5574 -0
  3. package/dist/exports/base-ui.md +535 -0
  4. package/dist/exports/catalog.json +28 -0
  5. package/dist/exports/design-system/README.md +1 -1
  6. package/dist/exports/design-system/components/Badge/README.md +1 -1
  7. package/dist/exports/design-system/components/Badge/preview.html +43 -43
  8. package/dist/exports/design-system/components/ChecklistNotice/README.md +8 -4
  9. package/dist/exports/design-system/components/ChecklistNotice/preview.html +71 -71
  10. package/dist/exports/design-system/components/ChipPicker/README.md +43 -0
  11. package/dist/exports/design-system/components/ChipPicker/preview.html +475 -0
  12. package/dist/exports/design-system/components/DataTable/README.md +7 -1
  13. package/dist/exports/design-system/components/DataTable/preview.html +202 -202
  14. package/dist/exports/design-system/components/EmptyState/README.md +1 -1
  15. package/dist/exports/design-system/components/FileDropZone/README.md +38 -0
  16. package/dist/exports/design-system/components/FileDropZone/preview.html +19 -0
  17. package/dist/exports/design-system/components/LineItemGrid/README.md +7 -4
  18. package/dist/exports/design-system/components/LineItemGrid/preview.html +154 -154
  19. package/dist/exports/design-system/components/MultiSelect/README.md +8 -2
  20. package/dist/exports/design-system/components/MultiSelect/preview.html +2 -2
  21. package/dist/exports/design-system/components/Notice/README.md +6 -2
  22. package/dist/exports/design-system/components/Notice/preview.html +2 -2
  23. package/dist/exports/design-system/components/RadioCard/README.md +43 -0
  24. package/dist/exports/design-system/components/RadioCard/preview.html +19 -0
  25. package/dist/exports/design-system/components/Shortcuts/README.md +80 -0
  26. package/dist/exports/design-system/components/Shortcuts/preview.html +19 -0
  27. package/dist/exports/design-system/components/SourcePreview/README.md +45 -0
  28. package/dist/exports/design-system/components/SourcePreview/preview.html +19 -0
  29. package/dist/exports/design-system/components/SplitButton/README.md +2 -1
  30. package/dist/exports/design-system/components/SplitButton/preview.html +2 -2
  31. package/dist/exports/design-system/components/StatBand/README.md +34 -0
  32. package/dist/exports/design-system/components/StatBand/preview.html +475 -0
  33. package/dist/exports/design-system/components/Stepper/README.md +34 -0
  34. package/dist/exports/design-system/components/Stepper/preview.html +19 -0
  35. package/dist/exports/design-system/components/SummaryStrip/README.md +36 -0
  36. package/dist/exports/design-system/components/SummaryStrip/preview.html +19 -0
  37. package/dist/exports/design-system/components/Table/README.md +2 -1
  38. package/dist/exports/design-system/components/Tabs/README.md +2 -1
  39. package/dist/exports/design-system/components/Tabs/preview.html +1 -1
  40. package/dist/exports/design-system/components/Text/README.md +29 -0
  41. package/dist/exports/design-system/components/Text/preview.html +19 -0
  42. package/dist/exports/design-system/components/bundle.css +2229 -414
  43. package/dist/exports/design-system/components/bundle.js +7 -7
  44. package/dist/exports/design-system/components/index.d.ts +5 -3
  45. package/package.json +2 -2
@@ -12,10 +12,16 @@ Base UI docs: https://base-ui.com/react/components/multi-select
12
12
  |---|---|
13
13
  | `MultiSelectPopup` | |
14
14
  | `MultiSelectList` | |
15
- | `MultiSelectOption` | |
15
+ | `MultiSelectOption` | `data-disabled` |
16
16
  | `MultiSelectOptionLabel` | |
17
+ | `MultiSelectOptionHint` | |
17
18
  | `MultiSelectOptionCount` | |
18
19
  | `MultiSelectFooter` | |
20
+ | `MultiSelectField` | `data-disabled` |
21
+ | `MultiSelectTrigger` | |
22
+ | `MultiSelectFieldLabel` | |
23
+ | `MultiSelectFind` | |
24
+ | `MultiSelectGroupLabel` | |
19
25
 
20
26
  Base UI sets the state attributes (`data-checked`, `data-open`, `data-disabled`...) itself. Set `data-size`, `data-emphasis`, `data-variant` and `data-color` yourself; `data-color` takes any palette name (`primary`, `secondary`, `error`...) and repaints the part in it.
21
27
 
@@ -32,4 +38,4 @@ export const Default: Story = {
32
38
  };
33
39
  ```
34
40
 
35
- The preview also shows `WithSelection`, `ManySelected`.
41
+ The preview also shows `WithSelection`, `ManySelected`, `LabelAbove`.
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Components" height=360 subtitle="Default / WithSelection / ManySelected" -->
1
+ <!-- @dsCard group="Components" height=480 subtitle="Default / WithSelection / ManySelected / LabelAbove" -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -12,7 +12,7 @@
12
12
  <body>
13
13
  <div id="root"></div>
14
14
  <script>
15
- (()=>{var x=Object.create;var i=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var h=Object.getPrototypeOf,M=Object.prototype.hasOwnProperty;var d=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),V=(e,t)=>{for(var a in t)i(e,a,{get:t[a],enumerable:!0})},C=(e,t,a,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of A(t))!M.call(e,n)&&n!==a&&i(e,n,{get:()=>t[n],enumerable:!(o=w(t,n))||o.enumerable});return e};var y=(e,t,a)=>(a=e!=null?x(h(e)):{},C(t||!e||!e.__esModule?i(a,"default",{value:e,enumerable:!0}):a,e));var f=d((W,S)=>{S.exports=window.React});var b=d(($,v)=>{v.exports=window.Loomiere});var p={};V(p,{Default:()=>j,ManySelected:()=>I,WithSelection:()=>D,default:()=>m});var u=y(f(),1),r=y(b(),1);var l=window.React;function c(e,t,a){let{children:o,...n}=t||{};return a!==void 0&&(n.key=a),o===void 0?l.createElement(e,n):Array.isArray(o)?l.createElement(e,n,...o):l.createElement(e,n,o)}var q=l.Fragment;var L={title:"Components/Lib/MultiSelect",component:r.MultiSelect,parameters:{layout:"centered"},tags:["autodocs","ds:lib"],args:{label:"Status",options:[],value:[],onValueChange:()=>{}}},m=L,g=[{value:"active",label:"Active",count:41},{value:"inactive",label:"Inactive",count:6},{value:"available",label:"Available from master",count:12}],j={render:function(){let[t,a]=u.useState([]);return c(r.MultiSelect,{label:"Status",allLabel:"All statuses",options:g,value:t,onValueChange:a})}},D={render:function(){let[t,a]=u.useState(["active","inactive"]);return c(r.MultiSelect,{label:"Status",allLabel:"All statuses",options:g,value:t,onValueChange:a})}},I={render:function(){let t=["Assets","Liabilities","Equity","Income","Cost of sales","Expenses"].map((n,R)=>({value:n,label:n,count:3+R})),[a,o]=u.useState(["Assets","Income","Expenses"]);return c(r.MultiSelect,{label:"Type",allLabel:"All types",options:t,value:a,onValueChange:o})}};var s=window.React,E=m||{},F=["Default","WithSelection","ManySelected"];function N({id:e}){let t=p[e],a={...E.args||{},...t.args||{}};return(t.render||(n=>s.createElement(E.component,n)))(a,{args:a,id:e,name:e})}var O=F.map(e=>s.createElement("section",{key:e,className:"ds-story"},s.createElement("p",{className:"ds-story-name"},e.replace(/([a-z])([A-Z])/g,"$1 $2")),s.createElement("div",{className:"ds-story-body"},s.createElement(N,{id:e}))));window.ReactDOM.createRoot(document.getElementById("root")).render(s.createElement(s.Fragment,null,O));})();
15
+ (()=>{var F=Object.create;var m=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var h=Object.getPrototypeOf,x=Object.prototype.hasOwnProperty;var b=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),C=(t,e)=>{for(var n in e)m(t,n,{get:e[n],enumerable:!0})},V=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of L(e))!x.call(t,a)&&a!==n&&m(t,a,{get:()=>e[a],enumerable:!(o=A(e,a))||o.enumerable});return t};var v=(t,e,n)=>(n=t!=null?F(h(t)):{},V(e||!t||!t.__esModule?m(n,"default",{value:t,enumerable:!0}):n,t));var g=b((T,y)=>{y.exports=window.React});var R=b((W,S)=>{S.exports=window.Loomiere});var p={};C(p,{CountedWithFind:()=>j,Default:()=>M,DisabledOptions:()=>P,LabelAbove:()=>N,ManySelected:()=>H,WithSelection:()=>D,default:()=>d});var r=v(g(),1),l=v(R(),1);var u=window.React;function s(t,e,n){let{children:o,...a}=e||{};return n!==void 0&&(a.key=n),o===void 0?u.createElement(t,a):Array.isArray(o)?u.createElement(t,a,...o):u.createElement(t,a,o)}var $=u.Fragment;var w={title:"Components/Lib/MultiSelect",component:l.MultiSelect,parameters:{layout:"centered"},tags:["autodocs","ds:lib"],args:{label:"Status",options:[],value:[],onValueChange:()=>{}}},d=w,f=[{value:"active",label:"Active",count:41},{value:"inactive",label:"Inactive",count:6},{value:"available",label:"Available from master",count:12}],M={render:function(){let[e,n]=r.useState([]);return s(l.MultiSelect,{label:"Status",allLabel:"All statuses",options:f,value:e,onValueChange:n})}},D={render:function(){let[e,n]=r.useState(["active","inactive"]);return s(l.MultiSelect,{label:"Status",allLabel:"All statuses",options:f,value:e,onValueChange:n})}},H={render:function(){let e=["Assets","Liabilities","Equity","Income","Cost of sales","Expenses"].map((a,c)=>({value:a,label:a,count:3+c})),[n,o]=r.useState(["Assets","Income","Expenses"]);return s(l.MultiSelect,{label:"Type",allLabel:"All types",options:e,value:n,onValueChange:o})}},N={render:function(){let[e,n]=r.useState([]),o=["1000 Bank","1500 Equipment","2000 Accounts Payable","4000 Revenue","6100 Rent"].map(a=>({value:a,label:a}));return s(l.MultiSelect,{label:"Accounts",labelPlacement:"above",allLabel:"All accounts",options:o,value:e,onValueChange:n})}},P={render:function(){let[e,n]=r.useState(["a"]);return s(l.MultiSelect,{label:"Entities",allLabel:"All Entities",options:[{value:"a",label:"Fictional Personal Holdings",count:3},{value:"b",label:"Fictional Retirement Holdings",count:1},{value:"c",label:"Fictional Family Trust",disabled:!0,hint:"No investments"}],value:e,onValueChange:n})}},j={render:function(){let[e,n]=r.useState(["a"]),o=["Fictional Personal Holdings","Fictional Design LLC","Fictional Family Trust","Fictional Rentals LLC","Fictional Retirement Holdings","Fictional Roth","Fictional Bakery Co.","Fictional Dental Group","Fictional Holdings Co."].map((a,c)=>({value:c===0?"a":`o${c}`,label:a,...c===1?{disabled:!0,hint:"No investments"}:{}}));return s(l.MultiSelect,{label:"Entities",labelPlacement:"above",noun:"Entities",findLabel:"Find an Entity",allLabel:"All Entities",options:o,value:e,onValueChange:n})}};var i=window.React,E=d||{},k=["Default","WithSelection","ManySelected","LabelAbove"];function I({id:t}){let e=p[t],n={...E.args||{},...e.args||{}};return(e.render||(a=>i.createElement(E.component,a)))(n,{args:n,id:t,name:t})}var O=k.map(t=>i.createElement("section",{key:t,className:"ds-story"},i.createElement("p",{className:"ds-story-name"},t.replace(/([a-z])([A-Z])/g,"$1 $2")),i.createElement("div",{className:"ds-story-body"},i.createElement(I,{id:t}))));window.ReactDOM.createRoot(document.getElementById("root")).render(i.createElement(i.Fragment,null,O));})();
16
16
 
17
17
  </script>
18
18
  </body>
@@ -10,7 +10,11 @@ Base UI docs: https://base-ui.com/react/components/notice
10
10
 
11
11
  | Class | Data attributes it answers to |
12
12
  |---|---|
13
- | `Notice` | `data-status`: `error`, `warning`, `success`, `info`; `data-technical` |
13
+ | `Notice` | `data-status`: `error`, `warning`, `success`, `info`; `data-technical`; `data-layout`: `row` |
14
+ | `NoticeTag` | |
15
+ | `NoticeBody` | |
16
+ | `NoticeHeading` | |
17
+ | `NoticeAction` | |
14
18
 
15
19
  Base UI sets the state attributes (`data-checked`, `data-open`, `data-disabled`...) itself. Set `data-size`, `data-emphasis`, `data-variant` and `data-color` yourself; `data-color` takes any palette name (`primary`, `secondary`, `error`...) and repaints the part in it.
16
20
 
@@ -27,4 +31,4 @@ export const Default: Story = {
27
31
  /** Every status, the neutral notice, and the technical style. */
28
32
  ```
29
33
 
30
- The preview also shows `Statuses`, `InAForm`.
34
+ The preview also shows `Statuses`, `InAForm`, `WithHeadingAndAction`.
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Components" height=360 subtitle="Default / Statuses / InAForm" -->
1
+ <!-- @dsCard group="Components" height=480 subtitle="Default / Statuses / InAForm / WithHeadingAndAction" -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -12,7 +12,7 @@
12
12
  <body>
13
13
  <div id="root"></div>
14
14
  <script>
15
- (()=>{var f=Object.create;var l=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var b=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var x=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),E=(e,t)=>{for(var n in t)l(e,n,{get:t[n],enumerable:!0})},N=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of g(t))!w.call(e,r)&&r!==n&&l(e,r,{get:()=>t[r],enumerable:!(s=h(t,r))||s.enumerable});return e};var S=(e,t,n)=>(n=e!=null?f(b(e)):{},N(t||!e||!e.__esModule?l(n,"default",{value:e,enumerable:!0}):n,e));var p=x((L,u)=>{u.exports=window.Loomiere});var d={};E(d,{Default:()=>F,InAForm:()=>k,Statuses:()=>R,default:()=>m});var o=S(p(),1);var i=window.React;function a(e,t,n){let{children:s,...r}=t||{};return n!==void 0&&(r.key=n),s===void 0?i.createElement(e,r):Array.isArray(s)?i.createElement(e,r,...s):i.createElement(e,r,s)}var B=i.Fragment;var v={title:"Components/Lib/Notice",component:o.Notice,parameters:{layout:"padded"},tags:["autodocs","ds:lib"]},m=v,F={args:{status:"error",children:"Email or password is incorrect, or the account is temporarily locked."},render:e=>a(o.Notice,{...e,style:{maxWidth:420}})},R={render:()=>a("div",{style:{display:"grid",gap:"var(--sl-space-3)",maxWidth:420},children:[a(o.Notice,{announce:!1,children:"Neutral: a note about this page."}),a(o.Notice,{status:"info",announce:!1,children:"Info: the import runs overnight."}),a(o.Notice,{status:"success",announce:!1,children:"If that email has an account, we've sent a link to it."}),a(o.Notice,{status:"warning",announce:!1,children:"Two accounts have no opening balance."}),a(o.Notice,{status:"error",announce:!1,children:"Can't reach the server. Check the connection and try again."}),a(o.Notice,{technical:!0,announce:!1,children:"This computer's keychain is unavailable: access denied by the system"})]})},k={render:()=>a("form",{style:{display:"grid",gap:"var(--sl-space-3)",maxWidth:360},onSubmit:e=>e.preventDefault(),children:[a(o.Field.Root,{children:[a(o.Field.Label,{children:"Email"}),a(o.Input,{type:"email",defaultValue:"jordan@example.com"})]}),a(o.Button,{type:"submit",children:"Sign in"}),a(o.Notice,{status:"error",announce:!1,children:"Enter your password"})]})};var c=window.React,y=m||{},I=["Default","Statuses","InAForm"];function j({id:e}){let t=d[e],n={...y.args||{},...t.args||{}};return(t.render||(r=>c.createElement(y.component,r)))(n,{args:n,id:e,name:e})}var A=I.map(e=>c.createElement("section",{key:e,className:"ds-story"},c.createElement("p",{className:"ds-story-name"},e.replace(/([a-z])([A-Z])/g,"$1 $2")),c.createElement("div",{className:"ds-story-body"},c.createElement(j,{id:e}))));window.ReactDOM.createRoot(document.getElementById("root")).render(c.createElement(c.Fragment,null,A));})();
15
+ (()=>{var y=Object.create;var l=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var v=Object.getPrototypeOf,b=Object.prototype.hasOwnProperty;var w=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports),x=(e,n)=>{for(var o in n)l(e,o,{get:n[o],enumerable:!0})},N=(e,n,o,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of g(n))!b.call(e,s)&&s!==o&&l(e,s,{get:()=>n[s],enumerable:!(r=f(n,s))||r.enumerable});return e};var S=(e,n,o)=>(o=e!=null?y(v(e)):{},N(n||!e||!e.__esModule?l(o,"default",{value:e,enumerable:!0}):o,e));var p=w((j,u)=>{u.exports=window.Loomiere});var m={};x(m,{Default:()=>R,InAForm:()=>F,Statuses:()=>A,WithHeadingAndAction:()=>B,default:()=>d});var a=S(p(),1);var i=window.React;function t(e,n,o){let{children:r,...s}=n||{};return o!==void 0&&(s.key=o),r===void 0?i.createElement(e,s):Array.isArray(r)?i.createElement(e,s,...r):i.createElement(e,s,r)}var L=i.Fragment;var E={title:"Components/Lib/Notice",component:a.Notice,parameters:{layout:"padded"},tags:["autodocs","ds:lib"]},d=E,R={args:{status:"error",children:"Email or password is incorrect, or the account is temporarily locked."},render:e=>t(a.Notice,{...e,style:{maxWidth:420}})},A={render:()=>t("div",{style:{display:"grid",gap:"var(--sl-space-3)",maxWidth:420},children:[t(a.Notice,{announce:!1,children:"Neutral: a note about this page."}),t(a.Notice,{status:"info",announce:!1,children:"Info: the import runs overnight."}),t(a.Notice,{status:"success",announce:!1,children:"If that email has an account, we've sent a link to it."}),t(a.Notice,{status:"warning",announce:!1,children:"Two accounts have no opening balance."}),t(a.Notice,{status:"error",announce:!1,children:"Can't reach the server. Check the connection and try again."}),t(a.Notice,{technical:!0,announce:!1,children:"This computer's keychain is unavailable: access denied by the system"})]})},F={render:()=>t("form",{style:{display:"grid",gap:"var(--sl-space-3)",maxWidth:360},onSubmit:e=>e.preventDefault(),children:[t(a.Field.Root,{children:[t(a.Field.Label,{children:"Email"}),t(a.Input,{type:"email",defaultValue:"jordan@example.com"})]}),t(a.Button,{type:"submit",children:"Sign in"}),t(a.Notice,{status:"error",announce:!1,children:"Enter your password"})]})},B={render:()=>t("div",{style:{display:"grid",gap:"var(--sl-space-3)",maxWidth:960},children:[t(a.Notice,{status:"warning",announce:!1,tag:t(a.Badge,{shape:"square",children:"Incomplete"}),heading:"3 excluded \xB7 Draft incomplete",action:t(a.Button,{emphasis:"standard",children:"Review details"}),children:t("p",{children:"3 For Review items can't be counted as they are, so these totals leave them out. The books don't change."})}),t(a.Notice,{announce:!1,tag:t(a.Badge,{shape:"square",emphasis:"bold",children:"Snapshot"}),heading:"Historical snapshot \xB7 Draft, not posted",action:t(a.Button,{emphasis:"standard",children:"Return to live Draft"}),children:t("p",{children:"Preserved accounting state. Later classification and posting changes are left out."})})]})};var c=window.React,h=d||{},D=["Default","Statuses","InAForm","WithHeadingAndAction"];function k({id:e}){let n=m[e],o={...h.args||{},...n.args||{}};return(n.render||(s=>c.createElement(h.component,s)))(o,{args:o,id:e,name:e})}var I=D.map(e=>c.createElement("section",{key:e,className:"ds-story"},c.createElement("p",{className:"ds-story-name"},e.replace(/([a-z])([A-Z])/g,"$1 $2")),c.createElement("div",{className:"ds-story-body"},c.createElement(k,{id:e}))));window.ReactDOM.createRoot(document.getElementById("root")).render(c.createElement(c.Fragment,null,I));})();
16
16
 
17
17
  </script>
18
18
  </body>
@@ -0,0 +1,43 @@
1
+ # RadioCard
2
+
3
+ The Base UI RadioCard styled by the theme. A Radio Group drawn as a grid of cards. Each card is the radio (a span with role radio): a preview, a bold label and a quiet description, on the raised surface with a 1px default border. The chosen card's border is 2px in the text color (the padding gives back the extra pixel so nothing moves) and a round check sits on its top right corner, half outside the card.
4
+
5
+ Use `Loomiere.RadioCard` (`import { RadioCard } from '@base-ui/react/radio-card'` in an app) and give each part the class below; the styles target those classes, not Base UI's own markup.
6
+
7
+ Base UI docs: https://base-ui.com/react/components/radio-card
8
+
9
+ ## Classes
10
+
11
+ | Class | Data attributes it answers to |
12
+ |---|---|
13
+ | `RadioCardGroup` | |
14
+ | `RadioCard` | `data-disabled`; `data-checked` |
15
+ | `RadioCardPreview` | |
16
+ | `RadioCardLabel` | |
17
+ | `RadioCardDescription` | |
18
+ | `RadioCardMark` | `data-unchecked` |
19
+
20
+ Base UI sets the state attributes (`data-checked`, `data-open`, `data-disabled`...) itself. Set `data-size`, `data-emphasis`, `data-variant` and `data-color` yourself; `data-color` takes any palette name (`primary`, `secondary`, `error`...) and repaints the part in it.
21
+
22
+ ## Example
23
+
24
+ From the RadioCard stories (`Swatches`):
25
+
26
+ ```tsx
27
+ export const Swatches: Story = {
28
+ render: () => {
29
+ const [value, setValue] = React.useState('sandstone');
30
+ return (
31
+ <RadioCardGroup aria-label="Look" value={value} onValueChange={(v) => setValue(v as string)} style={{ maxWidth: 560 }}>
32
+ <RadioCard value="sandstone" label="Sandstone">{swatch(['#2a1f17', '#964d2b', '#e8e2d9', '#fffdfa'])}</RadioCard>
33
+ <RadioCard value="prism" label="Prism">{swatch(['#1d2433', '#3b5bdb', '#dfe4ee', '#ffffff'])}</RadioCard>
34
+ <RadioCard value="highlighter" label="Highlighter">{swatch(['#1f1f1f', '#d9480f', '#fff3bf', '#ffffff'])}</RadioCard>
35
+ </RadioCardGroup>
36
+ );
37
+ },
38
+ };
39
+
40
+ /** With a description under each label and no preview: a choice that needs a sentence of meaning. */
41
+ ```
42
+
43
+ The preview also shows `Described`, `Disabled`.
@@ -0,0 +1,19 @@
1
+ <!-- @dsCard group="Components" height=360 subtitle="Swatches / Described / Disabled" -->
2
+ <!doctype html>
3
+ <html>
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <style>
7
+ body { margin: 0; padding: var(--sl-space-4, 16px); background: var(--sl-surface-canvas); color: var(--sl-text-primary); }
8
+ #root { display: grid; gap: var(--sl-space-5, 20px); }
9
+ .ds-story-name { margin: 0 0 var(--sl-space-2, 8px); font: var(--sl-font-label-minimize-font, 500 10px sans-serif); color: var(--sl-text-tertiary); text-transform: uppercase; letter-spacing: 0.06em; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div id="root"></div>
14
+ <script>
15
+ (()=>{var x=Object.create;var i=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var C=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var u=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),k=(e,t)=>{for(var a in t)i(e,a,{get:t[a],enumerable:!0})},D=(e,t,a,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of v(t))!E.call(e,n)&&n!==a&&i(e,n,{get:()=>t[n],enumerable:!(s=S(t,n))||s.enumerable});return e};var p=(e,t,a)=>(a=e!=null?x(C(e)):{},D(t||!e||!e.__esModule?i(a,"default",{value:e,enumerable:!0}):a,e));var y=u((O,b)=>{b.exports=window.React});var h=u((W,g)=>{g.exports=window.Loomiere});var m={};k(m,{Described:()=>V,Disabled:()=>j,Swatches:()=>G,default:()=>f});var R=p(y(),1),r=p(h(),1);var l=window.React;function o(e,t,a){let{children:s,...n}=t||{};return a!==void 0&&(n.key=a),s===void 0?l.createElement(e,n):Array.isArray(s)?l.createElement(e,n,...s):l.createElement(e,n,s)}var z=l.Fragment;var A={title:"Components/Lib/RadioCard",component:r.RadioCardGroup,parameters:{layout:"padded"},tags:["autodocs","ds:lib"]},f=A,c=e=>o("span",{style:{display:"flex",height:28,borderRadius:3,overflow:"hidden",border:"1px solid rgba(42,31,23,.15)"},children:e.map(t=>o("i",{style:{flex:1,background:t}},t))}),G={render:()=>{let[e,t]=R.useState("sandstone");return o(r.RadioCardGroup,{"aria-label":"Look",value:e,onValueChange:a=>t(a),style:{maxWidth:560},children:[o(r.RadioCard,{value:"sandstone",label:"Sandstone",children:c(["#2a1f17","#964d2b","#e8e2d9","#fffdfa"])}),o(r.RadioCard,{value:"prism",label:"Prism",children:c(["#1d2433","#3b5bdb","#dfe4ee","#ffffff"])}),o(r.RadioCard,{value:"highlighter",label:"Highlighter",children:c(["#1f1f1f","#d9480f","#fff3bf","#ffffff"])})]})}},V={render:()=>o(r.RadioCardGroup,{"aria-label":"Operating model",defaultValue:"firm",columns:2,style:{maxWidth:560},children:[o(r.RadioCard,{value:"firm",label:"Accounting Firm",description:"Accounting for many clients, each with its own chart of accounts."}),o(r.RadioCard,{value:"internal",label:"Internal Accounting",description:"Your own organization's accounting, with one shared chart of accounts."})]})},j={render:()=>o(r.RadioCardGroup,{"aria-label":"Mode",defaultValue:"light",style:{maxWidth:560},children:[o(r.RadioCard,{value:"system",label:"System"}),o(r.RadioCard,{value:"light",label:"Light"}),o(r.RadioCard,{value:"dark",label:"Dark",disabled:!0,description:"Not in this look"})]})};var d=window.React,w=f||{},F=["Swatches","Described","Disabled"];function L({id:e}){let t=m[e],a={...w.args||{},...t.args||{}};return(t.render||(n=>d.createElement(w.component,n)))(a,{args:a,id:e,name:e})}var M=F.map(e=>d.createElement("section",{key:e,className:"ds-story"},d.createElement("p",{className:"ds-story-name"},e.replace(/([a-z])([A-Z])/g,"$1 $2")),d.createElement("div",{className:"ds-story-body"},d.createElement(L,{id:e}))));window.ReactDOM.createRoot(document.getElementById("root")).render(d.createElement(d.Fragment,null,M));})();
16
+
17
+ </script>
18
+ </body>
19
+ </html>
@@ -0,0 +1,80 @@
1
+ # Shortcuts
2
+
3
+ The Base UI Shortcuts styled by the theme. Kbd: key caps for a shortcut, in the figures face, each a small raised cap with a heavier bottom edge. `data-tone="inverse"` draws them on a dark surface (a tooltip, the Go to hint) in the surrounding text color. ShortcutSequenceHint: the dark card that lists the next keys after the first key of a sequence. ShortcutsDialog: the cheat sheet, a find box, one statement-look table per group, and the single-key switch in its footer. CommandPalette: a dialog near the top of the screen with a search field, grouped options and a footer of key hints. The active option is tinted, not outlined, because focus stays in the field.
4
+
5
+ Use `Loomiere.Shortcuts` (`import { Shortcuts } from '@base-ui/react/shortcuts'` in an app) and give each part the class below; the styles target those classes, not Base UI's own markup.
6
+
7
+ Base UI docs: https://base-ui.com/react/components/shortcuts
8
+
9
+ ## Classes
10
+
11
+ | Class | Data attributes it answers to |
12
+ |---|---|
13
+ | `Kbd` | `data-tone`: `inverse` |
14
+ | `KbdKeys` | |
15
+ | `KbdKey` | |
16
+ | `KbdThen` | |
17
+ | `Button` | |
18
+ | `MenuItem` | |
19
+ | `TooltipPopup` | |
20
+ | `ShortcutSequenceHint` | |
21
+ | `ShortcutSequenceHintHead` | |
22
+ | `ShortcutSequenceHintTitle` | |
23
+ | `ShortcutSequenceHintCancel` | |
24
+ | `ShortcutSequenceHintList` | |
25
+ | `ShortcutsDialog` | |
26
+ | `DialogPopup` | `data-starting-style`; `data-ending-style` |
27
+ | `ShortcutsDialogFind` | |
28
+ | `Input` | |
29
+ | `ShortcutsDialogBody` | |
30
+ | `ShortcutsGroup` | |
31
+ | `ShortcutsGroupTitle` | |
32
+ | `ShortcutsDialogFooter` | |
33
+ | `ShortcutsDialogSwitch` | |
34
+ | `ShortcutsDialogSwitchText` | |
35
+ | `ShortcutsDialogSwitchLabel` | |
36
+ | `ShortcutsDialogSwitchNote` | |
37
+ | `ShortcutsDialogFooterNote` | |
38
+ | `CommandPalette` | |
39
+ | `CommandPaletteField` | |
40
+ | `CommandPaletteInput` | |
41
+ | `CommandPaletteList` | |
42
+ | `CommandPaletteGroupLabel` | |
43
+ | `CommandPaletteOption` | `data-active` |
44
+ | `CommandPaletteIcon` | |
45
+ | `CommandPaletteText` | |
46
+ | `CommandPaletteLabel` | |
47
+ | `CommandPaletteMeta` | |
48
+ | `CommandPaletteMatch` | |
49
+ | `EmptyState` | |
50
+ | `CommandPaletteFooter` | |
51
+ | `CommandPaletteFooterNote` | |
52
+
53
+ Base UI sets the state attributes (`data-checked`, `data-open`, `data-disabled`...) itself. Set `data-size`, `data-emphasis`, `data-variant` and `data-color` yourself; `data-color` takes any palette name (`primary`, `secondary`, `error`...) and repaints the part in it.
54
+
55
+ ## Example
56
+
57
+ From the Shortcuts stories (`KeyCaps`):
58
+
59
+ ```tsx
60
+ export const KeyCaps: Story = {
61
+ render: () => (
62
+ <div style={{ display: 'grid', gridTemplateColumns: 'max-content repeat(5, max-content)', gap: '12px 28px', alignItems: 'center' }}>
63
+ {(['mac', 'other'] as const).map((platform) => (
64
+ <ShortcutProvider key={platform} platform={platform}>
65
+ <strong>{platform === 'mac' ? 'Mac' : 'Windows'}</strong>
66
+ <Kbd keys="mod+k" />
67
+ <Kbd keys="mod+shift+d" />
68
+ <Kbd keys="mod+enter" />
69
+ <Kbd keys="j" />
70
+ <Kbd keys="g r" />
71
+ </ShortcutProvider>
72
+ ))}
73
+ </div>
74
+ ),
75
+ };
76
+
77
+ /** A tooltip names its keys after the label; the trigger carries aria-keyshortcuts. */
78
+ ```
79
+
80
+ The preview also shows `InTooltip`, `ProviderPaletteAndCheatSheet`, `RowKeys`.
@@ -0,0 +1,19 @@
1
+ <!-- @dsCard group="Components" height=480 subtitle="KeyCaps / InTooltip / ProviderPaletteAndCheatSheet / RowKeys" -->
2
+ <!doctype html>
3
+ <html>
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <style>
7
+ body { margin: 0; padding: var(--sl-space-4, 16px); background: var(--sl-surface-canvas); color: var(--sl-text-primary); }
8
+ #root { display: grid; gap: var(--sl-space-5, 20px); }
9
+ .ds-story-name { margin: 0 0 var(--sl-space-2, 8px); font: var(--sl-font-label-minimize-font, 500 10px sans-serif); color: var(--sl-text-tertiary); text-transform: uppercase; letter-spacing: 0.06em; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div id="root"></div>
14
+ <script>
15
+ (()=>{var R=Object.create;var u=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var F=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty;var m=(o,r)=>()=>(r||o((r={exports:{}}).exports,r),r.exports),E=(o,r)=>{for(var s in r)u(o,s,{get:r[s],enumerable:!0})},L=(o,r,s,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of A(r))!D.call(o,n)&&n!==s&&u(o,n,{get:()=>r[n],enumerable:!(a=T(r,n))||a.enumerable});return o};var y=(o,r,s)=>(s=o!=null?R(F(o)):{},L(r||!o||!o.__esModule?u(s,"default",{value:o,enumerable:!0}):s,o));var w=m((z,k)=>{k.exports=window.React});var f=m((J,S)=>{S.exports=window.Loomiere});var x=m((V,b)=>{b.exports=window.Loomiere});var g={};E(g,{InTooltip:()=>B,KeyCaps:()=>O,KeyHints:()=>G,ProviderPaletteAndCheatSheet:()=>H,RowKeys:()=>I,default:()=>h});var l=y(w(),1),t=y(f(),1),i=y(x(),1);var d=window.React;function e(o,r,s){let{children:a,...n}=r||{};return s!==void 0&&(n.key=s),a===void 0?d.createElement(o,n):Array.isArray(a)?d.createElement(o,n,...a):d.createElement(o,n,a)}var Z=d.Fragment;var N={title:"Components/Lib/Shortcuts",parameters:{layout:"padded"},tags:["autodocs","ds:lib"]},h=N,O={render:()=>e("div",{style:{display:"grid",gridTemplateColumns:"max-content repeat(5, max-content)",gap:"12px 28px",alignItems:"center"},children:["mac","other"].map(o=>e(t.ShortcutProvider,{platform:o,children:[e("strong",{children:o==="mac"?"Mac":"Windows"}),e(t.Kbd,{keys:"mod+k"}),e(t.Kbd,{keys:"mod+shift+d"}),e(t.Kbd,{keys:"mod+enter"}),e(t.Kbd,{keys:"j"}),e(t.Kbd,{keys:"g r"})]},o))})},B={render:()=>e(t.Tooltip.Provider,{children:e(t.Tooltip.Root,{defaultOpen:!0,children:[e(t.Tooltip.Trigger,{className:"Button","aria-keyshortcuts":(0,t.ariaKeyShortcuts)("mod+k"),children:"Search"}),e(t.Tooltip.Portal,{children:e(t.Tooltip.Positioner,{sideOffset:8,children:e(t.Tooltip.Popup,{children:["Search clients, entities, accounts ",e(t.Kbd,{keys:"mod+k"})]})})})]})})};function K(){let[o,r]=l.useState("Press ?, G then R, or \u2318K / Ctrl K."),[s,a]=l.useState(!1),[n,p]=l.useState(!1);(0,t.useShortcuts)([{keys:"mod+k",label:"Search and commands",handler:()=>p(!0)},{keys:"?",label:"This list of shortcuts",handler:()=>a(!0)},{keys:"g d",label:"Dashboard",group:"Go to",description:"Client or entity",handler:()=>r("Went to Dashboard")},{keys:"g r",label:"For Review",group:"Go to",description:"Client or entity",handler:()=>r("Went to For Review")},{keys:"g a",label:"Chart of Accounts",group:"Go to",description:"Client or entity",handler:()=>r("Went to Chart of Accounts")}]);let P=[{id:"c1",group:"Clients",label:"Northwind Fictional Holdings",meta:"Client \xB7 4 entities",onSelect:()=>r("Opened Northwind Fictional Holdings")},{id:"c2",group:"Clients",label:"Harbor Street Bakery",meta:"Client \xB7 3 entities",onSelect:()=>r("Opened Harbor Street Bakery")},{id:"e1",group:"Entities",label:"Northwind Fictional Design LLC",meta:"Entity \xB7 Northwind Fictional Holdings",onSelect:()=>r("Opened Northwind Fictional Design LLC")},{id:"a1",group:"Accounts",label:"Fictional Checking \xB7\xB7\xB7\xB71001",meta:"Bank account",keywords:["bank"],onSelect:()=>r("Opened Fictional Checking")},{id:"p1",group:"Pages",label:"For Review",meta:"12 waiting",shortcut:"g r",onSelect:()=>r("Went to For Review")},{id:"x1",group:"Actions",label:"Keyboard shortcuts",shortcut:"?",onSelect:()=>a(!0)}];return e("div",{style:{display:"flex",flexDirection:"column",gap:12,alignItems:"flex-start"},children:[e("p",{style:{margin:0},children:o}),e("div",{style:{display:"flex",gap:8},children:[e(t.Button,{onClick:()=>p(!0),"aria-keyshortcuts":(0,t.ariaKeyShortcuts)("mod+k"),children:["Search ",e(t.Kbd,{keys:"mod+k"})]}),e(t.Button,{onClick:()=>a(!0),children:["Shortcuts ",e(t.Kbd,{keys:"?"})]})]}),e(t.CommandPalette,{open:n,onOpenChange:p,items:P,groupOrder:["Clients","Entities","Accounts","Pages","Actions"],placeholder:"Search clients, entities, accounts, pages and actions",footerNote:"Pages follow where you are"}),e(i.ShortcutsDialog,{open:s,onOpenChange:a,groupOrder:["Anywhere","Go to","Lists and tables"],extra:[{keys:"j",label:"Next row",group:"Lists and tables",description:"Any list; \u2193 works too"},{keys:"k",label:"Previous row",group:"Lists and tables",description:"Any list; \u2191 works too"},{keys:"x",label:"Select the row",group:"Lists and tables",description:"Lists with checkboxes"},{keys:"esc",label:"Close the top layer",description:"Popup, dialog, drawer"}]})]})}var H={render:()=>e(t.ShortcutProvider,{children:e(K,{})})},C=[{id:"t1",party:"Blue Bottle Coffee",amount:18.4},{id:"t2",party:"Acme Paper Supply",amount:412.15},{id:"t3",party:"City of Northwind",amount:250},{id:"t4",party:"Lumen Studio",amount:6800}],I={render:()=>{let[o,r]=l.useState(C[0]),s=l.useMemo(()=>(0,i.defineColumns)([{id:"party",header:"Party",value:n=>n.party,rowHeader:!0},{id:"amount",header:"Amount",value:n=>n.amount,kind:"money",currency:"USD"}]),[]),a=(0,i.useCollection)({rows:C,columns:s,getRowId:n=>n.id});return e(t.ShortcutProvider,{children:e("div",{style:{display:"grid",gridTemplateColumns:"minmax(0, 1fr) 16rem",gap:24},children:[e(i.DataTable,{collection:a,label:"For Review",onRowActivate:r,onActiveRowChange:r,activeRowId:o.id}),e("aside",{"aria-label":"Detail",style:{padding:16,border:"1px solid var(--sl-border-default)"},children:[e("strong",{children:o.party}),e("p",{style:{margin:"8px 0 0"},children:["Use ",e(t.Kbd,{keys:"j"})," and ",e(t.Kbd,{keys:"k"})," on a row."]})]})]})})}};function j(){let{keyHints:o,setKeyHints:r}=(0,t.useShortcutSettings)();return e("div",{style:{display:"flex",flexDirection:"column",gap:16,alignItems:"flex-start"},children:[e("label",{className:"SwitchContainer",children:[e(t.Switch.Root,{checked:o,onCheckedChange:r,children:e(t.Switch.Thumb,{})}),"Show key hints"]}),e("div",{style:{display:"flex",gap:8},children:[e(t.Button,{"aria-keyshortcuts":"K",children:["\u2039 Previous ",e(t.Kbd,{keys:"k",hint:!0})]}),e(t.Button,{"aria-keyshortcuts":"J",children:["Next ",e(t.Kbd,{keys:"j",hint:!0})," \u203A"]})]}),e("p",{style:{margin:0},children:["Caps with ",e("code",{children:"hint"})," hide when the switch is off. The keys still work, and the cheat sheet and palette always show them."]})]})}var G={render:()=>e(t.ShortcutProvider,{children:e(j,{})})};var c=window.React,v=h||{},M=["KeyCaps","InTooltip","ProviderPaletteAndCheatSheet","RowKeys"];function W({id:o}){let r=g[o],s={...v.args||{},...r.args||{}};return(r.render||(n=>c.createElement(v.component,n)))(s,{args:s,id:o,name:o})}var U=M.map(o=>c.createElement("section",{key:o,className:"ds-story"},c.createElement("p",{className:"ds-story-name"},o.replace(/([a-z])([A-Z])/g,"$1 $2")),c.createElement("div",{className:"ds-story-body"},c.createElement(W,{id:o}))));window.ReactDOM.createRoot(document.getElementById("root")).render(c.createElement(c.Fragment,null,U));})();
16
+
17
+ </script>
18
+ </body>
19
+ </html>
@@ -0,0 +1,45 @@
1
+ # SourcePreview
2
+
3
+ The Base UI SourcePreview styled by the theme. A file's lines or a worksheet's rows in a ruled frame: the number in a quiet first column, rows on hairlines, a header line with an accent edge and a tint, skipped lines struck through. Rows share one grid (subgrid) so cells line up down the columns. Wide content scrolls inside.
4
+
5
+ Use `Loomiere.SourcePreview` (`import { SourcePreview } from '@base-ui/react/source-preview'` in an app) and give each part the class below; the styles target those classes, not Base UI's own markup.
6
+
7
+ Base UI docs: https://base-ui.com/react/components/source-preview
8
+
9
+ ## Classes
10
+
11
+ | Class | Data attributes it answers to |
12
+ |---|---|
13
+ | `SourcePreview` | `data-mono` |
14
+ | `SourcePreviewScroll` | |
15
+ | `SourcePreviewGrid` | |
16
+ | `SourcePreviewRow` | `data-state`: `skipped`, `header` |
17
+ | `SourcePreviewCell` | `data-marker`: `ignored`; `data-formula` |
18
+ | `SourcePreviewHead` | |
19
+ | `SourcePreviewNumber` | |
20
+ | `SourcePreviewDot` | |
21
+ | `SourcePreviewIgnored` | |
22
+ | `SourcePreviewColumn` | `data-marker`: `ignored` |
23
+ | `SourcePreviewTag` | |
24
+ | `SourcePreviewFx` | |
25
+ | `SourcePreviewHint` | |
26
+
27
+ Base UI sets the state attributes (`data-checked`, `data-open`, `data-disabled`...) itself. Set `data-size`, `data-emphasis`, `data-variant` and `data-color` yourself; `data-color` takes any palette name (`primary`, `secondary`, `error`...) and repaints the part in it.
28
+
29
+ ## Example
30
+
31
+ From the SourcePreview stories (`HeaderPicker`):
32
+
33
+ ```tsx
34
+ export const HeaderPicker: Story = {
35
+ args: { rows: lines, 'aria-label': 'First lines of the file' },
36
+ render: (args) => {
37
+ const [header, setHeader] = React.useState(3);
38
+ return <SourcePreview {...args} headerLine={header} onHeaderLineChange={setHeader} />;
39
+ },
40
+ };
41
+
42
+ /** Columns with mapped and ignored markers. */
43
+ ```
44
+
45
+ The preview also shows `Mapped`, `Formulas`.
@@ -0,0 +1,19 @@
1
+ <!-- @dsCard group="Components" height=360 subtitle="HeaderPicker / Mapped / Formulas" -->
2
+ <!doctype html>
3
+ <html>
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <style>
7
+ body { margin: 0; padding: var(--sl-space-4, 16px); background: var(--sl-surface-canvas); color: var(--sl-text-primary); }
8
+ #root { display: grid; gap: var(--sl-space-5, 20px); }
9
+ .ds-story-name { margin: 0 0 var(--sl-space-2, 8px); font: var(--sl-font-label-minimize-font, 500 10px sans-serif); color: var(--sl-text-tertiary); text-transform: uppercase; letter-spacing: 0.06em; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div id="root"></div>
14
+ <script>
15
+ (()=>{var y=Object.create;var l=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var L=Object.getPrototypeOf,R=Object.prototype.hasOwnProperty;var d=(e,r)=>()=>(r||e((r={exports:{}}).exports,r),r.exports),f=(e,r)=>{for(var t in r)l(e,t,{get:r[t],enumerable:!0})},A=(e,r,t,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of D(r))!R.call(e,a)&&a!==t&&l(e,a,{get:()=>r[a],enumerable:!(o=C(r,a))||o.enumerable});return e};var p=(e,r,t)=>(t=e!=null?y(L(e)):{},A(r||!e||!e.__esModule?l(t,"default",{value:e,enumerable:!0}):t,e));var b=d((H,u)=>{u.exports=window.React});var S=d((M,E)=>{E.exports=window.Loomiere});var i={};f(i,{Formulas:()=>F,HeaderPicker:()=>h,Mapped:()=>k,default:()=>m});var I=p(b(),1),c=p(S(),1);var s=window.React;function w(e,r,t){let{children:o,...a}=r||{};return t!==void 0&&(a.key=t),o===void 0?s.createElement(e,a):Array.isArray(o)?s.createElement(e,a,...o):s.createElement(e,a,o)}var v=s.Fragment;var O={title:"Components/Lib/SourcePreview",component:c.SourcePreview,parameters:{layout:"padded"},tags:["autodocs","ds:lib"]},m=O,T=["Fictional Checking \xB7\xB7\xB7\xB71001 \xB7 Northwind Fictional Design LLC","Activity from 09/30/2026 to 10/31/2026","Details,Posting Date,Description,Amount,Type,Balance,Check or Slip #","DEBIT,09/30/2026,FICTIONAL CLOUD HOSTING 0930,-89.00,DEBIT_CARD,52321.55,","DEBIT,10/01/2026,FICTIONAL PAYROLL SERVICES PAYROLL,-6240.00,ACH_DEBIT,46081.55,","CREDIT,10/03/2026,DEPOSIT LUMEN BOOKS INV 2026-118,1250.00,ACH_CREDIT,47331.55,"].map((e,r)=>({number:r+1,cells:e})),h={args:{rows:T,"aria-label":"First lines of the file"},render:e=>{let[r,t]=I.useState(3);return w(c.SourcePreview,{...e,headerLine:r,onHeaderLineChange:t})}},k={args:{"aria-label":"Source sample",columns:[{label:"Details",marker:"ignored"},{label:"Posting Date",marker:"mapped"},{label:"Description",marker:"mapped"},{label:"Amount",marker:"mapped",align:"end"},{label:"Balance",marker:"ignored",align:"end"}],rows:[{number:4,cells:["DEBIT","09/30/2026","FICTIONAL CLOUD HOSTING 0930","-89.00","52321.55"]},{number:5,cells:["DEBIT","10/01/2026","FICTIONAL PAYROLL SERVICES","-6240.00","46081.55"]}]}},F={args:{"aria-label":"Worksheet rows",numberLabel:"row",columns:[{label:"A"},{label:"B"},{label:"C",align:"end"}],rows:[{number:2,cells:["10/01/2026","Rent","2,400.00"]},{number:3,cells:["10/02/2026","Total",{value:"2,400.00",formula:"=SUM(C2:C2)"}]}],hint:"Row numbers are the worksheet's own."}};var n=window.React,g=m||{},N=["HeaderPicker","Mapped","Formulas"];function x({id:e}){let r=i[e],t={...g.args||{},...r.args||{}};return(r.render||(a=>n.createElement(g.component,a)))(t,{args:t,id:e,name:e})}var B=N.map(e=>n.createElement("section",{key:e,className:"ds-story"},n.createElement("p",{className:"ds-story-name"},e.replace(/([a-z])([A-Z])/g,"$1 $2")),n.createElement("div",{className:"ds-story-body"},n.createElement(x,{id:e}))));window.ReactDOM.createRoot(document.getElementById("root")).render(n.createElement(n.Fragment,null,B));})();
16
+
17
+ </script>
18
+ </body>
19
+ </html>
@@ -11,6 +11,7 @@ Not a Base UI part, so there is no base-ui.com page for it.
11
11
  | Class | Data attributes it answers to |
12
12
  |---|---|
13
13
  | `SplitButton` | |
14
+ | `MenuPopup` | `data-described` |
14
15
 
15
16
  Base UI sets the state attributes (`data-checked`, `data-open`, `data-disabled`...) itself. Set `data-size`, `data-emphasis`, `data-variant` and `data-color` yourself; `data-color` takes any palette name (`primary`, `secondary`, `error`...) and repaints the part in it.
16
17
 
@@ -22,4 +23,4 @@ From the SplitButton stories (`Default`):
22
23
  export const Default: Story = {};
23
24
  ```
24
25
 
25
- The preview also shows `Disabled`.
26
+ The preview also shows `Disabled`, `WithDescriptions`.
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Actions" height=240 subtitle="Default / Disabled" -->
1
+ <!-- @dsCard group="Actions" height=360 subtitle="Default / Disabled / WithDescriptions" -->
2
2
  <!doctype html>
3
3
  <html>
4
4
  <head>
@@ -12,7 +12,7 @@
12
12
  <body>
13
13
  <div id="root"></div>
14
14
  <script>
15
- (()=>{var y=Object.create;var s=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var S=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var g=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),w=(e,t)=>{for(var o in t)s(e,o,{get:t[o],enumerable:!0})},E=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of u(t))!f.call(e,a)&&a!==o&&s(e,a,{get:()=>t[a],enumerable:!(n=b(t,a))||n.enumerable});return e};var k=(e,t,o)=>(o=e!=null?y(S(e)):{},E(t||!e||!e.__esModule?s(o,"default",{value:e,enumerable:!0}):o,e));var d=g((L,m)=>{m.exports=window.Loomiere});var c={};w(c,{Default:()=>B,Disabled:()=>D,default:()=>l});var i=k(d(),1),x={title:"Components/Lib/SplitButton",component:i.SplitButton,parameters:{layout:"padded"},tags:["autodocs","ds:lib"],args:{label:"Add Transaction",onClick:()=>{},moreLabel:"More ways to add transactions",items:[{label:"Bank connection (not yet available)",onSelect:()=>{},disabled:!0},{label:"Import CSV",onSelect:()=>{}},{label:"Import Excel workbook",onSelect:()=>{}}]}},l=x,B={},D={args:{disabled:!0}};var r=window.React,p=l||{},M=["Default","Disabled"];function R({id:e}){let t=c[e],o={...p.args||{},...t.args||{}};return(t.render||(a=>r.createElement(p.component,a)))(o,{args:o,id:e,name:e})}var C=M.map(e=>r.createElement("section",{key:e,className:"ds-story"},r.createElement("p",{className:"ds-story-name"},e.replace(/([a-z])([A-Z])/g,"$1 $2")),r.createElement("div",{className:"ds-story-body"},r.createElement(R,{id:e}))));window.ReactDOM.createRoot(document.getElementById("root")).render(r.createElement(r.Fragment,null,C));})();
15
+ (()=>{var b=Object.create;var s=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var g=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),k=(e,t)=>{for(var o in t)s(e,o,{get:t[o],enumerable:!0})},w=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of S(t))!f.call(e,a)&&a!==o&&s(e,a,{get:()=>t[a],enumerable:!(n=y(t,a))||n.enumerable});return e};var B=(e,t,o)=>(o=e!=null?b(u(e)):{},w(t||!e||!e.__esModule?s(o,"default",{value:e,enumerable:!0}):o,e));var m=g((v,i)=>{i.exports=window.Loomiere});var c={};k(c,{Default:()=>x,Disabled:()=>D,WithDescriptions:()=>M,default:()=>l});var d=B(m(),1),E={title:"Components/Lib/SplitButton",component:d.SplitButton,parameters:{layout:"padded"},tags:["autodocs","ds:lib"],args:{label:"Add Transaction",onClick:()=>{},moreLabel:"More ways to add transactions",items:[{label:"Bank connection (not yet available)",onSelect:()=>{},disabled:!0},{label:"Import CSV",onSelect:()=>{}},{label:"Import Excel workbook",onSelect:()=>{}}]}},l=E,x={},D={args:{disabled:!0}},M={args:{items:[{label:"CSV",description:"Bank or card export, up to 5 MB",onSelect:()=>{}},{label:"Excel workbook",description:"A register sheet, up to 10 MB",onSelect:()=>{}},{label:"Bank connection",description:"Not yet available",onSelect:()=>{},disabled:!0}]}};var r=window.React,p=l||{},h=["Default","Disabled","WithDescriptions"];function C({id:e}){let t=c[e],o={...p.args||{},...t.args||{}};return(t.render||(a=>r.createElement(p.component,a)))(o,{args:o,id:e,name:e})}var N=h.map(e=>r.createElement("section",{key:e,className:"ds-story"},r.createElement("p",{className:"ds-story-name"},e.replace(/([a-z])([A-Z])/g,"$1 $2")),r.createElement("div",{className:"ds-story-body"},r.createElement(C,{id:e}))));window.ReactDOM.createRoot(document.getElementById("root")).render(r.createElement(r.Fragment,null,N));})();
16
16
 
17
17
  </script>
18
18
  </body>
@@ -0,0 +1,34 @@
1
+ # StatBand
2
+
3
+ The Base UI StatBand styled by the theme. The headline figures of a display page, in a band of their own: equal cells side by side, a 1px border, the sheet's heavy rule on top (sheet.rule-width), and a StatFigure (size sm) in each cell. The cells wrap to more rows when the band is narrow; each cell is at least 11rem wide. A figure wrapped in a link takes the accent color and its own double underline.
4
+
5
+ Use `Loomiere.StatBand` (`import { StatBand } from '@base-ui/react/stat-band'` in an app) and give each part the class below; the styles target those classes, not Base UI's own markup.
6
+
7
+ Base UI docs: https://base-ui.com/react/components/stat-band
8
+
9
+ ## Classes
10
+
11
+ | Class | Data attributes it answers to |
12
+ |---|---|
13
+ | `StatBand` | |
14
+ | `StatBandCell` | |
15
+ | `StatFigureValue` | |
16
+
17
+ Base UI sets the state attributes (`data-checked`, `data-open`, `data-disabled`...) itself. Set `data-size`, `data-emphasis`, `data-variant` and `data-color` yourself; `data-color` takes any palette name (`primary`, `secondary`, `error`...) and repaints the part in it.
18
+
19
+ ## Example
20
+
21
+ From the StatBand stories (`Default`):
22
+
23
+ ```tsx
24
+ export const Default: Story = {
25
+ play: async ({ canvasElement }) => {
26
+ const band = within(canvasElement).getByRole('group', { name: 'Draft summary' });
27
+ await expect(band.querySelectorAll('.StatBandCell').length).toBe(4);
28
+ },
29
+ };
30
+
31
+ /** A balance with the double underline, and a count that opens the work it counts (a link in the accent color). */
32
+ ```
33
+
34
+ The preview also shows `BalanceAndLink`.