pptx-vanilla-viewer 2.12.0 → 2.14.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/CHANGELOG.md +49 -0
- package/dist/ai-panel-OBPJQHVB.js +1 -0
- package/dist/ai-panel-PGBTDEHY.cjs +1 -0
- package/dist/{chunk-56CORRDB.js → chunk-TKGE7AOK.js} +311 -304
- package/dist/{chunk-WTF4OTWQ.cjs → chunk-XNBL4IIF.cjs} +311 -304
- package/dist/index.cjs +285 -71
- package/dist/index.d.ts +28 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +284 -70
- package/dist/styles.css +221 -7
- package/package.json +3 -1
- package/dist/ai-panel-E6UFMZWP.cjs +0 -1
- package/dist/ai-panel-GGBB3GUH.js +0 -1
package/dist/styles.css
CHANGED
|
@@ -938,6 +938,15 @@
|
|
|
938
938
|
}
|
|
939
939
|
.pptxv-inspector-tab:hover { color: var(--pptx-foreground); background: var(--pptx-accent); }
|
|
940
940
|
.pptxv-inspector-tab.is-active { background: var(--pptx-primary); color: var(--pptx-primary-foreground, #fff); }
|
|
941
|
+
/* Below this width, matches isDensePanelCompact()/MOBILE_BREAKPOINT (768) in
|
|
942
|
+
pptx-viewer-shared: getDensePanelTouchTargetPx(width) returns
|
|
943
|
+
MIN_TOUCH_TARGET_PX (44), so the Elements/Properties/Comments tab buttons
|
|
944
|
+
clear a touch-sized hit area. This binding's inspector pane has no inline
|
|
945
|
+
close button (its visibility is toggled elsewhere), so there is nothing
|
|
946
|
+
else to size here. */
|
|
947
|
+
@media (max-width: 767px) {
|
|
948
|
+
.pptxv-inspector-tab { min-height: 44px; }
|
|
949
|
+
}
|
|
941
950
|
/* Elements tab: layer-order rows. */
|
|
942
951
|
.pptxv-inspector-layer-list { display: flex; flex-direction: column; gap: 2px; }
|
|
943
952
|
.pptxv-inspector-layer-row {
|
|
@@ -1318,6 +1327,28 @@
|
|
|
1318
1327
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
1319
1328
|
}
|
|
1320
1329
|
|
|
1330
|
+
/* Touch target: matches MIN_TOUCH_TARGET_PX (44) from pptx-viewer-shared's
|
|
1331
|
+
render/responsive module, below MOBILE_BREAKPOINT (768). The `!important`
|
|
1332
|
+
is load-bearing: this button lives inside `.pptxv`, so it is also matched
|
|
1333
|
+
by css.ts's baseline `.pptxv :is(button, [role='button'])... { min-width:
|
|
1334
|
+
24px; min-height: 24px; }`, whose chained :not() pseudo-classes give it
|
|
1335
|
+
higher specificity than a plain class selector. */
|
|
1336
|
+
@media (max-width: 767px) {
|
|
1337
|
+
.pptxv-inspector-deck-btn { min-height: 44px !important; }
|
|
1338
|
+
.pptxv-inspector-tab { min-height: 44px !important; }
|
|
1339
|
+
.pptxv-inspector-lock-btn { min-width: 44px !important; min-height: 44px !important; }
|
|
1340
|
+
/* `.pptxv-field-select-input` (controls-extra.ts's shared `makeSelectField`
|
|
1341
|
+
factory) backs many inspector <select> rows (Shape Type, ...), so fixing
|
|
1342
|
+
it once here reaches all of them. A <select>, not a <button>, so css.ts's
|
|
1343
|
+
button-only baseline does not apply and no `!important` is needed. */
|
|
1344
|
+
.pptxv-field-select-input { min-height: 44px; }
|
|
1345
|
+
/* Table style presets (table-section.ts): a 3-column gallery of named,
|
|
1346
|
+
individually-labelled preview tiles ("Medium 1", ...) - plenty of room
|
|
1347
|
+
per column to grow past its 40px desktop height, unlike a dense colour
|
|
1348
|
+
swatch grid, so it gets the WCAG target rather than an exemption. */
|
|
1349
|
+
.pptxv-table-preset-swatch { height: 44px !important; }
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1321
1352
|
|
|
1322
1353
|
/* ── Ribbon shell and React-aligned command row ─────────────────────────── */
|
|
1323
1354
|
.pptxv-ribbon {
|
|
@@ -2288,6 +2319,21 @@
|
|
|
2288
2319
|
cursor: pointer;
|
|
2289
2320
|
}
|
|
2290
2321
|
.pptxv-modal-danger-btn:hover { background: rgb(239 68 68 / 0.2); }
|
|
2322
|
+
/* Below this width, matches isDensePanelCompact()/MOBILE_BREAKPOINT (768) in
|
|
2323
|
+
pptx-viewer-shared: getDensePanelTouchTargetPx(width) returns
|
|
2324
|
+
MIN_TOUCH_TARGET_PX (44), so the header close button, the footer/danger
|
|
2325
|
+
buttons, the text inputs and the Create/Join mode-toggle tabs of every
|
|
2326
|
+
modal built on this shell (Share, Broadcast) clear a touch-sized hit area.
|
|
2327
|
+
The footer itself is already outside the panel's own scroll region (only
|
|
2328
|
+
.pptxv-modal-body scrolls, see above), so it stays visible without needing
|
|
2329
|
+
shouldStickyActionRow's position: sticky. */
|
|
2330
|
+
@media (max-width: 767px) {
|
|
2331
|
+
.pptxv-modal-close { width: 44px; height: 44px; }
|
|
2332
|
+
.pptxv-modal-btn { min-height: 44px; }
|
|
2333
|
+
.pptxv-modal-danger-btn { min-height: 44px; }
|
|
2334
|
+
.pptxv-modal-input { min-height: 44px; }
|
|
2335
|
+
.pptxv-share-tabs button { min-height: 44px; }
|
|
2336
|
+
}
|
|
2291
2337
|
|
|
2292
2338
|
/* ── Share dialog: active-session status/details/connected-users ───────── */
|
|
2293
2339
|
.pptxv-share-status-row { display: flex; align-items: center; gap: 8px; font-size: 13px; }
|
|
@@ -2915,7 +2961,7 @@
|
|
|
2915
2961
|
.pptxv-mobile-comment { display: grid; gap: 6px; padding: 8px 0; border-bottom: 1px solid var(--pptx-border); }
|
|
2916
2962
|
.pptxv-mobile-comment textarea, .pptxv-mobile-comment-add textarea { box-sizing: border-box; width: 100%; min-height: 58px; padding: 8px; border: 1px solid var(--pptx-border); border-radius: var(--pptx-radius); background: var(--pptx-background); color: var(--pptx-foreground); font: inherit; }
|
|
2917
2963
|
.pptxv-mobile-comment-actions { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
2918
|
-
.pptxv-mobile-comment-actions button, .pptxv-mobile-comment-add button { min-height:
|
|
2964
|
+
.pptxv-mobile-comment-actions button, .pptxv-mobile-comment-add button { min-height: 44px !important; padding: 6px 10px; border: 1px solid var(--pptx-border); border-radius: var(--pptx-radius); background: var(--pptx-muted); color: var(--pptx-foreground); }
|
|
2919
2965
|
.pptxv-mobile-comment-add { display: grid; gap: 6px; padding-top: 10px; }
|
|
2920
2966
|
.pptxv-mobile-slide-list button { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 6px; border: 1px solid var(--pptx-border); border-radius: 8px; background: var(--pptx-muted); color: inherit; text-align: left; }
|
|
2921
2967
|
.pptxv-mobile-slide-list button.is-active { border-color: var(--pptx-primary); color: var(--pptx-primary); }
|
|
@@ -3042,7 +3088,19 @@
|
|
|
3042
3088
|
.pptxv-sorter-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; overflow: auto; padding: 18px; } .pptxv-sorter-card { overflow: hidden; border: 2px solid var(--pptx-border); border-radius: 7px; background: var(--pptx-card); } .pptxv-sorter-card.is-current { border-color: var(--pptx-primary); } .pptxv-sorter-card.is-hidden { opacity: .5; } .pptxv-sorter-card > button { display: grid; width: 100%; min-height: 90px; place-items: center; border: 0; background: var(--pptx-muted); color: inherit; font-size: 22px; cursor: pointer; } .pptxv-sorter-card div { display: flex; gap: 3px; padding: 5px; } .pptxv-sorter-card div button { flex: 1; padding: 4px; border: 0; background: transparent; color: inherit; font-size: 9px; cursor: pointer; }
|
|
3043
3089
|
.pptxv-custom-shows-active { display: flex; align-items: center; gap: 8px; } .pptxv-custom-shows-active select { flex: 1; min-width: 0; padding: 6px 8px; border: 1px solid var(--pptx-border); border-radius: 4px; background: var(--pptx-muted); color: inherit; }
|
|
3044
3090
|
.pptxv-custom-shows article { display: grid; grid-template-columns: 1fr auto auto auto; gap: 6px; padding: 8px; border: 1px solid var(--pptx-border); border-radius: 6px; } .pptxv-custom-shows article > div { grid-column: 1 / -1; max-height: 140px; overflow: auto; }
|
|
3045
|
-
@media (max-width: 767px) {
|
|
3091
|
+
@media (max-width: 767px) {
|
|
3092
|
+
.pptxv-parity-dialog { top: auto; bottom: 0; width: 100%; max-height: 88dvh; transform: translateX(-50%); border-radius: 16px 16px 0 0; }
|
|
3093
|
+
.pptxv-parity-header button { display: flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; }
|
|
3094
|
+
/* Touch target: matches MIN_TOUCH_TARGET_PX (44) from pptx-viewer-shared's
|
|
3095
|
+
render/responsive module. The Print/Share/Sorter/etc "parity" dialogs
|
|
3096
|
+
share this shell (parity-dialog-shell.ts); the header close button was
|
|
3097
|
+
already sized, but the footer action buttons (Cancel/OK/Print) and any
|
|
3098
|
+
select dropdown were left at their mouse-sized padding. */
|
|
3099
|
+
.pptxv-parity-footer button { min-width: 44px; min-height: 44px; }
|
|
3100
|
+
.pptxv-parity-select select, .pptxv-custom-shows-active select { min-height: 44px; }
|
|
3101
|
+
.pptxv-parity-check, .pptxv-parity-range { min-height: 44px; }
|
|
3102
|
+
.pptxv-parity-tabs button { min-height: 44px; }
|
|
3103
|
+
}
|
|
3046
3104
|
.pptxv-ole-edit-dialog { width: min(600px, calc(100vw - 32px)); }
|
|
3047
3105
|
.pptxv-ole-edit-loading, .pptxv-ole-edit-empty { color: var(--pptx-muted-foreground); }
|
|
3048
3106
|
.pptxv-ole-edit-error { color: var(--pptx-destructive); }
|
|
@@ -3055,6 +3113,15 @@
|
|
|
3055
3113
|
.pptxv-ole-edit-paragraphs textarea { padding: 6px 8px; border: 1px solid var(--pptx-border); border-radius: 4px; background: var(--pptx-muted); color: inherit; resize: vertical; }
|
|
3056
3114
|
.pptxv-ole-edit-deck-row { display: flex; flex-direction: column; gap: 4px; color: var(--pptx-muted-foreground); }
|
|
3057
3115
|
.pptxv-ole-edit-deck-row input { padding: 6px 8px; border: 1px solid var(--pptx-border); border-radius: 4px; background: var(--pptx-muted); color: var(--pptx-foreground); }
|
|
3116
|
+
/* Touch target: matches MIN_TOUCH_TARGET_PX (44) from pptx-viewer-shared's
|
|
3117
|
+
render/responsive module, below MOBILE_BREAKPOINT (768). The workspace
|
|
3118
|
+
Comments pane's "Add Comment" button (comments-panel.ts) carries no class
|
|
3119
|
+
of its own; `!important` beats css.ts's baseline
|
|
3120
|
+
`.pptxv :is(button, [role='button'])... { min-height: 24px; }`, whose
|
|
3121
|
+
chained :not() pseudo-classes out-specificity a plain class selector. */
|
|
3122
|
+
@media (max-width: 767px) {
|
|
3123
|
+
.pptxv-workspace-list button, .pptxv-workspace-pane header button { min-height: 44px !important; }
|
|
3124
|
+
}
|
|
3058
3125
|
|
|
3059
3126
|
|
|
3060
3127
|
/* ── Dialog shell override: the Options dialog is wider than parity dialogs ── */
|
|
@@ -3150,7 +3217,23 @@ label.pptxv-options-row { cursor: pointer; }
|
|
|
3150
3217
|
opacity/pointer-events on mousemove; !important here is required to win
|
|
3151
3218
|
over that inline style regardless of the JS auto-show timer. */
|
|
3152
3219
|
.pptxv.pptxv-no-show-popup .pptxv-present-toolbar-wrap { opacity: 0 !important; pointer-events: none !important; }
|
|
3153
|
-
@media (max-width: 767px) {
|
|
3220
|
+
@media (max-width: 767px) {
|
|
3221
|
+
.pptxv-options-body { flex-direction: column; }
|
|
3222
|
+
.pptxv-options-nav { flex-direction: row; width: 100%; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--pptx-border); }
|
|
3223
|
+
/* Matches isDensePanelCompact()/MOBILE_BREAKPOINT (768) in
|
|
3224
|
+
pptx-viewer-shared: getDensePanelTouchTargetPx(width) returns
|
|
3225
|
+
MIN_TOUCH_TARGET_PX (44). Every schema-driven control row (toggle /
|
|
3226
|
+
select / number / text, across every tab) gets a touch-sized hit area:
|
|
3227
|
+
the row itself (a <label> for a toggle, so enlarging it is enough there)
|
|
3228
|
+
and each select/text/number control. */
|
|
3229
|
+
.pptxv-options-row { min-height: 44px; }
|
|
3230
|
+
.pptxv-options-row select, .pptxv-options-row input[type='text'], .pptxv-options-row input[type='number'] { min-height: 44px; }
|
|
3231
|
+
/* The category rail's own tab buttons are discrete one-per-row controls
|
|
3232
|
+
too, so they get the same touch target as everything else in this
|
|
3233
|
+
dialog below the breakpoint - CLAUDE.md Rule 1 (React's SettingsDialog
|
|
3234
|
+
navBtnStyle already covers its own nav for the same reason). */
|
|
3235
|
+
.pptxv-options-nav button { min-height: 44px; }
|
|
3236
|
+
}
|
|
3154
3237
|
|
|
3155
3238
|
|
|
3156
3239
|
/* Animations > Animation: the full 27-preset catalogue in three captioned
|
|
@@ -3347,6 +3430,23 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
3347
3430
|
.pptxv-anim-bar-seg.is-exit { background: rgb(239 68 68 / 0.6); }
|
|
3348
3431
|
.pptxv-anim-bar-seg.is-none { background: color-mix(in srgb, var(--pptx-muted-foreground) 40%, transparent); }
|
|
3349
3432
|
.pptxv-anim-bar-seg.is-selected { outline: 1px solid var(--pptx-ring); }
|
|
3433
|
+
/* Below this width, matches isDensePanelCompact()/MOBILE_BREAKPOINT (768) in
|
|
3434
|
+
pptx-viewer-shared: getDensePanelTouchTargetPx(width) returns
|
|
3435
|
+
MIN_TOUCH_TARGET_PX (44) instead of DEFAULT_DENSE_BUTTON_PX (28), so the
|
|
3436
|
+
direction picker and the Preview button clear a touch-sized hit area. The
|
|
3437
|
+
panel is already single-column at every width. */
|
|
3438
|
+
@media (max-width: 767px) {
|
|
3439
|
+
.pptxv-anim-direction-btn, .pptxv-anim-preview-btn {
|
|
3440
|
+
min-width: 44px !important;
|
|
3441
|
+
min-height: 44px !important;
|
|
3442
|
+
}
|
|
3443
|
+
/* animation-panel-fields.ts's animSelect/animNumber (Entrance/Emphasis/Exit
|
|
3444
|
+
effect pickers, ...) carry no class of their own on the control. */
|
|
3445
|
+
.pptxv-inspector-animation select,
|
|
3446
|
+
.pptxv-inspector-animation input {
|
|
3447
|
+
min-height: 44px;
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3350
3450
|
|
|
3351
3451
|
/* ── Comments tab: threads, replies, edit-in-place ───────────────────── */
|
|
3352
3452
|
.pptxv-inspector-comment-badge {
|
|
@@ -3423,6 +3523,28 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
3423
3523
|
}
|
|
3424
3524
|
.pptxv-action-return-row[hidden] { display: none; }
|
|
3425
3525
|
|
|
3526
|
+
/* ── Table style editor: touch target only ────────────────────────────
|
|
3527
|
+
.pptxv-tse and .pptxv-tsef classes (table-style-editor.ts /
|
|
3528
|
+
table-style-editor-fields.ts) otherwise carry no CSS at all in this
|
|
3529
|
+
binding (unstyled/browser-default buttons) - out of scope to redesign
|
|
3530
|
+
here, but the Bold/Italic/Underline toggles and the editor's own action
|
|
3531
|
+
buttons still need to clear the WCAG touch target below the mobile
|
|
3532
|
+
breakpoint (768, MOBILE_BREAKPOINT / MIN_TOUCH_TARGET_PX in
|
|
3533
|
+
pptx-viewer-shared) since they are real, single-letter/narrow buttons. */
|
|
3534
|
+
@media (max-width: 767px) {
|
|
3535
|
+
.pptxv-tsef-toggle, .pptxv-tse-btn, .pptxv-tse-parts button, .pptxv-tse-actions button, .pptxv-tse-header button {
|
|
3536
|
+
min-width: 44px !important;
|
|
3537
|
+
min-height: 44px !important;
|
|
3538
|
+
}
|
|
3539
|
+
/* Action Settings section (action-section.ts): the trigger-type and
|
|
3540
|
+
custom-show <select>s carry no class of their own, so target them
|
|
3541
|
+
through the fieldset wrapper. !important is load-bearing (see
|
|
3542
|
+
css.ts's baseline .pptxv :is(button, [role='button'])... note above). */
|
|
3543
|
+
.pptxv-action-fieldset select {
|
|
3544
|
+
min-height: 44px !important;
|
|
3545
|
+
}
|
|
3546
|
+
}
|
|
3547
|
+
|
|
3426
3548
|
|
|
3427
3549
|
/* ── Quick Styles gallery ────────────────────────────────────────────── */
|
|
3428
3550
|
.pptxv-quick-styles {
|
|
@@ -3440,6 +3562,13 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
3440
3562
|
}
|
|
3441
3563
|
.pptxv-quick-style:hover:not(:disabled) { outline: 2px solid var(--pptx-primary); outline-offset: -1px; }
|
|
3442
3564
|
.pptxv-quick-style:disabled { opacity: 0.5; cursor: default; }
|
|
3565
|
+
/* Each preset is a discrete, individually-named action button (not a colour
|
|
3566
|
+
swatch), so it gets the shared WCAG touch target below the mobile
|
|
3567
|
+
breakpoint (768px, MOBILE_BREAKPOINT / getDensePanelTouchTargetPx in
|
|
3568
|
+
pptx-viewer-shared) rather than an exemption - CLAUDE.md Rule 2. */
|
|
3569
|
+
@media (max-width: 767px) {
|
|
3570
|
+
.pptxv-quick-style { height: 44px !important; min-width: 44px !important; }
|
|
3571
|
+
}
|
|
3443
3572
|
|
|
3444
3573
|
/* ── 3D text ─────────────────────────────────────────────────────────── */
|
|
3445
3574
|
.pptxv-text3d-options { display: grid; gap: 6px; }
|
|
@@ -3469,7 +3598,7 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
3469
3598
|
}
|
|
3470
3599
|
.pptxv-chart-grid-btn:hover:not(:disabled) { background: var(--pptx-accent); color: var(--pptx-accent-foreground); }
|
|
3471
3600
|
.pptxv-chart-grid-table { width: 100%; border-collapse: collapse; font-size: 11px; }
|
|
3472
|
-
.pptxv-chart-grid-table th, .pptxv-chart-grid-table td { padding: 1px; }
|
|
3601
|
+
.pptxv-chart-grid-table th, .pptxv-chart-grid-table td { padding: 1px; min-width: 72px; }
|
|
3473
3602
|
.pptxv-chart-grid-table th { font-weight: 400; }
|
|
3474
3603
|
.pptxv-chart-grid-table :is(th, td) { display: table-cell; white-space: nowrap; }
|
|
3475
3604
|
.pptxv-chart-grid-cell {
|
|
@@ -3497,6 +3626,23 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
3497
3626
|
cursor: pointer;
|
|
3498
3627
|
}
|
|
3499
3628
|
.pptxv-chart-grid-remove:hover { color: var(--pptx-destructive); }
|
|
3629
|
+
/* Below this width, matches isDensePanelCompact()/MOBILE_BREAKPOINT (768) in
|
|
3630
|
+
pptx-viewer-shared: getDenseGridLayoutPlan(width) returns
|
|
3631
|
+
stickyFirstColumn: true, minCellWidthPx: 64, and
|
|
3632
|
+
getDensePanelTouchTargetPx(width) returns MIN_TOUCH_TARGET_PX (44). Pins
|
|
3633
|
+
the category-label column so a value scrolled into view still reads
|
|
3634
|
+
against its row, and gives the add/remove controls a touch-sized hit area. */
|
|
3635
|
+
@media (max-width: 767px) {
|
|
3636
|
+
.pptxv-chart-grid-table th, .pptxv-chart-grid-table td { min-width: 64px; }
|
|
3637
|
+
.pptxv-chart-grid-table th:first-child, .pptxv-chart-grid-table td:first-child {
|
|
3638
|
+
position: sticky;
|
|
3639
|
+
left: 0;
|
|
3640
|
+
z-index: 1;
|
|
3641
|
+
background: var(--pptx-background);
|
|
3642
|
+
}
|
|
3643
|
+
.pptxv-chart-grid-table thead th:first-child { z-index: 2; }
|
|
3644
|
+
.pptxv-chart-grid-btn, .pptxv-chart-grid-remove { min-width: 44px !important; min-height: 44px !important; }
|
|
3645
|
+
}
|
|
3500
3646
|
|
|
3501
3647
|
/* ── Table data grid ─────────────────────────────────────────────────── */
|
|
3502
3648
|
.pptxv-table-grid-header { display: flex; align-items: center; justify-content: space-between; gap: 4px; }
|
|
@@ -3523,7 +3669,7 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
3523
3669
|
align-items: center;
|
|
3524
3670
|
justify-content: center;
|
|
3525
3671
|
gap: 2px;
|
|
3526
|
-
min-width:
|
|
3672
|
+
min-width: 72px;
|
|
3527
3673
|
margin: -1px 0 0 -1px;
|
|
3528
3674
|
padding: 1px 3px;
|
|
3529
3675
|
border: 1px solid var(--pptx-border);
|
|
@@ -3531,11 +3677,11 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
3531
3677
|
color: var(--pptx-muted-foreground);
|
|
3532
3678
|
white-space: nowrap;
|
|
3533
3679
|
}
|
|
3534
|
-
.pptxv-table-grid-gutter { flex: 0 0 38px; }
|
|
3680
|
+
.pptxv-table-grid-gutter { flex: 0 0 38px; min-width: 38px; }
|
|
3535
3681
|
.pptxv-table-grid-cell {
|
|
3536
3682
|
display: flex;
|
|
3537
3683
|
flex: 1 1 56px;
|
|
3538
|
-
min-width:
|
|
3684
|
+
min-width: 72px;
|
|
3539
3685
|
margin: -1px 0 0 -1px;
|
|
3540
3686
|
padding: 1px;
|
|
3541
3687
|
border: 1px solid var(--pptx-border);
|
|
@@ -3564,6 +3710,24 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
3564
3710
|
}
|
|
3565
3711
|
.pptxv-table-grid-remove[hidden] { display: none; }
|
|
3566
3712
|
.pptxv-table-grid-remove:hover { color: var(--pptx-destructive); }
|
|
3713
|
+
/* Below this width, matches isDensePanelCompact()/MOBILE_BREAKPOINT (768) in
|
|
3714
|
+
pptx-viewer-shared: getDenseGridLayoutPlan(width) returns
|
|
3715
|
+
stickyFirstColumn: true, minCellWidthPx: 64, and
|
|
3716
|
+
getDensePanelTouchTargetPx(width) returns MIN_TOUCH_TARGET_PX (44). Pins
|
|
3717
|
+
the row-number gutter so a cell scrolled into view still reads against its
|
|
3718
|
+
row, and gives the add/remove controls a touch-sized hit area. */
|
|
3719
|
+
@media (max-width: 767px) {
|
|
3720
|
+
.pptxv-table-grid-head:not(.pptxv-table-grid-gutter), .pptxv-table-grid-cell { min-width: 64px; }
|
|
3721
|
+
.pptxv-table-grid-gutter {
|
|
3722
|
+
min-width: 38px;
|
|
3723
|
+
position: sticky;
|
|
3724
|
+
left: 0;
|
|
3725
|
+
z-index: 1;
|
|
3726
|
+
background: var(--pptx-muted);
|
|
3727
|
+
}
|
|
3728
|
+
.pptxv-table-grid-btn { min-width: 44px !important; min-height: 44px !important; }
|
|
3729
|
+
.pptxv-table-grid-remove { min-width: 44px !important; min-height: 44px !important; }
|
|
3730
|
+
}
|
|
3567
3731
|
|
|
3568
3732
|
/* ── Media trim timeline ─────────────────────────────────────────────── */
|
|
3569
3733
|
.pptxv-media-timeline { display: grid; gap: 2px; margin: 6px 0; }
|
|
@@ -3756,6 +3920,43 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
3756
3920
|
}
|
|
3757
3921
|
.pptxv-image-alt-input:focus-visible { outline: 2px solid var(--pptx-ring); outline-offset: -1px; }
|
|
3758
3922
|
|
|
3923
|
+
/* chart-exhaustive-controls.ts's field()/tokenSelect() factory backs dozens
|
|
3924
|
+
of chart/table controls (Chart type, Grouping, Alignment, ...) and carried
|
|
3925
|
+
no class of its own, so a touch-target fix here reaches all of them. */
|
|
3926
|
+
@media (max-width: 767px) {
|
|
3927
|
+
.pptxv-exhaustive-field-control { min-height: 44px; min-width: 44px; }
|
|
3928
|
+
/* text-effects-controls.ts's own local field() helper (Transform warp
|
|
3929
|
+
select, ...) carries no class of its own either; target it through its
|
|
3930
|
+
section container. */
|
|
3931
|
+
.pptxv-inspector-text-effects select,
|
|
3932
|
+
.pptxv-inspector-text-effects input {
|
|
3933
|
+
min-height: 44px;
|
|
3934
|
+
}
|
|
3935
|
+
/* Several other inspector sub-panels' own local field() helpers
|
|
3936
|
+
(chart-filtered-series-section.ts, connector-arrow-controls.ts,
|
|
3937
|
+
table-cell-formatting.ts, shape-effects-controls.ts) carry no class of
|
|
3938
|
+
their own on the control either; same fix, through each section's own
|
|
3939
|
+
container class. Buttons get !important (css.ts's baseline, see the
|
|
3940
|
+
.pptxv-quick-style rule above); selects/inputs do not need it. */
|
|
3941
|
+
.pptxv-chart-filters select, .pptxv-chart-filters input,
|
|
3942
|
+
.pptxv-inspector-connector-arrows select, .pptxv-inspector-connector-arrows input,
|
|
3943
|
+
.pptxv-inspector-table-cell select, .pptxv-inspector-table-cell input,
|
|
3944
|
+
.pptxv-inspector-table-cell-fill select, .pptxv-inspector-table-cell-fill input,
|
|
3945
|
+
.pptxv-inspector-shape-effects select, .pptxv-inspector-shape-effects input {
|
|
3946
|
+
min-height: 44px;
|
|
3947
|
+
}
|
|
3948
|
+
.pptxv-chart-filters button,
|
|
3949
|
+
.pptxv-inspector-connector-arrows button,
|
|
3950
|
+
.pptxv-inspector-table-cell button,
|
|
3951
|
+
.pptxv-inspector-table-cell-fill button,
|
|
3952
|
+
.pptxv-inspector-table-structure button,
|
|
3953
|
+
.pptxv-chart-usershapes button,
|
|
3954
|
+
.pptxv-inspector-shape-effects button {
|
|
3955
|
+
min-width: 44px !important;
|
|
3956
|
+
min-height: 44px !important;
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
|
|
3759
3960
|
|
|
3760
3961
|
.pptxv-account { display: flex; flex-direction: column; gap: 28px; max-width: 640px; margin-top: 24px; }
|
|
3761
3962
|
.pptxv-account-section { padding: 20px; border: 1px solid var(--pptx-border); border-radius: 8px; background: var(--pptx-card); color: var(--pptx-card-foreground); }
|
|
@@ -4070,6 +4271,9 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
4070
4271
|
box-shadow: 0 -12px 36px rgb(0 0 0 / 0.35);
|
|
4071
4272
|
}
|
|
4072
4273
|
.pptxv.pptxv-presenting .pptxv-ai-panel { display: none; }
|
|
4274
|
+
/* Touch target: matches MIN_TOUCH_TARGET_PX (44) from pptx-viewer-shared's
|
|
4275
|
+
render/responsive module. */
|
|
4276
|
+
.pptxv-ai-close { min-width: 44px !important; min-height: 44px !important; }
|
|
4073
4277
|
}
|
|
4074
4278
|
|
|
4075
4279
|
|
|
@@ -4201,6 +4405,11 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
4201
4405
|
font-size: 0.625rem;
|
|
4202
4406
|
color: var(--pptx-muted-foreground);
|
|
4203
4407
|
}
|
|
4408
|
+
/* Touch target: matches MIN_TOUCH_TARGET_PX (44) from pptx-viewer-shared's
|
|
4409
|
+
render/responsive module, below MOBILE_BREAKPOINT (768). */
|
|
4410
|
+
@media (max-width: 767px) {
|
|
4411
|
+
.pptxv-ai-chats, .pptxv-ai-history-new, .pptxv-ai-history-delete { min-width: 44px !important; min-height: 44px !important; }
|
|
4412
|
+
}
|
|
4204
4413
|
|
|
4205
4414
|
|
|
4206
4415
|
/* ── Focused-target bar ───────────────────────────────────────────────── */
|
|
@@ -4270,6 +4479,11 @@ svg[data-pptx-motion-path-overlay] [data-pptx-motion-path-handle] { pointer-even
|
|
|
4270
4479
|
cursor: pointer;
|
|
4271
4480
|
}
|
|
4272
4481
|
.pptxv-ai-focus-merge svg { width: 12px; height: 12px; }
|
|
4482
|
+
/* Touch target: matches MIN_TOUCH_TARGET_PX (44) from pptx-viewer-shared's
|
|
4483
|
+
render/responsive module, below MOBILE_BREAKPOINT (768). */
|
|
4484
|
+
@media (max-width: 767px) {
|
|
4485
|
+
.pptxv-ai-focus-btn, .pptxv-ai-focus-merge, .pptxv-ai-focus-pick-done { min-width: 44px !important; min-height: 44px !important; }
|
|
4486
|
+
}
|
|
4273
4487
|
|
|
4274
4488
|
/* ── Pick-mode banner ─────────────────────────────────────────────────── */
|
|
4275
4489
|
.pptxv-ai-focus-pick {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pptx-vanilla-viewer",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"description": "Zero-framework PowerPoint viewer and editor: render, edit, present, and export PPTX slides with plain DOM, no React/Vue/Angular required.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"javascript",
|
|
@@ -61,10 +61,12 @@
|
|
|
61
61
|
"jspdf": "^4.2.1",
|
|
62
62
|
"jszip": "^3.10.2",
|
|
63
63
|
"lucide": "^1.43.0",
|
|
64
|
+
"opentype.js": "^2.0.0",
|
|
64
65
|
"pptx-viewer-mcp": "^2.5.0"
|
|
65
66
|
},
|
|
66
67
|
"devDependencies": {
|
|
67
68
|
"@types/dompurify": "^3.2.0",
|
|
69
|
+
"@types/opentype.js": "^1.3.10",
|
|
68
70
|
"happy-dom": "^20.14.0",
|
|
69
71
|
"tsdown": "^0.23.0",
|
|
70
72
|
"tsup": "^8.5.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
'use strict';var chunkWTF4OTWQ_cjs=require('./chunk-WTF4OTWQ.cjs');require('./chunk-B5PFHICE.cjs');function K(o){let{doc:t,t:n,controller:i}=o,a=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-focus"),h=(p,m,l)=>{let s=chunkWTF4OTWQ_cjs.Xn(t,"button","pptxv-ai-focus-btn");return s.type="button",s.title=m,s.setAttribute("aria-label",m),s.appendChild(chunkWTF4OTWQ_cjs.io(t,p)),s.addEventListener("click",l),s},x=()=>{a.replaceChildren();let p=i.getEffectiveTargets(),m=i.hasPicks(),l=i.isPinned(),s=i.isPicking(),g=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-focus-row"),f=chunkWTF4OTWQ_cjs.Xn(t,"span","pptxv-ai-focus-label");f.textContent=n("pptx.ai.focusScope"),g.appendChild(f);for(let r of chunkWTF4OTWQ_cjs.Kn(p,o.getSlides())){let b=chunkWTF4OTWQ_cjs.Xn(t,"span","pptxv-ai-focus-chip");(m||l)&&b.classList.add("is-strong"),b.title=r.title,b.textContent=r.label,g.appendChild(b);}if(l){let r=chunkWTF4OTWQ_cjs.Xn(t,"span","pptxv-ai-focus-pinned");r.textContent=n("pptx.ai.pinnedFocus"),g.appendChild(r);}let C=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-focus-actions"),d=chunkWTF4OTWQ_cjs.Ln(p,o.getSlides());if(d){let r=chunkWTF4OTWQ_cjs.Xn(t,"button","pptxv-ai-focus-merge");r.type="button",r.append(chunkWTF4OTWQ_cjs.io(t,"git-merge"),t.createTextNode(n("pptx.ai.mergeSelectedTables"))),r.addEventListener("click",()=>o.onSendDirective(chunkWTF4OTWQ_cjs.Mn(d.slideIndex,d.elementIdA,d.elementIdB))),C.appendChild(r);}let y=h("crosshair",n("pptx.ai.pickElement"),()=>s?i.stopPicking():i.startPicking());if(y.setAttribute("aria-pressed",String(s)),y.classList.toggle("is-active",s),C.appendChild(y),m?C.appendChild(h("close",n("pptx.ai.pickClear"),()=>i.clearPicks())):l?C.appendChild(h("pin-off",n("pptx.ai.clearFocus"),()=>i.clearPinnedFocus())):C.appendChild(h("pin",n("pptx.ai.pinFocus"),()=>i.pinFocus())),g.appendChild(C),a.appendChild(g),s){let r=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-focus-pick"),b=chunkWTF4OTWQ_cjs.io(t,"crosshair");b.classList.add("pptxv-ai-focus-pick-icon");let k=chunkWTF4OTWQ_cjs.Xn(t,"span","pptxv-ai-focus-pick-hint");k.textContent=n("pptx.ai.pickElementHint");let T=chunkWTF4OTWQ_cjs.Xn(t,"button","pptxv-ai-focus-pick-done");T.type="button",T.textContent=n("pptx.ai.pickDone"),T.addEventListener("click",()=>i.stopPicking()),r.append(b,k,T),a.appendChild(r);}},c=i.subscribe(x);return x(),{el:a,destroy(){c(),a.remove();}}}function O(o){let{doc:t,t:n}=o,i=chunkWTF4OTWQ_cjs.Xn(t,"button","pptxv-ai-chats");i.type="button",i.append(chunkWTF4OTWQ_cjs.io(t,"history"),t.createTextNode(n("pptx.ai.chats")));let a=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-history");a.hidden=true;let h=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-history-head"),x=chunkWTF4OTWQ_cjs.Xn(t,"span","pptxv-ai-history-title");x.textContent=n("pptx.ai.historyTitle");let c=chunkWTF4OTWQ_cjs.Xn(t,"button","pptxv-ai-history-new");c.type="button",c.append(chunkWTF4OTWQ_cjs.io(t,"plus"),t.createTextNode(n("pptx.ai.newChat"))),h.append(x,c);let p=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-history-body"),m=chunkWTF4OTWQ_cjs.Xn(t,"p","pptxv-ai-history-hint");m.textContent=n("pptx.ai.historyHint"),a.append(h,p,m);let l=chunkWTF4OTWQ_cjs.On({deckId:o.deckId,store:o.store,getMessages:o.getMessages,setMessages:o.setMessages,untitledLabel:n("pptx.ai.untitledChat"),onChatsChanged:()=>s()});function s(){p.replaceChildren();let f=l.chats();if(f.length===0){let d=chunkWTF4OTWQ_cjs.Xn(t,"p","pptxv-ai-history-empty");d.textContent=n("pptx.ai.historyEmpty"),p.appendChild(d);return}let C=chunkWTF4OTWQ_cjs.Xn(t,"ul","pptxv-ai-history-list");for(let d of f){let y=chunkWTF4OTWQ_cjs.Xn(t,"li","pptxv-ai-history-row"),r=chunkWTF4OTWQ_cjs.Xn(t,"button","pptxv-ai-history-resume");r.type="button",r.classList.toggle("is-active",d.id===l.activeChatId());let b=chunkWTF4OTWQ_cjs.Xn(t,"span","pptxv-ai-history-text"),k=chunkWTF4OTWQ_cjs.Xn(t,"span","pptxv-ai-history-name");k.textContent=d.title||n("pptx.ai.untitledChat");let T=chunkWTF4OTWQ_cjs.Xn(t,"span","pptxv-ai-history-meta");T.textContent=n("pptx.ai.messageCount",{count:d.messageCount}),b.append(k,T),r.append(chunkWTF4OTWQ_cjs.io(t,"comment"),b),r.addEventListener("click",()=>{l.resumeChat(d.id),a.hidden=true;});let P=chunkWTF4OTWQ_cjs.Xn(t,"button","pptxv-ai-history-delete");P.type="button",P.title=n("pptx.ai.deleteChat"),P.setAttribute("aria-label",n("pptx.ai.deleteChat")),P.appendChild(chunkWTF4OTWQ_cjs.io(t,"trash")),P.addEventListener("click",()=>{l.deleteChat(d.id);}),y.append(r,P),C.appendChild(y);}p.appendChild(C);}s(),i.addEventListener("click",()=>{a.hidden=!a.hidden;}),c.addEventListener("click",()=>{l.newChat(),a.hidden=true;});let g=f=>{a.hidden||!(f.target instanceof Node)||!a.contains(f.target)&&!i.contains(f.target)&&(a.hidden=true);};return t.addEventListener("mousedown",g),{button:i,el:a,notifyMessagesChanged:()=>l.notifyMessagesChanged(),destroy(){t.removeEventListener("mousedown",g),l.dispose(),i.remove(),a.remove();}}}var _={view:"eye",text:"text-box",shape:"shapes",theme:"font-color",table:"table",slide:"layout",chart:"chart",move:"move-right",delete:"trash",search:"search",nav:"move-right",animation:"play",notes:"sticky-note",tool:"wrench"};function W(o,t,n){let i=t.state==="output-error",a=t.state==="output-available",h=!i&&!a,x=chunkWTF4OTWQ_cjs.Tn(t.toolName,t.input,h?"present":"past"),c=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-tool"),p=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-tool-head"),m=chunkWTF4OTWQ_cjs.io(o,_[x.icon]??"wrench");m.classList.add("pptxv-ai-tool-icon");let l=chunkWTF4OTWQ_cjs.Xn(o,"span","pptxv-ai-tool-name");l.textContent=x.label;let s=chunkWTF4OTWQ_cjs.Xn(o,"span","pptxv-ai-tool-state");if(i?(s.classList.add("is-error"),s.append(chunkWTF4OTWQ_cjs.io(o,"alert"),o.createTextNode(n("pptx.ai.toolFailed")))):a?(s.classList.add("is-done"),s.append(chunkWTF4OTWQ_cjs.io(o,"check"),o.createTextNode(n("pptx.ai.toolDone")))):(s.classList.add("is-running"),s.textContent=n("pptx.ai.toolRunning")),p.append(m,l,s),c.appendChild(p),i&&t.errorText){let f=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-tool-error");f.textContent=t.errorText,c.appendChild(f);}let g=chunkWTF4OTWQ_cjs.Sn(t.input);if(g){let f=chunkWTF4OTWQ_cjs.Xn(o,"details","pptxv-ai-tool-details"),C=chunkWTF4OTWQ_cjs.Xn(o,"summary");C.textContent=n("pptx.ai.toolDetails");let d=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-tool-raw");d.textContent=`${chunkWTF4OTWQ_cjs.Rn(t.toolName)}: ${g}`,f.append(C,d),c.appendChild(f);}return c}function q(o,t,n,i){t.replaceChildren();for(let a of n){if(a.role==="system")continue;let h=a.role==="user",x=chunkWTF4OTWQ_cjs.Gn(a);if(x.length===0&&!h)continue;let c=chunkWTF4OTWQ_cjs.Xn(o,"div",`pptxv-ai-msg pptxv-ai-msg-${a.role}`),p=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-msg-avatar");p.setAttribute("aria-label",i(h?"pptx.ai.you":"pptx.ai.assistant")),p.appendChild(chunkWTF4OTWQ_cjs.io(o,h?"comment":"sparkles"));let m=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-msg-body");for(let l of x)if(l.kind==="text"){let s=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-msg-text");s.textContent=l.text,m.appendChild(s);}else m.appendChild(W(o,l,i));c.append(p,m),t.appendChild(c);}}function G(o,t,n,i,a){if(t.replaceChildren(),t.hidden=n.length===0,n.length===0)return;let h=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-proposals-header"),x=chunkWTF4OTWQ_cjs.Xn(o,"span","pptxv-ai-proposals-title");if(x.textContent=i("pptx.ai.pendingChanges",{count:n.length}),h.appendChild(x),n.length>1){let c=chunkWTF4OTWQ_cjs.Xn(o,"button","pptxv-ai-proposal-btn is-accept-all");c.type="button",c.textContent=i("pptx.ai.acceptAll"),c.addEventListener("click",()=>a.acceptAll()),h.appendChild(c);}t.appendChild(h);for(let c of n)t.appendChild(tt(o,c,i,a));}function tt(o,t,n,i){let a=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-proposal");a.dataset.proposalId=t.id;let h=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-proposal-eyebrow");h.textContent=n("pptx.ai.proposedChange"),a.appendChild(h);let x=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-proposal-label");if(x.textContent=t.label,a.appendChild(x),t.summary.length>0){let l=chunkWTF4OTWQ_cjs.Xn(o,"ul","pptxv-ai-proposal-summary");for(let s of t.summary){let g=chunkWTF4OTWQ_cjs.Xn(o,"li");g.textContent=chunkWTF4OTWQ_cjs.Dn(s),l.appendChild(g);}a.appendChild(l);}let c=chunkWTF4OTWQ_cjs.Xn(o,"div","pptxv-ai-proposal-actions"),p=chunkWTF4OTWQ_cjs.Xn(o,"button","pptxv-ai-proposal-btn is-accept");p.type="button",p.append(chunkWTF4OTWQ_cjs.io(o,"check"),o.createTextNode(n("pptx.ai.accept"))),p.addEventListener("click",()=>i.accept(t.id));let m=chunkWTF4OTWQ_cjs.Xn(o,"button","pptxv-ai-proposal-btn is-reject");return m.type="button",m.append(chunkWTF4OTWQ_cjs.io(o,"close"),o.createTextNode(n("pptx.ai.reject"))),m.addEventListener("click",()=>i.reject(t.id)),c.append(p,m),a.appendChild(c),a}async function wt(o){let{doc:t,host:n,t:i}=o;n.replaceChildren();let a=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-header"),h=chunkWTF4OTWQ_cjs.Xn(t,"span","pptxv-ai-title");h.textContent=i("pptx.ai.title");let x=chunkWTF4OTWQ_cjs.Xn(t,"button","pptxv-ai-close");x.type="button",x.title=i("pptx.ai.close"),x.setAttribute("aria-label",i("pptx.ai.close")),x.appendChild(chunkWTF4OTWQ_cjs.io(t,"close")),x.addEventListener("click",()=>o.onClose?.()),a.append(chunkWTF4OTWQ_cjs.io(t,"sparkles"),h,x);let c,p=o.controller,m=p?K({doc:t,t:i,controller:p,getSlides:()=>o.bridge.getSlides(),onSendDirective:u=>{c?.sendMessage(u);}}):null,l=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-messages");l.setAttribute("role","log"),l.setAttribute("aria-live","polite");let s=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-empty");s.textContent=i("pptx.ai.emptyHint"),l.appendChild(s);let g=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-proposals");g.hidden=true;let f=chunkWTF4OTWQ_cjs.Xn(t,"div","pptxv-ai-error");f.setAttribute("role","alert"),f.hidden=true;let C=chunkWTF4OTWQ_cjs.Xn(t,"form","pptxv-ai-composer"),d=chunkWTF4OTWQ_cjs.Xn(t,"textarea","pptxv-ai-input");d.rows=2,d.placeholder=i("pptx.ai.placeholder"),d.setAttribute("aria-label",i("pptx.ai.placeholder"));let y=chunkWTF4OTWQ_cjs.Xn(t,"button","pptxv-ai-send");y.type="submit",y.setAttribute("aria-label",i("pptx.ai.send")),y.appendChild(chunkWTF4OTWQ_cjs.io(t,"send")),C.append(d,y),n.append(a,...m?[m.el]:[],l,g,f,C);try{c=await(o.createChat??chunkWTF4OTWQ_cjs.Pn)({bridge:o.bridge,config:o.config});}catch{return s.textContent=i("pptx.ai.unavailableTitle"),d.disabled=true,y.disabled=true,m?.destroy(),{destroy:()=>n.replaceChildren()}}let r=c,b=O({doc:t,t:i,deckId:chunkWTF4OTWQ_cjs.Nn(o.bridge),store:o.historyStore,getMessages:()=>r.getSnapshot().messages,setMessages:u=>r.setMessages(u)});a.insertBefore(b.button,x),n.appendChild(b.el);let k=r.subscribe(()=>b.notifyMessagesChanged()),T=new Set,P=u=>{if(!p)return;let A=u.messages.flatMap(Y=>chunkWTF4OTWQ_cjs.Gn(Y).filter(Z=>Z.kind==="tool")).at(-1);if(!A||A.kind!=="tool"||A.state==="input-streaming"||T.has(A.toolCallId))return;T.add(A.toolCallId);let L=chunkWTF4OTWQ_cjs.Un(A.toolName,A.input);L&&L.slideIndex!==void 0&&o.goToSlide?.(L.slideIndex),p.flashToolTarget(L);},M=u=>{q(t,l,u.messages,i),s.hidden=u.messages.length>0,u.messages.length===0&&l.appendChild(s),G(t,g,r.proposals.list(),i,{accept:A=>{p?.flashToolTarget(null),r.proposals.apply(A),M(r.getSnapshot());},reject:A=>{r.proposals.revert(A),M(r.getSnapshot());},acceptAll:()=>{p?.flashToolTarget(null),r.proposals.acceptAll(),M(r.getSnapshot());}});let w=u.status==="submitted"||u.status==="streaming";n.classList.toggle("is-busy",w),y.setAttribute("aria-label",i(w?"pptx.ai.stop":"pptx.ai.send")),f.hidden=!u.error,f.textContent=u.error?i("pptx.ai.errorPrefix"):"",l.scrollTop=l.scrollHeight,P(u);},S=()=>{if(n.classList.contains("is-busy")){r.stop();return}let u=d.value.trim();u&&(d.value="",r.sendMessage(u));};C.addEventListener("submit",u=>{u.preventDefault(),S();}),d.addEventListener("keydown",u=>{u.key==="Enter"&&!u.shiftKey&&(u.preventDefault(),S());});let I=p?.getPrefill().nonce??0,J=()=>{if(!p)return;let u=p.getPrefill();u.nonce!==I&&(I=u.nonce,d.value=u.text,d.focus());},Q=p?.subscribe(J),X=r.subscribe(M);return M(r.getSnapshot()),{changeAnimator:r.changeAnimator,destroy(){X(),k(),b.destroy(),Q?.(),m?.destroy(),n.replaceChildren();}}}exports.createAiPanel=wt;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import {Xn,io,Pn,Nn,On,Gn,Un,Kn,Ln,Mn,Tn,Sn,Rn,Dn}from'./chunk-56CORRDB.js';import'./chunk-62D2TNHX.js';function K(o){let{doc:t,t:n,controller:i}=o,a=Xn(t,"div","pptxv-ai-focus"),h=(p,m,l)=>{let s=Xn(t,"button","pptxv-ai-focus-btn");return s.type="button",s.title=m,s.setAttribute("aria-label",m),s.appendChild(io(t,p)),s.addEventListener("click",l),s},x=()=>{a.replaceChildren();let p=i.getEffectiveTargets(),m=i.hasPicks(),l=i.isPinned(),s=i.isPicking(),g=Xn(t,"div","pptxv-ai-focus-row"),f=Xn(t,"span","pptxv-ai-focus-label");f.textContent=n("pptx.ai.focusScope"),g.appendChild(f);for(let r of Kn(p,o.getSlides())){let b=Xn(t,"span","pptxv-ai-focus-chip");(m||l)&&b.classList.add("is-strong"),b.title=r.title,b.textContent=r.label,g.appendChild(b);}if(l){let r=Xn(t,"span","pptxv-ai-focus-pinned");r.textContent=n("pptx.ai.pinnedFocus"),g.appendChild(r);}let C=Xn(t,"div","pptxv-ai-focus-actions"),d=Ln(p,o.getSlides());if(d){let r=Xn(t,"button","pptxv-ai-focus-merge");r.type="button",r.append(io(t,"git-merge"),t.createTextNode(n("pptx.ai.mergeSelectedTables"))),r.addEventListener("click",()=>o.onSendDirective(Mn(d.slideIndex,d.elementIdA,d.elementIdB))),C.appendChild(r);}let y=h("crosshair",n("pptx.ai.pickElement"),()=>s?i.stopPicking():i.startPicking());if(y.setAttribute("aria-pressed",String(s)),y.classList.toggle("is-active",s),C.appendChild(y),m?C.appendChild(h("close",n("pptx.ai.pickClear"),()=>i.clearPicks())):l?C.appendChild(h("pin-off",n("pptx.ai.clearFocus"),()=>i.clearPinnedFocus())):C.appendChild(h("pin",n("pptx.ai.pinFocus"),()=>i.pinFocus())),g.appendChild(C),a.appendChild(g),s){let r=Xn(t,"div","pptxv-ai-focus-pick"),b=io(t,"crosshair");b.classList.add("pptxv-ai-focus-pick-icon");let k=Xn(t,"span","pptxv-ai-focus-pick-hint");k.textContent=n("pptx.ai.pickElementHint");let T=Xn(t,"button","pptxv-ai-focus-pick-done");T.type="button",T.textContent=n("pptx.ai.pickDone"),T.addEventListener("click",()=>i.stopPicking()),r.append(b,k,T),a.appendChild(r);}},c=i.subscribe(x);return x(),{el:a,destroy(){c(),a.remove();}}}function O(o){let{doc:t,t:n}=o,i=Xn(t,"button","pptxv-ai-chats");i.type="button",i.append(io(t,"history"),t.createTextNode(n("pptx.ai.chats")));let a=Xn(t,"div","pptxv-ai-history");a.hidden=true;let h=Xn(t,"div","pptxv-ai-history-head"),x=Xn(t,"span","pptxv-ai-history-title");x.textContent=n("pptx.ai.historyTitle");let c=Xn(t,"button","pptxv-ai-history-new");c.type="button",c.append(io(t,"plus"),t.createTextNode(n("pptx.ai.newChat"))),h.append(x,c);let p=Xn(t,"div","pptxv-ai-history-body"),m=Xn(t,"p","pptxv-ai-history-hint");m.textContent=n("pptx.ai.historyHint"),a.append(h,p,m);let l=On({deckId:o.deckId,store:o.store,getMessages:o.getMessages,setMessages:o.setMessages,untitledLabel:n("pptx.ai.untitledChat"),onChatsChanged:()=>s()});function s(){p.replaceChildren();let f=l.chats();if(f.length===0){let d=Xn(t,"p","pptxv-ai-history-empty");d.textContent=n("pptx.ai.historyEmpty"),p.appendChild(d);return}let C=Xn(t,"ul","pptxv-ai-history-list");for(let d of f){let y=Xn(t,"li","pptxv-ai-history-row"),r=Xn(t,"button","pptxv-ai-history-resume");r.type="button",r.classList.toggle("is-active",d.id===l.activeChatId());let b=Xn(t,"span","pptxv-ai-history-text"),k=Xn(t,"span","pptxv-ai-history-name");k.textContent=d.title||n("pptx.ai.untitledChat");let T=Xn(t,"span","pptxv-ai-history-meta");T.textContent=n("pptx.ai.messageCount",{count:d.messageCount}),b.append(k,T),r.append(io(t,"comment"),b),r.addEventListener("click",()=>{l.resumeChat(d.id),a.hidden=true;});let P=Xn(t,"button","pptxv-ai-history-delete");P.type="button",P.title=n("pptx.ai.deleteChat"),P.setAttribute("aria-label",n("pptx.ai.deleteChat")),P.appendChild(io(t,"trash")),P.addEventListener("click",()=>{l.deleteChat(d.id);}),y.append(r,P),C.appendChild(y);}p.appendChild(C);}s(),i.addEventListener("click",()=>{a.hidden=!a.hidden;}),c.addEventListener("click",()=>{l.newChat(),a.hidden=true;});let g=f=>{a.hidden||!(f.target instanceof Node)||!a.contains(f.target)&&!i.contains(f.target)&&(a.hidden=true);};return t.addEventListener("mousedown",g),{button:i,el:a,notifyMessagesChanged:()=>l.notifyMessagesChanged(),destroy(){t.removeEventListener("mousedown",g),l.dispose(),i.remove(),a.remove();}}}var _={view:"eye",text:"text-box",shape:"shapes",theme:"font-color",table:"table",slide:"layout",chart:"chart",move:"move-right",delete:"trash",search:"search",nav:"move-right",animation:"play",notes:"sticky-note",tool:"wrench"};function W(o,t,n){let i=t.state==="output-error",a=t.state==="output-available",h=!i&&!a,x=Tn(t.toolName,t.input,h?"present":"past"),c=Xn(o,"div","pptxv-ai-tool"),p=Xn(o,"div","pptxv-ai-tool-head"),m=io(o,_[x.icon]??"wrench");m.classList.add("pptxv-ai-tool-icon");let l=Xn(o,"span","pptxv-ai-tool-name");l.textContent=x.label;let s=Xn(o,"span","pptxv-ai-tool-state");if(i?(s.classList.add("is-error"),s.append(io(o,"alert"),o.createTextNode(n("pptx.ai.toolFailed")))):a?(s.classList.add("is-done"),s.append(io(o,"check"),o.createTextNode(n("pptx.ai.toolDone")))):(s.classList.add("is-running"),s.textContent=n("pptx.ai.toolRunning")),p.append(m,l,s),c.appendChild(p),i&&t.errorText){let f=Xn(o,"div","pptxv-ai-tool-error");f.textContent=t.errorText,c.appendChild(f);}let g=Sn(t.input);if(g){let f=Xn(o,"details","pptxv-ai-tool-details"),C=Xn(o,"summary");C.textContent=n("pptx.ai.toolDetails");let d=Xn(o,"div","pptxv-ai-tool-raw");d.textContent=`${Rn(t.toolName)}: ${g}`,f.append(C,d),c.appendChild(f);}return c}function q(o,t,n,i){t.replaceChildren();for(let a of n){if(a.role==="system")continue;let h=a.role==="user",x=Gn(a);if(x.length===0&&!h)continue;let c=Xn(o,"div",`pptxv-ai-msg pptxv-ai-msg-${a.role}`),p=Xn(o,"div","pptxv-ai-msg-avatar");p.setAttribute("aria-label",i(h?"pptx.ai.you":"pptx.ai.assistant")),p.appendChild(io(o,h?"comment":"sparkles"));let m=Xn(o,"div","pptxv-ai-msg-body");for(let l of x)if(l.kind==="text"){let s=Xn(o,"div","pptxv-ai-msg-text");s.textContent=l.text,m.appendChild(s);}else m.appendChild(W(o,l,i));c.append(p,m),t.appendChild(c);}}function G(o,t,n,i,a){if(t.replaceChildren(),t.hidden=n.length===0,n.length===0)return;let h=Xn(o,"div","pptxv-ai-proposals-header"),x=Xn(o,"span","pptxv-ai-proposals-title");if(x.textContent=i("pptx.ai.pendingChanges",{count:n.length}),h.appendChild(x),n.length>1){let c=Xn(o,"button","pptxv-ai-proposal-btn is-accept-all");c.type="button",c.textContent=i("pptx.ai.acceptAll"),c.addEventListener("click",()=>a.acceptAll()),h.appendChild(c);}t.appendChild(h);for(let c of n)t.appendChild(tt(o,c,i,a));}function tt(o,t,n,i){let a=Xn(o,"div","pptxv-ai-proposal");a.dataset.proposalId=t.id;let h=Xn(o,"div","pptxv-ai-proposal-eyebrow");h.textContent=n("pptx.ai.proposedChange"),a.appendChild(h);let x=Xn(o,"div","pptxv-ai-proposal-label");if(x.textContent=t.label,a.appendChild(x),t.summary.length>0){let l=Xn(o,"ul","pptxv-ai-proposal-summary");for(let s of t.summary){let g=Xn(o,"li");g.textContent=Dn(s),l.appendChild(g);}a.appendChild(l);}let c=Xn(o,"div","pptxv-ai-proposal-actions"),p=Xn(o,"button","pptxv-ai-proposal-btn is-accept");p.type="button",p.append(io(o,"check"),o.createTextNode(n("pptx.ai.accept"))),p.addEventListener("click",()=>i.accept(t.id));let m=Xn(o,"button","pptxv-ai-proposal-btn is-reject");return m.type="button",m.append(io(o,"close"),o.createTextNode(n("pptx.ai.reject"))),m.addEventListener("click",()=>i.reject(t.id)),c.append(p,m),a.appendChild(c),a}async function wt(o){let{doc:t,host:n,t:i}=o;n.replaceChildren();let a=Xn(t,"div","pptxv-ai-header"),h=Xn(t,"span","pptxv-ai-title");h.textContent=i("pptx.ai.title");let x=Xn(t,"button","pptxv-ai-close");x.type="button",x.title=i("pptx.ai.close"),x.setAttribute("aria-label",i("pptx.ai.close")),x.appendChild(io(t,"close")),x.addEventListener("click",()=>o.onClose?.()),a.append(io(t,"sparkles"),h,x);let c,p=o.controller,m=p?K({doc:t,t:i,controller:p,getSlides:()=>o.bridge.getSlides(),onSendDirective:u=>{c?.sendMessage(u);}}):null,l=Xn(t,"div","pptxv-ai-messages");l.setAttribute("role","log"),l.setAttribute("aria-live","polite");let s=Xn(t,"div","pptxv-ai-empty");s.textContent=i("pptx.ai.emptyHint"),l.appendChild(s);let g=Xn(t,"div","pptxv-ai-proposals");g.hidden=true;let f=Xn(t,"div","pptxv-ai-error");f.setAttribute("role","alert"),f.hidden=true;let C=Xn(t,"form","pptxv-ai-composer"),d=Xn(t,"textarea","pptxv-ai-input");d.rows=2,d.placeholder=i("pptx.ai.placeholder"),d.setAttribute("aria-label",i("pptx.ai.placeholder"));let y=Xn(t,"button","pptxv-ai-send");y.type="submit",y.setAttribute("aria-label",i("pptx.ai.send")),y.appendChild(io(t,"send")),C.append(d,y),n.append(a,...m?[m.el]:[],l,g,f,C);try{c=await(o.createChat??Pn)({bridge:o.bridge,config:o.config});}catch{return s.textContent=i("pptx.ai.unavailableTitle"),d.disabled=true,y.disabled=true,m?.destroy(),{destroy:()=>n.replaceChildren()}}let r=c,b=O({doc:t,t:i,deckId:Nn(o.bridge),store:o.historyStore,getMessages:()=>r.getSnapshot().messages,setMessages:u=>r.setMessages(u)});a.insertBefore(b.button,x),n.appendChild(b.el);let k=r.subscribe(()=>b.notifyMessagesChanged()),T=new Set,P=u=>{if(!p)return;let A=u.messages.flatMap(Y=>Gn(Y).filter(Z=>Z.kind==="tool")).at(-1);if(!A||A.kind!=="tool"||A.state==="input-streaming"||T.has(A.toolCallId))return;T.add(A.toolCallId);let L=Un(A.toolName,A.input);L&&L.slideIndex!==void 0&&o.goToSlide?.(L.slideIndex),p.flashToolTarget(L);},M=u=>{q(t,l,u.messages,i),s.hidden=u.messages.length>0,u.messages.length===0&&l.appendChild(s),G(t,g,r.proposals.list(),i,{accept:A=>{p?.flashToolTarget(null),r.proposals.apply(A),M(r.getSnapshot());},reject:A=>{r.proposals.revert(A),M(r.getSnapshot());},acceptAll:()=>{p?.flashToolTarget(null),r.proposals.acceptAll(),M(r.getSnapshot());}});let w=u.status==="submitted"||u.status==="streaming";n.classList.toggle("is-busy",w),y.setAttribute("aria-label",i(w?"pptx.ai.stop":"pptx.ai.send")),f.hidden=!u.error,f.textContent=u.error?i("pptx.ai.errorPrefix"):"",l.scrollTop=l.scrollHeight,P(u);},S=()=>{if(n.classList.contains("is-busy")){r.stop();return}let u=d.value.trim();u&&(d.value="",r.sendMessage(u));};C.addEventListener("submit",u=>{u.preventDefault(),S();}),d.addEventListener("keydown",u=>{u.key==="Enter"&&!u.shiftKey&&(u.preventDefault(),S());});let I=p?.getPrefill().nonce??0,J=()=>{if(!p)return;let u=p.getPrefill();u.nonce!==I&&(I=u.nonce,d.value=u.text,d.focus());},Q=p?.subscribe(J),X=r.subscribe(M);return M(r.getSnapshot()),{changeAnimator:r.changeAnimator,destroy(){X(),k(),b.destroy(),Q?.(),m?.destroy(),n.replaceChildren();}}}export{wt as createAiPanel};
|