@shwfed/config 2.3.16 → 2.3.17

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 (32) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/preview/assets/{config-C4t_as1U.js → config-B_D_DLrg.js} +1 -1
  3. package/dist/preview/assets/{config-m-s6iTyN.js → config-CAUy5OIr.js} +1 -1
  4. package/dist/preview/assets/{config-AEM1zjvE.js → config-CAzy2oY1.js} +1 -1
  5. package/dist/preview/assets/{config-CRUg_Pcx.js → config-CDcbWHz1.js} +1 -1
  6. package/dist/preview/assets/{config-B4ITIOSI.js → config-D9wKVRfv.js} +1 -1
  7. package/dist/preview/assets/{config-DyvYQUK3.js → config-DReApS3g.js} +1 -1
  8. package/dist/preview/assets/{config-8iL9DU55.js → config-DkE2KJox.js} +1 -1
  9. package/dist/preview/assets/{config-C19W7NmV.js → config-lCt8xg5R.js} +1 -1
  10. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-CiwBbLRf.js → definition.vue_vue_type_script_setup_true_lang-CvzBdDHI.js} +1 -1
  11. package/dist/preview/assets/index-BUyz4nJb.css +1 -0
  12. package/dist/preview/assets/{index-BT8fF6jA.js → index-DOUzPsqV.js} +134 -132
  13. package/dist/preview/assets/index-DUZhCCDY.js +1 -0
  14. package/dist/preview/assets/{runtime-DTtdk8hJ.js → runtime-C7iG_6_s.js} +1 -1
  15. package/dist/preview/assets/{runtime-BHeaq-Ju.js → runtime-CEymLc8o.js} +1 -1
  16. package/dist/preview/assets/{runtime--kEuSRJR.js → runtime-CNI--nfZ.js} +1 -1
  17. package/dist/preview/assets/{runtime-BlndSTII.js → runtime-CWwZuZQ7.js} +1 -1
  18. package/dist/preview/assets/{runtime-BiAcObbN.js → runtime-Dg8BS7Rt.js} +1 -1
  19. package/dist/preview/assets/{runtime-n8qxUfe8.js → runtime-Dj39BqNd.js} +1 -1
  20. package/dist/preview/assets/{runtime-DDA8wR0s.js → runtime-TUjKxXEj.js} +1 -1
  21. package/dist/preview/assets/{runtime-KCPICzI0.js → runtime-eRS_ur88.js} +1 -1
  22. package/dist/preview/index.html +2 -2
  23. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/runtime.vue +36 -12
  24. package/dist/runtime/components/ui/tree/Tree.d.vue.ts +7 -0
  25. package/dist/runtime/components/ui/tree/Tree.vue +3 -1
  26. package/dist/runtime/components/ui/tree/Tree.vue.d.ts +7 -0
  27. package/dist/runtime/components/ui/tree/TreeNode.d.vue.ts +1 -0
  28. package/dist/runtime/components/ui/tree/TreeNode.vue +4 -2
  29. package/dist/runtime/components/ui/tree/TreeNode.vue.d.ts +1 -0
  30. package/package.json +1 -1
  31. package/dist/preview/assets/index-Br_eXThF.css +0 -1
  32. package/dist/preview/assets/index-DrZ27b4e.js +0 -1
@@ -0,0 +1 @@
1
+ import{aH as e}from"./index-DOUzPsqV.js";import{aI as r,aJ as s,aK as t}from"./index-DOUzPsqV.js";export{r as TableConfig,s as createTableConfig,e as default,t as getColumnTechnicalKey};
@@ -1 +1 @@
1
- import{d as _,an as j,ae as B,aq as r,az as m,aA as E,aB as S,e as k,u as v,aj as x,ak as L,am as b,o as C,al as R}from"./index-BT8fF6jA.js";import{_ as T}from"./definition.vue_vue_type_script_setup_true_lang-CiwBbLRf.js";const I=_({name:"ShwfedHttpDownloadActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(d){const c=d,g=R(),t=(e,n)=>x(e,{...L(g),...n}),l=b(),p=new Set(["success","error","warning","info"]);function f(e){const n=URL.createObjectURL(e),o=document.createElement("a");o.href=n,o.download=e.name,document.body.appendChild(o),o.click(),o.remove(),URL.revokeObjectURL(n)}const y=j(()=>B(function*(){const{template:e,messageExpression:n,resultExpression:o}=c.config,u=yield*t(e.request);if(!e.download){const s=yield*u.file();return yield*r(()=>f(s)),yield*m(l,c.config.onSuccess)}const a={json:yield*u.json()},i=o===void 0?"success":yield*E(t(o,a),s=>p.has(s)?s:"success");if(n!==void 0){const s=yield*t(n,a);yield*r(()=>S[i](s))}if(i==="success"||i==="info"){const h=yield*(yield*t(e.download,a)).file();yield*r(()=>f(h))}const w={success:c.config.onSuccess,warning:c.config.onWarning,error:c.config.onError,info:c.config.onInfo};return yield*m(l,w[i])}));return(e,n)=>(C(),k(T,{"action-id":d.buttonId,effect:v(y)},null,8,["action-id","effect"]))}});export{I as default};
1
+ import{d as _,an as j,ae as B,aq as r,az as m,aA as E,aB as S,e as k,u as v,aj as x,ak as L,am as b,o as C,al as R}from"./index-DOUzPsqV.js";import{_ as T}from"./definition.vue_vue_type_script_setup_true_lang-CvzBdDHI.js";const I=_({name:"ShwfedHttpDownloadActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(d){const c=d,g=R(),t=(e,n)=>x(e,{...L(g),...n}),l=b(),p=new Set(["success","error","warning","info"]);function f(e){const n=URL.createObjectURL(e),o=document.createElement("a");o.href=n,o.download=e.name,document.body.appendChild(o),o.click(),o.remove(),URL.revokeObjectURL(n)}const y=j(()=>B(function*(){const{template:e,messageExpression:n,resultExpression:o}=c.config,u=yield*t(e.request);if(!e.download){const s=yield*u.file();return yield*r(()=>f(s)),yield*m(l,c.config.onSuccess)}const a={json:yield*u.json()},i=o===void 0?"success":yield*E(t(o,a),s=>p.has(s)?s:"success");if(n!==void 0){const s=yield*t(n,a);yield*r(()=>S[i](s))}if(i==="success"||i==="info"){const h=yield*(yield*t(e.download,a)).file();yield*r(()=>f(h))}const w={success:c.config.onSuccess,warning:c.config.onWarning,error:c.config.onError,info:c.config.onInfo};return yield*m(l,w[i])}));return(e,n)=>(C(),k(T,{"action-id":d.buttonId,effect:v(y)},null,8,["action-id","effect"]))}});export{I as default};
@@ -1 +1 @@
1
- import{d as s,ad as B,ar as E,ae as _,af as i,as as x,at as p,e as M,w as c,u as d,a0 as N,am as b,aq as k,o as w,f as L,au as T,g as u,av as I,aw as H,a7 as S,al as V,ax as $,ay as z}from"./index-BT8fF6jA.js";import{_ as A}from"./definition.vue_vue_type_script_setup_true_lang-CiwBbLRf.js";const F=s({name:"ShwfedModalLayoutActionRuntime",__name:"runtime",props:{buttonId:{},config:{},buttonTitle:{}},setup(a){const n=a,{locale:l}=B(),f=e=>{},r=V(),m=b(),o=N(null),v=E(n.buttonId,{close:()=>k(()=>{o.value?.()})},m),g=s({name:"ModalBoundaryBridge",setup(e,{slots:t}){return H(r),$(z,v),()=>t.default?.()}}),h=(e,t)=>S()?.(e,t),C=_(function*(){const e=i(n.config.modalTitle,l.value)??i(n.buttonTitle,l.value)??"",{modal:t,close:y}=yield*x({title:e,width:n.config.modalWidth});o.value=()=>p(y()),yield*t,o.value=null});return(e,t)=>(w(),M(A,{"action-id":a.buttonId,effect:d(C)},{default:c(()=>[L("div",{style:T(a.config.modalMinHeight?`min-height: ${a.config.modalMinHeight}`:void 0)},[u(d(g),null,{default:c(()=>[u(I,{"slot-value":a.config.slot,configure:f,"find-entry":h},null,8,["slot-value"])]),_:1})],4)]),_:1},8,["action-id","effect"]))}});export{F as default};
1
+ import{d as s,ad as B,ar as E,ae as _,af as i,as as x,at as p,e as M,w as c,u as d,a0 as N,am as b,aq as k,o as w,f as L,au as T,g as u,av as I,aw as H,a7 as S,al as V,ax as $,ay as z}from"./index-DOUzPsqV.js";import{_ as A}from"./definition.vue_vue_type_script_setup_true_lang-CvzBdDHI.js";const F=s({name:"ShwfedModalLayoutActionRuntime",__name:"runtime",props:{buttonId:{},config:{},buttonTitle:{}},setup(a){const n=a,{locale:l}=B(),f=e=>{},r=V(),m=b(),o=N(null),v=E(n.buttonId,{close:()=>k(()=>{o.value?.()})},m),g=s({name:"ModalBoundaryBridge",setup(e,{slots:t}){return H(r),$(z,v),()=>t.default?.()}}),h=(e,t)=>S()?.(e,t),C=_(function*(){const e=i(n.config.modalTitle,l.value)??i(n.buttonTitle,l.value)??"",{modal:t,close:y}=yield*x({title:e,width:n.config.modalWidth});o.value=()=>p(y()),yield*t,o.value=null});return(e,t)=>(w(),M(A,{"action-id":a.buttonId,effect:d(C)},{default:c(()=>[L("div",{style:T(a.config.modalMinHeight?`min-height: ${a.config.modalMinHeight}`:void 0)},[u(d(g),null,{default:c(()=>[u(I,{"slot-value":a.config.slot,configure:f,"find-entry":h},null,8,["slot-value"])]),_:1})],4)]),_:1},8,["action-id","effect"]))}});export{F as default};
@@ -1 +1 @@
1
- import{d as f,ad as u,ae as l,af as g,ag as d,ah as m,ai as p,e as x,u as E,aj as _,ak as h,al as k,am as w,o as C}from"./index-BT8fF6jA.js";import{_ as I}from"./definition.vue_vue_type_script_setup_true_lang-CiwBbLRf.js";const R=f({name:"ShwfedHttpRequestConfirmActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(s){const n=s,{locale:c}=u(),a=k(),t=(e,o)=>_(e,{...h(a),...o}),i=w(),r=l(function*(){const e=g(n.config.markdown,c.value)??"",o=d(e,t);(yield*m({content:o,icon:n.config.icon,color:n.config.color}))||(yield*p(n.config.expression,t,{messageExpression:n.config.messageExpression,resultExpression:n.config.resultExpression,channel:i,triggers:{success:n.config.onSuccess,warning:n.config.onWarning,error:n.config.onError,info:n.config.onInfo}}))});return(e,o)=>(C(),x(I,{"action-id":s.buttonId,effect:E(r)},null,8,["action-id","effect"]))}});export{R as default};
1
+ import{d as f,ad as u,ae as l,af as g,ag as d,ah as m,ai as p,e as x,u as E,aj as _,ak as h,al as k,am as w,o as C}from"./index-DOUzPsqV.js";import{_ as I}from"./definition.vue_vue_type_script_setup_true_lang-CvzBdDHI.js";const R=f({name:"ShwfedHttpRequestConfirmActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(s){const n=s,{locale:c}=u(),a=k(),t=(e,o)=>_(e,{...h(a),...o}),i=w(),r=l(function*(){const e=g(n.config.markdown,c.value)??"",o=d(e,t);(yield*m({content:o,icon:n.config.icon,color:n.config.color}))||(yield*p(n.config.expression,t,{messageExpression:n.config.messageExpression,resultExpression:n.config.resultExpression,channel:i,triggers:{success:n.config.onSuccess,warning:n.config.onWarning,error:n.config.onError,info:n.config.onInfo}}))});return(e,o)=>(C(),x(I,{"action-id":s.buttonId,effect:E(r)},null,8,["action-id","effect"]))}});export{R as default};
@@ -1 +1 @@
1
- import{_ as s}from"./definition.vue_vue_type_script_setup_true_lang-CiwBbLRf.js";import{d as c,an as o,az as i,e as r,u as f,am as u,o as m}from"./index-BT8fF6jA.js";const g=c({name:"ShwfedEventDispatchActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(e){const n=e,t=u(),a=o(()=>i(t,n.config.triggers));return(p,d)=>(m(),r(s,{"action-id":e.buttonId,effect:f(a)},null,8,["action-id","effect"]))}});export{g as default};
1
+ import{_ as s}from"./definition.vue_vue_type_script_setup_true_lang-CvzBdDHI.js";import{d as c,an as o,az as i,e as r,u as f,am as u,o as m}from"./index-DOUzPsqV.js";const g=c({name:"ShwfedEventDispatchActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(e){const n=e,t=u(),a=o(()=>i(t,n.config.triggers));return(p,d)=>(m(),r(s,{"action-id":e.buttonId,effect:f(a)},null,8,["action-id","effect"]))}});export{g as default};
@@ -1 +1 @@
1
- import{_ as o}from"./definition.vue_vue_type_script_setup_true_lang-CiwBbLRf.js";import{d as n,e as a,u as c,o as f,ao as i}from"./index-BT8fF6jA.js";const _=n({name:"ShwfedPrototypeActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(e){const t=i;return(r,s)=>(f(),a(o,{"action-id":e.buttonId,effect:c(t)},null,8,["action-id","effect"]))}});export{_ as default};
1
+ import{_ as o}from"./definition.vue_vue_type_script_setup_true_lang-CvzBdDHI.js";import{d as n,e as a,u as c,o as f,ao as i}from"./index-DOUzPsqV.js";const _=n({name:"ShwfedPrototypeActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(e){const t=i;return(r,s)=>(f(),a(o,{"action-id":e.buttonId,effect:c(t)},null,8,["action-id","effect"]))}});export{_ as default};
@@ -1 +1 @@
1
- import{d as u,ad as l,e as i,u as p,$ as d,o as m,k as f,af as _,ag as k,aj as g,ak as w,al as x}from"./index-BT8fF6jA.js";const B=u({name:"ShwfedMarkdownItemRuntime",__name:"runtime",props:{config:{}},setup(n){const s=n,{locale:o}=l(),t=x(),c=(e,a)=>g(e,{...w(t),...a}),r=d(()=>{const e=_(s.config.content,o.value)??"";return k(e,c)});return(e,a)=>(m(),i(p(f),{"data-slot":"buttons-markdown",source:r.value,class:"prose prose-sm prose-zinc px-1"},null,8,["source"]))}});export{B as default};
1
+ import{d as u,ad as l,e as i,u as p,$ as d,o as m,k as f,af as _,ag as k,aj as g,ak as w,al as x}from"./index-DOUzPsqV.js";const B=u({name:"ShwfedMarkdownItemRuntime",__name:"runtime",props:{config:{}},setup(n){const s=n,{locale:o}=l(),t=x(),c=(e,a)=>g(e,{...w(t),...a}),r=d(()=>{const e=_(s.config.content,o.value)??"";return k(e,c)});return(e,a)=>(m(),i(p(f),{"data-slot":"buttons-markdown",source:r.value,class:"prose prose-sm prose-zinc px-1"},null,8,["source"]))}});export{B as default};
@@ -1 +1 @@
1
- import{d as i,an as f,ap as r,aq as d,e as u,u as m,aj as p,ak as l,al as _,o as g}from"./index-BT8fF6jA.js";import{_ as h}from"./definition.vue_vue_type_script_setup_true_lang-CiwBbLRf.js";const x=i({name:"ShwfedNavigationActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(e){const t=e,o=_(),c=(n,a)=>p(n,{...l(o),...a}),s=f(()=>r(c(t.config.url),n=>d(()=>{window.open(n,t.config.mode)})));return(n,a)=>(g(),u(h,{"action-id":e.buttonId,effect:m(s)},null,8,["action-id","effect"]))}});export{x as default};
1
+ import{d as i,an as f,ap as r,aq as d,e as u,u as m,aj as p,ak as l,al as _,o as g}from"./index-DOUzPsqV.js";import{_ as h}from"./definition.vue_vue_type_script_setup_true_lang-CvzBdDHI.js";const x=i({name:"ShwfedNavigationActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(e){const t=e,o=_(),c=(n,a)=>p(n,{...l(o),...a}),s=f(()=>r(c(t.config.url),n=>d(()=>{window.open(n,t.config.mode)})));return(n,a)=>(g(),u(h,{"action-id":e.buttonId,effect:m(s)},null,8,["action-id","effect"]))}});export{x as default};
@@ -1 +1 @@
1
- import{d as r,an as f,ai as u,e as p,u as g,aj as m,ak as l,al as d,am as x,o as E}from"./index-BT8fF6jA.js";import{_}from"./definition.vue_vue_type_script_setup_true_lang-CiwBbLRf.js";const k=r({name:"ShwfedHttpRequestActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(n){const e=n,t=d(),c=(s,o)=>m(s,{...l(t),...o}),i=x(),a=f(()=>u(e.config.expression,c,{messageExpression:e.config.messageExpression,resultExpression:e.config.resultExpression,channel:i,triggers:{success:e.config.onSuccess,warning:e.config.onWarning,error:e.config.onError,info:e.config.onInfo}}));return(s,o)=>(E(),p(_,{"action-id":n.buttonId,effect:g(a)},null,8,["action-id","effect"]))}});export{k as default};
1
+ import{d as r,an as f,ai as u,e as p,u as g,aj as m,ak as l,al as d,am as x,o as E}from"./index-DOUzPsqV.js";import{_}from"./definition.vue_vue_type_script_setup_true_lang-CvzBdDHI.js";const k=r({name:"ShwfedHttpRequestActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(n){const e=n,t=d(),c=(s,o)=>m(s,{...l(t),...o}),i=x(),a=f(()=>u(e.config.expression,c,{messageExpression:e.config.messageExpression,resultExpression:e.config.resultExpression,channel:i,triggers:{success:e.config.onSuccess,warning:e.config.onWarning,error:e.config.onError,info:e.config.onInfo}}));return(s,o)=>(E(),p(_,{"action-id":n.buttonId,effect:g(a)},null,8,["action-id","effect"]))}});export{k as default};
@@ -10,8 +10,8 @@
10
10
  `--primary`, the primary button variant renders as transparent. */
11
11
  body { --primary: #009689; }
12
12
  </style>
13
- <script type="module" crossorigin src="./assets/index-BT8fF6jA.js"></script>
14
- <link rel="stylesheet" crossorigin href="./assets/index-Br_eXThF.css">
13
+ <script type="module" crossorigin src="./assets/index-DOUzPsqV.js"></script>
14
+ <link rel="stylesheet" crossorigin href="./assets/index-BUyz4nJb.css">
15
15
  </head>
16
16
  <body>
17
17
  <div id="app"></div>
@@ -2,7 +2,7 @@
2
2
  import { Icon } from "@iconify/vue";
3
3
  import { Effect, Fiber, Option } from "effect";
4
4
  import { Fetch } from "fx-fetch";
5
- import { computed, ref, watch } from "vue";
5
+ import { computed, ref, shallowRef, watch } from "vue";
6
6
  import { useI18n } from "vue-i18n";
7
7
  import { cel as _rawCel } from "../../../../../utils/cel";
8
8
  import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
@@ -10,6 +10,7 @@ import { getLocalizedText } from "../../../../../share/locale";
10
10
  import { Field, FieldLabel } from "../../../../ui/field";
11
11
  import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "../../../../ui/input-group";
12
12
  import { Markdown } from "../../../../ui/markdown";
13
+ import { Skeleton } from "../../../../ui/skeleton";
13
14
  import { Tree as UiTree } from "../../../../ui/tree";
14
15
  import { interpolateMarkdown } from "../../../../table/utils/runtime";
15
16
  import { useFormReadonly } from "../../../utils/readonly";
@@ -26,7 +27,6 @@ const { locale, t } = useI18n({
26
27
  "tree-multi-search-label": "\u641C\u7D22",
27
28
  "tree-multi-search-clear": "\u6E05\u9664\u641C\u7D22",
28
29
  "tree-multi-load-error": "\u52A0\u8F7D\u5931\u8D25",
29
- "tree-multi-loading": "\u52A0\u8F7D\u4E2D\u2026",
30
30
  "tree-multi-empty": "\u65E0\u53EF\u9009\u9879",
31
31
  "tree-multi-readonly-empty": "\u2014",
32
32
  "tree-multi-readonly-separator": "\u3001"
@@ -35,7 +35,6 @@ const { locale, t } = useI18n({
35
35
  "tree-multi-search-label": "Search",
36
36
  "tree-multi-search-clear": "Clear search",
37
37
  "tree-multi-load-error": "Failed to load",
38
- "tree-multi-loading": "Loading\u2026",
39
38
  "tree-multi-empty": "No options",
40
39
  "tree-multi-readonly-empty": "\u2014",
41
40
  "tree-multi-readonly-separator": ", "
@@ -44,7 +43,6 @@ const { locale, t } = useI18n({
44
43
  "tree-multi-search-label": "\u691C\u7D22",
45
44
  "tree-multi-search-clear": "\u691C\u7D22\u3092\u30AF\u30EA\u30A2",
46
45
  "tree-multi-load-error": "\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
47
- "tree-multi-loading": "\u8AAD\u307F\u8FBC\u307F\u4E2D\u2026",
48
46
  "tree-multi-empty": "\u9078\u629E\u80A2\u306A\u3057",
49
47
  "tree-multi-readonly-empty": "\u2014",
50
48
  "tree-multi-readonly-separator": "\u3001"
@@ -222,15 +220,36 @@ function evalKeywords(node) {
222
220
  return [];
223
221
  }
224
222
  }
223
+ const searchCorpus = shallowRef(/* @__PURE__ */ new Map());
224
+ watch(
225
+ () => [
226
+ roots.value,
227
+ locale.value,
228
+ props.config.nodeLabel,
229
+ props.config.filter?.keywords
230
+ ],
231
+ () => {
232
+ const map = /* @__PURE__ */ new Map();
233
+ const stack = [...roots.value];
234
+ while (stack.length) {
235
+ const n = stack.pop();
236
+ const label = nodeLabelText(n).trim().toLowerCase();
237
+ const kw = evalKeywords(n).map((k) => k.trim().toLowerCase()).join("\n");
238
+ map.set(getKey(n), kw ? `${label}
239
+ ${kw}` : label);
240
+ const kids = getChildren(n);
241
+ if (kids && kids.length) stack.push(...kids);
242
+ }
243
+ searchCorpus.value = map;
244
+ },
245
+ { immediate: true }
246
+ );
225
247
  function filterPredicate(node, query) {
226
248
  const q = query.trim().toLowerCase();
227
249
  if (!q) return true;
228
- const label = nodeLabelText(node).trim().toLowerCase();
229
- if (label.includes(q)) return true;
230
- for (const k of evalKeywords(node)) {
231
- if (k.trim().toLowerCase().includes(q)) return true;
232
- }
233
- return false;
250
+ const hay = searchCorpus.value.get(getKey(node));
251
+ if (hay !== void 0) return hay.includes(q);
252
+ return nodeLabelText(node).trim().toLowerCase().includes(q);
234
253
  }
235
254
  const filterLabelText = computed(() => {
236
255
  const localized = props.config.filter?.label ? getLocalizedText(props.config.filter.label, locale.value) : void 0;
@@ -319,9 +338,13 @@ const readonlyText = computed(() => {
319
338
  </div>
320
339
  <div
321
340
  v-else-if="loading && roots.length === 0"
322
- class="min-h-9 py-1.5 text-sm text-zinc-400"
341
+ class="flex flex-col gap-1.5 py-1"
342
+ aria-busy="true"
323
343
  >
324
- {{ t("tree-multi-loading") }}
344
+ <Skeleton class="h-6 w-2/3" />
345
+ <Skeleton class="h-6 w-1/2" />
346
+ <Skeleton class="h-6 w-3/5" />
347
+ <Skeleton class="h-6 w-2/5" />
325
348
  </div>
326
349
 
327
350
  <UiTree
@@ -336,6 +359,7 @@ const readonlyText = computed(() => {
336
359
  :filter-predicate="filterPredicate"
337
360
  :filter-query="filterQuery"
338
361
  :initial-expanded="initialExpanded"
362
+ :show-focused-row="false"
339
363
  :class="isDisabled ? 'pointer-events-none opacity-60' : void 0"
340
364
  >
341
365
  <template #node="{ node }">
@@ -23,6 +23,13 @@ declare const __VLS_export: <Node>(__VLS_props: NonNullable<Awaited<typeof __VLS
23
23
  filterQuery?: string;
24
24
  /** Initial expanded set (uncontrolled). */
25
25
  initialExpanded?: NodeKey[];
26
+ /**
27
+ * Paint the focused row with a subtle background. Keyboard navigation
28
+ * still tracks focus either way — this only controls the visual. Forms
29
+ * and similar surfaces that don't expose keyboard nav to users can turn
30
+ * it off so a stray click doesn't leave a permanent highlight.
31
+ */
32
+ showFocusedRow?: boolean;
26
33
  } & {
27
34
  onMove?: ((payload: MoveEventPayload) => any) | undefined;
28
35
  "onUpdate:modelValue"?: ((value: string | string[] | undefined) => any) | undefined;
@@ -16,7 +16,8 @@ const props = defineProps({
16
16
  canDrop: { type: Function, required: false, default: void 0 },
17
17
  filterPredicate: { type: Function, required: false, default: void 0 },
18
18
  filterQuery: { type: String, required: false, default: "" },
19
- initialExpanded: { type: Array, required: false, default: () => [] }
19
+ initialExpanded: { type: Array, required: false, default: () => [] },
20
+ showFocusedRow: { type: Boolean, required: false, default: true }
20
21
  });
21
22
  const emit = defineEmits(["update:modelValue", "update:roots", "move"]);
22
23
  defineSlots();
@@ -275,6 +276,7 @@ const selectedPanePayload = computed(() => ({
275
276
  :is-expandable="isExpandable"
276
277
  :tree="tree"
277
278
  :focused-key="state.focusedKey.value"
279
+ :show-focused-row="showFocusedRow"
278
280
  @toggle-expand="handleToggleExpand"
279
281
  @toggle-select="handleToggleSelect"
280
282
  @focus-row="handleFocusRow"
@@ -23,6 +23,13 @@ declare const __VLS_export: <Node>(__VLS_props: NonNullable<Awaited<typeof __VLS
23
23
  filterQuery?: string;
24
24
  /** Initial expanded set (uncontrolled). */
25
25
  initialExpanded?: NodeKey[];
26
+ /**
27
+ * Paint the focused row with a subtle background. Keyboard navigation
28
+ * still tracks focus either way — this only controls the visual. Forms
29
+ * and similar surfaces that don't expose keyboard nav to users can turn
30
+ * it off so a stray click doesn't leave a permanent highlight.
31
+ */
32
+ showFocusedRow?: boolean;
26
33
  } & {
27
34
  onMove?: ((payload: MoveEventPayload) => any) | undefined;
28
35
  "onUpdate:modelValue"?: ((value: string | string[] | undefined) => any) | undefined;
@@ -25,6 +25,7 @@ declare const __VLS_export: <Node>(__VLS_props: NonNullable<Awaited<typeof __VLS
25
25
  isExpandable: (n: Node) => boolean;
26
26
  tree: TreeHandle<Node>;
27
27
  focusedKey: NodeKey | null;
28
+ showFocusedRow: boolean;
28
29
  } & {
29
30
  "onToggle-expand"?: ((key: string) => any) | undefined;
30
31
  "onToggle-select"?: ((key: string) => any) | undefined;
@@ -27,7 +27,8 @@ const props = defineProps({
27
27
  filterQuery: { type: String, required: true },
28
28
  isExpandable: { type: Function, required: true },
29
29
  tree: { type: Object, required: true },
30
- focusedKey: { type: [String, null], required: true }
30
+ focusedKey: { type: [String, null], required: true },
31
+ showFocusedRow: { type: Boolean, required: true }
31
32
  });
32
33
  const emit = defineEmits(["toggle-expand", "toggle-select", "focus-row"]);
33
34
  defineSlots();
@@ -109,7 +110,7 @@ const showChildren = computed(
109
110
  v-if="subtreeMatches"
110
111
  :class="cn(
111
112
  'group flex items-center justify-between gap-2 rounded px-1 py-1 outline-none',
112
- focusedKey === key && 'bg-(--primary)/10'
113
+ showFocusedRow && focusedKey === key && 'bg-(--primary)/10'
113
114
  )"
114
115
  tabindex="-1"
115
116
  @click.stop="emit('focus-row', key)"
@@ -250,6 +251,7 @@ const showChildren = computed(
250
251
  :is-expandable="isExpandable"
251
252
  :tree="tree"
252
253
  :focused-key="focusedKey"
254
+ :show-focused-row="showFocusedRow"
253
255
  @toggle-expand="(k) => emit('toggle-expand', k)"
254
256
  @toggle-select="(k) => emit('toggle-select', k)"
255
257
  @focus-row="(k) => emit('focus-row', k)"
@@ -25,6 +25,7 @@ declare const __VLS_export: <Node>(__VLS_props: NonNullable<Awaited<typeof __VLS
25
25
  isExpandable: (n: Node) => boolean;
26
26
  tree: TreeHandle<Node>;
27
27
  focusedKey: NodeKey | null;
28
+ showFocusedRow: boolean;
28
29
  } & {
29
30
  "onToggle-expand"?: ((key: string) => any) | undefined;
30
31
  "onToggle-select"?: ((key: string) => any) | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shwfed/config",
3
- "version": "2.3.16",
3
+ "version": "2.3.17",
4
4
  "description": "Configurable UI for SHWFED",
5
5
  "type": "module",
6
6
  "publishConfig": {