dsh-dialog-width 0.0.1

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.
package/lib/client.js ADDED
@@ -0,0 +1,516 @@
1
+ window.__ModuleLoader__.load({ id: "dsh-dialog-width", factory: (require) => {
2
+ var __modules = Object.create(null); var __cache = Object.create(null);
3
+ __modules["./conversation-width.js"] = function(module, exports, require, __load_) {
4
+ "use strict";
5
+ /**
6
+ * dsh-dialog-width — conversation-width override (browser half).
7
+ *
8
+ * When the user turns "plugin width control" on, this module:
9
+ *
10
+ * 1. Hides DSH's native 40 px hover drag handles. The handles live in a
11
+ * CSS-Modules file (`ConversationRoot.module.css`) whose class names are
12
+ * build-time-hashed, so a global stylesheet cannot target them by class —
13
+ * it MUST use the stable `data-width-handle` attribute selector.
14
+ *
15
+ * 2. Drives DSH's own shared width axis instead of forking it. The
16
+ * conversation root declares the single source of truth
17
+ * (`ConversationRoot.module.css`, `.root`):
18
+ *
19
+ * --dsh-chat-content-width: var(--dsh-chat-user-width, clamp(680px, calc(var(--dsh-conversation-column-width, 0px) * 0.64), 920px));
20
+ * --dsh-composer-card-max-width: calc(var(--dsh-chat-content-width) + 32px);
21
+ *
22
+ * Every consumer — the transcript column (`data-chat-flow`), message
23
+ * bubbles, wide-table bleed, the back-to-bottom control, the composer
24
+ * card, and the dock/stats line — reads those two variables, so forcing
25
+ * `--dsh-chat-user-width` keeps the input card and the conversation area
26
+ * in lockstep by construction. The plugin never sets max-widths itself.
27
+ *
28
+ * 3. Reproduces DSH's narrow-viewport clamp in CSS. Natively
29
+ * (`ConversationRoot.tsx`, `resolveContentWidth`) a stored preference is
30
+ * re-clamped against the live column width — published as
31
+ * `--dsh-conversation-column-width` by a ResizeObserver — so opening the
32
+ * sidebar narrows the content instead of letting it overflow. This module
33
+ * declares the same clamp declaratively on the conversation root:
34
+ *
35
+ * --dsh-chat-user-width: min(<width>px, max(640px, calc(var(--dsh-conversation-column-width, 99999px) - 2 * <sideMargin>px)));
36
+ *
37
+ * i.e. the column never claims more than the dialog width, and never
38
+ * leaves less than `sideMargin` of whitespace on either side; 640px is
39
+ * DSH's own content floor (CONTENT_MIN). The var() substitution happens
40
+ * on the conversation root — the same element DSH writes the live column
41
+ * width on — so the clamp tracks sidebar toggles and window resizes with
42
+ * zero JS. The declaration is `!important` so it also beats DSH's inline
43
+ * re-publication of `--dsh-chat-user-width` on the same element.
44
+ *
45
+ * 4. Mirrors the chosen px into the shared localStorage slot
46
+ * (`dsh.conversation.contentWidth`) so toggling plugin-width OFF surfaces
47
+ * the user's last choice in the native drag handles — the switch is
48
+ * value-preserving in both directions.
49
+ *
50
+ * When the user turns the feature OFF, the installer disposes: the handle
51
+ * rule and the width-axis override are removed and the native handles take
52
+ * over from whatever px the user last picked.
53
+ *
54
+ * The conversation root cannot be targeted by a stable attribute of its own
55
+ * (it only carries `data-phase`), so the override anchors on the stable
56
+ * `data-conversation-scroll` descendant: `div:has([data-conversation-scroll])`
57
+ * matches exactly the ancestors of the scroll body, and the innermost
58
+ * declaration that matters — the conversation root — is where DSH publishes
59
+ * the live column width.
60
+ * @module dsh-dialog-width/client/conversation-width
61
+ */
62
+ Object.defineProperty(exports, "__esModule", { value: true });
63
+ exports.installConversationWidthStyles = installConversationWidthStyles;
64
+ /**
65
+ * localStorage slot the native WidthHandle reads/writes
66
+ * (`ConversationRoot.tsx` WIDTH_PREF_KEY). Kept in sync with the server-side
67
+ * constant in src/config.ts — duplicated here because the client tsconfig's
68
+ * rootDir is `src/client` and cannot reach up into `src/`.
69
+ */
70
+ const CONVERSATION_WIDTH_STORAGE_KEY = 'dsh.conversation.contentWidth';
71
+ /** Stable attribute selector for the native WidthHandle strips (CSS-Modules-hashed class). */
72
+ const HANDLE_HIDE_RULE = '[data-width-handle]{display:none !important}';
73
+ /** DSH's own content floor (`ConversationRoot.tsx` CONTENT_MIN). */
74
+ const CONTENT_MIN_PX = 640;
75
+ /**
76
+ * CSS injected into <head> while plugin-width is on:
77
+ * - hide the native handles (hashed class → attribute selector)
78
+ * - clamp DSH's user-width preference to the plugin's dialog width, keeping
79
+ * at least `sideMargin` of whitespace per side as the live column narrows
80
+ * - mirror the raw px on :root (`--dsh-dialog-width-chat-width`) for any
81
+ * consumer that reads the legacy var from the document root.
82
+ */
83
+ function buildWidthCss(widthPx, sideMargin) {
84
+ return `
85
+ ${HANDLE_HIDE_RULE}
86
+ div:has([data-conversation-scroll]){--dsh-chat-user-width:min(${widthPx}px, max(${CONTENT_MIN_PX}px, calc(var(--dsh-conversation-column-width, 99999px) - ${sideMargin * 2}px))) !important}
87
+ :root{--dsh-dialog-width-chat-width:${widthPx}px}
88
+ `;
89
+ }
90
+ /**
91
+ * Install the width-override stylesheet. Idempotent: a second call with the
92
+ * same id returns the existing controller.
93
+ * @param widthPx - the plugin's chosen column width in px.
94
+ * @param sideMargin - whitespace in px to keep on each side of the column.
95
+ * @returns a controller exposing `setWidth` + `dispose`.
96
+ */
97
+ function installConversationWidthStyles(widthPx, sideMargin) {
98
+ const id = 'dsh-dialog-width-conversation-width';
99
+ let style = document.querySelector(`style[data-plugin-css="${id}"]`);
100
+ if (style === null) {
101
+ style = document.createElement('style');
102
+ style.dataset.plugin = 'dsh-dialog-width';
103
+ style.dataset.pluginCss = id;
104
+ document.head.appendChild(style);
105
+ }
106
+ // Persist to the shared storage slot so toggling plugin-width off surfaces
107
+ // the user's last choice in the native drag handles.
108
+ try {
109
+ localStorage.setItem(CONVERSATION_WIDTH_STORAGE_KEY, `${widthPx}`);
110
+ }
111
+ catch { /* storage may be disabled; ignore */ }
112
+ const apply = (px, margin) => {
113
+ style.textContent = buildWidthCss(px, margin);
114
+ // Belt-and-suspenders: also set the var directly on :root in case any
115
+ // consumer reads the legacy var via JS rather than via CSS cascade.
116
+ document.documentElement.style.setProperty('--dsh-dialog-width-chat-width', `${px}px`);
117
+ };
118
+ apply(widthPx, sideMargin);
119
+ return {
120
+ setWidth: (px, margin) => {
121
+ apply(px, margin);
122
+ try {
123
+ localStorage.setItem(CONVERSATION_WIDTH_STORAGE_KEY, `${px}`);
124
+ }
125
+ catch { /* ignore */ }
126
+ },
127
+ dispose: () => {
128
+ style?.remove();
129
+ document.documentElement.style.removeProperty('--dsh-dialog-width-chat-width');
130
+ },
131
+ };
132
+ }
133
+ };
134
+ __modules["./index.js"] = function(module, exports, require, __load_) {
135
+ "use strict";
136
+ Object.defineProperty(exports, "__esModule", { value: true });
137
+ exports.inject = exports.SettingsClient = void 0;
138
+ exports.apply = apply;
139
+ const jsx_runtime_1 = require("react/jsx-runtime");
140
+ /**
141
+ * dsh-dialog-width — browser half.
142
+ *
143
+ * Reads and writes the `dialog-width` settings namespace through the
144
+ * same-origin route served by the server half, applies the chosen dialog
145
+ * width live via a runtime `<style>` element, and renders the Settings
146
+ * panel section that edits it.
147
+ */
148
+ const react_1 = require("react");
149
+ const react_dom_1 = require("react-dom");
150
+ const conversation_width_ts_1 = __load_("./conversation-width.js");
151
+ const NS = 'dialog-width';
152
+ const SETTINGS_ROUTE = '/_dsh/dialog-width/settings';
153
+ /** Dialog width in px. Keep in sync with src/config.ts. */
154
+ const DEFAULT_DIALOG_WIDTH = 748;
155
+ const MIN_DIALOG_WIDTH = 600;
156
+ const MAX_DIALOG_WIDTH = 1600;
157
+ const en = {
158
+ nav: 'Dialog width',
159
+ settingsTitle: 'Dialog width',
160
+ settingsIntro: 'Control the conversation column width — either let the plugin drive it with a precise pixel value, or use DSH\'s native drag handles.',
161
+ sectionLayout: 'Layout',
162
+ dialogWidth: 'Dialog width',
163
+ dialogWidthHint: 'Number between 600 and 1600 px; 748 is DSH\'s default column width, larger values widen it.',
164
+ presetDefault: 'Default',
165
+ presetWide: 'Wide',
166
+ presetWideXl: 'Extra wide',
167
+ usePluginWidth: 'Plugin width control',
168
+ usePluginWidthHint: 'When ON, the width input / presets above drive the column and DSH\'s native drag handles are hidden. When OFF, DSH\'s native handles own the column; the width input mirrors their value.',
169
+ usePluginWidthOn: 'On',
170
+ usePluginWidthOff: 'Off',
171
+ sideMargin: 'Side margin',
172
+ sideMarginHint: 'Whitespace in px kept on each side of the conversation area. The column is clamped to the dialog width and narrows when the sidebar opens or the window shrinks, never hugging the edges. Minimum 32 px.',
173
+ defaultAction: 'Default',
174
+ applied: 'Applied',
175
+ unavailable: 'Settings unavailable.',
176
+ loading: 'Loading…',
177
+ readOnly: 'The active Settings provider is read-only.',
178
+ };
179
+ const zh = {
180
+ nav: '对话框宽度',
181
+ settingsTitle: '对话框宽度',
182
+ settingsIntro: '控制对话列宽——既可以用插件精确指定像素值,也可以使用 DSH 原生的拖拽手柄。',
183
+ sectionLayout: '布局',
184
+ dialogWidth: '对话框宽度',
185
+ dialogWidthHint: '取值 600–1600 px;748 为 DSH 默认列宽,数字越大越宽。',
186
+ presetDefault: '默认',
187
+ presetWide: '稍宽',
188
+ presetWideXl: '更宽',
189
+ usePluginWidth: '插件宽度控制',
190
+ usePluginWidthHint: '开启时,上方宽度输入 / 预设驱动列宽,并隐藏 DSH 原生的拖拽手柄;关闭时,DSH 原生手柄接管列宽,宽度输入同步显示当前值。',
191
+ usePluginWidthOn: '开启',
192
+ usePluginWidthOff: '关闭',
193
+ sideMargin: '两侧边距',
194
+ sideMarginHint: '会话区域两侧保留的空白(px)。列宽被钳制为对话框宽度,侧边栏打开或窗口缩小时内容会收窄,不会贴住边缘。最低 32 px。',
195
+ defaultAction: '默认',
196
+ applied: '已应用',
197
+ unavailable: '设置暂不可用。',
198
+ loading: '加载中…',
199
+ readOnly: '当前设置提供方为只读。',
200
+ };
201
+ function resolveDialogWidth(value) {
202
+ if (typeof value === 'number') {
203
+ return Math.min(MAX_DIALOG_WIDTH, Math.max(MIN_DIALOG_WIDTH, Math.round(value)));
204
+ }
205
+ return DEFAULT_DIALOG_WIDTH;
206
+ }
207
+ function resolveValue(value) {
208
+ return {
209
+ dialogWidth: resolveDialogWidth(value?.dialogWidth),
210
+ usePluginWidth: value?.usePluginWidth ?? true,
211
+ sideMargin: value?.sideMargin ?? 40,
212
+ };
213
+ }
214
+ /**
215
+ * Side margin in px (min 32). Keep in sync with src/config.ts — duplicated
216
+ * because the client tsconfig's rootDir is `src/client`.
217
+ */
218
+ const DEFAULT_SIDE_MARGIN = 50;
219
+ const MIN_SIDE_MARGIN = 32;
220
+ function resolveSideMargin(value) {
221
+ if (typeof value === 'number')
222
+ return Math.max(MIN_SIDE_MARGIN, Math.round(value));
223
+ return DEFAULT_SIDE_MARGIN;
224
+ }
225
+ const BASE_CSS = `
226
+ .dut-settings{display:grid;gap:8px;max-width:680px;padding:4px 2px 24px;color:var(--dsw-alias-label-primary)}
227
+ .dut-settings-header{display:flex;align-items:flex-start;gap:10px;padding:2px 2px 0}
228
+ .dut-logo{flex:none;display:grid;place-items:center;width:30px;height:30px;border-radius:9px;border:1px solid var(--dsw-alias-border-l1);background:linear-gradient(135deg,color-mix(in srgb,var(--dsw-alias-state-business-primary) 16%,transparent),transparent);font-size:15px;line-height:1}
229
+ .dut-settings-header h2{font-size:16px;letter-spacing:-.01em;margin:0 0 2px}
230
+ .dut-settings-header p{max-width:600px;margin:0;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.45}
231
+ .dut-panel{display:grid;gap:0;border:1px solid var(--dsw-alias-border-l1);border-radius:14px;background:var(--dsw-alias-bg-layer-1);box-shadow:var(--dsw-shadow-lv1);overflow:hidden}
232
+ .dut-section-label{font-size:10.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--dsw-alias-label-tertiary);padding:9px 16px 4px}
233
+ .dut-field{display:grid;gap:6px;padding:7px 16px 10px}
234
+ .dut-field+.dut-field{border-top:1px solid var(--dsw-alias-border-l1)}
235
+ .dut-field-top{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap}
236
+ .dut-field-top>span{font-size:13.5px;font-weight:600}
237
+ .dut-label{display:inline-flex;align-items:center;gap:6px}
238
+ .dut-hint{flex:none;display:inline-grid;place-items:center;width:15px;height:15px;border-radius:50%;border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);font-size:9.5px;font-weight:600;font-style:normal;line-height:1;cursor:help;user-select:none;transition:color .15s ease,border-color .15s ease}
239
+ .dut-hint:hover,.dut-hint:focus-visible{color:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary)}
240
+ .dut-hint-pop{position:fixed;z-index:9999;width:max-content;max-width:300px;padding:8px 10px;border-radius:8px;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font-size:11.5px;line-height:1.5;box-shadow:0 4px 16px rgba(0,0,0,.14);pointer-events:none}
241
+ .dut-controls{display:flex;align-items:center;gap:8px}
242
+ .dut-stepper{display:inline-flex;align-items:center;border:1px solid var(--dsw-alias-border-l1);border-radius:9px;background:var(--dsw-alias-bg-layer-2);overflow:hidden}
243
+ .dut-stepper button{width:28px;height:28px;border:none;background:transparent;color:inherit;font-size:15px;font-weight:500;line-height:1;cursor:pointer;display:grid;place-items:center;transition:background .15s ease}
244
+ .dut-stepper button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}
245
+ .dut-stepper button:disabled{opacity:.35;cursor:default}
246
+ .dut-stepper input{box-sizing:border-box;width:60px;height:28px;border:none;border-left:1px solid var(--dsw-alias-border-l1);border-right:1px solid var(--dsw-alias-border-l1);background:transparent;color:inherit;font:inherit;font-size:13px;text-align:center;-moz-appearance:textfield}
247
+ .dut-stepper input::-webkit-outer-spin-button,.dut-stepper input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
248
+ .dut-stepper input:focus{outline:none}
249
+ .dut-seg{display:inline-flex;padding:3px;gap:3px;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;background:var(--dsw-alias-bg-layer-2)}
250
+ .dut-seg button{border:none;border-radius:7px;padding:5px 12px;background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:12.5px;cursor:pointer;transition:background .15s ease,color .15s ease}
251
+ .dut-seg button:hover:not(:disabled){color:var(--dsw-alias-label-primary)}
252
+ .dut-seg button.dut-seg-active{background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent);color:var(--dsw-alias-state-business-primary);font-weight:600;box-shadow:none}
253
+ .dut-seg button.dut-seg-active:hover:not(:disabled){color:var(--dsw-alias-state-business-primary)}
254
+ .dut-seg button:disabled{opacity:.45;cursor:default}
255
+ .dut-presets{display:inline-flex;flex-wrap:wrap;margin-top:2px}
256
+ .dut-btn{display:inline-flex;align-items:center;height:26px;padding:0 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l1);background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:11.5px;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}
257
+ .dut-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
258
+ .dut-btn.dut-btn-active{background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent);border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 45%,transparent);color:var(--dsw-alias-state-business-primary)}
259
+ .dut-btn.dut-btn-active:hover{background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 18%,transparent);color:var(--dsw-alias-state-business-primary)}
260
+ .dut-btn:disabled{opacity:.4;cursor:default}
261
+ .dut-status{justify-self:start;font-size:11.5px;padding:3px 10px;border-radius:999px;background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent);color:var(--dsw-alias-state-success-primary);animation:dut-fadein .18s ease}
262
+ @keyframes dut-fadein{from{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:none}}
263
+ .dut-loading{padding:16px;border-radius:12px;background:var(--dsw-alias-bg-layer-2);font-size:12px;color:var(--dsw-alias-label-secondary)}
264
+ .dut-alert{padding:10px 12px;border-radius:10px;font-size:12px;line-height:1.5}
265
+ .dut-alert.warning{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 12%,transparent);color:var(--dsw-alias-state-warn-label)}
266
+ .dut-alert.error{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}
267
+ `;
268
+ function installBaseStyles() {
269
+ const id = 'dsh-dialog-width-base';
270
+ const existing = document.querySelector(`style[data-plugin-css="${id}"]`);
271
+ if (existing !== null)
272
+ return () => { };
273
+ const style = document.createElement('style');
274
+ style.dataset.plugin = 'dsh-dialog-width';
275
+ style.dataset.pluginCss = id;
276
+ style.textContent = BASE_CSS;
277
+ document.head.appendChild(style);
278
+ return () => { style.remove(); };
279
+ }
280
+ /**
281
+ * Settings requests retry briefly on 502/503: writing the profile patch
282
+ * hot-reloads the `web` node and restarts this plugin for a moment (it
283
+ * injects `web`), so a toggle click can land inside that window. The retry
284
+ * rides it out instead of surfacing "settings unavailable".
285
+ */
286
+ async function apiRequest(init) {
287
+ let lastError;
288
+ for (let attempt = 1; attempt <= 6; attempt++) {
289
+ try {
290
+ const response = await fetch(SETTINGS_ROUTE, { credentials: 'same-origin', ...init });
291
+ const body = await response.json();
292
+ if (response.ok && body.ok)
293
+ return body.value;
294
+ const failure = body;
295
+ const retryable = response.status === 502 || response.status === 503;
296
+ lastError = new Error(failure.error?.message ?? `Dialog width request failed with HTTP ${response.status}`);
297
+ if (!retryable)
298
+ throw lastError;
299
+ }
300
+ catch (error) {
301
+ lastError = error;
302
+ }
303
+ await new Promise((resolve) => setTimeout(resolve, attempt * 250));
304
+ }
305
+ throw lastError ?? new Error('Dialog width request failed');
306
+ }
307
+ /** Small external store shared by the Settings route and the CSS engine. */
308
+ class SettingsClient {
309
+ state = { status: 'loading', writable: false, value: undefined, revision: undefined };
310
+ listeners = new Set();
311
+ generation = 0;
312
+ subscribe = (listener) => {
313
+ this.listeners.add(listener);
314
+ return () => { this.listeners.delete(listener); };
315
+ };
316
+ getSnapshot = () => this.state;
317
+ publish(next) {
318
+ this.state = next;
319
+ for (const listener of this.listeners)
320
+ listener();
321
+ }
322
+ async load() {
323
+ const generation = ++this.generation;
324
+ if (this.state.status === 'loading')
325
+ this.publish({ ...this.state, status: 'loading' });
326
+ try {
327
+ const snapshot = await apiRequest();
328
+ if (generation !== this.generation)
329
+ return;
330
+ this.publish({
331
+ status: 'ready',
332
+ writable: snapshot.writable,
333
+ value: snapshot.value,
334
+ revision: snapshot.revision,
335
+ });
336
+ }
337
+ catch (error) {
338
+ if (generation !== this.generation)
339
+ return;
340
+ this.publish({ ...this.state, status: 'error', error: error instanceof Error ? error.message : String(error) });
341
+ }
342
+ }
343
+ async post(payload) {
344
+ const generation = ++this.generation;
345
+ const snapshot = await apiRequest({
346
+ method: 'POST',
347
+ headers: { 'Content-Type': 'application/json' },
348
+ body: JSON.stringify(payload),
349
+ });
350
+ if (generation !== this.generation)
351
+ return;
352
+ this.publish({
353
+ status: 'ready',
354
+ writable: snapshot.writable,
355
+ value: snapshot.value,
356
+ revision: snapshot.revision,
357
+ });
358
+ }
359
+ async set(field, value) {
360
+ await this.post({ action: 'set', field, value, expectedRevision: this.state.revision ?? 0 });
361
+ }
362
+ async unset(field) {
363
+ await this.post({ action: 'unset', field, expectedRevision: this.state.revision ?? 0 });
364
+ }
365
+ }
366
+ exports.SettingsClient = SettingsClient;
367
+ /** Required client services: slots (settings.section) and locale. */
368
+ exports.inject = ['slots', 'locale'];
369
+ /**
370
+ * Hover/focus hint: a small ⓘ next to the field label; the hint text renders
371
+ * in a fixed-position bubble portaled to <body> (so panel `overflow:hidden`
372
+ * can never clip it), measured in a layout effect to prefer the space above
373
+ * the anchor and flip below near the viewport top. No layout shift: hints
374
+ * never occupy flow height.
375
+ */
376
+ function Hint({ text }) {
377
+ const anchorRef = (0, react_1.useRef)(null);
378
+ const popRef = (0, react_1.useRef)(null);
379
+ const [open, setOpen] = (0, react_1.useState)(false);
380
+ const [pos, setPos] = (0, react_1.useState)({ top: -9999, left: -9999 });
381
+ (0, react_1.useLayoutEffect)(() => {
382
+ if (!open)
383
+ return;
384
+ const anchor = anchorRef.current?.getBoundingClientRect();
385
+ const pop = popRef.current;
386
+ if (anchor === undefined || pop === null)
387
+ return;
388
+ let left = Math.min(Math.max(8, anchor.left), window.innerWidth - pop.offsetWidth - 8);
389
+ let top = anchor.top - pop.offsetHeight - 8;
390
+ if (top < 8)
391
+ top = anchor.bottom + 8;
392
+ setPos({ top, left });
393
+ }, [open]);
394
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { ref: anchorRef, className: "dut-hint", role: "note", "aria-label": text, tabIndex: 0, onMouseEnter: () => { setOpen(true); }, onMouseLeave: () => { setOpen(false); }, onFocus: () => { setOpen(true); }, onBlur: () => { setOpen(false); }, children: "i" }), open && (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)("div", { ref: popRef, className: "dut-hint-pop", style: { top: pos.top, left: pos.left }, children: text }), document.body)] }));
395
+ }
396
+ function SettingsSection({ controller, t }) {
397
+ const state = (0, react_1.useSyncExternalStore)(controller.subscribe, controller.getSnapshot, controller.getSnapshot);
398
+ const resolved = resolveValue(state.value);
399
+ const writable = state.writable;
400
+ const [status, setStatus] = (0, react_1.useState)(undefined);
401
+ (0, react_1.useEffect)(() => { if (state.status === 'loading' && state.value === undefined)
402
+ void controller.load(); }, [controller, state.status, state.value]);
403
+ (0, react_1.useEffect)(() => {
404
+ if (status === undefined)
405
+ return;
406
+ const timer = setTimeout(() => { setStatus(undefined); }, 1800);
407
+ return () => { clearTimeout(timer); };
408
+ }, [status]);
409
+ const [widthDraft, setWidthDraft] = (0, react_1.useState)(String(resolved.dialogWidth));
410
+ const [marginDraft, setMarginDraft] = (0, react_1.useState)(String(resolved.sideMargin));
411
+ (0, react_1.useEffect)(() => { setWidthDraft(String(resolved.dialogWidth)); }, [resolved.dialogWidth]);
412
+ (0, react_1.useEffect)(() => { setMarginDraft(String(resolved.sideMargin)); }, [resolved.sideMargin]);
413
+ const commitDialogWidth = (raw) => {
414
+ setWidthDraft(raw);
415
+ const parsed = Number(raw);
416
+ if (!Number.isFinite(parsed))
417
+ return;
418
+ const clamped = Math.min(MAX_DIALOG_WIDTH, Math.max(MIN_DIALOG_WIDTH, Math.round(parsed)));
419
+ setWidthDraft(String(clamped));
420
+ void controller.set('dialogWidth', clamped).then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
421
+ };
422
+ const stepDialogWidth = (delta) => {
423
+ const next = Math.min(MAX_DIALOG_WIDTH, Math.max(MIN_DIALOG_WIDTH, resolved.dialogWidth + delta));
424
+ setWidthDraft(String(next));
425
+ void controller.set('dialogWidth', next).then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
426
+ };
427
+ const applyWidthPreset = (width) => {
428
+ setWidthDraft(String(width));
429
+ void controller.set('dialogWidth', width).then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
430
+ };
431
+ const setUsePluginWidth = (value) => {
432
+ void controller.set('usePluginWidth', value).then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
433
+ };
434
+ const commitSideMargin = (raw) => {
435
+ setMarginDraft(raw);
436
+ const parsed = Number(raw);
437
+ if (!Number.isFinite(parsed))
438
+ return;
439
+ const clamped = Math.max(32, Math.round(parsed));
440
+ setMarginDraft(String(clamped));
441
+ void controller.set('sideMargin', clamped).then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
442
+ };
443
+ const stepSideMargin = (delta) => {
444
+ const next = Math.max(32, resolved.sideMargin + delta);
445
+ setMarginDraft(String(next));
446
+ void controller.set('sideMargin', next).then(() => { setStatus('applied'); }).catch(() => { setStatus('unavailable'); });
447
+ };
448
+ if (state.status === 'loading' && state.value === undefined) {
449
+ return (0, jsx_runtime_1.jsx)("div", { className: "dut-settings", children: (0, jsx_runtime_1.jsx)("div", { className: "dut-loading", children: t('loading') }) });
450
+ }
451
+ if (state.status === 'error') {
452
+ return (0, jsx_runtime_1.jsx)("div", { className: "dut-settings", children: (0, jsx_runtime_1.jsx)("div", { className: "dut-alert error", children: t('unavailable') }) });
453
+ }
454
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "dut-settings", children: [(0, jsx_runtime_1.jsxs)("header", { className: "dut-settings-header", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-logo", children: "\uD83D\uDCD0" }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h2", { children: t('settingsTitle') }), (0, jsx_runtime_1.jsx)("p", { children: t('settingsIntro') })] })] }), !writable ? (0, jsx_runtime_1.jsx)("div", { className: "dut-alert warning", children: t('readOnly') }) : null, status === undefined ? null : (0, jsx_runtime_1.jsx)("div", { className: "dut-status", children: t(status) }), (0, jsx_runtime_1.jsxs)("section", { className: "dut-panel", children: [(0, jsx_runtime_1.jsx)("div", { className: "dut-section-label", children: t('sectionLayout') }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('usePluginWidth'), (0, jsx_runtime_1.jsx)(Hint, { text: t('usePluginWidthHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: resolved.usePluginWidth ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setUsePluginWidth(true); }, children: t('usePluginWidthOn') }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: !resolved.usePluginWidth ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { setUsePluginWidth(false); }, children: t('usePluginWidthOff') })] }) })] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "dut-field", children: [(0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('dialogWidth'), (0, jsx_runtime_1.jsx)(Hint, { text: t('dialogWidthHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-stepper", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", "aria-label": "\u2212", disabled: !writable || resolved.dialogWidth <= MIN_DIALOG_WIDTH, onClick: () => { stepDialogWidth(-20); }, children: "\u2212" }), (0, jsx_runtime_1.jsx)("input", { type: "number", min: MIN_DIALOG_WIDTH, max: MAX_DIALOG_WIDTH, step: 20, value: widthDraft, disabled: !writable, onChange: (event) => { setWidthDraft(event.target.value); }, onBlur: (event) => { commitDialogWidth(event.target.value); }, onKeyDown: (event) => { if (event.key === 'Enter')
455
+ commitDialogWidth(event.target.value); } }), (0, jsx_runtime_1.jsx)("button", { type: "button", "aria-label": "+", disabled: !writable || resolved.dialogWidth >= MAX_DIALOG_WIDTH, onClick: () => { stepDialogWidth(20); }, children: "+" })] }) })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-presets", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-seg", children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: resolved.dialogWidth === 880 ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { applyWidthPreset(880); }, children: [t('presetWide'), " \u00B7 880"] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: resolved.dialogWidth === 1024 ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { applyWidthPreset(1024); }, children: [t('presetWideXl'), " \u00B7 1024"] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: resolved.dialogWidth === 748 ? 'dut-seg-active' : '', disabled: !writable, onClick: () => { applyWidthPreset(748); }, children: [t('presetDefault'), " \u00B7 748"] })] }) })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-field", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-field-top", children: [(0, jsx_runtime_1.jsxs)("span", { className: "dut-label", children: [t('sideMargin'), (0, jsx_runtime_1.jsx)(Hint, { text: t('sideMarginHint') })] }), (0, jsx_runtime_1.jsx)("div", { className: "dut-controls", children: (0, jsx_runtime_1.jsxs)("div", { className: "dut-stepper", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", "aria-label": "\u2212", disabled: !writable || resolved.sideMargin <= 32, onClick: () => { stepSideMargin(-4); }, children: "\u2212" }), (0, jsx_runtime_1.jsx)("input", { type: "number", min: 32, step: 4, value: marginDraft, disabled: !writable, onChange: (event) => { setMarginDraft(event.target.value); }, onBlur: (event) => { commitSideMargin(event.target.value); }, onKeyDown: (event) => { if (event.key === 'Enter')
456
+ commitSideMargin(event.target.value); } }), (0, jsx_runtime_1.jsx)("button", { type: "button", "aria-label": "+", disabled: !writable, onClick: () => { stepSideMargin(4); }, children: "+" })] }) })] }) })] })] }));
457
+ }
458
+ function apply(ctx) {
459
+ ctx.effect(installBaseStyles, 'dsh-dialog-width: base styles');
460
+ ctx.effect(() => ctx.locale.register(NS, { en, zh }), 'dsh-dialog-width: locale');
461
+ const t = ctx.locale.bind(NS);
462
+ const controller = new SettingsClient();
463
+ // Width-axis override: when plugin-width is on, install the handle-hiding
464
+ // + user-width-clamp CSS (see conversation-width.ts — it drives DSH's own
465
+ // shared width axis, so the transcript, composer card, dock, and turn
466
+ // navigator all follow the stock math); when off, dispose it. The
467
+ // subscribe callback re-runs on every settings change, so width,
468
+ // sideMargin, and the toggle all apply live.
469
+ ctx.effect(() => {
470
+ let widthController;
471
+ const sync = () => {
472
+ const value = controller.getSnapshot().value;
473
+ const usePlugin = value?.usePluginWidth ?? true;
474
+ const width = resolveDialogWidth(value?.dialogWidth);
475
+ const sideMargin = resolveSideMargin(value?.sideMargin);
476
+ if (usePlugin) {
477
+ if (widthController === undefined) {
478
+ widthController = (0, conversation_width_ts_1.installConversationWidthStyles)(width, sideMargin);
479
+ }
480
+ else {
481
+ widthController.setWidth(width, sideMargin);
482
+ }
483
+ }
484
+ else if (widthController !== undefined) {
485
+ widthController.dispose();
486
+ widthController = undefined;
487
+ }
488
+ };
489
+ sync();
490
+ void controller.load();
491
+ return controller.subscribe(sync);
492
+ }, 'dsh-dialog-width: conversation width');
493
+ ctx.slots.inject('settings.section', () => ctx.slots.register({
494
+ name: 'settings.section',
495
+ id: NS,
496
+ order: 40,
497
+ label: () => t('nav'),
498
+ inject: () => ({ controller, t }),
499
+ }, SettingsSection));
500
+ }
501
+ };
502
+ function __resolve(from, request) {
503
+ if (!request.startsWith(".")) return request;
504
+ var parts = from.slice(2).split("/"); parts.pop();
505
+ for (var part of request.split("/")) { if (part === "." || part === "") continue; if (part === "..") parts.pop(); else parts.push(part); }
506
+ return "./" + parts.join("/");
507
+ }
508
+ function __load(id) {
509
+ if (__modules[id] === undefined) return require(id);
510
+ if (__cache[id] !== undefined) return __cache[id].exports;
511
+ var module = __cache[id] = { exports: {} };
512
+ __modules[id](module, module.exports, require, function(request) { var resolved = __resolve(id, request); return __modules[resolved] === undefined ? require(request) : __load(resolved); });
513
+ return module.exports;
514
+ }
515
+ return __load("./index.js"); } });
516
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sections":[{"offset":{"line":3,"column":0},"map":{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client/conversation-width.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;;AA8CH,wEAgCC;AA5ED;;;;;GAKG;AACH,MAAM,8BAA8B,GAAG,+BAA+B,CAAA;AAEtE,8FAA8F;AAC9F,MAAM,gBAAgB,GAAG,8CAA8C,CAAA;AAEvE,oEAAoE;AACpE,MAAM,cAAc,GAAG,GAAG,CAAA;AAE1B;;;;;;;GAOG;AACH,SAAS,aAAa,CAAC,OAAe,EAAE,UAAkB;IACxD,OAAO;EACP,gBAAgB;gEAC8C,OAAO,WAAW,cAAc,4DAA4D,UAAU,GAAG,CAAC;sCACpI,OAAO;CAC5C,CAAA;AACD,CAAC;AASD;;;;;;GAMG;AACH,SAAgB,8BAA8B,CAAC,OAAe,EAAE,UAAkB;IAChF,MAAM,EAAE,GAAG,qCAAqC,CAAA;IAChD,IAAI,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAmB,0BAA0B,EAAE,IAAI,CAAC,CAAA;IACtF,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;QACvC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,kBAAkB,CAAA;QACzC,KAAK,CAAC,OAAO,CAAC,SAAS,GAAG,EAAE,CAAA;QAC5B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAClC,CAAC;IAED,2EAA2E;IAC3E,qDAAqD;IACrD,IAAI,CAAC;QAAC,YAAY,CAAC,OAAO,CAAC,8BAA8B,EAAE,GAAG,OAAO,EAAE,CAAC,CAAA;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,qCAAqC,CAAC,CAAC;IAE1H,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,MAAc,EAAQ,EAAE;QACjD,KAAM,CAAC,WAAW,GAAG,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;QAC9C,sEAAsE;QACtE,oEAAoE;QACpE,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,+BAA+B,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACxF,CAAC,CAAA;IACD,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;IAE1B,OAAO;QACL,QAAQ,EAAE,CAAC,EAAU,EAAE,MAAc,EAAQ,EAAE;YAC7C,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;YACjB,IAAI,CAAC;gBAAC,YAAY,CAAC,OAAO,CAAC,8BAA8B,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC9F,CAAC;QACD,OAAO,EAAE,GAAS,EAAE;YAClB,KAAK,EAAE,MAAM,EAAE,CAAA;YACf,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,cAAc,CAAC,+BAA+B,CAAC,CAAA;QAChF,CAAC;KACF,CAAA;AACH,CAAC"}},{"offset":{"line":134,"column":0},"map":{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client/index.tsx"],"names":[],"mappings":"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"}}]}
package/lib/config.js ADDED
@@ -0,0 +1,54 @@
1
+ /**
2
+ * dsh-dialog-width — configuration.
3
+ *
4
+ * Owns the `dialog-width` settings namespace: a single toggle (plugin width
5
+ * control) plus the dialog width input (px). Everything else is owned by the
6
+ * host or other plugins.
7
+ * @module dsh-dialog-width/config
8
+ */
9
+ import z from '@deepseek-ai/schemastery';
10
+ /** Settings document namespace owned by this plugin. */
11
+ export const DIALOG_WIDTH_SETTINGS_NAMESPACE = 'dialog-width';
12
+ /** Dialog width in px. 600 is the chat-column minimum, 1600 the soft cap. */
13
+ export const MIN_DIALOG_WIDTH = 600;
14
+ export const MAX_DIALOG_WIDTH = 1600;
15
+ /** 748 matches the stock DSH column. */
16
+ export const DEFAULT_DIALOG_WIDTH = 748;
17
+ /**
18
+ * Plugin width control defaults to ON: existing settings documents never had
19
+ * this field, so the default must match what users saw before the native
20
+ * handles shipped — the plugin owning the column.
21
+ */
22
+ export const DEFAULT_USE_PLUGIN_WIDTH = true;
23
+ /** Default side margin in px — 50 gives a comfortable gap on each side. */
24
+ export const DEFAULT_SIDE_MARGIN = 50;
25
+ /** Minimum side margin in px — below 32 the gap becomes too tight. */
26
+ export const MIN_SIDE_MARGIN = 32;
27
+ /**
28
+ * localStorage slot the native WidthHandle reads/writes; kept here so a
29
+ * future rename of the host key only needs touching one place. We mirror
30
+ * the plugin's chosen px value here too so toggling plugin-width off
31
+ * surfaces the user's last choice in the native handle.
32
+ */
33
+ export const CONVERSATION_WIDTH_STORAGE_KEY = 'dsh.conversation.contentWidth';
34
+ /** Configuration schema with documented defaults. */
35
+ export const Config = z.object({
36
+ dialogWidth: z.number().min(MIN_DIALOG_WIDTH).max(MAX_DIALOG_WIDTH).default(DEFAULT_DIALOG_WIDTH),
37
+ usePluginWidth: z.boolean().default(DEFAULT_USE_PLUGIN_WIDTH),
38
+ sideMargin: z.number().min(MIN_SIDE_MARGIN).default(DEFAULT_SIDE_MARGIN),
39
+ });
40
+ /** Resolve a partial config into a fully defaulted value. */
41
+ export function resolveConfig(config = {}) {
42
+ const dialogWidth = resolveDialogWidth(config.dialogWidth);
43
+ const usePluginWidth = config.usePluginWidth ?? DEFAULT_USE_PLUGIN_WIDTH;
44
+ const sideMargin = config.sideMargin ?? DEFAULT_SIDE_MARGIN;
45
+ return { dialogWidth, usePluginWidth, sideMargin };
46
+ }
47
+ /** Normalize a dialog width value (legacy strings included) to px. */
48
+ export function resolveDialogWidth(value) {
49
+ if (typeof value === 'number') {
50
+ return Math.min(MAX_DIALOG_WIDTH, Math.max(MIN_DIALOG_WIDTH, Math.round(value)));
51
+ }
52
+ return DEFAULT_DIALOG_WIDTH;
53
+ }
54
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAGxC,wDAAwD;AACxD,MAAM,CAAC,MAAM,+BAA+B,GAAG,cAAc,CAAA;AA8B7D,6EAA6E;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA;AACnC,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAA;AACpC,wCAAwC;AACxC,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAA;AAEvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAA;AAE5C,2EAA2E;AAC3E,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAA;AACrC,sEAAsE;AACtE,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAA;AAEjC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,+BAA+B,CAAA;AAE7E,qDAAqD;AACrD,MAAM,CAAC,MAAM,MAAM,GAA8B,CAAC,CAAC,MAAM,CAAC;IACxD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC;IACjG,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,wBAAwB,CAAC;IAC7D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC;CACzE,CAAC,CAAA;AAYF,6DAA6D;AAC7D,MAAM,UAAU,aAAa,CAAC,SAA4B,EAAE;IAC1D,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IAC1D,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,wBAAwB,CAAA;IACxE,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,mBAAmB,CAAA;IAC3D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,CAAA;AACpD,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,kBAAkB,CAAC,KAAyB;IAC1D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAClF,CAAC;IACD,OAAO,oBAAoB,CAAA;AAC7B,CAAC"}