@flamingo-stack/openframe-frontend-core 0.0.481 → 0.0.482
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/{chunk-H6DFCF44.cjs → chunk-22AED5IC.cjs} +82 -82
- package/dist/{chunk-H6DFCF44.cjs.map → chunk-22AED5IC.cjs.map} +1 -1
- package/dist/{chunk-MGKCS6KS.js → chunk-3WCARCI4.js} +2 -2
- package/dist/{chunk-LNKWY74S.cjs → chunk-4HL6UENH.cjs} +5 -5
- package/dist/{chunk-LNKWY74S.cjs.map → chunk-4HL6UENH.cjs.map} +1 -1
- package/dist/{chunk-Y3Y2DLNO.js → chunk-6UGYBCEN.js} +3 -3
- package/dist/{chunk-BBUEY73L.js → chunk-7I5B5PQ4.js} +6269 -5339
- package/dist/chunk-7I5B5PQ4.js.map +1 -0
- package/dist/{chunk-PSPWT2Q5.js → chunk-7LWXWXEY.js} +4 -4
- package/dist/{chunk-M7O74OWG.cjs → chunk-ACOU5YJI.cjs} +31 -31
- package/dist/{chunk-M7O74OWG.cjs.map → chunk-ACOU5YJI.cjs.map} +1 -1
- package/dist/{chunk-INDFIVDV.cjs → chunk-AHGSN4AT.cjs} +12 -12
- package/dist/{chunk-INDFIVDV.cjs.map → chunk-AHGSN4AT.cjs.map} +1 -1
- package/dist/{chunk-VTSRDC4W.js → chunk-CKC3EAYT.js} +2 -2
- package/dist/{chunk-SASR7SK5.js → chunk-GZK7FWJJ.js} +20 -4
- package/dist/chunk-GZK7FWJJ.js.map +1 -0
- package/dist/{chunk-ZRANZNEA.js → chunk-JJE5TUZK.js} +2 -2
- package/dist/{chunk-66BNAFO6.js → chunk-JQIUBFHL.js} +4 -4
- package/dist/{chunk-MMCBQJKE.cjs → chunk-KUBJHB6I.cjs} +11 -11
- package/dist/{chunk-MMCBQJKE.cjs.map → chunk-KUBJHB6I.cjs.map} +1 -1
- package/dist/{chunk-ZV6E3U3C.cjs → chunk-MRGTMMJ3.cjs} +30 -30
- package/dist/{chunk-ZV6E3U3C.cjs.map → chunk-MRGTMMJ3.cjs.map} +1 -1
- package/dist/{chunk-OZJN54R5.cjs → chunk-NWVKG7QC.cjs} +37 -37
- package/dist/{chunk-OZJN54R5.cjs.map → chunk-NWVKG7QC.cjs.map} +1 -1
- package/dist/{chunk-AN47EIIJ.cjs → chunk-PHTSSHIQ.cjs} +59 -59
- package/dist/{chunk-AN47EIIJ.cjs.map → chunk-PHTSSHIQ.cjs.map} +1 -1
- package/dist/{chunk-N2JZ33V7.cjs → chunk-RUA3OXSJ.cjs} +26 -26
- package/dist/{chunk-N2JZ33V7.cjs.map → chunk-RUA3OXSJ.cjs.map} +1 -1
- package/dist/{chunk-LK623WCC.cjs → chunk-RZPF7MJ2.cjs} +9 -9
- package/dist/{chunk-LK623WCC.cjs.map → chunk-RZPF7MJ2.cjs.map} +1 -1
- package/dist/{chunk-G3UN2DXU.cjs → chunk-STYA77PH.cjs} +20 -4
- package/dist/chunk-STYA77PH.cjs.map +1 -0
- package/dist/{chunk-JUJY3HQS.cjs → chunk-U37UTLP7.cjs} +19 -19
- package/dist/{chunk-JUJY3HQS.cjs.map → chunk-U37UTLP7.cjs.map} +1 -1
- package/dist/{chunk-2DIOV7BR.js → chunk-UPN6EFOM.js} +4 -4
- package/dist/{chunk-OWMLWJQY.cjs → chunk-VPVOJD5X.cjs} +2432 -1502
- package/dist/chunk-VPVOJD5X.cjs.map +1 -0
- package/dist/{chunk-4SMRQ4SN.js → chunk-WBL5Y4PS.js} +3 -3
- package/dist/{chunk-FP4H6Y5O.js → chunk-WPYPSIY2.js} +3 -3
- package/dist/{chunk-R5WJJL4V.js → chunk-X5X43HFV.js} +5 -5
- package/dist/{chunk-DEHZ5CTC.js → chunk-XTWKDMCG.js} +2 -2
- package/dist/components/case-studies/index.cjs +9 -9
- package/dist/components/case-studies/index.js +3 -3
- package/dist/components/chat/index.cjs +3 -3
- package/dist/components/chat/index.js +2 -2
- package/dist/components/contact/index.cjs +4 -4
- package/dist/components/contact/index.js +3 -3
- package/dist/components/docs/index.cjs +6 -6
- package/dist/components/docs/index.js +5 -5
- package/dist/components/embeds/index.cjs +4 -4
- package/dist/components/embeds/index.js +3 -3
- package/dist/components/faq/index.cjs +4 -4
- package/dist/components/faq/index.js +3 -3
- package/dist/components/features/captions-url.cjs +12 -0
- package/dist/components/features/captions-url.cjs.map +1 -0
- package/dist/components/features/captions-url.js +10 -0
- package/dist/components/features/captions-url.js.map +1 -0
- package/dist/components/features/card-hit-layer.d.ts +40 -0
- package/dist/components/features/card-hit-layer.d.ts.map +1 -0
- package/dist/components/features/floating-walkthrough-video.d.ts +71 -0
- package/dist/components/features/floating-walkthrough-video.d.ts.map +1 -0
- package/dist/components/features/index.cjs +11 -3
- package/dist/components/features/index.cjs.map +1 -1
- package/dist/components/features/index.d.ts +4 -0
- package/dist/components/features/index.d.ts.map +1 -1
- package/dist/components/features/index.js +12 -4
- package/dist/components/features/use-walkthrough-video.d.ts +16 -0
- package/dist/components/features/use-walkthrough-video.d.ts.map +1 -0
- package/dist/components/features/video-bites-strip.d.ts.map +1 -1
- package/dist/components/features/video-center-badge.d.ts.map +1 -1
- package/dist/components/features/video-hover-preview.d.ts +68 -0
- package/dist/components/features/video-hover-preview.d.ts.map +1 -0
- package/dist/components/features/video.d.ts +78 -40
- package/dist/components/features/video.d.ts.map +1 -1
- package/dist/components/form.d.ts +0 -1
- package/dist/components/form.d.ts.map +1 -1
- package/dist/components/help-center-pages/index.cjs +21 -21
- package/dist/components/help-center-pages/index.js +12 -12
- package/dist/components/index.cjs +163 -155
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +18 -10
- package/dist/components/index.js.map +1 -1
- package/dist/components/navigation/index.cjs +3 -3
- package/dist/components/navigation/index.js +2 -2
- package/dist/components/onboarding-guides/index.cjs +6 -6
- package/dist/components/onboarding-guides/index.js +5 -5
- package/dist/components/related-content/index.cjs +4 -4
- package/dist/components/related-content/index.js +3 -3
- package/dist/components/tickets/index.cjs +6 -6
- package/dist/components/tickets/index.js +5 -5
- package/dist/components/ui/button/button-styles.d.ts +2 -0
- package/dist/components/ui/button/button-styles.d.ts.map +1 -1
- package/dist/components/ui/button/button.d.ts +2 -2
- package/dist/components/ui/button/button.d.ts.map +1 -1
- package/dist/components/ui/file-manager/index.cjs +50 -50
- package/dist/components/ui/file-manager/index.js +1 -1
- package/dist/components/ui/index.cjs +3 -3
- package/dist/components/ui/index.js +2 -2
- package/dist/components/ui/page-actions.d.ts +2 -1
- package/dist/components/ui/page-actions.d.ts.map +1 -1
- package/dist/index.cjs +27 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +28 -4
- package/dist/types/supabase.d.ts +80 -0
- package/dist/types/supabase.d.ts.map +1 -1
- package/dist/types/video-processing.d.ts +1 -1
- package/dist/types/video-processing.d.ts.map +1 -1
- package/dist/utils/announcement-storage.d.ts +1 -1
- package/dist/utils/announcement-storage.d.ts.map +1 -1
- package/dist/utils/dismiss-cookie.d.ts +27 -0
- package/dist/utils/dismiss-cookie.d.ts.map +1 -0
- package/dist/utils/dismissal-storage.d.ts +19 -0
- package/dist/utils/dismissal-storage.d.ts.map +1 -0
- package/dist/utils/index.cjs +48 -10
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +41 -11
- package/dist/utils/index.js.map +1 -1
- package/package.json +8 -2
- package/src/.index.md +39 -32
- package/src/.platform-domains.md +65 -0
- package/src/assets/.fae-avatar.md +33 -0
- package/src/assets/.index.md +15 -9
- package/src/components/.agent-mark.md +31 -0
- package/src/components/.announcement-bar.md +47 -35
- package/src/components/.calendar.md +19 -15
- package/src/components/.categories-cart.md +34 -30
- package/src/components/.category-card.md +33 -33
- package/src/components/.chart.md +38 -40
- package/src/components/.command.md +47 -23
- package/src/components/.comment-card.md +31 -26
- package/src/components/.content-loading-container.md +45 -20
- package/src/components/.context-menu.md +45 -31
- package/src/components/.date-time-picker.md +36 -30
- package/src/components/.empty-state.md +31 -31
- package/src/components/.faq-accordion.md +20 -30
- package/src/components/.filter-chip.md +36 -33
- package/src/components/.footer-waitlist-button.md +27 -21
- package/src/components/.footer.md +39 -24
- package/src/components/.form.md +32 -20
- package/src/components/.hero-image-uploader.md +35 -31
- package/src/components/.icon-display.md +53 -0
- package/src/components/.image-cropper.md +34 -33
- package/src/components/.index.md +25 -29
- package/src/components/.logs-list.md +27 -23
- package/src/components/.media-carousel.md +47 -26
- package/src/components/.metric-value.md +27 -24
- package/src/components/.msp-display.md +29 -23
- package/src/components/.open-source-features.md +23 -26
- package/src/components/.pagination.md +44 -39
- package/src/components/.persistent-filter-controls.md +61 -28
- package/src/components/.pricing-display.md +34 -33
- package/src/components/.results-count.md +33 -20
- package/src/components/.smooth-accordion.md +24 -20
- package/src/components/.social-icon-row.md +33 -21
- package/src/components/.sonner.md +40 -25
- package/src/components/.steps.md +39 -25
- package/src/components/.tool-icon.md +34 -21
- package/src/components/.unified-filter-logic.md +32 -36
- package/src/components/.user-display.md +33 -28
- package/src/components/.user-summary-stub.md +40 -33
- package/src/components/.vendor-display-button.md +17 -15
- package/src/components/.vendor-icon.md +17 -25
- package/src/components/.vendor-tag.md +39 -34
- package/src/components/.why-it-matters.md +15 -11
- package/src/components/.yes-no-display.md +36 -31
- package/src/components/authors/.author-detail-view.md +50 -0
- package/src/components/case-studies/.index.md +26 -0
- package/src/components/case-studies/.share-experience-section.md +45 -0
- package/src/components/chat/.approval-batch-message.md +48 -33
- package/src/components/chat/.approval-request-message.md +37 -26
- package/src/components/chat/.chat-archive-page.md +56 -0
- package/src/components/chat/.chat-attachment-bar.md +32 -40
- package/src/components/chat/.chat-composer.md +43 -0
- package/src/components/chat/.chat-container.md +41 -25
- package/src/components/chat/.chat-context-memory-bar.md +53 -0
- package/src/components/chat/.chat-context-picker.md +89 -0
- package/src/components/chat/.chat-header-icon-button.md +43 -0
- package/src/components/chat/.chat-header-search-field.md +51 -0
- package/src/components/chat/.chat-input.md +63 -30
- package/src/components/chat/.chat-list-empty-state.md +44 -0
- package/src/components/chat/.chat-message-enhanced.md +29 -31
- package/src/components/chat/.chat-message-list.md +34 -44
- package/src/components/chat/.chat-message-row.md +56 -0
- package/src/components/chat/.chat-message-skeleton.md +32 -26
- package/src/components/chat/.chat-panel-header-mobile.md +46 -0
- package/src/components/chat/.chat-panel-header.md +80 -0
- package/src/components/chat/.chat-sidebar-skeleton.md +31 -30
- package/src/components/chat/.chat-sidebar.md +36 -29
- package/src/components/chat/.chat-ticket-list.md +38 -23
- package/src/components/chat/.chat-typing-indicator.md +37 -19
- package/src/components/chat/.context-compaction-display.md +19 -15
- package/src/components/chat/.context-items-list.md +57 -0
- package/src/components/chat/.embeddable-chat.md +57 -66
- package/src/components/chat/.error-message-display.md +40 -22
- package/src/components/chat/.guide-mode-banner.md +41 -0
- package/src/components/chat/.guide-welcome.md +43 -0
- package/src/components/chat/.index.md +26 -21
- package/src/components/chat/.mingo-chat-history.md +63 -0
- package/src/components/chat/.mingo-chat-modals.md +44 -0
- package/src/components/chat/.mingo-history-rail.md +63 -0
- package/src/components/chat/.mingo-info-card.md +59 -0
- package/src/components/chat/.mingo-onboarding-card.md +21 -27
- package/src/components/chat/.mingo-welcome.md +60 -0
- package/src/components/chat/.model-display.md +33 -25
- package/src/components/chat/.msp-organization-card-skeleton.md +44 -0
- package/src/components/chat/.msp-organization-card.md +51 -0
- package/src/components/chat/.nav-link-anchor-via-runtime.md +36 -25
- package/src/components/chat/.quick-action-chip.md +60 -0
- package/src/components/chat/.quick-action-marquee.md +53 -0
- package/src/components/chat/.quick-action-wall.md +68 -0
- package/src/components/chat/.remark-mention-chips.md +41 -0
- package/src/components/chat/.slash-command-suggestions.md +30 -36
- package/src/components/chat/.source-action-button.md +28 -25
- package/src/components/chat/.tool-call-blocks.md +18 -30
- package/src/components/chat/.tool-execution-display.md +29 -34
- package/src/components/chat/entity-cards/.admin-content-card.md +29 -22
- package/src/components/chat/entity-cards/.blog-card.md +44 -33
- package/src/components/chat/entity-cards/.blog-image-placeholder.md +20 -18
- package/src/components/chat/entity-cards/.case-study-card.md +24 -33
- package/src/components/chat/entity-cards/.chat-ticket-item.md +39 -22
- package/src/components/chat/entity-cards/.customer-interview-card.md +29 -32
- package/src/components/chat/entity-cards/.data-room-doc-card.md +21 -22
- package/src/components/chat/entity-cards/.dispatch.md +41 -24
- package/src/components/chat/entity-cards/.entity-author-card.md +36 -33
- package/src/components/chat/entity-cards/.entity-portrait-card.md +47 -0
- package/src/components/chat/entity-cards/.generic-entity-card.md +26 -25
- package/src/components/chat/entity-cards/.github-activity-card.md +35 -41
- package/src/components/chat/entity-cards/.hubspot-ticket-card.md +22 -28
- package/src/components/chat/entity-cards/.index.md +33 -44
- package/src/components/chat/entity-cards/.investor-update-card.md +36 -25
- package/src/components/chat/entity-cards/.onboarding-guide-card.md +20 -29
- package/src/components/chat/entity-cards/.product-release-card-defaults.md +26 -19
- package/src/components/chat/entity-cards/.program-card.md +30 -33
- package/src/components/chat/entity-cards/.roadmap-card.md +40 -31
- package/src/components/chat/entity-cards/.roadmap-vote-button.md +33 -36
- package/src/components/chat/entity-cards/.slack-message-card.md +31 -32
- package/src/components/chat/entity-cards/.use-cover-image-fallback.md +47 -0
- package/src/components/chat/entity-cards/.use-entity-card-link.md +51 -0
- package/src/components/chat/entity-cards/.use-entity-card-placeholder.md +47 -0
- package/src/components/chat/entity-cards/.what-i-shipped-card.md +43 -0
- package/src/components/chat/hooks/.index.md +33 -30
- package/src/components/chat/hooks/.use-chat-card-item.md +30 -17
- package/src/components/chat/hooks/.use-chat-dialog-manager.md +59 -0
- package/src/components/chat/hooks/.use-chat-identity.md +37 -25
- package/src/components/chat/hooks/.use-chunk-catchup.md +53 -36
- package/src/components/chat/hooks/.use-empty-state-config.md +39 -0
- package/src/components/chat/hooks/.use-jetstream-dialog-subscription.md +65 -30
- package/src/components/chat/hooks/.use-nats-chat-adapter.md +55 -36
- package/src/components/chat/hooks/.use-nats-dialog-subscription.md +66 -50
- package/src/components/chat/hooks/.use-realtime-chunk-processor.md +58 -31
- package/src/components/chat/hooks/.use-scripted-stream.md +46 -0
- package/src/components/chat/hooks/.use-slash-commands.md +32 -25
- package/src/components/chat/hooks/.use-sse-chat-adapter.md +32 -21
- package/src/components/chat/hooks/.use-unified-chat.md +45 -35
- package/src/components/chat/types/.api.types.md +49 -41
- package/src/components/chat/types/.chat.types.md +56 -34
- package/src/components/chat/types/.component.types.md +36 -36
- package/src/components/chat/types/.context-item.types.md +61 -0
- package/src/components/chat/types/.index.md +32 -17
- package/src/components/chat/types/.message.types.md +44 -45
- package/src/components/chat/types/.network.types.md +46 -46
- package/src/components/chat/types/.processing.types.md +49 -37
- package/src/components/chat/types/.unified-chat-state.types.md +41 -26
- package/src/components/chat/types/entities/.content-ref.md +20 -31
- package/src/components/chat/types/entities/.investor-update.md +14 -16
- package/src/components/chat/types/entities/.onboarding-guide.md +35 -34
- package/src/components/chat/types/entities/.program-types.md +55 -43
- package/src/components/chat/utils/.chip-action-class.md +17 -19
- package/src/components/chat/utils/.chip-styles.md +18 -18
- package/src/components/chat/utils/.chunk-parser.md +48 -37
- package/src/components/chat/utils/.compact-card-classes.md +33 -35
- package/src/components/chat/utils/.execute-navigation.md +49 -0
- package/src/components/chat/utils/.extract-incomplete-message-state.md +9 -12
- package/src/components/chat/utils/.history-merge.md +65 -0
- package/src/components/chat/utils/.icon-library.md +33 -31
- package/src/components/chat/utils/.icon-registry.md +44 -0
- package/src/components/chat/utils/.index.md +37 -33
- package/src/components/chat/utils/.is-cross-origin-url.md +26 -22
- package/src/components/chat/utils/.message-segment-accumulator.md +46 -25
- package/src/components/chat/utils/.nav-anchor-props.md +29 -34
- package/src/components/chat/utils/.nav-click-handler.md +29 -33
- package/src/components/chat/utils/.process-historical-messages.md +29 -33
- package/src/components/chat/utils/.scripted-stream.md +52 -0
- package/src/components/chat/utils/.source-row-cta.md +32 -31
- package/src/components/chat/utils/.tool-call-helpers.md +25 -17
- package/src/components/contact/.contact-form.md +24 -19
- package/src/components/docs/.doc-navigation-context.md +49 -0
- package/src/components/docs/.doc-viewer.md +64 -0
- package/src/components/docs/.docs-hub-page.md +49 -0
- package/src/components/docs/.index.md +51 -0
- package/src/components/docs/.skeletons.md +47 -0
- package/src/components/docs/.use-docs-resolve-link.md +61 -0
- package/src/components/docs/.use-document-tree.md +83 -0
- package/src/components/docs/.use-scroll-spy.md +58 -0
- package/src/components/embeds/.embed-container.md +45 -0
- package/src/components/embeds/.embed-iframe.md +51 -0
- package/src/components/embeds/.figma-embed.md +43 -0
- package/src/components/embeds/.file-download-card.md +47 -0
- package/src/components/embeds/.google-sheets-viewer.md +40 -0
- package/src/components/embeds/.index.md +58 -0
- package/src/components/embeds/.linkedin-embed-client.md +50 -0
- package/src/components/embeds/.markdown-image.md +40 -0
- package/src/components/embeds/.og-link-preview.md +54 -0
- package/src/components/embeds/.pdf-viewer.md +43 -0
- package/src/components/embeds/.reddit-embed-client.md +40 -0
- package/src/components/embeds/.rich-markdown-runtime.md +53 -0
- package/src/components/embeds/.twitter-embed-client.md +44 -0
- package/src/components/faq/.faq-document-page.md +68 -0
- package/src/components/faq/.faq-section.md +55 -0
- package/src/components/faq/.index.md +29 -0
- package/src/components/faq/.json-ld.md +48 -0
- package/src/components/features/.array-entry-manager.md +32 -24
- package/src/components/features/.auth-providers-list.md +33 -32
- package/src/components/features/.captions-url.md +43 -0
- package/src/components/features/.cards-strip.md +48 -0
- package/src/components/features/.changelog-manager.md +17 -20
- package/src/components/features/.command-box.md +11 -16
- package/src/components/features/.entity-summary-editor.md +20 -15
- package/src/components/features/.entity-tag-badges.md +43 -0
- package/src/components/features/.entity-video-section.md +31 -41
- package/src/components/features/.figma-prototype-viewer.md +55 -37
- package/src/components/features/.filters-dropdown.md +14 -13
- package/src/components/features/.highlight-config-section.md +19 -16
- package/src/components/features/.highlight-video-combined-section.md +28 -19
- package/src/components/features/.highlight-video-preview.md +13 -11
- package/src/components/features/.highlight-video-section.md +26 -22
- package/src/components/features/.index.md +40 -36
- package/src/components/features/.media-gallery-manager.md +37 -35
- package/src/components/features/.mux-origins.md +46 -0
- package/src/components/features/.og-editor-preview.md +29 -24
- package/src/components/features/.os-type-badge-group.md +26 -18
- package/src/components/features/.os-type-badge.md +41 -24
- package/src/components/features/.paths-display.md +42 -25
- package/src/components/features/.platform-badge.md +26 -17
- package/src/components/features/.policy-configuration-panel.md +33 -31
- package/src/components/features/.provider-button.md +29 -20
- package/src/components/features/.push-button-selector.md +39 -41
- package/src/components/features/.release-media-manager.md +41 -34
- package/src/components/features/.section-selector.md +27 -16
- package/src/components/features/.select-button.md +21 -32
- package/src/components/features/.seo-editor-preview.md +49 -36
- package/src/components/features/.social-links-manager.md +40 -18
- package/src/components/features/.start-with-openframe-button.md +30 -32
- package/src/components/features/.status-filter-component.md +29 -38
- package/src/components/features/.tags-selector.md +25 -29
- package/src/components/features/.transcript-summary-editor.md +24 -18
- package/src/components/features/.use-video-warmup.md +47 -0
- package/src/components/features/.video-bites-display.md +36 -37
- package/src/components/features/.video-bites-shared.md +44 -0
- package/src/components/features/.video-bites-strip.md +63 -0
- package/src/components/features/.video-center-badge.md +38 -0
- package/src/components/features/.video-ratio-tabs.md +38 -31
- package/src/components/features/.video-source-selector.md +24 -27
- package/src/components/features/.video.md +35 -27
- package/src/components/features/.waitlist-form.md +39 -33
- package/src/components/features/.warning-block.md +53 -0
- package/src/components/features/ai-enrich/.AIEnrichSection.md +24 -25
- package/src/components/features/ai-enrich/.AIRequiredBadge.md +22 -21
- package/src/components/features/ai-enrich/.AIStatusIndicator.md +42 -35
- package/src/components/features/ai-enrich/.AIWarningsSection.md +23 -20
- package/src/components/features/ai-enrich/.ConfidenceBadge.md +35 -20
- package/src/components/features/auth/.auth-benefits-panel.md +48 -0
- package/src/components/features/auth/.auth-branding.md +51 -0
- package/src/components/features/auth/.auth-shell.md +51 -0
- package/src/components/features/auth/.back-to-login-link.md +48 -0
- package/src/components/features/auth/.complete-account-form.md +45 -0
- package/src/components/features/auth/.create-organization-form.md +53 -0
- package/src/components/features/auth/.index.md +48 -0
- package/src/components/features/auth/.invite-link-invalid-modal.md +42 -0
- package/src/components/features/auth/.login-form.md +42 -0
- package/src/components/features/auth/.openframe-sso-login-form.md +46 -0
- package/src/components/features/auth/.openframe-sso-signup-form.md +51 -0
- package/src/components/features/auth/.password-reset-form.md +57 -0
- package/src/components/features/auth/.sso-auth-shell.md +35 -0
- package/src/components/features/auth/.sso-providers.md +42 -0
- package/src/components/features/auth/.terms-agreement-label.md +28 -0
- package/src/components/features/board/.board-column-header.md +24 -18
- package/src/components/features/board/.board-column.md +32 -32
- package/src/components/features/board/.board-ticket-approval.md +42 -0
- package/src/components/features/board/.board.md +38 -38
- package/src/components/features/board/.index.md +35 -38
- package/src/components/features/board/.ticket-card.md +33 -36
- package/src/components/features/board/.types.md +38 -31
- package/src/components/features/card-hit-layer.tsx +84 -0
- package/src/components/features/floating-walkthrough-video.tsx +891 -0
- package/src/components/features/index.ts +4 -0
- package/src/components/features/notifications/.approval-request-notification-tile.md +45 -0
- package/src/components/features/notifications/.index.md +35 -31
- package/src/components/features/notifications/.notification-drawer.md +32 -19
- package/src/components/features/notifications/.notification-popups.md +51 -0
- package/src/components/features/notifications/.notification-tile.md +43 -27
- package/src/components/features/notifications/.notifications-context.md +42 -45
- package/src/components/features/notifications/.types.md +51 -31
- package/src/components/features/ticket-status-config-list/.ticket-status-config-list.md +51 -0
- package/src/components/features/time-tracker/.index.md +48 -0
- package/src/components/features/time-tracker/.time-tracker-context.md +55 -0
- package/src/components/features/time-tracker/.time-tracker-header-button.md +51 -0
- package/src/components/features/time-tracker/.time-tracker-panel.md +58 -0
- package/src/components/features/time-tracker/.types.md +51 -0
- package/src/components/features/time-tracker/.use-tracker-clock.md +32 -0
- package/src/components/features/use-walkthrough-video.ts +70 -0
- package/src/components/features/video-bites-strip.tsx +46 -146
- package/src/components/features/video-center-badge.tsx +11 -2
- package/src/components/features/video-hover-preview.tsx +201 -0
- package/src/components/features/video.tsx +368 -73
- package/src/components/help-center-pages/.delivery-page.md +51 -0
- package/src/components/help-center-pages/.index.md +51 -0
- package/src/components/help-center-pages/.onboarding-guides-catalog-page.md +53 -0
- package/src/components/help-center-pages/.product-releases-list-page.md +51 -0
- package/src/components/help-center-pages/.roadmap-page.md +46 -0
- package/src/components/icons/.figma-icon.md +13 -7
- package/src/components/icons/.index.md +26 -22
- package/src/components/icons/.vendor-directory-icon.md +30 -18
- package/src/components/icons/.x-logo.md +26 -10
- package/src/components/icons-v2-generated/.index.md +30 -41
- package/src/components/icons-v2-generated/brand-logos/.index.md +25 -19
- package/src/components/icons-v2-generated/communication/.index.md +26 -30
- package/src/components/icons-v2-generated/logos/.flamingo-logo-icon.md +41 -0
- package/src/components/layout/.article-detail-layout.md +32 -21
- package/src/components/layout/.page-container.md +25 -23
- package/src/components/layout/.page-heading.md +48 -0
- package/src/components/layout/.page-layout.md +30 -25
- package/src/components/layout/.title-block.md +43 -24
- package/src/components/loading/.card-skeleton.md +28 -35
- package/src/components/loading/.category-card-skeleton.md +25 -23
- package/src/components/loading/.device-card-skeleton.md +22 -15
- package/src/components/loading/.margin-report-skeleton.md +30 -35
- package/src/components/loading/.openmsp-heartbeat.md +30 -32
- package/src/components/loading/.organization-card-skeleton.md +22 -25
- package/src/components/loading/.organization-icon-skeleton.md +39 -27
- package/src/components/loading/.page-layout-skeleton.md +50 -28
- package/src/components/loading/.unified-skeleton.md +37 -40
- package/src/components/loading/.users-grid-skeleton.md +19 -38
- package/src/components/navigation/.app-header.md +35 -28
- package/src/components/navigation/.app-layout-context.md +48 -0
- package/src/components/navigation/.app-layout-drawer.md +56 -0
- package/src/components/navigation/.app-layout.md +24 -23
- package/src/components/navigation/.header-mingo-button.md +46 -0
- package/src/components/navigation/.header-organization-filter.md +32 -18
- package/src/components/navigation/.header.md +24 -31
- package/src/components/navigation/.index.md +36 -50
- package/src/components/navigation/.mingo-ai-button.md +41 -0
- package/src/components/navigation/.mobile-burger-menu.md +29 -29
- package/src/components/navigation/.mobile-nav-panel.md +41 -49
- package/src/components/navigation/.multi-level-navigation.md +76 -0
- package/src/components/navigation/.navigation-sidebar-item.md +14 -14
- package/src/components/navigation/.navigation-sidebar.md +30 -23
- package/src/components/navigation/.sliding-sidebar.md +30 -25
- package/src/components/navigation/.sticky-section-nav.md +23 -21
- package/src/components/onboarding-guides/.index.md +40 -0
- package/src/components/onboarding-guides/.onboarding-guide-detail-view.md +55 -0
- package/src/components/onboarding-guides/.onboarding-guides-catalog-skeleton.md +33 -0
- package/src/components/onboarding-guides/.onboarding-guides-catalog-view.md +50 -0
- package/src/components/onboarding-guides/hooks/.use-onboarding-guides.md +54 -0
- package/src/components/platform/.CveLink.md +28 -17
- package/src/components/platform/.ScriptArguments.md +18 -23
- package/src/components/platform/.ScriptInfoSection.md +27 -21
- package/src/components/platform/.ShellTypeBadge.md +34 -18
- package/src/components/platform/.SoftwareInfo.md +23 -21
- package/src/components/platform/.ToolBadge.md +18 -16
- package/src/components/profile/.ProfileLoadingSkeleton.md +24 -23
- package/src/components/related-content/.index.md +41 -0
- package/src/components/related-content/.related-content-section.md +62 -0
- package/src/components/shared/.article-author-byline.md +56 -0
- package/src/components/shared/.detail-page-skeleton.md +32 -43
- package/src/components/shared/.media-gallery-strip.md +43 -0
- package/src/components/shared/delivery/.delivery-lists.md +20 -19
- package/src/components/shared/delivery/.delivery-row.md +24 -20
- package/src/components/shared/delivery/.delivery-table.md +20 -22
- package/src/components/shared/dev-section/.dev-card-row.md +28 -36
- package/src/components/shared/dev-section/.dev-section-page.md +36 -25
- package/src/components/shared/dev-section/.dev-section-view.md +32 -22
- package/src/components/shared/doc-search/.doc-search-bar.md +58 -0
- package/src/components/shared/doc-search/.doc-search-result-row.md +50 -0
- package/src/components/shared/doc-search/.format-relative-path.md +30 -0
- package/src/components/shared/doc-search/.index.md +46 -0
- package/src/components/shared/doc-search/.map-doc-search-results.md +44 -0
- package/src/components/shared/doc-search/.resolve-search-result-action.md +52 -0
- package/src/components/shared/doc-search/.types.md +49 -0
- package/src/components/shared/doc-search/.use-doc-search.md +66 -0
- package/src/components/shared/legal-document/.legal-document-page.md +26 -20
- package/src/components/shared/legal-document/.use-legal-docs.md +36 -30
- package/src/components/shared/onboarding/.onboarding-step-card.md +24 -16
- package/src/components/shared/onboarding/.onboarding-walkthrough.md +42 -28
- package/src/components/shared/product-release/.index.md +33 -24
- package/src/components/shared/product-release/.product-release-card-skeleton.md +22 -28
- package/src/components/shared/product-release/.product-release-card.md +28 -29
- package/src/components/shared/product-release/.product-releases-view.md +49 -0
- package/src/components/shared/product-release/.release-detail-page.md +30 -15
- package/src/components/shared/roadmap/.index.md +29 -24
- package/src/components/shared/roadmap/.roadmap-grid.md +43 -54
- package/src/components/shared/roadmap/.roadmap-view.md +41 -0
- package/src/components/shared/roadmap/.use-roadmap-voting.md +27 -17
- package/src/components/switch.tsx +1 -1
- package/src/components/tickets/.help-center-card.md +32 -28
- package/src/components/tickets/.help-center-create-form.md +34 -22
- package/src/components/tickets/.help-center-list.md +36 -25
- package/src/components/tickets/.index.md +30 -45
- package/src/components/tickets/.ticket-center.md +31 -38
- package/src/components/tickets/.ticket-detail-drawer.md +20 -30
- package/src/components/tickets/.ticket-open-form.md +24 -26
- package/src/components/tickets/.ticket-reply-composer.md +51 -0
- package/src/components/tickets/.ticket-row.md +26 -11
- package/src/components/tickets/.types.md +56 -38
- package/src/components/tickets/hooks/.use-ticket-actions.md +60 -47
- package/src/components/tickets/hooks/.use-ticket-engagements.md +27 -27
- package/src/components/tickets/hooks/.use-tickets-list.md +24 -30
- package/src/components/ui/.accordion.md +28 -21
- package/src/components/ui/.actions-menu.md +36 -54
- package/src/components/ui/.ai-generated-badge.md +25 -0
- package/src/components/ui/.alert-dialog.md +21 -16
- package/src/components/ui/.alert.md +30 -25
- package/src/components/ui/.allowed-domains-input.md +26 -15
- package/src/components/ui/.announcement-bar-view.md +46 -0
- package/src/components/ui/.autocomplete.md +40 -27
- package/src/components/ui/.badge.md +34 -31
- package/src/components/ui/.brand-association-card.md +22 -18
- package/src/components/ui/.breadcrumb.md +18 -14
- package/src/components/ui/.bullet-list.md +35 -23
- package/src/components/ui/.card.md +47 -30
- package/src/components/ui/.checkbox-block.md +34 -22
- package/src/components/ui/.checkbox-with-description.md +18 -20
- package/src/components/ui/.chevron-button.md +29 -29
- package/src/components/ui/.circular-progress.md +30 -41
- package/src/components/ui/.color-preset-select.md +54 -0
- package/src/components/ui/.color-swatch.md +37 -0
- package/src/components/ui/.content-loader.md +34 -27
- package/src/components/ui/.crossfade-panels.md +50 -0
- package/src/components/ui/.cursor-pagination.md +38 -26
- package/src/components/ui/.dashboard-info-card.md +46 -27
- package/src/components/ui/.date-picker.md +52 -36
- package/src/components/ui/.device-card-compact.md +23 -20
- package/src/components/ui/.device-card.md +39 -30
- package/src/components/ui/.dialog.md +14 -14
- package/src/components/ui/.drawer.md +45 -39
- package/src/components/ui/.dropdown-button.md +41 -33
- package/src/components/ui/.dropdown-menu.md +40 -23
- package/src/components/ui/.duration-input.md +41 -0
- package/src/components/ui/.entity-image.md +32 -28
- package/src/components/ui/.error-state.md +30 -26
- package/src/components/ui/.fade-preview.md +44 -0
- package/src/components/ui/.field-wrapper.md +34 -23
- package/src/components/ui/.file-upload.md +30 -18
- package/src/components/ui/.filter-modal.md +30 -32
- package/src/components/ui/.filter-pill-row.md +58 -0
- package/src/components/ui/.floating-tooltip.md +27 -32
- package/src/components/ui/.hidden-tags-popup.md +18 -20
- package/src/components/ui/.highlight-card.md +36 -23
- package/src/components/ui/.honeypot-field.md +41 -0
- package/src/components/ui/.hover-dropdown.md +44 -31
- package/src/components/ui/.image-gallery-modal.md +28 -30
- package/src/components/ui/.image-uploader.md +39 -22
- package/src/components/ui/.index.md +33 -31
- package/src/components/ui/.info-card-row.md +50 -0
- package/src/components/ui/.info-card.md +27 -20
- package/src/components/ui/.info-row.md +30 -24
- package/src/components/ui/.info-section.md +63 -0
- package/src/components/ui/.input.md +29 -28
- package/src/components/ui/.label.md +34 -26
- package/src/components/ui/.markdown-editor.md +26 -25
- package/src/components/ui/.marquee-wall.md +64 -0
- package/src/components/ui/.menubar.md +50 -16
- package/src/components/ui/.modal-v2.md +41 -27
- package/src/components/ui/.modal.md +22 -19
- package/src/components/ui/.more-actions-menu.md +30 -24
- package/src/components/ui/.navigation-menu.md +40 -25
- package/src/components/ui/.organization-card.md +46 -27
- package/src/components/ui/.page-actions.md +55 -41
- package/src/components/ui/.page-loader.md +40 -23
- package/src/components/ui/.password-input.md +30 -0
- package/src/components/ui/.phone-input.md +20 -22
- package/src/components/ui/.portal-container.md +43 -0
- package/src/components/ui/.progress-bar.md +40 -27
- package/src/components/ui/.release-changelog-section.md +32 -26
- package/src/components/ui/.rich-markdown-renderer.md +45 -0
- package/src/components/ui/.scroll-fade.md +56 -0
- package/src/components/ui/.search-input.md +55 -37
- package/src/components/ui/.select.md +25 -26
- package/src/components/ui/.service-card.md +25 -19
- package/src/components/ui/.sheet.md +21 -21
- package/src/components/ui/.simple-markdown-renderer.md +36 -24
- package/src/components/ui/.slack-channel-chip.md +49 -0
- package/src/components/ui/.square-avatar.md +29 -26
- package/src/components/ui/.stacked-rows-panel.md +61 -0
- package/src/components/ui/.status-badge.md +30 -24
- package/src/components/ui/.status-indicator.md +35 -21
- package/src/components/ui/.tab-content.md +34 -22
- package/src/components/ui/.tab-navigation.md +40 -50
- package/src/components/ui/.tab-selector.md +48 -31
- package/src/components/ui/.tabs.md +34 -21
- package/src/components/ui/.tag-search-input.md +20 -20
- package/src/components/ui/.tag-select-dropdown.md +59 -0
- package/src/components/ui/.tag.md +25 -43
- package/src/components/ui/.tags-input.md +31 -31
- package/src/components/ui/.textarea.md +32 -30
- package/src/components/ui/.ticket-attachments-list.md +36 -29
- package/src/components/ui/.ticket-info-section.md +37 -42
- package/src/components/ui/.ticket-status-config-row.md +66 -0
- package/src/components/ui/.ticket-status-tag.md +39 -35
- package/src/components/ui/.toaster.md +21 -15
- package/src/components/ui/.toggle.md +38 -37
- package/src/components/ui/.tooltip.md +16 -13
- package/src/components/ui/button/.button-styles.md +17 -18
- package/src/components/ui/button/.button.md +30 -37
- package/src/components/ui/button/.split-button.md +46 -23
- package/src/components/ui/button/button-styles.ts +13 -0
- package/src/components/ui/button/button.tsx +5 -0
- package/src/components/ui/data-table/.data-table-body.md +50 -35
- package/src/components/ui/data-table/.data-table-empty.md +17 -33
- package/src/components/ui/data-table/.data-table-header.md +43 -40
- package/src/components/ui/data-table/.data-table-row.md +31 -31
- package/src/components/ui/data-table/.types.md +23 -28
- package/src/components/ui/file-manager/.file-manager-breadcrumb.md +16 -24
- package/src/components/ui/file-manager/.file-manager-empty.md +23 -15
- package/src/components/ui/file-manager/.file-manager-skeleton.md +34 -36
- package/src/components/ui/file-manager/.file-manager-table-row.md +29 -29
- package/src/components/ui/file-manager/.file-manager-table.md +39 -24
- package/src/components/ui/no-data/.index.md +22 -0
- package/src/components/ui/no-data/.no-data-actions.md +29 -0
- package/src/components/ui/no-data/.no-data-message.md +37 -0
- package/src/components/ui/no-data/.no-data-styles.md +39 -0
- package/src/components/ui/no-data/.no-data.md +59 -0
- package/src/components/ui/page-actions.tsx +2 -1
- package/src/components/ui/query-report-table/.query-report-table-header.md +15 -15
- package/src/components/ui/query-report-table/.query-report-table-row.md +16 -16
- package/src/components/ui/query-report-table/.query-report-table.md +39 -24
- package/src/components/ui/table/.table-column-filter-dropdown.md +15 -9
- package/src/components/ui/table/.table-description-cell.md +13 -12
- package/src/components/ui/table/.table-empty-state.md +19 -20
- package/src/components/ui/table/.table-row.md +30 -20
- package/src/components/ui/table/.table-skeleton.md +32 -27
- package/src/components/ui/table/.table-timestamp-cell.md +24 -23
- package/src/components/ui/table/.table.md +43 -30
- package/src/components/ui/table/.types.md +49 -45
- package/src/components/ui/table/.use-table-motion.md +45 -0
- package/src/contexts/.chat-runtime-context.md +55 -26
- package/src/contexts/.endpoints-runtime-context.md +40 -44
- package/src/embed-shims/.next-navigation.md +38 -31
- package/src/hooks/.api-hooks.md +28 -21
- package/src/hooks/.index.md +30 -25
- package/src/hooks/.use-authed-image-src.md +38 -0
- package/src/hooks/.use-contact-submission.md +35 -36
- package/src/hooks/.use-humanity-signals.md +47 -0
- package/src/hooks/.use-near-viewport.md +30 -30
- package/src/hooks/.use-og-placeholder-url.md +57 -0
- package/src/hooks/.use-scroll-to-hash.md +46 -0
- package/src/hooks/.use-self-fetch.md +52 -0
- package/src/hooks/state/.flatten-schema.md +37 -29
- package/src/hooks/ui/.index.md +37 -25
- package/src/hooks/ui/.use-auto-limit-tags.md +55 -38
- package/src/hooks/ui/.use-deferred-error.md +44 -0
- package/src/hooks/ui/.use-focus-trap.md +59 -0
- package/src/hooks/ui/.use-header-height.md +37 -0
- package/src/hooks/ui/.use-horizontal-scrollbar.md +25 -34
- package/src/hooks/ui/.use-marquee-engine.md +73 -0
- package/src/hooks/ui/.use-notification-permission.md +49 -0
- package/src/hooks/ui/.use-reset-on-page-hidden.md +40 -0
- package/src/hooks/ui/.use-suppress-clone-focus.md +41 -0
- package/src/nats/.index.md +39 -0
- package/src/nats/.nats-provider.md +46 -0
- package/src/nats/.nats.md +38 -28
- package/src/nats/.shared-connection.md +56 -0
- package/src/nats/.use-nats-subscription.md +57 -0
- package/src/stories/.ActionsMenu.stories.md +57 -0
- package/src/stories/.Alert.stories.md +46 -0
- package/src/stories/.AnnouncementBar.stories.md +59 -32
- package/src/stories/.AppLayoutDrawer.stories.md +60 -0
- package/src/stories/.AppLayoutSidebar.stories.md +45 -0
- package/src/stories/.ApprovalBatchMessage.stories.md +46 -0
- package/src/stories/.ApprovalBatchMessageClient.stories.md +55 -0
- package/src/stories/.ApprovalRequestMessage.stories.md +50 -0
- package/src/stories/.ApprovalRequestMessageClient.stories.md +41 -0
- package/src/stories/.BlogCard.stories.md +52 -0
- package/src/stories/.Board.stories.md +25 -20
- package/src/stories/.Button.stories.md +35 -40
- package/src/stories/.CampaignCardAdmin.stories.md +38 -0
- package/src/stories/.CardsStrip.stories.md +39 -0
- package/src/stories/.CaseStudyCard.stories.md +41 -0
- package/src/stories/.ChatContainer.stories.md +41 -0
- package/src/stories/.ChatInlineVideoPill.stories.md +36 -0
- package/src/stories/.ChatMessageEnhanced.stories.md +51 -0
- package/src/stories/.ChatMingoInfoCards.stories.md +30 -0
- package/src/stories/.ChatTicketList.stories.md +38 -22
- package/src/stories/.ChatTypingIndicator.stories.md +47 -0
- package/src/stories/.CheckboxBlock.stories.md +34 -35
- package/src/stories/.ContextCompactionDisplay.stories.md +28 -0
- package/src/stories/.CustomerInterviewCard.stories.md +36 -0
- package/src/stories/.DashboardInfoCard.stories.md +40 -33
- package/src/stories/.DataRoomDocCard.stories.md +42 -0
- package/src/stories/.DataTable.stories.md +37 -32
- package/src/stories/.DatePicker.stories.md +34 -30
- package/src/stories/.EmbeddableChat.stories.md +45 -28
- package/src/stories/.EmptyState.stories.md +55 -0
- package/src/stories/.ErrorMessageDisplay.stories.md +45 -0
- package/src/stories/.FilterModal.stories.md +28 -22
- package/src/stories/.GenericEntityCard.stories.md +50 -0
- package/src/stories/.GitHubActivityCard.stories.md +41 -0
- package/src/stories/.GuideWelcome.stories.md +38 -0
- package/src/stories/.Header.stories.md +32 -22
- package/src/stories/.HubspotTicketCard.stories.md +41 -0
- package/src/stories/.InfoCard.stories.md +37 -26
- package/src/stories/.InfoCardRow.stories.md +48 -0
- package/src/stories/.InfoSection.stories.md +55 -0
- package/src/stories/.Input.stories.md +45 -35
- package/src/stories/.InvestorUpdateCard.stories.md +41 -0
- package/src/stories/.MarqueeWall.stories.md +53 -0
- package/src/stories/.MingoAiButton.stories.md +31 -0
- package/src/stories/.MingoChatModals.stories.md +47 -0
- package/src/stories/.MingoInfoCard.stories.md +50 -0
- package/src/stories/.MingoOnboardingCard.stories.md +19 -19
- package/src/stories/.MingoWelcome.stories.md +41 -0
- package/src/stories/.MobileNavPanel.stories.md +52 -0
- package/src/stories/.Modal.stories.md +19 -16
- package/src/stories/.MspOrganizationCard.stories.md +45 -0
- package/src/stories/.NotificationDrawer.stories.md +39 -28
- package/src/stories/.OSTypeBadge.stories.md +34 -25
- package/src/stories/.OnboardingGuideCard.stories.md +41 -0
- package/src/stories/.PageActions.stories.md +21 -21
- package/src/stories/.PageContainer.stories.md +29 -24
- package/src/stories/.PageLayout.stories.md +18 -35
- package/src/stories/.PolicyConfigurationPanel.stories.md +58 -0
- package/src/stories/.ProductReleaseCard.stories.md +39 -0
- package/src/stories/.ProgramCard.stories.md +51 -0
- package/src/stories/.QuickActionChip.stories.md +59 -0
- package/src/stories/.QuickActionMarquee.stories.md +51 -0
- package/src/stories/.QuickActionWall.stories.md +58 -0
- package/src/stories/.RoadmapCard.stories.md +41 -0
- package/src/stories/.ShellTypeBadge.stories.md +42 -22
- package/src/stories/.SlackMessageCard.stories.md +42 -0
- package/src/stories/.SlashCommandSuggestions.stories.md +21 -31
- package/src/stories/.SplitButton.stories.md +23 -25
- package/src/stories/.StackedRowsPanel.stories.md +65 -0
- package/src/stories/.TabSelector.stories.md +26 -38
- package/src/stories/.Tag.stories.md +32 -27
- package/src/stories/.ThinkingDisplay.stories.md +43 -0
- package/src/stories/.TicketCard.stories.md +60 -0
- package/src/stories/.TicketInfoSection.stories.md +28 -20
- package/src/stories/.TimeTracker.stories.md +35 -0
- package/src/stories/.Toaster.stories.md +26 -20
- package/src/stories/.ToolBadge.stories.md +34 -24
- package/src/stories/.ToolExecutionDisplay.stories.md +22 -20
- package/src/stories/.ToolExecutionDisplayClient.stories.md +33 -0
- package/src/stories/.VideoBitesStrip.stories.md +37 -0
- package/src/stories/.WarningBlock.stories.md +51 -0
- package/src/stories/__fixtures__/.chat-card-decorator.md +39 -0
- package/src/stories/__fixtures__/.chat-cards.md +57 -0
- package/src/stories/auth/.CompleteAccount.stories.md +36 -0
- package/src/stories/auth/.CreateOrganization.stories.md +52 -0
- package/src/stories/auth/.InviteLinkInvalid.stories.md +21 -0
- package/src/stories/auth/.Login.stories.md +32 -0
- package/src/stories/auth/.OpenFrameSso.stories.md +58 -0
- package/src/stories/auth/.PasswordReset.stories.md +49 -0
- package/src/styles/ods-interaction-states.css +32 -0
- package/src/types/.announcement.md +67 -35
- package/src/types/.blog.md +44 -41
- package/src/types/.case-study.md +31 -17
- package/src/types/.content-ref.md +37 -0
- package/src/types/.customer-interview.md +38 -38
- package/src/types/.doc-source.md +87 -0
- package/src/types/.entity-author.md +53 -0
- package/src/types/.entity-platform.md +40 -0
- package/src/types/.index.md +23 -17
- package/src/types/.marketing.md +32 -35
- package/src/types/.navigation.md +31 -19
- package/src/types/.os.types.md +30 -31
- package/src/types/.permissions.md +49 -35
- package/src/types/.platform.md +44 -28
- package/src/types/.product-release.md +59 -42
- package/src/types/.shell.types.md +46 -30
- package/src/types/.supabase.md +43 -29
- package/src/types/.tool.types.md +43 -23
- package/src/types/.video-processing.md +40 -31
- package/src/types/supabase.ts +80 -0
- package/src/types/video-processing.ts +1 -0
- package/src/utils/.announcement-storage.md +49 -17
- package/src/utils/.app-config.md +22 -18
- package/src/utils/.brand-marks.md +46 -0
- package/src/utils/.cn.md +40 -29
- package/src/utils/.color-analysis.md +34 -25
- package/src/utils/.common.md +43 -23
- package/src/utils/.content-href.md +64 -0
- package/src/utils/.content-ref-groups.md +51 -0
- package/src/utils/.date-utils.md +46 -35
- package/src/utils/.doc-path-utils.md +38 -0
- package/src/utils/.doc-tree-nav.md +51 -0
- package/src/utils/.embed-authed-fetch.md +48 -32
- package/src/utils/.embed-content-fetch.md +36 -0
- package/src/utils/.embed-url-converters.md +52 -0
- package/src/utils/.extract-items.md +49 -0
- package/src/utils/.faq-anchor.md +48 -0
- package/src/utils/.format.md +73 -55
- package/src/utils/.humanity-signals.md +59 -0
- package/src/utils/.index.md +73 -31
- package/src/utils/.list-url.md +43 -0
- package/src/utils/.markdown-section-extractor.md +57 -0
- package/src/utils/.markdown-to-plain.md +51 -0
- package/src/utils/.media-carousel-utils-stub.md +42 -31
- package/src/utils/.ods-color-utils.md +84 -43
- package/src/utils/.og-placeholder.md +45 -0
- package/src/utils/.page-header-constants.md +26 -0
- package/src/utils/.platform-config.md +34 -34
- package/src/utils/.release-badge.md +47 -0
- package/src/utils/.release-cover.md +45 -0
- package/src/utils/.same-page-hash-nav.md +45 -0
- package/src/utils/.scroll-into-view.md +32 -25
- package/src/utils/.seo-description.md +37 -0
- package/src/utils/.seo-title.md +25 -0
- package/src/utils/.social-embed-cache.md +37 -0
- package/src/utils/.source-icons.md +30 -34
- package/src/utils/.suggestion-url.md +46 -0
- package/src/utils/.tool-utils.md +39 -24
- package/src/utils/.tree-builder.md +64 -0
- package/src/utils/.video-bite-id.md +42 -0
- package/src/utils/announcement-storage.ts +9 -18
- package/src/utils/dev-sections/.dev-section-param-keys.md +51 -0
- package/src/utils/dev-sections/.openframe-dev-sections.md +40 -28
- package/src/utils/dismiss-cookie.ts +55 -0
- package/src/utils/dismissal-storage.ts +38 -0
- package/src/utils/index.ts +3 -0
- package/dist/chunk-BBUEY73L.js.map +0 -1
- package/dist/chunk-G3UN2DXU.cjs.map +0 -1
- package/dist/chunk-OWMLWJQY.cjs.map +0 -1
- package/dist/chunk-SASR7SK5.js.map +0 -1
- package/src/components/chat/utils/.onboarding-icons.md +0 -28
- package/src/hooks/.use-og-placeholder.md +0 -51
- /package/dist/{chunk-MGKCS6KS.js.map → chunk-3WCARCI4.js.map} +0 -0
- /package/dist/{chunk-Y3Y2DLNO.js.map → chunk-6UGYBCEN.js.map} +0 -0
- /package/dist/{chunk-PSPWT2Q5.js.map → chunk-7LWXWXEY.js.map} +0 -0
- /package/dist/{chunk-VTSRDC4W.js.map → chunk-CKC3EAYT.js.map} +0 -0
- /package/dist/{chunk-ZRANZNEA.js.map → chunk-JJE5TUZK.js.map} +0 -0
- /package/dist/{chunk-66BNAFO6.js.map → chunk-JQIUBFHL.js.map} +0 -0
- /package/dist/{chunk-2DIOV7BR.js.map → chunk-UPN6EFOM.js.map} +0 -0
- /package/dist/{chunk-4SMRQ4SN.js.map → chunk-WBL5Y4PS.js.map} +0 -0
- /package/dist/{chunk-FP4H6Y5O.js.map → chunk-WPYPSIY2.js.map} +0 -0
- /package/dist/{chunk-R5WJJL4V.js.map → chunk-X5X43HFV.js.map} +0 -0
- /package/dist/{chunk-DEHZ5CTC.js.map → chunk-XTWKDMCG.js.map} +0 -0
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* layout="native" → intrinsic aspect ratio. Bites grid, blog cards.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
-
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
33
|
+
import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
34
34
|
import MuxPlayer from '@mux/mux-player-react';
|
|
35
35
|
import { VideoPlayBadge, VideoUnmuteGlyph } from './video-center-badge';
|
|
36
36
|
import { fetchPriorityProp } from '../../utils/fetch-priority';
|
|
@@ -214,7 +214,33 @@ export function extractYouTubeId(url: string): string | null {
|
|
|
214
214
|
// Props
|
|
215
215
|
// =============================================================================
|
|
216
216
|
|
|
217
|
-
export type VideoLayout = 'centered' | 'fill' | 'native';
|
|
217
|
+
export type VideoLayout = 'centered' | 'fill' | 'native' | 'wide';
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Imperative snapshot/control handle for playback-handoff surfaces (the
|
|
221
|
+
* floating walkthrough widget's mini-player continuation). Getters power
|
|
222
|
+
* close-time snapshots; the mutators let a close/reopen gesture drive the
|
|
223
|
+
* player without remounting. `getDuration` exists so an "ended" predicate
|
|
224
|
+
* (`duration - time < 1s`) is evaluable at close time.
|
|
225
|
+
*/
|
|
226
|
+
export interface VideoPlayerHandle {
|
|
227
|
+
getCurrentTime(): number;
|
|
228
|
+
getDuration(): number;
|
|
229
|
+
getPaused(): boolean;
|
|
230
|
+
getMuted(): boolean;
|
|
231
|
+
play(): Promise<void>;
|
|
232
|
+
pause(): void;
|
|
233
|
+
setMuted(muted: boolean): void;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** Muted-fallback state reported to hosts that own their own unmute control
|
|
237
|
+
* (`onMutedFallbackChange`). `blocked` is true when even the muted play()
|
|
238
|
+
* retry was rejected (iOS Low Power Mode) — the host's control is really
|
|
239
|
+
* a "play" affordance in that state, not an "unmute" one. */
|
|
240
|
+
export interface VideoMutedFallbackState {
|
|
241
|
+
muted: boolean;
|
|
242
|
+
blocked: boolean;
|
|
243
|
+
}
|
|
218
244
|
|
|
219
245
|
interface VideoCommonProps {
|
|
220
246
|
/** Layout wrapper. Detail pages pass `"centered"`. Default `"native"`. */
|
|
@@ -237,9 +263,14 @@ interface VideoCommonProps {
|
|
|
237
263
|
minimalControls?: boolean;
|
|
238
264
|
}
|
|
239
265
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
266
|
+
/**
|
|
267
|
+
* File-playback options. Declared ONCE and mixed into the public prop unions
|
|
268
|
+
* AND the internal player, because these were hand-copied into four places and
|
|
269
|
+
* every new prop had to be added to all of them (18 props x 4 sites before this
|
|
270
|
+
* collapse). The dispatcher forwards them with a spread, so a prop added here
|
|
271
|
+
* reaches FilePlayer for free.
|
|
272
|
+
*/
|
|
273
|
+
interface VideoFilePlaybackProps {
|
|
243
274
|
/**
|
|
244
275
|
* SRT raw content. Deprecated: pass `captionsUrl` (VTT) instead.
|
|
245
276
|
* Native `<track>` requires a URL; raw SRT can't be rendered without
|
|
@@ -249,60 +280,117 @@ interface VideoFileProps extends VideoCommonProps {
|
|
|
249
280
|
srtContent?: string | null;
|
|
250
281
|
/** HTTPS URL to a VTT captions file. Rendered as a native `<track>`. */
|
|
251
282
|
captionsUrl?: string | null;
|
|
252
|
-
/** Autoplay muted on mount (forwarded as MuxPlayer `autoPlay="muted"`)
|
|
283
|
+
/** Autoplay muted on mount (forwarded as MuxPlayer `autoPlay="muted"`). */
|
|
253
284
|
autoPlay?: boolean;
|
|
254
285
|
/** Loop playback — short bite previews. */
|
|
255
286
|
loop?: boolean;
|
|
256
|
-
/** Hide all player chrome (MuxPlayer `--controls: none`)
|
|
287
|
+
/** Hide all player chrome (MuxPlayer `--controls: none`). */
|
|
257
288
|
chromeless?: boolean;
|
|
258
|
-
/** Play while the pointer hovers
|
|
259
|
-
*
|
|
260
|
-
* the browser's autoplay policy rejects unmuted hover playback. */
|
|
289
|
+
/** Play while the pointer hovers, pause on leave. Tries WITH sound at 50%
|
|
290
|
+
* first; falls back to muted when autoplay policy rejects unmuted. */
|
|
261
291
|
playOnHover?: boolean;
|
|
262
|
-
/** CONTROLLED variant of playOnHover: the host owns the hover state
|
|
263
|
-
* the bite-strip card, whose overlay also counts as "hovering the card").
|
|
264
|
-
* true → start hover playback, false → pause. When provided, the internal
|
|
265
|
-
* pointer handlers are disabled. */
|
|
292
|
+
/** CONTROLLED variant of playOnHover: the host owns the hover state. */
|
|
266
293
|
playWhenHovered?: boolean;
|
|
267
|
-
/**
|
|
268
|
-
* seeked to `#t=0.1` (media-fragment trick; paints on iOS Safari where a
|
|
269
|
-
* fragmentless metadata load stays blank). No chrome, no playback, no
|
|
270
|
-
* MuxPlayer cost — the resting facade layer under strip cards when no
|
|
271
|
-
* poster asset exists. `poster`/`fit`/`className` are honored; all other
|
|
272
|
-
* player props are ignored. */
|
|
273
|
-
firstFrameOnly?: boolean;
|
|
274
|
-
/** Media preload hint. When omitted, the SSOT default applies:
|
|
275
|
-
* `'metadata'` (manifest + ~1 segment buffered on mount — instant
|
|
276
|
-
* hover/click start, bounded by playback-core's maxBufferLength=1 clamp),
|
|
277
|
-
* downgraded to `'none'` on Save-Data connections. Pass a value only to
|
|
278
|
-
* override the policy deliberately. */
|
|
294
|
+
/** Media preload hint. When omitted the SSOT default applies. */
|
|
279
295
|
preload?: 'none' | 'metadata' | 'auto';
|
|
280
|
-
/**
|
|
281
|
-
* (MuxPlayer default); `'cover'` crops to fill — aspect-cropped grid
|
|
282
|
-
* cells and social-post mockups. */
|
|
296
|
+
/** object-fit for the media element. */
|
|
283
297
|
fit?: 'contain' | 'cover';
|
|
298
|
+
/** Start position in seconds (applied at LOAD time). */
|
|
299
|
+
startTime?: number;
|
|
300
|
+
/** Imperative handle for snapshot/control (mini-player continuation). */
|
|
301
|
+
playerHandleRef?: React.Ref<VideoPlayerHandle>;
|
|
302
|
+
/** Attempt UNMUTED autoplay on mount; falls back to muted on rejection. */
|
|
303
|
+
autoPlayUnmuted?: boolean;
|
|
304
|
+
/** Arm the muted-fallback state (host renders its own unmute affordance). */
|
|
305
|
+
startMuted?: boolean;
|
|
306
|
+
/** Host's standing mute intent — hover playback must not override it. */
|
|
307
|
+
mutedIntent?: boolean;
|
|
308
|
+
/** Suppress the INTERNAL center unmute glyph. Hosts whose own overlay
|
|
309
|
+
* button sits above the media render their own reachable control. */
|
|
310
|
+
hideMutedBadge?: boolean;
|
|
311
|
+
/** Reports muted-fallback state changes — see `VideoMutedFallbackState`. */
|
|
312
|
+
onMutedFallbackChange?: (state: VideoMutedFallbackState) => void;
|
|
313
|
+
/** Fired on the media element's `ended` event. */
|
|
314
|
+
onEnded?: () => void;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** The keys above, for the dispatcher's spread. `satisfies` rejects an EXTRA
|
|
318
|
+
* or misspelled key; the assertion below rejects a MISSING one (which would
|
|
319
|
+
* otherwise compile fine and silently stop forwarding that prop). */
|
|
320
|
+
const VIDEO_FILE_PLAYBACK_KEYS = [
|
|
321
|
+
'srtContent', 'captionsUrl', 'autoPlay', 'loop', 'chromeless', 'playOnHover',
|
|
322
|
+
'playWhenHovered', 'preload', 'fit', 'startTime', 'playerHandleRef',
|
|
323
|
+
'autoPlayUnmuted', 'startMuted', 'mutedIntent', 'hideMutedBadge',
|
|
324
|
+
'onMutedFallbackChange', 'onEnded',
|
|
325
|
+
] as const satisfies readonly (keyof VideoFilePlaybackProps)[];
|
|
326
|
+
|
|
327
|
+
/** Build-time proof that a key list covers EVERY key of its interface — the
|
|
328
|
+
* `satisfies` on the list itself only rejects extra/misspelled keys, so
|
|
329
|
+
* without this a newly added prop compiles fine and silently stops being
|
|
330
|
+
* forwarded. Instantiate once per (interface, key-list) pair. */
|
|
331
|
+
type AllKeysForwarded<TProps, TKeys extends readonly (keyof TProps)[]> =
|
|
332
|
+
Exclude<keyof TProps, TKeys[number]> extends never ? true : never;
|
|
333
|
+
|
|
334
|
+
/** Copy only the declared keys that are actually PRESENT on the union member,
|
|
335
|
+
* so an absent optional prop stays absent rather than becoming `undefined`. */
|
|
336
|
+
function pickForwardedKeys<TProps>(
|
|
337
|
+
props: VideoProps,
|
|
338
|
+
keys: readonly (keyof TProps)[],
|
|
339
|
+
): TProps {
|
|
340
|
+
const out: Record<string, unknown> = {};
|
|
341
|
+
for (const k of keys) {
|
|
342
|
+
if ((k as string) in props) out[k as string] = (props as unknown as Record<string, unknown>)[k as string];
|
|
343
|
+
}
|
|
344
|
+
return out as TProps;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const _filePlaybackForwarded: AllKeysForwarded<VideoFilePlaybackProps, typeof VIDEO_FILE_PLAYBACK_KEYS> = true;
|
|
348
|
+
void _filePlaybackForwarded;
|
|
349
|
+
|
|
350
|
+
const pickFilePlayback = (props: VideoProps): VideoFilePlaybackProps =>
|
|
351
|
+
pickForwardedKeys<VideoFilePlaybackProps>(props, VIDEO_FILE_PLAYBACK_KEYS);
|
|
352
|
+
|
|
353
|
+
interface VideoFileProps extends VideoCommonProps, VideoFilePlaybackProps {
|
|
354
|
+
kind: 'file';
|
|
355
|
+
url: string;
|
|
356
|
+
firstFrameOnly?: boolean;
|
|
284
357
|
}
|
|
285
358
|
|
|
286
|
-
|
|
359
|
+
/** YouTube-facade behavior props, declared ONCE and reused by every layer that
|
|
360
|
+
* forwards them (the two union members, the facade, its inner). Same reason as
|
|
361
|
+
* `VideoFilePlaybackProps`: four hand-kept copies drift silently. */
|
|
362
|
+
interface VideoYouTubeFacadeProps {
|
|
363
|
+
/** Activate the facade (mount the iframe) immediately — for surfaces whose
|
|
364
|
+
* opening interaction IS the play gesture (the walkthrough theater). The
|
|
365
|
+
* embed URL already carries `autoplay=1`. */
|
|
366
|
+
autoActivate?: boolean;
|
|
367
|
+
/** Edge-triggered pause signal: when this flips false→true while activated,
|
|
368
|
+
* the facade posts a `pauseVideo` command over its existing
|
|
369
|
+
* `enablejsapi=1` postMessage channel. Lets a closing dialog stop iframe
|
|
370
|
+
* audio BEFORE the exit animation finishes unmounting it. */
|
|
371
|
+
suspended?: boolean;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const VIDEO_YOUTUBE_FACADE_KEYS = [
|
|
375
|
+
'autoActivate', 'suspended',
|
|
376
|
+
] as const satisfies readonly (keyof VideoYouTubeFacadeProps)[];
|
|
377
|
+
|
|
378
|
+
const _youTubeForwarded: AllKeysForwarded<VideoYouTubeFacadeProps, typeof VIDEO_YOUTUBE_FACADE_KEYS> = true;
|
|
379
|
+
void _youTubeForwarded;
|
|
380
|
+
|
|
381
|
+
const pickYouTube = (props: VideoProps): VideoYouTubeFacadeProps =>
|
|
382
|
+
pickForwardedKeys<VideoYouTubeFacadeProps>(props, VIDEO_YOUTUBE_FACADE_KEYS);
|
|
383
|
+
|
|
384
|
+
interface VideoYouTubeProps extends VideoCommonProps, VideoYouTubeFacadeProps {
|
|
287
385
|
kind: 'youtube';
|
|
288
386
|
/** Either a full YT URL or just the video id. */
|
|
289
387
|
url: string;
|
|
290
388
|
}
|
|
291
389
|
|
|
292
|
-
interface VideoAutoProps extends VideoCommonProps {
|
|
390
|
+
interface VideoAutoProps extends VideoCommonProps, VideoFilePlaybackProps, VideoYouTubeFacadeProps {
|
|
293
391
|
kind?: 'auto';
|
|
294
392
|
url: string;
|
|
295
|
-
srtContent?: string | null;
|
|
296
|
-
captionsUrl?: string | null;
|
|
297
|
-
/** See VideoFileProps — no-ops when the URL resolves to the YouTube branch. */
|
|
298
|
-
autoPlay?: boolean;
|
|
299
|
-
loop?: boolean;
|
|
300
|
-
chromeless?: boolean;
|
|
301
|
-
playOnHover?: boolean;
|
|
302
|
-
playWhenHovered?: boolean;
|
|
303
393
|
firstFrameOnly?: boolean;
|
|
304
|
-
preload?: 'none' | 'metadata' | 'auto';
|
|
305
|
-
fit?: 'contain' | 'cover';
|
|
306
394
|
}
|
|
307
395
|
|
|
308
396
|
export type VideoProps = VideoFileProps | VideoYouTubeProps | VideoAutoProps;
|
|
@@ -326,6 +414,7 @@ export function Video(props: VideoProps): React.ReactElement | null {
|
|
|
326
414
|
priority={props.priority}
|
|
327
415
|
className={props.className}
|
|
328
416
|
minimalControls={props.minimalControls}
|
|
417
|
+
{...pickYouTube(props)}
|
|
329
418
|
/>
|
|
330
419
|
) : 'firstFrameOnly' in props && props.firstFrameOnly ? (
|
|
331
420
|
<FirstFramePreview
|
|
@@ -339,15 +428,7 @@ export function Video(props: VideoProps): React.ReactElement | null {
|
|
|
339
428
|
url={url}
|
|
340
429
|
poster={props.poster}
|
|
341
430
|
muted={props.muted}
|
|
342
|
-
|
|
343
|
-
captionsUrl={'captionsUrl' in props ? props.captionsUrl : null}
|
|
344
|
-
autoPlay={'autoPlay' in props ? props.autoPlay : undefined}
|
|
345
|
-
loop={'loop' in props ? props.loop : undefined}
|
|
346
|
-
chromeless={'chromeless' in props ? props.chromeless : undefined}
|
|
347
|
-
playOnHover={'playOnHover' in props ? props.playOnHover : undefined}
|
|
348
|
-
playWhenHovered={'playWhenHovered' in props ? props.playWhenHovered : undefined}
|
|
349
|
-
preload={'preload' in props ? props.preload : undefined}
|
|
350
|
-
fit={'fit' in props ? props.fit : undefined}
|
|
431
|
+
{...pickFilePlayback(props)}
|
|
351
432
|
className={props.className}
|
|
352
433
|
/>
|
|
353
434
|
);
|
|
@@ -402,6 +483,17 @@ function wrapWithLayout(
|
|
|
402
483
|
);
|
|
403
484
|
case 'fill':
|
|
404
485
|
return <div className="absolute inset-0 w-full h-full">{inner}</div>;
|
|
486
|
+
case 'wide':
|
|
487
|
+
// In-flow 16:9 at full width, no max-width cap. The theater surface:
|
|
488
|
+
// the video sizes the box (contributes height, unlike `fill`), and any
|
|
489
|
+
// following siblings (the AI summary in EntityVideoSection) flow beneath
|
|
490
|
+
// it. `max-w-3xl` (centered) would strand a small video in a wide dialog.
|
|
491
|
+
// `bg-ods-bg` (the darkest neutral surface) gives the theater a proper
|
|
492
|
+
// near-black video stage — letterbox bars and the pre-play frame read as
|
|
493
|
+
// a video player, not a gray card. Border dropped: a stage has no chrome.
|
|
494
|
+
return (
|
|
495
|
+
<div className="w-full aspect-video rounded-lg overflow-hidden bg-ods-bg">{inner}</div>
|
|
496
|
+
);
|
|
405
497
|
case 'native':
|
|
406
498
|
default:
|
|
407
499
|
// `native` callers (blog cards etc.) are
|
|
@@ -458,22 +550,10 @@ function FirstFramePreview({
|
|
|
458
550
|
// File branch — MuxPlayer (handles both .m3u8 HLS and plain .mp4)
|
|
459
551
|
// -----------------------------------------------------------------------------
|
|
460
552
|
|
|
461
|
-
interface FilePlayerProps {
|
|
553
|
+
interface FilePlayerProps extends VideoFilePlaybackProps {
|
|
462
554
|
url: string;
|
|
463
555
|
poster?: string | null;
|
|
464
556
|
muted?: boolean;
|
|
465
|
-
srtContent?: string | null;
|
|
466
|
-
captionsUrl?: string | null;
|
|
467
|
-
autoPlay?: boolean;
|
|
468
|
-
loop?: boolean;
|
|
469
|
-
chromeless?: boolean;
|
|
470
|
-
playOnHover?: boolean;
|
|
471
|
-
playWhenHovered?: boolean;
|
|
472
|
-
/** Media preload hint — see the public `VideoFileProps.preload` JSDoc.
|
|
473
|
-
* When omitted, defaults to 'metadata' ('none' under Save-Data). */
|
|
474
|
-
preload?: 'none' | 'metadata' | 'auto';
|
|
475
|
-
/** Object-fit — 'cover' maps to media-chrome's `--media-object-fit`. */
|
|
476
|
-
fit?: 'contain' | 'cover';
|
|
477
557
|
className?: string;
|
|
478
558
|
}
|
|
479
559
|
|
|
@@ -490,6 +570,14 @@ function FilePlayer({
|
|
|
490
570
|
playWhenHovered,
|
|
491
571
|
preload,
|
|
492
572
|
fit,
|
|
573
|
+
startTime,
|
|
574
|
+
playerHandleRef,
|
|
575
|
+
autoPlayUnmuted,
|
|
576
|
+
startMuted,
|
|
577
|
+
mutedIntent = false,
|
|
578
|
+
hideMutedBadge,
|
|
579
|
+
onMutedFallbackChange,
|
|
580
|
+
onEnded,
|
|
493
581
|
className,
|
|
494
582
|
}: FilePlayerProps): React.ReactElement {
|
|
495
583
|
// Explicit preload policy — never rely on the browser/MuxPlayer implicit
|
|
@@ -519,9 +607,18 @@ function FilePlayer({
|
|
|
519
607
|
pause?: () => void;
|
|
520
608
|
muted?: boolean;
|
|
521
609
|
volume?: number;
|
|
610
|
+
currentTime?: number;
|
|
611
|
+
duration?: number;
|
|
612
|
+
paused?: boolean;
|
|
522
613
|
addEventListener?: (type: string, listener: () => void) => void;
|
|
523
614
|
removeEventListener?: (type: string, listener: () => void) => void;
|
|
524
615
|
} | null>(null);
|
|
616
|
+
// True while the muted fallback is ALSO a blocked-autoplay state (even muted
|
|
617
|
+
// play() was rejected — iOS Low Power). Lets the host label its control
|
|
618
|
+
// "play" vs "unmute". MUST be state, not a ref: the blocked transition often
|
|
619
|
+
// lands while `hoverMutedFallback` is already true (a ref write wouldn't
|
|
620
|
+
// re-run the reporting effect, so hosts would never see blocked: true).
|
|
621
|
+
const [mutedFallbackBlocked, setMutedFallbackBlocked] = useState(false);
|
|
525
622
|
// Dev/opt-in hover→'playing' latency metric (see videoPerfDebugEnabled).
|
|
526
623
|
// One listener at a time — re-entering hover replaces it; hover-leave and
|
|
527
624
|
// unmount clear it so no stale listener survives across generations.
|
|
@@ -575,11 +672,14 @@ function FilePlayer({
|
|
|
575
672
|
try {
|
|
576
673
|
el.volume = 0.5;
|
|
577
674
|
if (userHasInteracted) {
|
|
578
|
-
// Post-activation: unmuted playback is allowed — play with sound
|
|
675
|
+
// Post-activation: unmuted playback is allowed — play with sound,
|
|
676
|
+
// UNLESS the host holds a standing mute intent. Force-unmuting here
|
|
677
|
+
// audibly undid an explicit mute on the next hover, while the host's
|
|
678
|
+
// toggle still rendered "muted".
|
|
579
679
|
// The NotAllowedError guard stays as a belt-and-suspenders fallback;
|
|
580
680
|
// a fast hover-out's pause() rejects with AbortError and must not
|
|
581
681
|
// restart playback (name mismatch + cleared hoverActiveRef).
|
|
582
|
-
el.muted =
|
|
682
|
+
el.muted = mutedIntentRef.current;
|
|
583
683
|
(el.play?.() as Promise<void> | undefined)?.catch?.((err: unknown) => {
|
|
584
684
|
const name = (err as { name?: string } | null)?.name;
|
|
585
685
|
if (
|
|
@@ -589,7 +689,15 @@ function FilePlayer({
|
|
|
589
689
|
) {
|
|
590
690
|
try {
|
|
591
691
|
el.muted = true;
|
|
592
|
-
(el.play?.() as Promise<void> | undefined)?.catch?.(() => {
|
|
692
|
+
(el.play?.() as Promise<void> | undefined)?.catch?.(() => {
|
|
693
|
+
// Even MUTED playback was rejected (iOS Low Power, Firefox
|
|
694
|
+
// media.autoplay.default=5, enterprise policy). Report it, or
|
|
695
|
+
// the host renders a "Pause"/"Unmute" control over a video
|
|
696
|
+
// that never started and the first press is a no-op.
|
|
697
|
+
if (hoverActiveRef.current && generation === hoverGenerationRef.current) {
|
|
698
|
+
setMutedFallbackBlocked(true);
|
|
699
|
+
}
|
|
700
|
+
});
|
|
593
701
|
setHoverMutedFallback(true);
|
|
594
702
|
} catch { /* give up silently */ }
|
|
595
703
|
}
|
|
@@ -600,7 +708,14 @@ function FilePlayer({
|
|
|
600
708
|
// rejection round-trip, and UNMUTE LIVE the instant the user's first
|
|
601
709
|
// click/keydown lands anywhere while this hover is still active.
|
|
602
710
|
el.muted = true;
|
|
603
|
-
(el.play?.() as Promise<void> | undefined)?.catch?.(() => {
|
|
711
|
+
(el.play?.() as Promise<void> | undefined)?.catch?.(() => {
|
|
712
|
+
// Same as the post-activation retry above: a rejected MUTED play is
|
|
713
|
+
// "blocked", not "muted", and the host's control label depends on
|
|
714
|
+
// the difference.
|
|
715
|
+
if (hoverActiveRef.current && generation === hoverGenerationRef.current) {
|
|
716
|
+
setMutedFallbackBlocked(true);
|
|
717
|
+
}
|
|
718
|
+
});
|
|
604
719
|
setHoverMutedFallback(true);
|
|
605
720
|
clearActivationWaiter();
|
|
606
721
|
const waiter = () => {
|
|
@@ -652,6 +767,146 @@ function FilePlayer({
|
|
|
652
767
|
|
|
653
768
|
const handleHoverEnter = playOnHover && !hoverControlled ? startHoverPlayback : undefined;
|
|
654
769
|
const handleHoverLeave = playOnHover && !hoverControlled ? stopHoverPlayback : undefined;
|
|
770
|
+
|
|
771
|
+
// Report muted-fallback transitions to hosts that render their own control
|
|
772
|
+
// (hideMutedBadge). Emitted on every change to hoverMutedFallback so the
|
|
773
|
+
// host's card-level unmute/play affordance stays in sync.
|
|
774
|
+
// Read through a ref, NOT the closure: startHoverPlayback is memoized on
|
|
775
|
+
// empty-dep callbacks, so it would capture render-0's value forever (that is
|
|
776
|
+
// why threading the prop through three layers still did nothing). Adding it
|
|
777
|
+
// to the deps instead would re-run hover playback on every mute toggle and
|
|
778
|
+
// play() over an explicit pause.
|
|
779
|
+
const mutedIntentRef = useRef(mutedIntent);
|
|
780
|
+
mutedIntentRef.current = mutedIntent;
|
|
781
|
+
const onMutedFallbackChangeRef = useRef(onMutedFallbackChange);
|
|
782
|
+
onMutedFallbackChangeRef.current = onMutedFallbackChange;
|
|
783
|
+
useEffect(() => {
|
|
784
|
+
onMutedFallbackChangeRef.current?.({
|
|
785
|
+
muted: hoverMutedFallback,
|
|
786
|
+
blocked: hoverMutedFallback && mutedFallbackBlocked,
|
|
787
|
+
});
|
|
788
|
+
}, [hoverMutedFallback, mutedFallbackBlocked]);
|
|
789
|
+
|
|
790
|
+
// Autoplay-on-mount for handoff surfaces (theater open / resume card). Runs
|
|
791
|
+
// once. `autoPlayUnmuted` tries sound (the mount is gesture-adjacent) and
|
|
792
|
+
// falls back to muted + fallback state on rejection; `startMuted` (used with
|
|
793
|
+
// MuxPlayer's own muted autoPlay) just arms the fallback state so the host's
|
|
794
|
+
// unmute control shows from the first frame.
|
|
795
|
+
const autoPlayKickedRef = useRef(false);
|
|
796
|
+
useEffect(() => {
|
|
797
|
+
if (autoPlayKickedRef.current) return;
|
|
798
|
+
if (startMuted) {
|
|
799
|
+
// Actually mute the element. Previously this only armed the UI state, so
|
|
800
|
+
// a paused+muted resume (no autoPlay to carry `muted`) sat unmuted and
|
|
801
|
+
// the first Play press blasted full volume while every label said muted.
|
|
802
|
+
const mutedEl = hoverPlayerRef.current;
|
|
803
|
+
if (!mutedEl) return; // latch AFTER the ref read — see the branch below
|
|
804
|
+
autoPlayKickedRef.current = true;
|
|
805
|
+
try { mutedEl.muted = true; } catch { /* ignore */ }
|
|
806
|
+
setMutedFallbackBlocked(false);
|
|
807
|
+
setHoverMutedFallback(true);
|
|
808
|
+
// When this surface is ALSO autoplaying, MuxPlayer issues its own muted
|
|
809
|
+
// play() whose rejection we never see. Issue a parallel one purely to
|
|
810
|
+
// OBSERVE the outcome: a redundant play on an already-playing element is
|
|
811
|
+
// a no-op, but a rejection is the only signal that the host must render
|
|
812
|
+
// "Play" instead of "Pause" over a video that never started.
|
|
813
|
+
if (autoPlay) {
|
|
814
|
+
try {
|
|
815
|
+
(mutedEl.play?.() as Promise<void> | undefined)?.catch?.(() => setMutedFallbackBlocked(true));
|
|
816
|
+
} catch { setMutedFallbackBlocked(true); }
|
|
817
|
+
}
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
if (!autoPlayUnmuted) return;
|
|
821
|
+
const el = hoverPlayerRef.current;
|
|
822
|
+
// Latch AFTER the ref check: setting it first meant a null player on the
|
|
823
|
+
// first run burned the one-shot kick with no retry (the deps never change).
|
|
824
|
+
if (!el) return;
|
|
825
|
+
autoPlayKickedRef.current = true;
|
|
826
|
+
try {
|
|
827
|
+
el.muted = false;
|
|
828
|
+
el.volume = typeof el.volume === 'number' ? el.volume : 1;
|
|
829
|
+
(el.play?.() as Promise<void> | undefined)?.catch?.((err: unknown) => {
|
|
830
|
+
const name = (err as { name?: string } | null)?.name;
|
|
831
|
+
if (name !== 'NotAllowedError') return;
|
|
832
|
+
// Unmuted rejected — retry muted; if THAT rejects too, mark blocked.
|
|
833
|
+
try {
|
|
834
|
+
el.muted = true;
|
|
835
|
+
(el.play?.() as Promise<void> | undefined)?.catch?.(() => {
|
|
836
|
+
setMutedFallbackBlocked(true);
|
|
837
|
+
setHoverMutedFallback(true);
|
|
838
|
+
});
|
|
839
|
+
setMutedFallbackBlocked(false);
|
|
840
|
+
setHoverMutedFallback(true);
|
|
841
|
+
} catch {
|
|
842
|
+
setMutedFallbackBlocked(true);
|
|
843
|
+
setHoverMutedFallback(true);
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
} catch { /* ignore */ }
|
|
847
|
+
}, [autoPlayUnmuted, startMuted, autoPlay]);
|
|
848
|
+
|
|
849
|
+
// volumechange listener — clears the muted-fallback state when the media is
|
|
850
|
+
// unmuted by ANY path (MuxPlayer's own chrome in the theater, or the host
|
|
851
|
+
// control). Without this a stale glyph/state can persist after a chrome unmute.
|
|
852
|
+
useEffect(() => {
|
|
853
|
+
const el = hoverPlayerRef.current;
|
|
854
|
+
if (!el?.addEventListener) return;
|
|
855
|
+
const onVolumeChange = () => {
|
|
856
|
+
if (el.muted === false) {
|
|
857
|
+
setMutedFallbackBlocked(false);
|
|
858
|
+
setHoverMutedFallback(false);
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
try { el.addEventListener('volumechange', onVolumeChange); } catch { /* ignore */ }
|
|
862
|
+
return () => { try { el.removeEventListener?.('volumechange', onVolumeChange); } catch { /* ignore */ } };
|
|
863
|
+
}, []);
|
|
864
|
+
|
|
865
|
+
// `playing` clears the blocked-autoplay flag. Without this, once a muted
|
|
866
|
+
// retry had been rejected (iOS Low Power) the host's centre glyph read "Play"
|
|
867
|
+
// over a playing video forever — the flag was only cleared by an unmute.
|
|
868
|
+
useEffect(() => {
|
|
869
|
+
const el = hoverPlayerRef.current;
|
|
870
|
+
if (!el?.addEventListener) return;
|
|
871
|
+
const onPlaying = () => setMutedFallbackBlocked(false);
|
|
872
|
+
try { el.addEventListener('playing', onPlaying); } catch { /* ignore */ }
|
|
873
|
+
return () => { try { el.removeEventListener?.('playing', onPlaying); } catch { /* ignore */ } };
|
|
874
|
+
}, []);
|
|
875
|
+
|
|
876
|
+
// ended listener — host clears its handoff (mini-player continuation).
|
|
877
|
+
const onEndedRef = useRef(onEnded);
|
|
878
|
+
onEndedRef.current = onEnded;
|
|
879
|
+
useEffect(() => {
|
|
880
|
+
const el = hoverPlayerRef.current;
|
|
881
|
+
if (!el?.addEventListener) return;
|
|
882
|
+
const handler = () => onEndedRef.current?.();
|
|
883
|
+
try { el.addEventListener('ended', handler); } catch { /* ignore */ }
|
|
884
|
+
return () => { try { el.removeEventListener?.('ended', handler); } catch { /* ignore */ } };
|
|
885
|
+
}, []);
|
|
886
|
+
|
|
887
|
+
// Imperative handle — snapshot getters + control mutators for handoff.
|
|
888
|
+
useImperativeHandle(playerHandleRef, (): VideoPlayerHandle => ({
|
|
889
|
+
getCurrentTime: () => hoverPlayerRef.current?.currentTime ?? 0,
|
|
890
|
+
getDuration: () => {
|
|
891
|
+
const d = hoverPlayerRef.current?.duration;
|
|
892
|
+
return typeof d === 'number' && isFinite(d) ? d : 0;
|
|
893
|
+
},
|
|
894
|
+
getPaused: () => hoverPlayerRef.current?.paused ?? true,
|
|
895
|
+
getMuted: () => hoverPlayerRef.current?.muted ?? false,
|
|
896
|
+
play: async () => { await hoverPlayerRef.current?.play?.(); },
|
|
897
|
+
pause: () => { try { hoverPlayerRef.current?.pause?.(); } catch { /* ignore */ } },
|
|
898
|
+
setMuted: (m: boolean) => {
|
|
899
|
+
const el = hoverPlayerRef.current;
|
|
900
|
+
if (!el) return;
|
|
901
|
+
try {
|
|
902
|
+
el.muted = m;
|
|
903
|
+
if (!m) {
|
|
904
|
+
setMutedFallbackBlocked(false);
|
|
905
|
+
setHoverMutedFallback(false);
|
|
906
|
+
}
|
|
907
|
+
} catch { /* ignore */ }
|
|
908
|
+
},
|
|
909
|
+
}), [playerHandleRef]);
|
|
655
910
|
// Raw SRT text is unusable without a custom overlay — and we just deleted
|
|
656
911
|
// the 900-LOC custom-controls layer that owned that overlay. Consumers
|
|
657
912
|
// pass `captionsUrl` (the API-side VTT conversion) alongside `srtContent`
|
|
@@ -683,7 +938,11 @@ function FilePlayer({
|
|
|
683
938
|
// is ever undefined on a `data-app-type` we haven't themed yet.
|
|
684
939
|
// NEVER let Mux pink leak onto a non-Flamingo platform.
|
|
685
940
|
accentColor="var(--ods-accent, var(--color-accent-primary))"
|
|
686
|
-
|
|
941
|
+
// `startMuted` only ARMS the muted-fallback state (so a host can render
|
|
942
|
+
// its own unmute control); it must not imply autoplay, or a resume that
|
|
943
|
+
// closed PAUSED would start playing while the toggle still reads "Play".
|
|
944
|
+
autoPlay={autoPlay ? 'muted' : autoPlayUnmuted ? 'any' : undefined}
|
|
945
|
+
startTime={typeof startTime === 'number' ? startTime : undefined}
|
|
687
946
|
loop={loop}
|
|
688
947
|
className={className}
|
|
689
948
|
// Fill the wrapping aspect-ratio container instead of MuxPlayer's
|
|
@@ -725,7 +984,7 @@ function FilePlayer({
|
|
|
725
984
|
// Styled to match media-chrome's center controls exactly (the play glyph in
|
|
726
985
|
// the same slot): plain large white glyph, no circle/border/background,
|
|
727
986
|
// slight dim on hover — so unmute reads as just another center control.
|
|
728
|
-
const unmuteBadge = hoverMutedFallback ? (
|
|
987
|
+
const unmuteBadge = hoverMutedFallback && !hideMutedBadge ? (
|
|
729
988
|
<button
|
|
730
989
|
type="button"
|
|
731
990
|
aria-label="Unmute"
|
|
@@ -763,6 +1022,18 @@ function FilePlayer({
|
|
|
763
1022
|
</div>
|
|
764
1023
|
);
|
|
765
1024
|
}
|
|
1025
|
+
// Handoff surfaces (autoPlayUnmuted / startMuted) need the relative wrapper so
|
|
1026
|
+
// the internal center unmute badge can dock — the bare branch has none. Hosts
|
|
1027
|
+
// that render their OWN control pass hideMutedBadge (unmuteBadge is null then,
|
|
1028
|
+
// but the wrapper is harmless).
|
|
1029
|
+
if (autoPlayUnmuted || startMuted) {
|
|
1030
|
+
return (
|
|
1031
|
+
<div className="relative w-full h-full">
|
|
1032
|
+
{player}
|
|
1033
|
+
{unmuteBadge}
|
|
1034
|
+
</div>
|
|
1035
|
+
);
|
|
1036
|
+
}
|
|
766
1037
|
return player;
|
|
767
1038
|
}
|
|
768
1039
|
|
|
@@ -770,7 +1041,7 @@ function FilePlayer({
|
|
|
770
1041
|
// YouTube facade — inlined lite-youtube-embed pattern
|
|
771
1042
|
// -----------------------------------------------------------------------------
|
|
772
1043
|
|
|
773
|
-
interface YouTubeFacadeProps {
|
|
1044
|
+
interface YouTubeFacadeProps extends VideoYouTubeFacadeProps {
|
|
774
1045
|
url: string;
|
|
775
1046
|
title?: string;
|
|
776
1047
|
priority?: boolean;
|
|
@@ -784,16 +1055,20 @@ function YouTubeFacade({
|
|
|
784
1055
|
priority,
|
|
785
1056
|
className,
|
|
786
1057
|
minimalControls,
|
|
1058
|
+
// `...facade` rather than naming each one: this hop is invisible to the
|
|
1059
|
+
// build-time forwarding proof, so a prop added to VideoYouTubeFacadeProps
|
|
1060
|
+
// would reach here and silently stop before Inner.
|
|
1061
|
+
...facade
|
|
787
1062
|
}: YouTubeFacadeProps): React.ReactElement | null {
|
|
788
1063
|
// `extractYouTubeId` handles both bare 11-char ids AND full URLs in a
|
|
789
1064
|
// single call site, so the resolution logic lives in exactly one place.
|
|
790
1065
|
const videoId = extractYouTubeId(url);
|
|
791
1066
|
if (!videoId) return null;
|
|
792
1067
|
|
|
793
|
-
return <YouTubeFacadeInner videoId={videoId} title={title} priority={priority} className={className} minimalControls={minimalControls} />;
|
|
1068
|
+
return <YouTubeFacadeInner videoId={videoId} title={title} priority={priority} className={className} minimalControls={minimalControls} {...facade} />;
|
|
794
1069
|
}
|
|
795
1070
|
|
|
796
|
-
interface YouTubeFacadeInnerProps {
|
|
1071
|
+
interface YouTubeFacadeInnerProps extends VideoYouTubeFacadeProps {
|
|
797
1072
|
videoId: string;
|
|
798
1073
|
title: string;
|
|
799
1074
|
priority?: boolean;
|
|
@@ -836,8 +1111,10 @@ function YouTubeFacadeInner({
|
|
|
836
1111
|
priority,
|
|
837
1112
|
className,
|
|
838
1113
|
minimalControls,
|
|
1114
|
+
autoActivate,
|
|
1115
|
+
suspended,
|
|
839
1116
|
}: YouTubeFacadeInnerProps): React.ReactElement {
|
|
840
|
-
const [activated, setActivated] = useState(
|
|
1117
|
+
const [activated, setActivated] = useState(Boolean(autoActivate));
|
|
841
1118
|
const iframeRef = useRef<HTMLIFrameElement | null>(null);
|
|
842
1119
|
|
|
843
1120
|
// Embed URL + poster URLs only change when `videoId` or `minimalControls`
|
|
@@ -976,6 +1253,24 @@ function YouTubeFacadeInner({
|
|
|
976
1253
|
};
|
|
977
1254
|
}, [activated]);
|
|
978
1255
|
|
|
1256
|
+
// Close-side pause: a closing dialog flips `suspended` false→true. Post the
|
|
1257
|
+
// pauseVideo command over the same enablejsapi channel so the iframe stops
|
|
1258
|
+
// BEFORE the Radix exit animation unmounts it (an unmount-cleanup post would
|
|
1259
|
+
// fire too late). Edge-triggered: only acts on the false→true transition
|
|
1260
|
+
// while activated (prev seeded false, so the initial render never pauses).
|
|
1261
|
+
const prevSuspendedRef = useRef(false);
|
|
1262
|
+
useEffect(() => {
|
|
1263
|
+
const wasSuspended = prevSuspendedRef.current;
|
|
1264
|
+
prevSuspendedRef.current = Boolean(suspended);
|
|
1265
|
+
if (!activated) return;
|
|
1266
|
+
if (suspended && !wasSuspended) {
|
|
1267
|
+
iframeRef.current?.contentWindow?.postMessage(
|
|
1268
|
+
'{"event":"command","func":"pauseVideo","args":[]}',
|
|
1269
|
+
YT_NOCOOKIE_ORIGIN,
|
|
1270
|
+
);
|
|
1271
|
+
}
|
|
1272
|
+
}, [suspended, activated]);
|
|
1273
|
+
|
|
979
1274
|
const wrapperClass = `relative w-full ${className ?? ''}`;
|
|
980
1275
|
const wrapperStyle = { paddingBottom: '56.25%' as const };
|
|
981
1276
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<!-- source-hash: 64f9480271adbe15fe1f799c4d66f96a -->
|
|
2
|
+
Thin wrapper page component that composes `DevSectionPage` chrome with `DeliveryLists` to render the full bug-fixes & enhancements delivery view, exposing only the API endpoint configuration and layout props to host applications.
|
|
3
|
+
|
|
4
|
+
## Key Components
|
|
5
|
+
|
|
6
|
+
| Export | Type | Description |
|
|
7
|
+
|---|---|---|
|
|
8
|
+
| `DeliveryPage` | `React.FC` | Main page component wrapping `DevSectionPage` + `DeliveryLists` |
|
|
9
|
+
| `DeliveryPageProps` | `interface` | Configuration props for endpoints, layout, and content slots |
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| `completedEndpoint` | `string` | `/api/delivery/completed` | GET endpoint for "Recently Completed" bucket |
|
|
16
|
+
| `inProgressEndpoint` | `string` | `/api/delivery/in-progress` | GET endpoint for "Active Tasks" bucket |
|
|
17
|
+
| `backButton` | `{ label?, href? } \| false` | `{ href: '/' }` | Back-button config; pass `false` to hide |
|
|
18
|
+
| `title` | `string` | — | Override page title |
|
|
19
|
+
| `subtitle` | `string` | — | Override page subtitle |
|
|
20
|
+
| `belowContent` | `ReactNode` | — | Optional slot rendered below the lists, inside page chrome |
|
|
21
|
+
| `shell` | `boolean` | `true` | Set `false` when host layout already provides the page container |
|
|
22
|
+
|
|
23
|
+
## Usage Example
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { DeliveryPage } from './delivery-page'
|
|
27
|
+
|
|
28
|
+
// Minimal usage — defaults apply
|
|
29
|
+
export default function Page() {
|
|
30
|
+
return <DeliveryPage />
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Custom endpoints + embedded layout (no standalone shell)
|
|
34
|
+
export default function EmbeddedDelivery() {
|
|
35
|
+
return (
|
|
36
|
+
<DeliveryPage
|
|
37
|
+
completedEndpoint="/api/ops/delivery/done"
|
|
38
|
+
inProgressEndpoint="/api/ops/delivery/active"
|
|
39
|
+
backButton={{ label: 'Back to Dashboard', href: '/dashboard' }}
|
|
40
|
+
title="Bug Fixes & Enhancements"
|
|
41
|
+
subtitle="Current sprint delivery status"
|
|
42
|
+
shell={false}
|
|
43
|
+
belowContent={<DeliveryFootnote />}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Source
|
|
50
|
+
|
|
51
|
+
[`delivery-page.tsx`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/delivery-page.tsx)
|