rowvia 0.3.3 → 0.3.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.
Files changed (45) hide show
  1. package/dist/fields.css +1 -1
  2. package/dist/fields.es.js +1167 -1104
  3. package/dist/fields.umd.cjs +1 -1
  4. package/dist/rowvia.css +1 -1
  5. package/dist/rowvia.es.js +5834 -4698
  6. package/dist/rowvia.umd.cjs +71 -55
  7. package/dist/types/components/scrollbars.d.ts +11 -3
  8. package/dist/types/components/table-cell-content.d.ts +9 -0
  9. package/dist/types/components/table-groups.d.ts +32 -0
  10. package/dist/types/components/table-headers.d.ts +11 -0
  11. package/dist/types/components/table-inline-editor.d.ts +13 -0
  12. package/dist/types/components/table-popup.d.ts +3 -0
  13. package/dist/types/components/table-presentation.d.ts +14 -0
  14. package/dist/types/components/table-text-editor.d.ts +29 -0
  15. package/dist/types/conditions/index.d.ts +12 -0
  16. package/dist/types/contracts/work-item.d.ts +1 -1
  17. package/dist/types/fields/internal/anchored-popup.d.ts +23 -0
  18. package/dist/types/fields/popup.d.ts +7 -9
  19. package/dist/types/fields/types.d.ts +3 -0
  20. package/dist/types/index.d.ts +1 -0
  21. package/dist/types/vue/DualPanePicker.d.ts +211 -0
  22. package/dist/types/vue/controls.d.ts +3961 -0
  23. package/dist/types/vue/index.d.ts +6 -0
  24. package/dist/types/vue/registry.d.ts +10 -0
  25. package/dist/types/vue-conditions/ConditionGroup.d.ts +120 -0
  26. package/dist/types/vue-conditions/ConditionRow.d.ts +94 -0
  27. package/dist/types/vue-conditions/ConditionValue.d.ts +56 -0
  28. package/dist/types/vue-conditions/controls.d.ts +12 -0
  29. package/dist/types/vue-conditions/index.d.ts +6 -0
  30. package/dist/types/work-items/index.d.ts +13 -1
  31. package/dist/types/work-items/tool-field-picker.d.ts +14 -0
  32. package/dist/types/work-items/tool-filter.d.ts +14 -0
  33. package/dist/types/work-items/tool-icons.d.ts +1 -0
  34. package/dist/types/work-items/tool-panel.d.ts +17 -0
  35. package/dist/types/work-items/tool-state.d.ts +21 -0
  36. package/dist/types/work-items/toolbar.d.ts +10 -2
  37. package/dist/types/work-items/views/rule-panels.d.ts +2 -0
  38. package/dist/types/work-items/workflow-detail-types.d.ts +20 -0
  39. package/dist/types/work-items/workflow-field-popups.d.ts +4 -0
  40. package/dist/types/work-items/workflow-legend.d.ts +16 -0
  41. package/dist/types/work-items/workflow-presentation.d.ts +3 -0
  42. package/dist/vue.css +1 -0
  43. package/dist/vue.es.js +631 -0
  44. package/dist/vue.umd.cjs +1 -0
  45. package/package.json +27 -7
@@ -1,10 +1,18 @@
1
1
  export interface ScrollbarOptions {
2
2
  viewport: HTMLElement;
3
3
  wrapper: HTMLElement;
4
- onHorizontalScroll: (left: number) => void;
4
+ onHorizontalScroll(left: number): void;
5
+ content?: Element | null;
6
+ labels?: {
7
+ horizontal?: string;
8
+ vertical?: string;
9
+ };
5
10
  }
6
- /** External scrollbars mirror a viewport without owning its data or rendering. */
7
- export declare function createScrollbars(options: ScrollbarOptions): {
11
+ /** Overlay controls share the grid's scroll position without changing its layout. */
12
+ export declare function createScrollbars({ viewport, wrapper, onHorizontalScroll, content, labels }: ScrollbarOptions): {
8
13
  sync: () => void;
9
14
  destroy(): void;
10
15
  };
16
+ /** Alias for hosts mounting the table presentation helpers together. */
17
+ export declare const mountTableScrollbars: typeof createScrollbars;
18
+ export type TableScrollbarOptions = ScrollbarOptions;
@@ -0,0 +1,9 @@
1
+ export interface CellContentOptions {
2
+ textSelector?: string;
3
+ cellSelector?: string;
4
+ richTextSelector?: string;
5
+ }
6
+ /** Presentation only: retain full display text while the grid renders one line. */
7
+ export declare function mountCellContent(grid: HTMLElement, options?: CellContentOptions): {
8
+ destroy(): void;
9
+ };
@@ -0,0 +1,32 @@
1
+ import type { FieldConfig } from '../fields/types';
2
+ import type { GridApi, RowNode } from '../types';
3
+ export declare const TABLE_GROUP_HEIGHT = 50;
4
+ export declare const TABLE_GROUP_INDENT = 16;
5
+ export declare function groupLeadingGap(node: RowNode): number;
6
+ export declare function groupTrailingSpace(node: RowNode): number;
7
+ export declare function tableGroupRowHeight(node: RowNode, rowHeight: number): number;
8
+ export declare function groupBoxHeight(node: RowNode, rowHeight: number): number;
9
+ export declare function groupRowNumber(node: RowNode): number;
10
+ export declare function groupCaption(node: RowNode, field?: FieldConfig, emptyLabel?: string): {
11
+ label: string;
12
+ color: string | undefined;
13
+ };
14
+ export interface TableGroupOptions {
15
+ wrapper?: HTMLElement;
16
+ grid?: HTMLElement;
17
+ emptyLabel?: string;
18
+ countLabel?: (count: number) => string;
19
+ toggleLabel?: (expanded: boolean, label: string) => string;
20
+ caption?: (node: RowNode) => {
21
+ label: string;
22
+ color?: string;
23
+ };
24
+ /** Hosts can retain expansion across remounts by supplying this map. */
25
+ expansion?: Map<string, boolean>;
26
+ }
27
+ /** The grid owns grouping, selection and virtualization. This presentation layer
28
+ * spans its pinned/scrollable sections without introducing a duplicate group column. */
29
+ export declare function mountTableGroups(root: HTMLElement, api: GridApi, field: (level: number) => FieldConfig | undefined, rowHeight: () => number, onToggle: () => void, options?: TableGroupOptions): {
30
+ restoreExpansion(): void;
31
+ destroy(): void;
32
+ };
@@ -0,0 +1,11 @@
1
+ import type { ColumnApi } from '../types';
2
+ export interface TableHeaderOptions {
3
+ wrapper?: HTMLElement;
4
+ viewport?: HTMLElement | null;
5
+ canGesture?: (key: string) => boolean;
6
+ menuAnchor?: (cell: HTMLElement) => HTMLElement;
7
+ }
8
+ /** ColumnApi owns state; this layer owns pointer feedback and edge autoscrolling. */
9
+ export declare function mountTableHeaders(root: HTMLElement, columns: ColumnApi, changed: () => void, closePopup: () => void, menu: (anchor: HTMLElement, key: string) => void, styled?: boolean, options?: TableHeaderOptions): {
10
+ destroy(): void;
11
+ };
@@ -0,0 +1,13 @@
1
+ import type { ControlEditor } from '../fields/types';
2
+ export interface InlineCellEditorOptions {
3
+ /** 选项/日期这类控件选中即生效,选了就存,不必等失焦。 */
4
+ commitOnChange?: boolean;
5
+ saveErrorMessage?: string;
6
+ /** Additional host-owned popup boundaries. */
7
+ isInside?: (node: Node) => boolean;
8
+ }
9
+ /** Host a field control in a cell; persistence remains an asynchronous host callback. */
10
+ export declare function mountInlineCellEditor(cell: HTMLElement, editor: ControlEditor, save: (value: unknown) => Promise<boolean>, onClose?: () => void, onInput?: () => void, options?: InlineCellEditorOptions): {
11
+ cancel: () => void;
12
+ commit: (close?: boolean) => Promise<void>;
13
+ };
@@ -0,0 +1,3 @@
1
+ /** Shared with standalone field popups; fields keep their own dependency boundary. */
2
+ export { anchorPopup, fixedOrigin } from '../fields/internal/anchored-popup';
3
+ export type { AnchoredPopupOptions, PopupPlacement } from '../fields/internal/anchored-popup';
@@ -0,0 +1,14 @@
1
+ export { anchorPopup, fixedOrigin } from './table-popup';
2
+ export type { AnchoredPopupOptions, PopupPlacement } from './table-popup';
3
+ export { createScrollbars, mountTableScrollbars } from './scrollbars';
4
+ export type { ScrollbarOptions, TableScrollbarOptions } from './scrollbars';
5
+ export { mountTableHeaders } from './table-headers';
6
+ export type { TableHeaderOptions } from './table-headers';
7
+ export { TABLE_GROUP_HEIGHT, TABLE_GROUP_INDENT, groupLeadingGap, groupTrailingSpace, tableGroupRowHeight, groupBoxHeight, groupRowNumber, groupCaption, mountTableGroups, } from './table-groups';
8
+ export type { TableGroupOptions } from './table-groups';
9
+ export { mountInlineCellEditor } from './table-inline-editor';
10
+ export type { InlineCellEditorOptions } from './table-inline-editor';
11
+ export { mountMultiTextCellEditor } from './table-text-editor';
12
+ export type { MultiTextField, MultiTextCellEditorOptions, MultiTextEditorMessages } from './table-text-editor';
13
+ export { mountCellContent } from './table-cell-content';
14
+ export type { CellContentOptions } from './table-cell-content';
@@ -0,0 +1,29 @@
1
+ export interface MultiTextField {
2
+ label: string;
3
+ placeholder?: string;
4
+ maxLength?: number;
5
+ required?: boolean;
6
+ }
7
+ export interface MultiTextCellEditorOptions {
8
+ messages?: Partial<MultiTextEditorMessages>;
9
+ field: MultiTextField;
10
+ value: unknown;
11
+ save: (value: string) => Promise<boolean>;
12
+ onClose?: () => void;
13
+ onInput?: () => void;
14
+ }
15
+ export interface MultiTextEditorMessages {
16
+ undo: string;
17
+ redo: string;
18
+ expand: string;
19
+ collapse: string;
20
+ done: string;
21
+ placeholder: string;
22
+ required: string;
23
+ saveError: string;
24
+ }
25
+ /** Feishu's multi-line cell editor: a floating card over the cell, not an in-cell input. */
26
+ export declare function mountMultiTextCellEditor(cell: HTMLElement, options: MultiTextCellEditorOptions): {
27
+ cancel: () => void;
28
+ commit: () => Promise<void>;
29
+ };
@@ -0,0 +1,12 @@
1
+ /** Editing metadata only. Hosts retain their own AST, conversion and evaluation. */
2
+ export interface ConditionChoice {
3
+ value: string | number | boolean;
4
+ label: string;
5
+ disabled?: boolean;
6
+ }
7
+ export interface ConditionOperatorChoice extends ConditionChoice {
8
+ noValue?: boolean;
9
+ }
10
+ export type ConditionValueKind = 'text' | 'number' | 'boolean' | 'options' | 'number-range' | 'date' | 'date-range';
11
+ /** Preserve incomplete drafts and the untouched endpoint without normalising the host's value. */
12
+ export declare function updateConditionRange(value: unknown, index: 0 | 1, next: unknown): unknown[];
@@ -130,7 +130,7 @@ export interface WorkItem {
130
130
  export type Field = string;
131
131
  export interface Rule {
132
132
  field: Field;
133
- operator: "contains" | "equals" | "notEqual" | "blank" | "notBlank";
133
+ operator: "contains" | "notContains" | "equals" | "notEqual" | "blank" | "notBlank" | "gt" | "gte" | "lt" | "lte";
134
134
  value: string;
135
135
  }
136
136
  export interface ColorRule extends Rule {
@@ -0,0 +1,23 @@
1
+ export type PopupPlacement = 'cell' | 'below' | 'choice' | 'column' | 'overlay';
2
+ export interface AnchoredPopupOptions {
3
+ /** Size a nested shell when the positioned element is a portal layer. */
4
+ sizeElement?: HTMLElement;
5
+ width?: 'anchor' | 'auto' | number | (() => number);
6
+ widthOffset?: number;
7
+ gap?: number;
8
+ align?: 'start' | 'end';
9
+ optionSelector?: string;
10
+ optionTextSelector?: string;
11
+ /** Fullscreen editors suspend anchoring until they return to a card. */
12
+ paused?: () => boolean;
13
+ }
14
+ /** Viewport origin of the nearest fixed-position containing block. */
15
+ export declare function fixedOrigin(element: Element): {
16
+ x: number;
17
+ y: number;
18
+ };
19
+ /** Anchor fixed layers through translated/scaled containing blocks, flip and clamp. */
20
+ export declare function anchorPopup(panel: HTMLElement, anchor: HTMLElement, placement: PopupPlacement, onDetached: () => void, options?: AnchoredPopupOptions): {
21
+ update: () => void;
22
+ destroy: () => void;
23
+ };
@@ -1,12 +1,3 @@
1
- /**
2
- * Top-layer popup host for field controls.
3
- *
4
- * Feishu Project renders option lists, calendars and cascade columns in a
5
- * body-level layer that floats above the page: it never joins the document
6
- * flow, never changes the geometry of the field that opened it and always
7
- * paints above the drawer/table below it. Rowvia reproduces that contract
8
- * here so every control shares one anchor/flip/clamp implementation.
9
- */
10
1
  export interface FieldPopupOptions {
11
2
  /** Element the popup is anchored to; normally the field trigger box. */
12
3
  anchor: HTMLElement;
@@ -31,6 +22,13 @@ export interface FieldPopup {
31
22
  reposition: () => void;
32
23
  close: () => void;
33
24
  }
25
+ export interface FieldPopupPresentation {
26
+ className?: string;
27
+ width?: FieldPopupOptions['width'];
28
+ align?: FieldPopupOptions['align'];
29
+ }
30
+ /** A scoped presentation hook runs during popup creation, before positioning. */
31
+ export declare function registerFieldPopupPresentation(owner: HTMLElement, presentation: (anchor: HTMLElement) => FieldPopupPresentation | undefined): () => void;
34
32
  /** True when the node belongs to any open field popup (option list, calendar, ...). */
35
33
  export declare function isInsideFieldPopup(node: Node | null, owner?: HTMLElement): boolean;
36
34
  /** Close every open field popup; hosts call this when a whole surface unmounts. */
@@ -62,6 +62,9 @@ export interface FieldConfig {
62
62
  showTime?: boolean;
63
63
  showRange?: boolean;
64
64
  showSeconds?: boolean;
65
+ months?: 1 | 2;
66
+ rangeLabels?: [string, string];
67
+ collapseOnSelect?: boolean;
65
68
  };
66
69
  colors?: Record<string, string>;
67
70
  defaultValue?: unknown;
@@ -24,6 +24,7 @@ export type * from './work-items/workflow-detail-types';
24
24
  export { createControlRegistry, BaseFieldControl, sanitizeRichText } from './work-items/fields/registry';
25
25
  export { createWorkItemFormSurface, evalFormCondition, evalFormScope } from './forms/form-surface';
26
26
  export type { ComponentInteraction, InteractionOptions, InteractionSource } from './shared/interaction';
27
+ export * from './components/table-presentation';
27
28
  export { createTagCell, createMediaCell } from './components/cells';
28
29
  export type { TagCellOptions, MediaCellOptions } from './components/cells';
29
30
  export { BaseField, renderContent, createFieldRegistry, CustomField, TextField, NumberField, RichTextField, TextareaField, ChoiceField, MultiChoiceField, PersonField, MultiPersonField, RelationField, MultiRelationField, RadioField, CascadeField, MultiCascadeField, DateTimeField, DateField, DateRangeField, SwitchField, AttachmentField, LocationField, VoteField, SingleVoteField, MultiVoteField, ComputedField, SignalField, CompositeField, LinkField, EmailField, PhoneField, ActionField } from './fields/index';
@@ -0,0 +1,211 @@
1
+ import { type PropType } from 'vue';
2
+ /** Candidate data stays host-owned; keys absent from items remain selected. */
3
+ export interface DualPanePickerItem {
4
+ key: string;
5
+ label: string;
6
+ sublabel?: string;
7
+ avatarText?: string;
8
+ avatarColor?: string;
9
+ /** Disables selection in the candidate pane. */
10
+ disabled?: boolean;
11
+ }
12
+ export declare const DualPanePicker: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
13
+ modelValue: {
14
+ type: PropType<string[]>;
15
+ required: true;
16
+ };
17
+ items: {
18
+ type: PropType<DualPanePickerItem[]>;
19
+ required: true;
20
+ };
21
+ disabled: BooleanConstructor;
22
+ disabledKeys: {
23
+ type: PropType<string[]>;
24
+ default: () => never[];
25
+ };
26
+ checkedKeys: {
27
+ type: PropType<string[]>;
28
+ default: () => never[];
29
+ };
30
+ excludedKeys: {
31
+ type: PropType<string[]>;
32
+ default: () => never[];
33
+ };
34
+ searchable: {
35
+ type: BooleanConstructor;
36
+ default: boolean;
37
+ };
38
+ searchPlaceholder: {
39
+ type: StringConstructor;
40
+ default: string;
41
+ };
42
+ searchAriaLabel: {
43
+ type: StringConstructor;
44
+ default: string;
45
+ };
46
+ groupLabel: {
47
+ type: StringConstructor;
48
+ default: string;
49
+ };
50
+ selectAll: {
51
+ type: BooleanConstructor;
52
+ default: boolean;
53
+ };
54
+ clearable: {
55
+ type: BooleanConstructor;
56
+ default: boolean;
57
+ };
58
+ totalText: {
59
+ type: StringConstructor;
60
+ default: string;
61
+ };
62
+ selectedText: {
63
+ type: StringConstructor;
64
+ default: string;
65
+ };
66
+ selectAllText: {
67
+ type: StringConstructor;
68
+ default: string;
69
+ };
70
+ unselectAllText: {
71
+ type: StringConstructor;
72
+ default: string;
73
+ };
74
+ clearText: {
75
+ type: StringConstructor;
76
+ default: string;
77
+ };
78
+ removeText: {
79
+ type: StringConstructor;
80
+ default: string;
81
+ };
82
+ disabledHint: {
83
+ type: StringConstructor;
84
+ default: string;
85
+ };
86
+ emptyText: {
87
+ type: StringConstructor;
88
+ default: string;
89
+ };
90
+ selectedEmptyText: {
91
+ type: StringConstructor;
92
+ default: string;
93
+ };
94
+ height: {
95
+ type: StringConstructor;
96
+ default: string;
97
+ };
98
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
99
+ [key: string]: any;
100
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
101
+ 'update:modelValue': (_value: string[]) => true;
102
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
103
+ modelValue: {
104
+ type: PropType<string[]>;
105
+ required: true;
106
+ };
107
+ items: {
108
+ type: PropType<DualPanePickerItem[]>;
109
+ required: true;
110
+ };
111
+ disabled: BooleanConstructor;
112
+ disabledKeys: {
113
+ type: PropType<string[]>;
114
+ default: () => never[];
115
+ };
116
+ checkedKeys: {
117
+ type: PropType<string[]>;
118
+ default: () => never[];
119
+ };
120
+ excludedKeys: {
121
+ type: PropType<string[]>;
122
+ default: () => never[];
123
+ };
124
+ searchable: {
125
+ type: BooleanConstructor;
126
+ default: boolean;
127
+ };
128
+ searchPlaceholder: {
129
+ type: StringConstructor;
130
+ default: string;
131
+ };
132
+ searchAriaLabel: {
133
+ type: StringConstructor;
134
+ default: string;
135
+ };
136
+ groupLabel: {
137
+ type: StringConstructor;
138
+ default: string;
139
+ };
140
+ selectAll: {
141
+ type: BooleanConstructor;
142
+ default: boolean;
143
+ };
144
+ clearable: {
145
+ type: BooleanConstructor;
146
+ default: boolean;
147
+ };
148
+ totalText: {
149
+ type: StringConstructor;
150
+ default: string;
151
+ };
152
+ selectedText: {
153
+ type: StringConstructor;
154
+ default: string;
155
+ };
156
+ selectAllText: {
157
+ type: StringConstructor;
158
+ default: string;
159
+ };
160
+ unselectAllText: {
161
+ type: StringConstructor;
162
+ default: string;
163
+ };
164
+ clearText: {
165
+ type: StringConstructor;
166
+ default: string;
167
+ };
168
+ removeText: {
169
+ type: StringConstructor;
170
+ default: string;
171
+ };
172
+ disabledHint: {
173
+ type: StringConstructor;
174
+ default: string;
175
+ };
176
+ emptyText: {
177
+ type: StringConstructor;
178
+ default: string;
179
+ };
180
+ selectedEmptyText: {
181
+ type: StringConstructor;
182
+ default: string;
183
+ };
184
+ height: {
185
+ type: StringConstructor;
186
+ default: string;
187
+ };
188
+ }>> & Readonly<{
189
+ "onUpdate:modelValue"?: ((_value: string[]) => any) | undefined;
190
+ }>, {
191
+ height: string;
192
+ selectAll: boolean;
193
+ disabled: boolean;
194
+ disabledKeys: string[];
195
+ checkedKeys: string[];
196
+ excludedKeys: string[];
197
+ searchable: boolean;
198
+ searchPlaceholder: string;
199
+ searchAriaLabel: string;
200
+ groupLabel: string;
201
+ clearable: boolean;
202
+ totalText: string;
203
+ selectedText: string;
204
+ selectAllText: string;
205
+ unselectAllText: string;
206
+ clearText: string;
207
+ removeText: string;
208
+ disabledHint: string;
209
+ emptyText: string;
210
+ selectedEmptyText: string;
211
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;