@a3s-lab/office 0.21.0 → 0.22.0
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/COLLABORATION_ROADMAP.md +1 -1
- package/README.md +87 -274
- package/dist/0~6090.js +1 -0
- package/dist/0~spreadsheet-editor.js +322 -86
- package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +28 -0
- package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +2 -0
- package/dist/internal/features/work/editors/spreadsheet-date-time-command.d.ts +14 -0
- package/dist/internal/features/work/editors/spreadsheet-date-time-ribbon.d.ts +8 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +35 -0
- package/docs/latest/en/browser-editor-architecture.md +16 -16
- package/package.json +5 -1
package/COLLABORATION_ROADMAP.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This roadmap defines one versioned collaboration protocol for every A3S Office
|
|
4
4
|
editor and for native CLI/coding-agent clients. It complements `ROADMAP.md`,
|
|
5
|
-
which tracks editor capability parity with
|
|
5
|
+
which tracks editor capability parity with Traditional Office.
|
|
6
6
|
|
|
7
7
|
## Design invariants
|
|
8
8
|
|
package/README.md
CHANGED
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
<a href="https://a3s-lab.github.io/Office/">Playground</a> ·
|
|
23
23
|
<a href="https://a3s-lab.github.io/Office/docs/">Documentation</a> ·
|
|
24
24
|
<a href="#quick-start">Quick start</a> ·
|
|
25
|
-
<a href="#
|
|
25
|
+
<a href="#editor-capability-comparison">Editors</a> ·
|
|
26
26
|
<a href="#real-time-collaboration">Collaboration</a> ·
|
|
27
27
|
<a href="#native-automation">Automation</a> ·
|
|
28
28
|
<a href="#architecture">Architecture</a> ·
|
|
29
|
-
<a href="ROADMAP.md">
|
|
29
|
+
<a href="ROADMAP.md">Capability roadmap</a> ·
|
|
30
30
|
<a href="COLLABORATION_ROADMAP.md">Collaboration roadmap</a> ·
|
|
31
31
|
<a href="CONTRIBUTING.md">Contributing</a>
|
|
32
32
|
</p>
|
|
@@ -96,6 +96,86 @@ The images below are committed visual-regression baselines from the real
|
|
|
96
96
|
</tr>
|
|
97
97
|
</table>
|
|
98
98
|
|
|
99
|
+
## Editor capability comparison
|
|
100
|
+
|
|
101
|
+
The tables below compare capability families, not button counts or visual
|
|
102
|
+
similarity. **Supported** means the editable path has deterministic tests or
|
|
103
|
+
native round-trip evidence. **Partial** means a useful path exists with a
|
|
104
|
+
documented fidelity boundary. **Gap** means no product-grade editable path
|
|
105
|
+
exists yet. Traditional Office availability varies by application, platform,
|
|
106
|
+
edition, and subscription; its column describes the conventional suite
|
|
107
|
+
baseline rather than one specific release.
|
|
108
|
+
|
|
109
|
+
### Document
|
|
110
|
+
|
|
111
|
+
| Capability | A3S Office today | Traditional Office baseline |
|
|
112
|
+
| --- | --- | --- |
|
|
113
|
+
| Text, paragraphs, lists, and styles | **Supported** — structured editing, formatting, clipboard, format painter, and undo/redo | Mature authoring with a broader long-tail style catalog |
|
|
114
|
+
| Page layout and rendering | **Partial** — sections, margins, page size, columns, headers/footers, fields, and live pagination | Desktop-grade pagination, print layout, and vector output |
|
|
115
|
+
| Tables, pictures, and equations | **Partial** — rich table geometry, floating pictures, crop/wrap, and structured OMML | Broader drawings, text boxes, charts, WordArt, and SmartArt |
|
|
116
|
+
| Comments, revisions, and collaboration | **Partial** — comments, suggestions, text/format revisions, decisions, Yjs presence, and host relay contracts | Full revision families plus integrated sharing and review services |
|
|
117
|
+
| References and document generation | **Partial** — bookmarks, links, captions, cross-references, citations, notes, and common fields | TOC/index authoring, mail merge, compare/combine, and broader fields |
|
|
118
|
+
| Ribbon and shortcuts | **Supported** — responsive Office-style ribbon and editor-scoped daily-writing shortcuts | Complete desktop shortcut and contextual-tool surface |
|
|
119
|
+
| Very large documents | **Supported with boundaries** — bounded 100,000-block plain-document windows and measured edit/navigation budgets | Native-engine virtualization with device-dependent limits |
|
|
120
|
+
| DOCX and PDF fidelity | **Partial** — source-aware DOCX preservation and live-layout raster PDF export | Broader legacy/OOXML compatibility and searchable vector PDF output |
|
|
121
|
+
|
|
122
|
+
### Spreadsheet
|
|
123
|
+
|
|
124
|
+
| Capability | A3S Office today | Traditional Office baseline |
|
|
125
|
+
| --- | --- | --- |
|
|
126
|
+
| Cells, sheets, navigation, and history | **Supported** — multiple sheets, sparse editing, search, clipboard, fill, and undo/redo | Mature grid workflows across desktop and web |
|
|
127
|
+
| Formatting and style rendering | **Partial** — native fonts, colors, borders, alignment, number formats, cell styles, and static date/time entry | Broader themes, locale formats, rich text, and advanced style effects |
|
|
128
|
+
| Ribbon and shortcuts | **Partial** — common Office-style Home/Data/View commands and grid-scoped shortcuts | Larger command catalog and platform-specific accelerators |
|
|
129
|
+
| Formulas and recalculation | **Partial** — dependency-aware calculation and common formula paths | Wider functions, arrays, volatile semantics, and calculation parity |
|
|
130
|
+
| Tables, pivots, charts, and rules | **Partial** — native tables, pivots, charts, conditional formatting, and validation | Calculated columns, slicers, pivot charts, advanced rules, and analysis |
|
|
131
|
+
| Large worksheets | **Supported with boundaries** — maximum-dimension sparse import/editing and viewport-bounded Canvas painting | Highly optimized native grid with hardware-dependent limits |
|
|
132
|
+
| Files and printing | **Partial** — XLS/XLSX/ODS/CSV import, XLSX export, and PDF output | Broader round trips, external data, print fidelity, and legacy conversion |
|
|
133
|
+
| External data, macros, and specialist analysis | **Gap** — active macros are never executed; bounded models are still needed for data connections and solver-like tools | Established data, macro/add-in, scenario, and optimization ecosystems |
|
|
134
|
+
|
|
135
|
+
### Presentation
|
|
136
|
+
|
|
137
|
+
| Capability | A3S Office today | Traditional Office baseline |
|
|
138
|
+
| --- | --- | --- |
|
|
139
|
+
| Slide and object editing | **Supported** — slide lifecycle, scene editing, multi-selection, grouping, transforms, and guides | Mature slide and drawing workflows |
|
|
140
|
+
| Text, shapes, tables, charts, and images | **Partial** — typed editable objects with native import/export paths | Broader shapes, connectors, effects, SmartArt, and embedded chart editing |
|
|
141
|
+
| Masters and layouts | **Partial** — import/export inheritance with editable common paths | Full visual master, layout, and placeholder authoring |
|
|
142
|
+
| Transitions and timings | **Partial** — fade, push, wipe, split, cut, and click/automatic advance | Broader transition catalog and timing controls |
|
|
143
|
+
| Animations and media | **Gap** — no production animation timeline, trigger model, audio, video, or recording path | Object animation, motion paths, media editing, and recording |
|
|
144
|
+
| Slideshow and presenter workflows | **Supported** — current/beginning start, keyboard playback, notes, timer, and responsive presenter view | Rehearsal, recording, ink/laser, and richer multi-display controls |
|
|
145
|
+
| Review and collaboration | **Partial** — comments, shared presence, remote object locations, and host transport | Threads, assignments, mentions, and integrated cloud review |
|
|
146
|
+
| PPTX, print, PDF, and video | **Partial** — PPTX round trip plus slide/notes/handout PDF models; no video export | Broader print controls, vector fidelity, media preservation, and video export |
|
|
147
|
+
|
|
148
|
+
### PDF
|
|
149
|
+
|
|
150
|
+
| Capability | A3S Office today | Traditional Office baseline |
|
|
151
|
+
| --- | --- | --- |
|
|
152
|
+
| Rendering and navigation | **Supported** — PDFium pages, thumbnails, zoom, keyboard navigation, and bounded long-file windows | Mature desktop/web viewing and navigation |
|
|
153
|
+
| Search and text evidence | **Supported with boundaries** — browser search and bounded native text-layer evidence | Broader tagged-PDF reading order and accessibility extraction |
|
|
154
|
+
| Annotations, forms, and save | **Supported** — common annotations, appearance controls, form filling, history, and save | Broader stamps, measurements, form authoring, scripts, and signatures |
|
|
155
|
+
| Existing text, image, and object editing | **Gap** — no safe production content-stream editing path | Direct text/object editing with font and layout recovery |
|
|
156
|
+
| Page organization | **Gap** — insert, delete, rotate, reorder, extract, merge, and split are not yet editable | Complete page organization workflows |
|
|
157
|
+
| Compression, conversion, and OCR | **Gap / host boundary** — provider contracts are required for authoritative conversion and OCR | Integrated optimization, conversion, and scanned-document recognition |
|
|
158
|
+
| Signatures, protection, and redaction | **Gap / host boundary** — trusted identity and destructive-content guarantees are required | E-signing, certificate validation, encryption, sanitization, and true redaction |
|
|
159
|
+
| AI and real-time collaboration | **Host-owned** — typed page/text evidence, Yjs review records, presence, and provider-neutral ports | Typically bundled with account, storage, and model services |
|
|
160
|
+
|
|
161
|
+
### Markdown
|
|
162
|
+
|
|
163
|
+
Markdown is an A3S Office differentiator rather than a parity target.
|
|
164
|
+
|
|
165
|
+
| Capability | A3S Office today | Traditional Office baseline |
|
|
166
|
+
| --- | --- | --- |
|
|
167
|
+
| Source and visual editing | **Supported** — GFM source, visual mode, synchronized split preview, and source-native history | No standard first-class Markdown editor |
|
|
168
|
+
| Tables, tasks, links, images, and code | **Supported** — format-native Markdown structures in both editing modes | Usually represented through rich-document conversion or plain text |
|
|
169
|
+
| Responsive UI and shortcuts | **Supported** — desktop split view, phone single-surface modes, and editor-scoped formatting | Depends on a text editor, add-in, or conversion workflow |
|
|
170
|
+
| Collaboration | **Supported** — Yjs content, Awareness presence, remote selections, and host-owned transport | Usually available only after conversion into a cloud document format |
|
|
171
|
+
| Import, export, and automation | **Supported** — direct Markdown round trip plus typed browser, CLI, MCP, and agent mutations | No shared native Markdown automation contract |
|
|
172
|
+
|
|
173
|
+
Document and Markdown accept public TipTap Extensions. Spreadsheet,
|
|
174
|
+
Presentation, and PDF expose stable host ports rather than private command
|
|
175
|
+
contexts. Editor engines and large runtime assets load only when their surface
|
|
176
|
+
is requested. The complete gap inventory and exit evidence live in the
|
|
177
|
+
[capability roadmap](ROADMAP.md).
|
|
178
|
+
|
|
99
179
|
## Why A3S Office
|
|
100
180
|
|
|
101
181
|
- **Product-native UI** — Complete Office-style surfaces with no required
|
|
@@ -397,274 +477,6 @@ into the PDF; searchable text and vector output remain future fidelity work.
|
|
|
397
477
|
Copyable React, Vue, and Web Component examples live in the
|
|
398
478
|
[component documentation](https://a3s-lab.github.io/Office/docs/components/).
|
|
399
479
|
|
|
400
|
-
## Five format-native surfaces
|
|
401
|
-
|
|
402
|
-
Each surface keeps a canonical model that matches its file format and user
|
|
403
|
-
interaction model.
|
|
404
|
-
|
|
405
|
-
- **Document** — Pagination, sections, focused page-setup tabs, clean page
|
|
406
|
-
margins with on-demand header/footer editing, outline navigation with
|
|
407
|
-
contextual full-text results, keyboard-operated live physical-page raster
|
|
408
|
-
thumbnails with viewport-bounded capture, and shared virtualized
|
|
409
|
-
long-document windows for page buttons, heading rows, full-text results, and
|
|
410
|
-
tracked-revision and anchored-comment review that preserve native scroll
|
|
411
|
-
distance, sparse current/selection/draft pins, and Home/End reachability;
|
|
412
|
-
a WPS-familiar command catalog, quick-access undo and redo, a priority-aware
|
|
413
|
-
adaptive and persistently collapsible ribbon whose tabs can temporarily
|
|
414
|
-
expose commands; WPS-oriented Insert groups and direct Page Layout presets
|
|
415
|
-
for margins, orientation, paper size, and columns, with matching advanced
|
|
416
|
-
Page Setup destinations; WPS-oriented References, Review, and View groups,
|
|
417
|
-
direct tracked-change navigation and decisions, contextual object tabs, and
|
|
418
|
-
viewport-calculated 100%, one-page, and page-width zoom; an actionable status
|
|
419
|
-
bar with live word-count details, WPS `Ctrl+Shift+G`, keyboard-traversable
|
|
420
|
-
view and zoom controls, and compact Web prioritization; editor-scoped WPS
|
|
421
|
-
formatting, paragraph, style, and review shortcuts, plus a permission-free
|
|
422
|
-
formatting clipboard and one-shot format painter shared with compatible
|
|
423
|
-
header and footer formatting, paragraph styles and phone-sized
|
|
424
|
-
paragraph-spacing and pagination controls
|
|
425
|
-
with touch targets and exact invoker-focus restoration; stable compact-ribbon
|
|
426
|
-
edge paging and viewport-bounded list galleries with touch-sized numbering
|
|
427
|
-
actions, selection-preserving bullet and numbering commands, and explicit
|
|
428
|
-
Escape-to-invoker focus restoration;
|
|
429
|
-
grouped bundled, common system, monospace, imported, and host-provided font
|
|
430
|
-
choices with live typeface previews, independent table layout algorithms,
|
|
431
|
-
auto, percentage, or pixel preferred widths, left/center/right placement,
|
|
432
|
-
indentation, table-level cell margins, cell-level margin overrides, and
|
|
433
|
-
rendered column measurements for autofit tables. One Table Properties dialog
|
|
434
|
-
presents table, row, column, and cell tabs. It combines preferred width,
|
|
435
|
-
placement, and indent with selected-row height and pagination, current-column
|
|
436
|
-
width, and selected-cell vertical alignment and margins. The complete draft
|
|
437
|
-
commits in one TipTap transaction and one undo record while untouched imported
|
|
438
|
-
measurements and partial margin inheritance retain their exact source values.
|
|
439
|
-
Cancel and Escape discard the draft and restore the exact ribbon invoker;
|
|
440
|
-
compact layouts keep tabs, numeric steppers, and footer actions touch-sized. A
|
|
441
|
-
contextual Picture Properties workflow combines centimeter width and height,
|
|
442
|
-
a per-image aspect-ratio lock, inline/square/top-and-bottom wrapping,
|
|
443
|
-
alignment, text distance, and alternative text. It commits only changed
|
|
444
|
-
fields in one TipTap history entry, preserves untouched imported dimensions
|
|
445
|
-
exactly, and retains the image selection and invoker focus after apply,
|
|
446
|
-
cancel, or Escape on desktop and phone layouts. A
|
|
447
|
-
reusable table-border pen with all, outside, inside, and individual-edge
|
|
448
|
-
targets, per-edge DOCX border preservation, and bounded `basedOn` table-style
|
|
449
|
-
inheritance with whole-table, banded row or column, first/last row or column,
|
|
450
|
-
and corner-cell formatting. Conditional fills, borders, bold, italic,
|
|
451
|
-
underline, strikethrough, fonts, and text colors are materialized before
|
|
452
|
-
direct table, cell, paragraph, and run formatting. Conditional paragraph
|
|
453
|
-
alignment, direction, indents, spacing and line rules, pagination rules, and
|
|
454
|
-
tab stops use the same precedence chain. Paragraph shading follows document
|
|
455
|
-
defaults, based-on paragraph styles, conditional table styles, and direct
|
|
456
|
-
formatting in that order. The complete Word `w:shd` pattern set, independent
|
|
457
|
-
foreground/background colors, `auto`, `nil` resets, and independently tinted
|
|
458
|
-
or shaded theme references remain structured through body and page-chrome
|
|
459
|
-
HTML; browser previews use bounded CSS masks while DOCX export restores the
|
|
460
|
-
native pattern and both theme channels. Preview follows Word's tint-over-shade
|
|
461
|
-
precedence when both transforms occur on one theme channel while retaining
|
|
462
|
-
both attributes for export. Malformed, duplicated,
|
|
463
|
-
namespace-spoofed, relationship-bound, or unresolved theme values fail closed
|
|
464
|
-
instead of inheriting stale shading. Theme tint and shade values resolve for
|
|
465
|
-
table borders and cell fills across edit, preview, and RGB-stable export.
|
|
466
|
-
Paragraph borders use the same precedence chain and retain the complete
|
|
467
|
-
`w:pBdr` model: schema-ordered `top`, `left`, `bottom`, `right`, `between`,
|
|
468
|
-
and facing-page `bar` edges; all 197 line and art styles; direct, automatic,
|
|
469
|
-
and theme colors; eighth-point or point widths; spacing; shadow; and frame.
|
|
470
|
-
Physical edges remain editable CSS, while art, between-paragraph, and
|
|
471
|
-
facing-page behavior uses a bounded browser approximation; DOCX export
|
|
472
|
-
restores the exact native edge set and attributes. Direct CSS edits replace
|
|
473
|
-
only the edited edge's theme binding, strict and transitional namespaces are
|
|
474
|
-
accepted, and malformed order, duplicates, spoofed namespaces, unsafe
|
|
475
|
-
attributes, invalid measures, and unresolved themes fail closed.
|
|
476
|
-
Splittable table rows that exceed a full physical page
|
|
477
|
-
continue at paragraph boundaries with repeated heading rows on every page,
|
|
478
|
-
viewport-safe comment drafting and focus-preserving citation drafts, tracked
|
|
479
|
-
changes, notes,
|
|
480
|
-
pointer- and Shift+F10-accessible host-defined selection menus, and shared
|
|
481
|
-
edit/preview/PDF typography and page-chrome placement. Editing, read-only
|
|
482
|
-
preview, and browser PDF export share one live pagination result. Tail edits
|
|
483
|
-
reuse the stable physical-page prefix, including resolved first/odd/even
|
|
484
|
-
headers, footers, page numbers, and navigation descriptors. Browser DOM
|
|
485
|
-
measurement runs in bounded 32 ms slices and yields only between top-level
|
|
486
|
-
blocks; document edits abort stale passes before a snapshot is committed, so
|
|
487
|
-
long repagination work does not monopolize the browser event loop.
|
|
488
|
-
Real DOCX fixtures provide deterministic A3S Test evidence for inherited
|
|
489
|
-
table styling across edit and preview, a centered 62.5% table with table and
|
|
490
|
-
cell margin overrides, all four Table Properties tabs at 390 px, exact
|
|
491
|
-
preservation of untouched cell-margin edges, a complete 390 px Picture
|
|
492
|
-
Properties flow, and a 120-paragraph row across three physical pages through
|
|
493
|
-
the final table content and following paragraph.
|
|
494
|
-
A direct-formatting A4 fixture also runs through a real WPS Writer PDF export
|
|
495
|
-
and a page-only browser comparison. Its automatic line spacing, paragraph
|
|
496
|
-
gaps, centered fixed table, row heights, borders, fills, and cell margins
|
|
497
|
-
stay within the checked one-pixel layout-landmark budget while preserving
|
|
498
|
-
the original OOXML line multiples for DOCX export.
|
|
499
|
-
Separate 30-row common-font, 36-row CJK-font, 18-row document-grid, and
|
|
500
|
-
30-row multilingual-script matrices now gate text-band positions against
|
|
501
|
-
WPS. DOCX import selects the Word `ascii`, `hAnsi`, `eastAsia`, or `cs` font
|
|
502
|
-
slot from the run script, including complex-script bold, italic, size, and
|
|
503
|
-
RTL overrides. The browser keeps the measured per-font automatic-line
|
|
504
|
-
advance, while DOCX round trips retain the section `docGrid` type and line
|
|
505
|
-
pitch and each run's `snapToGrid` override.
|
|
506
|
-
_DOCX import/export; PDF export._
|
|
507
|
-
- **Markdown** — GFM source, visual editing, synchronized and resizable split
|
|
508
|
-
preview, source-native undo/redo with typing coalescing and selection restore,
|
|
509
|
-
source-aware ribbon formatting and shortcuts, empty-source guidance, task
|
|
510
|
-
lists, tables, links, images, code, a flat reading surface with a comfortable
|
|
511
|
-
line length, and keyboard-accessible host-defined selection menus across both
|
|
512
|
-
editing surfaces. At phone widths, Source and Preview each use the complete
|
|
513
|
-
workspace instead of being compressed into two stacked panes. _Markdown
|
|
514
|
-
import/export._
|
|
515
|
-
- **Spreadsheet** — Multiple sheets, formulas, dependency-aware recalculation,
|
|
516
|
-
live selection statistics, an A3S-owned worksheet bar with lifecycle and
|
|
517
|
-
color controls, safe deletion confirmation, in-place rename validation, a
|
|
518
|
-
grid-aligned single-row responsive workbook footer that keeps the active
|
|
519
|
-
worksheet and its actions visible across window and phone-width changes,
|
|
520
|
-
selection-preserving undo/redo, deterministic Arrow, Enter, Tab, Home,
|
|
521
|
-
PageUp/PageDown, row, column, and all-cells selection shortcuts, Cmd/Ctrl
|
|
522
|
-
formatting through root-scoped capture before vendor grid listeners, an
|
|
523
|
-
WPS-style Home and Editing Find and Select menu whose editor-owned
|
|
524
|
-
`Cmd/Ctrl+F` search finds displayed values, raw values, formulas, and sparse
|
|
525
|
-
cells without opening browser Find, plus view-only `Ctrl+G` and `F5` Go To
|
|
526
|
-
for direct, quoted cross-sheet, and named ranges without content updates,
|
|
527
|
-
Undo records, or sparse materialization, with a viewport-safe phone Find
|
|
528
|
-
layout, touch-sized controls, bounded validation, and exact focus restoration,
|
|
529
|
-
desktop workbook task panes that become focus-contained phone dialogs with
|
|
530
|
-
an inert workbook background and exact ribbon-invoker restoration,
|
|
531
|
-
a WPS-familiar command catalog and tab order, quick-access Undo and Redo,
|
|
532
|
-
a priority-aware adaptive and collapsible ribbon with temporary tab
|
|
533
|
-
expansion, an executable Home clipboard group whose Paste, Cut, and Copy
|
|
534
|
-
commands share the permission-resilient local fallback with their WPS
|
|
535
|
-
shortcuts, a WPS-style Paste split command with quick All, Values, Formulas,
|
|
536
|
-
and Formatting actions plus `Cmd/Ctrl+Alt+V` Paste Special for ten content
|
|
537
|
-
modes, arithmetic operations, Skip blanks, Transpose, translated formula
|
|
538
|
-
references, rich same-editor styles/comments/validation/merges/column widths,
|
|
539
|
-
bounded TSV fallback, one-step Undo, and fail-closed protected or unsafe
|
|
540
|
-
targets, an Insert and Links Hyperlink command with grid-scoped `Cmd/Ctrl+K`,
|
|
541
|
-
accessible Web page, cell-range, and worksheet targets, explicit Edit and
|
|
542
|
-
Remove, immutable dense/sparse updates, content/style/comment preservation,
|
|
543
|
-
exact focus restoration, one-step Undo, and fail-closed unsafe, hidden,
|
|
544
|
-
protected, pivot, or out-of-bounds targets, a Data and Data Tools Validation
|
|
545
|
-
command for lists, whole numbers, decimals, dates, and text length across
|
|
546
|
-
multiple ranges, compact rule writes and removal, input messages,
|
|
547
|
-
invalid-input blocking, 1900/1904-aware XLSX date round trips, exact focus
|
|
548
|
-
restoration, one-step Undo, and fail-closed protected, merged, pivot,
|
|
549
|
-
read-only, invalid, out-of-bounds, or over-10,000-cell targets, native
|
|
550
|
-
Spreadsheet Tables/ListObjects through Insert and grid-scoped `Cmd/Ctrl+T`,
|
|
551
|
-
bounded current-region or explicit-range creation, canonical unique headers,
|
|
552
|
-
a contextual Table Design ribbon with editable names, 60 OOXML
|
|
553
|
-
Light/Medium/Dark styles, first/last-column emphasis and row/column stripes,
|
|
554
|
-
visible-range Canvas styling, sparse-safe Convert to Range, row/column
|
|
555
|
-
reconciliation, native XLSX table parts and supported filters, one-step Undo,
|
|
556
|
-
browser/Yjs record convergence, and fail-closed overlap, merge, AutoFilter,
|
|
557
|
-
protection, pivot, invalid, or over-100,000-cell targets, a WPS-style
|
|
558
|
-
Format Painter with
|
|
559
|
-
single-use and double-click locked
|
|
560
|
-
sessions, cross-sheet range-pattern tiling, Escape cancellation, and native
|
|
561
|
-
style-only writes, Home and Font Grow/Shrink Font commands with
|
|
562
|
-
`Cmd/Ctrl+Shift+.` / `Cmd/Ctrl+]` and `Cmd/Ctrl+Shift+,` / `Cmd/Ctrl+[` aliases,
|
|
563
|
-
per-cell mixed-size stepping, native rectangle compaction, a 10,000-cell
|
|
564
|
-
bound, and one-step Undo, a WPS-style Underline split control with single,
|
|
565
|
-
double, single-accounting, and double-accounting styles, exact Format Cells
|
|
566
|
-
and XLSX round trips, active-style-aware `Cmd/Ctrl+U` toggling, and WPS
|
|
567
|
-
`Ctrl+2`, `Ctrl+3`, and `Ctrl+4` aliases for Bold, Italic, and Underline;
|
|
568
|
-
Automatic Color and No Fill remove direct text and background colors instead
|
|
569
|
-
of hard-coding replacements, a
|
|
570
|
-
keyboard-accessible WPS Text Orientation menu with horizontal, both 45-degree
|
|
571
|
-
angles, stacked vertical, rotate-up, and rotate-down choices, exact Fortune
|
|
572
|
-
`rt` / `tr='3'` and OOXML 0–180 / 255 round trips, a 10,000-cell guard, and
|
|
573
|
-
one-batch Undo, plus a cell-border split control with side, all,
|
|
574
|
-
outside, inside, horizontal, vertical, clear, independent diagonal-down and
|
|
575
|
-
diagonal-up targets, crossed-border composition, ten native line styles,
|
|
576
|
-
exact color selection, compact overlapping range writes, exact OOXML
|
|
577
|
-
direction preservation through Paste Special, Yjs, XLSX export, and reopen,
|
|
578
|
-
`Cmd/Ctrl+Shift+&` Outside Borders and `Cmd/Ctrl+Shift+_` Clear Borders,
|
|
579
|
-
single-update undo, and grid-focus restoration, Conditional Formatting under
|
|
580
|
-
Home and Styles, executable
|
|
581
|
-
sorting plus WPS-style AutoFilter under Data, finite current-region discovery,
|
|
582
|
-
`Cmd/Ctrl+Shift+L` toggling, an `Alt+ArrowDown` keyboard filter menu,
|
|
583
|
-
a Home and Cells Rows and Columns menu for inserting above, below, left, or
|
|
584
|
-
right, deleting selected rows or columns, and hiding or unhiding rows and
|
|
585
|
-
columns through the shared structure command port, including grid-scoped
|
|
586
|
-
`Cmd/Ctrl+9`, `Cmd/Ctrl+0`, `Cmd/Ctrl+Shift+9`, and `Cmd/Ctrl+Shift+0`
|
|
587
|
-
shortcuts with 10,000-row and 1,000-column allocation guards, a Home and
|
|
588
|
-
Alignment Merge and Center split control with
|
|
589
|
-
Merge Cells, Merge Across, Unmerge Cells, Unmerge and Fill, and the WPS
|
|
590
|
-
`Ctrl+M` shortcut through one controlled native workbook batch,
|
|
591
|
-
a Home and Editing Clear menu for independently removing content, formats,
|
|
592
|
-
comments, hyperlinks, or all cell state while preserving merge geometry,
|
|
593
|
-
with Delete and Backspace mapped to Clear Contents,
|
|
594
|
-
a Home and Editing Fill menu for Down, Right, Up, and Left with native
|
|
595
|
-
relative-formula and style propagation, WPS `Cmd/Ctrl+D` and `Cmd/Ctrl+R`
|
|
596
|
-
shortcuts, one-step history, protected-range preflight, a 50,000-target-cell
|
|
597
|
-
guard, and sparse-row-safe execution,
|
|
598
|
-
a WPS AutoSum split command before Fill with Sum, Average, Count, Maximum,
|
|
599
|
-
and Minimum, the editor-scoped `Alt+=` Sum shortcut, contiguous source
|
|
600
|
-
inference above or left of a blank target, multi-formula totals rows and
|
|
601
|
-
columns, target-style preservation, merged/protected/read-only/pivot and
|
|
602
|
-
overwrite preflight, a 1,000-formula bound, sparse-safe native batches, and
|
|
603
|
-
one-step history,
|
|
604
|
-
Home and Number presets for General, Number, CNY Currency, Accounting,
|
|
605
|
-
Percentage, Short Date, Time, Scientific, Fraction, and Text, including the
|
|
606
|
-
seven standard `Cmd/Ctrl+Shift` format shortcuts, exact XLSX format-code
|
|
607
|
-
round trips, value/formula preservation, and one-step history, plus
|
|
608
|
-
10,000-cell-bounded Increase/Decrease Decimal commands that retain every
|
|
609
|
-
cell's format family across mixed selections and commit one native batch,
|
|
610
|
-
a WPS-style Format Cells dialog under Home and Number with the editor-scoped
|
|
611
|
-
`Cmd/Ctrl+1` shortcut, functional Number, Alignment, Font, Border, Fill, and
|
|
612
|
-
Protection tabs, untouched mixed-value preservation, custom native number
|
|
613
|
-
codes, compact protection ranges, dense/sparse representation retention,
|
|
614
|
-
bounded blank-cell materialization, one controlled update and one Undo
|
|
615
|
-
record per Apply, and exact launcher or remounted-grid focus restoration,
|
|
616
|
-
a Home and Styles gallery with 17 WPS built-in cell styles grouped as Common,
|
|
617
|
-
Data and Model, and Titles and Totals, true native previews, two-dimensional
|
|
618
|
-
keyboard navigation, a 10,000-cell bound, blank-cell styling, per-cell border
|
|
619
|
-
semantics, current-style recognition without private markers, one-step
|
|
620
|
-
history, and direct XLSX font, fill, alignment, wrap, rotation, border, and
|
|
621
|
-
number-format XF round trips; imported theme, indexed, automatic, and tint
|
|
622
|
-
identities for direct font, solid-fill, and border colors survive unrelated
|
|
623
|
-
edits and Yjs transport when the rendered RGB and palette slot still agree,
|
|
624
|
-
while changed or conflicting colors safely export as explicit RGB,
|
|
625
|
-
a View and Window Freeze Panes menu for current-cell, top-row, first-column,
|
|
626
|
-
and unfreeze patterns with XLSX round trips, and visible F9 workbook
|
|
627
|
-
recalculation,
|
|
628
|
-
Shift+F11 creation, Ctrl/Cmd+PageUp/PageDown switching in edit and read-only
|
|
629
|
-
preview,
|
|
630
|
-
one shared cell/worksheet context-menu surface with executable shortcut
|
|
631
|
-
hints that becomes a touch-sized, scrollable bottom action sheet on phones,
|
|
632
|
-
keyboard-operated cells and sheet tabs, direct type-to-edit,
|
|
633
|
-
permission-resilient multi-cell cut/copy/paste, clear, F2 editing, and
|
|
634
|
-
focus-safe Escape behavior, direct
|
|
635
|
-
font-family, vertical-alignment, text-wrap, number-format, and decimal
|
|
636
|
-
controls, charts, validation, protection, comments, and print settings.
|
|
637
|
-
_XLSX, XLS, ODS, and CSV import; XLSX and PDF export._
|
|
638
|
-
- **Presentation** — Typed slide scene graph, multi-selection, groups, object
|
|
639
|
-
transforms, keyboard-accessible table-size insertion, Shift+F10-accessible
|
|
640
|
-
native slide and object context actions, guides, comments, transitions,
|
|
641
|
-
editor-scoped formatting and clipboard shortcuts that restore the selected
|
|
642
|
-
object, a docked desktop chart inspector that becomes a focus-contained modal
|
|
643
|
-
surface whenever it overlays the canvas, docked desktop comment review that
|
|
644
|
-
becomes a readable, touch-sized, focus-contained full-editor modal on phones
|
|
645
|
-
with dirty-draft cancellation and exact invoker restoration, a dismissible
|
|
646
|
-
phone slide navigator, a top-aligned phone canvas with a priority-aware status
|
|
647
|
-
bar, one-step slideshow from the beginning or current slide,
|
|
648
|
-
keyboard-complete playback, and a responsive presenter view with one
|
|
649
|
-
navigation strip, current/next context, speaker notes, and a session timer.
|
|
650
|
-
_PPTX import/export; PDF export._
|
|
651
|
-
- **PDF** — PDFium rendering, navigation, search, form filling, annotations,
|
|
652
|
-
annotation color, opacity, compatible stroke-width controls, history,
|
|
653
|
-
a scrollable page-thumbnail rail with current-page synchronization and
|
|
654
|
-
focus-synchronized Arrow/Home/End navigation, a 32-thumbnail hard window,
|
|
655
|
-
cancellation of stale PDFium bitmap tasks, bounded main-page rendering for
|
|
656
|
-
long files, and a dismissible page drawer whose phone trigger stays in the
|
|
657
|
-
page controls instead of covering PDF content,
|
|
658
|
-
focus-safe page and search drafts, responsive search-result, navigation, and
|
|
659
|
-
zoom controls, editor-scoped shortcuts, and a keyboard-operated overflow menu
|
|
660
|
-
that retains secondary annotation tools and appearance settings on phones.
|
|
661
|
-
_PDF open/save._
|
|
662
|
-
|
|
663
|
-
Document and Markdown accept public TipTap Extensions. Spreadsheet,
|
|
664
|
-
Presentation, and PDF expose stable host ports rather than their internal
|
|
665
|
-
command contexts. Editor engines and large runtime assets load only when that
|
|
666
|
-
surface is requested.
|
|
667
|
-
|
|
668
480
|
## Controlled by design
|
|
669
481
|
|
|
670
482
|
A3S Office is headless at the product boundary, not at the UI boundary. The
|
|
@@ -1495,10 +1307,10 @@ minor release may still include breaking model changes. Required migrations
|
|
|
1495
1307
|
will be called out in the [changelog](CHANGELOG.md).
|
|
1496
1308
|
|
|
1497
1309
|
The project targets predictable browser editing and file preservation, not
|
|
1498
|
-
pixel parity with every
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1310
|
+
pixel parity with every Traditional Office feature. Unsupported OOXML semantics
|
|
1311
|
+
and fidelity gaps remain explicit compatibility boundaries instead of being
|
|
1312
|
+
silently approximated. Track product depth and release evidence in the
|
|
1313
|
+
[editor quality roadmap](docs/latest/en/editor-quality-roadmap.md).
|
|
1502
1314
|
|
|
1503
1315
|
## Development
|
|
1504
1316
|
|
|
@@ -1535,6 +1347,7 @@ without hard-coded return URLs.
|
|
|
1535
1347
|
|
|
1536
1348
|
- [Live Playground](https://a3s-lab.github.io/Office/)
|
|
1537
1349
|
- [Documentation center](https://a3s-lab.github.io/Office/docs/)
|
|
1350
|
+
- [A3S Office 0.22.0 documentation](https://a3s-lab.github.io/Office/docs/0.22.0/)
|
|
1538
1351
|
- [A3S Office 0.21.0 documentation](https://a3s-lab.github.io/Office/docs/0.21.0/)
|
|
1539
1352
|
- [A3S Office 0.20.0 documentation](https://a3s-lab.github.io/Office/docs/0.20.0/)
|
|
1540
1353
|
- [A3S Office 0.19.0 documentation](https://a3s-lab.github.io/Office/docs/0.19.0/)
|
package/dist/0~6090.js
CHANGED
|
@@ -257,6 +257,7 @@ function shortcutCodeKey(code) {
|
|
|
257
257
|
if ('Space' === code) return 'space';
|
|
258
258
|
if ('Equal' === code) return 'equal';
|
|
259
259
|
if ('Minus' === code) return 'minus';
|
|
260
|
+
if ('Semicolon' === code) return ';';
|
|
260
261
|
if ('Comma' === code) return ',';
|
|
261
262
|
if ('Period' === code) return '.';
|
|
262
263
|
return null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __webpack_require__ } from "./0~rslib-runtime.js";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Workbook } from "@fortune-sheet/react";
|
|
4
|
-
import { AArrowDown, AArrowUp, AlignCenter, AlignLeft, AlignRight, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignVerticalJustifyStart, ArrowDown, ArrowDownToLine, ArrowLeft, ArrowLeftToLine, ArrowRight, ArrowRightToLine, ArrowUp, ArrowUpToLine, BadgeJapaneseYen, BarChart3, BetweenHorizontalEnd, BetweenHorizontalStart, BetweenVerticalEnd, BetweenVerticalStart, Bold, Bookmark, Calculator, Check, ChevronDown, ChevronLeft, ChevronRight, ClipboardPaste, Cloud, Columns3, Copy, CopyPlus, DecimalsArrowLeft, DecimalsArrowRight, Eraser, Eye, EyeOff, FileX2, Globe2, Grid2X2, Grid3X3, Hash, Italic, KeyRound, Layers2, Link2, Link2Off, ListChecks, ListFilter, LocateFixed, Merge, MessageSquareX, MoveHorizontal, MoveVertical, Paintbrush, Palette, PanelLeft, PanelTop, PanelsTopLeft, Pencil, Percent, Plus, Printer, Redo2, RefreshCw, Rows3, Save, Scissors, Search, Settings2, ShieldCheck, Sigma, SortAsc, SortDesc, Strikethrough, SwatchBook, Table2, TableProperties, Trash2, Underline, Undo2, WrapText, X } from "lucide-react";
|
|
4
|
+
import { AArrowDown, AArrowUp, AlignCenter, AlignLeft, AlignRight, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignVerticalJustifyStart, ArrowDown, ArrowDownToLine, ArrowLeft, ArrowLeftToLine, ArrowRight, ArrowRightToLine, ArrowUp, ArrowUpToLine, BadgeJapaneseYen, BarChart3, BetweenHorizontalEnd, BetweenHorizontalStart, BetweenVerticalEnd, BetweenVerticalStart, Bold, Bookmark, Calculator, CalendarClock, CalendarDays, Check, ChevronDown, ChevronLeft, ChevronRight, ClipboardPaste, Clock, Cloud, Columns3, Copy, CopyPlus, DecimalsArrowLeft, DecimalsArrowRight, Eraser, Eye, EyeOff, FileX2, Globe2, Grid2X2, Grid3X3, Hash, Italic, KeyRound, Layers2, Link2, Link2Off, ListChecks, ListFilter, LocateFixed, Merge, MessageSquareX, MoveHorizontal, MoveVertical, Paintbrush, Palette, PanelLeft, PanelTop, PanelsTopLeft, Pencil, Percent, Plus, Printer, Redo2, RefreshCw, Rows3, Save, Scissors, Search, Settings2, ShieldCheck, Sigma, SortAsc, SortDesc, Strikethrough, SwatchBook, Table2, TableProperties, Trash2, Underline, Undo2, WrapText, X } from "lucide-react";
|
|
5
5
|
import { Fragment as external_react_Fragment, cloneElement, memo, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
6
6
|
import { genarate, indexToColumnChar, update as core_update } from "@fortune-sheet/core";
|
|
7
7
|
import { freezeImportedSpreadsheetCell, spreadsheetTextOrientationFromChoice, spreadsheetMatrixProfile, withoutEditableRange, spreadsheetTextOrientationFromAngle, isSpreadsheetTextOrientationId, normalizeSpreadsheetConditionalVisualOptions, spreadsheetCellValueWithDiagonalBorder, spreadsheetUnderlineCellValue, effectiveSpreadsheetPageSetup, attachSpreadsheetShownCommentCells, withEditableRange, sameSpreadsheetHistoryValue, createOfficeSpreadsheetCollaborationBinding as createWorkOfficeSpreadsheetCollaborationBinding, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconForValue, defaultSpreadsheetConditionalIconThresholds, spreadsheetUnderlineStyle, normalizeSpreadsheetDateValidationBoundary, sheetProtectionAuthority, editableRangeCellCount, unlockedCellCount, registerDerivedSpreadsheetMatrix, editableRangeRequiresCredentials, spreadsheetTextOrientationCellStyle, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, spreadsheetConditionalThresholdValue, spreadsheetTextOrientationChoiceFromCell, normalizeSheetProtectionAuthority, withSheetProtection, defaultSpreadsheetColorScaleThresholds, spreadsheetProtectionKey, spreadsheetDiagonalBorderFromCellValue, SPREADSHEET_CONDITIONAL_ICON_SETS, protectedSheetCount, withSheetSelectionPermissions, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, spreadsheetConditionalComparisonNeedsUpperValue, drawSpreadsheetConditionalIcon, spreadsheetTextOrientationFromCell, replaceOfficeSpreadsheetCollaboration as replaceWorkOfficeSpreadsheetCollaboration, readOfficeSpreadsheetCollaboration as readWorkOfficeSpreadsheetCollaboration, spreadsheetConditionalThresholdsEqual, isSpreadsheetUnderlineStyle, spreadsheetVisibleTextRotationFromCell } from "./5045.js";
|
|
@@ -3236,6 +3236,38 @@ const spreadsheetCommandCatalog = {
|
|
|
3236
3236
|
group: 'number'
|
|
3237
3237
|
}
|
|
3238
3238
|
},
|
|
3239
|
+
insertCurrentDate: {
|
|
3240
|
+
id: 'number.insertCurrentDate',
|
|
3241
|
+
label: '插入当前日期',
|
|
3242
|
+
location: {
|
|
3243
|
+
area: 'ribbon',
|
|
3244
|
+
tab: 'home',
|
|
3245
|
+
group: 'number'
|
|
3246
|
+
},
|
|
3247
|
+
shortcut: {
|
|
3248
|
+
label: 'Ctrl+;',
|
|
3249
|
+
aria: 'Control+;',
|
|
3250
|
+
editor: [
|
|
3251
|
+
'Control-;'
|
|
3252
|
+
]
|
|
3253
|
+
}
|
|
3254
|
+
},
|
|
3255
|
+
insertCurrentTime: {
|
|
3256
|
+
id: 'number.insertCurrentTime',
|
|
3257
|
+
label: '插入当前时间',
|
|
3258
|
+
location: {
|
|
3259
|
+
area: 'ribbon',
|
|
3260
|
+
tab: 'home',
|
|
3261
|
+
group: 'number'
|
|
3262
|
+
},
|
|
3263
|
+
shortcut: {
|
|
3264
|
+
label: 'Ctrl+Shift+;',
|
|
3265
|
+
aria: 'Control+Shift+;',
|
|
3266
|
+
editor: [
|
|
3267
|
+
'Control-Shift-;'
|
|
3268
|
+
]
|
|
3269
|
+
}
|
|
3270
|
+
},
|
|
3239
3271
|
formatCells: {
|
|
3240
3272
|
id: 'number.formatCells',
|
|
3241
3273
|
label: '设置单元格格式',
|
|
@@ -6036,6 +6068,207 @@ function clampSpreadsheetDataValidationFocus(value, range) {
|
|
|
6036
6068
|
const focus = 'number' == typeof value && Number.isFinite(value) ? Math.trunc(value) : minimum;
|
|
6037
6069
|
return Math.min(maximum, Math.max(minimum, focus));
|
|
6038
6070
|
}
|
|
6071
|
+
const MAX_SPREADSHEET_ROWS = 1048576;
|
|
6072
|
+
const spreadsheetPasteContentOptions = [
|
|
6073
|
+
{
|
|
6074
|
+
value: 'all',
|
|
6075
|
+
label: '全部',
|
|
6076
|
+
richOnly: false
|
|
6077
|
+
},
|
|
6078
|
+
{
|
|
6079
|
+
value: 'formulas',
|
|
6080
|
+
label: '公式',
|
|
6081
|
+
richOnly: false
|
|
6082
|
+
},
|
|
6083
|
+
{
|
|
6084
|
+
value: 'values',
|
|
6085
|
+
label: '值',
|
|
6086
|
+
richOnly: false
|
|
6087
|
+
},
|
|
6088
|
+
{
|
|
6089
|
+
value: 'formats',
|
|
6090
|
+
label: '格式',
|
|
6091
|
+
richOnly: true
|
|
6092
|
+
},
|
|
6093
|
+
{
|
|
6094
|
+
value: 'comments',
|
|
6095
|
+
label: '批注',
|
|
6096
|
+
richOnly: true
|
|
6097
|
+
},
|
|
6098
|
+
{
|
|
6099
|
+
value: 'validation',
|
|
6100
|
+
label: '数据验证',
|
|
6101
|
+
richOnly: true
|
|
6102
|
+
},
|
|
6103
|
+
{
|
|
6104
|
+
value: 'all-except-borders',
|
|
6105
|
+
label: '边框除外的全部',
|
|
6106
|
+
richOnly: true
|
|
6107
|
+
},
|
|
6108
|
+
{
|
|
6109
|
+
value: 'formulas-and-number-formats',
|
|
6110
|
+
label: '公式和数字格式',
|
|
6111
|
+
richOnly: true
|
|
6112
|
+
},
|
|
6113
|
+
{
|
|
6114
|
+
value: 'values-and-number-formats',
|
|
6115
|
+
label: '值和数字格式',
|
|
6116
|
+
richOnly: true
|
|
6117
|
+
},
|
|
6118
|
+
{
|
|
6119
|
+
value: 'column-widths',
|
|
6120
|
+
label: '列宽',
|
|
6121
|
+
richOnly: true
|
|
6122
|
+
}
|
|
6123
|
+
];
|
|
6124
|
+
const spreadsheetPasteOperationOptions = [
|
|
6125
|
+
{
|
|
6126
|
+
value: 'none',
|
|
6127
|
+
label: '无'
|
|
6128
|
+
},
|
|
6129
|
+
{
|
|
6130
|
+
value: 'add',
|
|
6131
|
+
label: '加'
|
|
6132
|
+
},
|
|
6133
|
+
{
|
|
6134
|
+
value: 'subtract',
|
|
6135
|
+
label: '减'
|
|
6136
|
+
},
|
|
6137
|
+
{
|
|
6138
|
+
value: 'multiply',
|
|
6139
|
+
label: '乘'
|
|
6140
|
+
},
|
|
6141
|
+
{
|
|
6142
|
+
value: 'divide',
|
|
6143
|
+
label: '除'
|
|
6144
|
+
}
|
|
6145
|
+
];
|
|
6146
|
+
const MILLISECONDS_PER_DAY = 86400000;
|
|
6147
|
+
const MINUTES_PER_DAY = 1440;
|
|
6148
|
+
const EXCEL_1900_EPOCH_UTC = Date.UTC(1899, 11, 30);
|
|
6149
|
+
function spreadsheetDateTimeEntry(kind, now) {
|
|
6150
|
+
if (!Number.isFinite(now.getTime())) return null;
|
|
6151
|
+
if ('date' === kind) {
|
|
6152
|
+
const year = now.getFullYear();
|
|
6153
|
+
const month = now.getMonth();
|
|
6154
|
+
const day = now.getDate();
|
|
6155
|
+
const value = (Date.UTC(year, month, day) - EXCEL_1900_EPOCH_UTC) / MILLISECONDS_PER_DAY;
|
|
6156
|
+
if (!Number.isFinite(value)) return null;
|
|
6157
|
+
return {
|
|
6158
|
+
format: {
|
|
6159
|
+
fa: 'yyyy-MM-dd',
|
|
6160
|
+
t: 'd'
|
|
6161
|
+
},
|
|
6162
|
+
formulaBarValue: `${padDatePart(year, 4)}-${padDatePart(month + 1)}-${padDatePart(day)}`,
|
|
6163
|
+
value
|
|
6164
|
+
};
|
|
6165
|
+
}
|
|
6166
|
+
if ('time' !== kind) return null;
|
|
6167
|
+
const hours = now.getHours();
|
|
6168
|
+
const minutes = now.getMinutes();
|
|
6169
|
+
return {
|
|
6170
|
+
format: {
|
|
6171
|
+
fa: 'hh:mm',
|
|
6172
|
+
t: 'd'
|
|
6173
|
+
},
|
|
6174
|
+
formulaBarValue: `${padDatePart(hours)}:${padDatePart(minutes)}`,
|
|
6175
|
+
value: (60 * hours + minutes) / MINUTES_PER_DAY
|
|
6176
|
+
};
|
|
6177
|
+
}
|
|
6178
|
+
function createSpreadsheetDateTimeExtension() {
|
|
6179
|
+
return createOfficeEditorExtension({
|
|
6180
|
+
name: 'spreadsheetDateTime',
|
|
6181
|
+
addCommands: ()=>({
|
|
6182
|
+
insertCurrentDateTime: {
|
|
6183
|
+
canExecute: (context, kind)=>isSpreadsheetDateTimeKind(kind) && null !== spreadsheetDateTimeTarget(context),
|
|
6184
|
+
execute: insertCurrentSpreadsheetDateTime
|
|
6185
|
+
}
|
|
6186
|
+
}),
|
|
6187
|
+
addKeyboardShortcuts: ()=>({
|
|
6188
|
+
[spreadsheetCommandCatalog.insertCurrentDate.shortcut.editor["0"]]: ({ can, commands }, event)=>runSpreadsheetDateTimeShortcut(event, 'date', can.insertCurrentDateTime, commands.insertCurrentDateTime),
|
|
6189
|
+
[spreadsheetCommandCatalog.insertCurrentTime.shortcut.editor["0"]]: ({ can, commands }, event)=>runSpreadsheetDateTimeShortcut(event, 'time', can.insertCurrentDateTime, commands.insertCurrentDateTime)
|
|
6190
|
+
})
|
|
6191
|
+
});
|
|
6192
|
+
}
|
|
6193
|
+
function insertCurrentSpreadsheetDateTime(context, kind) {
|
|
6194
|
+
if (!isSpreadsheetDateTimeKind(kind)) return false;
|
|
6195
|
+
const target = spreadsheetDateTimeTarget(context);
|
|
6196
|
+
const entry = spreadsheetDateTimeEntry(kind, new Date());
|
|
6197
|
+
if (!target || !entry || !context.workbook) return false;
|
|
6198
|
+
try {
|
|
6199
|
+
context.workbook.batchCallApis([
|
|
6200
|
+
{
|
|
6201
|
+
name: 'setCellValuesByRange',
|
|
6202
|
+
args: [
|
|
6203
|
+
[
|
|
6204
|
+
[
|
|
6205
|
+
entry.value
|
|
6206
|
+
]
|
|
6207
|
+
],
|
|
6208
|
+
target.range,
|
|
6209
|
+
{
|
|
6210
|
+
id: target.sheetId
|
|
6211
|
+
}
|
|
6212
|
+
]
|
|
6213
|
+
},
|
|
6214
|
+
{
|
|
6215
|
+
name: 'setCellFormatByRange',
|
|
6216
|
+
args: [
|
|
6217
|
+
'ct',
|
|
6218
|
+
entry.format,
|
|
6219
|
+
target.range,
|
|
6220
|
+
{
|
|
6221
|
+
id: target.sheetId
|
|
6222
|
+
}
|
|
6223
|
+
]
|
|
6224
|
+
}
|
|
6225
|
+
]);
|
|
6226
|
+
} catch {
|
|
6227
|
+
return false;
|
|
6228
|
+
}
|
|
6229
|
+
try {
|
|
6230
|
+
context.formulaBar?.setValue(entry.formulaBarValue);
|
|
6231
|
+
} catch {}
|
|
6232
|
+
return true;
|
|
6233
|
+
}
|
|
6234
|
+
function spreadsheetDateTimeTarget(context) {
|
|
6235
|
+
const workbook = context.workbook;
|
|
6236
|
+
const sheetId = context.targetSheetId;
|
|
6237
|
+
if (!context.editable || !workbook || !sheetId || sheetId !== context.activeSheetId) return null;
|
|
6238
|
+
try {
|
|
6239
|
+
const selection = finiteSpreadsheetSelection(workbook.getSelection()?.at(-1) ?? context.fallbackRange);
|
|
6240
|
+
const row = selection.row_focus ?? selection.row[0] ?? 0;
|
|
6241
|
+
const column = selection.column_focus ?? selection.column[0] ?? 0;
|
|
6242
|
+
if (!Number.isSafeInteger(row) || row < 0 || row >= MAX_SPREADSHEET_ROWS || !Number.isSafeInteger(column) || column < 0 || column >= 16384) return null;
|
|
6243
|
+
const range = {
|
|
6244
|
+
row: [
|
|
6245
|
+
row,
|
|
6246
|
+
row
|
|
6247
|
+
],
|
|
6248
|
+
column: [
|
|
6249
|
+
column,
|
|
6250
|
+
column
|
|
6251
|
+
]
|
|
6252
|
+
};
|
|
6253
|
+
const sheet = context.content.sheets.find((candidate)=>candidate.id === sheetId);
|
|
6254
|
+
return canMutateSpreadsheetCellRange(sheet, range) ? {
|
|
6255
|
+
range,
|
|
6256
|
+
sheetId
|
|
6257
|
+
} : null;
|
|
6258
|
+
} catch {
|
|
6259
|
+
return null;
|
|
6260
|
+
}
|
|
6261
|
+
}
|
|
6262
|
+
function runSpreadsheetDateTimeShortcut(event, kind, canExecute, execute) {
|
|
6263
|
+
if (event.repeat || event.isComposing || isOfficeShortcutBlocked(event.target) || isSpreadsheetNativeTextUndoTarget(event.target) || !isSpreadsheetGridKeyboardTarget(event.target) || !canExecute(kind)) return false;
|
|
6264
|
+
return execute(kind);
|
|
6265
|
+
}
|
|
6266
|
+
function isSpreadsheetDateTimeKind(value) {
|
|
6267
|
+
return 'date' === value || 'time' === value;
|
|
6268
|
+
}
|
|
6269
|
+
function padDatePart(value, length = 2) {
|
|
6270
|
+
return String(value).padStart(length, '0');
|
|
6271
|
+
}
|
|
6039
6272
|
function canApplySpreadsheetCellMerge(sheet, range, command) {
|
|
6040
6273
|
if (!sheet) return false;
|
|
6041
6274
|
const normalized = normalizeSpreadsheetCellMergeRange(range);
|
|
@@ -8368,6 +8601,7 @@ function createSpreadsheetEditorExtensions() {
|
|
|
8368
8601
|
createSpreadsheetCellBorderExtension(),
|
|
8369
8602
|
createSpreadsheetCellStyleExtension(),
|
|
8370
8603
|
createSpreadsheetNumberFormatExtension(),
|
|
8604
|
+
createSpreadsheetDateTimeExtension(),
|
|
8371
8605
|
createSpreadsheetNavigationExtension(),
|
|
8372
8606
|
createSpreadsheetDataValidationExtension(),
|
|
8373
8607
|
createSpreadsheetHyperlinkExtension(),
|
|
@@ -10721,6 +10955,73 @@ function SpreadsheetUnderlineGlyph({ style }) {
|
|
|
10721
10955
|
})
|
|
10722
10956
|
});
|
|
10723
10957
|
}
|
|
10958
|
+
function SpreadsheetDateTimeMenu({ can, commands }) {
|
|
10959
|
+
const items = [
|
|
10960
|
+
{
|
|
10961
|
+
definition: spreadsheetCommandCatalog.insertCurrentDate,
|
|
10962
|
+
icon: /*#__PURE__*/ jsx(CalendarDays, {
|
|
10963
|
+
size: 16
|
|
10964
|
+
}),
|
|
10965
|
+
kind: 'date'
|
|
10966
|
+
},
|
|
10967
|
+
{
|
|
10968
|
+
definition: spreadsheetCommandCatalog.insertCurrentTime,
|
|
10969
|
+
icon: /*#__PURE__*/ jsx(Clock, {
|
|
10970
|
+
size: 16
|
|
10971
|
+
}),
|
|
10972
|
+
kind: 'time'
|
|
10973
|
+
}
|
|
10974
|
+
];
|
|
10975
|
+
const disabled = items.every(({ kind })=>!can.insertCurrentDateTime(kind));
|
|
10976
|
+
return /*#__PURE__*/ jsx(Popover, {
|
|
10977
|
+
label: "日期和时间",
|
|
10978
|
+
panelLabel: "插入日期和时间",
|
|
10979
|
+
panelRole: "menu",
|
|
10980
|
+
portal: true,
|
|
10981
|
+
className: "work-spreadsheet-ribbon-menu-root",
|
|
10982
|
+
panelClassName: "work-office-context-menu work-spreadsheet-ribbon-menu",
|
|
10983
|
+
disabled: disabled,
|
|
10984
|
+
focusFirstOnOpen: true,
|
|
10985
|
+
onPanelKeyDown: moveOfficeMenuFocus,
|
|
10986
|
+
trigger: (triggerProps, { open })=>/*#__PURE__*/ jsxs("button", {
|
|
10987
|
+
...triggerProps,
|
|
10988
|
+
className: `with-label work-spreadsheet-ribbon-menu-trigger work-spreadsheet-date-time-trigger${open ? ' active' : ''}`,
|
|
10989
|
+
title: "插入当前日期或时间(Ctrl+; / Ctrl+Shift+;)",
|
|
10990
|
+
children: [
|
|
10991
|
+
/*#__PURE__*/ jsx(CalendarClock, {
|
|
10992
|
+
size: 19
|
|
10993
|
+
}),
|
|
10994
|
+
/*#__PURE__*/ jsx("span", {
|
|
10995
|
+
children: "日期和时间"
|
|
10996
|
+
})
|
|
10997
|
+
]
|
|
10998
|
+
}),
|
|
10999
|
+
children: (close)=>items.map(({ definition, icon, kind })=>/*#__PURE__*/ jsxs("button", {
|
|
11000
|
+
type: "button",
|
|
11001
|
+
role: "menuitem",
|
|
11002
|
+
tabIndex: -1,
|
|
11003
|
+
"aria-label": definition.label,
|
|
11004
|
+
"aria-keyshortcuts": definition.shortcut.aria,
|
|
11005
|
+
disabled: !can.insertCurrentDateTime(kind),
|
|
11006
|
+
onClick: ()=>{
|
|
11007
|
+
close();
|
|
11008
|
+
commands.insertCurrentDateTime(kind);
|
|
11009
|
+
},
|
|
11010
|
+
children: [
|
|
11011
|
+
/*#__PURE__*/ jsx("span", {
|
|
11012
|
+
className: "work-spreadsheet-ribbon-menu-item-icon",
|
|
11013
|
+
children: icon
|
|
11014
|
+
}),
|
|
11015
|
+
/*#__PURE__*/ jsx("span", {
|
|
11016
|
+
children: definition.label
|
|
11017
|
+
}),
|
|
11018
|
+
/*#__PURE__*/ jsx("kbd", {
|
|
11019
|
+
children: definition.shortcut.label
|
|
11020
|
+
})
|
|
11021
|
+
]
|
|
11022
|
+
}, definition.id))
|
|
11023
|
+
});
|
|
11024
|
+
}
|
|
10724
11025
|
const spreadsheetNumberFormatOptions = [
|
|
10725
11026
|
{
|
|
10726
11027
|
value: 'general',
|
|
@@ -10918,16 +11219,25 @@ function SpreadsheetNumberRibbonGroup({ can, commands, toolbarCell }) {
|
|
|
10918
11219
|
label: "数字",
|
|
10919
11220
|
priority: "high",
|
|
10920
11221
|
children: [
|
|
10921
|
-
/*#__PURE__*/
|
|
10922
|
-
className: "work-spreadsheet-number-format",
|
|
10923
|
-
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
|
|
10927
|
-
|
|
10928
|
-
|
|
10929
|
-
|
|
10930
|
-
|
|
11222
|
+
/*#__PURE__*/ jsxs("div", {
|
|
11223
|
+
className: "work-spreadsheet-number-format-stack",
|
|
11224
|
+
children: [
|
|
11225
|
+
/*#__PURE__*/ jsx(OfficeSelect, {
|
|
11226
|
+
className: "work-spreadsheet-number-format",
|
|
11227
|
+
ariaLabel: "数字格式",
|
|
11228
|
+
value: numberFormatPreset,
|
|
11229
|
+
disabled: !can.setCellFormat('ct', currentNumberFormatValue),
|
|
11230
|
+
options: spreadsheetNumberFormatOptions,
|
|
11231
|
+
onValueChange: (preset)=>{
|
|
11232
|
+
if ('custom' === preset) return;
|
|
11233
|
+
commands.setCellFormat('ct', spreadsheetNumberFormatValue(spreadsheetNumberFormatCode(preset), toolbarCell));
|
|
11234
|
+
}
|
|
11235
|
+
}),
|
|
11236
|
+
/*#__PURE__*/ jsx(SpreadsheetDateTimeMenu, {
|
|
11237
|
+
can: can,
|
|
11238
|
+
commands: commands
|
|
11239
|
+
})
|
|
11240
|
+
]
|
|
10931
11241
|
}),
|
|
10932
11242
|
/*#__PURE__*/ jsx(WorkOfficeRibbonButton, {
|
|
10933
11243
|
label: `${currencyDefinition.label}格式`,
|
|
@@ -13784,81 +14094,6 @@ function formatCellsSelectionDescription(source) {
|
|
|
13784
14094
|
const columns = source.range.column[1] - source.range.column[0] + 1;
|
|
13785
14095
|
return `设置当前选区的数字、对齐、字体、边框、填充和保护属性(${rows} 行 × ${columns} 列)。`;
|
|
13786
14096
|
}
|
|
13787
|
-
const MAX_SPREADSHEET_ROWS = 1048576;
|
|
13788
|
-
const spreadsheetPasteContentOptions = [
|
|
13789
|
-
{
|
|
13790
|
-
value: 'all',
|
|
13791
|
-
label: '全部',
|
|
13792
|
-
richOnly: false
|
|
13793
|
-
},
|
|
13794
|
-
{
|
|
13795
|
-
value: 'formulas',
|
|
13796
|
-
label: '公式',
|
|
13797
|
-
richOnly: false
|
|
13798
|
-
},
|
|
13799
|
-
{
|
|
13800
|
-
value: 'values',
|
|
13801
|
-
label: '值',
|
|
13802
|
-
richOnly: false
|
|
13803
|
-
},
|
|
13804
|
-
{
|
|
13805
|
-
value: 'formats',
|
|
13806
|
-
label: '格式',
|
|
13807
|
-
richOnly: true
|
|
13808
|
-
},
|
|
13809
|
-
{
|
|
13810
|
-
value: 'comments',
|
|
13811
|
-
label: '批注',
|
|
13812
|
-
richOnly: true
|
|
13813
|
-
},
|
|
13814
|
-
{
|
|
13815
|
-
value: 'validation',
|
|
13816
|
-
label: '数据验证',
|
|
13817
|
-
richOnly: true
|
|
13818
|
-
},
|
|
13819
|
-
{
|
|
13820
|
-
value: 'all-except-borders',
|
|
13821
|
-
label: '边框除外的全部',
|
|
13822
|
-
richOnly: true
|
|
13823
|
-
},
|
|
13824
|
-
{
|
|
13825
|
-
value: 'formulas-and-number-formats',
|
|
13826
|
-
label: '公式和数字格式',
|
|
13827
|
-
richOnly: true
|
|
13828
|
-
},
|
|
13829
|
-
{
|
|
13830
|
-
value: 'values-and-number-formats',
|
|
13831
|
-
label: '值和数字格式',
|
|
13832
|
-
richOnly: true
|
|
13833
|
-
},
|
|
13834
|
-
{
|
|
13835
|
-
value: 'column-widths',
|
|
13836
|
-
label: '列宽',
|
|
13837
|
-
richOnly: true
|
|
13838
|
-
}
|
|
13839
|
-
];
|
|
13840
|
-
const spreadsheetPasteOperationOptions = [
|
|
13841
|
-
{
|
|
13842
|
-
value: 'none',
|
|
13843
|
-
label: '无'
|
|
13844
|
-
},
|
|
13845
|
-
{
|
|
13846
|
-
value: 'add',
|
|
13847
|
-
label: '加'
|
|
13848
|
-
},
|
|
13849
|
-
{
|
|
13850
|
-
value: 'subtract',
|
|
13851
|
-
label: '减'
|
|
13852
|
-
},
|
|
13853
|
-
{
|
|
13854
|
-
value: 'multiply',
|
|
13855
|
-
label: '乘'
|
|
13856
|
-
},
|
|
13857
|
-
{
|
|
13858
|
-
value: 'divide',
|
|
13859
|
-
label: '除'
|
|
13860
|
-
}
|
|
13861
|
-
];
|
|
13862
14097
|
function captureSpreadsheetClipboardSnapshot(content, sheetId, selection, plainText) {
|
|
13863
14098
|
const range = spreadsheet_cell_range_normalizeSpreadsheetCellRange(selection);
|
|
13864
14099
|
const sheet = content.sheets.find((candidate)=>candidate.id === sheetId);
|
|
@@ -23988,6 +24223,7 @@ function spreadsheetCommandsWithGridFocus(commands, restoreFocus) {
|
|
|
23988
24223
|
deleteSelectedStructure: afterSuccessfulCommand(commands.deleteSelectedStructure),
|
|
23989
24224
|
fillSelectedCells: afterSuccessfulCommand(commands.fillSelectedCells),
|
|
23990
24225
|
insertSelectedStructure: afterSuccessfulCommand(commands.insertSelectedStructure),
|
|
24226
|
+
insertCurrentDateTime: afterSuccessfulCommand(commands.insertCurrentDateTime),
|
|
23991
24227
|
mergeSelectedCells: afterSuccessfulCommand(commands.mergeSelectedCells),
|
|
23992
24228
|
openPasteSpecial: afterSuccessfulCommand(commands.openPasteSpecial),
|
|
23993
24229
|
pasteSelection: afterSuccessfulCommand(commands.pasteSelection),
|
|
@@ -364,6 +364,34 @@ export declare const spreadsheetCommandCatalog: {
|
|
|
364
364
|
readonly group: "number";
|
|
365
365
|
};
|
|
366
366
|
};
|
|
367
|
+
readonly insertCurrentDate: {
|
|
368
|
+
readonly id: "number.insertCurrentDate";
|
|
369
|
+
readonly label: "插入当前日期";
|
|
370
|
+
readonly location: {
|
|
371
|
+
readonly area: "ribbon";
|
|
372
|
+
readonly tab: "home";
|
|
373
|
+
readonly group: "number";
|
|
374
|
+
};
|
|
375
|
+
readonly shortcut: {
|
|
376
|
+
readonly label: "Ctrl+;";
|
|
377
|
+
readonly aria: "Control+;";
|
|
378
|
+
readonly editor: readonly ["Control-;"];
|
|
379
|
+
};
|
|
380
|
+
};
|
|
381
|
+
readonly insertCurrentTime: {
|
|
382
|
+
readonly id: "number.insertCurrentTime";
|
|
383
|
+
readonly label: "插入当前时间";
|
|
384
|
+
readonly location: {
|
|
385
|
+
readonly area: "ribbon";
|
|
386
|
+
readonly tab: "home";
|
|
387
|
+
readonly group: "number";
|
|
388
|
+
};
|
|
389
|
+
readonly shortcut: {
|
|
390
|
+
readonly label: "Ctrl+Shift+;";
|
|
391
|
+
readonly aria: "Control+Shift+;";
|
|
392
|
+
readonly editor: readonly ["Control-Shift-;"];
|
|
393
|
+
};
|
|
394
|
+
};
|
|
367
395
|
readonly formatCells: {
|
|
368
396
|
readonly id: "number.formatCells";
|
|
369
397
|
readonly label: "设置单元格格式";
|
|
@@ -11,6 +11,7 @@ import type { SpreadsheetCellRange } from './spreadsheet-cell-range';
|
|
|
11
11
|
import type { SpreadsheetCellStyleChoice } from './spreadsheet-cell-style';
|
|
12
12
|
import type { SpreadsheetCellFillDirection } from './spreadsheet-cell-fill';
|
|
13
13
|
import { type SpreadsheetFontSizeDirection } from './spreadsheet-font-size-command';
|
|
14
|
+
import { type SpreadsheetDateTimeKind } from './spreadsheet-date-time-command';
|
|
14
15
|
import type { SpreadsheetDataValidationRequest, SpreadsheetDataValidationTarget } from './spreadsheet-data-validation';
|
|
15
16
|
import { type SpreadsheetCellMergeCommand } from './spreadsheet-cell-merge';
|
|
16
17
|
import type { SpreadsheetFormatPainterMode } from './spreadsheet-format-painter';
|
|
@@ -169,6 +170,7 @@ export interface SpreadsheetEditorCommands {
|
|
|
169
170
|
fillSelectedCells: (direction: SpreadsheetCellFillDirection) => boolean;
|
|
170
171
|
hideSheet: (sheetId: string) => boolean;
|
|
171
172
|
insertSelectedStructure: (axis: SpreadsheetStructureAxis, position: SpreadsheetStructureInsertPosition) => boolean;
|
|
173
|
+
insertCurrentDateTime: (kind: SpreadsheetDateTimeKind) => boolean;
|
|
172
174
|
mergeSelectedCells: (command: SpreadsheetCellMergeCommand) => boolean;
|
|
173
175
|
moveSheet: (sheetId: string, direction: SpreadsheetSheetMoveDirection) => boolean;
|
|
174
176
|
moveSelection: (move: SpreadsheetSelectionMove, extend: boolean) => boolean;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Cell } from '@fortune-sheet/core';
|
|
2
|
+
import type { SpreadsheetCommandContext, SpreadsheetEditorCommands } from './spreadsheet-command-controller';
|
|
3
|
+
import { type OfficeEditorExtension } from './office-editor-extension';
|
|
4
|
+
export type SpreadsheetDateTimeKind = 'date' | 'time';
|
|
5
|
+
export interface SpreadsheetDateTimeEntry {
|
|
6
|
+
format: NonNullable<Cell['ct']> & {
|
|
7
|
+
fa: string;
|
|
8
|
+
t: string;
|
|
9
|
+
};
|
|
10
|
+
formulaBarValue: string;
|
|
11
|
+
value: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function spreadsheetDateTimeEntry(kind: SpreadsheetDateTimeKind, now: Date): SpreadsheetDateTimeEntry | null;
|
|
14
|
+
export declare function createSpreadsheetDateTimeExtension(): OfficeEditorExtension<SpreadsheetCommandContext, SpreadsheetEditorCommands>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SpreadsheetEditorCanCommands, SpreadsheetEditorCommands } from './spreadsheet-command-controller';
|
|
2
|
+
type SpreadsheetDateTimeCanCommands = Pick<SpreadsheetEditorCanCommands, 'insertCurrentDateTime'>;
|
|
3
|
+
type SpreadsheetDateTimeCommands = Pick<SpreadsheetEditorCommands, 'insertCurrentDateTime'>;
|
|
4
|
+
export declare function SpreadsheetDateTimeMenu({ can, commands, }: {
|
|
5
|
+
can: SpreadsheetDateTimeCanCommands;
|
|
6
|
+
commands: SpreadsheetDateTimeCommands;
|
|
7
|
+
}): import("react").JSX.Element;
|
|
8
|
+
export {};
|
package/dist/office-kernel.wasm
CHANGED
|
Binary file
|
package/dist/styles.css
CHANGED
|
@@ -13885,6 +13885,41 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
|
|
|
13885
13885
|
min-width: 94px;
|
|
13886
13886
|
}
|
|
13887
13887
|
|
|
13888
|
+
.work-spreadsheet-number-format-stack {
|
|
13889
|
+
flex-direction: column;
|
|
13890
|
+
flex: 0 0 94px;
|
|
13891
|
+
gap: 2px;
|
|
13892
|
+
width: 94px;
|
|
13893
|
+
height: 51px;
|
|
13894
|
+
display: flex;
|
|
13895
|
+
}
|
|
13896
|
+
|
|
13897
|
+
.work-spreadsheet-number-format-stack > .work-spreadsheet-ribbon-menu-root {
|
|
13898
|
+
width: 94px;
|
|
13899
|
+
min-width: 0;
|
|
13900
|
+
}
|
|
13901
|
+
|
|
13902
|
+
.work-office-ribbon .work-office-toolbar .work-spreadsheet-number-format-stack .work-spreadsheet-date-time-trigger.with-label {
|
|
13903
|
+
flex-direction: row;
|
|
13904
|
+
justify-content: flex-start;
|
|
13905
|
+
gap: 4px;
|
|
13906
|
+
width: 94px;
|
|
13907
|
+
min-width: 94px;
|
|
13908
|
+
height: 21px;
|
|
13909
|
+
padding: 0 6px;
|
|
13910
|
+
}
|
|
13911
|
+
|
|
13912
|
+
.work-office-ribbon .work-office-toolbar .work-spreadsheet-number-format-stack .work-spreadsheet-date-time-trigger.with-label > svg {
|
|
13913
|
+
width: 14px;
|
|
13914
|
+
height: 14px;
|
|
13915
|
+
}
|
|
13916
|
+
|
|
13917
|
+
.work-office-ribbon .work-office-toolbar .work-spreadsheet-number-format-stack .work-spreadsheet-date-time-trigger.with-label > span {
|
|
13918
|
+
max-width: 66px;
|
|
13919
|
+
font-size: 9px;
|
|
13920
|
+
line-height: 11px;
|
|
13921
|
+
}
|
|
13922
|
+
|
|
13888
13923
|
.work-spreadsheet-workbook-panel {
|
|
13889
13924
|
z-index: 8;
|
|
13890
13925
|
border-left: 1px solid var(--a3s-line);
|
|
@@ -47,17 +47,17 @@ model:
|
|
|
47
47
|
and compacts low-priority, then normal-priority groups before exposing group
|
|
48
48
|
paging. It can remain collapsed; activating a tab temporarily overlays that
|
|
49
49
|
tab's commands without moving the document, and an outside pointer action
|
|
50
|
-
returns to the compact row. Writer routes its catalogued
|
|
50
|
+
returns to the compact row. Writer routes its catalogued Traditional Office font-size,
|
|
51
51
|
alignment, line-spacing, heading, spelling, field-refresh, comment, and
|
|
52
52
|
track-changes shortcuts only while the document surface owns the event. The
|
|
53
|
-
status route uses the same catalog for
|
|
53
|
+
status route uses the same catalog for Traditional Office word count, opening live page,
|
|
54
54
|
word, character, and paragraph details from either `Ctrl+Shift+G` or the
|
|
55
|
-
visible count. Its local formatting clipboard powers
|
|
55
|
+
visible count. Its local formatting clipboard powers Traditional Office copy-format and
|
|
56
56
|
paste-format shortcuts
|
|
57
57
|
plus a one-shot format painter without requiring browser clipboard access;
|
|
58
58
|
paste replaces only direct character and paragraph formatting, preserving
|
|
59
59
|
links, comments, and revision semantics in one document transaction.
|
|
60
|
-
Header and footer TipTap surfaces register the same
|
|
60
|
+
Header and footer TipTap surfaces register the same Traditional Office alignment and
|
|
61
61
|
copy-format shortcuts. Cross-surface paste retains compatible marks and
|
|
62
62
|
paragraph attributes while falling back from unsupported heading nodes.
|
|
63
63
|
Writer orders Insert commands as Pages, Table, Illustrations, Links, Header
|
|
@@ -105,11 +105,11 @@ model:
|
|
|
105
105
|
page metrics and scroll viewport. Picture, Table, and Header and Footer tabs
|
|
106
106
|
carry explicit contextual semantics and disappear with their selection. The
|
|
107
107
|
Spreadsheet shell now uses the same responsive ribbon contract with its own
|
|
108
|
-
command catalog and workbook semantics. It keeps the
|
|
108
|
+
command catalog and workbook semantics. It keeps the Traditional Office tab order, places
|
|
109
109
|
Conditional Formatting under Home and Styles, exposes real sorting under
|
|
110
110
|
Data, and owns F9 workbook recalculation in the root-scoped keyboard
|
|
111
111
|
controller. Paste, Cut, and Copy live in the first Home group; both button
|
|
112
|
-
clicks and
|
|
112
|
+
clicks and Traditional Office shortcuts cross one clipboard command port before using the
|
|
113
113
|
permission-resilient browser/local clipboard implementation. Paste Special
|
|
114
114
|
extends that port with a versioned rich snapshot and a pure bounded planner
|
|
115
115
|
instead of delegating mutation to rendered vendor controls. Quick All,
|
|
@@ -136,7 +136,7 @@ model:
|
|
|
136
136
|
`Alt+ArrowDown`. The Fortune adapter only exposes the header trigger and
|
|
137
137
|
value menu, adding dialog, checkbox, focus-restoration, and keyboard
|
|
138
138
|
semantics without making vendor DOM text the command contract. Freeze Panes
|
|
139
|
-
also stays controlled: a pure model translates the current
|
|
139
|
+
also stays controlled: a pure model translates the current Traditional Office cell into
|
|
140
140
|
rows above and columns left or applies top-row and first-column presets, a
|
|
141
141
|
typed View command performs one immutable workbook update, and the native
|
|
142
142
|
Fortune/XLSX frozen-pane model remains the render and serialization
|
|
@@ -300,7 +300,7 @@ focus restoration.
|
|
|
300
300
|
| --- | --- | --- | --- |
|
|
301
301
|
| Document | One TipTap/ProseMirror body tree retained across editing and read-only preview, controlled TipTap header/footer surfaces with direct paper-margin editing and a contextual ribbon, one typography and page-chrome baseline across editing, preview, and PDF surfaces, a persistent typed heading-navigation pane with active-selection tracking, filtering and collapsible keyboard traversal, host-owned selected-text menus with full document context and range-mapped async commands, responsive and keyboard-operated paragraph-style and list galleries, typed bullet and numbering commands with restart/continue/start controls, typed physical-page and section-page descriptors, repeated first/default/even page chrome, a versioned structured model with an HTML compatibility representation, prefix-reused visual-line measurement and pages, page decorations, page-aware horizontal and vertical rulers for page margins, paragraph indents and typed tab stops, structured list-item pagination, explicit paragraph and list-item direction, compact spacing and pagination controls, typed inline/square/tight/through/top-and-bottom/no-wrap image layout and floating-image drawing layers, imported style-inherited paragraph properties, structured inline tabs, and theme-aware run font/size/color/background import | Worker plus resumable Rust/WASM flow pagination and Rustybuzz shaping across CSS-matched registered text runs; the same live result remains mounted in read-only preview and is consumed by bounded browser PDF capture, including eligible list paragraphs, Unicode bidi level segmentation, ordered per-grapheme font fallback, packaged Latin/CJK/Arabic/Hebrew faces, and structured left-to-right tabs, with explicit DOM and JavaScript fallbacks for text affected by supported floats | Language-complete font substitution, complete Word style and numbering coverage, locale-complete and bidirectional tabs, arbitrary floating-object geometry and non-image drawing layers, complex table flow, searchable/vector PDF output, and loss-preserving OOXML package state |
|
|
302
302
|
| Markdown | TipTap visual editing with a resizable source-and-preview split view by default, source-aware ribbon formatting and shortcuts, bounded source-native history with coalesced typing and selection restoration, host-defined selection menus across both editing surfaces, GFM tables, strikethrough, autolinks and nested task lists, controlled source state, coalesced preview rebuilds, proportional pane scrolling, keyboard-adjustable pane sizing, a flat measure-bounded reading surface, optional visual or source-only views, and a full-workspace Source/Preview switch on phones | No kernel required for normal editing | CommonMark differential fixtures, multi-megabyte profiling, and an off-main-thread parser boundary when measurements justify it |
|
|
303
|
-
| Spreadsheet | Fortune Sheet grid integrated with the shared Office shell,
|
|
303
|
+
| Spreadsheet | Fortune Sheet grid integrated with the shared Office shell, an Office-oriented command catalog and tab order, quick-access Undo and Redo, a priority-aware adaptive and collapsible ribbon with temporary tab expansion, Home and Styles Conditional Formatting, Home and Cells row/column insertion and deletion through the shared typed structure commands, Home and Alignment Merge and Center plus Merge Cells, Merge Across, Unmerge Cells, and Unmerge and Fill through one native-model-backed controlled batch per intent and the Traditional Office `Ctrl+M` shortcut, Home and Font native strikethrough through the same typed formatting command and Traditional Office `Cmd/Ctrl+5`, Home and Editing Clear All, Formats, Contents, Comments, and Hyperlinks with Delete/Backspace mapped to content-only clearing and merge geometry retained, Data sorting and AutoFilter with bounded current-region discovery, controlled filter state, Traditional Office toggle and header-menu shortcuts, and accessible vendor menu semantics, View and Window Freeze Panes with Traditional Office current-cell, top-row, first-column, and unfreeze patterns backed by controlled state and native XLSX frozen panes, Formulas and F9 workbook recalculation, an executable Home clipboard group with permission-resilient Paste, Cut, and Copy plus an Office-style one-shot and locked Format Painter for bounded cross-sheet native-style patterns, shared grid/formula/footer visual tokens and one spreadsheet accent across selection, sheet tabs, menus, and zoom, an A3S-owned accessible single-row workbook footer for creation, activation, rename, duplicate, color, hide, reorder, delete, selection status, and zoom, a resize-observed worksheet viewport that keeps the active tab and its touch action visible across desktop, compact, and phone-width changes, one cell/worksheet context-menu surface whose displayed accelerators remain executable while the menu owns focus, Arrow/Home/End tab navigation plus Shift+F10 and native context-menu access, typed editing and calculation command ports, A3S-owned deterministic Arrow, Enter, Tab, Home, PageUp/PageDown, extended-selection, row, column, and all-cells keyboard commands, selection-preserving focus restoration across controlled workbook remounts and F2/Escape editing transitions, Cmd/Ctrl formatting, undo/redo, clear, a permission-resilient editor-local clipboard fallback, Shift+F11 sheet creation, and Ctrl/Cmd+PageUp/PageDown sheet-navigation shortcuts, direct font-family, horizontal/vertical-alignment, text-wrap, general/number/percent, and decimal-place controls backed by native cell-style keys, live count/sum/average selection summaries, operation-driven sparse-workbook projection, guarded controlled-value remounts that reject stale engine callbacks, and no-history result patches with cell-scoped Fortune fallback | Versioned, cancellable Worker/Rust-WASM calculation sessions using the shared bounded Rust formula parser, retained formula ASTs, incremental forward/reverse dependency graphs, dirty-subgraph recalculation, cross-sheet references, and a dynamically loaded JavaScript fallback | A3S-owned virtual grid, moving replacement projection off the main thread, broader Excel formula semantics, A3S-owned custom number-format evaluation, and print layout |
|
|
304
304
|
| Presentation | Scene canvas with ordered typed multi-selection, persistent nested browser groups, native PPTX group-node export, exact keyboard-accessible table-dimension insertion, native slide/object context actions with optional AI actions, a separate object/content editing state, one on-demand TipTap instance, collective move/scale/nudge/clipboard/delete/layer commands, selection-bound alignment and distribution, typed group/ungroup commands, one typed dispatcher for ribbon commands, editor-scoped shortcuts with post-command selection focus, direct beginning/current-slide playback with fullscreen fallback, frame-coalesced transactional move/resize previews that commit once on pointer release, two-level thumbnail node and scene windowing, and a phone stage that top-aligns the primary canvas while retaining one readable slide indicator beside view and zoom controls | Revisioned, cancellable Worker/Rust-WASM slide-relative alignment and object-set snapping with typed visual guides and a JavaScript fallback | Arbitrary rotated or reflected PPTX group transforms, connectors, theme resolution, text fitting, kernel-owned thumbnail layout, and slide serialization |
|
|
305
305
|
| PDF | PDFium-backed page rendering with an A3S-owned responsive toolbar, a scrollable page-thumbnail rail with active-page synchronization and bounded bitmap/DOM windowing, a focus-contained phone page drawer, and typed capability controllers for navigation, zoom, search, basic annotations, annotation color, opacity, compatible stroke-width defaults and selection updates, history, and save; page and search drafts cancel without accidental commands, shortcuts remain scoped to the PDF root, and compact widths retain page status while exposing search-result traversal, navigation, zoom, and history through the keyboard-operated overflow menu | PDFium WebAssembly | Forms, redaction review, page organization, and reopen fixtures |
|
|
306
306
|
|
|
@@ -635,7 +635,7 @@ The current browser-kernel slice collects contiguous geometry-affecting text
|
|
|
635
635
|
runs from eligible paragraphs. Each run carries an ordered registered font
|
|
636
636
|
stack, size, line height, letter spacing, ligature, and kerning behavior. Font
|
|
637
637
|
families and normal/italic styles remain exact; numeric weights follow the CSS
|
|
638
|
-
Fonts matching order so
|
|
638
|
+
Fonts matching order so Office-style values such as 680 or 730 select a registered
|
|
639
639
|
700 face. When a family has only one normal-style weight, the same face
|
|
640
640
|
provides deterministic metrics for browser-synthesized bold text. The kernel
|
|
641
641
|
selects a face for each grapheme, joins adjacent selections that use the same
|
|
@@ -816,13 +816,13 @@ numbering settings. Reversed lists, per-item `value` overrides, native Word
|
|
|
816
816
|
list-identity continuation, arbitrary multilevel templates, and loss-preserving
|
|
817
817
|
custom numbering formats remain later fidelity gates.
|
|
818
818
|
|
|
819
|
-
The declared direct-formatting layout slice now has a real
|
|
819
|
+
The declared direct-formatting layout slice now has a real Traditional Office Writer reference
|
|
820
820
|
gate. Its deterministic A4 fixture uses installed Arial runs, explicit OOXML
|
|
821
821
|
paragraph spacing, a fixed centered table, direct cell fills and borders, and
|
|
822
822
|
physical cell margins. Automatic `w:line` values retain their original OOXML
|
|
823
|
-
multiples for export while the browser applies the measured
|
|
823
|
+
multiples for export while the browser applies the measured Traditional Office single-line
|
|
824
824
|
font metric; imported tables no longer receive editor-only block margins. The
|
|
825
|
-
Windows parity workflow exports the same fixture through
|
|
825
|
+
Windows parity workflow exports the same fixture through Traditional Office, captures both
|
|
826
826
|
794 by 1123 CSS-pixel pages, and rejects page-size, landmark, or bounded pixel
|
|
827
827
|
differences. Language-complete font substitution, variable font axes, the
|
|
828
828
|
remaining character and table style properties, non-image floating-object
|
|
@@ -1181,7 +1181,7 @@ Migration to browser-native OOXML is staged:
|
|
|
1181
1181
|
editing surfaces.
|
|
1182
1182
|
|
|
1183
1183
|
Each stage needs compatibility fixtures, deterministic layout goldens, large
|
|
1184
|
-
document performance budgets, and real Microsoft Office and
|
|
1184
|
+
document performance budgets, and real Microsoft Office and Traditional Office
|
|
1185
1185
|
interoperability evidence before it can be described as fidelity-complete.
|
|
1186
1186
|
|
|
1187
1187
|
## Delivery roadmap
|
|
@@ -1225,7 +1225,7 @@ bundle regression.
|
|
|
1225
1225
|
|
|
1226
1226
|
Exit criteria: deterministic layout goldens for the supported feature set;
|
|
1227
1227
|
incremental reflow does not rebuild unaffected pages; DOCX fixtures round-trip
|
|
1228
|
-
through Microsoft Word and
|
|
1228
|
+
through Microsoft Word and Traditional Office without losing unsupported package parts.
|
|
1229
1229
|
|
|
1230
1230
|
### Stage 3: spreadsheet calculation and virtualization
|
|
1231
1231
|
|
|
@@ -1355,7 +1355,7 @@ window.
|
|
|
1355
1355
|
Exit criteria: object drag and resize stay interactive on complex slides;
|
|
1356
1356
|
partial rich-text formatting survives PPTX round trips; masters, layouts,
|
|
1357
1357
|
themes, tables, charts, links, and notes have compatibility fixtures for
|
|
1358
|
-
PowerPoint and
|
|
1358
|
+
PowerPoint and Traditional Office.
|
|
1359
1359
|
|
|
1360
1360
|
### Stage 5: PDF product surface
|
|
1361
1361
|
|
|
@@ -1415,7 +1415,7 @@ page window rather than the complete file.
|
|
|
1415
1415
|
CLI, MCP server, and Skill.
|
|
1416
1416
|
|
|
1417
1417
|
Exit criteria: import-edit-export fixtures show semantic and package-level
|
|
1418
|
-
round-trip evidence in Microsoft Office and
|
|
1418
|
+
round-trip evidence in Microsoft Office and Traditional Office; unsupported content is
|
|
1419
1419
|
retained or rejected explicitly, never silently discarded.
|
|
1420
1420
|
|
|
1421
1421
|
## Performance gates
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a3s-lab/office",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Open-source collaborative browser editors for documents, Markdown, spreadsheets, presentations, and PDFs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"office",
|
|
@@ -88,6 +88,7 @@
|
|
|
88
88
|
"playground:typecheck": "tsc --noEmit -p playground/tsconfig.json",
|
|
89
89
|
"playground:visual": "playwright test --config playwright.config.ts",
|
|
90
90
|
"playground:visual:spreadsheet-data-validation": "playwright test visual-tests/spreadsheet-data-validation.functional.spec.ts --config playwright.config.ts",
|
|
91
|
+
"playground:visual:spreadsheet-date-time": "playwright test visual-tests/spreadsheet-date-time.functional.spec.ts --config playwright.config.ts",
|
|
91
92
|
"playground:visual:spreadsheet-diagonal-borders": "playwright test visual-tests/spreadsheet-diagonal-borders.functional.spec.ts --config playwright.config.ts",
|
|
92
93
|
"playground:visual:spreadsheet-font-colors-shortcuts": "playwright test visual-tests/spreadsheet-font-colors-shortcuts.functional.spec.ts --config playwright.config.ts",
|
|
93
94
|
"playground:visual:spreadsheet-hyperlink": "playwright test visual-tests/spreadsheet-hyperlink.functional.spec.ts --config playwright.config.ts",
|
|
@@ -160,6 +161,8 @@
|
|
|
160
161
|
"test:e2e:spreadsheet-data-validation:check": "a3s-test check tests/e2e/spreadsheet-data-validation.acl --json",
|
|
161
162
|
"test:e2e:spreadsheet-diagonal-borders": "a3s-test run tests/e2e/spreadsheet-diagonal-borders.acl --json",
|
|
162
163
|
"test:e2e:spreadsheet-diagonal-borders:check": "a3s-test check tests/e2e/spreadsheet-diagonal-borders.acl --json",
|
|
164
|
+
"test:e2e:spreadsheet-date-time": "a3s-test run tests/e2e/spreadsheet-date-time.acl --json",
|
|
165
|
+
"test:e2e:spreadsheet-date-time:check": "a3s-test check tests/e2e/spreadsheet-date-time.acl --json",
|
|
163
166
|
"test:e2e:spreadsheet-hyperlink": "a3s-test run tests/e2e/spreadsheet-hyperlink.acl --json",
|
|
164
167
|
"test:e2e:spreadsheet-hyperlink:check": "a3s-test check tests/e2e/spreadsheet-hyperlink.acl --json",
|
|
165
168
|
"test:e2e:spreadsheet-maximum-sparse": "a3s-test run tests/e2e/spreadsheet-maximum-sparse.acl --json",
|
|
@@ -179,6 +182,7 @@
|
|
|
179
182
|
"test:e2e:writer-status": "a3s-test run tests/e2e/word-status-bar.acl --json",
|
|
180
183
|
"test:e2e:writer-status:check": "a3s-test check tests/e2e/word-status-bar.acl --json",
|
|
181
184
|
"test:wps-layout": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/test-wps-layout-parity.ps1",
|
|
185
|
+
"test:office-layout": "bun run test:wps-layout",
|
|
182
186
|
"test:watch": "rstest --watch",
|
|
183
187
|
"typecheck": "tsc --noEmit"
|
|
184
188
|
},
|