@linkdesk/ui 0.1.0 → 0.1.2
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/dist/button/Button.d.ts +13 -2
- package/dist/combobox/Combobox.d.ts +1 -1
- package/dist/hooks/useClickPreview.d.ts +33 -0
- package/dist/hooks/useClipboardKeys.d.ts +33 -0
- package/dist/hooks/useDebouncedInput.d.ts +18 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1484 -971
- package/dist/select-box/SelectBox.d.ts +1 -1
- package/dist/string-list-editor/StringListEditor.d.ts +44 -0
- package/dist/string-list-editor/urlSourceKey.d.ts +13 -0
- package/package.json +1 -1
package/dist/button/Button.d.ts
CHANGED
|
@@ -2,18 +2,29 @@
|
|
|
2
2
|
* E5.8#99:实心 accent 动作按钮(按钮双轨制实心轨)——动作/提交,对标 VS Code。
|
|
3
3
|
* ghost 轨(选择/分组)= SegmentedRadio。双轨约定:选什么用 ghost 分段,做什么用实心按钮。
|
|
4
4
|
*
|
|
5
|
+
* E6#30.14 variant——语义动作层级(10-市场UI拥有权.md §四·一:安装=success 填充 / 卸载=danger /
|
|
6
|
+
* 禁用=ghost;视觉源 = mockup 02 st-*):
|
|
7
|
+
* 缺省 = 实心 accent(现状不变)——主操作
|
|
8
|
+
* success = 实心绿(--success)——正面主操作(安装 / 启用)
|
|
9
|
+
* danger = 破坏性次级(danger 文本+边,非实心——destructive 不抢主操作眼)
|
|
10
|
+
* ghost = 次级透明钮(text-secondary + separator 边)
|
|
11
|
+
* 变体样式全走语义/主题 token,零硬编码 hex(硬约束 1)。variant = props 非配置项(零新配置)。
|
|
12
|
+
*
|
|
5
13
|
* 抽壳动机:动作按钮此前是 settings 插件 CSS 类 .settings-action-btn,却被壳共享组件
|
|
6
14
|
* FilePathInput 消费——壳组件依赖插件 CSS 的倒置耦合。收编壳后 shell 组件零依赖插件样式,
|
|
7
15
|
* 第三方插件直接用 <Button> 即得壳动作按钮(不用拷 CSS)。
|
|
8
16
|
*
|
|
9
|
-
* 消费方:settings renderHint:"action" 命令按钮、背景图三态按钮、FilePathInput
|
|
17
|
+
* 消费方:settings renderHint:"action" 命令按钮、背景图三态按钮、FilePathInput「…」按钮、
|
|
18
|
+
* marketplace 详情 action bar(禁用/启用/卸载,E6#30.14c)。
|
|
10
19
|
*/
|
|
20
|
+
type ButtonVariant = "success" | "danger" | "ghost";
|
|
11
21
|
interface ButtonProps {
|
|
12
22
|
children: React.ReactNode;
|
|
13
23
|
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
14
24
|
disabled?: boolean;
|
|
15
25
|
title?: string;
|
|
16
26
|
type?: "button" | "submit" | "reset";
|
|
27
|
+
variant?: ButtonVariant;
|
|
17
28
|
}
|
|
18
|
-
declare function Button({ children, onClick, disabled, title, type }: ButtonProps): import("react").JSX.Element;
|
|
29
|
+
declare function Button({ children, onClick, disabled, title, type, variant }: ButtonProps): import("react").JSX.Element;
|
|
19
30
|
export default Button;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* 选择下拉项 / Enter / 失焦(文本有变更)→ onChange(新值);文本无变更 → 不触发。
|
|
10
10
|
*
|
|
11
11
|
* 归一化:壳组件库范畴(components/shared/)——壳视图 + 插件共用。
|
|
12
|
-
*
|
|
12
|
+
* 壳内部引用 @src 源码;插件作者(含内置插件 E6#54c)→ `import { Combobox } from "@linkdesk/ui"`。
|
|
13
13
|
* 下拉面板视觉复用 SelectBox(.selectbox-dropdown/list/item/empty 类)——一个视觉语言
|
|
14
14
|
* 一处写,jscpd 0 克隆门禁:Combobox.css 只定义 field/input/arrow,下拉视觉零重写。
|
|
15
15
|
*/
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useClickPreview — 单击预览 / 双击锁定归一化 hook。
|
|
3
|
+
* E4V#28e:从 FileTreeNode 提取——任何树/列表组件复用同一交互。
|
|
4
|
+
* E6#15h 归位:@linkdesk/ui 零件(本文件 = 壳单一源码副本;任何插件含第三方 `import { useClickPreview } from "@linkdesk/ui"`)。
|
|
5
|
+
* 详见 08-共享hook归位.md。
|
|
6
|
+
*
|
|
7
|
+
* 对标 VS Code explorer 的文件点击行为:
|
|
8
|
+
* - 单击(mousedown 启动 250ms 定时器)→ 预览标签页(斜体,可替换)
|
|
9
|
+
* - 双击(e.detail === 2)→ 锁定标签页(正体,不再替换)
|
|
10
|
+
* - disabled = 目录节点——不启动定时器,不响应双击锁定
|
|
11
|
+
*
|
|
12
|
+
* @param onPreview 预览回调——定时器到期后触发
|
|
13
|
+
* @param onPin 锁定回调——双击时触发
|
|
14
|
+
* @param disabled 禁用预览/锁定(如目录节点),默认 false
|
|
15
|
+
* @param delay 双击检测窗口(ms),默认 250
|
|
16
|
+
* @returns { handleMouseDown, handleClick }——展开到行级事件处理器
|
|
17
|
+
*/
|
|
18
|
+
interface UseClickPreviewOptions {
|
|
19
|
+
onPreview: () => void;
|
|
20
|
+
onPin: () => void;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
delay?: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function useClickPreview({ onPreview, onPin, disabled, delay }: UseClickPreviewOptions): {
|
|
25
|
+
handleMouseDown: (e: {
|
|
26
|
+
button?: number;
|
|
27
|
+
}) => void;
|
|
28
|
+
handleClick: (e: {
|
|
29
|
+
detail: number;
|
|
30
|
+
button?: number;
|
|
31
|
+
}) => void;
|
|
32
|
+
};
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useClipboardKeys — 池侧 Ctrl/Cmd+C / X / V 剪贴板键归一化 hook。
|
|
3
|
+
* E5.8#24.8.3 定案(用户拍板路径 2):共享 hook 消除每插件重复的剪贴板键处理。
|
|
4
|
+
* E6#15h 归位:@linkdesk/ui 零件(本文件 = 壳单一源码副本;任何插件含第三方 `import { useClipboardKeys } from "@linkdesk/ui"`)。
|
|
5
|
+
* 详见 08-共享hook归位.md。
|
|
6
|
+
*
|
|
7
|
+
* 背景(教训链——看 memory keyboard-router-before-input-event):
|
|
8
|
+
* 壳级剪贴板键已删(E5.8#24.8.1)——主进程 keyCache 命中 = 无条件 preventDefault,
|
|
9
|
+
* 在池 WCV 收到键之前吞掉,且不认 when/可编辑状态 → 池内 Monaco 原生复制粘贴全死。
|
|
10
|
+
* 正解 = 池侧自处理:插件在自己 React keydown 里处理文本键。DOM 焦点天然分区——
|
|
11
|
+
* 文件树聚焦才收键,Monaco 聚焦收不到,多插件各干各的 ctrl+c 互不打扰,
|
|
12
|
+
* 不需要 when、不需要冲突检测。
|
|
13
|
+
*
|
|
14
|
+
* 机制与语义分离:
|
|
15
|
+
* 机制(ctrl/meta 检测 + preventDefault + 键映射)归一在此 hook——一处实现一处修。
|
|
16
|
+
* 语义(复制/剪切/粘贴各自做什么)由插件声明式交出——AI 只填回调,零追踪影响面。
|
|
17
|
+
*
|
|
18
|
+
* 焦点守卫天然成立:本 hook 返回的 handler 挂在插件容器 onKeyDown 上——
|
|
19
|
+
* 只有插件聚焦才收到事件;可编辑子元素(如重命名 InlineInput)须自行 stopPropagation,
|
|
20
|
+
* 否则打字时 Ctrl+C/V/X 冒泡到容器(文件树已如此处理)。
|
|
21
|
+
*
|
|
22
|
+
* @param onCopy 复制回调(Ctrl+C / Cmd+C)
|
|
23
|
+
* @param onCut 剪切回调(Ctrl+X / Cmd+X)
|
|
24
|
+
* @param onPaste 粘贴回调(Ctrl+V / Cmd+V)
|
|
25
|
+
* @returns `(e) => boolean`——在消费方 onKeyDown 中组合:返回 true 表示该键已被消费
|
|
26
|
+
* (调用方应 return,勿继续走其他逻辑);false 表示未命中剪贴板键。
|
|
27
|
+
*/
|
|
28
|
+
export interface UseClipboardKeysCallbacks {
|
|
29
|
+
onCopy?: () => void;
|
|
30
|
+
onCut?: () => void;
|
|
31
|
+
onPaste?: () => void;
|
|
32
|
+
}
|
|
33
|
+
export declare function useClipboardKeys(callbacks: UseClipboardKeysCallbacks): (e: React.KeyboardEvent) => boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useDebouncedInput — 防抖输入归一化 hook。
|
|
3
|
+
* E3.6 E36#7.3c 提取:本地 state 即时响应 + 模块级/外部 state 防抖同步。
|
|
4
|
+
* E6#15h 归位:@linkdesk/ui 零件(本文件 = 壳单一源码副本;任何插件含第三方 `import { useDebouncedInput } from "@linkdesk/ui"`)。
|
|
5
|
+
* 详见 08-共享hook归位.md。
|
|
6
|
+
*
|
|
7
|
+
* 使用场景:输入框值需要即时反馈(不卡打字),但下游过滤/搜索走防抖(不每键重渲染)。
|
|
8
|
+
* 命令面板流畅就是因为输入是本地 state——这个 hook 把同样的模式归一化。
|
|
9
|
+
*
|
|
10
|
+
* @param setExternal 防抖后同步到的外部 setter(如模块级 setSearch)
|
|
11
|
+
* @param debounceMs 防抖毫秒数,默认 150
|
|
12
|
+
* @returns { value, onChange, onClear }——直接展开到 <input> 上
|
|
13
|
+
*/
|
|
14
|
+
export declare function useDebouncedInput(setExternal: (value: string) => void, debounceMs?: number): {
|
|
15
|
+
value: string;
|
|
16
|
+
onChange: (next: string) => void;
|
|
17
|
+
onClear: () => void;
|
|
18
|
+
};
|
package/dist/index.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.button{background:var(--accent);color:var(--text-on-accent);border:none;border-radius:var(--radius-sm);padding:4px 12px;font-size:var(--font-size-sm);cursor:pointer;white-space:nowrap}.button:hover{opacity:.85}.button:disabled{opacity:.5;cursor:default}.colorpicker-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--z-overlay-backdrop)}.colorpicker-panel{position:fixed;z-index:var(--z-overlay);background:var(--bg-window);border:1px solid var(--separator);border-radius:var(--radius-md);padding:12px;box-shadow:var(--shadow-float);display:flex;flex-wrap:wrap;width:232px;gap:8px;top:50%;left:50%;transform:translate(-50%,-50%)}.colorpicker-panel[style]{transform:none}.colorpicker-sv{width:180px;height:150px;border-radius:var(--radius-sm);position:relative;cursor:crosshair;overflow:hidden;-webkit-user-select:none;user-select:none}.colorpicker-sv-white{position:absolute;top:0;right:0;bottom:0;left:0;background:linear-gradient(to right,#fff,transparent)}.colorpicker-sv-black{position:absolute;top:0;right:0;bottom:0;left:0;background:linear-gradient(to top,#000,transparent)}.colorpicker-sv-cursor{position:absolute;width:10px;height:10px;border:2px solid #fff;border-radius:var(--radius-full);box-shadow:var(--shadow-tiny);transform:translate(-50%,-50%);pointer-events:none}.colorpicker-hue{width:180px;height:14px;border-radius:var(--radius-md);position:relative;cursor:pointer;-webkit-user-select:none;user-select:none;background:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.colorpicker-hue-cursor{position:absolute;top:-2px;width:4px;height:18px;background:#fff;border-radius:var(--radius-xs);box-shadow:var(--shadow-tiny);transform:translate(-50%);pointer-events:none}.colorpicker-footer{display:flex;align-items:center;gap:6px;width:100%}.colorpicker-preview{width:28px;height:28px;border-radius:var(--radius-sm);border:1px solid var(--separator);flex-shrink:0}.colorpicker-hex{flex:1;min-width:0;height:calc(26px * var(--ui-scale));padding:2px 6px;border:1px solid var(--separator);border-radius:var(--radius-sm);background:var(--bg-input);color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size-sm);outline:none;box-sizing:border-box}.colorpicker-hex:focus{border-color:var(--accent)}.colorpicker-ok{height:calc(26px * var(--ui-scale));padding:0 12px;background:var(--accent);color:var(--text-on-accent);border:none;border-radius:var(--radius-sm);font-size:var(--font-size-sm);cursor:pointer;flex-shrink:0}.colorpicker-ok:hover{background:var(--accent-hover)}.colorpicker-presets{width:100%;display:flex;gap:6px;flex-wrap:wrap;padding-top:4px;border-top:1px solid var(--separator)}.colorpicker-preset{width:18px;height:18px;border-radius:var(--radius-full);border:1px solid var(--separator);cursor:pointer;transition:transform .1s}.colorpicker-preset:hover{transform:scale(1.2);border-color:var(--accent)}.combobox{position:relative;display:inline-block;min-width:100px}.combobox-field{display:flex;align-items:center;gap:4px;padding:3px 6px;background:var(--bg-input);color:var(--text-primary);border:1px solid var(--border);border-radius:var(--radius-xs);font-size:var(--font-size-md);line-height:1.6;cursor:text}.combobox-field:hover:not(.selectbox-disabled){border-color:var(--accent)}.combobox.selectbox-open .combobox-field{border-color:var(--accent)}.combobox-input{flex:1;min-width:0;padding:0;background:transparent;border:none;outline:none;color:inherit;font:inherit;line-height:1.6}.combobox-input::placeholder{color:var(--text-muted)}.combobox-input:disabled{opacity:.5}.selectbox{position:relative;display:inline-block;min-width:100px;-webkit-user-select:none;user-select:none}.selectbox-trigger{display:flex;align-items:center;justify-content:space-between;gap:4px;width:100%;padding:3px 6px;background:var(--bg-input);color:var(--text-primary);border:1px solid var(--border);border-radius:var(--radius-xs);font-size:var(--font-size-md);line-height:1.6;cursor:pointer;font-family:inherit;text-align:left}.selectbox-trigger:hover:not(:disabled){border-color:var(--accent)}.selectbox-trigger:disabled{opacity:.5;cursor:default}.selectbox-open .selectbox-trigger{border-color:var(--accent)}.selectbox-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.selectbox-swatch{display:inline-block;width:10px;height:10px;margin-right:5px;border-radius:50%;border:1px solid color-mix(in srgb,var(--text-primary) 35%,transparent);vertical-align:middle;flex-shrink:0}.selectbox-arrow{flex-shrink:0;font-size:var(--font-size-sm);transition:transform .15s ease}.selectbox-arrow-up{transform:rotate(180deg)}.selectbox-dropdown{position:absolute;top:100%;left:0;margin-top:2px;background:var(--bg-window);border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:var(--shadow-pop);overflow:hidden;z-index:var(--z-dropdown);max-height:260px;max-width:calc(100vw - 24px);display:flex;flex-direction:column;animation:selectbox-in .1s ease-out}@keyframes selectbox-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.selectbox-search{padding:4px;border-bottom:1px solid var(--separator)}.selectbox-search-input{width:100%;padding:2px 6px;background:var(--bg-input);color:var(--text-primary);border:1px solid var(--border);border-radius:var(--radius-xs);font-size:var(--font-size-sm);font-family:inherit;outline:none;box-sizing:border-box}.selectbox-search-input:focus{border-color:var(--accent)}.selectbox-list{list-style:none;margin:0;padding:2px 0;overflow-y:auto;outline:none}.selectbox-item{padding:3px 8px;font-size:var(--font-size-md);line-height:1.6;color:var(--text-primary);cursor:pointer}.selectbox-item-focus{background:var(--accent);color:var(--text-on-accent)}.selectbox-item-selected:not(.selectbox-item-focus){background:var(--bg-selection)}.selectbox-empty{padding:6px 8px;font-size:var(--font-size-sm);color:var(--text-muted);text-align:center}.selectbox-disabled{pointer-events:none}.ctx-menu{position:fixed;min-width:140px;max-width:280px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-hairline),var(--context-menu-shadow);padding:4px 0;overflow:hidden;outline:none;opacity:0;transform:scale(.96);transform-origin:top left;transition:opacity .15s ease-out,transform .15s ease-out}.ctx-menu:focus-visible{outline:none}.ctx-menu.show{opacity:1;transform:scale(1)}.ctx-item{display:flex;align-items:center;gap:8px;padding:6px 12px;font-size:var(--font-size-md);font-weight:400;line-height:1.6;color:var(--text-primary);cursor:pointer;transition:background 60ms;-webkit-user-select:none;user-select:none}.ctx-item:hover,.ctx-item.focused{background:var(--tab-hover-bg);color:var(--text-primary);box-shadow:inset 2px 0 0 var(--accent)}.ctx-item-icon{flex-shrink:0;width:calc(16px * var(--ui-scale));height:calc(16px * var(--ui-scale));font-size:var(--font-size-lg);display:flex;align-items:center;justify-content:center;opacity:.75}.ctx-item:hover .ctx-item-icon,.ctx-item.focused .ctx-item-icon{opacity:1;color:var(--accent)}.ctx-item-shortcut{flex-shrink:0;margin-left:12px;font-size:var(--font-size-xs);opacity:.6;font-family:var(--font-mono);letter-spacing:.2px}.ctx-item:hover .ctx-item-shortcut,.ctx-item.focused .ctx-item-shortcut{opacity:.9;color:var(--text-secondary)}.ctx-item-check{flex-shrink:0;width:16px;font-size:var(--font-size-sm);color:var(--accent);display:flex;align-items:center}.ctx-item-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ctx-divider{height:1px;background:var(--separator);margin:4px 12px}.ctx-item-danger{color:var(--danger)}.ctx-item-danger .ctx-item-icon{opacity:1}.ctx-item-danger:hover,.ctx-item-danger.focused{background:var(--tab-hover-bg);color:var(--danger);box-shadow:inset 2px 0 0 var(--danger)}.ctx-item-danger:hover .ctx-item-shortcut,.ctx-item-danger.focused .ctx-item-shortcut{opacity:.9;color:var(--text-secondary)}.form-row{display:flex;align-items:center;gap:8px;margin-bottom:6px;font-size:var(--font-size-sm);color:var(--text-primary)}.form-row>label,.form-row>.form-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-row>.toggle,.form-row>.input,.form-row>select,.form-row>.form-control{flex-shrink:0}.number-input{display:inline-flex;align-items:center;gap:0}.number-input-btn{display:flex;align-items:center;justify-content:center;width:calc(22px * var(--ui-scale));height:calc(24px * var(--ui-scale));padding:0;border:1px solid var(--border);background:var(--bg-input);color:var(--text-primary);font-size:var(--font-size-lg);line-height:1;cursor:pointer;transition:background .15s,border-color .15s;-webkit-user-select:none;user-select:none}.number-input-btn:first-child{border-radius:var(--radius-sm) 0 0 var(--radius-sm);border-right:none}.number-input-btn:last-child{border-radius:0 var(--radius-sm) var(--radius-sm) 0;border-left:none}.number-input-btn:hover:not(:disabled){background:var(--tab-hover-bg)}.number-input-btn:active:not(:disabled){background:var(--accent);color:var(--text-on-accent)}.number-input-btn:disabled{opacity:.3;cursor:default}.number-input-field{border-radius:0;text-align:center;width:44px}.number-input-unit{margin:0 6px 0 8px;color:var(--text-muted);font-size:var(--font-size-sm);line-height:1;-webkit-user-select:none;user-select:none}.segmented-radio{display:flex;gap:4px}.segmented-radio__option{display:flex;flex-direction:column;align-items:center;gap:4px;padding:4px 8px;background:transparent;border:1px solid var(--separator);border-radius:var(--radius-sm);cursor:pointer;transition:border-color .12s ease,background .12s ease}.segmented-radio__option:hover{border-color:var(--text-muted);background:var(--hover-overlay)}.segmented-radio__option:focus-visible{outline:1px solid var(--accent);outline-offset:1px}.segmented-radio__option.is-selected{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 12%,transparent)}.segmented-radio__label{font-size:var(--font-size-sm);color:var(--text-secondary);white-space:nowrap}.segmented-radio__option.is-selected .segmented-radio__label{color:var(--text-primary)}.slider{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:130px;height:4px;margin:0;border-radius:var(--radius-sm);background:linear-gradient(to right,var(--accent) var(--slider-pct, 0%),var(--border) var(--slider-pct, 0%));cursor:pointer;outline-offset:4px}.slider:disabled{opacity:.4;cursor:default}.slider::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:12px;height:12px;border-radius:50%;background:var(--text-primary);box-shadow:var(--shadow-tiny);cursor:grab}.slider::-webkit-slider-thumb:active{cursor:grabbing}.theme-picker{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;width:100%}.theme-card{border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;cursor:pointer;background:var(--bg-card);padding:0;text-align:left;color:inherit;font:inherit;transition:border-color .15s ease,transform .15s ease}.theme-card:hover{border-color:var(--separator);transform:translateY(-1px)}.theme-card:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.theme-card.active{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.theme-preview{height:44px;display:flex;align-items:center;gap:3px;padding:8px;overflow:hidden}.theme-preview .pv-bar{width:26px;height:12px;border-radius:var(--radius-xs)}.theme-preview .pv-dots{display:flex;gap:3px}.theme-preview .pv-dot{width:12px;height:12px;border-radius:50%;border:1px solid color-mix(in srgb,var(--text-primary) 35%,transparent)}.theme-card .tname{padding:6px 8px;font-size:var(--font-size-xs);color:var(--text-secondary);display:flex;align-items:center;justify-content:space-between;gap:4px;overflow:hidden}.theme-card.active .tname{color:var(--text-primary)}.theme-card .tname-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.theme-card .badge{font-size:var(--font-size-2xs);color:var(--accent);white-space:nowrap}.theme-picker-empty{color:var(--text-muted);font-size:var(--font-size-sm);padding:8px 0}.toggle{width:36px;height:20px;border-radius:var(--radius-pill);background:var(--border);transition:background .15s;cursor:pointer;position:relative;flex-shrink:0}.toggle.on{background:var(--accent)}.toggle:after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:var(--radius-pill);background:var(--toggle-knob);transition:transform .15s}.toggle.on:after{transform:translate(16px);background:var(--toggle-knob-on, var(--text-on-accent))}.toggle.disabled{opacity:.4;cursor:not-allowed}.inline-input{border:1px solid var(--border);background:var(--bg-input);color:var(--text-primary);font-family:inherit;outline:none;box-sizing:border-box;width:100%;transition:border-color .15s ease-out,box-shadow .15s ease-out}.inline-input:focus{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.inline-input--compact{height:calc(22px * var(--ui-scale));font-size:var(--font-size-sm);padding:0 4px}.inline-input--normal{height:calc(32px * var(--ui-scale));font-size:var(--font-size-md);padding:0 8px}
|
|
1
|
+
.badge{display:inline-flex;align-items:center;background:var(--badge-background);color:var(--badge-foreground);border-radius:var(--radius-sm);padding:1px 6px;font-size:var(--font-size-2xs);font-weight:500;line-height:1.4;white-space:nowrap;flex-shrink:0}.button{background:var(--accent);color:var(--text-on-accent);border:1px solid transparent;border-radius:var(--radius-sm);padding:4px 12px;font-size:var(--font-size-sm);cursor:pointer;white-space:nowrap}.button:hover:not(:disabled){opacity:.85}.button:disabled{opacity:.5;cursor:default}.button--success{background:var(--success);border-color:var(--success);color:var(--badge-text)}.button--ghost{background:transparent;border-color:var(--separator);color:var(--text-secondary)}.button--ghost:hover:not(:disabled){background:var(--hover-overlay);color:var(--text-primary);opacity:1}.button--danger{background:transparent;border-color:color-mix(in srgb,var(--danger) 45%,transparent);color:var(--danger)}.button--danger:hover:not(:disabled){background:color-mix(in srgb,var(--danger) 10%,transparent);border-color:color-mix(in srgb,var(--danger) 75%,transparent);opacity:1}.colorpicker-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--z-overlay-backdrop)}.colorpicker-panel{position:fixed;z-index:var(--z-overlay);background:var(--bg-window);border:1px solid var(--separator);border-radius:var(--radius-md);padding:12px;box-shadow:var(--shadow-float);display:flex;flex-wrap:wrap;width:232px;gap:8px;top:50%;left:50%;transform:translate(-50%,-50%)}.colorpicker-panel[style]{transform:none}.colorpicker-sv{width:180px;height:150px;border-radius:var(--radius-sm);position:relative;cursor:crosshair;overflow:hidden;-webkit-user-select:none;user-select:none}.colorpicker-sv-white{position:absolute;top:0;right:0;bottom:0;left:0;background:linear-gradient(to right,#fff,transparent)}.colorpicker-sv-black{position:absolute;top:0;right:0;bottom:0;left:0;background:linear-gradient(to top,#000,transparent)}.colorpicker-sv-cursor{position:absolute;width:10px;height:10px;border:2px solid #fff;border-radius:var(--radius-full);box-shadow:var(--shadow-tiny);transform:translate(-50%,-50%);pointer-events:none}.colorpicker-hue{width:180px;height:14px;border-radius:var(--radius-md);position:relative;cursor:pointer;-webkit-user-select:none;user-select:none;background:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.colorpicker-hue-cursor{position:absolute;top:-2px;width:4px;height:18px;background:#fff;border-radius:var(--radius-xs);box-shadow:var(--shadow-tiny);transform:translate(-50%);pointer-events:none}.colorpicker-footer{display:flex;align-items:center;gap:6px;width:100%}.colorpicker-preview{width:28px;height:28px;border-radius:var(--radius-sm);border:1px solid var(--separator);flex-shrink:0}.colorpicker-hex{flex:1;min-width:0;height:calc(26px * var(--ui-scale));padding:2px 6px;border:1px solid var(--separator);border-radius:var(--radius-sm);background:var(--bg-input);color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size-sm);outline:none;box-sizing:border-box}.colorpicker-hex:focus{border-color:var(--accent)}.colorpicker-ok{height:calc(26px * var(--ui-scale));padding:0 12px;background:var(--accent);color:var(--text-on-accent);border:none;border-radius:var(--radius-sm);font-size:var(--font-size-sm);cursor:pointer;flex-shrink:0}.colorpicker-ok:hover{background:var(--accent-hover)}.colorpicker-presets{width:100%;display:flex;gap:6px;flex-wrap:wrap;padding-top:4px;border-top:1px solid var(--separator)}.colorpicker-preset{width:18px;height:18px;border-radius:var(--radius-full);border:1px solid var(--separator);cursor:pointer;transition:transform .1s}.colorpicker-preset:hover{transform:scale(1.2);border-color:var(--accent)}.combobox{position:relative;display:inline-block;min-width:100px}.combobox-field{display:flex;align-items:center;gap:4px;padding:3px 6px;background:var(--bg-input);color:var(--text-primary);border:1px solid var(--border);border-radius:var(--radius-xs);font-size:var(--font-size-md);line-height:1.6;cursor:text}.combobox-field:hover:not(.selectbox-disabled){border-color:var(--accent)}.combobox.selectbox-open .combobox-field{border-color:var(--accent)}.combobox-input{flex:1;min-width:0;padding:0;background:transparent;border:none;outline:none;color:inherit;font:inherit;line-height:1.6}.combobox-input::placeholder{color:var(--text-muted)}.combobox-input:disabled{opacity:.5}.selectbox{position:relative;display:inline-block;min-width:100px;-webkit-user-select:none;user-select:none}.selectbox-trigger{display:flex;align-items:center;justify-content:space-between;gap:4px;width:100%;padding:3px 6px;background:var(--bg-input);color:var(--text-primary);border:1px solid var(--border);border-radius:var(--radius-xs);font-size:var(--font-size-md);line-height:1.6;cursor:pointer;font-family:inherit;text-align:left}.selectbox-trigger:hover:not(:disabled){border-color:var(--accent)}.selectbox-trigger:disabled{opacity:.5;cursor:default}.selectbox-open .selectbox-trigger{border-color:var(--accent)}.selectbox-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.selectbox-swatch{display:inline-block;width:10px;height:10px;margin-right:5px;border-radius:50%;border:1px solid color-mix(in srgb,var(--text-primary) 35%,transparent);vertical-align:middle;flex-shrink:0}.selectbox-arrow{flex-shrink:0;font-size:var(--font-size-sm);transition:transform .15s ease}.selectbox-arrow-up{transform:rotate(180deg)}.selectbox-dropdown{position:absolute;top:100%;left:0;margin-top:2px;background:var(--bg-window);border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:var(--shadow-pop);overflow:hidden;z-index:var(--z-dropdown);max-height:260px;max-width:calc(100vw - 24px);display:flex;flex-direction:column;animation:selectbox-in .1s ease-out}@keyframes selectbox-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.selectbox-search{padding:4px;border-bottom:1px solid var(--separator)}.selectbox-search-input{width:100%;padding:2px 6px;background:var(--bg-input);color:var(--text-primary);border:1px solid var(--border);border-radius:var(--radius-xs);font-size:var(--font-size-sm);font-family:inherit;outline:none;box-sizing:border-box}.selectbox-search-input:focus{border-color:var(--accent)}.selectbox-list{list-style:none;margin:0;padding:2px 0;overflow-y:auto;outline:none}.selectbox-item{padding:3px 8px;font-size:var(--font-size-md);line-height:1.6;color:var(--text-primary);cursor:pointer}.selectbox-item-focus{background:var(--accent);color:var(--text-on-accent)}.selectbox-item-selected:not(.selectbox-item-focus){background:var(--bg-selection)}.selectbox-empty{padding:6px 8px;font-size:var(--font-size-sm);color:var(--text-muted);text-align:center}.selectbox-disabled{pointer-events:none}.ctx-menu{position:fixed;min-width:140px;max-width:280px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-hairline),var(--context-menu-shadow);padding:4px 0;overflow:hidden;outline:none;opacity:0;transform:scale(.96);transform-origin:top left;transition:opacity .15s ease-out,transform .15s ease-out}.ctx-menu:focus-visible{outline:none}.ctx-menu.show{opacity:1;transform:scale(1)}.ctx-item{display:flex;align-items:center;gap:8px;padding:6px 12px;font-size:var(--font-size-md);font-weight:400;line-height:1.6;color:var(--text-primary);cursor:pointer;transition:background 60ms;-webkit-user-select:none;user-select:none}.ctx-item:hover,.ctx-item.focused{background:var(--tab-hover-bg);color:var(--text-primary);box-shadow:inset 2px 0 0 var(--accent)}.ctx-item-icon{flex-shrink:0;width:calc(16px * var(--ui-scale));height:calc(16px * var(--ui-scale));font-size:var(--font-size-lg);display:flex;align-items:center;justify-content:center;opacity:.75}.ctx-item:hover .ctx-item-icon,.ctx-item.focused .ctx-item-icon{opacity:1;color:var(--accent)}.ctx-item-shortcut{flex-shrink:0;margin-left:12px;font-size:var(--font-size-xs);opacity:.6;font-family:var(--font-mono);letter-spacing:.2px}.ctx-item:hover .ctx-item-shortcut,.ctx-item.focused .ctx-item-shortcut{opacity:.9;color:var(--text-secondary)}.ctx-item-check{flex-shrink:0;width:16px;font-size:var(--font-size-sm);color:var(--accent);display:flex;align-items:center}.ctx-item-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ctx-divider{height:1px;background:var(--separator);margin:4px 12px}.ctx-item-danger{color:var(--danger)}.ctx-item-danger .ctx-item-icon{opacity:1}.ctx-item-danger:hover,.ctx-item-danger.focused{background:var(--tab-hover-bg);color:var(--danger);box-shadow:inset 2px 0 0 var(--danger)}.ctx-item-danger:hover .ctx-item-shortcut,.ctx-item-danger.focused .ctx-item-shortcut{opacity:.9;color:var(--text-secondary)}.form-row{display:flex;align-items:center;gap:8px;margin-bottom:6px;font-size:var(--font-size-sm);color:var(--text-primary)}.form-row>label,.form-row>.form-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-row>.toggle,.form-row>.input,.form-row>select,.form-row>.form-control{flex-shrink:0}.number-input{display:inline-flex;align-items:center;gap:0}.number-input-btn{display:flex;align-items:center;justify-content:center;width:calc(22px * var(--ui-scale));height:calc(24px * var(--ui-scale));padding:0;border:1px solid var(--border);background:var(--bg-input);color:var(--text-primary);font-size:var(--font-size-lg);line-height:1;cursor:pointer;transition:background .15s,border-color .15s;-webkit-user-select:none;user-select:none}.number-input-btn:first-child{border-radius:var(--radius-sm) 0 0 var(--radius-sm);border-right:none}.number-input-btn:last-child{border-radius:0 var(--radius-sm) var(--radius-sm) 0;border-left:none}.number-input-btn:hover:not(:disabled){background:var(--tab-hover-bg)}.number-input-btn:active:not(:disabled){background:var(--accent);color:var(--text-on-accent)}.number-input-btn:disabled{opacity:.3;cursor:default}.number-input-field{border-radius:0;text-align:center;width:44px}.number-input-unit{margin:0 6px 0 8px;color:var(--text-muted);font-size:var(--font-size-sm);line-height:1;-webkit-user-select:none;user-select:none}.segmented-radio{display:flex;gap:4px}.segmented-radio__option{display:flex;flex-direction:column;align-items:center;gap:4px;padding:4px 8px;background:transparent;border:1px solid var(--separator);border-radius:var(--radius-sm);cursor:pointer;transition:border-color .12s ease,background .12s ease}.segmented-radio__option:hover{border-color:var(--text-muted);background:var(--hover-overlay)}.segmented-radio__option:focus-visible{outline:1px solid var(--accent);outline-offset:1px}.segmented-radio__option.is-selected{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 12%,transparent)}.segmented-radio__label{font-size:var(--font-size-sm);color:var(--text-secondary);white-space:nowrap}.segmented-radio__option.is-selected .segmented-radio__label{color:var(--text-primary)}.slider{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:130px;height:4px;margin:0;border-radius:var(--radius-sm);background:linear-gradient(to right,var(--accent) var(--slider-pct, 0%),var(--border) var(--slider-pct, 0%));cursor:pointer;outline-offset:4px}.slider:disabled{opacity:.4;cursor:default}.slider::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:12px;height:12px;border-radius:50%;background:var(--text-primary);box-shadow:var(--shadow-tiny);cursor:grab}.slider::-webkit-slider-thumb:active{cursor:grabbing}.sle{display:flex;flex-direction:column;gap:4px;width:100%}.sle-row{display:flex;align-items:center;gap:6px;min-height:calc(24px * var(--ui-scale, 1));width:100%;box-sizing:border-box}.sle-glyph{font-size:var(--font-size-sm);color:var(--text-muted);flex-shrink:0}.sle-url{flex:1;min-width:0;font-family:var(--font-mono);font-size:var(--font-size-xs);color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.sle-badge{flex-shrink:0;font-size:var(--font-size-2xs);color:var(--text-muted);background:var(--bg-window);padding:1px 4px;border-radius:3px;white-space:nowrap}.sle-lock{font-size:var(--font-size-sm);color:var(--text-muted);flex-shrink:0}.sle-del{display:flex;align-items:center;justify-content:center;width:calc(24px * var(--ui-scale, 1));height:calc(24px * var(--ui-scale, 1));padding:0;background:transparent;border:none;border-radius:3px;color:var(--text-muted);cursor:pointer;font-size:var(--font-size-sm);flex-shrink:0;transition:color .15s ease,background .15s ease}.sle-del:hover{color:var(--error);background:var(--hover-overlay)}.sle-add-row{display:flex;align-items:center;gap:6px;width:100%}.sle-input{flex:1;min-width:0;box-sizing:border-box;background:var(--bg-input);border:1px solid var(--border);border-radius:var(--radius-sm);padding:4px 8px;color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size-xs);transition:border-color .15s;outline:none}.sle-input:focus{border-color:var(--accent)}.sle-add-btn{flex-shrink:0;padding:3px 8px;border:1px solid var(--separator);border-radius:4px;background:transparent;color:var(--text-primary);cursor:pointer;font-size:var(--font-size-xs);font-family:inherit;white-space:nowrap}.sle-add-btn:hover:not(:disabled){background:var(--tab-hover-bg)}.sle-add-btn:disabled{opacity:.5;cursor:not-allowed}.sle-msg{display:block;font-size:var(--font-size-2xs);line-height:1.5;padding:0 2px}.sle-msg--error{color:var(--error)}.sle-msg--hint{color:var(--text-muted)}.theme-picker{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;width:100%}.theme-card{border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;cursor:pointer;background:var(--bg-card);padding:0;text-align:left;color:inherit;font:inherit;transition:border-color .15s ease,transform .15s ease}.theme-card:hover{border-color:var(--separator);transform:translateY(-1px)}.theme-card:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.theme-card.active{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.theme-preview{height:44px;display:flex;align-items:center;gap:3px;padding:8px;overflow:hidden}.theme-preview .pv-bar{width:26px;height:12px;border-radius:var(--radius-xs)}.theme-preview .pv-dots{display:flex;gap:3px}.theme-preview .pv-dot{width:12px;height:12px;border-radius:50%;border:1px solid color-mix(in srgb,var(--text-primary) 35%,transparent)}.theme-card .tname{padding:6px 8px;font-size:var(--font-size-xs);color:var(--text-secondary);display:flex;align-items:center;justify-content:space-between;gap:4px;overflow:hidden}.theme-card.active .tname{color:var(--text-primary)}.theme-card .tname-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.theme-card .badge{font-size:var(--font-size-2xs);color:var(--accent);white-space:nowrap}.theme-picker-empty{color:var(--text-muted);font-size:var(--font-size-sm);padding:8px 0}.toggle{width:36px;height:20px;border-radius:var(--radius-pill);background:var(--border);transition:background .15s;cursor:pointer;position:relative;flex-shrink:0}.toggle.on{background:var(--accent)}.toggle:after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:var(--radius-pill);background:var(--toggle-knob);transition:transform .15s}.toggle.on:after{transform:translate(16px);background:var(--toggle-knob-on, var(--text-on-accent))}.toggle.disabled{opacity:.4;cursor:not-allowed}.inline-input{border:1px solid var(--border);background:var(--bg-input);color:var(--text-primary);font-family:inherit;outline:none;box-sizing:border-box;width:100%;transition:border-color .15s ease-out,box-shadow .15s ease-out}.inline-input:focus{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.inline-input--compact{height:calc(22px * var(--ui-scale));font-size:var(--font-size-sm);padding:0 4px}.inline-input--normal{height:calc(32px * var(--ui-scale));font-size:var(--font-size-md);padding:0 8px}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** @linkdesk/ui 公共类型入口(E6#54b 构建生成——勿手改;改导出面改 packages/linkdesk-ui/src/index.ts 后重跑 build) */
|
|
2
|
+
export { default as Badge } from "./badge/Badge";
|
|
2
3
|
export { default as Button } from "./button/Button";
|
|
3
4
|
export { default as ColorPicker } from "./color-picker/ColorPicker";
|
|
4
5
|
export { default as Combobox } from "./combobox/Combobox";
|
|
@@ -11,11 +12,17 @@ export { default as NumberInput } from "./number-input/NumberInput";
|
|
|
11
12
|
export { default as SegmentedRadio } from "./segmented-radio/SegmentedRadio";
|
|
12
13
|
export { default as SelectBox } from "./select-box/SelectBox";
|
|
13
14
|
export { default as Slider } from "./slider/Slider";
|
|
15
|
+
export { default as StringListEditor } from "./string-list-editor/StringListEditor";
|
|
14
16
|
export { default as ThemePicker } from "./theme-picker/ThemePicker";
|
|
15
17
|
export { default as Toggle } from "./toggle/Toggle";
|
|
16
18
|
export { InlineInput } from "./inline-input/InlineInput";
|
|
17
19
|
export { PluginIcon } from "./plugin-icon/PluginIcon";
|
|
20
|
+
export { default as OverlayPortal } from "./overlay-portal/OverlayPortal";
|
|
21
|
+
export { useClickPreview } from "./hooks/useClickPreview";
|
|
22
|
+
export { useClipboardKeys } from "./hooks/useClipboardKeys";
|
|
23
|
+
export { useDebouncedInput } from "./hooks/useDebouncedInput";
|
|
18
24
|
export { inferSliderStep } from "./slider/sliderStep";
|
|
25
|
+
export { urlSourceKey } from "./string-list-editor/urlSourceKey";
|
|
19
26
|
export type { InlineInputHandle } from "./inline-input/InlineInput";
|
|
20
27
|
export type { ContextMenuProps } from "./context-menu/ContextMenu";
|
|
21
28
|
export type { ManifestIconShape, ResolvedIcon } from "./plugin-icon/iconUtils";
|