@a3s-lab/office 0.36.0 → 0.37.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.
Files changed (59) hide show
  1. package/README.md +18 -6
  2. package/dist/0~3557.js +2 -1
  3. package/dist/0~3635.js +4 -1
  4. package/dist/0~7048.js +93 -1
  5. package/dist/0~9073.js +7 -2
  6. package/dist/0~presentation-editor.js +45 -9
  7. package/dist/0~spreadsheet-editor.js +20321 -16966
  8. package/dist/4121.js +1942 -1939
  9. package/dist/{3266.js → 5416.js} +1504 -20
  10. package/dist/9333.js +1 -1
  11. package/dist/core.d.ts +1 -0
  12. package/dist/core.js +141 -28
  13. package/dist/index.js +1 -1
  14. package/dist/internal/features/work/editors/office-shortcuts.d.ts +1 -0
  15. package/dist/internal/features/work/editors/spreadsheet-auto-filter-command.d.ts +3 -0
  16. package/dist/internal/features/work/editors/spreadsheet-auto-filter-condition-dialog-model.d.ts +27 -0
  17. package/dist/internal/features/work/editors/spreadsheet-auto-filter-condition-dialog.d.ts +17 -0
  18. package/dist/internal/features/work/editors/spreadsheet-auto-filter-menu.d.ts +10 -0
  19. package/dist/internal/features/work/editors/spreadsheet-auto-filter.d.ts +16 -4
  20. package/dist/internal/features/work/editors/spreadsheet-cell-range.d.ts +1 -0
  21. package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +9 -0
  22. package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +13 -1
  23. package/dist/internal/features/work/editors/spreadsheet-current-region.d.ts +12 -0
  24. package/dist/internal/features/work/editors/spreadsheet-editor.d.ts +3 -0
  25. package/dist/internal/features/work/editors/spreadsheet-sort-appearance.d.ts +45 -0
  26. package/dist/internal/features/work/editors/spreadsheet-sort-collation.d.ts +8 -0
  27. package/dist/internal/features/work/editors/spreadsheet-sort-command.d.ts +3 -0
  28. package/dist/internal/features/work/editors/spreadsheet-sort-custom-list-editor.d.ts +8 -0
  29. package/dist/internal/features/work/editors/spreadsheet-sort-custom-list-store.d.ts +13 -0
  30. package/dist/internal/features/work/editors/spreadsheet-sort-custom-list.d.ts +26 -0
  31. package/dist/internal/features/work/editors/spreadsheet-sort-dialog.d.ts +9 -0
  32. package/dist/internal/features/work/editors/spreadsheet-sort-matrix.d.ts +4 -0
  33. package/dist/internal/features/work/editors/spreadsheet-sort-options-dialog.d.ts +7 -0
  34. package/dist/internal/features/work/editors/spreadsheet-sort-order-controls.d.ts +16 -0
  35. package/dist/internal/features/work/editors/spreadsheet-sort-range-dialog.d.ts +7 -0
  36. package/dist/internal/features/work/editors/spreadsheet-sort.d.ts +138 -0
  37. package/dist/internal/features/work/editors/spreadsheet-table-totals.d.ts +39 -0
  38. package/dist/internal/features/work/editors/spreadsheet-table.d.ts +11 -1
  39. package/dist/internal/features/work/editors/use-spreadsheet-auto-filter.d.ts +12 -3
  40. package/dist/internal/features/work/editors/use-spreadsheet-sort.d.ts +26 -0
  41. package/dist/internal/features/work/editors/work-office-chrome.d.ts +3 -0
  42. package/dist/internal/features/work/work-spreadsheet-auto-filter.d.ts +14 -0
  43. package/dist/internal/features/work/work-spreadsheet-dynamic-filter.d.ts +7 -0
  44. package/dist/internal/features/work/work-spreadsheet-filter-contract.d.ts +3 -0
  45. package/dist/internal/features/work/work-spreadsheet-wildcard.d.ts +7 -0
  46. package/dist/internal/features/work/work-types.d.ts +45 -7
  47. package/dist/internal/features/work/work-xlsx-interop.d.ts +2 -1
  48. package/dist/internal/features/work/work-xlsx-table-filters.d.ts +3 -1
  49. package/dist/internal/kernel/office-kernel-spreadsheet-fallback-formula.d.ts +11 -0
  50. package/dist/office-kernel.wasm +0 -0
  51. package/dist/office-kernel.worker.js +93 -1
  52. package/dist/styles.css +789 -145
  53. package/dist/vue.d.ts +3 -1
  54. package/dist/vue.js +2 -0
  55. package/dist/web-component.d.ts +3 -1
  56. package/dist/web-component.js +9 -0
  57. package/dist/work-spreadsheet-package-scan.worker.js +2 -1
  58. package/docs/latest/en/browser-editor-architecture.md +136 -2
  59. package/package.json +24 -1
@@ -2,6 +2,7 @@ import type { WorkOfficeCollaborationSession } from '../../../collaboration/offi
2
2
  import type { WorkEditorAgentRequest } from '../work-agent-request';
3
3
  import type { WorkSpreadsheetContent } from '../work-types';
4
4
  import { type SpreadsheetEditorCommands } from './spreadsheet-command-controller';
5
+ import type { SpreadsheetSortCustomListStore } from './spreadsheet-sort-custom-list-store';
5
6
  import { type WorkOfficeFileAction } from './work-office-chrome';
6
7
  export interface SpreadsheetEditorProps {
7
8
  autoFocus?: boolean;
@@ -10,6 +11,7 @@ export interface SpreadsheetEditorProps {
10
11
  kernelWasmUrl?: string;
11
12
  preview: boolean;
12
13
  saveStatus?: string;
14
+ sortCustomListStore?: SpreadsheetSortCustomListStore;
13
15
  fileActions?: readonly WorkOfficeFileAction[];
14
16
  onChange: (content: WorkSpreadsheetContent) => void;
15
17
  onAgentRequest?: (request: WorkEditorAgentRequest) => void | Promise<void>;
@@ -19,4 +21,5 @@ export declare function focusSpreadsheetGrid(container: HTMLElement | null, { fo
19
21
  focusOrigin?: Element | null;
20
22
  forceInitial?: boolean;
21
23
  }): void;
24
+ export declare function preserveSpreadsheetGridFocus(container: HTMLElement | null, target: EventTarget | null): void;
22
25
  export declare function spreadsheetCommandsWithGridFocus(commands: SpreadsheetEditorCommands, restoreFocus: () => void): SpreadsheetEditorCommands;
@@ -0,0 +1,45 @@
1
+ import type { Cell } from '@fortune-sheet/core';
2
+ import { type SpreadsheetConditionalIconSetName } from '../work-spreadsheet-conditional-icons';
3
+ import type { WorkSpreadsheetSheet } from '../work-types';
4
+ import type { SpreadsheetCellRange } from './spreadsheet-cell-range';
5
+ export type SpreadsheetSortAppearanceKind = 'cell-color' | 'font-color' | 'icon';
6
+ export type SpreadsheetSortAppearancePosition = 'first' | 'last';
7
+ export interface SpreadsheetSortIconTarget {
8
+ iconSet: SpreadsheetConditionalIconSetName;
9
+ index: number;
10
+ }
11
+ export type SpreadsheetSortAppearanceTarget = {
12
+ color: string | null;
13
+ kind: 'cell-color';
14
+ } | {
15
+ color: string | null;
16
+ kind: 'font-color';
17
+ } | {
18
+ icon: SpreadsheetSortIconTarget;
19
+ kind: 'icon';
20
+ };
21
+ export interface SpreadsheetSortCellAppearance {
22
+ /** Undefined means the cell has a native pattern or gradient without one color. */
23
+ cellColor?: string | null;
24
+ /** Null represents the automatic/default font color. */
25
+ fontColor: string | null;
26
+ icon: SpreadsheetSortIconTarget | null;
27
+ }
28
+ export type SpreadsheetSortAppearanceRows = readonly (readonly SpreadsheetSortCellAppearance[])[];
29
+ export interface SpreadsheetSortAppearanceField {
30
+ cellColors: readonly (string | null)[];
31
+ fontColors: readonly (string | null)[];
32
+ icons: readonly SpreadsheetSortIconTarget[];
33
+ index: number;
34
+ }
35
+ export declare function createSpreadsheetSortAppearanceRows(sheet: WorkSpreadsheetSheet, range: SpreadsheetCellRange, rows: readonly (readonly (Cell | null)[])[]): SpreadsheetSortAppearanceRows;
36
+ export declare function createSpreadsheetSortDirectAppearanceRows(rows: readonly (readonly (Cell | null)[])[]): SpreadsheetSortAppearanceRows;
37
+ export declare function spreadsheetSortAppearanceFields(rows: SpreadsheetSortAppearanceRows, range: SpreadsheetCellRange, orientation: 'top-to-bottom' | 'left-to-right', hasHeader: boolean): readonly SpreadsheetSortAppearanceField[];
38
+ export declare function normalizeSpreadsheetSortColor(value: unknown): string | null | undefined;
39
+ export declare function normalizeSpreadsheetSortIcon(value: unknown): SpreadsheetSortIconTarget | null;
40
+ export declare function spreadsheetSortAppearanceTargetValue(target: SpreadsheetSortAppearanceTarget): string;
41
+ export declare function parseSpreadsheetSortAppearanceTargetValue(value: string): SpreadsheetSortAppearanceTarget | null;
42
+ export declare function spreadsheetSortAppearanceTargetLabel(target: SpreadsheetSortAppearanceTarget): string;
43
+ export declare function spreadsheetSortAppearanceTargets(field: SpreadsheetSortAppearanceField | undefined, kind: SpreadsheetSortAppearanceKind): readonly SpreadsheetSortAppearanceTarget[];
44
+ export declare function spreadsheetSortAppearanceTargetsEqual(left: SpreadsheetSortAppearanceTarget, right: SpreadsheetSortAppearanceTarget): boolean;
45
+ export declare function spreadsheetSortCellMatchesAppearance(appearance: SpreadsheetSortCellAppearance | undefined, target: SpreadsheetSortAppearanceTarget): boolean;
@@ -0,0 +1,8 @@
1
+ export type SpreadsheetSortTextMethod = 'pinyin' | 'stroke';
2
+ export interface SpreadsheetSortTextOptions {
3
+ caseSensitive: boolean;
4
+ textMethod: SpreadsheetSortTextMethod;
5
+ }
6
+ export declare const DEFAULT_SPREADSHEET_SORT_TEXT_OPTIONS: SpreadsheetSortTextOptions;
7
+ export declare function isSpreadsheetSortTextMethod(value: unknown): value is SpreadsheetSortTextMethod;
8
+ export declare function createSpreadsheetSortTextComparator(options: SpreadsheetSortTextOptions): ((left: string, right: string) => number) | null;
@@ -0,0 +1,3 @@
1
+ import { type OfficeEditorExtension } from './office-editor-extension';
2
+ import type { SpreadsheetCommandContext, SpreadsheetEditorCommands } from './spreadsheet-command-controller';
3
+ export declare function createSpreadsheetSortExtension(): OfficeEditorExtension<SpreadsheetCommandContext, SpreadsheetEditorCommands>;
@@ -0,0 +1,8 @@
1
+ export declare function SpreadsheetSortCustomListEditor({ error, level, text, onCancel, onChange, onUse, }: {
2
+ error: string | null;
3
+ level: number;
4
+ text: string;
5
+ onCancel: () => void;
6
+ onChange: (text: string) => void;
7
+ onUse: () => void;
8
+ }): import("react").JSX.Element;
@@ -0,0 +1,13 @@
1
+ export declare const DEFAULT_SPREADSHEET_SORT_CUSTOM_LIST_STORAGE_KEY = "a3s-office.spreadsheet-sort-custom-lists.v1";
2
+ export interface SpreadsheetSortCustomListStore {
3
+ load(): readonly (readonly string[])[];
4
+ save(lists: readonly (readonly string[])[]): void;
5
+ }
6
+ export declare class LocalStorageSpreadsheetSortCustomListStore implements SpreadsheetSortCustomListStore {
7
+ private readonly storage;
8
+ private readonly key;
9
+ constructor(storage: Pick<Storage, 'getItem' | 'setItem'>, key?: string);
10
+ load(): readonly (readonly string[])[];
11
+ save(lists: readonly (readonly string[])[]): void;
12
+ }
13
+ export declare function normalizeStoredSpreadsheetSortCustomLists(input: unknown): readonly (readonly string[])[];
@@ -0,0 +1,26 @@
1
+ export declare const MAX_SPREADSHEET_SORT_CUSTOM_LIST_ENTRIES = 256;
2
+ export declare const MAX_SPREADSHEET_SORT_CUSTOM_LIST_ENTRY_CODE_POINTS = 128;
3
+ export declare const MAX_SPREADSHEET_SORT_CUSTOM_LIST_CODE_POINTS = 4096;
4
+ export declare const MAX_SPREADSHEET_SORT_USER_CUSTOM_LISTS = 32;
5
+ export type SpreadsheetSortCustomListSource = 'built-in' | 'stored' | 'session';
6
+ export interface SpreadsheetSortCustomList {
7
+ entries: readonly string[];
8
+ label: string;
9
+ source: SpreadsheetSortCustomListSource;
10
+ }
11
+ export type SpreadsheetSortCustomListErrorCode = 'duplicate-entry' | 'entry-too-long' | 'invalid-entry' | 'list-too-long' | 'not-enough-entries' | 'too-many-entries';
12
+ export type SpreadsheetSortCustomListValidationResult = {
13
+ entries: string[];
14
+ ok: true;
15
+ } | {
16
+ code: SpreadsheetSortCustomListErrorCode;
17
+ message: string;
18
+ ok: false;
19
+ };
20
+ export declare function parseSpreadsheetSortCustomList(text: string): SpreadsheetSortCustomListValidationResult;
21
+ export declare function validateSpreadsheetSortCustomList(input: unknown): SpreadsheetSortCustomListValidationResult;
22
+ export declare function createSpreadsheetSortCustomList(entries: readonly string[], source?: SpreadsheetSortCustomListSource): SpreadsheetSortCustomList | null;
23
+ export declare function mergeSpreadsheetSortCustomLists(lists: readonly SpreadsheetSortCustomList[]): readonly SpreadsheetSortCustomList[];
24
+ export declare function spreadsheetSortCustomListsEqual(left: readonly string[], right: readonly string[]): boolean;
25
+ export declare function spreadsheetSortCustomListMatchKey(value: number | string): string;
26
+ export declare const SPREADSHEET_SORT_BUILT_IN_CUSTOM_LISTS: readonly [SpreadsheetSortCustomList, SpreadsheetSortCustomList, SpreadsheetSortCustomList, SpreadsheetSortCustomList, SpreadsheetSortCustomList, SpreadsheetSortCustomList, SpreadsheetSortCustomList];
@@ -0,0 +1,9 @@
1
+ import { type SpreadsheetSortDialogSource, type SpreadsheetSortDialogValue } from './spreadsheet-sort';
2
+ import { type SpreadsheetSortCustomList } from './spreadsheet-sort-custom-list';
3
+ export declare function SpreadsheetSortDialog({ source, restoreFocusTarget, onApply, onRememberCustomList, onClose, }: {
4
+ source: SpreadsheetSortDialogSource;
5
+ restoreFocusTarget: () => HTMLElement | null;
6
+ onApply: (value: SpreadsheetSortDialogValue) => boolean;
7
+ onRememberCustomList?: (list: SpreadsheetSortCustomList) => SpreadsheetSortCustomList | void;
8
+ onClose: () => void;
9
+ }): import("react").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import type { Cell } from '@fortune-sheet/core';
2
+ import { type SpreadsheetSortRequest, type SpreadsheetSortResult } from './spreadsheet-sort';
3
+ import { type SpreadsheetSortAppearanceRows } from './spreadsheet-sort-appearance';
4
+ export declare function sortSpreadsheetMatrix(source: readonly (readonly (Cell | null)[])[], request: SpreadsheetSortRequest, appearanceRows?: SpreadsheetSortAppearanceRows): SpreadsheetSortResult;
@@ -0,0 +1,7 @@
1
+ import type { SpreadsheetSortOptions } from './spreadsheet-sort';
2
+ export declare function SpreadsheetSortOptionsDialog({ value, restoreFocusTarget, onApply, onClose, }: {
3
+ value: SpreadsheetSortOptions;
4
+ restoreFocusTarget: () => HTMLElement | null;
5
+ onApply: (value: SpreadsheetSortOptions) => void;
6
+ onClose: () => void;
7
+ }): import("react").JSX.Element;
@@ -0,0 +1,16 @@
1
+ import type { SpreadsheetSortKey, SpreadsheetSortOrientation } from './spreadsheet-sort';
2
+ import { type SpreadsheetSortAppearanceField, type SpreadsheetSortAppearanceTarget } from './spreadsheet-sort-appearance';
3
+ import { type SpreadsheetSortCustomList } from './spreadsheet-sort-custom-list';
4
+ export declare function SpreadsheetSortOrderControls({ appearanceField, customLists, level, orientation, sortKey, onBeginCustomListEdit, onChange, }: {
5
+ appearanceField: SpreadsheetSortAppearanceField | undefined;
6
+ customLists: readonly SpreadsheetSortCustomList[];
7
+ level: number;
8
+ orientation: SpreadsheetSortOrientation;
9
+ sortKey: SpreadsheetSortKey;
10
+ onBeginCustomListEdit: (entries?: readonly string[]) => void;
11
+ onChange: (key: SpreadsheetSortKey) => void;
12
+ }): import("react").JSX.Element;
13
+ export declare function spreadsheetSortAppearanceKey(index: number, target: SpreadsheetSortAppearanceTarget, position: 'first' | 'last'): SpreadsheetSortKey;
14
+ export declare function nextSpreadsheetSortKey(keys: readonly SpreadsheetSortKey[], fields: readonly {
15
+ index: number;
16
+ }[], appearanceFields: readonly SpreadsheetSortAppearanceField[]): SpreadsheetSortKey | null;
@@ -0,0 +1,7 @@
1
+ import type { SpreadsheetSortRangeChoice, SpreadsheetSortRangeDialogSource } from './spreadsheet-sort';
2
+ export declare function SpreadsheetSortRangeDialog({ source, restoreFocusTarget, onApply, onClose, }: {
3
+ source: SpreadsheetSortRangeDialogSource;
4
+ restoreFocusTarget: () => HTMLElement | null;
5
+ onApply: (choice: SpreadsheetSortRangeChoice) => boolean;
6
+ onClose: () => void;
7
+ }): import("react").JSX.Element;
@@ -0,0 +1,138 @@
1
+ import type { Cell } from '@fortune-sheet/core';
2
+ import type { WorkSpreadsheetSheet } from '../work-types';
3
+ import { type SpreadsheetCellRange } from './spreadsheet-cell-range';
4
+ import { type SpreadsheetSortAppearanceKind, type SpreadsheetSortAppearancePosition, type SpreadsheetSortAppearanceRows, type SpreadsheetSortIconTarget } from './spreadsheet-sort-appearance';
5
+ import { type SpreadsheetSortTextOptions } from './spreadsheet-sort-collation';
6
+ import { type SpreadsheetSortCustomList } from './spreadsheet-sort-custom-list';
7
+ export type { SpreadsheetSortAppearanceRows, SpreadsheetSortCellAppearance, SpreadsheetSortIconTarget, } from './spreadsheet-sort-appearance';
8
+ export type { SpreadsheetSortTextMethod, SpreadsheetSortTextOptions, } from './spreadsheet-sort-collation';
9
+ export type { SpreadsheetSortCustomList } from './spreadsheet-sort-custom-list';
10
+ export declare const MAX_SPREADSHEET_SORT_KEYS = 64;
11
+ export declare const MAX_SPREADSHEET_SORT_CELLS = 1000000;
12
+ export type SpreadsheetSortDirection = 'ascending' | 'descending';
13
+ export type SpreadsheetSortOrientation = 'top-to-bottom' | 'left-to-right';
14
+ export type SpreadsheetSortKey = {
15
+ color?: never;
16
+ customList?: never;
17
+ direction: SpreadsheetSortDirection;
18
+ icon?: never;
19
+ index: number;
20
+ position?: never;
21
+ sortOn?: never;
22
+ } | {
23
+ color?: never;
24
+ customList: readonly string[];
25
+ direction?: never;
26
+ icon?: never;
27
+ index: number;
28
+ position?: never;
29
+ sortOn?: never;
30
+ } | {
31
+ color: string | null;
32
+ customList?: never;
33
+ direction?: never;
34
+ icon?: never;
35
+ index: number;
36
+ position: SpreadsheetSortAppearancePosition;
37
+ sortOn: Exclude<SpreadsheetSortAppearanceKind, 'icon'>;
38
+ } | {
39
+ color?: never;
40
+ customList?: never;
41
+ direction?: never;
42
+ icon: SpreadsheetSortIconTarget;
43
+ index: number;
44
+ position: SpreadsheetSortAppearancePosition;
45
+ sortOn: 'icon';
46
+ };
47
+ export interface SpreadsheetSortOptions extends SpreadsheetSortTextOptions {
48
+ orientation: SpreadsheetSortOrientation;
49
+ }
50
+ export interface SpreadsheetSortDialogValue extends SpreadsheetSortOptions {
51
+ hasHeader: boolean;
52
+ keys: SpreadsheetSortKey[];
53
+ }
54
+ export interface SpreadsheetSortTarget {
55
+ activeColumn: number;
56
+ activeRow: number;
57
+ range: SpreadsheetCellRange;
58
+ }
59
+ export interface SpreadsheetSortRangeCandidate {
60
+ available: boolean;
61
+ range: SpreadsheetCellRange;
62
+ }
63
+ export type SpreadsheetSortIntent = {
64
+ type: 'custom';
65
+ } | {
66
+ type: 'quick';
67
+ direction: SpreadsheetSortDirection;
68
+ };
69
+ export interface SpreadsheetSortOpenRequest {
70
+ activeColumn: number;
71
+ activeRow: number;
72
+ expanded?: SpreadsheetSortRangeCandidate;
73
+ intent: SpreadsheetSortIntent;
74
+ selected: SpreadsheetSortRangeCandidate;
75
+ sheetId: string;
76
+ }
77
+ export interface SpreadsheetSortRangePlan {
78
+ expandedRange: SpreadsheetCellRange | null;
79
+ selectedRange: SpreadsheetCellRange;
80
+ }
81
+ export type SpreadsheetSortRangeChoice = 'expand' | 'selection';
82
+ export interface SpreadsheetSortRangeDialogSource {
83
+ canSortExpandedRange: boolean;
84
+ canSortSelection: boolean;
85
+ expandedRangeReference: string;
86
+ selectedRangeReference: string;
87
+ sheetName: string;
88
+ }
89
+ export type SpreadsheetSortRequest = Omit<SpreadsheetSortDialogValue, keyof SpreadsheetSortTextOptions> & Partial<SpreadsheetSortTextOptions> & {
90
+ range: SpreadsheetCellRange;
91
+ sheetId: string;
92
+ };
93
+ export interface SpreadsheetSortNormalizedRequest extends SpreadsheetSortDialogValue {
94
+ range: SpreadsheetCellRange;
95
+ sheetId: string;
96
+ }
97
+ export interface SpreadsheetSortField {
98
+ index: number;
99
+ label: string;
100
+ }
101
+ export interface SpreadsheetSortDialogSource {
102
+ activeRow: number;
103
+ appearanceRows: SpreadsheetSortAppearanceRows;
104
+ columns: SpreadsheetSortField[];
105
+ customLists: readonly SpreadsheetSortCustomList[];
106
+ range: SpreadsheetCellRange;
107
+ rangeReference: string;
108
+ rows: SpreadsheetSortField[];
109
+ sheetId: string;
110
+ sheetName: string;
111
+ value: SpreadsheetSortDialogValue;
112
+ }
113
+ export type SpreadsheetSortErrorCode = 'column-out-of-range' | 'duplicate-key' | 'formula-reference-out-of-range' | 'invalid-appearance' | 'invalid-case-sensitivity' | 'invalid-custom-list' | 'invalid-direction' | 'invalid-header' | 'invalid-matrix' | 'invalid-orientation' | 'invalid-range' | 'invalid-text-method' | 'missing-key' | 'not-enough-columns' | 'not-enough-rows' | 'range-too-large' | 'row-out-of-range' | 'too-many-keys' | 'unsupported-text-method' | 'unsupported-linked-cell';
114
+ export type SpreadsheetSortValidationResult = {
115
+ ok: true;
116
+ request: SpreadsheetSortNormalizedRequest;
117
+ } | {
118
+ code: SpreadsheetSortErrorCode;
119
+ message: string;
120
+ ok: false;
121
+ };
122
+ export type SpreadsheetSortResult = {
123
+ ok: true;
124
+ rows: (Cell | null)[][];
125
+ } | {
126
+ code: SpreadsheetSortErrorCode;
127
+ message: string;
128
+ ok: false;
129
+ };
130
+ export declare function createSpreadsheetSortRangePlan(sheet: WorkSpreadsheetSheet, selectedRange: SpreadsheetCellRange): SpreadsheetSortRangePlan | null;
131
+ export declare function createSpreadsheetSortRangeDialogSource(sheetName: string, request: SpreadsheetSortOpenRequest): SpreadsheetSortRangeDialogSource | null;
132
+ export declare function createSpreadsheetSortDialogSource(sheetId: string, sheetName: string, target: SpreadsheetSortTarget, rows: readonly (readonly (Cell | null)[])[], customLists?: readonly SpreadsheetSortCustomList[], appearanceRows?: SpreadsheetSortAppearanceRows): SpreadsheetSortDialogSource | null;
133
+ export declare function validateSpreadsheetSortRequest(request: SpreadsheetSortRequest): SpreadsheetSortValidationResult;
134
+ export declare function spreadsheetSortFailureMessage(result: SpreadsheetSortValidationResult | SpreadsheetSortResult): string | null;
135
+ export declare function spreadsheetSortAppearanceRowsMatch(rows: readonly (readonly (Cell | null)[])[], appearances: SpreadsheetSortAppearanceRows): boolean;
136
+ export declare function spreadsheetSortError(code: SpreadsheetSortErrorCode): Extract<SpreadsheetSortValidationResult, {
137
+ ok: false;
138
+ }>;
@@ -0,0 +1,39 @@
1
+ import type { WorkSpreadsheetSheet, WorkSpreadsheetTable, WorkSpreadsheetTableColumn, WorkSpreadsheetTableTotalsFunction } from '../work-types';
2
+ export declare const MAX_SPREADSHEET_TABLE_TOTALS_FORMULA_LENGTH = 8192;
3
+ export declare const MAX_SPREADSHEET_TABLE_TOTALS_LABEL_LENGTH = 255;
4
+ export declare const DEFAULT_SPREADSHEET_TABLE_TOTALS_LABEL = "Total";
5
+ /** The closed function set exposed by the Table Design totals menu. */
6
+ export declare const SPREADSHEET_TABLE_TOTALS_FUNCTIONS: readonly ["sum", "average", "count", "countNums", "max", "min", "stdDev", "stdDevP", "var", "varP", "custom"];
7
+ export interface SpreadsheetTableTotalsColumnPatch {
8
+ totalsFormula?: string | null;
9
+ totalsFunction?: WorkSpreadsheetTableTotalsFunction | null;
10
+ totalsLabel?: string | null;
11
+ }
12
+ export declare function spreadsheetTableTotalsFunctionLabel(value: WorkSpreadsheetTableTotalsFunction | undefined): string;
13
+ export declare function normalizeSpreadsheetTableTotalsFunction(value: unknown): WorkSpreadsheetTableTotalsFunction | undefined;
14
+ /** Normalize a table totals formula to the editable leading-equals form. */
15
+ export declare function normalizeSpreadsheetTableTotalsFormula(value: unknown): string | undefined;
16
+ export declare function normalizeSpreadsheetTableTotalsLabel(value: unknown): string | undefined;
17
+ export declare function spreadsheetTableTotalsFunctionFromOoxml(value: unknown): WorkSpreadsheetTableTotalsFunction | undefined;
18
+ export declare function spreadsheetTableTotalsFunctionToOoxml(value: WorkSpreadsheetTableTotalsFunction | undefined): string | undefined;
19
+ /**
20
+ * Returns the formula that should be placed in one totals-row cell. Native
21
+ * aggregate functions use SUBTOTAL so filtered-out rows stay excluded; a
22
+ * custom rule uses its explicit formula.
23
+ */
24
+ export declare function spreadsheetTableTotalsFormula(table: WorkSpreadsheetTable, columnOffset: number): string | undefined;
25
+ export declare function spreadsheetTableTotalsColumnPatch(columns: readonly WorkSpreadsheetTableColumn[], patches: Readonly<Record<string, SpreadsheetTableTotalsColumnPatch>> | readonly (SpreadsheetTableTotalsColumnPatch | null | undefined)[] | undefined): WorkSpreadsheetTableColumn[] | null;
26
+ /** Apply the native default label used when a totals row is first enabled. */
27
+ export declare function withDefaultSpreadsheetTableTotalsLabel(columns: readonly WorkSpreadsheetTableColumn[], totalsRow: boolean): WorkSpreadsheetTableColumn[];
28
+ /** True when a proposed totals row would overwrite a populated cell. */
29
+ export declare function spreadsheetTableTotalsRowHasContent(sheet: WorkSpreadsheetSheet, table: WorkSpreadsheetTable, row?: number): boolean;
30
+ /**
31
+ * Synchronize totals-row cells after a table metadata change. Explicitly
32
+ * changed column metadata owns the target cell; untouched manual cells remain
33
+ * authoritative. The helper works with Fortune's dense and sparse forms.
34
+ */
35
+ export declare function synchronizeSpreadsheetTableTotalsRow(sheet: WorkSpreadsheetSheet, previousTable: WorkSpreadsheetTable | undefined, nextTable: WorkSpreadsheetTable, options?: {
36
+ force?: boolean;
37
+ }): WorkSpreadsheetSheet;
38
+ /** Reconcile metadata after a user edits a totals-row cell directly. */
39
+ export declare function reconcileSpreadsheetTableTotalsColumns(sheet: WorkSpreadsheetSheet, table: WorkSpreadsheetTable, editedOffsets?: ReadonlySet<number>): WorkSpreadsheetTableColumn[];
@@ -1,6 +1,7 @@
1
1
  import type { Selection } from '@fortune-sheet/core';
2
2
  import type { WorkSpreadsheetContent, WorkSpreadsheetSheet, WorkSpreadsheetTable, WorkSpreadsheetTableStyle } from '../work-types';
3
3
  import { type SpreadsheetCellRange } from './spreadsheet-cell-range';
4
+ import { type SpreadsheetTableTotalsColumnPatch } from './spreadsheet-table-totals';
4
5
  export { MAX_SPREADSHEET_TABLE_CELLS } from './spreadsheet-table-limits';
5
6
  export interface SpreadsheetTableTarget {
6
7
  sheetId: string;
@@ -9,6 +10,7 @@ export interface SpreadsheetTableTarget {
9
10
  export interface SpreadsheetTableDialogValue {
10
11
  headerRow: boolean;
11
12
  rangeReference: string;
13
+ totalsRow?: boolean;
12
14
  }
13
15
  export interface SpreadsheetTableDialogSource {
14
16
  name: string;
@@ -24,6 +26,10 @@ export interface SpreadsheetTableRequest {
24
26
  range: SpreadsheetCellRange;
25
27
  sheetId: string;
26
28
  style?: WorkSpreadsheetTableStyle;
29
+ /** Create the table with a native totals row appended to the range. */
30
+ totalsRow?: boolean;
31
+ /** Initial per-column totals metadata, keyed by zero-based table offset. */
32
+ totalsColumns?: Readonly<Record<string, SpreadsheetTableTotalsColumnPatch>> | readonly (SpreadsheetTableTotalsColumnPatch | null | undefined)[];
27
33
  }
28
34
  export type SpreadsheetTableValidation = {
29
35
  columns: string[];
@@ -36,7 +42,7 @@ export type SpreadsheetTableValidation = {
36
42
  message: string;
37
43
  ok: false;
38
44
  };
39
- export type SpreadsheetTableErrorCode = 'auto-filter-overlap' | 'invalid-column-name' | 'invalid-name' | 'invalid-range' | 'invalid-style' | 'merged-range' | 'name-conflict' | 'out-of-bounds' | 'protected-range' | 'pivot-table' | 'range-too-large' | 'sheet-not-found' | 'table-overlap';
45
+ export type SpreadsheetTableErrorCode = 'auto-filter-overlap' | 'invalid-column-name' | 'invalid-name' | 'invalid-range' | 'invalid-style' | 'invalid-totals' | 'merged-range' | 'name-conflict' | 'out-of-bounds' | 'protected-range' | 'pivot-table' | 'range-too-large' | 'sheet-not-found' | 'table-overlap' | 'totals-row-content';
40
46
  export interface SpreadsheetTableDesignPatch {
41
47
  name?: string;
42
48
  showColumnStripes?: boolean;
@@ -44,6 +50,10 @@ export interface SpreadsheetTableDesignPatch {
44
50
  showLastColumn?: boolean;
45
51
  showRowStripes?: boolean;
46
52
  style?: WorkSpreadsheetTableStyle;
53
+ /** Toggle the native totals row. Enabling appends one row to the table. */
54
+ totalsRow?: boolean;
55
+ /** Update per-column totals function, label, or custom formula. */
56
+ totalsColumns?: Readonly<Record<string, SpreadsheetTableTotalsColumnPatch>> | readonly (SpreadsheetTableTotalsColumnPatch | null | undefined)[];
47
57
  }
48
58
  export declare function createSpreadsheetTableDialogSource(content: WorkSpreadsheetContent, target: SpreadsheetTableTarget): SpreadsheetTableDialogSource | null;
49
59
  export declare function spreadsheetTableRangeFromText(value: string): SpreadsheetCellRange | null;
@@ -1,9 +1,12 @@
1
1
  import type { Selection } from '@fortune-sheet/core';
2
- import { type RefObject } from 'react';
2
+ import { type ReactNode, type RefObject } from 'react';
3
3
  import type { WorkSpreadsheetContent } from '../work-types';
4
- import type { SpreadsheetAutoFilterCommandPort, SpreadsheetWorkbookCommandPort } from './spreadsheet-command-controller';
4
+ import type { SpreadsheetAutoFilterCommandPort, SpreadsheetEditorCommands, SpreadsheetWorkbookCommandPort } from './spreadsheet-command-controller';
5
5
  export interface UseSpreadsheetAutoFilterOptions {
6
6
  canvasRef: RefObject<HTMLElement | null>;
7
+ commandsRef: {
8
+ current: SpreadsheetEditorCommands | null;
9
+ };
7
10
  content: WorkSpreadsheetContent;
8
11
  editable: boolean;
9
12
  mountRevision?: number;
@@ -15,7 +18,13 @@ export interface UseSpreadsheetAutoFilterOptions {
15
18
  export interface SpreadsheetAutoFilterController {
16
19
  active: boolean;
17
20
  commandPort: SpreadsheetAutoFilterCommandPort;
21
+ dialog: ReactNode;
18
22
  reserveAltKey: () => boolean;
23
+ selectionForChange: () => SpreadsheetAutoFilterSelectionState | null;
19
24
  status: string;
20
25
  }
21
- export declare function useSpreadsheetAutoFilter({ canvasRef, content, editable, mountRevision, onChange, selection, sheetId, workbook, }: UseSpreadsheetAutoFilterOptions): SpreadsheetAutoFilterController;
26
+ export interface SpreadsheetAutoFilterSelectionState {
27
+ selections: Selection[];
28
+ sheetId: string;
29
+ }
30
+ export declare function useSpreadsheetAutoFilter({ canvasRef, commandsRef, content, editable, mountRevision, onChange, selection, sheetId, workbook, }: UseSpreadsheetAutoFilterOptions): SpreadsheetAutoFilterController;
@@ -0,0 +1,26 @@
1
+ import type { Cell } from '@fortune-sheet/core';
2
+ import type { WorkSpreadsheetContent } from '../work-types';
3
+ import type { SpreadsheetEditorCommands, SpreadsheetSortCommandPort } from './spreadsheet-command-controller';
4
+ import { type SpreadsheetSortRangeCandidate } from './spreadsheet-sort';
5
+ import { type SpreadsheetSortCustomListStore } from './spreadsheet-sort-custom-list-store';
6
+ interface SpreadsheetSortReadRequest {
7
+ range: SpreadsheetSortRangeCandidate['range'];
8
+ sheetId: string;
9
+ }
10
+ export declare function useSpreadsheetSort({ commandsRef, contentRef, focusGrid, getGridFocusTarget, getRows, preview, customListStore, }: {
11
+ commandsRef: {
12
+ current: SpreadsheetEditorCommands | null;
13
+ };
14
+ contentRef: {
15
+ current: WorkSpreadsheetContent;
16
+ };
17
+ focusGrid: (focusOrigin: Element | null) => void;
18
+ getGridFocusTarget: () => HTMLElement | null;
19
+ getRows: (request: SpreadsheetSortReadRequest) => (Cell | null)[][] | null;
20
+ preview: boolean;
21
+ customListStore?: SpreadsheetSortCustomListStore;
22
+ }): {
23
+ commandPort: SpreadsheetSortCommandPort;
24
+ dialog: import("react").JSX.Element | null;
25
+ };
26
+ export {};
@@ -8,9 +8,12 @@ export interface WorkOfficeRibbonTab<T extends string> {
8
8
  export interface WorkOfficeFileAction {
9
9
  id: string;
10
10
  label: string;
11
+ /** Uses a neutral file glyph when omitted so the menu never reserves a blank icon cell. */
11
12
  icon?: ReactNode;
12
13
  shortcut?: string;
13
14
  disabled?: boolean;
15
+ /** Visually distinguishes an irreversible action without changing its behavior. */
16
+ danger?: boolean;
14
17
  separatorBefore?: boolean;
15
18
  onSelect: () => void | Promise<void>;
16
19
  }
@@ -0,0 +1,14 @@
1
+ import type { WorkSpreadsheetFilter, WorkSpreadsheetFilterCriteria, WorkSpreadsheetSheet } from './work-types';
2
+ import { type WorkSpreadsheetDynamicFilterContext } from './work-spreadsheet-dynamic-filter';
3
+ export interface WorkSpreadsheetAutoFilterRange {
4
+ column: [number, number];
5
+ row: [number, number];
6
+ }
7
+ export declare function normalizedWorkSpreadsheetAutoFilterRange(selection: WorkSpreadsheetSheet['filter_select']): WorkSpreadsheetAutoFilterRange | null;
8
+ export declare function workSpreadsheetAutoFilterCriteria(sheet: WorkSpreadsheetSheet | undefined, column: number): WorkSpreadsheetFilterCriteria | null;
9
+ export declare function workSpreadsheetAutoFilterCriteriaEntries(sheet: WorkSpreadsheetSheet): WorkSpreadsheetFilter[];
10
+ export declare function workSpreadsheetSheetWithAutoFilterCriteria(sheet: WorkSpreadsheetSheet, column: number, criteria: WorkSpreadsheetFilterCriteria, context?: WorkSpreadsheetDynamicFilterContext): WorkSpreadsheetSheet | null;
11
+ export declare function workSpreadsheetSheetWithoutAutoFilterCriteria(sheet: WorkSpreadsheetSheet, column: number): WorkSpreadsheetSheet | null;
12
+ export declare function workSpreadsheetAutoFilterManuallyHiddenRows(sheet: WorkSpreadsheetSheet): Set<string>;
13
+ export declare function workSpreadsheetSheetWithImportedAutoFilterCriteria(sheet: WorkSpreadsheetSheet, entries: readonly WorkSpreadsheetFilter[], context?: WorkSpreadsheetDynamicFilterContext): WorkSpreadsheetSheet;
14
+ export declare function normalizeWorkSpreadsheetFilterCriteria(criteria: unknown): WorkSpreadsheetFilterCriteria | null;
@@ -0,0 +1,7 @@
1
+ import type { Cell } from '@fortune-sheet/core';
2
+ import type { WorkSpreadsheetDynamicFilter } from './work-types';
3
+ export interface WorkSpreadsheetDynamicFilterContext {
4
+ now: Date;
5
+ }
6
+ export declare function workSpreadsheetDynamicFilterMatcher(kind: WorkSpreadsheetDynamicFilter, cells: Iterable<Cell | null>, context: WorkSpreadsheetDynamicFilterContext): ((cell: Cell | null) => boolean) | null;
7
+ export declare function workSpreadsheetCellIsDate(cell: Cell | null): boolean;
@@ -0,0 +1,3 @@
1
+ export declare const WORK_SPREADSHEET_FILTER_TEXT_MAX_CHARACTERS = 32767;
2
+ export declare function workSpreadsheetFilterTextCharacters(value: string): number;
3
+ export declare function workSpreadsheetFilterTextIsBounded(value: string): boolean;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Compiles the WPS/OOXML wildcard language into a controlled token matcher. `*`
3
+ * matches zero or more characters, `?` matches one normalized Unicode
4
+ * character, and `~` escapes `*`, `?`, or another `~`.
5
+ */
6
+ export declare function workSpreadsheetWildcardMatcher(source: string): (value: string) => boolean;
7
+ export declare function workSpreadsheetHasUnescapedWildcard(source: string): boolean;
@@ -241,13 +241,23 @@ export interface WorkSpreadsheetTableColumn {
241
241
  * stores the editable form with a leading `=`; XLSX table parts omit it.
242
242
  */
243
243
  calculatedFormula?: string;
244
+ /**
245
+ * Native totals-row aggregation. An omitted value means that the totals
246
+ * cell is not owned by the table. The controlled model uses camelCase names
247
+ * while XLSX table parts use their OOXML spellings.
248
+ */
249
+ totalsFunction?: WorkSpreadsheetTableTotalsFunction;
250
+ /** Optional text label rendered in this column's totals-row cell. */
251
+ totalsLabel?: string;
252
+ /**
253
+ * A bounded custom totals-row formula. The controlled model stores the
254
+ * editable form with a leading `=`; XLSX table parts omit it.
255
+ */
256
+ totalsFormula?: string;
244
257
  }
258
+ export type WorkSpreadsheetTableTotalsFunction = 'sum' | 'average' | 'count' | 'countNums' | 'max' | 'min' | 'stdDev' | 'stdDevP' | 'var' | 'varP' | 'custom';
245
259
  export type WorkSpreadsheetDynamicFilter = 'above-average' | 'below-average' | 'tomorrow' | 'today' | 'yesterday' | 'next-week' | 'this-week' | 'last-week' | 'next-month' | 'this-month' | 'last-month' | 'next-quarter' | 'this-quarter' | 'last-quarter' | 'next-year' | 'this-year' | 'last-year' | 'year-to-date' | 'quarter-1' | 'quarter-2' | 'quarter-3' | 'quarter-4' | 'month-1' | 'month-2' | 'month-3' | 'month-4' | 'month-5' | 'month-6' | 'month-7' | 'month-8' | 'month-9' | 'month-10' | 'month-11' | 'month-12';
246
- export type WorkSpreadsheetTableFilterCriteria = {
247
- type: 'values';
248
- values: string[];
249
- includeBlanks: boolean;
250
- } | {
260
+ export type WorkSpreadsheetCustomFilterCondition = {
251
261
  type: 'equals';
252
262
  value: string;
253
263
  } | {
@@ -262,9 +272,21 @@ export type WorkSpreadsheetTableFilterCriteria = {
262
272
  } | {
263
273
  type: 'begins-with';
264
274
  value: string;
275
+ } | {
276
+ type: 'does-not-begin-with';
277
+ value: string;
265
278
  } | {
266
279
  type: 'ends-with';
267
280
  value: string;
281
+ } | {
282
+ type: 'does-not-end-with';
283
+ value: string;
284
+ } | {
285
+ type: 'matches-wildcard';
286
+ value: string;
287
+ } | {
288
+ type: 'does-not-match-wildcard';
289
+ value: string;
268
290
  } | {
269
291
  type: 'greater-than';
270
292
  value: string;
@@ -277,6 +299,11 @@ export type WorkSpreadsheetTableFilterCriteria = {
277
299
  } | {
278
300
  type: 'less-than-or-equal';
279
301
  value: string;
302
+ };
303
+ export type WorkSpreadsheetFilterCriteria = WorkSpreadsheetCustomFilterCondition | {
304
+ type: 'values';
305
+ values: string[];
306
+ includeBlanks: boolean;
280
307
  } | {
281
308
  type: 'between';
282
309
  lower: string;
@@ -285,6 +312,13 @@ export type WorkSpreadsheetTableFilterCriteria = {
285
312
  type: 'not-between';
286
313
  lower: string;
287
314
  upper: string;
315
+ } | {
316
+ type: 'compound';
317
+ conjunction: 'and' | 'or';
318
+ conditions: [
319
+ WorkSpreadsheetCustomFilterCondition,
320
+ WorkSpreadsheetCustomFilterCondition
321
+ ];
288
322
  } | {
289
323
  type: 'blanks';
290
324
  } | {
@@ -305,10 +339,14 @@ export type WorkSpreadsheetTableFilterCriteria = {
305
339
  type: 'dynamic';
306
340
  kind: WorkSpreadsheetDynamicFilter;
307
341
  };
308
- export interface WorkSpreadsheetTableFilter {
342
+ /** @deprecated Use `WorkSpreadsheetFilterCriteria` for new integrations. */
343
+ export type WorkSpreadsheetTableFilterCriteria = WorkSpreadsheetFilterCriteria;
344
+ export interface WorkSpreadsheetFilter {
309
345
  column: number;
310
- criteria: WorkSpreadsheetTableFilterCriteria;
346
+ criteria: WorkSpreadsheetFilterCriteria;
311
347
  }
348
+ /** @deprecated Use `WorkSpreadsheetFilter` for new integrations. */
349
+ export type WorkSpreadsheetTableFilter = WorkSpreadsheetFilter;
312
350
  export interface WorkSpreadsheetTable {
313
351
  /** Stable browser-model identity. OOXML numeric identity is kept separately. */
314
352
  id: string;
@@ -10,13 +10,14 @@ import { type XlsxPageSetup } from './work-xlsx-page-setup';
10
10
  import { type XlsxProtectionFeatures } from './work-xlsx-protection';
11
11
  import { type XlsxWorksheetXmlScan } from './work-xlsx-worksheet-scan';
12
12
  import { type XlsxRichTextCell } from './work-xlsx-rich-text';
13
- import type { WorkSpreadsheetTable } from './work-types';
13
+ import type { WorkSpreadsheetFilter, WorkSpreadsheetTable } from './work-types';
14
14
  type FrozenPane = NonNullable<Sheet['frozen']>;
15
15
  export interface XlsxDataValidation {
16
16
  references: string[];
17
17
  item: FortuneDataValidationItem;
18
18
  }
19
19
  export interface XlsxSheetFeatures {
20
+ autoFilterCriteria: WorkSpreadsheetFilter[];
20
21
  directCellStyles: XlsxDirectCellStyle[];
21
22
  frozen?: FrozenPane;
22
23
  validations: XlsxDataValidation[];