@flamingo-stack/openframe-frontend-core 0.0.703 → 0.0.704-snapshot.20261006133653
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-3L7KCOGO.cjs → chunk-2QEUFXNS.cjs} +30 -30
- package/dist/{chunk-BMJUKS6S.cjs → chunk-3256UJXS.cjs} +47 -47
- package/dist/{chunk-GZYLZ4MB.js → chunk-4S7TJYRQ.js} +3 -3
- package/dist/{chunk-ENGBNKUJ.js → chunk-5EFZO5EB.js} +675 -569
- package/dist/{chunk-TCZCMD5Q.js → chunk-5HBHO5TB.js} +1 -1
- package/dist/{chunk-BOUPNYUV.js → chunk-64HOMVYC.js} +5 -5
- package/dist/{chunk-YR6JPJF4.js → chunk-6XIF2Z7I.js} +4 -4
- package/dist/{chunk-NU724ZVN.cjs → chunk-7GHB2IK6.cjs} +121 -121
- package/dist/{chunk-GX3OUTFO.cjs → chunk-7ZYIC7NA.cjs} +69 -55
- package/dist/{chunk-53AC23ZN.js → chunk-A6WVQKOZ.js} +24 -24
- package/dist/{chunk-4OGAXAEG.cjs → chunk-ABU3TGXA.cjs} +3 -3
- package/dist/{chunk-RTXTGLGB.cjs → chunk-ACV4DFQ3.cjs} +4 -4
- package/dist/{chunk-RLDAYA2A.cjs → chunk-BH6PJP66.cjs} +29 -29
- package/dist/{chunk-BRXOGCH3.cjs → chunk-BIZNSF3U.cjs} +3 -3
- package/dist/{chunk-2A4XES7R.cjs → chunk-BM5MVGH3.cjs} +3 -3
- package/dist/{chunk-6YCXA7CN.js → chunk-CH5232HV.js} +20 -19
- package/dist/{chunk-UIBSSVON.cjs → chunk-D7BTSVMS.cjs} +2 -2
- package/dist/{chunk-YBGEPKC2.cjs → chunk-F7Y2ZS5U.cjs} +6 -6
- package/dist/{chunk-5V6O73EH.js → chunk-FLKJYMVB.js} +3 -3
- package/dist/{chunk-NMGX2ZTU.js → chunk-IFUQVZF4.js} +17 -17
- package/dist/{chunk-2NE3DNXY.js → chunk-IKCQK67U.js} +2 -2
- package/dist/{chunk-KFDP3DUL.cjs → chunk-IXPUM3AW.cjs} +98 -98
- package/dist/{chunk-QGTDWFT6.js → chunk-IZHZMBIX.js} +2469 -1928
- package/dist/{chunk-67CXGPTW.cjs → chunk-JKEEFQOX.cjs} +505 -72
- package/dist/{chunk-NYSYSKSH.cjs → chunk-M6HTJTFH.cjs} +15 -15
- package/dist/{chunk-OGLCD3UL.js → chunk-MFFCUVWG.js} +6 -6
- package/dist/{chunk-KJ5LWATV.js → chunk-MKXO4Q5P.js} +7 -7
- package/dist/{chunk-EMCQGFXD.cjs → chunk-MMOODW57.cjs} +28 -27
- package/dist/{chunk-Q76ZTHNV.js → chunk-MP2C3LJ4.js} +1 -1
- package/dist/{chunk-J4K5JOLI.js → chunk-MV4HYG3B.js} +25 -11
- package/dist/{chunk-2T6QWNXU.js → chunk-NDESEPW5.js} +99 -11
- package/dist/{chunk-HHFPQNP3.js → chunk-NJDHFC55.js} +15 -15
- package/dist/{chunk-HUOLB7ZN.cjs → chunk-OHFS7VOU.cjs} +9 -9
- package/dist/{chunk-7632TNE7.js → chunk-OSNIZNVH.js} +7 -7
- package/dist/{chunk-UTW4SQDI.js → chunk-OUHMD6EU.js} +10 -10
- package/dist/{chunk-MXHJROXJ.cjs → chunk-P23CRLU4.cjs} +1245 -1139
- package/dist/{chunk-64O4L7WN.js → chunk-PDWVPI3S.js} +11 -55
- package/dist/{chunk-DAW6TDZB.js → chunk-PFC2HWQA.js} +30 -16
- package/dist/{chunk-G55W76S6.js → chunk-POZ7F77D.js} +12 -13
- package/dist/{chunk-PJP5SMOU.js → chunk-PPEZGUL7.js} +500 -67
- package/dist/{chunk-SFGXIFYO.cjs → chunk-QC7Q3XCE.cjs} +24 -24
- package/dist/{chunk-MDBHZBW7.cjs → chunk-RKV5B7EU.cjs} +92 -4
- package/dist/{chunk-5VPIC5MD.cjs → chunk-SAAZEWUR.cjs} +12 -12
- package/dist/{chunk-IIMICN7L.cjs → chunk-TYWLNCNH.cjs} +4 -48
- package/dist/{chunk-HYLIQMZH.cjs → chunk-UBP5RNGK.cjs} +33 -33
- package/dist/{chunk-HUMWQMCU.js → chunk-UT4YHQZW.js} +3 -3
- package/dist/{chunk-BSEIEWM5.cjs → chunk-V3H26CNS.cjs} +28 -14
- package/dist/{chunk-NGJCWEYX.cjs → chunk-VHCACDKP.cjs} +46 -46
- package/dist/{chunk-SL2FOFT2.js → chunk-VMAZCLX4.js} +7 -7
- package/dist/{chunk-5FFNNJM7.js → chunk-VR2ZLFCP.js} +1 -1
- package/dist/{chunk-NCTYD7HL.js → chunk-VYWMEL5F.js} +14 -14
- package/dist/{chunk-HY5YL3U5.cjs → chunk-XBWE423R.cjs} +1994 -1453
- package/dist/{chunk-XCIFHW4E.cjs → chunk-XOYH2YQE.cjs} +2 -2
- package/dist/{chunk-S6V7A5FS.cjs → chunk-ZQZFIE2K.cjs} +32 -33
- package/dist/components/case-studies/index.cjs +24 -24
- package/dist/components/case-studies/index.js +10 -10
- package/dist/components/chat/chat-archive-page.d.ts +3 -3
- package/dist/components/chat/chat-archive-page.d.ts.map +1 -1
- package/dist/components/chat/chat-input.d.ts.map +1 -1
- package/dist/components/chat/chat-nav-sidebar.d.ts +4 -0
- package/dist/components/chat/chat-nav-sidebar.d.ts.map +1 -1
- package/dist/components/chat/chat-panel-header.d.ts +3 -2
- package/dist/components/chat/chat-panel-header.d.ts.map +1 -1
- package/dist/components/chat/embeddable-chat.d.ts +36 -2
- package/dist/components/chat/embeddable-chat.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +14 -6
- package/dist/components/chat/index.d.ts +4 -1
- package/dist/components/chat/index.d.ts.map +1 -1
- package/dist/components/chat/index.js +13 -5
- package/dist/components/chat/mingo-archive-list.d.ts +17 -0
- package/dist/components/chat/mingo-archive-list.d.ts.map +1 -0
- package/dist/components/chat/mingo-chat-header.d.ts +31 -0
- package/dist/components/chat/mingo-chat-header.d.ts.map +1 -0
- package/dist/components/chat/mingo-chat-rail.d.ts +54 -0
- package/dist/components/chat/mingo-chat-rail.d.ts.map +1 -0
- package/dist/components/chat/model-display.d.ts.map +1 -1
- package/dist/components/contact/contact-form.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +11 -11
- package/dist/components/contact/index.js +10 -10
- package/dist/components/content-loading-container.d.ts +1 -1
- package/dist/components/content-loading-container.d.ts.map +1 -1
- package/dist/components/docs/index.cjs +14 -14
- package/dist/components/docs/index.js +13 -13
- package/dist/components/docs/skeletons.d.ts.map +1 -1
- package/dist/components/embeds/index.cjs +11 -11
- package/dist/components/embeds/index.js +10 -10
- package/dist/components/faq/index.cjs +12 -12
- package/dist/components/faq/index.js +11 -11
- package/dist/components/features/figma-prototype-viewer.d.ts.map +1 -1
- package/dist/components/features/index.cjs +10 -10
- package/dist/components/features/index.js +9 -9
- package/dist/components/features/media-gallery-manager.d.ts.map +1 -1
- package/dist/components/features/parallax-image-showcase.d.ts.map +1 -1
- package/dist/components/features/policy-configuration-panel.d.ts.map +1 -1
- package/dist/components/features/section-selector.d.ts.map +1 -1
- package/dist/components/help-center-pages/index.cjs +119 -119
- package/dist/components/help-center-pages/index.js +39 -39
- package/dist/components/help-center-pages/trust-center-sections.d.ts +2 -2
- package/dist/components/help-center-pages/trust-center-sections.d.ts.map +1 -1
- package/dist/components/index.cjs +94 -86
- package/dist/components/index.js +32 -24
- package/dist/components/layout/article-detail-layout.d.ts +1 -1
- package/dist/components/layout/article-detail-layout.d.ts.map +1 -1
- package/dist/components/layout/page-container.d.ts.map +1 -1
- package/dist/components/layout/title-block.d.ts +2 -2
- package/dist/components/layout/title-block.d.ts.map +1 -1
- package/dist/components/loading/page-layout-skeleton.d.ts.map +1 -1
- package/dist/components/loading/unified-skeleton.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/booking-form.d.ts +4 -4
- package/dist/components/meeting-scheduler/booking-form.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/context-panel.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/index.cjs +127 -127
- package/dist/components/meeting-scheduler/index.d.ts +2 -2
- package/dist/components/meeting-scheduler/index.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/index.js +50 -50
- package/dist/components/navigation/app-header.d.ts +4 -0
- package/dist/components/navigation/app-header.d.ts.map +1 -1
- package/dist/components/navigation/app-layout-side-panel.d.ts +142 -0
- package/dist/components/navigation/app-layout-side-panel.d.ts.map +1 -0
- package/dist/components/navigation/app-layout.d.ts +11 -1
- package/dist/components/navigation/app-layout.d.ts.map +1 -1
- package/dist/components/navigation/header-mingo-button.d.ts +4 -1
- package/dist/components/navigation/header-mingo-button.d.ts.map +1 -1
- package/dist/components/navigation/index.cjs +13 -13
- package/dist/components/navigation/index.d.ts +1 -0
- package/dist/components/navigation/index.d.ts.map +1 -1
- package/dist/components/navigation/index.js +12 -12
- package/dist/components/navigation/navigation-sidebar.d.ts +8 -1
- package/dist/components/navigation/navigation-sidebar.d.ts.map +1 -1
- package/dist/components/navigation/sliding-sidebar.d.ts.map +1 -1
- package/dist/components/onboarding-guides/index.cjs +14 -14
- package/dist/components/onboarding-guides/index.js +13 -13
- package/dist/components/persistent-filter-controls.d.ts.map +1 -1
- package/dist/components/related-content/index.cjs +7 -7
- package/dist/components/related-content/index.js +6 -6
- package/dist/components/shared/detail-page-skeleton.d.ts.map +1 -1
- package/dist/components/tickets/help-center-create-form.d.ts +4 -4
- package/dist/components/tickets/index.cjs +15 -15
- package/dist/components/tickets/index.js +14 -14
- package/dist/components/ui/announcement-bar-view.d.ts.map +1 -1
- package/dist/components/ui/breadcrumb.d.ts.map +1 -1
- package/dist/components/ui/checkbox-block.d.ts.map +1 -1
- package/dist/components/ui/dashboard-info-card.d.ts +1 -1
- package/dist/components/ui/dashboard-info-card.d.ts.map +1 -1
- package/dist/components/ui/data-table/data-table-body.d.ts +2 -2
- package/dist/components/ui/data-table/data-table-skeleton.d.ts +2 -2
- package/dist/components/ui/data-table/data-table-skeleton.d.ts.map +1 -1
- package/dist/components/ui/data-table/utils.d.ts +2 -2
- package/dist/components/ui/dialog.d.ts.map +1 -1
- package/dist/components/ui/drawer.d.ts.map +1 -1
- package/dist/components/ui/entity-image.d.ts +2 -2
- package/dist/components/ui/file-manager/index.cjs +36 -36
- package/dist/components/ui/file-manager/index.js +3 -3
- package/dist/components/ui/filter-modal.d.ts.map +1 -1
- package/dist/components/ui/index.cjs +18 -10
- package/dist/components/ui/index.js +17 -9
- package/dist/components/ui/info-card-row.d.ts.map +1 -1
- package/dist/components/ui/menubar.d.ts +1 -1
- package/dist/components/ui/menubar.d.ts.map +1 -1
- package/dist/components/ui/modal-v2.d.ts.map +1 -1
- package/dist/components/ui/modal.d.ts.map +1 -1
- package/dist/components/ui/no-data/no-data-actions.d.ts.map +1 -1
- package/dist/components/ui/no-data/no-data-styles.d.ts +1 -1
- package/dist/components/ui/no-data/no-data-styles.d.ts.map +1 -1
- package/dist/components/ui/page-actions.d.ts.map +1 -1
- package/dist/components/ui/sheet.d.ts.map +1 -1
- package/dist/components/ui/table/table-skeleton.d.ts +1 -1
- package/dist/components/ui/table/table-skeleton.d.ts.map +1 -1
- package/dist/hooks/index.cjs +23 -9
- package/dist/hooks/index.js +24 -10
- package/dist/hooks/ui/index.d.ts +1 -0
- package/dist/hooks/ui/index.d.ts.map +1 -1
- package/dist/hooks/ui/use-content-breakpoint.d.ts +32 -0
- package/dist/hooks/ui/use-content-breakpoint.d.ts.map +1 -0
- package/dist/hooks/ui/use-isomorphic-layout-effect.d.ts +2 -2
- package/dist/hooks/ui/use-isomorphic-layout-effect.d.ts.map +1 -1
- package/dist/hooks/ui/use-media-query.d.ts.map +1 -1
- package/dist/index.cjs +39 -17
- package/dist/index.js +41 -19
- package/dist/styles/layout-steps.d.ts +30 -0
- package/dist/styles/layout-steps.d.ts.map +1 -0
- package/dist/tailwind.config.cjs +36 -11
- package/dist/tailwind.config.js +36 -11
- package/eslint-config/README.md +9 -0
- package/eslint-config/base.js +17 -1
- package/eslint-config/layout-variants.js +57 -0
- package/package.json +3 -1
- package/src/ODS_TOKEN_RULES.md +40 -0
- package/src/components/chat/chat-archive-page.tsx +9 -7
- package/src/components/chat/chat-input.tsx +5 -1
- package/src/components/chat/chat-nav-sidebar.tsx +10 -4
- package/src/components/chat/chat-panel-header.tsx +8 -5
- package/src/components/chat/embeddable-chat.tsx +675 -485
- package/src/components/chat/index.ts +4 -0
- package/src/components/chat/mingo-archive-list.tsx +108 -0
- package/src/components/chat/mingo-chat-header.tsx +104 -0
- package/src/components/chat/mingo-chat-rail.tsx +361 -0
- package/src/components/chat/model-display.tsx +8 -1
- package/src/components/contact/contact-form.tsx +11 -9
- package/src/components/content-loading-container.tsx +4 -2
- package/src/components/docs/doc-viewer.tsx +7 -7
- package/src/components/docs/skeletons.tsx +7 -4
- package/src/components/dynamic-skeleton.tsx +1 -1
- package/src/components/embeds/claude-embed.tsx +1 -1
- package/src/components/embeds/embed-viewer-frame.tsx +4 -4
- package/src/components/embeds/figma-embed.tsx +2 -2
- package/src/components/embeds/google-sheets-viewer.tsx +1 -1
- package/src/components/embeds/pdf-viewer.tsx +3 -3
- package/src/components/empty-state.tsx +6 -6
- package/src/components/faq/faq-section.tsx +2 -2
- package/src/components/faq-accordion.tsx +1 -1
- package/src/components/features/board/board-column-header.tsx +1 -1
- package/src/components/features/command-box.tsx +3 -3
- package/src/components/features/entity-video-section.tsx +2 -2
- package/src/components/features/figma-prototype-viewer.tsx +4 -1
- package/src/components/features/media-gallery-manager.tsx +3 -1
- package/src/components/features/parallax-image-showcase.tsx +9 -6
- package/src/components/features/policy-configuration-panel.tsx +9 -7
- package/src/components/features/provider-button.tsx +1 -1
- package/src/components/features/section-selector.tsx +11 -6
- package/src/components/features/select-button.tsx +4 -4
- package/src/components/features/seo-editor-preview.tsx +2 -2
- package/src/components/features/video-ratio-tabs.tsx +3 -3
- package/src/components/features/waitlist-form.tsx +1 -1
- package/src/components/help-center-pages/trust-center-page.tsx +1 -1
- package/src/components/help-center-pages/trust-center-sections.tsx +14 -14
- package/src/components/icon-display.tsx +1 -1
- package/src/components/layout/article-detail-layout.tsx +4 -2
- package/src/components/layout/list-page-layout.tsx +2 -2
- package/src/components/layout/page-container.tsx +26 -14
- package/src/components/layout/page-heading.tsx +1 -1
- package/src/components/layout/page-layout.tsx +1 -1
- package/src/components/layout/title-block.tsx +13 -13
- package/src/components/loading/card-skeleton.tsx +11 -11
- package/src/components/loading/category-vendor-selector-skeleton.tsx +1 -1
- package/src/components/loading/content-skeleton.tsx +6 -6
- package/src/components/loading/device-card-skeleton.tsx +1 -1
- package/src/components/loading/margin-report-skeleton.tsx +7 -7
- package/src/components/loading/msp-profile-form-skeleton.tsx +3 -3
- package/src/components/loading/organization-card-skeleton.tsx +2 -2
- package/src/components/loading/page-layout-skeleton.tsx +80 -68
- package/src/components/loading/unified-skeleton.tsx +16 -6
- package/src/components/media-carousel.tsx +3 -3
- package/src/components/meeting-scheduler/booking-form.tsx +9 -8
- package/src/components/meeting-scheduler/context-panel.tsx +8 -6
- package/src/components/meeting-scheduler/directory.tsx +4 -4
- package/src/components/meeting-scheduler/index.tsx +15 -15
- package/src/components/meeting-scheduler/slot-picker.tsx +12 -12
- package/src/components/navigation/app-header.tsx +6 -0
- package/src/components/navigation/app-layout-side-panel.tsx +594 -0
- package/src/components/navigation/app-layout.tsx +69 -4
- package/src/components/navigation/header-mingo-button.tsx +13 -3
- package/src/components/navigation/index.ts +5 -0
- package/src/components/navigation/navigation-sidebar.tsx +17 -3
- package/src/components/navigation/sliding-sidebar.tsx +2 -1
- package/src/components/pagination.tsx +3 -3
- package/src/components/persistent-filter-controls.tsx +6 -2
- package/src/components/platform/ScriptArguments.tsx +1 -1
- package/src/components/platform/ScriptInfoSection.tsx +4 -4
- package/src/components/platform/SoftwareSourceBadge.tsx +1 -1
- package/src/components/shared/article-author-byline.tsx +1 -1
- package/src/components/shared/delivery/delivery-lists.tsx +2 -2
- package/src/components/shared/delivery/delivery-row.tsx +7 -7
- package/src/components/shared/delivery/delivery-table.tsx +3 -3
- package/src/components/shared/detail-page-skeleton.tsx +11 -5
- package/src/components/shared/dev-section/dev-card-row.tsx +6 -6
- package/src/components/shared/dev-section/dev-section-view.tsx +1 -1
- package/src/components/shared/product-release/product-release-card-skeleton.tsx +8 -8
- package/src/components/shared/product-release/product-release-card.tsx +9 -9
- package/src/components/shared/product-release/product-releases-view.tsx +1 -1
- package/src/components/shared/product-release/release-detail-page.tsx +5 -5
- package/src/components/shared/roadmap/roadmap-grid-skeleton.tsx +1 -1
- package/src/components/shared/roadmap/roadmap-grid.tsx +3 -3
- package/src/components/tickets/help-center-card.tsx +1 -1
- package/src/components/tickets/help-center-create-form.tsx +12 -12
- package/src/components/ui/announcement-bar-view.tsx +2 -10
- package/src/components/ui/benefit-card.tsx +18 -18
- package/src/components/ui/brand-association-grid.tsx +4 -4
- package/src/components/ui/breadcrumb.tsx +4 -1
- package/src/components/ui/card.tsx +1 -1
- package/src/components/ui/checkbox-block.tsx +9 -7
- package/src/components/ui/content-loader.tsx +3 -3
- package/src/components/ui/cursor-pagination.tsx +3 -3
- package/src/components/ui/dashboard-info-card.tsx +13 -9
- package/src/components/ui/data-attribution.tsx +2 -2
- package/src/components/ui/data-table/data-table-body.tsx +2 -2
- package/src/components/ui/data-table/data-table-header.tsx +15 -15
- package/src/components/ui/data-table/data-table-skeleton.tsx +6 -6
- package/src/components/ui/data-table/utils.ts +5 -5
- package/src/components/ui/dialog.tsx +4 -1
- package/src/components/ui/drawer.tsx +2 -1
- package/src/components/ui/duration-input.tsx +1 -1
- package/src/components/ui/entity-image.tsx +3 -3
- package/src/components/ui/feature-card.tsx +10 -10
- package/src/components/ui/file-manager/file-manager-action-bar.tsx +1 -1
- package/src/components/ui/file-manager/file-manager.tsx +1 -1
- package/src/components/ui/filter-modal.tsx +8 -1
- package/src/components/ui/highlight-card.tsx +7 -7
- package/src/components/ui/info-card-row.tsx +10 -6
- package/src/components/ui/modal-v2.tsx +7 -2
- package/src/components/ui/modal.tsx +3 -2
- package/src/components/ui/no-data/no-data-actions.tsx +10 -4
- package/src/components/ui/no-data/no-data-styles.ts +1 -1
- package/src/components/ui/no-data/no-data.tsx +1 -1
- package/src/components/ui/organization-card.tsx +1 -1
- package/src/components/ui/page-actions.tsx +34 -5
- package/src/components/ui/progress-bar.tsx +2 -2
- package/src/components/ui/query-report-table/query-report-table.tsx +1 -1
- package/src/components/ui/search-input.tsx +2 -2
- package/src/components/ui/service-card.tsx +2 -2
- package/src/components/ui/sheet.tsx +2 -1
- package/src/components/ui/skeleton.tsx +3 -3
- package/src/components/ui/stacked-rows-panel.tsx +4 -4
- package/src/components/ui/tab-navigation.tsx +2 -2
- package/src/components/ui/tab-selector.tsx +2 -2
- package/src/components/ui/table/table-header.tsx +3 -3
- package/src/components/ui/table/table-skeleton.tsx +3 -3
- package/src/components/ui/table/utils.ts +5 -5
- package/src/components/ui/tag-search-input.tsx +3 -3
- package/src/components/ui/tags-manager.tsx +5 -5
- package/src/components/ui/test-run.tsx +2 -2
- package/src/components/ui/ticket-info-section.tsx +1 -1
- package/src/components/ui/ticket-notes-section.tsx +1 -1
- package/src/components/ui/ticket-status-config-row.tsx +15 -15
- package/src/hooks/ui/index.ts +1 -0
- package/src/hooks/ui/use-content-breakpoint.ts +58 -0
- package/src/hooks/ui/use-media-query.ts +3 -2
- package/src/styles/app-globals.css +13 -0
- package/src/styles/index.css +2 -0
- package/src/styles/layout-steps.ts +14 -0
- package/src/styles/ods-colors.css +15 -0
- package/src/styles/ods-content-area-tokens.css +27 -0
- package/src/styles/ods-content-area.css +31 -0
- package/src/styles/ods-effects.css +4 -2
- package/src/styles/ods-responsive-tokens.css +14 -4
- package/tailwind.config.ts +42 -7
|
@@ -4,6 +4,7 @@ import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
|
4
4
|
import { X } from 'lucide-react';
|
|
5
5
|
import { type ComponentPropsWithoutRef, type ElementRef, type HTMLAttributes, forwardRef } from 'react';
|
|
6
6
|
|
|
7
|
+
import { ViewportBreakpoints } from '../../hooks/ui/use-content-breakpoint';
|
|
7
8
|
import { cn } from '../../utils/cn';
|
|
8
9
|
|
|
9
10
|
const Dialog = DialogPrimitive.Root;
|
|
@@ -65,7 +66,9 @@ const DialogContent = forwardRef<
|
|
|
65
66
|
{/* min-h-0 is load-bearing: a grid item defaults to min-height:auto and
|
|
66
67
|
would refuse to shrink below its content, so the cap above would push
|
|
67
68
|
past the viewport instead of handing this box a scrollbar. */}
|
|
68
|
-
<div className="grid min-h-0 gap-[var(--spacing-system-mf)] overflow-y-auto">
|
|
69
|
+
<div className="grid min-h-0 gap-[var(--spacing-system-mf)] overflow-y-auto">
|
|
70
|
+
<ViewportBreakpoints>{children}</ViewportBreakpoints>
|
|
71
|
+
</div>
|
|
69
72
|
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
|
70
73
|
<X className="h-4 w-4" />
|
|
71
74
|
<span className="sr-only">Close</span>
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
useSyncExternalStore,
|
|
17
17
|
} from 'react';
|
|
18
18
|
|
|
19
|
+
import { ViewportBreakpoints } from '../../hooks/ui/use-content-breakpoint';
|
|
19
20
|
import { useHeaderHeight } from '../../hooks/ui/use-header-height';
|
|
20
21
|
import { type PanelDefaultSize, useResizablePanelSize } from '../../hooks/ui/use-resizable-panel-size';
|
|
21
22
|
import { cn } from '../../utils/cn';
|
|
@@ -309,7 +310,7 @@ const DrawerContent = forwardRef<ComponentRef<typeof DialogPrimitive.Content>, D
|
|
|
309
310
|
className={cn(drawerPanelVariants({ side, flush, size }), className, panelClassName)}
|
|
310
311
|
style={{ ...sizeStyle, ...panelStyle }}
|
|
311
312
|
>
|
|
312
|
-
{children}
|
|
313
|
+
<ViewportBreakpoints>{children}</ViewportBreakpoints>
|
|
313
314
|
</div>
|
|
314
315
|
</DialogPrimitive.Content>
|
|
315
316
|
</DrawerPortal>
|
|
@@ -115,7 +115,7 @@ export function DurationInput({ value, onChange, invalid, className }: DurationI
|
|
|
115
115
|
}
|
|
116
116
|
}}
|
|
117
117
|
className={cn(
|
|
118
|
-
'flex h-11 w-full items-center gap-[var(--spacing-system-xxs)] rounded-md border border-ods-border bg-ods-card px-[var(--spacing-system-sf)] transition-colors duration-200 md:h-12',
|
|
118
|
+
'flex h-11 w-full items-center gap-[var(--spacing-system-xxs)] rounded-md border border-ods-border bg-ods-card px-[var(--spacing-system-sf)] transition-colors duration-200 content-md:h-12',
|
|
119
119
|
'cursor-text focus-within:border-ods-accent',
|
|
120
120
|
invalid && 'border-ods-error focus-within:border-ods-error',
|
|
121
121
|
className,
|
|
@@ -7,7 +7,7 @@ import { cn } from '../../utils/cn';
|
|
|
7
7
|
import { personInitials } from '../../utils/format';
|
|
8
8
|
|
|
9
9
|
/** The design size, when a caller does not state one. */
|
|
10
|
-
const ENTITY_IMAGE_SIZE = 'size-[52px] md:size-[60px]';
|
|
10
|
+
const ENTITY_IMAGE_SIZE = 'size-[52px] content-md:size-[60px]';
|
|
11
11
|
|
|
12
12
|
export interface EntityImageProps {
|
|
13
13
|
src?: string | null;
|
|
@@ -18,10 +18,10 @@ export interface EntityImageProps {
|
|
|
18
18
|
* REPLACES the default size, for both the image and its initials fallback.
|
|
19
19
|
*
|
|
20
20
|
* Sizing through `className` does NOT work here and cannot be made to:
|
|
21
|
-
* the default is responsive (`size-[52px] md:size-[60px]`), and
|
|
21
|
+
* the default is responsive (`size-[52px] content-md:size-[60px]`), and
|
|
22
22
|
* tailwind-merge lets `size-*` override `w`/`h` but never the reverse — so a
|
|
23
23
|
* caller passing `h-4 w-6` dropped the base `size-[52px]` and kept
|
|
24
|
-
* `md:size-[60px]`, rendering 16px on a phone and 60px on a desktop. State
|
|
24
|
+
* `content-md:size-[60px]`, rendering 16px on a phone and 60px on a desktop. State
|
|
25
25
|
* the size here instead; it is substituted, not merged.
|
|
26
26
|
*/
|
|
27
27
|
sizeClassName?: string;
|
|
@@ -59,9 +59,9 @@ export interface FeatureCardGridProps {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
const GRID_COLUMNS = {
|
|
62
|
-
2: 'grid-cols-1 md:grid-cols-2',
|
|
63
|
-
3: 'grid-cols-1 md:grid-cols-3',
|
|
64
|
-
4: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-4',
|
|
62
|
+
2: 'grid-cols-1 content-md:grid-cols-2',
|
|
63
|
+
3: 'grid-cols-1 content-md:grid-cols-3',
|
|
64
|
+
4: 'grid-cols-1 content-md:grid-cols-2 content-lg:grid-cols-4',
|
|
65
65
|
} as const;
|
|
66
66
|
|
|
67
67
|
/**
|
|
@@ -75,10 +75,10 @@ function fourColumnBorders(index: number, count: number): string {
|
|
|
75
75
|
if (index < count - 1) classes.push('border-b');
|
|
76
76
|
const mdRows = Math.ceil(count / 2);
|
|
77
77
|
const lgRows = Math.ceil(count / 4);
|
|
78
|
-
classes.push(index % 2 === 0 && index < count - 1 ? 'md:border-r' : 'md:border-r-0');
|
|
79
|
-
classes.push(Math.floor(index / 2) < mdRows - 1 ? 'md:border-b' : 'md:border-b-0');
|
|
80
|
-
classes.push(index % 4 !== 3 && index < count - 1 ? 'lg:border-r' : 'lg:border-r-0');
|
|
81
|
-
classes.push(Math.floor(index / 4) < lgRows - 1 ? 'lg:border-b' : 'lg:border-b-0');
|
|
78
|
+
classes.push(index % 2 === 0 && index < count - 1 ? 'content-md:border-r' : 'content-md:border-r-0');
|
|
79
|
+
classes.push(Math.floor(index / 2) < mdRows - 1 ? 'content-md:border-b' : 'content-md:border-b-0');
|
|
80
|
+
classes.push(index % 4 !== 3 && index < count - 1 ? 'content-lg:border-r' : 'content-lg:border-r-0');
|
|
81
|
+
classes.push(Math.floor(index / 4) < lgRows - 1 ? 'content-lg:border-b' : 'content-lg:border-b-0');
|
|
82
82
|
return ` ${classes.join(' ')}`;
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -117,7 +117,7 @@ export function FeatureCardGrid({
|
|
|
117
117
|
if (!isLastInRow) {
|
|
118
118
|
// On mobile (1 column), never show right border
|
|
119
119
|
// On desktop (2/3 columns), show right border except for last in row
|
|
120
|
-
classes += ' md:border-r border-ods-border';
|
|
120
|
+
classes += ' content-md:border-r border-ods-border';
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
// Bottom border logic
|
|
@@ -130,10 +130,10 @@ export function FeatureCardGrid({
|
|
|
130
130
|
|
|
131
131
|
// Desktop: override mobile border, show bottom border for all rows except last
|
|
132
132
|
if (!isLastRow) {
|
|
133
|
-
classes += ' md:border-b border-ods-border';
|
|
133
|
+
classes += ' content-md:border-b border-ods-border';
|
|
134
134
|
} else {
|
|
135
135
|
// Last row on desktop - remove bottom border
|
|
136
|
-
classes += ' md:border-b-0';
|
|
136
|
+
classes += ' content-md:border-b-0';
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
return classes;
|
|
@@ -17,7 +17,7 @@ export function FileManagerActionBar({
|
|
|
17
17
|
className,
|
|
18
18
|
}: FileManagerActionBarProps) {
|
|
19
19
|
return (
|
|
20
|
-
<div className={cn('flex flex-wrap items-center gap-4 md:justify-end', className)}>
|
|
20
|
+
<div className={cn('flex flex-wrap items-center gap-4 content-md:justify-end', className)}>
|
|
21
21
|
<Button variant="outline" size="small-legacy" onClick={onNewFolder} leftIcon={<FolderPlus className="h-4 w-4" />}>
|
|
22
22
|
New Folder
|
|
23
23
|
</Button>
|
|
@@ -129,7 +129,7 @@ export function FileManager({
|
|
|
129
129
|
return (
|
|
130
130
|
<div className={cn('flex h-full flex-col bg-ods-bg', className)}>
|
|
131
131
|
<div className="flex min-h-0 flex-1 flex-col space-y-6 py-2">
|
|
132
|
-
<div className="mb-4 flex flex-col justify-between gap-4 md:flex-row">
|
|
132
|
+
<div className="mb-4 flex flex-col justify-between gap-4 content-md:flex-row">
|
|
133
133
|
<FileManagerBreadcrumb items={breadcrumbItems} onItemClick={handleBreadcrumbClick} />
|
|
134
134
|
|
|
135
135
|
{showActions && (
|
|
@@ -175,7 +175,14 @@ export function FilterModal({
|
|
|
175
175
|
const isEmpty = !isLoading && !hasSort && !hasFilterGroups && !hasTagFilter && !dateFilter;
|
|
176
176
|
|
|
177
177
|
return (
|
|
178
|
-
<ModalV2
|
|
178
|
+
<ModalV2
|
|
179
|
+
isOpen={isOpen}
|
|
180
|
+
onClose={onClose}
|
|
181
|
+
// Full width as the phone's bottom sheet. A wide window gets the medium dialog
|
|
182
|
+
// width instead: page content narrowed by a docked side panel shows the
|
|
183
|
+
// mobile filter button there too, and a window-wide sheet read as broken.
|
|
184
|
+
className={cn('max-h-[90vh] max-w-none md:max-w-[min(42rem,calc(100vw-2rem))]', className)}
|
|
185
|
+
>
|
|
179
186
|
<ModalV2Header>
|
|
180
187
|
<ModalV2Title>{title}</ModalV2Title>
|
|
181
188
|
</ModalV2Header>
|
|
@@ -18,11 +18,11 @@ export function HighlightCard({ item, className = '' }: HighlightCardProps) {
|
|
|
18
18
|
const desktopWidth = item.category.length * 14;
|
|
19
19
|
|
|
20
20
|
return (
|
|
21
|
-
<div className={`relative bg-ods-bg p-6 md:p-10 ${className}`}>
|
|
21
|
+
<div className={`relative bg-ods-bg p-6 content-md:p-10 ${className}`}>
|
|
22
22
|
<div className="relative">
|
|
23
23
|
{/* Mobile highlight */}
|
|
24
24
|
<div
|
|
25
|
-
className="absolute left-[80px] top-0 h-8 rounded-md md:hidden"
|
|
25
|
+
className="absolute left-[80px] top-0 h-8 rounded-md content-md:hidden"
|
|
26
26
|
style={{
|
|
27
27
|
backgroundColor: item.highlightBg,
|
|
28
28
|
width: `${mobileWidth}px`,
|
|
@@ -30,7 +30,7 @@ export function HighlightCard({ item, className = '' }: HighlightCardProps) {
|
|
|
30
30
|
/>
|
|
31
31
|
{/* Desktop highlight */}
|
|
32
32
|
<div
|
|
33
|
-
className="absolute left-[95px] top-0 hidden h-10 rounded-md md:block"
|
|
33
|
+
className="absolute left-[95px] top-0 hidden h-10 rounded-md content-md:block"
|
|
34
34
|
style={{
|
|
35
35
|
backgroundColor: item.highlightBg,
|
|
36
36
|
width: `${desktopWidth}px`,
|
|
@@ -57,7 +57,7 @@ export function HighlightCardGrid({
|
|
|
57
57
|
className = '',
|
|
58
58
|
cardClassName = 'bg-ods-card border border-ods-border rounded-lg p-0 overflow-hidden',
|
|
59
59
|
}: HighlightCardGridProps) {
|
|
60
|
-
const gridCols = columns === 2 ? 'grid-cols-1 md:grid-cols-2' : 'grid-cols-1 md:grid-cols-3';
|
|
60
|
+
const gridCols = columns === 2 ? 'grid-cols-1 content-md:grid-cols-2' : 'grid-cols-1 content-md:grid-cols-3';
|
|
61
61
|
const itemsPerRow = columns;
|
|
62
62
|
const rows = Math.ceil(items.length / itemsPerRow);
|
|
63
63
|
|
|
@@ -68,7 +68,7 @@ export function HighlightCardGrid({
|
|
|
68
68
|
if (!isLastInRow) {
|
|
69
69
|
// On mobile (1 column), never show right border
|
|
70
70
|
// On desktop (2/3 columns), show right border except for last in row
|
|
71
|
-
classes += ' md:border-r border-ods-border';
|
|
71
|
+
classes += ' content-md:border-r border-ods-border';
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
// Bottom border logic
|
|
@@ -81,10 +81,10 @@ export function HighlightCardGrid({
|
|
|
81
81
|
|
|
82
82
|
// Desktop: override mobile border, show bottom border for all rows except last
|
|
83
83
|
if (!isLastRow) {
|
|
84
|
-
classes += ' md:border-b border-ods-border';
|
|
84
|
+
classes += ' content-md:border-b border-ods-border';
|
|
85
85
|
} else {
|
|
86
86
|
// Last row on desktop - remove bottom border
|
|
87
|
-
classes += ' md:border-b-0';
|
|
87
|
+
classes += ' content-md:border-b-0';
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
return classes;
|
|
@@ -14,7 +14,7 @@ export interface InfoCardRowProps {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const CELL =
|
|
17
|
-
'flex items-center gap-[var(--spacing-system-s)] min-w-0 p-[var(--spacing-system-xsf)] md:p-[var(--spacing-system-m)] min-h-[60px] md:min-h-[76px]';
|
|
17
|
+
'flex items-center gap-[var(--spacing-system-s)] min-w-0 p-[var(--spacing-system-xsf)] content-md:p-[var(--spacing-system-m)] min-h-[60px] content-md:min-h-[76px]';
|
|
18
18
|
|
|
19
19
|
function StatCell({ section, className }: { section: InfoCardRowSection; className?: string }) {
|
|
20
20
|
return (
|
|
@@ -24,11 +24,13 @@ function StatCell({ section, className }: { section: InfoCardRowSection; classNa
|
|
|
24
24
|
<div className="flex min-w-0 items-center gap-[var(--spacing-system-s)]">
|
|
25
25
|
<p className="min-w-0 flex-1 truncate text-ods-text-primary text-h3">{section.caption}</p>
|
|
26
26
|
{section.icon && (
|
|
27
|
-
<div className="flex size-6 shrink-0 items-center justify-center md:hidden">{section.icon}</div>
|
|
27
|
+
<div className="flex size-6 shrink-0 items-center justify-center content-md:hidden">{section.icon}</div>
|
|
28
28
|
)}
|
|
29
29
|
</div>
|
|
30
30
|
</div>
|
|
31
|
-
{section.icon &&
|
|
31
|
+
{section.icon && (
|
|
32
|
+
<div className="hidden size-6 shrink-0 items-center justify-center content-md:flex">{section.icon}</div>
|
|
33
|
+
)}
|
|
32
34
|
</div>
|
|
33
35
|
);
|
|
34
36
|
}
|
|
@@ -37,11 +39,13 @@ export function InfoCardRow({ lead, stats, className }: InfoCardRowProps) {
|
|
|
37
39
|
return (
|
|
38
40
|
<div
|
|
39
41
|
className={cn(
|
|
40
|
-
'flex shrink-0 flex-col overflow-hidden rounded-md border border-ods-border bg-ods-card md:flex-row',
|
|
42
|
+
'flex shrink-0 flex-col overflow-hidden rounded-md border border-ods-border bg-ods-card content-md:flex-row',
|
|
41
43
|
className,
|
|
42
44
|
)}
|
|
43
45
|
>
|
|
44
|
-
<div
|
|
46
|
+
<div
|
|
47
|
+
className={cn(CELL, 'border-b border-ods-border content-md:flex-1 content-md:border-b-0 content-md:border-r')}
|
|
48
|
+
>
|
|
45
49
|
{lead.icon && (
|
|
46
50
|
<div className="flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-sm border border-ods-border [&>*]:size-full [&_img]:object-cover">
|
|
47
51
|
{lead.icon}
|
|
@@ -53,7 +57,7 @@ export function InfoCardRow({ lead, stats, className }: InfoCardRowProps) {
|
|
|
53
57
|
</div>
|
|
54
58
|
</div>
|
|
55
59
|
|
|
56
|
-
<div className="flex md:flex-1">
|
|
60
|
+
<div className="flex content-md:flex-1">
|
|
57
61
|
<StatCell section={stats[0]} className="border-r border-ods-border" />
|
|
58
62
|
<StatCell section={stats[1]} />
|
|
59
63
|
</div>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { type ReactNode, createContext, forwardRef, useContext, useRef, useEffect, useState } from 'react';
|
|
4
4
|
import { RemoveScroll } from 'react-remove-scroll';
|
|
5
|
+
import { ViewportBreakpoints } from '../../hooks/ui/use-content-breakpoint';
|
|
5
6
|
import { cn } from '../../utils/cn';
|
|
6
7
|
import { XmarkIcon } from '../icons-v2-generated';
|
|
7
8
|
|
|
@@ -235,7 +236,9 @@ const Modal = forwardRef<HTMLDivElement, ModalProps>(
|
|
|
235
236
|
mirrored there as INSET_TRANSITION_MS — it delays the app's
|
|
236
237
|
scroll-the-focused-field re-assert until this transition settles. */}
|
|
237
238
|
<div
|
|
238
|
-
|
|
239
|
+
// `ods-viewport-layer`: a modal follows the window, so a modal opened from a
|
|
240
|
+
// narrow content area takes the window's tokens, not the area's mobile ones.
|
|
241
|
+
className="ods-viewport-layer fixed inset-0 z-[1300] flex items-end justify-center transition-[padding] duration-200 md:items-center"
|
|
239
242
|
style={{ paddingBottom: 'var(--of-keyboard-inset, 0px)' }}
|
|
240
243
|
>
|
|
241
244
|
<div
|
|
@@ -303,7 +306,9 @@ const Modal = forwardRef<HTMLDivElement, ModalProps>(
|
|
|
303
306
|
role="dialog"
|
|
304
307
|
aria-modal="true"
|
|
305
308
|
>
|
|
306
|
-
<ModalContext.Provider value={{ onClose }}>
|
|
309
|
+
<ModalContext.Provider value={{ onClose }}>
|
|
310
|
+
<ViewportBreakpoints>{children}</ViewportBreakpoints>
|
|
311
|
+
</ModalContext.Provider>
|
|
307
312
|
</div>
|
|
308
313
|
</div>
|
|
309
314
|
</RemoveScroll>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { usePreventScroll } from '@react-aria/overlays';
|
|
4
4
|
import { type ReactNode, forwardRef, useEffect } from 'react';
|
|
5
|
+
import { ViewportBreakpoints } from '../../hooks/ui/use-content-breakpoint';
|
|
5
6
|
import { cn } from '../../utils/cn';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -61,7 +62,7 @@ const Modal = forwardRef<HTMLDivElement, ModalProps>(({ isOpen, onClose, childre
|
|
|
61
62
|
if (!isOpen) return null;
|
|
62
63
|
|
|
63
64
|
return (
|
|
64
|
-
<div className="fixed inset-0 z-[1300] flex items-center justify-center">
|
|
65
|
+
<div className="ods-viewport-layer fixed inset-0 z-[1300] flex items-center justify-center">
|
|
65
66
|
<div className="absolute inset-0 bg-ods-overlay" onClick={onClose} aria-hidden="true" />
|
|
66
67
|
<div
|
|
67
68
|
ref={ref}
|
|
@@ -72,7 +73,7 @@ const Modal = forwardRef<HTMLDivElement, ModalProps>(({ isOpen, onClose, childre
|
|
|
72
73
|
role="dialog"
|
|
73
74
|
aria-modal="true"
|
|
74
75
|
>
|
|
75
|
-
{children}
|
|
76
|
+
<ViewportBreakpoints>{children}</ViewportBreakpoints>
|
|
76
77
|
</div>
|
|
77
78
|
</div>
|
|
78
79
|
);
|
|
@@ -25,13 +25,15 @@ const NoDataAction = React.forwardRef<HTMLDivElement, NoDataActionProps>(functio
|
|
|
25
25
|
ref={ref}
|
|
26
26
|
className={cn(
|
|
27
27
|
'flex flex-1 items-center gap-[var(--spacing-system-s)] p-[var(--spacing-system-m)] text-ods-text-secondary',
|
|
28
|
-
'md:w-[224px] md:flex-none md:flex-col md:items-start md:gap-[var(--spacing-system-xs)]',
|
|
28
|
+
'content-md:w-[224px] content-md:flex-none content-md:flex-col content-md:items-start content-md:gap-[var(--spacing-system-xs)]',
|
|
29
29
|
className,
|
|
30
30
|
)}
|
|
31
31
|
{...props}
|
|
32
32
|
>
|
|
33
33
|
{icon && <span className={cn(noDataIconClasses, 'text-ods-text-primary')}>{icon}</span>}
|
|
34
|
-
<span className="min-w-0 flex-1 break-words text-h6 md:w-full md:flex-none">
|
|
34
|
+
<span className="min-w-0 flex-1 break-words text-h6 content-md:w-full content-md:flex-none">
|
|
35
|
+
{label ?? children}
|
|
36
|
+
</span>
|
|
35
37
|
</div>
|
|
36
38
|
);
|
|
37
39
|
});
|
|
@@ -61,7 +63,11 @@ const NoDataActions = React.forwardRef<HTMLDivElement, NoDataActionsProps>(funct
|
|
|
61
63
|
return (
|
|
62
64
|
<div
|
|
63
65
|
ref={ref}
|
|
64
|
-
className={cn(
|
|
66
|
+
className={cn(
|
|
67
|
+
noDataActionsVariants({ variant }),
|
|
68
|
+
'flex w-full flex-col content-md:w-auto content-md:flex-row',
|
|
69
|
+
className,
|
|
70
|
+
)}
|
|
65
71
|
{...props}
|
|
66
72
|
>
|
|
67
73
|
{blocks.map((block, index) => (
|
|
@@ -69,7 +75,7 @@ const NoDataActions = React.forwardRef<HTMLDivElement, NoDataActionsProps>(funct
|
|
|
69
75
|
{index > 0 && (
|
|
70
76
|
<div
|
|
71
77
|
aria-hidden="true"
|
|
72
|
-
className="shrink-0 self-stretch border-t border-ods-border md:border-l md:border-t-0"
|
|
78
|
+
className="shrink-0 self-stretch border-t border-ods-border content-md:border-l content-md:border-t-0"
|
|
73
79
|
/>
|
|
74
80
|
)}
|
|
75
81
|
{block}
|
|
@@ -7,7 +7,7 @@ import { cva, type VariantProps } from 'class-variance-authority';
|
|
|
7
7
|
// Leading-icon glyph scale: 16px on mobile, 24px on md+. Color is intentionally
|
|
8
8
|
// omitted so the glyph inherits the current text color.
|
|
9
9
|
export const noDataIconClasses =
|
|
10
|
-
'inline-flex shrink-0 items-center justify-center [&_svg]:h-4 [&_svg]:w-4 md:[&_svg]:h-6 md:[&_svg]:w-6';
|
|
10
|
+
'inline-flex shrink-0 items-center justify-center [&_svg]:h-4 [&_svg]:w-4 content-md:[&_svg]:h-6 content-md:[&_svg]:w-6';
|
|
11
11
|
|
|
12
12
|
// Surface for the info-block group container: a transparent, bordered panel with
|
|
13
13
|
// rounded corners. `overflow-hidden` keeps only the outer blocks round — inner
|
|
@@ -65,7 +65,7 @@ const NoData = React.forwardRef<HTMLDivElement, NoDataProps>(function NoDataImpl
|
|
|
65
65
|
leftIcon={buttonIcon}
|
|
66
66
|
onClick={onButtonClick}
|
|
67
67
|
{...buttonProps}
|
|
68
|
-
className={cn('w-full md:w-auto', buttonProps?.className)}
|
|
68
|
+
className={cn('w-full content-md:w-auto', buttonProps?.className)}
|
|
69
69
|
>
|
|
70
70
|
{buttonLabel}
|
|
71
71
|
</Button>
|
|
@@ -127,7 +127,7 @@ export function OrganizationCard({
|
|
|
127
127
|
customFooter
|
|
128
128
|
) : footerStats && footerStats.length > 0 ? (
|
|
129
129
|
<div className="flex w-full min-w-0 items-center justify-between gap-2">
|
|
130
|
-
<div className="flex min-w-0 flex-shrink items-center gap-3 md:gap-4">
|
|
130
|
+
<div className="flex min-w-0 flex-shrink items-center gap-3 content-md:gap-4">
|
|
131
131
|
{footerStats.map((stat, index) => (
|
|
132
132
|
<div key={index} className="flex flex-shrink-0 items-center gap-1">
|
|
133
133
|
{stat.icon}
|
|
@@ -355,7 +355,7 @@ function IconButtonsVariant({
|
|
|
355
355
|
return (
|
|
356
356
|
<>
|
|
357
357
|
{/* Desktop: every action as an icon button + optional overflow menu */}
|
|
358
|
-
<div className={cn('hidden items-center md:flex', ACTIONS_GAP, className)}>
|
|
358
|
+
<div className={cn('hidden items-center content-md:flex', ACTIONS_GAP, className)}>
|
|
359
359
|
{selector}
|
|
360
360
|
{loading ? (
|
|
361
361
|
<ActionSkeletons actions={desktopActions} />
|
|
@@ -370,7 +370,7 @@ function IconButtonsVariant({
|
|
|
370
370
|
</div>
|
|
371
371
|
|
|
372
372
|
{/* Mobile: single icon button OR all actions merged into one "..." menu */}
|
|
373
|
-
<div className={cn('flex md:hidden', className)}>
|
|
373
|
+
<div className={cn('flex content-md:hidden', className)}>
|
|
374
374
|
{loading ? (
|
|
375
375
|
<MobileTriggerSkeleton />
|
|
376
376
|
) : useSingleActionMobile && singleAction ? (
|
|
@@ -386,6 +386,12 @@ function IconButtonsVariant({
|
|
|
386
386
|
/**
|
|
387
387
|
* Primary buttons variant — primary + outline buttons on desktop,
|
|
388
388
|
* fixed bottom bar on mobile.
|
|
389
|
+
*
|
|
390
|
+
* The bottom bar spans the WINDOW, so it stays on the viewport `md` step. A
|
|
391
|
+
* content area narrowed by a docked side panel is a third case: the window is
|
|
392
|
+
* wide (no bar) but the title row has no room for every labelled button, so the
|
|
393
|
+
* actions compact into the row instead. `md:content-max-md:` is exactly that case
|
|
394
|
+
* and never matches outside a content area.
|
|
389
395
|
*/
|
|
390
396
|
function PrimaryButtonsVariant({
|
|
391
397
|
actions,
|
|
@@ -407,7 +413,7 @@ function PrimaryButtonsVariant({
|
|
|
407
413
|
|
|
408
414
|
return (
|
|
409
415
|
<>
|
|
410
|
-
<div className={cn('hidden items-center md:flex', ACTIONS_GAP, className)}>
|
|
416
|
+
<div className={cn('hidden items-center md:content-md:flex', ACTIONS_GAP, className)}>
|
|
411
417
|
{loading ? (
|
|
412
418
|
// No overflow trigger in this variant — an unknown action set settles
|
|
413
419
|
// into a labelled button, not a square one.
|
|
@@ -419,6 +425,10 @@ function PrimaryButtonsVariant({
|
|
|
419
425
|
)}
|
|
420
426
|
</div>
|
|
421
427
|
|
|
428
|
+
<div className={cn('hidden items-center md:content-max-md:flex', ACTIONS_GAP, className)}>
|
|
429
|
+
{loading ? <MobileTriggerSkeleton /> : <CompactPrimaryActions actions={desktopActions} />}
|
|
430
|
+
</div>
|
|
431
|
+
|
|
422
432
|
<MobileBottomActions actions={sortedActions} loading={loading} />
|
|
423
433
|
</>
|
|
424
434
|
);
|
|
@@ -449,7 +459,7 @@ function MenuPrimaryVariant({
|
|
|
449
459
|
|
|
450
460
|
return (
|
|
451
461
|
<>
|
|
452
|
-
<div className={cn('hidden items-center md:flex', ACTIONS_GAP, className)}>
|
|
462
|
+
<div className={cn('hidden items-center content-md:flex', ACTIONS_GAP, className)}>
|
|
453
463
|
{selector}
|
|
454
464
|
{loading ? (
|
|
455
465
|
<ActionSkeletons actions={desktopActions} />
|
|
@@ -465,7 +475,7 @@ function MenuPrimaryVariant({
|
|
|
465
475
|
)}
|
|
466
476
|
</div>
|
|
467
477
|
|
|
468
|
-
<div className={cn('flex md:hidden', className)}>
|
|
478
|
+
<div className={cn('flex content-md:hidden', className)}>
|
|
469
479
|
{loading ? (
|
|
470
480
|
<MobileTriggerSkeleton />
|
|
471
481
|
) : hasMobileMenuItems || selector ? (
|
|
@@ -479,6 +489,25 @@ function MenuPrimaryVariant({
|
|
|
479
489
|
);
|
|
480
490
|
}
|
|
481
491
|
|
|
492
|
+
/**
|
|
493
|
+
* `primary-buttons` in a narrow content area of a wide window: the accent (and
|
|
494
|
+
* icon-only) actions stay buttons, the other labelled ones fold into one "..."
|
|
495
|
+
* menu — unless that menu would hold a single action, which stays a button.
|
|
496
|
+
*/
|
|
497
|
+
function CompactPrimaryActions({ actions }: { actions: PageActionButton[] }) {
|
|
498
|
+
const foldable = actions.filter(action => action.variant !== 'accent' && !!action.label);
|
|
499
|
+
const fold = foldable.length > 1;
|
|
500
|
+
const inline = fold ? actions.filter(action => !foldable.includes(action)) : actions;
|
|
501
|
+
return (
|
|
502
|
+
<>
|
|
503
|
+
{fold && <ActionsMenuDropdown groups={[{ items: foldable.flatMap(actionToMenuItems) }]} />}
|
|
504
|
+
{inline.map((action, idx) => (
|
|
505
|
+
<React.Fragment key={`compact-${actionKey(action, idx)}`}>{renderActionButton(action)}</React.Fragment>
|
|
506
|
+
))}
|
|
507
|
+
</>
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
|
|
482
511
|
function MobileBottomActions({ actions, loading }: { actions: PageActionButton[]; loading?: boolean }) {
|
|
483
512
|
return (
|
|
484
513
|
<div
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import type React from 'react';
|
|
4
4
|
import { useEffect, useRef, useState } from 'react';
|
|
5
|
-
import {
|
|
5
|
+
import { useContentMdUp } from '../../hooks/ui/use-content-breakpoint';
|
|
6
6
|
|
|
7
7
|
type ProgressBarProps = {
|
|
8
8
|
progress: number; // 0–100
|
|
@@ -27,7 +27,7 @@ export const ProgressBar: React.FC<ProgressBarProps> = ({
|
|
|
27
27
|
mobileHeight = 8,
|
|
28
28
|
inverted = false,
|
|
29
29
|
}) => {
|
|
30
|
-
const isMdUp =
|
|
30
|
+
const isMdUp = useContentMdUp() ?? true;
|
|
31
31
|
const effectiveSegmentWidth = isMdUp ? segmentWidth : mobileSegmentWidth;
|
|
32
32
|
const effectiveHeight = isMdUp ? height : mobileHeight;
|
|
33
33
|
|
|
@@ -65,7 +65,7 @@ export function QueryReportTable({
|
|
|
65
65
|
{headerActions}
|
|
66
66
|
{showExport && data.length > 0 && (
|
|
67
67
|
<Button
|
|
68
|
-
className="bg-ods-card max-md:hidden"
|
|
68
|
+
className="bg-ods-card content-max-md:hidden"
|
|
69
69
|
variant="outline"
|
|
70
70
|
leftIcon={<Download02Icon size={18} className="text-ods-text-secondary" />}
|
|
71
71
|
onClick={handleExport}
|
|
@@ -117,7 +117,7 @@ export interface SearchInputProps {
|
|
|
117
117
|
|
|
118
118
|
const containerStyles = cn(
|
|
119
119
|
// Layout & spacing — matches lib Input component
|
|
120
|
-
'flex h-11 cursor-text items-center gap-2 rounded-[6px] border px-3 md:h-12',
|
|
120
|
+
'flex h-11 cursor-text items-center gap-2 rounded-[6px] border px-3 content-md:h-12',
|
|
121
121
|
'has-[:focus-visible]:outline-none',
|
|
122
122
|
'group',
|
|
123
123
|
'transition-colors duration-200',
|
|
@@ -456,7 +456,7 @@ export function SearchInput({
|
|
|
456
456
|
}}
|
|
457
457
|
>
|
|
458
458
|
{/* Start Adornment — pinned left, shrink-0 */}
|
|
459
|
-
<span className="flex-shrink-0 text-ods-text-secondary transition-colors duration-200 group-has-[:focus]:text-ods-accent [&_svg]:size-4 md:[&_svg]:size-6">
|
|
459
|
+
<span className="flex-shrink-0 text-ods-text-secondary transition-colors duration-200 group-has-[:focus]:text-ods-accent [&_svg]:size-4 content-md:[&_svg]:size-6">
|
|
460
460
|
{startAdornment !== undefined ? startAdornment : <SearchIcon />}
|
|
461
461
|
</span>
|
|
462
462
|
|
|
@@ -113,10 +113,10 @@ function ServiceCardRowItem({ row }: { row: ServiceCardRow }) {
|
|
|
113
113
|
|
|
114
114
|
return (
|
|
115
115
|
<div className="flex min-w-0 items-center gap-3">
|
|
116
|
-
{row.label && <div className="w-20 shrink-0 text-ods-text-primary text-h6 md:w-24">{row.label}</div>}
|
|
116
|
+
{row.label && <div className="w-20 shrink-0 text-ods-text-primary text-h6 content-md:w-24">{row.label}</div>}
|
|
117
117
|
<div
|
|
118
118
|
className={cn(
|
|
119
|
-
'flex h-12 min-w-0 flex-1 items-center justify-between rounded-md border border-ods-border bg-ods-bg px-3 md:px-4',
|
|
119
|
+
'flex h-12 min-w-0 flex-1 items-center justify-between rounded-md border border-ods-border bg-ods-bg px-3 content-md:px-4',
|
|
120
120
|
row.monospace ? 'font-mono' : '',
|
|
121
121
|
)}
|
|
122
122
|
>
|
|
@@ -5,6 +5,7 @@ import { cva, type VariantProps } from 'class-variance-authority';
|
|
|
5
5
|
import { X } from 'lucide-react';
|
|
6
6
|
import { type ComponentPropsWithoutRef, type ElementRef, type HTMLAttributes, forwardRef } from 'react';
|
|
7
7
|
|
|
8
|
+
import { ViewportBreakpoints } from '../../hooks/ui/use-content-breakpoint';
|
|
8
9
|
import { cn } from '../../utils/cn';
|
|
9
10
|
|
|
10
11
|
const Sheet = SheetPrimitive.Root;
|
|
@@ -57,7 +58,7 @@ const SheetContent = forwardRef<ElementRef<typeof SheetPrimitive.Content>, Sheet
|
|
|
57
58
|
<SheetPortal>
|
|
58
59
|
<SheetOverlay />
|
|
59
60
|
<SheetPrimitive.Content ref={ref} className={cn(sheetVariants({ side }), className)} {...props}>
|
|
60
|
-
{children}
|
|
61
|
+
<ViewportBreakpoints>{children}</ViewportBreakpoints>
|
|
61
62
|
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
|
|
62
63
|
<X className="h-4 w-4" />
|
|
63
64
|
<span className="sr-only">Close</span>
|
|
@@ -68,9 +68,9 @@ const SkeletonGrid = forwardRef<HTMLDivElement, SkeletonGridProps>(
|
|
|
68
68
|
ref={ref}
|
|
69
69
|
className={cn(
|
|
70
70
|
`grid grid-cols-1 gap-6`,
|
|
71
|
-
columns === 2 && 'md:grid-cols-2',
|
|
72
|
-
columns === 3 && 'md:grid-cols-3',
|
|
73
|
-
columns === 4 && 'md:grid-cols-4',
|
|
71
|
+
columns === 2 && 'content-md:grid-cols-2',
|
|
72
|
+
columns === 3 && 'content-md:grid-cols-3',
|
|
73
|
+
columns === 4 && 'content-md:grid-cols-4',
|
|
74
74
|
className,
|
|
75
75
|
)}
|
|
76
76
|
{...props}
|
|
@@ -83,15 +83,15 @@ const CELL_ITEMS_ALIGN: Record<PanelColumnAlign, string> = {
|
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
const HIDE_CLASS: Record<PanelHideAt, string> = {
|
|
86
|
-
md: 'hidden md:flex',
|
|
87
|
-
lg: 'hidden lg:flex',
|
|
88
|
-
xl: 'hidden xl:flex',
|
|
86
|
+
md: 'hidden content-md:flex',
|
|
87
|
+
lg: 'hidden content-lg:flex',
|
|
88
|
+
xl: 'hidden content-xl:flex',
|
|
89
89
|
};
|
|
90
90
|
|
|
91
91
|
// Base column-row class. Row height is content-driven via the min-heights, matching
|
|
92
92
|
// the joined-row pattern used across the detail layouts (56px mobile, 80px tablet+).
|
|
93
93
|
const ROW_CLASS =
|
|
94
|
-
'flex items-center gap-[var(--spacing-system-m)] px-[var(--spacing-system-m)] min-h-14 md:min-h-20 border-b border-ods-border last:border-b-0';
|
|
94
|
+
'flex items-center gap-[var(--spacing-system-m)] px-[var(--spacing-system-m)] min-h-14 content-md:min-h-20 border-b border-ods-border last:border-b-0';
|
|
95
95
|
|
|
96
96
|
function CellValue({ column }: { column: PanelColumn }) {
|
|
97
97
|
const valueNode = (
|
|
@@ -399,7 +399,7 @@ const TabBar = memo(function TabBarImpl({
|
|
|
399
399
|
<div className="relative flex items-center justify-center">
|
|
400
400
|
<tab.icon
|
|
401
401
|
className={cn(
|
|
402
|
-
'h-4 w-4 transition-colors md:h-6 md:w-6',
|
|
402
|
+
'h-4 w-4 transition-colors content-md:h-6 content-md:w-6',
|
|
403
403
|
isActive ? 'text-ods-accent' : 'text-ods-text-secondary',
|
|
404
404
|
)}
|
|
405
405
|
/>
|
|
@@ -412,7 +412,7 @@ const TabBar = memo(function TabBarImpl({
|
|
|
412
412
|
) : null}
|
|
413
413
|
|
|
414
414
|
{tab.sublabel ? (
|
|
415
|
-
<span className="flex min-w-0 flex-col items-start text-left md:flex-row md:items-baseline md:gap-[var(--spacing-system-xsf)]">
|
|
415
|
+
<span className="flex min-w-0 flex-col items-start text-left content-md:flex-row content-md:items-baseline content-md:gap-[var(--spacing-system-xsf)]">
|
|
416
416
|
<span
|
|
417
417
|
className={cn(
|
|
418
418
|
'whitespace-nowrap transition-colors text-h4',
|
|
@@ -78,7 +78,7 @@ export function TabSelector({
|
|
|
78
78
|
'flex gap-[var(--spacing-system-xxs)] bg-ods-bg p-[var(--spacing-system-xxs)]',
|
|
79
79
|
flush
|
|
80
80
|
? 'h-10 w-full'
|
|
81
|
-
: cn('h-11 rounded-md border border-ods-border md:h-12', scrollable ? 'overflow-x-auto' : 'w-full'),
|
|
81
|
+
: cn('h-11 rounded-md border border-ods-border content-md:h-12', scrollable ? 'overflow-x-auto' : 'w-full'),
|
|
82
82
|
)}
|
|
83
83
|
>
|
|
84
84
|
{items.map(item => {
|
|
@@ -112,7 +112,7 @@ export function TabSelector({
|
|
|
112
112
|
)}
|
|
113
113
|
>
|
|
114
114
|
{item.icon && (
|
|
115
|
-
<span className="flex size-4 shrink-0 items-center justify-center md:size-6">{item.icon}</span>
|
|
115
|
+
<span className="flex size-4 shrink-0 items-center justify-center content-md:size-6">{item.icon}</span>
|
|
116
116
|
)}
|
|
117
117
|
{item.label}
|
|
118
118
|
{item.badge && item.badge}
|