@jayyuen66/dsh-plugin-shared 0.2.3 → 0.2.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.
@@ -0,0 +1,105 @@
1
+ import{createElement as e,useCallback as t,useEffect as n,useId as r,useLayoutEffect as i,useMemo as a,useRef as o,useState as s}from"react";const c=`
2
+ .dsu-form{display:flex;flex-direction:column}
3
+ .dsu-section{margin-top:24px;padding-top:24px;border-top:.5px solid var(--dsw-alias-border-l1)}
4
+ .dsu-form>.dsu-section:first-child{margin-top:0;padding-top:0;border-top:0}
5
+ .dsu-sectionTitle{margin:0;font-size:15px;font-weight:600;line-height:1.4;color:var(--dsw-alias-label-primary)}
6
+ .dsu-sectionHint{margin:4px 0 0;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
7
+ .dsu-statusbar{display:flex;flex-wrap:wrap;gap:4px 8px;margin-top:8px;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
8
+ .dsu-field{display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,360px);column-gap:32px;align-items:center;padding:12px 0;border-top:.5px solid var(--dsw-alias-border-l2)}
9
+ .dsu-fieldMeta{display:flex;flex-direction:column;gap:4px;min-width:0}
10
+ .dsu-labelRow{display:flex;align-items:center;gap:6px;min-width:0}
11
+ .dsu-label{font-size:13px;font-weight:500;line-height:1.5;color:var(--dsw-alias-label-primary)}
12
+ .dsu-labelMono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px}
13
+ .dsu-hint{margin:0;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
14
+ .dsu-control{min-width:0;display:flex;align-items:center;gap:8px}
15
+ .dsu-fieldWide{grid-template-columns:minmax(0,1fr);align-items:start}
16
+ .dsu-fieldWide .dsu-control{width:100%;max-width:720px;margin-top:2px}
17
+ .dsu-help{display:inline-flex;align-items:center;gap:6px;min-width:0}
18
+ .dsu-helpBtn{appearance:none;border:0;background:transparent;padding:0;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;color:var(--dsw-alias-label-tertiary);cursor:help;border-radius:50%;flex:none}
19
+ .dsu-help:hover .dsu-helpBtn,.dsu-helpBtn:focus-visible{color:var(--dsw-alias-label-primary)}
20
+ .dsu-helpBtn:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}
21
+ .dsu-tip{position:fixed;z-index:60;box-sizing:border-box;max-width:min(340px,calc(100vw - 16px));max-height:calc(100vh - 16px);overflow:auto;overflow-wrap:anywhere;padding:10px 12px;border-radius:10px;background:var(--dsw-alias-bg-layer-2);border:.5px solid var(--dsw-alias-border-l3);box-shadow:0 12px 32px rgb(0 0 0 / 45%);font-size:12px;line-height:1.6;font-weight:400;color:var(--dsw-alias-label-secondary)}
22
+ .dsu-input{width:100%;height:34px;padding:0 12px;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px}
23
+ .dsu-input:focus-visible{outline:none;border-color:var(--dsw-alias-state-business-primary)}
24
+ .dsu-input[aria-invalid="true"]{border-color:var(--dsw-alias-state-error-primary)}
25
+ .dsu-input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}
26
+ .dsu-input::placeholder{color:var(--dsw-alias-label-tertiary)}
27
+ .dsu-textarea{height:auto;min-height:96px;padding:8px 12px;line-height:1.6;resize:vertical}
28
+ .dsu-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
29
+ .dsu-numberWrap{display:flex;flex-direction:column;gap:4px;width:100%;min-width:0}
30
+ .dsu-number{display:flex;align-items:center;gap:8px;min-width:0}
31
+ .dsu-number .dsu-input{min-width:0}
32
+ .dsu-unit{flex:none;font-size:12px;color:var(--dsw-alias-label-tertiary)}
33
+ .dsu-error{margin:0;font-size:12px;line-height:1.5;color:var(--dsw-alias-state-error-primary)}
34
+ .dsu-switch{appearance:none;width:36px;height:20px;border-radius:999px;border:0;padding:2px;background:var(--dsw-alias-border-l3);display:flex;align-items:center;cursor:pointer;flex:none;transition:background-color .16s}
35
+ .dsu-knob{width:16px;height:16px;border-radius:50%;background:var(--dsw-alias-label-primary);transition:transform .16s,background-color .16s}
36
+ .dsu-switch[aria-checked="true"]{background:var(--dsw-alias-label-primary)}
37
+ .dsu-switch[aria-checked="true"] .dsu-knob{transform:translateX(16px);background:var(--dsw-alias-label-primary-foreground)}
38
+ .dsu-switch:disabled{opacity:.4;cursor:not-allowed}
39
+ .dsu-switch:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}
40
+ .dsu-selectWrap{position:relative;width:100%;min-width:0}
41
+ .dsu-select{display:flex;align-items:center;justify-content:space-between;gap:8px;text-align:left;cursor:pointer}
42
+ .dsu-select[aria-expanded="true"]{border-color:var(--dsw-alias-state-business-primary)}
43
+ .dsu-selectValue{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
44
+ .dsu-chevron{flex:none;color:var(--dsw-alias-label-tertiary);transition:transform .16s}
45
+ .dsu-select[aria-expanded="true"] .dsu-chevron{transform:rotate(180deg)}
46
+ .dsu-menu{position:fixed;position-area:block-end span-inline-start;justify-self:start;margin-top:6px;z-index:70;padding:4px;background:var(--dsw-alias-bg-layer-2);border:.5px solid var(--dsw-alias-border-l3);border-radius:12px;box-shadow:0 12px 32px rgb(0 0 0 / 50%);max-height:280px;overflow:auto}
47
+ .dsu-option{appearance:none;border:0;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;line-height:1.4;width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 10px;border-radius:8px;cursor:pointer;text-align:left}
48
+ .dsu-option:hover,.dsu-option[data-active="true"]{background:var(--dsw-alias-bg-layer-3)}
49
+ .dsu-option:disabled{color:var(--dsw-alias-label-tertiary);cursor:not-allowed}
50
+ .dsu-option:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}
51
+ .dsu-optionGroup{padding:6px 10px 2px;font-size:11px;font-weight:600;color:var(--dsw-alias-label-tertiary)}
52
+ .dsu-check{opacity:0;flex:none}
53
+ .dsu-option[aria-selected="true"] .dsu-check{opacity:1}
54
+ .dsu-savebar{display:flex;align-items:center;gap:8px;padding:12px 0;margin-top:24px;border-top:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base)}
55
+ .dsu-savebar[data-dirty="true"]{position:sticky;bottom:0;z-index:2;box-shadow:0 -12px 24px rgb(0 0 0 / 35%)}
56
+ .dsu-btn{appearance:none;border:.5px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;line-height:1.5;border-radius:var(--dsw-radius-md);padding:5px 14px;cursor:pointer;transition:background-color .12s,border-color .12s,color .12s,filter .12s}
57
+ .dsu-btn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-border-l3)}
58
+ .dsu-btn:active:not(:disabled){background:var(--dsw-alias-bg-layer-1)}
59
+ .dsu-btn:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}
60
+ .dsu-btn:disabled{opacity:.4;cursor:not-allowed}
61
+ .dsu-btnPrimary{background:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}
62
+ .dsu-btnPrimary:hover:not(:disabled){background:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary);filter:brightness(.9)}
63
+ .dsu-btnPrimary:active:not(:disabled){background:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary);filter:brightness(.84)}
64
+ .dsu-btnDanger{color:var(--dsw-alias-state-error-primary)}
65
+ .dsu-btnDanger:hover:not(:disabled){color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-2)}
66
+ .dsu-status{margin-left:auto;font-size:12px;color:var(--dsw-alias-label-tertiary)}
67
+ .dsu-statusError{color:var(--dsw-alias-state-error-primary)}
68
+ .dsu-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(200px,100%),1fr));gap:0 24px}
69
+ .dsu-grid>.dsu-field{display:flex;flex-direction:column;align-items:stretch;gap:6px;padding:10px 0;border-top:.5px solid var(--dsw-alias-border-l1)}
70
+ .dsu-grid>.dsu-field .dsu-control{width:100%}
71
+ @media (max-width:640px){
72
+ .dsu-field{grid-template-columns:minmax(0,1fr);align-items:start}
73
+ .dsu-control{width:100%;max-width:720px}
74
+ .dsu-section{margin-top:20px;padding-top:20px}
75
+ }
76
+ @media (prefers-reduced-motion:reduce){
77
+ .dsu-switch,.dsu-knob,.dsu-chevron,.dsu-btn{transition:none}
78
+ }
79
+ `;function l(e,t=30){return e.length<=t?{hint:e}:{detail:e}}function u(t){return e(`div`,{className:`dsu-form`},t.children)}function d(t){return e(`section`,{className:`dsu-section`},e(`h2`,{className:`dsu-sectionTitle`},t.title),t.hint===void 0?null:e(`p`,{className:`dsu-sectionHint`},t.hint),t.children)}function f(t){return e(`div`,{className:`dsu-grid`},t.children)}function p(t){if(t.items.length===0)return null;let n=t.items.map((t,n)=>e(`span`,{key:n},n===0?t:`· ${t}`));return e(`div`,{className:`dsu-statusbar`},...n)}function m(a){let c=r(),[l,u]=s(!1),[d,f]=s(!1),p=o(!1),m=o(!1),h=o(!1),g=o(null),_=o(null),v=o(null),y=t(()=>{v.current!==null&&(clearTimeout(v.current),v.current=null)},[]),b=t(()=>{let e=g.current,t=_.current;
80
+ /* v8 ignore next 3 -- place 只在 open 的 layout effect 与挂载期监听器里调用;refs 为空只可能是卸载竞态 */
81
+ if(e===null||t===null)return;let n=e.getBoundingClientRect(),r=t.offsetWidth,i=t.offsetHeight,{left:a}=n,o=n.bottom+8;o+i>window.innerHeight-8&&(o=n.top-i-8),a+r>window.innerWidth-8&&(a=window.innerWidth-r-8);let s=Math.max(8,window.innerWidth-r-8),c=Math.max(8,window.innerHeight-i-8);t.style.left=`${Math.min(Math.max(8,a),s)}px`,t.style.top=`${Math.min(Math.max(8,o),c)}px`},[]),x=t(()=>{y(),h.current=!1,f(!1),u(!1)},[y]),S=t(()=>{y(),u(!0)},[y]),C=t(()=>{y(),p.current||m.current||h.current||(v.current=setTimeout(()=>{
82
+ /* v8 ignore next 3 -- 任何重新进入/钉住都会 cancelHide;这次复查只防未来的异步路径 */
83
+ v.current=null,p.current||m.current||h.current||u(!1)},120))},[y]),w=t(e=>{h.current=e,f(e)},[]);i(()=>{if(!l)return()=>{};b();let e=e=>{let{target:t}=e;t instanceof Node&&_.current?.contains(t)===!0||(h.current?b():x())},t=()=>{b()};return window.addEventListener(`scroll`,e,!0),window.addEventListener(`resize`,t),()=>{window.removeEventListener(`scroll`,e,!0),window.removeEventListener(`resize`,t)}},[l,a.detail,b,x]),n(()=>{if(!l)return()=>{};let e=e=>{e.key===`Escape`&&x()};return document.addEventListener(`keydown`,e),()=>{document.removeEventListener(`keydown`,e)}},[l,x]),n(()=>y,[y]);let T=e(`button`,{ref:g,type:`button`,className:`dsu-helpBtn`,"aria-label":`${a.label} 说明`,"aria-describedby":c,"aria-pressed":d,onClick:()=>{h.current?x():(w(!0),S())}},e(`svg`,{width:12,height:12,viewBox:`0 0 14 14`,"aria-hidden":!0},e(`circle`,{cx:7,cy:7,r:6,fill:`none`,stroke:`currentColor`,strokeWidth:1.2}),e(`path`,{d:`M7 6.2v4`,stroke:`currentColor`,strokeWidth:1.3,strokeLinecap:`round`}),e(`circle`,{cx:7,cy:4.3,r:.8,fill:`currentColor`}))),E=e(`div`,{ref:_,id:c,role:`tooltip`,className:`dsu-tip`,hidden:!l},a.detail),D=a.showLabel===!1?null:e(`span`,{className:`dsu-label${a.compact===!0?` dsu-labelMono`:``}`},a.label);return e(`span`,{className:`dsu-help`,onMouseEnter:()=>{p.current=!0,S()},onMouseLeave:()=>{p.current=!1,C()},onFocus:()=>{m.current=!0,S()},onBlur:e=>{let t=e.relatedTarget;t instanceof Node&&e.currentTarget.contains(t)||(m.current=!1,C())}},D,T,E)}function h(t){let n=`dsu-label${t.compact===!0?` dsu-labelMono`:``}`,r=t.controlId===void 0?e(`span`,{className:n},t.label):e(`label`,{className:n,htmlFor:t.controlId},t.label);return e(`div`,{className:`dsu-labelRow`},r,t.detail===void 0?null:e(m,{label:t.label,detail:t.detail,showLabel:!1}))}function g(t){let n=t.controlId===void 0?void 0:`${t.controlId}-hint`;return e(`div`,{className:`dsu-field${t.wide===!0?` dsu-fieldWide`:``}`},e(`div`,{className:`dsu-fieldMeta`},e(h,{label:t.label,detail:t.detail,compact:t.compact,controlId:t.controlId}),t.hint===void 0?null:e(`p`,{className:`dsu-hint`,id:n},t.hint)),e(`div`,{className:`dsu-control`},t.children))}function _(t){let n=r(),i=t.hint===void 0?void 0:`${n}-hint`;return e(g,{...t,controlId:n},e(`button`,{type:`button`,role:`switch`,id:n,className:`dsu-switch`,"aria-checked":t.checked,"aria-describedby":i,"data-field":t.field,disabled:t.disabled===!0,onClick:()=>{t.onChange(!t.checked)}},e(`span`,{className:`dsu-knob`})))}function v(t){let i=typeof t.value==`number`&&Number.isFinite(t.value)?String(t.value):``,[a,c]=s(i),[l,u]=s(!1),d=o(void 0),f=r(),p=r(),m=[t.hint===void 0?void 0:`${f}-hint`,l?p:void 0].filter(e=>e!==void 0),h=m.length===0?void 0:m.join(` `);n(()=>{t.value!==d.current&&(d.current=t.value,c(i),u(!1))},[t.value,i]);let _=e=>{let n=t.min??-1/0,r=t.max??1/0;if(!Number.isFinite(e)||e<n||e>r)return!1;let{step:i}=t;if(i===void 0||i<=0)return!0;let a=(e-(t.min??0))/i;return Math.abs(a-Math.round(a))<1e-9},v=e=>{if(c(e),e===``){u(!1),d.current=void 0,t.onChange(void 0);return}let n=Number(e);_(n)?(u(!1),d.current=n,t.onChange(n)):u(!0)},y=()=>{a===``||l||c(String(Number(a)))};return e(g,{...t,controlId:f},e(`div`,{className:`dsu-numberWrap`},e(`div`,{className:`dsu-number`},e(`input`,{className:`dsu-input`,type:`number`,inputMode:`numeric`,id:f,value:a,min:t.min,max:t.max,step:t.step,placeholder:t.placeholder,"aria-invalid":l||void 0,"aria-describedby":h,"data-field":t.field,disabled:t.disabled===!0,onChange:e=>{v(e.target.value)},onBlur:y}),t.unit===void 0?null:e(`span`,{className:`dsu-unit`},t.unit)),l?e(`p`,{className:`dsu-error`,id:p},t.invalidHint):null))}function y(t){let[i,a]=s(t.value),[o,c]=s(!1),l=r(),u=t.hint===void 0?void 0:`${l}-hint`;n(()=>{o||a(t.value)},[t.value,o]);let d={id:l,className:`dsu-input${t.multiline===!0?` dsu-textarea`:``}${t.monospace===!0?` dsu-mono`:``}`,value:i,placeholder:t.placeholder,"aria-describedby":u,"data-field":t.field,disabled:t.disabled===!0,onFocus:()=>{c(!0)},onBlur:()=>{c(!1)},onChange:e=>{a(e.target.value),t.onChange(e.target.value)}};return e(g,{...t,controlId:l},t.multiline===!0?e(`textarea`,d):e(`input`,d))}function b(t){let i=t.separator??`comma`,a=t.value.join(i===`newline`?`
84
+ `:`, `),[o,c]=s(a),[l,u]=s(!1),d=r(),f=t.hint===void 0?void 0:`${d}-hint`;n(()=>{l||c(a)},[a,l]);let p=e=>e.split(i===`newline`?`
85
+ `:`,`).map(e=>e.trim()).filter(e=>e.length>0),m={id:d,className:`dsu-input${i===`newline`?` dsu-textarea dsu-mono`:``}`,value:o,placeholder:t.placeholder,"aria-describedby":f,"data-field":t.field,disabled:t.disabled===!0,onFocus:()=>{u(!0)},onBlur:()=>{u(!1)},onChange:e=>{c(e.target.value),t.onChange(p(e.target.value))}};return e(g,{...t,controlId:d},e(i===`newline`?`textarea`:`input`,m))}function x(){return`happyDOM`in globalThis?!1:typeof CSS<`u`&&typeof CSS.supports==`function`&&CSS.supports(`position-area: block-end`)}function S(c){let[l,u]=s(!1),[d,f]=s(0),p=o(null),m=o(null),h=r(),_=r(),v=`--dsu-${_.replaceAll(/[^a-zA-Z0-9]/gu,``)}`,y=c.hint===void 0?void 0:`${_}-hint`,{disabled:b,value:S,options:C,onChange:w}=c,T=a(()=>C.map((e,t)=>({option:e,index:t})).filter(e=>e.option.disabled!==!0),[C]),E=C.find(e=>e.value===S)?.label??S,D=C[d],O=D!==void 0&&D.disabled!==!0,k=t(()=>{let e=p.current,t=m.current;
86
+ /* v8 ignore next 3 -- place 只在 open 的 layout effect 里调用;refs 为空只可能是卸载竞态 */
87
+ if(e===null||t===null)return;let n=e.getBoundingClientRect(),r=Math.min(n.width,window.innerWidth-16);if(t.style.width=`${r}px`,x())return;t.style.marginTop=`0px`;let{left:i}=n;i+r>window.innerWidth-8&&(i=window.innerWidth-r-8);let a=t.offsetHeight,o=n.bottom+6;o+a>window.innerHeight-8&&(o=n.top-a-6);let s=Math.max(8,window.innerWidth-r-8),c=Math.max(8,window.innerHeight-a-8);t.style.left=`${Math.min(Math.max(8,i),s)}px`,t.style.top=`${Math.min(Math.max(8,o),c)}px`},[]),A=t(()=>{u(!1)},[]),j=t(()=>{if(b===!0)return;let e=T.find(e=>e.option.value===S)??T.at(0);e!==void 0&&(f(e.index),u(!0))},[b,S,T]),M=t(e=>{
88
+ /* v8 ignore next 3 -- 浮层只能经由 openMenu 打开;组件禁用时打不开 */
89
+ if(b===!0)return;let t=C[e];
90
+ /* v8 ignore next 3 -- disabled 选项在浏览器里不派发 click;越界下标由调用方保证 */
91
+ t!==void 0&&t.disabled!==!0&&(w(t.value),A(),p.current?.focus())},[b,C,w,A]),N=t(e=>{let t=T.findIndex(e=>e.index===d);
92
+ /* v8 ignore next 5 -- open 时归一 effect 已保证 enabled 非空且 active 落在可用项上 */
93
+ if(t===-1||T.length===0)return;let n=(t+e+T.length)%T.length,r=T[n];
94
+ /* v8 ignore next 3 -- next 由取模保证在界内 */
95
+ r!==void 0&&f(r.index)},[d,T]);i(()=>{if(!l)return()=>{};k();let e=e=>{let t=e.target;m.current?.contains(t)!==!0&&p.current?.contains(t)!==!0&&A()},t=e=>{let{target:t}=e;t instanceof Node&&m.current?.contains(t)===!0||A()},n=()=>{k()};return document.addEventListener(`pointerdown`,e,!0),window.addEventListener(`scroll`,t,!0),window.addEventListener(`resize`,n),()=>{document.removeEventListener(`pointerdown`,e,!0),window.removeEventListener(`scroll`,t,!0),window.removeEventListener(`resize`,n)}},[l,c.options,k,A]),n(()=>{if(!l)return;if(b===!0||T.length===0){A();return}if(T.some(e=>e.index===d))return;let e=T.find(e=>e.option.value===S)??T.at(0);
96
+ /* v8 ignore next 3 -- enabled 非空在上一分支已保证 */
97
+ e!==void 0&&f(e.index)},[l,b,S,C,d,A,T]),i(()=>{if(!l)return;let e=m.current;
98
+ /* v8 ignore next 2 -- 同上,menu 在 open 的 commit 之后必然已挂上 */
99
+ if(e===null)return;let t=e.querySelector(`[data-active="true"]`);
100
+ /* v8 ignore next 2 -- active 已由归一 effect 保证落在可用项上 */
101
+ t!==null&&(t.offsetTop<e.scrollTop?e.scrollTop=t.offsetTop:t.offsetTop+t.offsetHeight>e.scrollTop+e.clientHeight&&(e.scrollTop=t.offsetTop+t.offsetHeight-e.clientHeight))},[l,d,C]);let P=e=>{if(e.key===`ArrowDown`||e.key===`ArrowUp`){if(e.preventDefault(),!l){j();return}N(e.key===`ArrowDown`?1:-1)}else if(e.key===`Home`||e.key===`End`){if(e.preventDefault(),l||j(),T.length===0)return;let t=e.key===`Home`?T.at(0):T.at(-1);
102
+ /* v8 ignore next 3 -- enabled 为空已在上一条返回 */
103
+ if(t===void 0)return;f(t.index)}else if(e.key===`Enter`||e.key===` `){if(e.preventDefault(),!l){j();return}M(d)}else(e.key===`Tab`||e.key===`Escape`)&&A()},F=[],I;for(let[t,n]of C.entries())n.group!==I&&(n.group!==void 0&&F.push(e(`div`,{key:`group-${t}-${n.group}`,className:`dsu-optionGroup`,role:`presentation`},n.group)),I=n.group),F.push(e(`button`,{key:`option-${n.value}`,type:`button`,role:`option`,id:`${h}-${t}`,className:`dsu-option`,tabIndex:-1,"aria-selected":n.value===c.value,"data-active":t===d,disabled:n.disabled===!0,onMouseDown:e=>{e.preventDefault()},onClick:()=>{M(t)},onMouseEnter:()=>{
104
+ /* v8 ignore next -- happy-dom 对 disabled 元素不派发 mouse 事件;浏览器实现各有差异,保留禁用检查 */
105
+ n.disabled!==!0&&f(t)}},e(`span`,null,n.label),e(`svg`,{className:`dsu-check`,width:14,height:14,viewBox:`0 0 14 14`,"aria-hidden":!0},e(`path`,{d:`M2.5 7.5l3 3 6-7`,fill:`none`,stroke:`currentColor`,strokeWidth:1.5,strokeLinecap:`round`,strokeLinejoin:`round`}))));return e(g,{...c,controlId:_},e(`div`,{className:`dsu-selectWrap`,onBlur:e=>{let t=e.relatedTarget;t instanceof Node&&e.currentTarget.contains(t)||A()}},e(`button`,{ref:p,type:`button`,id:_,style:{anchorName:v},className:`dsu-select dsu-input`,role:`combobox`,"aria-haspopup":`listbox`,"aria-expanded":l,"aria-controls":`${h}-list`,"aria-activedescendant":l&&O?`${h}-${d}`:void 0,"aria-describedby":y,"data-field":c.field,disabled:b===!0||C.length===0,onClick:()=>{l?A():j()},onKeyDown:P},e(`span`,{className:`dsu-selectValue`},E),e(`svg`,{className:`dsu-chevron`,width:14,height:14,viewBox:`0 0 14 14`,"aria-hidden":!0},e(`path`,{d:`M3 5l4 4 4-4`,fill:`none`,stroke:`currentColor`,strokeWidth:1.5,strokeLinecap:`round`,strokeLinejoin:`round`}))),e(`div`,{ref:m,id:`${h}-list`,role:`listbox`,className:`dsu-menu`,style:{positionAnchor:v,positionTryFallbacks:`flip-block, flip-inline`},"aria-label":c.label,hidden:!l},...F)))}function C(t){let n=!t.writable||t.busy||!t.dirty,r;return r=t.error===null?t.writable?t.dirty?t.dirtyLabel:t.cleanLabel:t.readOnlyLabel:t.error,e(`div`,{className:`dsu-savebar`,"data-dirty":t.dirty},e(`button`,{type:`button`,className:`dsu-btn dsu-btnPrimary`,"data-field":`save`,disabled:n,onClick:t.onSave},t.busy?t.savingLabel:t.saveLabel),e(`button`,{type:`button`,className:`dsu-btn`,"data-field":`discard`,disabled:n,onClick:t.onDiscard},t.revertLabel),e(`span`,{className:t.error===null?`dsu-status`:`dsu-status dsu-statusError`},r))}export{y as a,h as c,f as d,d as f,c as h,v as i,m as l,l as m,S as n,_ as o,p,b as r,g as s,C as t,u};
package/dist/card-ui.js CHANGED
@@ -1,105 +1 @@
1
- import{createElement as e,useCallback as t,useEffect as n,useId as r,useLayoutEffect as i,useMemo as a,useRef as o,useState as s}from"react";const c=`
2
- .dsu-form{display:flex;flex-direction:column}
3
- .dsu-section{margin-top:24px;padding-top:24px;border-top:.5px solid var(--dsw-alias-border-l1)}
4
- .dsu-form>.dsu-section:first-child{margin-top:0;padding-top:0;border-top:0}
5
- .dsu-sectionTitle{margin:0;font-size:15px;font-weight:600;line-height:1.4;color:var(--dsw-alias-label-primary)}
6
- .dsu-sectionHint{margin:4px 0 0;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
7
- .dsu-statusbar{display:flex;flex-wrap:wrap;gap:4px 8px;margin-top:8px;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
8
- .dsu-field{display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,360px);column-gap:32px;align-items:center;padding:12px 0;border-top:.5px solid var(--dsw-alias-border-l2)}
9
- .dsu-fieldMeta{display:flex;flex-direction:column;gap:4px;min-width:0}
10
- .dsu-labelRow{display:flex;align-items:center;gap:6px;min-width:0}
11
- .dsu-label{font-size:13px;font-weight:500;line-height:1.5;color:var(--dsw-alias-label-primary)}
12
- .dsu-labelMono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px}
13
- .dsu-hint{margin:0;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
14
- .dsu-control{min-width:0;display:flex;align-items:center;gap:8px}
15
- .dsu-fieldWide{grid-template-columns:minmax(0,1fr);align-items:start}
16
- .dsu-fieldWide .dsu-control{width:100%;max-width:720px;margin-top:2px}
17
- .dsu-help{display:inline-flex;align-items:center;gap:6px;min-width:0}
18
- .dsu-helpBtn{appearance:none;border:0;background:transparent;padding:0;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;color:var(--dsw-alias-label-tertiary);cursor:help;border-radius:50%;flex:none}
19
- .dsu-help:hover .dsu-helpBtn,.dsu-helpBtn:focus-visible{color:var(--dsw-alias-label-primary)}
20
- .dsu-helpBtn:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}
21
- .dsu-tip{position:fixed;z-index:60;box-sizing:border-box;max-width:min(340px,calc(100vw - 16px));max-height:calc(100vh - 16px);overflow:auto;overflow-wrap:anywhere;padding:10px 12px;border-radius:10px;background:var(--dsw-alias-bg-layer-2);border:.5px solid var(--dsw-alias-border-l3);box-shadow:0 12px 32px rgb(0 0 0 / 45%);font-size:12px;line-height:1.6;font-weight:400;color:var(--dsw-alias-label-secondary)}
22
- .dsu-input{width:100%;height:34px;padding:0 12px;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px}
23
- .dsu-input:focus-visible{outline:none;border-color:var(--dsw-alias-state-business-primary)}
24
- .dsu-input[aria-invalid="true"]{border-color:var(--dsw-alias-state-error-primary)}
25
- .dsu-input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}
26
- .dsu-input::placeholder{color:var(--dsw-alias-label-tertiary)}
27
- .dsu-textarea{height:auto;min-height:96px;padding:8px 12px;line-height:1.6;resize:vertical}
28
- .dsu-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
29
- .dsu-numberWrap{display:flex;flex-direction:column;gap:4px;width:100%;min-width:0}
30
- .dsu-number{display:flex;align-items:center;gap:8px;min-width:0}
31
- .dsu-number .dsu-input{min-width:0}
32
- .dsu-unit{flex:none;font-size:12px;color:var(--dsw-alias-label-tertiary)}
33
- .dsu-error{margin:0;font-size:12px;line-height:1.5;color:var(--dsw-alias-state-error-primary)}
34
- .dsu-switch{appearance:none;width:36px;height:20px;border-radius:999px;border:0;padding:2px;background:var(--dsw-alias-border-l3);display:flex;align-items:center;cursor:pointer;flex:none;transition:background-color .16s}
35
- .dsu-knob{width:16px;height:16px;border-radius:50%;background:var(--dsw-alias-label-primary);transition:transform .16s,background-color .16s}
36
- .dsu-switch[aria-checked="true"]{background:var(--dsw-alias-label-primary)}
37
- .dsu-switch[aria-checked="true"] .dsu-knob{transform:translateX(16px);background:var(--dsw-alias-label-primary-foreground)}
38
- .dsu-switch:disabled{opacity:.4;cursor:not-allowed}
39
- .dsu-switch:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}
40
- .dsu-selectWrap{position:relative;width:100%;min-width:0}
41
- .dsu-select{display:flex;align-items:center;justify-content:space-between;gap:8px;text-align:left;cursor:pointer}
42
- .dsu-select[aria-expanded="true"]{border-color:var(--dsw-alias-state-business-primary)}
43
- .dsu-selectValue{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
44
- .dsu-chevron{flex:none;color:var(--dsw-alias-label-tertiary);transition:transform .16s}
45
- .dsu-select[aria-expanded="true"] .dsu-chevron{transform:rotate(180deg)}
46
- .dsu-menu{position:fixed;z-index:70;padding:4px;background:var(--dsw-alias-bg-layer-2);border:.5px solid var(--dsw-alias-border-l3);border-radius:12px;box-shadow:0 12px 32px rgb(0 0 0 / 50%);max-height:280px;overflow:auto}
47
- .dsu-option{appearance:none;border:0;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;line-height:1.4;width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 10px;border-radius:8px;cursor:pointer;text-align:left}
48
- .dsu-option:hover,.dsu-option[data-active="true"]{background:var(--dsw-alias-bg-layer-3)}
49
- .dsu-option:disabled{color:var(--dsw-alias-label-tertiary);cursor:not-allowed}
50
- .dsu-option:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}
51
- .dsu-optionGroup{padding:6px 10px 2px;font-size:11px;font-weight:600;color:var(--dsw-alias-label-tertiary)}
52
- .dsu-check{opacity:0;flex:none}
53
- .dsu-option[aria-selected="true"] .dsu-check{opacity:1}
54
- .dsu-savebar{display:flex;align-items:center;gap:8px;padding:12px 0;margin-top:24px;border-top:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base)}
55
- .dsu-savebar[data-dirty="true"]{position:sticky;bottom:0;z-index:2;box-shadow:0 -12px 24px rgb(0 0 0 / 35%)}
56
- .dsu-btn{appearance:none;border:.5px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;line-height:1.5;border-radius:var(--dsw-radius-md);padding:5px 14px;cursor:pointer;transition:background-color .12s,border-color .12s,color .12s,filter .12s}
57
- .dsu-btn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-border-l3)}
58
- .dsu-btn:active:not(:disabled){background:var(--dsw-alias-bg-layer-1)}
59
- .dsu-btn:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}
60
- .dsu-btn:disabled{opacity:.4;cursor:not-allowed}
61
- .dsu-btnPrimary{background:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}
62
- .dsu-btnPrimary:hover:not(:disabled){background:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary);filter:brightness(.9)}
63
- .dsu-btnPrimary:active:not(:disabled){background:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary);filter:brightness(.84)}
64
- .dsu-btnDanger{color:var(--dsw-alias-state-error-primary)}
65
- .dsu-btnDanger:hover:not(:disabled){color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-2)}
66
- .dsu-status{margin-left:auto;font-size:12px;color:var(--dsw-alias-label-tertiary)}
67
- .dsu-statusError{color:var(--dsw-alias-state-error-primary)}
68
- .dsu-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(200px,100%),1fr));gap:0 24px}
69
- .dsu-grid>.dsu-field{display:flex;flex-direction:column;align-items:stretch;gap:6px;padding:10px 0;border-top:.5px solid var(--dsw-alias-border-l1)}
70
- .dsu-grid>.dsu-field .dsu-control{width:100%}
71
- @media (max-width:640px){
72
- .dsu-field{grid-template-columns:minmax(0,1fr);align-items:start}
73
- .dsu-control{width:100%;max-width:720px}
74
- .dsu-section{margin-top:20px;padding-top:20px}
75
- }
76
- @media (prefers-reduced-motion:reduce){
77
- .dsu-switch,.dsu-knob,.dsu-chevron,.dsu-btn{transition:none}
78
- }
79
- `;function l(e,t=30){return e.length<=t?{hint:e}:{detail:e}}function u(t){return e(`div`,{className:`dsu-form`},t.children)}function d(t){return e(`section`,{className:`dsu-section`},e(`h2`,{className:`dsu-sectionTitle`},t.title),t.hint===void 0?null:e(`p`,{className:`dsu-sectionHint`},t.hint),t.children)}function f(t){return e(`div`,{className:`dsu-grid`},t.children)}function p(t){if(t.items.length===0)return null;let n=t.items.map((t,n)=>e(`span`,{key:n},n===0?t:`· ${t}`));return e(`div`,{className:`dsu-statusbar`},...n)}function m(a){let c=r(),[l,u]=s(!1),[d,f]=s(!1),p=o(!1),m=o(!1),h=o(!1),g=o(null),_=o(null),v=o(null),y=t(()=>{v.current!==null&&(clearTimeout(v.current),v.current=null)},[]),b=t(()=>{let e=g.current,t=_.current;
80
- /* v8 ignore next 3 -- place 只在 open 的 layout effect 与挂载期监听器里调用;refs 为空只可能是卸载竞态 */
81
- if(e===null||t===null)return;let n=e.getBoundingClientRect(),r=t.offsetWidth,i=t.offsetHeight,{left:a}=n,o=n.bottom+8;o+i>window.innerHeight-8&&(o=n.top-i-8),a+r>window.innerWidth-8&&(a=window.innerWidth-r-8);let s=Math.max(8,window.innerWidth-r-8),c=Math.max(8,window.innerHeight-i-8);t.style.left=`${Math.min(Math.max(8,a),s)}px`,t.style.top=`${Math.min(Math.max(8,o),c)}px`},[]),x=t(()=>{y(),h.current=!1,f(!1),u(!1)},[y]),S=t(()=>{y(),u(!0)},[y]),C=t(()=>{y(),!(p.current||m.current||h.current)&&(v.current=setTimeout(()=>{
82
- /* v8 ignore next 3 -- 任何重新进入/钉住都会 cancelHide;这次复查只防未来的异步路径 */
83
- v.current=null,p.current||m.current||h.current||u(!1)},120))},[y]),w=t(e=>{h.current=e,f(e)},[]);i(()=>{if(!l)return()=>{};b();let e=e=>{let{target:t}=e;t instanceof Node&&_.current?.contains(t)===!0||(h.current?b():x())},t=()=>{b()};return window.addEventListener(`scroll`,e,!0),window.addEventListener(`resize`,t),()=>{window.removeEventListener(`scroll`,e,!0),window.removeEventListener(`resize`,t)}},[l,a.detail,b,x]),n(()=>{if(!l)return()=>{};let e=e=>{e.key===`Escape`&&x()};return document.addEventListener(`keydown`,e),()=>{document.removeEventListener(`keydown`,e)}},[l,x]),n(()=>y,[y]);let T=e(`button`,{ref:g,type:`button`,className:`dsu-helpBtn`,"aria-label":`${a.label} 说明`,"aria-describedby":c,"aria-pressed":d,onClick:()=>{h.current?x():(w(!0),S())}},e(`svg`,{width:12,height:12,viewBox:`0 0 14 14`,"aria-hidden":!0},e(`circle`,{cx:7,cy:7,r:6,fill:`none`,stroke:`currentColor`,strokeWidth:1.2}),e(`path`,{d:`M7 6.2v4`,stroke:`currentColor`,strokeWidth:1.3,strokeLinecap:`round`}),e(`circle`,{cx:7,cy:4.3,r:.8,fill:`currentColor`}))),E=e(`div`,{ref:_,id:c,role:`tooltip`,className:`dsu-tip`,hidden:!l},a.detail),D=a.showLabel===!1?null:e(`span`,{className:`dsu-label${a.compact===!0?` dsu-labelMono`:``}`},a.label);return e(`span`,{className:`dsu-help`,onMouseEnter:()=>{p.current=!0,S()},onMouseLeave:()=>{p.current=!1,C()},onFocus:()=>{m.current=!0,S()},onBlur:e=>{let t=e.relatedTarget;t instanceof Node&&e.currentTarget.contains(t)||(m.current=!1,C())}},D,T,E)}function h(t){let n=`dsu-label${t.compact===!0?` dsu-labelMono`:``}`,r=t.controlId===void 0?e(`span`,{className:n},t.label):e(`label`,{className:n,htmlFor:t.controlId},t.label);return e(`div`,{className:`dsu-labelRow`},r,t.detail===void 0?null:e(m,{label:t.label,detail:t.detail,showLabel:!1}))}function g(t){let n=t.controlId===void 0?void 0:`${t.controlId}-hint`;return e(`div`,{className:`dsu-field${t.wide===!0?` dsu-fieldWide`:``}`},e(`div`,{className:`dsu-fieldMeta`},e(h,{label:t.label,detail:t.detail,compact:t.compact,controlId:t.controlId}),t.hint===void 0?null:e(`p`,{className:`dsu-hint`,id:n},t.hint)),e(`div`,{className:`dsu-control`},t.children))}function _(t){let n=r(),i=t.hint===void 0?void 0:`${n}-hint`;return e(g,{...t,controlId:n},e(`button`,{type:`button`,role:`switch`,id:n,className:`dsu-switch`,"aria-checked":t.checked,"aria-describedby":i,"data-field":t.field,disabled:t.disabled===!0,onClick:()=>{t.onChange(!t.checked)}},e(`span`,{className:`dsu-knob`})))}function v(t){let i=typeof t.value==`number`&&Number.isFinite(t.value)?String(t.value):``,[a,c]=s(i),[l,u]=s(!1),d=o(void 0),f=r(),p=r(),m=[t.hint===void 0?void 0:`${f}-hint`,l?p:void 0].filter(e=>e!==void 0),h=m.length===0?void 0:m.join(` `);n(()=>{t.value!==d.current&&(d.current=t.value,c(i),u(!1))},[t.value,i]);let _=e=>{let n=t.min??-1/0,r=t.max??1/0;if(!Number.isFinite(e)||e<n||e>r)return!1;let{step:i}=t;if(i===void 0||i<=0)return!0;let a=(e-(t.min??0))/i;return Math.abs(a-Math.round(a))<1e-9},v=e=>{if(c(e),e===``){u(!1),d.current=void 0,t.onChange(void 0);return}let n=Number(e);_(n)?(u(!1),d.current=n,t.onChange(n)):u(!0)},y=()=>{a===``||l||c(String(Number(a)))};return e(g,{...t,controlId:f},e(`div`,{className:`dsu-numberWrap`},e(`div`,{className:`dsu-number`},e(`input`,{className:`dsu-input`,type:`number`,inputMode:`numeric`,id:f,value:a,min:t.min,max:t.max,step:t.step,placeholder:t.placeholder,"aria-invalid":l||void 0,"aria-describedby":h,"data-field":t.field,disabled:t.disabled===!0,onChange:e=>{v(e.target.value)},onBlur:y}),t.unit===void 0?null:e(`span`,{className:`dsu-unit`},t.unit)),l?e(`p`,{className:`dsu-error`,id:p},t.invalidHint):null))}function y(t){let[i,a]=s(t.value),[o,c]=s(!1),l=r(),u=t.hint===void 0?void 0:`${l}-hint`;n(()=>{o||a(t.value)},[t.value,o]);let d={id:l,className:`dsu-input${t.multiline===!0?` dsu-textarea`:``}${t.monospace===!0?` dsu-mono`:``}`,value:i,placeholder:t.placeholder,"aria-describedby":u,"data-field":t.field,disabled:t.disabled===!0,onFocus:()=>{c(!0)},onBlur:()=>{c(!1)},onChange:e=>{a(e.target.value),t.onChange(e.target.value)}};return e(g,{...t,controlId:l},t.multiline===!0?e(`textarea`,d):e(`input`,d))}function b(t){let i=t.separator??`comma`,a=t.value.join(i===`newline`?`
84
- `:`, `),[o,c]=s(a),[l,u]=s(!1),d=r(),f=t.hint===void 0?void 0:`${d}-hint`;n(()=>{l||c(a)},[a,l]);let p=e=>e.split(i===`newline`?`
85
- `:`,`).map(e=>e.trim()).filter(e=>e.length>0),m={id:d,className:`dsu-input${i===`newline`?` dsu-textarea dsu-mono`:``}`,value:o,placeholder:t.placeholder,"aria-describedby":f,"data-field":t.field,disabled:t.disabled===!0,onFocus:()=>{u(!0)},onBlur:()=>{u(!1)},onChange:e=>{c(e.target.value),t.onChange(p(e.target.value))}};return e(g,{...t,controlId:d},e(i===`newline`?`textarea`:`input`,m))}function x(c){let[l,u]=s(!1),[d,f]=s(0),p=o(null),m=o(null),h=r(),_=r(),v=c.hint===void 0?void 0:`${_}-hint`,{disabled:y,value:b,options:x,onChange:S}=c,C=a(()=>x.map((e,t)=>({option:e,index:t})).filter(e=>e.option.disabled!==!0),[x]),w=x.find(e=>e.value===b)?.label??b,T=x[d],E=T!==void 0&&T.disabled!==!0,D=t(()=>{let e=p.current,t=m.current;
86
- /* v8 ignore next 3 -- place 只在 open 的 layout effect 里调用;refs 为空只可能是卸载竞态 */
87
- if(e===null||t===null)return;let n=e.getBoundingClientRect(),r=Math.min(n.width,window.innerWidth-16),{left:i}=n;i+r>window.innerWidth-8&&(i=window.innerWidth-r-8);let a=t.offsetHeight,o=n.bottom+6;o+a>window.innerHeight-8&&(o=n.top-a-6);let s=Math.max(8,window.innerWidth-r-8),c=Math.max(8,window.innerHeight-a-8);t.style.width=`${r}px`,t.style.left=`${Math.min(Math.max(8,i),s)}px`,t.style.top=`${Math.min(Math.max(8,o),c)}px`},[]),O=t(()=>{u(!1)},[]),k=t(()=>{if(y===!0)return;let e=C.find(e=>e.option.value===b)??C.at(0);e!==void 0&&(f(e.index),u(!0))},[y,b,C]),A=t(e=>{
88
- /* v8 ignore next 3 -- 浮层只能经由 openMenu 打开;组件禁用时打不开 */
89
- if(y===!0)return;let t=x[e];
90
- /* v8 ignore next 3 -- disabled 选项在浏览器里不派发 click;越界下标由调用面保证 */
91
- t!==void 0&&t.disabled!==!0&&(S(t.value),O(),p.current?.focus())},[y,x,S,O]),j=t(e=>{let t=C.findIndex(e=>e.index===d);
92
- /* v8 ignore next 5 -- open 时归一 effect 已保证 enabled 非空且 active 落在可用项上 */
93
- if(t===-1||C.length===0)return;let n=(t+e+C.length)%C.length,r=C[n];
94
- /* v8 ignore next 3 -- next 由取模保证在界内 */
95
- r!==void 0&&f(r.index)},[d,C]);i(()=>{if(!l)return()=>{};D();let e=e=>{let t=e.target;m.current?.contains(t)!==!0&&p.current?.contains(t)!==!0&&O()},t=e=>{let{target:t}=e;t instanceof Node&&m.current?.contains(t)===!0||O()},n=()=>{D()};return document.addEventListener(`pointerdown`,e,!0),window.addEventListener(`scroll`,t,!0),window.addEventListener(`resize`,n),()=>{document.removeEventListener(`pointerdown`,e,!0),window.removeEventListener(`scroll`,t,!0),window.removeEventListener(`resize`,n)}},[l,c.options,D,O]),n(()=>{if(!l)return;if(y===!0||C.length===0){O();return}if(C.some(e=>e.index===d))return;let e=C.find(e=>e.option.value===b)??C.at(0);
96
- /* v8 ignore next 3 -- enabled 非空在上一分支已保证 */
97
- e!==void 0&&f(e.index)},[l,y,b,x,d,O,C]),i(()=>{if(!l)return;let e=m.current;
98
- /* v8 ignore next 2 -- 同上,menu 在 open 的 commit 之后必然已挂上 */
99
- if(e===null)return;let t=e.querySelector(`[data-active="true"]`);
100
- /* v8 ignore next 2 -- active 已由归一 effect 保证落在可用项上 */
101
- t!==null&&(t.offsetTop<e.scrollTop?e.scrollTop=t.offsetTop:t.offsetTop+t.offsetHeight>e.scrollTop+e.clientHeight&&(e.scrollTop=t.offsetTop+t.offsetHeight-e.clientHeight))},[l,d,x]);let M=e=>{if(e.key===`ArrowDown`||e.key===`ArrowUp`){if(e.preventDefault(),!l){k();return}j(e.key===`ArrowDown`?1:-1)}else if(e.key===`Home`||e.key===`End`){if(e.preventDefault(),l||k(),C.length===0)return;let t=e.key===`Home`?C.at(0):C.at(-1);
102
- /* v8 ignore next 3 -- enabled 为空已在上一条返回 */
103
- if(t===void 0)return;f(t.index)}else if(e.key===`Enter`||e.key===` `){if(e.preventDefault(),!l){k();return}A(d)}else(e.key===`Tab`||e.key===`Escape`)&&O()},N=[],P;for(let[t,n]of x.entries())n.group!==P&&(n.group!==void 0&&N.push(e(`div`,{key:`group-${t}-${n.group}`,className:`dsu-optionGroup`,role:`presentation`},n.group)),P=n.group),N.push(e(`button`,{key:`option-${n.value}`,type:`button`,role:`option`,id:`${h}-${t}`,className:`dsu-option`,tabIndex:-1,"aria-selected":n.value===c.value,"data-active":t===d,disabled:n.disabled===!0,onMouseDown:e=>{e.preventDefault()},onClick:()=>{A(t)},onMouseEnter:()=>{
104
- /* v8 ignore next -- happy-dom 对 disabled 元素不派发 mouse 事件;浏览器实现各有差异,保留禁用检查 */
105
- n.disabled!==!0&&f(t)}},e(`span`,null,n.label),e(`svg`,{className:`dsu-check`,width:14,height:14,viewBox:`0 0 14 14`,"aria-hidden":!0},e(`path`,{d:`M2.5 7.5l3 3 6-7`,fill:`none`,stroke:`currentColor`,strokeWidth:1.5,strokeLinecap:`round`,strokeLinejoin:`round`}))));return e(g,{...c,controlId:_},e(`div`,{className:`dsu-selectWrap`,onBlur:e=>{let t=e.relatedTarget;t instanceof Node&&e.currentTarget.contains(t)||O()}},e(`button`,{ref:p,type:`button`,id:_,className:`dsu-select dsu-input`,role:`combobox`,"aria-haspopup":`listbox`,"aria-expanded":l,"aria-controls":`${h}-list`,"aria-activedescendant":l&&E?`${h}-${d}`:void 0,"aria-describedby":v,"data-field":c.field,disabled:y===!0||x.length===0,onClick:()=>{l?O():k()},onKeyDown:M},e(`span`,{className:`dsu-selectValue`},w),e(`svg`,{className:`dsu-chevron`,width:14,height:14,viewBox:`0 0 14 14`,"aria-hidden":!0},e(`path`,{d:`M3 5l4 4 4-4`,fill:`none`,stroke:`currentColor`,strokeWidth:1.5,strokeLinecap:`round`,strokeLinejoin:`round`}))),e(`div`,{ref:m,id:`${h}-list`,role:`listbox`,className:`dsu-menu`,"aria-label":c.label,hidden:!l},...N)))}function S(t){let n=!t.writable||t.busy||!t.dirty,r;return r=t.error===null?t.writable?t.dirty?t.dirtyLabel:t.cleanLabel:t.readOnlyLabel:t.error,e(`div`,{className:`dsu-savebar`,"data-dirty":t.dirty},e(`button`,{type:`button`,className:`dsu-btn dsu-btnPrimary`,"data-field":`save`,disabled:n,onClick:t.onSave},t.busy?t.savingLabel:t.saveLabel),e(`button`,{type:`button`,className:`dsu-btn`,"data-field":`discard`,disabled:n,onClick:t.onDiscard},t.revertLabel),e(`span`,{className:t.error===null?`dsu-status`:`dsu-status dsu-statusError`},r))}export{c as CARD_UI_CSS,u as CardForm,g as Field,f as FieldGrid,h as FieldLabel,m as InfoTip,b as ListField,v as NumberField,S as SaveBar,d as Section,x as SelectField,p as StatusBar,y as TextField,_ as ToggleField,l as splitHint};
1
+ export{h as CARD_UI_CSS,u as CardForm,s as Field,d as FieldGrid,c as FieldLabel,l as InfoTip,r as ListField,i as NumberField,t as SaveBar,f as Section,n as SelectField,p as StatusBar,a as TextField,o as ToggleField,m as splitHint}from"./card-ui-D2cuQvLS.js";
@@ -0,0 +1 @@
1
+ import{a as e,c as t,d as n,f as r,h as i,i as a,l as o,m as s,n as c,o as l,p as u,r as d,s as f,t as p,u as m}from"./card-ui-D2cuQvLS.js";import{diffTouched as h}from"./card-diff.js";import{claimApply as g}from"./card-apply.js";import{fieldOf as _,isRecord as v}from"./record.js";import{errorText as y}from"./errors.js";const b=`@jayyuen66/dsh-plugin-shared`;function x(){}export{i as CARD_UI_CSS,m as CardForm,f as Field,n as FieldGrid,t as FieldLabel,o as InfoTip,d as ListField,a as NumberField,p as SaveBar,r as Section,c as SelectField,u as StatusBar,e as TextField,l as ToggleField,x as apply,g as claimApply,h as diffTouched,y as errorText,_ as fieldOf,v as isRecord,b as name,s as splitHint};