@a3s-lab/office 0.37.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.
- package/README.md +6 -1
- package/dist/0~3557.js +2 -1
- package/dist/0~3635.js +4 -1
- package/dist/0~9073.js +7 -2
- package/dist/0~presentation-editor.js +45 -9
- package/dist/0~spreadsheet-editor.js +13345 -10343
- package/dist/{3266.js → 5416.js} +1139 -15
- package/dist/9333.js +1 -1
- package/dist/core.d.ts +1 -0
- package/dist/core.js +112 -26
- package/dist/index.js +1 -1
- package/dist/internal/features/work/editors/office-shortcuts.d.ts +1 -0
- package/dist/internal/features/work/editors/spreadsheet-auto-filter-command.d.ts +3 -0
- package/dist/internal/features/work/editors/spreadsheet-auto-filter-condition-dialog-model.d.ts +27 -0
- package/dist/internal/features/work/editors/spreadsheet-auto-filter-condition-dialog.d.ts +17 -0
- package/dist/internal/features/work/editors/spreadsheet-auto-filter-menu.d.ts +10 -0
- package/dist/internal/features/work/editors/spreadsheet-auto-filter.d.ts +16 -4
- package/dist/internal/features/work/editors/spreadsheet-cell-range.d.ts +1 -0
- package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +9 -0
- package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +13 -1
- package/dist/internal/features/work/editors/spreadsheet-current-region.d.ts +12 -0
- package/dist/internal/features/work/editors/spreadsheet-editor.d.ts +3 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-appearance.d.ts +45 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-collation.d.ts +8 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-command.d.ts +3 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-custom-list-editor.d.ts +8 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-custom-list-store.d.ts +13 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-custom-list.d.ts +26 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-dialog.d.ts +9 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-matrix.d.ts +4 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-options-dialog.d.ts +7 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-order-controls.d.ts +16 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-range-dialog.d.ts +7 -0
- package/dist/internal/features/work/editors/spreadsheet-sort.d.ts +138 -0
- package/dist/internal/features/work/editors/use-spreadsheet-auto-filter.d.ts +12 -3
- package/dist/internal/features/work/editors/use-spreadsheet-sort.d.ts +26 -0
- package/dist/internal/features/work/editors/work-office-chrome.d.ts +3 -0
- package/dist/internal/features/work/work-spreadsheet-auto-filter.d.ts +14 -0
- package/dist/internal/features/work/work-spreadsheet-dynamic-filter.d.ts +7 -0
- package/dist/internal/features/work/work-spreadsheet-filter-contract.d.ts +3 -0
- package/dist/internal/features/work/work-spreadsheet-wildcard.d.ts +7 -0
- package/dist/internal/features/work/work-types.d.ts +31 -7
- package/dist/internal/features/work/work-xlsx-interop.d.ts +2 -1
- package/dist/internal/features/work/work-xlsx-table-filters.d.ts +3 -1
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +544 -20
- package/dist/vue.d.ts +3 -1
- package/dist/vue.js +2 -0
- package/dist/web-component.d.ts +3 -1
- package/dist/web-component.js +9 -0
- package/dist/work-spreadsheet-package-scan.worker.js +2 -1
- package/docs/latest/en/browser-editor-architecture.md +128 -0
- package/package.json +21 -1
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ workflows, and a separate Rust automation plane.
|
|
|
56
56
|
|
|
57
57
|
## Latest on `main`
|
|
58
58
|
|
|
59
|
-
The `0.37.
|
|
59
|
+
The `0.37.1` release exposes these capabilities as normal user-facing
|
|
60
60
|
Playground templates, with matching implementation detail in the documentation:
|
|
61
61
|
|
|
62
62
|
| Editor | Latest capability | Public entry |
|
|
@@ -152,6 +152,7 @@ baseline rather than one specific release.
|
|
|
152
152
|
| Formatting and style rendering | **Partial** — native fonts, colors, borders, alignment, number formats, cell styles, all 17 native non-solid OOXML pattern fills, native linear/path XLSX gradients, and one Format Cells surface that authors none, solid, pattern, or gradient fills with exact geometry and 2–256 ordered stops; static date/time entry, contrast-safe font preview, native XLSX rich-text runs, selected-text font formatting, direct formula-bar/F2 insertion or deletion, and bounded authenticated formatted-HTML paste | Disjoint multi-edit rich-text authoring, broader themes, locale formats, and advanced style effects |
|
|
153
153
|
| Ribbon and shortcuts | **Partial** — common Office-style Home/Data/View commands, grid-scoped shortcuts, and focused Font-dialog aliases | Larger command catalog and platform-specific accelerators |
|
|
154
154
|
| Formulas and recalculation | **Partial** — dependency-aware calculation plus bounded structured references (`Table[Column]`, contiguous ranges, `#All`/`#Headers`/`#Data`/`#Totals`/`#This Row`, and `[@Column]`) in the shared Rust/WASM and JavaScript paths | Wider functions, arrays, volatile semantics, and calculation parity |
|
|
155
|
+
| Sort and filter | **Partial** — Traditional Office-style current-region expansion warnings for partial selections; Traditional Office-compatible top-to-bottom or left-to-right Custom Sort with stable value, custom-list, effective cell-color, effective font-color, and conditional-format icon keys; offline Simplified Chinese pinyin/stroke comparison, optional lowercase-before-uppercase case sensitivity, and lexical numeric text; seven built-in month/weekday sequences; bounded typed host-stored or mounted-session sequences; header retention for top-to-bottom sorting; top/bottom or left/right appearance placement; up to 64 ordered keys; blanks-last value behavior; axis-aware relative-formula translation; and one-step Undo; plus worksheet AutoFilter authoring, keyboard menus, common text/value/numeric/blank conditions, exactly two same-column conditions joined by AND or OR, native OOXML `*`/`?`/`~` wildcard expressions, negative prefix/suffix operators, tie-aware Top/Bottom item and percentage filters, locally evaluated above/below-average and complete native relative-date, month, and quarter dynamic families on typed 1900-system date cells, multi-column row ownership, manual-hide preservation, and native XLSX criteria round trips with imported dynamic-filter recomputation | Custom-list deletion/reordering UI, broader locale collation, source-level 1904 date-system retention for dynamic dates, large aggregate/rank Worker/WASM offload, and table/AutoFilter-integrated custom sorting |
|
|
155
156
|
| Tables, pivots, charts, and rules | **Partial** — native tables, bounded structured-reference formulas, calculated-column formulas with automatic fill for newly inserted body rows, complete common totals-row authoring, pivots, charts, conditional formatting, and common validation rules with complete input/error-setting authoring | Slicers, pivot charts, custom/dependent validation rules, advanced analysis, and broader browser alert flows |
|
|
156
157
|
| Large worksheets | **Supported with boundaries** — maximum-dimension sparse import/editing and viewport-bounded Canvas painting | Highly optimized native grid with hardware-dependent limits |
|
|
157
158
|
| Files and printing | **Partial** — XLS/XLSX/ODS/CSV import, XLSX export, and PDF output | Broader round trips, external data, print fidelity, and legacy conversion |
|
|
@@ -216,6 +217,9 @@ is requested. The complete gap inventory and exit evidence live in the
|
|
|
216
217
|
preserving spatial arrow-key navigation.
|
|
217
218
|
Shared Office selects use 44 px phone option rows and bounded internal
|
|
218
219
|
scrolling while retaining keyboard selection and exact focus restoration.
|
|
220
|
+
Host-provided file menus keep every action visually identifiable with an
|
|
221
|
+
explicit or neutral fallback icon, readable long labels, grouped destructive
|
|
222
|
+
actions, and a visible keyboard focus ring.
|
|
219
223
|
- **Editor-scoped zoom** — Status controls and Ctrl/Cmd + mouse-wheel gestures
|
|
220
224
|
share each surface's bounded zoom model without changing the host browser's
|
|
221
225
|
page scale.
|
|
@@ -1647,6 +1651,7 @@ keep working without hard-coded return URLs.
|
|
|
1647
1651
|
|
|
1648
1652
|
- [Live Playground](https://a3s-lab.github.io/Office/playground/)
|
|
1649
1653
|
- [Documentation center](https://a3s-lab.github.io/Office/docs/)
|
|
1654
|
+
- [A3S Office 0.37.1 documentation](https://a3s-lab.github.io/Office/docs/0.37.1/)
|
|
1650
1655
|
- [A3S Office 0.37.0 documentation](https://a3s-lab.github.io/Office/docs/0.37.0/)
|
|
1651
1656
|
- [A3S Office 0.36.0 documentation](https://a3s-lab.github.io/Office/docs/0.36.0/)
|
|
1652
1657
|
- [A3S Office 0.34.0 documentation](https://a3s-lab.github.io/Office/docs/0.34.0/)
|
package/dist/0~3557.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useEffect, useLayoutEffect, useMemo, useRef } from "react";
|
|
2
|
+
import { isOfficeCompositionKeyboardEvent } from "./0~3635.js";
|
|
2
3
|
import { matchesOfficeEditorKeyboardShortcut } from "./0~8136.js";
|
|
3
4
|
const DEFAULT_EXTENSION_PRIORITY = 100;
|
|
4
5
|
function createOfficeEditorExtension(config) {
|
|
@@ -97,7 +98,7 @@ function createOfficeEditorRuntime(initialContext, extensions, options = {}) {
|
|
|
97
98
|
storage: Object.freeze(storage),
|
|
98
99
|
can: ()=>canApi,
|
|
99
100
|
handleKeyDown: (event)=>{
|
|
100
|
-
if (event.defaultPrevented) return false;
|
|
101
|
+
if (event.defaultPrevented || isOfficeCompositionKeyboardEvent(event)) return false;
|
|
101
102
|
for (const instance of instances)for (const shortcut of instance.keyboardShortcuts)if (matchesOfficeEditorKeyboardShortcut(event, shortcut.shortcut) && shortcut.handler(readContext(), commandApi, canApi, event)) {
|
|
102
103
|
event.preventDefault();
|
|
103
104
|
return true;
|
package/dist/0~3635.js
CHANGED
|
@@ -314,10 +314,13 @@ function swatchForeground(color) {
|
|
|
314
314
|
}
|
|
315
315
|
const MODAL_DIALOG_SELECTOR = '[role="dialog"][aria-modal="true"]';
|
|
316
316
|
const OFFICE_SHORTCUT_IGNORE_SELECTOR = '[data-office-shortcuts="ignore"]';
|
|
317
|
+
function isOfficeCompositionKeyboardEvent(event) {
|
|
318
|
+
return event.isComposing || 'Process' === event.key || 229 === event.keyCode;
|
|
319
|
+
}
|
|
317
320
|
function isOfficeShortcutBlocked(target) {
|
|
318
321
|
if ("u" < typeof document) return false;
|
|
319
322
|
if (target instanceof Element && (target.closest(MODAL_DIALOG_SELECTOR) || target.closest(OFFICE_SHORTCUT_IGNORE_SELECTOR))) return true;
|
|
320
323
|
if (document.activeElement instanceof Element && (document.activeElement.closest(MODAL_DIALOG_SELECTOR) || document.activeElement.closest(OFFICE_SHORTCUT_IGNORE_SELECTOR))) return true;
|
|
321
324
|
return null !== document.querySelector(MODAL_DIALOG_SELECTOR);
|
|
322
325
|
}
|
|
323
|
-
export { OfficeColorPicker, isOfficeShortcutBlocked };
|
|
326
|
+
export { OfficeColorPicker, isOfficeCompositionKeyboardEvent, isOfficeShortcutBlocked };
|
package/dist/0~9073.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment as jsx_runtime_Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
|
-
import { ArrowUpRight, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Eye, Minus, Plus } from "lucide-react";
|
|
4
|
+
import { ArrowUpRight, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Eye, File, Minus, Plus } from "lucide-react";
|
|
5
5
|
import { WorkOfficeCollaborationParticipants, moveOfficeMenuFocus, Popover, matchesAriaKeyShortcuts, officeOverlayPortalRoot } from "./0~8136.js";
|
|
6
6
|
const CONTEXT_MENU_MARGIN = 8;
|
|
7
7
|
const CONTEXT_MENU_TAB_STOP_SELECTOR = 'a[href]:not([tabindex="-1"]), button:not(:disabled):not([tabindex="-1"]), input:not(:disabled):not([type="hidden"]):not([tabindex="-1"]), select:not(:disabled):not([tabindex="-1"]), textarea:not(:disabled):not([tabindex="-1"]), [contenteditable="true"]:not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])';
|
|
@@ -1071,6 +1071,8 @@ function WorkOfficeFileMenu({ actions }) {
|
|
|
1071
1071
|
type: "button",
|
|
1072
1072
|
role: "menuitem",
|
|
1073
1073
|
tabIndex: -1,
|
|
1074
|
+
className: action.danger ? 'danger' : void 0,
|
|
1075
|
+
"data-danger": action.danger ? 'true' : void 0,
|
|
1074
1076
|
disabled: action.disabled,
|
|
1075
1077
|
onClick: ()=>{
|
|
1076
1078
|
close();
|
|
@@ -1080,9 +1082,12 @@ function WorkOfficeFileMenu({ actions }) {
|
|
|
1080
1082
|
/*#__PURE__*/ jsx("span", {
|
|
1081
1083
|
className: "work-office-file-action-icon",
|
|
1082
1084
|
"aria-hidden": "true",
|
|
1083
|
-
children: action.icon
|
|
1085
|
+
children: action.icon ?? /*#__PURE__*/ jsx(File, {
|
|
1086
|
+
size: 16
|
|
1087
|
+
})
|
|
1084
1088
|
}),
|
|
1085
1089
|
/*#__PURE__*/ jsx("span", {
|
|
1090
|
+
className: "work-office-file-action-label",
|
|
1086
1091
|
children: action.label
|
|
1087
1092
|
}),
|
|
1088
1093
|
action.shortcut && /*#__PURE__*/ jsx("kbd", {
|
|
@@ -21,7 +21,7 @@ import { WorkspaceContextMenu, isWorkspaceContextMenuKeyboardEvent, WorkOfficeZo
|
|
|
21
21
|
import { presentationAgentProposalTargets, SpreadsheetChartSeriesStyleEditor, applyPresentationAgentProposalChanges, normalizeOptionalOfficeNumber, SpreadsheetErrorBarEditor, useOfficeHistory, presentationNotesProposalTarget, presentationAgentSelection, SpreadsheetTrendlineEditor, presentationAgentMenuItems } from "./0~3539.js";
|
|
22
22
|
import { slideTransitionDurationMilliseconds, workSlideAnimationIndex, workSlideAnimationForElement, remapWorkSlideAnimations, createWorkSlideTransition, workSlideTransitionsEqual, workSlideAnimationCues, initialWorkSlideAnimationCueIndex, normalizeWorkSlideAnimation, createWorkSlideAnimation, removeWorkSlideAnimationsForElements } from "./0~5809.js";
|
|
23
23
|
import { createOfficeEditorExtension, useOfficeEditorRuntime, useOfficeEditorKeyboardShortcuts } from "./0~3557.js";
|
|
24
|
-
import { isOfficeShortcutBlocked, OfficeColorPicker } from "./0~3635.js";
|
|
24
|
+
import { isOfficeShortcutBlocked, OfficeColorPicker, isOfficeCompositionKeyboardEvent } from "./0~3635.js";
|
|
25
25
|
import { normalizeDocumentHref, DOCUMENT_LINK_VALIDATION_MESSAGE } from "./0~work-document-links.js";
|
|
26
26
|
import { showToast } from "./6489.js";
|
|
27
27
|
import { scaledPresentationVisuals } from "./0~work-presentation-visual-scale.js";
|
|
@@ -4357,6 +4357,8 @@ function PresentationTextEditor({ autoFocus = false, element, onChange, onEditor
|
|
|
4357
4357
|
const onEditorChangeRef = useRef(onEditorChange);
|
|
4358
4358
|
const onExitEditingRef = useRef(onExitEditing);
|
|
4359
4359
|
const onSelectionChangeRef = useRef(onSelectionChange);
|
|
4360
|
+
const editorRef = useRef(null);
|
|
4361
|
+
const compositionPublishTimerRef = useRef(null);
|
|
4360
4362
|
const appliedSignatureRef = useRef(presentationTextElementSignature(element));
|
|
4361
4363
|
const initialContentRef = useRef(presentationTextElementHtml(element));
|
|
4362
4364
|
const initialFocusTargetRef = useRef("u" > typeof document && document.activeElement instanceof HTMLElement ? document.activeElement : null);
|
|
@@ -4368,6 +4370,30 @@ function PresentationTextEditor({ autoFocus = false, element, onChange, onEditor
|
|
|
4368
4370
|
const extensions = useMemo(()=>createPresentationTextEditorExtensions(element.placeholder?.prompt ?? '输入文字'), [
|
|
4369
4371
|
element.placeholder?.prompt
|
|
4370
4372
|
]);
|
|
4373
|
+
const publishEditorValue = (current)=>{
|
|
4374
|
+
const value = presentationTextValue(current, elementRef.current);
|
|
4375
|
+
const signature = presentationTextElementSignature({
|
|
4376
|
+
...elementRef.current,
|
|
4377
|
+
...value
|
|
4378
|
+
});
|
|
4379
|
+
if (signature === appliedSignatureRef.current) return;
|
|
4380
|
+
appliedSignatureRef.current = signature;
|
|
4381
|
+
onChangeRef.current(value);
|
|
4382
|
+
};
|
|
4383
|
+
const cancelCompositionPublication = ()=>{
|
|
4384
|
+
if (null === compositionPublishTimerRef.current) return;
|
|
4385
|
+
window.clearTimeout(compositionPublishTimerRef.current);
|
|
4386
|
+
compositionPublishTimerRef.current = null;
|
|
4387
|
+
};
|
|
4388
|
+
const publishCommittedComposition = ()=>{
|
|
4389
|
+
cancelCompositionPublication();
|
|
4390
|
+
compositionPublishTimerRef.current = window.setTimeout(()=>{
|
|
4391
|
+
compositionPublishTimerRef.current = null;
|
|
4392
|
+
const current = editorRef.current;
|
|
4393
|
+
if (!current || current.isDestroyed || current.view.composing) return;
|
|
4394
|
+
publishEditorValue(current);
|
|
4395
|
+
}, 0);
|
|
4396
|
+
};
|
|
4371
4397
|
const editor = useEditor({
|
|
4372
4398
|
extensions,
|
|
4373
4399
|
content: initialContentRef.current,
|
|
@@ -4380,7 +4406,18 @@ function PresentationTextEditor({ autoFocus = false, element, onChange, onEditor
|
|
|
4380
4406
|
role: 'textbox',
|
|
4381
4407
|
spellcheck: 'true'
|
|
4382
4408
|
},
|
|
4409
|
+
handleDOMEvents: {
|
|
4410
|
+
compositionstart: ()=>{
|
|
4411
|
+
cancelCompositionPublication();
|
|
4412
|
+
return false;
|
|
4413
|
+
},
|
|
4414
|
+
compositionend: ()=>{
|
|
4415
|
+
publishCommittedComposition();
|
|
4416
|
+
return false;
|
|
4417
|
+
}
|
|
4418
|
+
},
|
|
4383
4419
|
handleKeyDown: (view, event)=>{
|
|
4420
|
+
if (view.composing || isOfficeCompositionKeyboardEvent(event)) return false;
|
|
4384
4421
|
if ('Escape' !== event.key || !onExitEditingRef.current) return false;
|
|
4385
4422
|
const object = view.dom.closest('[data-slide-element-origin]');
|
|
4386
4423
|
event.preventDefault();
|
|
@@ -4390,18 +4427,17 @@ function PresentationTextEditor({ autoFocus = false, element, onChange, onEditor
|
|
|
4390
4427
|
}
|
|
4391
4428
|
},
|
|
4392
4429
|
onCreate: ({ editor: current })=>{
|
|
4430
|
+
editorRef.current = current;
|
|
4393
4431
|
applyPresentationTextStoredMarks(current, elementRef.current);
|
|
4394
4432
|
},
|
|
4433
|
+
onDestroy: ()=>{
|
|
4434
|
+
editorRef.current = null;
|
|
4435
|
+
cancelCompositionPublication();
|
|
4436
|
+
},
|
|
4395
4437
|
onSelectionUpdate: ()=>onSelectionChangeRef.current?.(),
|
|
4396
4438
|
onUpdate: ({ editor: current })=>{
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
...elementRef.current,
|
|
4400
|
-
...value
|
|
4401
|
-
});
|
|
4402
|
-
if (signature === appliedSignatureRef.current) return;
|
|
4403
|
-
appliedSignatureRef.current = signature;
|
|
4404
|
-
onChangeRef.current(value);
|
|
4439
|
+
if (current.view.composing) return;
|
|
4440
|
+
publishEditorValue(current);
|
|
4405
4441
|
}
|
|
4406
4442
|
});
|
|
4407
4443
|
useEffect(()=>{
|