rj-grid 0.2.1 → 0.2.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/rj-grid.js +619 -336
- package/dist/style.css +126 -0
- package/dist/types/src/RjOptionSelect.vue.d.ts +49 -0
- package/dist/types/src/optionsSource.d.ts +24 -1
- package/dist/types/src/types.d.ts +4 -1
- package/package.json +1 -1
package/dist/style.css
CHANGED
|
@@ -261,6 +261,111 @@
|
|
|
261
261
|
padding: 2px;
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
.rj-query-select.rj-opt-select {
|
|
265
|
+
position: relative;
|
|
266
|
+
display: inline-flex;
|
|
267
|
+
min-width: 120px;
|
|
268
|
+
font-size: var(--rj-ui-font, 12px);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.rj-opt-trigger {
|
|
272
|
+
display: inline-flex;
|
|
273
|
+
flex: 1;
|
|
274
|
+
gap: 4px;
|
|
275
|
+
align-items: center;
|
|
276
|
+
justify-content: space-between;
|
|
277
|
+
width: 100%;
|
|
278
|
+
height: calc(var(--rj-ui-h, 26px) - 2px);
|
|
279
|
+
padding: 0 6px;
|
|
280
|
+
font-size: var(--rj-ui-font, 12px);
|
|
281
|
+
color: var(--rj-text);
|
|
282
|
+
cursor: pointer;
|
|
283
|
+
background: var(--rj-bg);
|
|
284
|
+
border: 1px solid var(--rj-border-strong);
|
|
285
|
+
border-radius: var(--rj-radius);
|
|
286
|
+
outline: none;
|
|
287
|
+
}
|
|
288
|
+
.rj-opt-trigger:focus, .rj-opt-trigger:hover {
|
|
289
|
+
border-color: var(--rj-primary);
|
|
290
|
+
}
|
|
291
|
+
.rj-opt-trigger.is-placeholder .rj-opt-text {
|
|
292
|
+
color: var(--rj-text-secondary);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.rj-opt-text {
|
|
296
|
+
overflow: hidden;
|
|
297
|
+
text-overflow: ellipsis;
|
|
298
|
+
white-space: nowrap;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.rj-opt-arrow {
|
|
302
|
+
flex: none;
|
|
303
|
+
color: var(--rj-text-secondary);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.rj-opt-panel {
|
|
307
|
+
position: absolute;
|
|
308
|
+
top: 100%;
|
|
309
|
+
left: 0;
|
|
310
|
+
z-index: 60;
|
|
311
|
+
display: flex;
|
|
312
|
+
flex-direction: column;
|
|
313
|
+
min-width: 100%;
|
|
314
|
+
max-width: 320px;
|
|
315
|
+
margin-top: 2px;
|
|
316
|
+
background: var(--rj-bg);
|
|
317
|
+
border: 1px solid var(--rj-border);
|
|
318
|
+
border-radius: var(--rj-radius);
|
|
319
|
+
box-shadow: var(--rj-shadow);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.rj-opt-search {
|
|
323
|
+
width: calc(100% - 8px);
|
|
324
|
+
height: calc(var(--rj-ui-h, 26px) - 2px);
|
|
325
|
+
padding: 0 6px;
|
|
326
|
+
margin: 4px;
|
|
327
|
+
font-size: var(--rj-ui-font, 12px);
|
|
328
|
+
color: var(--rj-text);
|
|
329
|
+
background: var(--rj-bg);
|
|
330
|
+
border: 1px solid var(--rj-border-strong);
|
|
331
|
+
border-radius: var(--rj-radius);
|
|
332
|
+
outline: none;
|
|
333
|
+
}
|
|
334
|
+
.rj-opt-search:focus {
|
|
335
|
+
border-color: var(--rj-primary);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.rj-opt-list {
|
|
339
|
+
max-height: 220px;
|
|
340
|
+
overflow: auto;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.rj-opt-row {
|
|
344
|
+
display: flex;
|
|
345
|
+
gap: 4px;
|
|
346
|
+
align-items: center;
|
|
347
|
+
padding: 4px 8px;
|
|
348
|
+
line-height: 1.5;
|
|
349
|
+
cursor: pointer;
|
|
350
|
+
}
|
|
351
|
+
.rj-opt-row:hover, .rj-opt-row.is-active {
|
|
352
|
+
color: var(--rj-primary);
|
|
353
|
+
background: var(--rj-primary-bg);
|
|
354
|
+
}
|
|
355
|
+
.rj-opt-row.is-selected .rj-option-label {
|
|
356
|
+
font-weight: 600;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.rj-opt-check {
|
|
360
|
+
flex: none;
|
|
361
|
+
margin: 0;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.rj-opt-empty {
|
|
365
|
+
padding: 6px 8px;
|
|
366
|
+
color: #999;
|
|
367
|
+
}
|
|
368
|
+
|
|
264
369
|
.rj-query-add {
|
|
265
370
|
border-style: dashed;
|
|
266
371
|
}
|
|
@@ -1139,6 +1244,27 @@
|
|
|
1139
1244
|
color: var(--rj-primary);
|
|
1140
1245
|
}
|
|
1141
1246
|
|
|
1247
|
+
.rj-option-tree .rj-option-row {
|
|
1248
|
+
display: flex;
|
|
1249
|
+
gap: 4px;
|
|
1250
|
+
align-items: center;
|
|
1251
|
+
}
|
|
1252
|
+
.rj-option-tree .rj-option-caret {
|
|
1253
|
+
flex: none;
|
|
1254
|
+
width: 14px;
|
|
1255
|
+
color: var(--rj-text-secondary);
|
|
1256
|
+
cursor: pointer;
|
|
1257
|
+
user-select: none;
|
|
1258
|
+
}
|
|
1259
|
+
.rj-option-tree .rj-option-caret.is-leaf {
|
|
1260
|
+
cursor: default;
|
|
1261
|
+
}
|
|
1262
|
+
.rj-option-tree .rj-option-label {
|
|
1263
|
+
overflow: hidden;
|
|
1264
|
+
text-overflow: ellipsis;
|
|
1265
|
+
white-space: nowrap;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1142
1268
|
.rj-editor-error {
|
|
1143
1269
|
position: absolute;
|
|
1144
1270
|
top: 100%;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { RjEditorOption } from './types';
|
|
2
|
+
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
|
|
3
|
+
options?: RjEditorOption[] | undefined;
|
|
4
|
+
modelValue?: any;
|
|
5
|
+
multiple?: boolean | undefined;
|
|
6
|
+
placeholder?: string | undefined;
|
|
7
|
+
}>, {
|
|
8
|
+
options: () => never[];
|
|
9
|
+
modelValue: undefined;
|
|
10
|
+
multiple: boolean;
|
|
11
|
+
placeholder: string;
|
|
12
|
+
}>>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
13
|
+
"update:modelValue": (v: any) => void;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
|
|
15
|
+
options?: RjEditorOption[] | undefined;
|
|
16
|
+
modelValue?: any;
|
|
17
|
+
multiple?: boolean | undefined;
|
|
18
|
+
placeholder?: string | undefined;
|
|
19
|
+
}>, {
|
|
20
|
+
options: () => never[];
|
|
21
|
+
modelValue: undefined;
|
|
22
|
+
multiple: boolean;
|
|
23
|
+
placeholder: string;
|
|
24
|
+
}>>> & Readonly<{
|
|
25
|
+
"onUpdate:modelValue"?: ((v: any) => any) | undefined;
|
|
26
|
+
}>, {
|
|
27
|
+
options: RjEditorOption[];
|
|
28
|
+
placeholder: string;
|
|
29
|
+
modelValue: any;
|
|
30
|
+
multiple: boolean;
|
|
31
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
32
|
+
export default _default;
|
|
33
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
34
|
+
type __VLS_TypePropsToRuntimeProps<T> = {
|
|
35
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
36
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
37
|
+
} : {
|
|
38
|
+
type: import('vue').PropType<T[K]>;
|
|
39
|
+
required: true;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
type __VLS_WithDefaults<P, D> = {
|
|
43
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
|
|
44
|
+
default: D[K];
|
|
45
|
+
}> : P[K];
|
|
46
|
+
};
|
|
47
|
+
type __VLS_Prettify<T> = {
|
|
48
|
+
[K in keyof T]: T[K];
|
|
49
|
+
} & {};
|
|
@@ -22,9 +22,32 @@ export declare const defaultOptionsAccessor: RjOptionsAccessor;
|
|
|
22
22
|
* 把任意接口返回归一成 RjEditorOption[]:
|
|
23
23
|
* - map 命中优先(完全自定义);
|
|
24
24
|
* - 否则按 labelKey/valueKey(或默认字段)取;
|
|
25
|
-
* - childrenKey(默认 'children'
|
|
25
|
+
* - childrenKey(默认 'children')命中数组即保留为 children,递归归一(不再拍平),供下拉按层级渲染。
|
|
26
26
|
*/
|
|
27
27
|
export declare function normalizeOptions(raw: unknown, shape?: RjOptionShape): RjEditorOption[];
|
|
28
|
+
/** 深度优先拍平选项树(丢弃 children 引用),供 value→label 映射 / 枚举候选等需要扁平列表的消费点 */
|
|
29
|
+
export declare function flattenOptions(options: RjEditorOption[]): RjEditorOption[];
|
|
30
|
+
/**
|
|
31
|
+
* 按搜索词剪枝选项树(大小写不敏 contains):
|
|
32
|
+
* - 节点自身命中 → 保留该节点及其完整子树(可继续下钻);
|
|
33
|
+
* - 自身未命中但有后代命中 → 作为祖先路径保留(children 为剪枝后的子集);
|
|
34
|
+
* - 空查询原样返回。返回全新节点对象,不污染缓存。
|
|
35
|
+
*/
|
|
36
|
+
export declare function filterOptionTree(options: RjEditorOption[], query: string): RjEditorOption[];
|
|
37
|
+
/** 树渲染行:option + 层级深度 + 是否可展开 + 当前是否已展开 */
|
|
38
|
+
export interface RjOptionRow {
|
|
39
|
+
option: RjEditorOption;
|
|
40
|
+
depth: number;
|
|
41
|
+
hasChildren: boolean;
|
|
42
|
+
expanded: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 按展开集合把(已剪枝的)选项树铺成可渲染的可见行(深度优先)。
|
|
46
|
+
* expanded 以 String(value) 为键;未展开节点的子树不进入可见行。
|
|
47
|
+
*/
|
|
48
|
+
export declare function flattenTreeForRender(options: RjEditorOption[], expanded: Set<string>): RjOptionRow[];
|
|
49
|
+
/** 收集树中所有“有子节点”的 value(String 化),用于默认展开全部 */
|
|
50
|
+
export declare function collectParentKeys(options: RjEditorOption[], acc?: Set<string>): Set<string>;
|
|
28
51
|
/** 解析选项源所需的网格级加载器 */
|
|
29
52
|
export interface RjOptionLoaders {
|
|
30
53
|
dictLoader?: (key: string) => unknown | Promise<unknown>;
|
|
@@ -108,11 +108,14 @@ export type RjEditorType = 'input' | 'number' | 'date' | 'select' | 'richSelect'
|
|
|
108
108
|
export interface RjEditorOption {
|
|
109
109
|
label: string;
|
|
110
110
|
value: any;
|
|
111
|
+
/** 树形子节点:载体源含 childrenKey 时保留层级(下拉按树渲染,显示/标签映射自动拍平) */
|
|
112
|
+
children?: RjEditorOption[];
|
|
111
113
|
}
|
|
112
114
|
/**
|
|
113
115
|
* 统一选项载体:一份数据源同时驱动 显示(value→label) / select 筛选候选 / select 编辑器 / NLQ 枚举。
|
|
114
116
|
* 数组=静态候选;函数=工厂(可同步/异步,网格级按列只解析一次);对象=按 load/ref/dict 取数,
|
|
115
|
-
* 再用 map 或 labelKey/valueKey 归一,childrenKey(默认 'children'
|
|
117
|
+
* 再用 map 或 labelKey/valueKey 归一,childrenKey(默认 'children')命中数组即保留为 children 树,
|
|
118
|
+
* 供下拉按层级渲染(显示标签映射会自动深度优先拍平,父/子节点均可命中 value→label)。
|
|
116
119
|
*/
|
|
117
120
|
export type RjOptionSource = RjEditorOption[] | ((row?: RjRowData) => RjEditorOption[] | Promise<RjEditorOption[]>) | {
|
|
118
121
|
/** 静态候选(对象式) */
|