visio-react-viewer 0.4.0 → 0.5.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/dist/index.js +593 -351
- package/dist/types/src/backstage.d.ts +7 -1
- package/dist/types/src/contract.d.ts +1 -1
- package/dist/types/src/controller.d.ts +5 -0
- package/dist/types/src/ribbon.d.ts +3 -2
- package/dist/types/src/styles.d.ts +1 -1
- package/dist/types/src/viewer-backstage.d.ts +2 -5
- package/dist/types/src/viewer-input.d.ts +0 -2
- package/dist/types/src/viewer-options.d.ts +22 -0
- package/dist/types/src/viewer-ruler.d.ts +6 -0
- package/dist/types/src/viewer-search.d.ts +16 -16
- package/dist/types/src/viewer-share.d.ts +20 -0
- package/package.json +4 -4
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import type { OfficeBackstageItem } from 'ooxml-ui/controls';
|
|
1
2
|
/** Visio's File (backstage) pages, in Visio's order. Save and Close act without a page. */
|
|
2
3
|
export declare const BACKSTAGE_ITEMS: readonly [readonly ["info", "Info"], readonly ["new", "New"], readonly ["open", "Open"], readonly ["save", "Save"], readonly ["save-as", "Save As"], readonly ["print", "Print"], readonly ["share", "Share"], readonly ["export", "Export"], readonly ["close", "Close"]];
|
|
3
4
|
export declare const BACKSTAGE_FOOTER: readonly [readonly ["account", "Account"], readonly ["feedback", "Feedback"], readonly ["options", "Options"]];
|
|
4
|
-
export type BackstagePage = Exclude<(typeof BACKSTAGE_ITEMS)[number][0] | (typeof BACKSTAGE_FOOTER)[number][0], 'save' | 'close'>;
|
|
5
|
+
export type BackstagePage = Exclude<(typeof BACKSTAGE_ITEMS)[number][0] | (typeof BACKSTAGE_FOOTER)[number][0], 'save' | 'close' | 'options'>;
|
|
6
|
+
/** The navigation items, with optional disabled states (Save and Close follow the drawing). */
|
|
7
|
+
export declare function backstageItems(state?: Partial<Record<string, {
|
|
8
|
+
disabled: boolean;
|
|
9
|
+
title?: string;
|
|
10
|
+
}>>): OfficeBackstageItem[];
|
|
5
11
|
/**
|
|
6
12
|
* Visio's backstage: a full-window File view with a navigation column and one page per item.
|
|
7
13
|
* Static application structure only; document values are filled in later as text.
|
|
@@ -59,6 +59,11 @@ export declare class ViewerController {
|
|
|
59
59
|
/** Atomic source-backed edits. Core owns protection, dependency and target validation. */
|
|
60
60
|
applyEdits(edits: readonly VisioEdit[]): Promise<void>;
|
|
61
61
|
undo(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Adopt a package from a shared session as one undoable history step. Emits `document-change`
|
|
64
|
+
* with kind `remote`, which a session must not publish back.
|
|
65
|
+
*/
|
|
66
|
+
applyRemoteSource(bytes: Uint8Array): Promise<void>;
|
|
62
67
|
redo(): Promise<void>;
|
|
63
68
|
cancelEdit(): void;
|
|
64
69
|
exportVsdx(): VsdxExportResult;
|
|
@@ -6,7 +6,8 @@ export type { VisioRibbonAction } from './ribbon-action.js';
|
|
|
6
6
|
export declare const RIBBON_TABS: readonly [readonly ["home", "Home", typeof buildHomePanel], readonly ["insert", "Insert", typeof buildInsertPanel], readonly ["design", "Design", typeof buildDesignPanel], readonly ["data", "Data", typeof buildDataPanel], readonly ["process", "Process", typeof buildProcessPanel], readonly ["review", "Review", typeof buildReviewPanel], readonly ["view", "View", typeof buildViewPanel], readonly ["help", "Help", typeof buildHelpPanel]];
|
|
7
7
|
export type RibbonTab = (typeof RIBBON_TABS)[number][0];
|
|
8
8
|
/**
|
|
9
|
-
* The Visio ribbon
|
|
10
|
-
*
|
|
9
|
+
* The Visio ribbon on the shared `office-ui-ribbon`: Quick Access Toolbar, File, one panel per
|
|
10
|
+
* tab and Tell me. The shared element owns the tab row, selection and arrow-key movement;
|
|
11
|
+
* commands emit `ribbon-action` events for the router.
|
|
11
12
|
*/
|
|
12
13
|
export declare function createRibbon(doc: Document): HTMLElement;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Inherited public tokens use local fallback aliases so host themes are never shadowed. */
|
|
2
|
-
export declare const viewerStyles = "\n:host {\n --_vv-bg:var(--vv-background,#eceae8); --_vv-surface:var(--vv-surface,#fff);\n --_vv-secondary:var(--vv-secondary,#f3f2f1); --_vv-ink:var(--vv-ink,#1f1f1f);\n --_vv-muted:var(--vv-muted,#605e5c); --_vv-border:var(--vv-border,#e1dfdd);\n --_vv-accent:var(--vv-accent,#3955a3); --_vv-accent-soft:var(--vv-accent-soft,rgba(57,85,163,.10));\n display:flex; flex-direction:column; min-width:0; min-height:320px; height:100%; overflow:hidden;\n color:var(--_vv-ink); background:var(--_vv-bg); font:12px/1.5 \"Segoe UI\",Arial,sans-serif; contain:layout;\n}\n* { box-sizing:border-box; }\n[hidden] { display:none !important; }\nbutton,select,input,textarea { font:inherit; color:inherit; border:1px solid var(--_vv-border); background:var(--_vv-surface); border-radius:4px; min-height:28px; padding:3px 8px; }\nbutton { cursor:pointer; }\nbutton:hover:enabled { background:var(--_vv-accent-soft); border-color:var(--_vv-accent); }\nbutton:disabled { opacity:.4; cursor:default; }\nbutton:focus-visible,select:focus-visible,input:focus-visible,textarea:focus-visible,summary:focus-visible,[tabindex]:focus-visible { outline:2px solid var(--vv-focus,var(--_vv-accent)); outline-offset:2px; }\nbutton[aria-pressed=\"true\"] { color:var(--_vv-accent); background:var(--_vv-accent-soft); }\n.toolbar { flex:none; min-width:0; border-bottom:1px solid var(--_vv-border); background:var(--_vv-surface); }\n.spacer { flex:1; }\n.ribbon-tabs { height:35px; display:flex; align-items:stretch; padding:0 4px; border-bottom:1px solid var(--_vv-border); }\n.ribbon-tabs button { position:relative; min-height:34px; padding:7px 14px; border:0; border-radius:0; background:transparent; color:var(--_vv-muted); font-size:12px; font-weight:500; }\n.ribbon-tabs button[aria-selected=\"true\"] { color:var(--_vv-accent); }\n.ribbon-tabs button[aria-selected=\"true\"]::after { content:\"\"; position:absolute; inset:auto 0 -1px; height:2.5px; background:var(--_vv-accent); }\n.ribbon-content { min-height:82px; display:flex; align-items:stretch; gap:0; padding:2px 4px; overflow-x:auto; }\n.ribbon-group { display:flex; flex-direction:column; justify-content:space-between; flex:none; gap:2px; padding:3px 10px 4px; border-right:1px solid var(--_vv-border); }\n.group-label { font-size:10px; line-height:12px; color:var(--_vv-muted); text-align:center; }\n.ribbon-actions { display:flex; align-items:stretch; gap:2px; flex:1; }\n.ribbon-command { display:flex; flex-direction:column; justify-content:center; align-items:center; gap:2px; min-width:70px; padding:2px 6px; border-color:transparent; background:transparent; font-size:11px; white-space:nowrap; }\n.ribbon-hint { align-self:center; flex:none; margin:0; padding:0 16px; font-size:11px; line-height:18px; color:var(--_vv-muted); }\n.search-group { width:330px; }\n.search-controls { display:flex; align-items:center; gap:4px; flex-wrap:wrap; }\n.search-controls label { display:flex; align-items:center; min-width:0; gap:6px; flex:1; font-size:11px; }\n.search-controls input { width:100%; min-width:0; padding:3px 6px; font-size:11px; }\n.search-controls button { padding:3px 6px; font-size:10px; background:var(--_vv-secondary); }\n.search-controls [role=\"status\"] { display:block; width:100%; min-height:15px; font-size:10px; line-height:15px; color:var(--_vv-muted); overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }\n.workspace { position:relative; display:flex; flex:1; min-width:0; min-height:0; overflow:hidden; }\n.pane-heading { height:37px; display:flex; align-items:center; justify-content:space-between; gap:8px; padding:8px 10px; border-bottom:1px solid var(--_vv-border); font-size:11px; font-weight:600; }\n.inspector-kind { color:var(--_vv-muted); font-size:10px; font-weight:400; }\n.viewport { position:relative; display:flex; flex-direction:column; flex:1; overflow:auto; min-width:0; min-height:0; padding:16px 4px; background:var(--_vv-bg); }\n.paper { display:block; flex:none; background:white; box-shadow:var(--vv-shadow,0 2px 8px rgb(0 0 0 / 14%)); margin:auto; }\n.paper [data-shape-id] { cursor:pointer; }\n.paper [data-selected=\"true\"] > [data-geometry] { stroke:var(--_vv-accent) !important; stroke-width:.025 !important; }\n.inspector-pane { flex:0 0 288px; width:288px; min-width:0; overflow:auto; border-left:1px solid var(--_vv-border); background:var(--_vv-secondary); }\n.inspector-body { display:flex; flex-direction:column; gap:12px; padding:12px 10px; }\n.inspector-card,.edit-controls,.layer-controls { min-width:0; padding:8px; margin:0; border:1px solid var(--_vv-border); border-radius:4px; background:var(--_vv-surface); font-size:11px; line-height:17px; }\n.document-card h2 { margin:0 0 8px; font-size:10px; font-weight:500; letter-spacing:.5px; text-transform:uppercase; color:var(--_vv-muted); }\n.current-page-name { margin:0 0 8px; font-size:12px; font-weight:500; overflow-wrap:anywhere; }\n.document-card dl { display:grid; grid-template-columns:1fr auto; gap:4px 10px; margin:0; font-size:11px; }\n.document-card dt { color:var(--_vv-muted); }\n.document-card dd { margin:0; text-align:right; overflow-wrap:anywhere; }\n.selection-hint { margin:0; padding:0 2px; color:var(--_vv-muted); font-size:11px; }\nsummary { cursor:pointer; min-height:22px; line-height:22px; font-weight:500; }\nsummary::marker { color:var(--_vv-muted); font-size:10px; }\n.shape-inspector div { max-height:260px; overflow:auto; }\n.shape-inspector p { margin:6px 0; overflow-wrap:anywhere; }\n.shape-inspector dl { display:grid; grid-template-columns:minmax(60px,1fr) 1.5fr; gap:6px 10px; }\n.shape-inspector dt { font-weight:500; }\n.shape-inspector dd { margin:0; overflow-wrap:anywhere; white-space:pre-wrap; }\n.shape-inspector h3 { margin:12px 0 5px; font-size:11px; }\n.shape-inspector a { color:var(--_vv-accent); overflow-wrap:anywhere; }\n.edit-controls p,.layer-controls p { margin:6px 0; color:var(--_vv-muted); overflow-wrap:anywhere; }\n.edit-controls textarea { display:block; width:100%; resize:vertical; max-height:180px; margin-top:4px; background:var(--_vv-secondary); }\n.edit-controls label { display:block; margin-top:8px; }\n.edit-actions { display:flex; flex-wrap:wrap; gap:4px; margin-top:8px; }\n.edit-actions button { font-size:11px; padding:3px 7px; }\n.edit-actions [data-edit=\"apply\"]:enabled { background:var(--_vv-accent); border-color:var(--_vv-accent); color:var(--vv-accent-ink,#fff); }\n.edit-controls [data-geometry] { min-width:0; margin:8px 0 0; padding:6px; border:1px solid var(--_vv-border); }\n.edit-controls [data-geometry-field] { display:block; width:100%; min-width:0; margin-top:4px; }\n.edit-controls [data-geometry-error] { color:var(--vv-danger,#b42318); }\n.edit-controls [data-edit-error] { color:var(--vv-danger,#b42318); }\n.edit-controls [data-edit-diagnostics] { max-height:100px; overflow:auto; padding-left:16px; }\n.layer-controls [data-layer-list] { max-height:240px; overflow:auto; }\n.layer-controls fieldset { border:1px solid var(--_vv-border); margin:6px 0; padding:6px; min-width:0; }\n.layer-controls legend { max-width:100%; overflow-wrap:anywhere; }\n.layer-controls fieldset div { display:flex; align-items:center; gap:6px; margin:3px 0; }\n.layer-controls label { display:flex; align-items:center; gap:6px; overflow-wrap:anywhere; }\n.layer-controls input { flex-shrink:0; width:16px; height:16px; min-height:16px; padding:0; accent-color:var(--_vv-accent); }\n.notes ul { max-height:220px; overflow:auto; padding-left:17px; margin:6px 0 0; color:var(--_vv-muted); }\n.notes li { margin:5px 0; overflow-wrap:anywhere; }\n.notes-strip { flex:none; display:flex; align-items:center; justify-content:space-between; min-height:25.5px; padding:0 12px; border-top:1px solid var(--_vv-border); background:var(--_vv-bg); color:var(--_vv-muted); font-size:10px; }\n.notes-strip button { min-height:24.5px; padding:2px 0; border:0; background:transparent; color:var(--_vv-muted); font-size:11px; }\n.notes-strip button::before { content:\"\u25B8\"; margin-right:6px; }\n.notes-strip button[aria-expanded=\"true\"]::before { content:\"\u25BE\"; }\n.status { flex:none; display:flex; align-items:center; justify-content:space-between; gap:12px; min-width:0; min-height:29px; padding:0 8px 0 12px; border-top:1px solid var(--_vv-border); color:var(--_vv-muted); background:var(--_vv-surface); font-size:10px; }\n.status-message { display:flex; gap:16px; min-width:0; }\n.status-message span { overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }\n.empty { max-width:360px; margin:60px auto; padding:16px; text-align:center; color:var(--_vv-muted); font-size:12px; }\n.empty strong { display:block; color:var(--_vv-ink); font-size:18px; font-weight:500; margin-bottom:8px; }\n@media(max-width:1100px) { .ribbon-hint { display:none; } [data-diagnostics] { display:none; } }\n@media(max-width:760px) {\n button,select,input,textarea { min-height:44px; }\n button { min-width:44px; }\n summary { min-height:44px; line-height:44px; }\n .ribbon-tabs { height:44px; }\n .ribbon-tabs button { min-height:44px; padding:8px 16px; }\n .ribbon-content { min-height:86px; }\n .ribbon-group { padding:4px 8px; }\n .search-group { width:100%; border-right:0; }\n .search-controls { gap:4px; }\n .search-controls label { font-size:12px; }\n .search-controls input { font-size:12px; }\n .search-controls button { min-width:44px; font-size:0; padding:3px; }\n .search-controls [data-action=\"search-previous\"]::before { content:\"\u2039\"; font-size:22px; }\n .search-controls [data-action=\"search-next\"]::before { content:\"\u203A\"; font-size:22px; }\n #home-panel>.ribbon-group:not(.search-group):not(.undo-group) { display:none; }\n .ribbon-command { min-width:90px; }\n .workspace { display:block; overflow:auto; }\n .viewport { height:340px; min-height:260px; padding:16px 4px; }\n .inspector-pane { width:100%; overflow:visible; border-left:0; border-top:1px solid var(--_vv-border); }\n .inspector-body { gap:8px; padding:10px; }\n .inspector-card,.edit-controls,.layer-controls { font-size:12px; }\n .layer-controls label { min-height:44px; }\n .layer-controls input { min-width:20px; width:20px; height:20px; min-height:20px; }\n .notes-strip { min-height:44px; padding:0 10px; }\n .notes-strip button { min-height:44px; }\n .status { flex-wrap:wrap; gap:0; padding:4px 8px; }\n .status-message { width:100%; min-height:18px; }\n}\n@media(pointer:coarse) {\n button,select,input,textarea { min-height:44px; }\n button { min-width:44px; }\n summary,.layer-controls label { min-height:44px; line-height:44px; }\n .ribbon-tabs { min-height:44px; height:44px; }\n .ribbon-tabs button { min-height:44px; }\n .ribbon-content { min-height:96px; }\n .search-group { width:380px; max-width:100%; }\n .notes-strip button { min-height:44px; height:44px; }\n .layer-controls input { min-height:20px; }\n}\n/* Suite ribbon: tabs lead directly into Visio command groups. */\n.ribbon-tabs { height:40px; }\n.ribbon-tabs button { min-height:39px; padding:8px 16px; }\n.ribbon-content { min-height:104px; padding:4px 4px; }\n.search-group { order:2; width:320px; }\n.ribbon-hint { order:3; padding:10px 18px; }\n.ribbon-command { min-width:82px; }\n.pane-close { display:none; }\n@media(max-width:760px) {\n .ribbon-tabs { height:44px; }\n .ribbon-tabs button { min-height:44px; }\n .ribbon-content { min-height:54px; padding:4px 0; }\n .search-group { flex:0 0 100%; width:100%; min-height:54px; }\n .search-feedback,.group-label { display:none; }\n .ribbon-content { overflow-x:auto; scroll-snap-type:x mandatory; }\n .workspace { display:flex; position:relative; overflow:hidden; }\n .viewport { flex:1; width:100%; height:100%; min-height:0; padding:16px 4px; }\n .inspector-pane { position:absolute; inset:0 0 0 auto; width:min(320px,100%); z-index:4; overflow:auto; border-left:1px solid var(--_vv-border); box-shadow:-8px 0 24px #0002; }\n .pane-close { display:block; width:44px; height:44px; padding:0; font-size:22px; background:transparent; border:0; }\n .inspector-kind { margin-left:auto; }\n .notes-strip { display:none; }\n .status { min-height:48px; padding:2px 8px; }\n .status-message { display:none; }\n}\n.toolbar { position:relative; }\n.ribbon-tools { display:flex; flex:none; order:0; }\n.tools-content { display:flex; align-items:stretch; }\n.ribbon-tools>summary { display:none; }\n.ribbon-command { font-size:12px; min-width:88px; }\n.ribbon-hint { font-size:12px; line-height:20px; flex:1; }\n.group-label { font-size:11px; line-height:14px; }\n.inspector-card,.edit-controls,.layer-controls { font-size:12px; line-height:18px; }\n.selection-hint,.document-card dl { font-size:12px; }\n.pane-heading { font-size:12px; }\n.inspector-pane .pane-heading { position:sticky; top:0; z-index:1; background:var(--_vv-secondary); flex:none; }\n.status .notes-strip { border:0; padding:0 8px; background:transparent; min-height:28px; }\n.status .notes-strip>span { display:none; }\n.status-message { flex:1; }\n@media(max-width:760px) {\n #home-panel { overflow:visible; min-height:54px; padding:4px; }\n .ribbon-tools { display:block; flex:0 0 84px; width:84px; order:1; }\n .ribbon-tools>summary { display:flex; min-height:44px; align-items:center; justify-content:center; gap:6px; padding:0 10px; border:1px solid var(--_vv-border); background:var(--_vv-surface); border-radius:4px; font-size:12px; cursor:pointer; list-style:none; }\n .ribbon-tools>summary::-webkit-details-marker { display:none; }\n .ribbon-tools .tools-content { display:flex; position:absolute; top:100%; left:4px; right:4px; z-index:6; flex-direction:column; padding:12px; gap:12px; border:1px solid var(--_vv-border); border-radius:4px; background:var(--_vv-surface); box-shadow:0 12px 28px #0003; max-height:60vh; overflow:auto; }\n .ribbon-tools:not([open])>.tools-content { display:none; }\n .ribbon-tools .ribbon-group { display:flex; width:100%; min-height:64px; border:0; padding:0; }\n .ribbon-tools .ribbon-actions { justify-content:space-between; }\n .ribbon-tools .ribbon-command { min-width:88px; font-size:12px; }\n .ribbon-tools .search-group { order:1; flex:auto; }\n .ribbon-tools .search-feedback { display:block; }\n .status { flex-wrap:nowrap; gap:4px; min-height:48px; }\n .status .notes-strip { display:none; }\n}\n@media(pointer:coarse) { .ribbon-tabs {height:45px;min-height:45px;} .ribbon-tabs button {min-height:44px;height:44px;} }\n@media(prefers-reduced-motion:reduce) { * { scroll-behavior:auto !important; } }\n";
|
|
2
|
+
export declare const viewerStyles = "\n:host {\n --_vv-bg:var(--vv-background,#eceae8); --_vv-surface:var(--vv-surface,#fff);\n --_vv-secondary:var(--vv-secondary,#f3f2f1); --_vv-ink:var(--vv-ink,#1f1f1f);\n --_vv-muted:var(--vv-muted,#605e5c); --_vv-border:var(--vv-border,#e1dfdd);\n --_vv-accent:var(--vv-accent,#3955a3); --_vv-accent-soft:var(--vv-accent-soft,rgba(57,85,163,.10));\n display:flex; flex-direction:column; min-width:0; min-height:320px; height:100%; overflow:hidden;\n color:var(--_vv-ink); background:var(--_vv-bg); font:12px/1.5 \"Segoe UI\",Arial,sans-serif; contain:layout;\n}\n* { box-sizing:border-box; }\n[hidden] { display:none !important; }\nbutton,select,input,textarea { font:inherit; color:inherit; border:1px solid var(--_vv-border); background:var(--_vv-surface); border-radius:4px; min-height:28px; padding:3px 8px; }\nbutton { cursor:pointer; }\nbutton:hover:enabled { background:var(--_vv-accent-soft); border-color:var(--_vv-accent); }\nbutton:disabled { opacity:.4; cursor:default; }\nbutton:focus-visible,select:focus-visible,input:focus-visible,textarea:focus-visible,summary:focus-visible,[tabindex]:focus-visible { outline:2px solid var(--vv-focus,var(--_vv-accent)); outline-offset:2px; }\nbutton[aria-pressed=\"true\"] { color:var(--_vv-accent); background:var(--_vv-accent-soft); }\n.toolbar { flex:none; min-width:0; border-bottom:1px solid var(--_vv-border); background:var(--_vv-surface); }\n.spacer { flex:1; }\n.ribbon-content { min-height:82px; display:flex; align-items:stretch; gap:0; padding:2px 4px; overflow-x:auto; }\n.ribbon-group { display:flex; flex-direction:column; justify-content:space-between; flex:none; gap:2px; padding:3px 10px 4px; border-right:1px solid var(--_vv-border); }\n.group-label { font-size:10px; line-height:12px; color:var(--_vv-muted); text-align:center; }\n.ribbon-actions { display:flex; align-items:stretch; gap:2px; flex:1; }\n.ribbon-command { display:flex; flex-direction:column; justify-content:center; align-items:center; gap:2px; min-width:70px; padding:2px 6px; border-color:transparent; background:transparent; font-size:11px; white-space:nowrap; }\n.ribbon-hint { align-self:center; flex:none; margin:0; padding:0 16px; font-size:11px; line-height:18px; color:var(--_vv-muted); }\n.workspace { position:relative; display:flex; flex:1; min-width:0; min-height:0; overflow:hidden; }\n.pane-heading { height:37px; display:flex; align-items:center; justify-content:space-between; gap:8px; padding:8px 10px; border-bottom:1px solid var(--_vv-border); font-size:11px; font-weight:600; }\n.inspector-kind { color:var(--_vv-muted); font-size:10px; font-weight:400; }\n.viewport { position:relative; display:flex; flex-direction:column; flex:1; overflow:auto; min-width:0; min-height:0; padding:16px 4px; background:var(--_vv-bg); }\n.paper { display:block; flex:none; background:white; box-shadow:var(--vv-shadow,0 2px 8px rgb(0 0 0 / 14%)); margin:auto; }\n.paper [data-shape-id] { cursor:pointer; }\n.paper [data-selected=\"true\"] > [data-geometry] { stroke:var(--_vv-accent) !important; stroke-width:.025 !important; }\n.inspector-pane { flex:0 0 288px; width:288px; min-width:0; overflow:auto; border-left:1px solid var(--_vv-border); background:var(--_vv-secondary); }\n.inspector-body { display:flex; flex-direction:column; gap:12px; padding:12px 10px; }\n.inspector-card,.edit-controls,.layer-controls { min-width:0; padding:8px; margin:0; border:1px solid var(--_vv-border); border-radius:4px; background:var(--_vv-surface); font-size:11px; line-height:17px; }\n.document-card h2 { margin:0 0 8px; font-size:10px; font-weight:500; letter-spacing:.5px; text-transform:uppercase; color:var(--_vv-muted); }\n.current-page-name { margin:0 0 8px; font-size:12px; font-weight:500; overflow-wrap:anywhere; }\n.document-card dl { display:grid; grid-template-columns:1fr auto; gap:4px 10px; margin:0; font-size:11px; }\n.document-card dt { color:var(--_vv-muted); }\n.document-card dd { margin:0; text-align:right; overflow-wrap:anywhere; }\n.selection-hint { margin:0; padding:0 2px; color:var(--_vv-muted); font-size:11px; }\nsummary { cursor:pointer; min-height:22px; line-height:22px; font-weight:500; }\nsummary::marker { color:var(--_vv-muted); font-size:10px; }\n.shape-inspector div { max-height:260px; overflow:auto; }\n.shape-inspector p { margin:6px 0; overflow-wrap:anywhere; }\n.shape-inspector dl { display:grid; grid-template-columns:minmax(60px,1fr) 1.5fr; gap:6px 10px; }\n.shape-inspector dt { font-weight:500; }\n.shape-inspector dd { margin:0; overflow-wrap:anywhere; white-space:pre-wrap; }\n.shape-inspector h3 { margin:12px 0 5px; font-size:11px; }\n.shape-inspector a { color:var(--_vv-accent); overflow-wrap:anywhere; }\n.edit-controls p,.layer-controls p { margin:6px 0; color:var(--_vv-muted); overflow-wrap:anywhere; }\n.edit-controls textarea { display:block; width:100%; resize:vertical; max-height:180px; margin-top:4px; background:var(--_vv-secondary); }\n.edit-controls label { display:block; margin-top:8px; }\n.edit-actions { display:flex; flex-wrap:wrap; gap:4px; margin-top:8px; }\n.edit-actions button { font-size:11px; padding:3px 7px; }\n.edit-actions [data-edit=\"apply\"]:enabled { background:var(--_vv-accent); border-color:var(--_vv-accent); color:var(--vv-accent-ink,#fff); }\n.edit-controls [data-geometry] { min-width:0; margin:8px 0 0; padding:6px; border:1px solid var(--_vv-border); }\n.edit-controls [data-geometry-field] { display:block; width:100%; min-width:0; margin-top:4px; }\n.edit-controls [data-geometry-error] { color:var(--vv-danger,#b42318); }\n.edit-controls [data-edit-error] { color:var(--vv-danger,#b42318); }\n.edit-controls [data-edit-diagnostics] { max-height:100px; overflow:auto; padding-left:16px; }\n.layer-controls [data-layer-list] { max-height:240px; overflow:auto; }\n.layer-controls fieldset { border:1px solid var(--_vv-border); margin:6px 0; padding:6px; min-width:0; }\n.layer-controls legend { max-width:100%; overflow-wrap:anywhere; }\n.layer-controls fieldset div { display:flex; align-items:center; gap:6px; margin:3px 0; }\n.layer-controls label { display:flex; align-items:center; gap:6px; overflow-wrap:anywhere; }\n.layer-controls input { flex-shrink:0; width:16px; height:16px; min-height:16px; padding:0; accent-color:var(--_vv-accent); }\n.notes ul { max-height:220px; overflow:auto; padding-left:17px; margin:6px 0 0; color:var(--_vv-muted); }\n.notes li { margin:5px 0; overflow-wrap:anywhere; }\n.notes-strip { flex:none; display:flex; align-items:center; justify-content:space-between; min-height:25.5px; padding:0 12px; border-top:1px solid var(--_vv-border); background:var(--_vv-bg); color:var(--_vv-muted); font-size:10px; }\n.notes-strip button { min-height:24.5px; padding:2px 0; border:0; background:transparent; color:var(--_vv-muted); font-size:11px; }\n.notes-strip button::before { content:\"\u25B8\"; margin-right:6px; }\n.notes-strip button[aria-expanded=\"true\"]::before { content:\"\u25BE\"; }\n.status { flex:none; display:flex; align-items:center; justify-content:space-between; gap:12px; min-width:0; min-height:29px; padding:0 8px 0 12px; border-top:1px solid var(--_vv-border); color:var(--_vv-muted); background:var(--_vv-surface); font-size:10px; }\n.status-message { display:flex; gap:16px; min-width:0; }\n.status-message span { overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }\n.empty { max-width:360px; margin:60px auto; padding:16px; text-align:center; color:var(--_vv-muted); font-size:12px; }\n.empty strong { display:block; color:var(--_vv-ink); font-size:18px; font-weight:500; margin-bottom:8px; }\n@media(max-width:1100px) { .ribbon-hint { display:none; } [data-diagnostics] { display:none; } }\n@media(max-width:760px) {\n button,select,input,textarea { min-height:44px; }\n button { min-width:44px; }\n summary { min-height:44px; line-height:44px; }\n .ribbon-content { min-height:86px; }\n .ribbon-group { padding:4px 8px; }\n #home-panel>.ribbon-group:not(.search-group):not(.undo-group) { display:none; }\n .ribbon-command { min-width:90px; }\n .workspace { display:block; overflow:auto; }\n .viewport { height:340px; min-height:260px; padding:16px 4px; }\n .inspector-pane { width:100%; overflow:visible; border-left:0; border-top:1px solid var(--_vv-border); }\n .inspector-body { gap:8px; padding:10px; }\n .inspector-card,.edit-controls,.layer-controls { font-size:12px; }\n .layer-controls label { min-height:44px; }\n .layer-controls input { min-width:20px; width:20px; height:20px; min-height:20px; }\n .notes-strip { min-height:44px; padding:0 10px; }\n .notes-strip button { min-height:44px; }\n .status { flex-wrap:wrap; gap:0; padding:4px 8px; }\n .status-message { width:100%; min-height:18px; }\n}\n@media(pointer:coarse) {\n button,select,input,textarea { min-height:44px; }\n button { min-width:44px; }\n summary,.layer-controls label { min-height:44px; line-height:44px; }\n .ribbon-content { min-height:96px; }\n .notes-strip button { min-height:44px; height:44px; }\n .layer-controls input { min-height:20px; }\n}\n/* Suite ribbon: tabs lead directly into Visio command groups. */\n.ribbon-content { min-height:104px; padding:4px 4px; }\n.ribbon-hint { order:3; padding:10px 18px; }\n.ribbon-command { min-width:82px; }\n.pane-close { display:none; }\n@media(max-width:760px) {\n .ribbon-content { min-height:54px; padding:4px 0; }\n .search-feedback,.group-label { display:none; }\n .ribbon-content { overflow-x:auto; scroll-snap-type:x mandatory; }\n .workspace { display:flex; position:relative; overflow:hidden; }\n .viewport { flex:1; width:100%; height:100%; min-height:0; padding:16px 4px; }\n .inspector-pane { position:absolute; inset:0 0 0 auto; width:min(320px,100%); z-index:4; overflow:auto; border-left:1px solid var(--_vv-border); box-shadow:-8px 0 24px #0002; }\n .pane-close { display:block; width:44px; height:44px; padding:0; font-size:22px; background:transparent; border:0; }\n .inspector-kind { margin-left:auto; }\n .notes-strip { display:none; }\n .status { min-height:48px; padding:2px 8px; }\n .status-message { display:none; }\n}\n.toolbar { position:relative; }\n.ribbon-tools { display:flex; flex:none; order:0; }\n.tools-content { display:flex; align-items:stretch; }\n.ribbon-tools>summary { display:none; }\n.ribbon-command { font-size:12px; min-width:88px; }\n.ribbon-hint { font-size:12px; line-height:20px; flex:1; }\n.group-label { font-size:11px; line-height:14px; }\n.inspector-card,.edit-controls,.layer-controls { font-size:12px; line-height:18px; }\n.selection-hint,.document-card dl { font-size:12px; }\n.pane-heading { font-size:12px; }\n.inspector-pane .pane-heading { position:sticky; top:0; z-index:1; background:var(--_vv-secondary); flex:none; }\n.status .notes-strip { border:0; padding:0 8px; background:transparent; min-height:28px; }\n.status .notes-strip>span { display:none; }\n.status-message { flex:1; }\n@media(max-width:760px) {\n #home-panel { overflow:visible; min-height:54px; padding:4px; }\n .ribbon-tools { display:block; flex:0 0 84px; width:84px; order:1; }\n .ribbon-tools>summary { display:flex; min-height:44px; align-items:center; justify-content:center; gap:6px; padding:0 10px; border:1px solid var(--_vv-border); background:var(--_vv-surface); border-radius:4px; font-size:12px; cursor:pointer; list-style:none; }\n .ribbon-tools>summary::-webkit-details-marker { display:none; }\n .ribbon-tools .tools-content { display:flex; position:absolute; top:100%; left:4px; right:4px; z-index:6; flex-direction:column; padding:12px; gap:12px; border:1px solid var(--_vv-border); border-radius:4px; background:var(--_vv-surface); box-shadow:0 12px 28px #0003; max-height:60vh; overflow:auto; }\n .ribbon-tools:not([open])>.tools-content { display:none; }\n .ribbon-tools .ribbon-group { display:flex; width:100%; min-height:64px; border:0; padding:0; }\n .ribbon-tools .ribbon-actions { justify-content:space-between; }\n .ribbon-tools .ribbon-command { min-width:88px; font-size:12px; }\n .ribbon-tools .search-feedback { display:block; }\n .status { flex-wrap:nowrap; gap:4px; min-height:48px; }\n .status .notes-strip { display:none; }\n}\n@media(prefers-reduced-motion:reduce) { * { scroll-behavior:auto !important; } }\n";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ViewerState } from './controller.js';
|
|
2
2
|
import type { VsdxSource } from './contract.js';
|
|
3
|
-
import type
|
|
3
|
+
import { type BackstagePage } from './backstage.js';
|
|
4
4
|
/** What the backstage needs from the element; every action delegates to existing APIs. */
|
|
5
5
|
export interface BackstageHost {
|
|
6
6
|
root: ShadowRoot;
|
|
@@ -17,13 +17,10 @@ export interface BackstageHost {
|
|
|
17
17
|
};
|
|
18
18
|
closeDocument(): void;
|
|
19
19
|
revealNotes(): void;
|
|
20
|
+
showOptions(): void;
|
|
20
21
|
announce(message: string): void;
|
|
21
22
|
noteCount(): number;
|
|
22
23
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Visio's File backstage: opened from the File tab, closed with Back or Escape (focus returns to
|
|
25
|
-
* File). Open, Save, Save As, Export, Print and Close are real; the rest is shown disabled.
|
|
26
|
-
*/
|
|
27
24
|
export declare class ViewerBackstage {
|
|
28
25
|
#private;
|
|
29
26
|
private readonly host;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { ViewerController } from './controller.js';
|
|
2
2
|
interface Controls {
|
|
3
3
|
viewport: HTMLDivElement;
|
|
4
|
-
commandRoot: ShadowRoot;
|
|
5
4
|
zoomSlider: HTMLElement & {
|
|
6
5
|
value: number;
|
|
7
6
|
};
|
|
8
|
-
searchInput: HTMLInputElement;
|
|
9
7
|
}
|
|
10
8
|
/** Own every DOM listener and abort them together when the surface is disposed. */
|
|
11
9
|
export declare function wireViewerInputs(controls: Controls, controller: ViewerController, fit: (mode: 'page' | 'width') => void): () => void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type OfficeOptionCategory, type OfficeProfile } from 'ooxml-ui/controls';
|
|
2
|
+
/**
|
|
3
|
+
* Visio's File > Options categories, in Visio's order. Only User name and Initials are honoured
|
|
4
|
+
* today (they are the local profile, also used as the identity in a shared session); every other
|
|
5
|
+
* setting is shown disabled with the capability it is waiting for.
|
|
6
|
+
*/
|
|
7
|
+
export declare const VISIO_OPTION_CATEGORIES: readonly OfficeOptionCategory[];
|
|
8
|
+
/** The Options dialog element. Built once and appended to the viewer's shadow root. */
|
|
9
|
+
export declare function createOptionsDialog(doc: Document): HTMLElement;
|
|
10
|
+
/**
|
|
11
|
+
* File > Account and File > Options share one local profile. Edits in either are written to the
|
|
12
|
+
* suite-wide profile store, mirrored into the other and reported through `onProfile`.
|
|
13
|
+
*/
|
|
14
|
+
export declare class ViewerProfile {
|
|
15
|
+
#private;
|
|
16
|
+
private readonly onProfile;
|
|
17
|
+
constructor(root: ShadowRoot, onProfile?: (profile: OfficeProfile) => void);
|
|
18
|
+
get profile(): OfficeProfile;
|
|
19
|
+
/** Open Visio Options, on General as Visio does. */
|
|
20
|
+
showOptions(category?: string): void;
|
|
21
|
+
wire(): () => void;
|
|
22
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visio's rulers: inch scales along the top and left of the drawing window with 0 at the page's
|
|
3
|
+
* left and bottom edges (vertical values grow upward, as in Visio). Drawn by the shared
|
|
4
|
+
* `office-ui-ruler`; this module only lays them out and says where zero is. Viewer-only
|
|
5
|
+
* presentation: nothing is read from or written to the document beyond the rendered page box.
|
|
6
|
+
*/
|
|
1
7
|
export interface Rulers {
|
|
2
8
|
element: HTMLElement;
|
|
3
9
|
render(visible: boolean, zoom: number): void;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import type { ViewerState } from './controller.js';
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { ViewerController, ViewerState } from './controller.js';
|
|
2
|
+
export type FindBar = HTMLElement & {
|
|
3
|
+
open: boolean;
|
|
4
|
+
value: string;
|
|
5
|
+
status: string;
|
|
6
|
+
statusTitle: string;
|
|
7
|
+
show(): void;
|
|
8
|
+
close(): void;
|
|
9
|
+
};
|
|
4
10
|
/**
|
|
5
|
-
* Visio opens Find from Home > Editing rather than keeping a box in the ribbon. The
|
|
6
|
-
* sits under the ribbon, hidden until Find... or Ctrl+F
|
|
11
|
+
* Visio opens Find from Home > Editing rather than keeping a box in the ribbon. The shared
|
|
12
|
+
* `office-ui-find-bar` sits under the ribbon, hidden until Find... or Ctrl+F; Enter and
|
|
13
|
+
* Shift+Enter step through matching shapes and Escape clears, then closes.
|
|
7
14
|
*/
|
|
8
|
-
export declare function createFindBar(doc: Document):
|
|
9
|
-
/**
|
|
10
|
-
export declare function wireFindBar(bar:
|
|
11
|
-
export
|
|
12
|
-
input: HTMLInputElement;
|
|
13
|
-
status: HTMLSpanElement;
|
|
14
|
-
previous: HTMLButtonElement;
|
|
15
|
-
next: HTMLButtonElement;
|
|
16
|
-
}
|
|
17
|
-
export declare function searchControls(root: ShadowRoot): SearchControls;
|
|
18
|
-
export declare function renderSearchControls(controls: SearchControls, state: ViewerState): void;
|
|
15
|
+
export declare function createFindBar(doc: Document): FindBar;
|
|
16
|
+
/** Route the find bar's queries and steps to the controller; `closed` restores focus. */
|
|
17
|
+
export declare function wireFindBar(bar: FindBar, controller: ViewerController, closed: () => void): () => void;
|
|
18
|
+
export declare function renderFindBar(bar: FindBar, state: ViewerState): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { OfficeProfile } from 'ooxml-ui/controls';
|
|
2
|
+
import type { ViewerController } from './controller.js';
|
|
3
|
+
type Collab = typeof import('ooxml-core/collab');
|
|
4
|
+
/**
|
|
5
|
+
* File > Share: a live session over `ooxml-core/collab` (Yjs). Peers in other windows of this
|
|
6
|
+
* browser share the whole VSDX package through a BroadcastChannel; remote changes arrive as one
|
|
7
|
+
* undoable history step. The collab runtime loads only when sharing starts.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ViewerShare {
|
|
10
|
+
#private;
|
|
11
|
+
private readonly controller;
|
|
12
|
+
private readonly profile;
|
|
13
|
+
private readonly loadCollab;
|
|
14
|
+
constructor(root: ShadowRoot, controller: ViewerController, profile: () => OfficeProfile, loadCollab?: () => Promise<Collab>);
|
|
15
|
+
get active(): boolean;
|
|
16
|
+
wire(): () => void;
|
|
17
|
+
start(roomId: string): Promise<void>;
|
|
18
|
+
stop(): void;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "visio-react-viewer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Local-first Visio viewer for react",
|
|
5
5
|
"homepage": "https://christophervr.github.io/visio-viewer/",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"emf-converter": "4.8.9",
|
|
31
|
-
"ooxml-core": "^0.
|
|
32
|
-
"ooxml-ui": "^0.
|
|
33
|
-
"visio-core": "^0.
|
|
31
|
+
"ooxml-core": "^0.14.1",
|
|
32
|
+
"ooxml-ui": "^0.13.0",
|
|
33
|
+
"visio-core": "^0.3.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"react": ">=18"
|