@12-apps/ui 6.41.1 → 6.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/components/data-display/DataGrid/DataGrid.body.js +2 -2
- package/dist/_internal/components/data-display/DataGrid/DataGrid.cells.js +1 -1
- package/dist/_internal/components/data-display/DataGrid/DataGrid.js +3 -3
- package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +6 -6
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +7 -7
- package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +4 -4
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +5 -5
- package/dist/_internal/components/data-display/FleetMap/FleetMap.fixtures.js +1 -1
- package/dist/_internal/components/data-display/Lightbox/Lightbox.js +7 -7
- package/dist/_internal/components/data-display/Lightbox/LightboxControls.js +2 -2
- package/dist/_internal/components/data-display/Lightbox/LightboxCurrentMedia.js +3 -2
- package/dist/_internal/components/data-display/Lightbox/LightboxMedia.js +2 -1
- package/dist/_internal/components/data-display/Lightbox/LightboxOverlay.js +3 -3
- package/dist/_internal/components/data-display/Lightbox/LightboxThumbnails.js +2 -1
- package/dist/_internal/components/data-display/TimingDiagram/TimingDiagram.js +2 -2
- package/dist/_internal/components/data-display/TimingDiagram/TimingDiagram.views.js +1 -1
- package/dist/_internal/components/data-display/index.js +12 -12
- package/dist/_internal/components/feedback/TutorialOverlay/TutorialOverlay.js +2 -2
- package/dist/_internal/components/feedback/TutorialOverlay/TutorialStepBody.js +1 -1
- package/dist/_internal/components/feedback/index.js +2 -2
- package/dist/_internal/components/index.js +16 -16
- package/dist/_internal/components/layout/Dashboard/Dashboard.js +2 -2
- package/dist/_internal/components/layout/Dashboard/DashboardParts.js +1 -1
- package/dist/_internal/components/layout/SettingsLayout/SettingsLayout.js +4 -4
- package/dist/_internal/components/layout/SettingsLayout/SettingsPanel.js +3 -3
- package/dist/_internal/components/layout/SettingsLayout/SettingsSectionChips.js +2 -2
- package/dist/_internal/components/layout/SettingsLayout/SettingsSectionChips.scroll.js +7 -1
- package/dist/_internal/components/layout/index.js +2 -2
- package/dist/_internal/en-US.data-display.js +3 -1
- package/dist/_internal/en-US.feedback.js +1 -1
- package/dist/_internal/pt-BR.data-display.js +3 -1
- package/dist/_internal/pt-BR.feedback.js +1 -1
- package/dist/{chunk-K4L42FF6.js → chunk-24JOJJ2J.js} +3 -3
- package/dist/chunk-24JOJJ2J.js.map +1 -0
- package/dist/{chunk-LODMNSLR.js → chunk-3GYPZ5MI.js} +4 -3
- package/dist/chunk-3GYPZ5MI.js.map +1 -0
- package/dist/{chunk-HFVYWHJT.js → chunk-AP4LSXRK.js} +2 -2
- package/dist/{chunk-MEBQKYH4.js → chunk-BX7QWHKC.js} +2 -2
- package/dist/{chunk-UFNIS7KC.js → chunk-GGBFDHXE.js} +11 -8
- package/dist/chunk-GGBFDHXE.js.map +1 -0
- package/dist/chunk-GT2RCOHM.js +184 -0
- package/dist/chunk-GT2RCOHM.js.map +1 -0
- package/dist/{chunk-2XHIF3M3.js → chunk-GXQDWHPN.js} +25 -3
- package/dist/chunk-GXQDWHPN.js.map +1 -0
- package/dist/{chunk-F7JTIHV5.js → chunk-ICDAYOJ6.js} +6 -5
- package/dist/chunk-ICDAYOJ6.js.map +1 -0
- package/dist/{chunk-ASCUWG55.js → chunk-IOCY5G43.js} +8 -3
- package/dist/chunk-IOCY5G43.js.map +1 -0
- package/dist/{chunk-RZ2VZ7SL.js → chunk-JMEPGXJG.js} +2 -2
- package/dist/{chunk-3MEIGSDK.js → chunk-LTTYUSJ2.js} +5 -2
- package/dist/chunk-LTTYUSJ2.js.map +1 -0
- package/dist/{chunk-3AQD2EA6.js → chunk-M42ZOCO7.js} +10 -9
- package/dist/chunk-M42ZOCO7.js.map +1 -0
- package/dist/{chunk-GJFAI3J5.js → chunk-OOB3YWPX.js} +17 -10
- package/dist/chunk-OOB3YWPX.js.map +1 -0
- package/dist/{chunk-TZASFX6G.js → chunk-P53KRCKW.js} +4 -4
- package/dist/{chunk-2DWBJJK6.js → chunk-RBGUS7WO.js} +2 -2
- package/dist/{chunk-ZEYUSS3W.js → chunk-SQNQQTP7.js} +4 -3
- package/dist/chunk-SQNQQTP7.js.map +1 -0
- package/dist/chunk-SV4FYSDL.js +92 -0
- package/dist/chunk-SV4FYSDL.js.map +1 -0
- package/dist/{chunk-CKHFYTIX.js → chunk-TBMGYQJF.js} +15 -5
- package/dist/chunk-TBMGYQJF.js.map +1 -0
- package/dist/{chunk-TCNTIGMY.js → chunk-TDXEO2UI.js} +2 -2
- package/dist/{chunk-ASHXIAJO.js → chunk-UGH2DDST.js} +5 -2
- package/dist/chunk-UGH2DDST.js.map +1 -0
- package/dist/{chunk-WFAJTO2B.js → chunk-UVFZQCC7.js} +5 -9
- package/dist/chunk-UVFZQCC7.js.map +1 -0
- package/dist/{chunk-U5SH3VRJ.js → chunk-V5ZLUJV7.js} +25 -3
- package/dist/chunk-V5ZLUJV7.js.map +1 -0
- package/dist/{chunk-VCBV5JM7.js → chunk-VNOXUWK7.js} +2 -2
- package/dist/{chunk-IVJKILIX.js → chunk-VZ4VAQX3.js} +2 -2
- package/dist/{chunk-5QAJ3Y5F.js → chunk-XQWUVQ2F.js} +2 -2
- package/dist/{chunk-H5ZTIELC.js → chunk-ZFXTRPQO.js} +5 -4
- package/dist/chunk-ZFXTRPQO.js.map +1 -0
- package/dist/{chunk-UT73NGRS.js → chunk-ZSTUKSTJ.js} +2 -2
- package/dist/data-display/DataGrid.js +3 -3
- package/dist/data-display/DataViews.js +7 -7
- package/dist/data-display/Lightbox.js +7 -7
- package/dist/data-display/TimingDiagram.js +2 -2
- package/dist/en-US.js +4 -2
- package/dist/feedback/TutorialOverlay.js +2 -2
- package/dist/layout/Dashboard.js +2 -2
- package/dist/layout/SettingsLayout.js +4 -4
- package/dist/locales.js +8 -4
- package/dist/locales.js.map +1 -1
- package/dist/pt-BR.js +4 -2
- package/dist/types/components/data-display/DataGrid/DataGrid.body.d.ts.map +1 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.cells.d.ts +3 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.cells.d.ts.map +1 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.d.ts +1 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.d.ts.map +1 -1
- package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts +12 -2
- package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +8 -2
- package/dist/types/components/data-display/DataViews/data-views-copy.d.ts.map +1 -1
- package/dist/types/components/data-display/DataViews/data-views-grid-bodies.d.ts.map +1 -1
- package/dist/types/components/data-display/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/types/components/data-display/Lightbox/LightboxMedia.d.ts.map +1 -1
- package/dist/types/components/data-display/Lightbox/LightboxThumbnails.d.ts.map +1 -1
- package/dist/types/components/data-display/TimingDiagram/TimingDiagram.d.ts.map +1 -1
- package/dist/types/components/data-display/TimingDiagram/TimingDiagram.views.d.ts +2 -0
- package/dist/types/components/data-display/TimingDiagram/TimingDiagram.views.d.ts.map +1 -1
- package/dist/types/components/layout/Dashboard/Dashboard.d.ts +1 -1
- package/dist/types/components/layout/Dashboard/Dashboard.types.d.ts +22 -12
- package/dist/types/components/layout/Dashboard/Dashboard.types.d.ts.map +1 -1
- package/dist/types/components/layout/Dashboard/DashboardParts.d.ts +1 -1
- package/dist/types/components/layout/Dashboard/DashboardParts.d.ts.map +1 -1
- package/dist/types/components/layout/SettingsLayout/SettingsSectionChips.d.ts.map +1 -1
- package/dist/types/components/layout/SettingsLayout/SettingsSectionChips.scroll.d.ts +20 -2
- package/dist/types/components/layout/SettingsLayout/SettingsSectionChips.scroll.d.ts.map +1 -1
- package/dist/types/copy/data-display.d.ts +40 -1
- package/dist/types/copy/data-display.d.ts.map +1 -1
- package/dist/types/copy/feedback.d.ts +7 -1
- package/dist/types/copy/feedback.d.ts.map +1 -1
- package/dist/types/en-US.data-display.d.ts +2 -1
- package/dist/types/en-US.data-display.d.ts.map +1 -1
- package/dist/types/en-US.feedback.d.ts.map +1 -1
- package/dist/types/locales.d.ts +2 -1
- package/dist/types/locales.d.ts.map +1 -1
- package/dist/types/pt-BR.data-display.d.ts +2 -1
- package/dist/types/pt-BR.data-display.d.ts.map +1 -1
- package/dist/types/pt-BR.feedback.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/data-display/DataGrid/DataGrid.body.tsx +2 -1
- package/src/components/data-display/DataGrid/DataGrid.cells.tsx +7 -4
- package/src/components/data-display/DataGrid/DataGrid.tsx +2 -1
- package/src/components/data-display/DataGrid/DataGrid.types.ts +13 -2
- package/src/components/data-display/DataViews/data-views-copy.ts +8 -2
- package/src/components/data-display/DataViews/data-views-grid-bodies.tsx +1 -0
- package/src/components/data-display/Lightbox/Lightbox.tsx +8 -2
- package/src/components/data-display/Lightbox/LightboxMedia.tsx +5 -2
- package/src/components/data-display/Lightbox/LightboxThumbnails.tsx +7 -3
- package/src/components/data-display/TimingDiagram/TimingDiagram.tsx +10 -7
- package/src/components/data-display/TimingDiagram/TimingDiagram.views.tsx +6 -2
- package/src/components/feedback/TutorialOverlay/TutorialStepBody.tsx +2 -2
- package/src/components/layout/Dashboard/Dashboard.types.ts +22 -12
- package/src/components/layout/Dashboard/DashboardParts.tsx +10 -7
- package/src/components/layout/SettingsLayout/SettingsSectionChips.scroll.ts +212 -28
- package/src/components/layout/SettingsLayout/SettingsSectionChips.tsx +24 -4
- package/src/copy/data-display.ts +41 -1
- package/src/copy/feedback.ts +7 -1
- package/src/en-US.data-display.ts +23 -0
- package/src/en-US.feedback.ts +3 -0
- package/src/locales.ts +2 -0
- package/src/pt-BR.data-display.ts +23 -0
- package/src/pt-BR.feedback.ts +3 -0
- package/dist/chunk-2XHIF3M3.js.map +0 -1
- package/dist/chunk-3AQD2EA6.js.map +0 -1
- package/dist/chunk-3MEIGSDK.js.map +0 -1
- package/dist/chunk-ASCUWG55.js.map +0 -1
- package/dist/chunk-ASHXIAJO.js.map +0 -1
- package/dist/chunk-BAFDSAWY.js +0 -86
- package/dist/chunk-BAFDSAWY.js.map +0 -1
- package/dist/chunk-CKHFYTIX.js.map +0 -1
- package/dist/chunk-F7JTIHV5.js.map +0 -1
- package/dist/chunk-GJFAI3J5.js.map +0 -1
- package/dist/chunk-H5ZTIELC.js.map +0 -1
- package/dist/chunk-K4L42FF6.js.map +0 -1
- package/dist/chunk-LODMNSLR.js.map +0 -1
- package/dist/chunk-SLJAQA2X.js +0 -82
- package/dist/chunk-SLJAQA2X.js.map +0 -1
- package/dist/chunk-U5SH3VRJ.js.map +0 -1
- package/dist/chunk-UFNIS7KC.js.map +0 -1
- package/dist/chunk-WFAJTO2B.js.map +0 -1
- package/dist/chunk-ZEYUSS3W.js.map +0 -1
- /package/dist/{chunk-HFVYWHJT.js.map → chunk-AP4LSXRK.js.map} +0 -0
- /package/dist/{chunk-MEBQKYH4.js.map → chunk-BX7QWHKC.js.map} +0 -0
- /package/dist/{chunk-RZ2VZ7SL.js.map → chunk-JMEPGXJG.js.map} +0 -0
- /package/dist/{chunk-TZASFX6G.js.map → chunk-P53KRCKW.js.map} +0 -0
- /package/dist/{chunk-2DWBJJK6.js.map → chunk-RBGUS7WO.js.map} +0 -0
- /package/dist/{chunk-TCNTIGMY.js.map → chunk-TDXEO2UI.js.map} +0 -0
- /package/dist/{chunk-VCBV5JM7.js.map → chunk-VNOXUWK7.js.map} +0 -0
- /package/dist/{chunk-IVJKILIX.js.map → chunk-VZ4VAQX3.js.map} +0 -0
- /package/dist/{chunk-5QAJ3Y5F.js.map → chunk-XQWUVQ2F.js.map} +0 -0
- /package/dist/{chunk-UT73NGRS.js.map → chunk-ZSTUKSTJ.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/feedback/TutorialOverlay/TutorialStepBody.tsx"],"sourcesContent":["import CompleteIcon from '@mui/icons-material/CheckCircle';\nimport CloseIcon from '@mui/icons-material/Close';\nimport PrevIcon from '@mui/icons-material/NavigateBefore';\nimport NextIcon from '@mui/icons-material/NavigateNext';\nimport RestartIcon from '@mui/icons-material/Refresh';\nimport Box from '@mui/material/Box/index.js';\nimport Button from '@mui/material/Button/index.js';\nimport IconButton from '@mui/material/IconButton/index.js';\nimport Stack from '@mui/material/Stack/index.js';\nimport Typography from '@mui/material/Typography/index.js';\nimport { alpha, styled } from '@mui/material/styles/index.js';\nimport React, { } from 'react';\n\nimport { onMedia, uiInk } from '../../../tokens/ink';\nimport { rem } from '../../../tokens/relative';\n\nimport type { TutorialOverlayProps } from './TutorialOverlay.types';\nimport type { TutorialCopy } from '../../../copy';\n\n// Animation keyframes\n\nconst StepIndicator = styled(Box)(({ theme }) => ({\n display: 'flex',\n gap: theme.spacing(1),\n marginTop: theme.spacing(2),\n marginBottom: theme.spacing(2) }));\n\n\nconst StepDot = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'active' && prop !== 'completed' })<{ active?: boolean; completed?: boolean }>(({ theme, active, completed }) => ({\n width: rem(theme, 8),\n height: rem(theme, 8),\n borderRadius: '50%',\n background: completed\n ? theme.palette.success.main\n : active\n ? theme.palette.primary.main\n : alpha(theme.palette.text.primary, 0.3),\n transition: 'all 0.3s ease',\n ...(active && {\n transform: 'scale(1.5)' }) }));\n\n// Title, body copy, the step dots and the navigation row.\n\n// The step's controls: skip/restart on the left, previous/next on the right.\nconst TutorialStepNav: React.FC<{\n copy: TutorialCopy;\n currentStep: number;\n stepCount: number;\n isLastStep: boolean;\n allowSkip: boolean;\n requiresActionBeforeNext?: boolean;\n onNext: () => void;\n onPrev: () => void;\n onSkip: () => void;\n onRestart: () => void;\n}> = ({\n copy,\n currentStep,\n stepCount,\n isLastStep,\n allowSkip,\n requiresActionBeforeNext,\n onNext,\n onPrev,\n onSkip,\n onRestart }) => (\n <Stack\n direction=\"row\"\n spacing={1}\n justifyContent=\"space-between\"\n data-testid=\"tutorial-navigation\"\n >\n <Stack direction=\"row\" spacing={1}>\n {allowSkip && (\n <Button size=\"small\" onClick={onSkip} variant=\"text\">\n {copy.skip}\n </Button>\n )}\n {stepCount > 1 && (\n <IconButton\n size=\"small\"\n onClick={onRestart}\n disabled={currentStep === 0}\n title={copy.restart}\n >\n <RestartIcon fontSize=\"small\" />\n </IconButton>\n )}\n </Stack>\n\n <Stack direction=\"row\" spacing={1}>\n {stepCount > 1 && currentStep > 0 && (\n <Button\n size=\"small\"\n startIcon={<PrevIcon />}\n onClick={onPrev}\n disabled={currentStep === 0}\n data-testid=\"tutorial-prev-button\"\n >\n {copy.previous}\n </Button>\n )}\n\n {!isLastStep ? (\n <Button\n variant=\"contained\"\n size=\"small\"\n endIcon={<NextIcon />}\n onClick={onNext}\n disabled={requiresActionBeforeNext}\n title={requiresActionBeforeNext ? copy.requiresAction : ''}\n data-testid=\"tutorial-next-button\"\n >\n {copy.next}\n </Button>\n ) : (\n <Button\n variant=\"contained\"\n size=\"small\"\n endIcon={<CompleteIcon />}\n onClick={onNext}\n sx={(theme) => {\n const [from, to] = uiInk(theme).celebration.mint;\n return { background: `linear-gradient(135deg, ${from} 0%, ${to} 100%)` };\n }}\n data-testid=\"tutorial-finish-button\"\n >\n {stepCount === 1 ? copy.complete : copy.finish}\n </Button>\n )}\n </Stack>\n </Stack>\n);\n\nconst StepDots: React.FC<{ currentStep: number; stepCount: number }> = ({\n currentStep,\n stepCount }) => (\n <StepIndicator data-testid=\"tutorial-step-indicators\">\n {Array.from({ length: stepCount }).map((_, index) => (\n <StepDot\n key={index}\n active={index === currentStep}\n completed={index < currentStep}\n data-testid={`tutorial-indicator-${index}`}\n />\n ))}\n </StepIndicator>\n);\n\n// Title, and the close button when skipping is allowed.\nconst TutorialStepHeader: React.FC<{\n title: React.ReactNode;\n currentStep: number;\n allowSkip: boolean;\n onSkip: () => void;\n}> = ({ title, currentStep, allowSkip, onSkip }) => (\n <Box\n sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}\n >\n <Typography\n id={`tutorial-title-${currentStep}`}\n variant=\"h6\"\n fontWeight=\"bold\"\n sx={{ flex: 1 }}\n data-testid=\"tutorial-step-title\"\n >\n {title}\n </Typography>\n {allowSkip && (\n <IconButton\n size=\"small\"\n onClick={onSkip}\n sx={{ ml: 1, mt: -1, mr: -1 }}\n data-testid=\"tutorial-close-button\"\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n )}\n </Box>\n);\n\nexport const TutorialStepBody: React.FC<{\n copy: TutorialCopy;\n step: TutorialOverlayProps['steps'][number];\n currentStep: number;\n stepCount: number;\n progress: number;\n isLastStep: boolean;\n allowSkip: boolean;\n showProgress: boolean;\n requiresActionBeforeNext?: boolean;\n onNext: () => void;\n onPrev: () => void;\n onSkip: () => void;\n onRestart: () => void;\n}> = ({\n copy,\n step,\n currentStep,\n stepCount,\n progress: _progress,\n isLastStep,\n allowSkip,\n showProgress,\n requiresActionBeforeNext,\n onNext,\n onPrev,\n onSkip,\n onRestart }) => (\n <Stack spacing={2}>\n <TutorialStepHeader\n title={step.title}\n currentStep={currentStep}\n allowSkip={allowSkip}\n onSkip={onSkip}\n />\n\n <Typography\n id={`tutorial-content-${currentStep}`}\n variant=\"body2\"\n color=\"text.secondary\"\n data-testid=\"tutorial-step-content\"\n >\n {step.content}\n </Typography>\n\n {showProgress && (\n <Typography variant=\"caption\" color=\"text.secondary\" align=\"center\">\n {currentStep + 1} of {stepCount}\n </Typography>\n )}\n\n {step.action && (\n <Button\n variant=\"contained\"\n size=\"small\"\n onClick={step.action.onClick}\n sx={(theme) => {\n const [from, to] = uiInk(theme).celebration.violet;\n return { background: `linear-gradient(135deg, ${from} 0%, ${to} 100%)`, color: onMedia(theme) };\n }}\n >\n {step.action.label}\n </Button>\n )}\n\n <StepDots currentStep={currentStep} stepCount={stepCount} />\n\n <TutorialStepNav\n copy={copy}\n currentStep={currentStep}\n stepCount={stepCount}\n isLastStep={isLastStep}\n allowSkip={allowSkip}\n requiresActionBeforeNext={requiresActionBeforeNext}\n onNext={onNext}\n onPrev={onPrev}\n onSkip={onSkip}\n onRestart={onRestart}\n />\n </Stack>\n);\n\n// Main component\n"],"mappings":"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","names":[]}
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "./chunk-KHG57NAE.js";
|
|
26
26
|
import {
|
|
27
27
|
DataGrid
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-SQNQQTP7.js";
|
|
29
29
|
import {
|
|
30
30
|
default as default2
|
|
31
31
|
} from "./chunk-6DPAWXZ3.js";
|
|
@@ -79,7 +79,8 @@ function GridBody({
|
|
|
79
79
|
expansion: toGridExpansion(rowDetail, copy),
|
|
80
80
|
"data-testid": dataTestId,
|
|
81
81
|
emptyState,
|
|
82
|
-
emptyText: copy.grid.emptyFilteredTitle
|
|
82
|
+
emptyText: copy.grid.emptyFilteredTitle,
|
|
83
|
+
copy: copy.grid
|
|
83
84
|
}
|
|
84
85
|
)
|
|
85
86
|
}
|
|
@@ -273,4 +274,4 @@ function GridMain(props) {
|
|
|
273
274
|
export {
|
|
274
275
|
GridMain
|
|
275
276
|
};
|
|
276
|
-
//# sourceMappingURL=chunk-
|
|
277
|
+
//# sourceMappingURL=chunk-3GYPZ5MI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataViews/data-views-grid-bodies.tsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\n\nimport { DataGrid, type GridColumn, type GridSort } from \"../DataGrid\";\nimport { Box } from \"../../../mui/Box\";\n\nimport {\n cardTargetWidthFor,\n cardScaleForZoom,\n DENSITY_BOARD_SCALE,\n DENSITY_ROW_PADDING,\n useDataViewsLayout,\n type DataViewsDensity,\n} from \"./data-views-layout-context\";\nimport { cardGridTracks } from \"./data-views-grid-helpers\";\nimport { DataViewsBoard, type BoardConfig } from \"./DataViewsBoard\";\nimport { SelectAllStrip } from \"./data-views-select-all-strip\";\nimport { ListCardGroup, type ListGroupConfig } from \"./list-card-rails\";\nimport type { DataViewCardSelection } from \"./data-views-types\";\nimport { toGridExpansion, type DataViewRowDetail } from \"./data-views-row-detail\";\nimport type { DataViewsController } from \"./use-data-views-state\";\nimport { useDataViewsCopy } from \"./data-views-copy-context\";\nimport { sxRem } from \"../../../tokens/relative\";\n\n/* ── Body (grid) ─────────────────────────────────────────────────────────── */\n\ninterface GridBodyProps<T extends Record<string, unknown>> {\n rows: T[];\n columns: GridColumn<T>[];\n getRowId: (row: T) => string | number;\n selectedIds: Array<string | number>;\n onChangeSelected: (ids: Array<string | number>) => void;\n sortBy: GridSort[];\n onChangeSortBy: (next: GridSort[]) => void;\n /** \"server\" defers ordering to the backend (rows render as-is); \"client\" sorts in-grid. */\n sortMode: \"client\" | \"server\";\n /** Vertical cell padding, from the density preference. */\n rowPadding: number;\n rowDetail?: DataViewRowDetail<T>;\n dataTestId?: string;\n emptyState?: React.ReactNode;\n}\n\n/** The dense DataGrid with multi-select, wrapped in the scrollable table region. */\nfunction GridBody<T extends Record<string, unknown>>({\n rows,\n columns,\n getRowId,\n selectedIds,\n onChangeSelected,\n sortBy,\n onChangeSortBy,\n sortMode,\n rowPadding,\n rowDetail,\n dataTestId,\n emptyState,\n}: GridBodyProps<T>): React.JSX.Element {\n const copy = useDataViewsCopy();\n return (\n <Box\n sx={{\n width: \"100%\",\n overflowX: \"auto\",\n mt: 1.5,\n // Tabwoah-style dense rows: MUI's default TableCell padding keeps rows\n // tall regardless of rowHeight, so the DENSITY preference is applied\n // here rather than through `rowHeight`, which it would fight.\n \"& .MuiTableCell-root\": { py: rowPadding, fontSize: sxRem(13) },\n \"& .MuiTableCell-head\": { py: 0.5, fontSize: sxRem(12) },\n }}\n >\n <DataGrid<T>\n rows={rows}\n columns={columns}\n getRowId={(row) => getRowId(row)}\n virtualizeRows={false}\n density=\"compact\"\n rowHeight={36}\n headerHeight={36}\n selection={{ mode: \"multi\", selectedRowIds: selectedIds, onChangeSelected }}\n sorting={{ mode: sortMode, sortBy, onChangeSortBy }}\n expansion={toGridExpansion(rowDetail, copy)}\n data-testid={dataTestId}\n emptyState={emptyState}\n emptyText={copy.grid.emptyFilteredTitle}\n copy={copy.grid}\n />\n </Box>\n );\n}\n\n/* ── Body (cards) ────────────────────────────────────────────────────────── */\n\ninterface CardBodyProps<T extends Record<string, unknown>> {\n rows: T[];\n renderCard: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n getRowId: (row: T) => string | number;\n selectedIds: Set<string | number>;\n onToggleId: (id: string | number) => void;\n /** The width each card asks for; `auto-fill` turns it into a column count. */\n targetCardWidth: number;\n /** Content scale (padding + type) handed to each card, from the zoom slider. */\n cardScale: number;\n dataTestId?: string;\n emptyState?: React.ReactNode;\n}\n\n/**\n * The \"Grade\" layout: the filtered/sorted rows rendered as an auto-filling grid\n * of entity-supplied cards. Reuses `rows` (= `c.matched`), so search/filter/sort\n * apply; the column width comes from the zoom slider, and each card is handed its\n * selection state so it can drive its own checkbox (BaseCard) — the same\n * selection model as the table.\n */\nfunction CardBody<T extends Record<string, unknown>>({\n rows,\n renderCard,\n getRowId,\n selectedIds,\n onToggleId,\n targetCardWidth,\n cardScale,\n dataTestId,\n emptyState,\n}: CardBodyProps<T>): React.JSX.Element {\n if (rows.length === 0) {\n return <Box sx={{ mt: 1.5 }}>{emptyState}</Box>;\n }\n return (\n <Box\n sx={{\n mt: 1.5,\n display: \"grid\",\n // Fixed inter-card gap — deliberately NOT scaled by the zoom slider, so\n // only the cards grow while the space between them stays constant.\n gap: 1.5,\n ...cardGridTracks(targetCardWidth),\n }}\n data-testid={dataTestId ? `${dataTestId}-cards` : \"data-views-cards\"}\n >\n {rows.map((row) => {\n const id = getRowId(row);\n return (\n <Box key={id}>\n {renderCard(row, {\n selected: selectedIds.has(id),\n onToggleSelect: () => onToggleId(id),\n scale: cardScale,\n })}\n </Box>\n );\n })}\n </Box>\n );\n}\n\n/* ── Body (list) ─────────────────────────────────────────────────────────── */\n\ninterface ListBodyProps<T extends Record<string, unknown>> {\n rows: T[];\n renderListRow: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n getRowId: (row: T) => string | number;\n selectedIds: Set<string | number>;\n onToggleId: (id: string | number) => void;\n /** Gap between rows, from the density preference. */\n rowGap: number;\n /** The list's shared column config. See {@link ListGroupConfig}. */\n group?: ListGroupConfig<T>;\n /** The density every row answers, handed to the group when there is one. */\n density: DataViewsDensity;\n dataTestId?: string;\n emptyState?: React.ReactNode;\n}\n\n/**\n * The \"Lista\" layout: one FULL-WIDTH row per record, rendered by the entity — a\n * marker, a title, a subtitle and a value on the right is the shape it was\n * designed for (FUT-733).\n *\n * It sits between the table and the cards rather than replacing either: the\n * table is for comparing many columns, the cards are for browsing, and the list\n * is for scanning a queue on a narrow screen. Selection is the SAME model as\n * both — each row receives its selection state, so it can drive its own\n * checkbox and the bulk menu behaves identically in every layout.\n *\n * `scale` is handed over as 1 rather than the zoom multiplier, and the zoom\n * slider is hidden in this layout: a full-width row has no card size to\n * multiply. See {@link DataViewsZoomSlider}.\n */\nfunction ListBody<T extends Record<string, unknown>>({\n rows,\n renderListRow,\n getRowId,\n selectedIds,\n onToggleId,\n rowGap,\n group,\n density,\n dataTestId,\n emptyState,\n}: ListBodyProps<T>): React.JSX.Element {\n if (rows.length === 0) {\n return <Box sx={{ mt: 1.5 }}>{emptyState}</Box>;\n }\n const testId = dataTestId ? `${dataTestId}-list` : \"data-views-list\";\n const selectionFor = (id: string | number): DataViewCardSelection => ({\n selected: selectedIds.has(id),\n onToggleSelect: () => onToggleId(id),\n scale: 1,\n });\n\n if (group) {\n return (\n <Box sx={{ mt: 1.5 }}>\n <ListCardGroup\n cells={group.cells}\n metaColumns={group.metaColumns}\n rails={group.rails}\n reserveGutters={group.reserveGutters}\n density={density}\n gap={rowGap}\n dataTestId={testId}\n >\n {rows.map((row) => {\n const id = getRowId(row);\n // A FRAGMENT, NOT A BOX. The row is subgrid over the group's tracks\n // (`gridColumn: span railCount`), which only resolves while the card\n // is a DIRECT child of the group's grid. One wrapper element and the\n // span is measured against a grid that isn't there, so every rail\n // collapses — the exact failure the group exists to prevent.\n return (\n <React.Fragment key={id}>\n {renderListRow(row, selectionFor(id))}\n </React.Fragment>\n );\n })}\n </ListCardGroup>\n </Box>\n );\n }\n\n return (\n <Box\n sx={{ mt: 1.5, display: \"flex\", flexDirection: \"column\", gap: rowGap }}\n data-testid={testId}\n >\n {rows.map((row) => {\n const id = getRowId(row);\n return <Box key={id}>{renderListRow(row, selectionFor(id))}</Box>;\n })}\n </Box>\n );\n}\n\n/* ── Body selector (board vs list vs cards vs table, from context) ───────── */\n\ninterface GridMainProps<T extends Record<string, unknown>> {\n c: DataViewsController<T>;\n getRowId: (row: T) => string | number;\n renderCard?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /** Opt-in \"Lista\" layout — one full-width row per record. */\n renderListRow?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /** The Lista's shared columns. Omitted, each row resolves its own tracks. */\n listGroup?: ListGroupConfig<T>;\n /** Opt-in \"Quadro\" (board) layout — needs `renderCard`, since it reuses the card. */\n board?: BoardConfig<T>;\n /** Opt-in expandable rows — the TABLE only; the headerless layouts ignore it. */\n rowDetail?: DataViewRowDetail<T>;\n dataTestId?: string;\n emptyState?: React.ReactNode;\n testIdPrefix: string;\n}\n\n/**\n * The headerless layouts, each preceded by its own select-all.\n *\n * The strip is rendered HERE rather than inside each body so all three agree on\n * where it sits and what it says — and so the table, which already has one in\n * its `<thead>`, never gets a second.\n */\nfunction Headerless<T extends Record<string, unknown>>({\n c,\n getRowId,\n testIdPrefix,\n children,\n}: {\n c: DataViewsController<T>;\n getRowId: (row: T) => string | number;\n testIdPrefix: string;\n children: React.ReactNode;\n}): React.JSX.Element {\n return (\n <>\n <SelectAllStrip\n rows={c.matched}\n getRowId={getRowId}\n selectedIds={c.selectedIds}\n onChange={(next) => c.setSelectedIds(next)}\n testIdPrefix={testIdPrefix}\n />\n {children}\n </>\n );\n}\n\n/**\n * The body for one of the three HEADERLESS layouts, or `null` for the table.\n *\n * Split out from {@link GridMain} so the select-all strip is wrapped around the\n * result exactly once instead of being repeated identically in every branch —\n * which is also what keeps either function inside the line budget.\n */\nfunction headerlessBody<T extends Record<string, unknown>>(\n { c, getRowId, renderCard, renderListRow, listGroup, board, dataTestId, emptyState }: GridMainProps<T>,\n { layout, zoom, density }: ReturnType<typeof useDataViewsLayout>,\n): React.ReactNode | null {\n if (layout === \"list\" && renderListRow) {\n return (\n <ListBody\n rows={c.matched}\n renderListRow={renderListRow}\n getRowId={getRowId}\n selectedIds={c.selectedIds}\n onToggleId={c.toggleId}\n rowGap={DENSITY_ROW_PADDING[density]}\n group={listGroup}\n density={density}\n dataTestId={dataTestId}\n emptyState={emptyState}\n />\n );\n }\n if (layout === \"board\" && board && renderCard) {\n return (\n <DataViewsBoard\n rows={c.matched}\n board={board}\n getRowId={getRowId}\n renderCard={renderCard}\n selectedIds={c.selectedIds}\n onToggleId={c.toggleId}\n // DENSITY, not zoom: the board's own knob in the Exibição tab is how\n // wide its columns are, and it is the only sizing control the board\n // has since the zoom slider was removed.\n cardScale={DENSITY_BOARD_SCALE[density]}\n dataTestId={dataTestId}\n />\n );\n }\n if (layout === \"cards\" && renderCard) {\n return (\n <CardBody\n rows={c.matched}\n renderCard={renderCard}\n getRowId={getRowId}\n selectedIds={c.selectedIds}\n onToggleId={c.toggleId}\n targetCardWidth={cardTargetWidthFor(zoom, density)}\n cardScale={cardScaleForZoom(zoom)}\n dataTestId={dataTestId}\n emptyState={emptyState}\n />\n );\n }\n return null;\n}\n\n/** Picks the body from the layout context: board, list, cards, or the dense grid. */\nexport function GridMain<T extends Record<string, unknown>>(props: GridMainProps<T>): React.JSX.Element {\n const { c, getRowId, dataTestId, emptyState, testIdPrefix } = props;\n const layoutState = useDataViewsLayout();\n const body = headerlessBody(props, layoutState);\n if (body) {\n return (\n <Headerless c={c} getRowId={getRowId} testIdPrefix={testIdPrefix}>\n {body}\n </Headerless>\n );\n }\n return (\n <GridBody\n rows={c.matched}\n columns={c.gridColumns}\n getRowId={getRowId}\n selectedIds={[...c.selectedIds]}\n onChangeSelected={(ids) => c.setSelectedIds(new Set(ids))}\n sortBy={c.state.sortBy}\n onChangeSortBy={(next: GridSort[]) => c.patch({ sortBy: next })}\n sortMode={c.serverMode ? \"server\" : \"client\"}\n rowPadding={DENSITY_ROW_PADDING[layoutState.density]}\n rowDetail={props.rowDetail}\n dataTestId={dataTestId}\n emptyState={emptyState}\n />\n );\n}\n\n"],"mappings":"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","names":["default"]}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "./chunk-KW3H5FUS.js";
|
|
14
14
|
import {
|
|
15
15
|
GridMain
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-3GYPZ5MI.js";
|
|
17
17
|
import {
|
|
18
18
|
DataViewsPagination
|
|
19
19
|
} from "./chunk-BA6Z52QN.js";
|
|
@@ -238,4 +238,4 @@ function GridShell(props) {
|
|
|
238
238
|
export {
|
|
239
239
|
GridShell
|
|
240
240
|
};
|
|
241
|
-
//# sourceMappingURL=chunk-
|
|
241
|
+
//# sourceMappingURL=chunk-AP4LSXRK.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DataViewsGrid
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZSTUKSTJ.js";
|
|
4
4
|
import {
|
|
5
5
|
DeleteViewDialog
|
|
6
6
|
} from "./chunk-DH5UJD2I.js";
|
|
@@ -178,4 +178,4 @@ function renderViewDialogs(ctl, fields, columns, views, testIdPrefix, onSaved) {
|
|
|
178
178
|
export {
|
|
179
179
|
DataViewsTableBase
|
|
180
180
|
};
|
|
181
|
-
//# sourceMappingURL=chunk-
|
|
181
|
+
//# sourceMappingURL=chunk-BX7QWHKC.js.map
|
|
@@ -34,9 +34,9 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
34
34
|
var DashboardSpacer = () => /* @__PURE__ */ jsx(Box, { sx: { flex: 1 }, "aria-hidden": true });
|
|
35
35
|
DashboardSpacer.displayName = "Dashboard.Spacer";
|
|
36
36
|
var DashboardInfo = ({
|
|
37
|
-
title
|
|
37
|
+
title,
|
|
38
38
|
children,
|
|
39
|
-
ariaLabel
|
|
39
|
+
ariaLabel
|
|
40
40
|
}) => {
|
|
41
41
|
const { testIdPrefix } = useDashboardContext();
|
|
42
42
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
@@ -75,9 +75,12 @@ var DashboardInfo = ({
|
|
|
75
75
|
] });
|
|
76
76
|
};
|
|
77
77
|
DashboardInfo.displayName = "Dashboard.Info";
|
|
78
|
-
var DashboardFilterToggle = ({
|
|
78
|
+
var DashboardFilterToggle = ({
|
|
79
|
+
hideLabel,
|
|
80
|
+
showLabel
|
|
81
|
+
}) => {
|
|
79
82
|
const { filtersVisible, toggleFilters, activeFilterCount, testIdPrefix } = useDashboardContext();
|
|
80
|
-
const label =
|
|
83
|
+
const label = filtersVisible ? hideLabel : showLabel;
|
|
81
84
|
return /* @__PURE__ */ jsx(Tooltip, { title: label, children: /* @__PURE__ */ jsx(
|
|
82
85
|
IconButton,
|
|
83
86
|
{
|
|
@@ -93,10 +96,10 @@ var DashboardFilterToggle = ({ ariaLabel }) => {
|
|
|
93
96
|
};
|
|
94
97
|
DashboardFilterToggle.displayName = "Dashboard.FilterToggle";
|
|
95
98
|
var DashboardSettings = ({
|
|
96
|
-
title
|
|
99
|
+
title,
|
|
97
100
|
closeLabel,
|
|
98
101
|
children,
|
|
99
|
-
ariaLabel
|
|
102
|
+
ariaLabel,
|
|
100
103
|
href,
|
|
101
104
|
linkComponent
|
|
102
105
|
}) => {
|
|
@@ -148,7 +151,7 @@ var DEFAULT_EXPORT_FORMATS = [
|
|
|
148
151
|
var DashboardExport = ({
|
|
149
152
|
formats = DEFAULT_EXPORT_FORMATS,
|
|
150
153
|
onExport,
|
|
151
|
-
label
|
|
154
|
+
label
|
|
152
155
|
}) => {
|
|
153
156
|
const { testIdPrefix } = useDashboardContext();
|
|
154
157
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
@@ -212,4 +215,4 @@ export {
|
|
|
212
215
|
DashboardAction,
|
|
213
216
|
DashboardActions
|
|
214
217
|
};
|
|
215
|
-
//# sourceMappingURL=chunk-
|
|
218
|
+
//# sourceMappingURL=chunk-GGBFDHXE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/layout/Dashboard/DashboardParts.tsx"],"sourcesContent":["'use client';\n\nimport CloseIcon from '@mui/icons-material/Close';\nimport ExpandMoreIcon from '@mui/icons-material/ExpandMore';\nimport ExportIcon from '@mui/icons-material/FileDownloadOutlined';\nimport FilterIcon from '@mui/icons-material/FilterListRounded';\nimport InfoIcon from '@mui/icons-material/InfoOutlined';\nimport SettingsIcon from '@mui/icons-material/SettingsOutlined';\nimport Badge from '@mui/material/Badge/index.js';\nimport Box from '@mui/material/Box/index.js';\nimport Dialog from '@mui/material/Dialog/index.js';\nimport DialogContent from '@mui/material/DialogContent/index.js';\nimport DialogTitle from '@mui/material/DialogTitle/index.js';\nimport IconButton from '@mui/material/IconButton/index.js';\nimport Menu from '@mui/material/Menu/index.js';\nimport MenuItem from '@mui/material/MenuItem/index.js';\nimport Popover from '@mui/material/Popover/index.js';\nimport Tooltip from '@mui/material/Tooltip/index.js';\nimport Typography from '@mui/material/Typography/index.js';\nimport React, { useState } from 'react';\n\nimport { HeaderActions } from '../../form/HeaderActions';\nimport { HeaderButton } from '../../form/HeaderButton';\nimport { useDashboardContext } from './DashboardContext';\nimport type {\n DashboardActionProps,\n DashboardActionsProps,\n DashboardExportFormat,\n DashboardExportProps,\n DashboardFilterToggleProps,\n DashboardInfoProps,\n DashboardSettingsProps,\n} from './Dashboard.types';\nimport { sxRem } from '../../../tokens/relative';\n\n/** Flexible spacer — everything composed after it is pushed to the right. */\nexport const DashboardSpacer = (): React.JSX.Element => <Box sx={{ flex: 1 }} aria-hidden />;\nDashboardSpacer.displayName = 'Dashboard.Spacer';\n\nexport const DashboardInfo = ({\n title,\n children,\n ariaLabel,\n}: DashboardInfoProps): React.JSX.Element => {\n const { testIdPrefix } = useDashboardContext();\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);\n const open = Boolean(anchorEl);\n return (\n <>\n <Tooltip title={ariaLabel}>\n <IconButton\n size=\"small\"\n aria-label={ariaLabel}\n aria-haspopup=\"dialog\"\n onClick={(e) => setAnchorEl(e.currentTarget)}\n data-testid={`${testIdPrefix}-info-trigger`}\n sx={{ color: 'text.secondary' }}\n >\n <InfoIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n <Popover\n open={open}\n anchorEl={anchorEl}\n onClose={() => setAnchorEl(null)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n slotProps={{ paper: { sx: { width: sxRem(360), maxWidth: '90vw' } } }}\n data-testid={`${testIdPrefix}-info-popover`}\n >\n <Box sx={{ px: 2, py: 1.5, borderBottom: 1, borderColor: 'divider', display: 'flex', gap: 1, alignItems: 'center' }}>\n <InfoIcon fontSize=\"small\" sx={{ color: 'text.secondary' }} />\n <Typography sx={{ fontWeight: 600 }}>{title}</Typography>\n </Box>\n <Box sx={{ px: 2, py: 1.5, fontSize: sxRem(14), color: 'text.secondary' }}>{children}</Box>\n </Popover>\n </>\n );\n};\nDashboardInfo.displayName = 'Dashboard.Info';\n\nexport const DashboardFilterToggle = ({\n hideLabel,\n showLabel,\n}: DashboardFilterToggleProps): React.JSX.Element => {\n const { filtersVisible, toggleFilters, activeFilterCount, testIdPrefix } = useDashboardContext();\n const label = filtersVisible ? hideLabel : showLabel;\n return (\n <Tooltip title={label}>\n <IconButton\n size=\"small\"\n aria-label={label}\n aria-pressed={filtersVisible}\n onClick={toggleFilters}\n data-testid={`${testIdPrefix}-filter-toggle`}\n sx={{ color: filtersVisible ? 'primary.main' : 'text.secondary', bgcolor: filtersVisible ? 'action.selected' : 'transparent' }}\n >\n <Badge badgeContent={activeFilterCount} color=\"primary\" overlap=\"circular\">\n <FilterIcon fontSize=\"small\" />\n </Badge>\n </IconButton>\n </Tooltip>\n );\n};\nDashboardFilterToggle.displayName = 'Dashboard.FilterToggle';\n\nexport const DashboardSettings = ({\n title,\n closeLabel,\n children,\n ariaLabel,\n href,\n linkComponent,\n}: DashboardSettingsProps): React.JSX.Element => {\n const { testIdPrefix } = useDashboardContext();\n const [open, setOpen] = useState(false);\n\n // Link mode: the gear navigates to a settings route (e.g. the page's\n // Configuração section) instead of opening an in-page dialog.\n if (href) {\n const LinkComponent = linkComponent ?? 'a';\n return (\n <Tooltip title={ariaLabel}>\n <IconButton\n size=\"small\"\n aria-label={ariaLabel}\n component={LinkComponent}\n href={href}\n data-testid={`${testIdPrefix}-settings-trigger`}\n sx={{ color: 'text.secondary' }}\n >\n <SettingsIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n );\n }\n\n return (\n <>\n <Tooltip title={ariaLabel}>\n <IconButton\n size=\"small\"\n aria-label={ariaLabel}\n aria-haspopup=\"dialog\"\n onClick={() => setOpen(true)}\n data-testid={`${testIdPrefix}-settings-trigger`}\n sx={{ color: 'text.secondary' }}\n >\n <SettingsIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n <Dialog open={open} onClose={() => setOpen(false)} maxWidth=\"sm\" fullWidth data-testid={`${testIdPrefix}-settings-dialog`}>\n <DialogTitle sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n {title}\n <IconButton aria-label={closeLabel} size=\"small\" onClick={() => setOpen(false)}>\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n </DialogTitle>\n <DialogContent dividers>{children}</DialogContent>\n </Dialog>\n </>\n );\n};\nDashboardSettings.displayName = 'Dashboard.Settings';\n\nconst DEFAULT_EXPORT_FORMATS: DashboardExportFormat[] = [\n { id: 'csv', label: 'CSV (.csv)' },\n { id: 'xlsx', label: 'Excel (.xlsx)' },\n { id: 'json', label: 'JSON (.json)' },\n];\n\nexport const DashboardExport = ({\n formats = DEFAULT_EXPORT_FORMATS,\n onExport,\n label,\n}: DashboardExportProps): React.JSX.Element => {\n const { testIdPrefix } = useDashboardContext();\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const open = Boolean(anchorEl);\n return (\n <>\n <HeaderButton\n variant=\"outlined\"\n color=\"inherit\"\n text={label}\n icon={<ExportIcon fontSize=\"small\" />}\n endIcon={<ExpandMoreIcon fontSize=\"small\" />}\n onClick={(e) => setAnchorEl(e.currentTarget)}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n dataTestId={`${testIdPrefix}-export-trigger`}\n />\n <Menu anchorEl={anchorEl} open={open} onClose={() => setAnchorEl(null)} data-testid={`${testIdPrefix}-export-menu`}>\n {formats.map((format) => (\n <MenuItem\n key={format.id}\n onClick={() => {\n onExport(format.id);\n setAnchorEl(null);\n }}\n data-testid={`${testIdPrefix}-export-${format.id}`}\n >\n {format.label}\n </MenuItem>\n ))}\n </Menu>\n </>\n );\n};\nDashboardExport.displayName = 'Dashboard.Export';\n\nexport const DashboardAction = ({ children }: DashboardActionProps): React.JSX.Element => (\n <Box sx={{ display: 'inline-flex' }}>{children}</Box>\n);\nDashboardAction.displayName = 'Dashboard.Action';\n\n/**\n * The header's actions, declared as a LIST — `<Dashboard.Action>`'s plural.\n *\n * `<Dashboard.Action>` is a slot: it renders whatever you hand it, once per\n * action, and a page with five of them draws five equally-loud buttons. That is\n * the right primitive for one button and the wrong one for five, and the pages\n * here that grew a fifth action all grew it the same way — by adding a fifth\n * slot, because the slot was the only thing on offer.\n *\n * This part answers the question the slot cannot: given N actions, how many\n * belong on the bar? See {@link HeaderActions} for the rule (0 ⇒ nothing,\n * 1 ⇒ a button, n ⇒ a button and a menu of the rest).\n *\n * Both stay. A header still composes `<Dashboard.Action>` for the one control\n * that is not an action at all — a link, a toggle, a status pill — and reaches\n * for this when it has actions to rank.\n */\nexport const DashboardActions = ({\n actions,\n moreLabel,\n collapseBelow,\n}: DashboardActionsProps): React.JSX.Element => {\n const { testIdPrefix } = useDashboardContext();\n return (\n <HeaderActions\n actions={actions}\n moreLabel={moreLabel}\n collapseBelow={collapseBelow}\n testIdPrefix={`${testIdPrefix}-actions`}\n />\n );\n};\nDashboardActions.displayName = 'Dashboard.Actions';\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// src/components/layout/SettingsLayout/SettingsSectionChips.scroll.ts
|
|
2
|
+
var LANDED_SLACK = 1;
|
|
3
|
+
var QUIET_BEFORE_SETTLED_MS = 250;
|
|
4
|
+
var SCROLL_DELTA_EPSILON = 2;
|
|
5
|
+
var POINTER_MOVE_EPSILON = 2;
|
|
6
|
+
function horizontalDelta(event) {
|
|
7
|
+
if (!(event instanceof WheelEvent)) return 0;
|
|
8
|
+
return event.deltaX !== 0 ? event.deltaX : event.shiftKey ? event.deltaY : 0;
|
|
9
|
+
}
|
|
10
|
+
var cachedRtlScrollType;
|
|
11
|
+
function detectRtlScrollType(doc) {
|
|
12
|
+
if (cachedRtlScrollType) return cachedRtlScrollType;
|
|
13
|
+
const probe = doc.createElement("div");
|
|
14
|
+
const inner = doc.createElement("div");
|
|
15
|
+
inner.style.width = "10px";
|
|
16
|
+
probe.appendChild(inner);
|
|
17
|
+
probe.dir = "rtl";
|
|
18
|
+
probe.style.width = "4px";
|
|
19
|
+
probe.style.position = "absolute";
|
|
20
|
+
probe.style.top = "-1000px";
|
|
21
|
+
probe.style.overflow = "scroll";
|
|
22
|
+
doc.body.appendChild(probe);
|
|
23
|
+
let type = "reverse";
|
|
24
|
+
if (probe.scrollLeft > 0) {
|
|
25
|
+
type = "default";
|
|
26
|
+
} else {
|
|
27
|
+
probe.scrollLeft = 1;
|
|
28
|
+
if (probe.scrollLeft === 0) type = "negative";
|
|
29
|
+
}
|
|
30
|
+
doc.body.removeChild(probe);
|
|
31
|
+
cachedRtlScrollType = type;
|
|
32
|
+
return type;
|
|
33
|
+
}
|
|
34
|
+
function isRtlStrip(strip) {
|
|
35
|
+
const view = strip.ownerDocument.defaultView;
|
|
36
|
+
const getComputedStyle = view?.getComputedStyle ?? globalThis.getComputedStyle;
|
|
37
|
+
return getComputedStyle(strip).direction === "rtl";
|
|
38
|
+
}
|
|
39
|
+
function physicalScrollLeft(strip) {
|
|
40
|
+
const raw = strip.scrollLeft;
|
|
41
|
+
if (!isRtlStrip(strip)) return raw;
|
|
42
|
+
const max = strip.scrollWidth - strip.clientWidth;
|
|
43
|
+
const type = detectRtlScrollType(strip.ownerDocument);
|
|
44
|
+
if (type === "negative") return raw + max;
|
|
45
|
+
if (type === "reverse") return max - raw;
|
|
46
|
+
return raw;
|
|
47
|
+
}
|
|
48
|
+
function toRawScrollLeft(strip, physical) {
|
|
49
|
+
if (!isRtlStrip(strip)) return physical;
|
|
50
|
+
const max = strip.scrollWidth - strip.clientWidth;
|
|
51
|
+
const type = detectRtlScrollType(strip.ownerDocument);
|
|
52
|
+
if (type === "negative") return physical - max;
|
|
53
|
+
if (type === "reverse") return max - physical;
|
|
54
|
+
return physical;
|
|
55
|
+
}
|
|
56
|
+
function restsOnAim(strip, aimed) {
|
|
57
|
+
const reachable = Math.min(aimed, strip.scrollWidth - strip.clientWidth);
|
|
58
|
+
return Math.abs(physicalScrollLeft(strip) - reachable) <= LANDED_SLACK;
|
|
59
|
+
}
|
|
60
|
+
function createGestureListeners(state) {
|
|
61
|
+
const onPointerDown = (event) => {
|
|
62
|
+
state.pointer = true;
|
|
63
|
+
state.pointerMoved = false;
|
|
64
|
+
state.pointerDownAt = event instanceof MouseEvent ? event.clientX : Number.NaN;
|
|
65
|
+
};
|
|
66
|
+
const onPointerMove = (event) => {
|
|
67
|
+
if (!(event instanceof MouseEvent) || Number.isNaN(state.pointerDownAt)) return;
|
|
68
|
+
if (Math.abs(event.clientX - state.pointerDownAt) > POINTER_MOVE_EPSILON) state.pointerMoved = true;
|
|
69
|
+
};
|
|
70
|
+
const onPointerUp = () => {
|
|
71
|
+
state.pointer = false;
|
|
72
|
+
state.pointerDownAt = Number.NaN;
|
|
73
|
+
};
|
|
74
|
+
const onTouchStart = (event) => {
|
|
75
|
+
state.touch = true;
|
|
76
|
+
state.touchMoved = false;
|
|
77
|
+
state.touchDownAt = event instanceof TouchEvent ? event.touches[0]?.clientX ?? Number.NaN : Number.NaN;
|
|
78
|
+
};
|
|
79
|
+
const onTouchMove = (event) => {
|
|
80
|
+
if (!(event instanceof TouchEvent) || Number.isNaN(state.touchDownAt)) return;
|
|
81
|
+
const clientX = event.touches[0]?.clientX;
|
|
82
|
+
if (clientX !== void 0 && Math.abs(clientX - state.touchDownAt) > POINTER_MOVE_EPSILON) {
|
|
83
|
+
state.touchMoved = true;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const onTouchEnd = () => {
|
|
87
|
+
state.touch = false;
|
|
88
|
+
state.touchDownAt = Number.NaN;
|
|
89
|
+
};
|
|
90
|
+
const onPointerCancel = () => {
|
|
91
|
+
state.nudged = true;
|
|
92
|
+
onPointerUp();
|
|
93
|
+
};
|
|
94
|
+
const onKeydown = () => {
|
|
95
|
+
state.nudged = true;
|
|
96
|
+
};
|
|
97
|
+
const onWheel = (event) => {
|
|
98
|
+
if (horizontalDelta(event) !== 0) state.nudged = true;
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
onStrip: [
|
|
102
|
+
["pointerdown", onPointerDown],
|
|
103
|
+
["pointermove", onPointerMove],
|
|
104
|
+
["touchstart", onTouchStart],
|
|
105
|
+
["touchmove", onTouchMove],
|
|
106
|
+
["pointercancel", onPointerCancel],
|
|
107
|
+
["keydown", onKeydown],
|
|
108
|
+
["wheel", onWheel]
|
|
109
|
+
],
|
|
110
|
+
// A gesture can END off the strip, so its end is heard on the window.
|
|
111
|
+
onView: [
|
|
112
|
+
["pointerup", onPointerUp],
|
|
113
|
+
["pointercancel", onPointerUp],
|
|
114
|
+
["touchend", onTouchEnd],
|
|
115
|
+
["touchcancel", onTouchEnd]
|
|
116
|
+
]
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function watchVisitorScroll(strip) {
|
|
120
|
+
const view = strip.ownerDocument.defaultView;
|
|
121
|
+
const hasScrollEnd = "onscrollend" in strip;
|
|
122
|
+
const state = {
|
|
123
|
+
pointer: false,
|
|
124
|
+
touch: false,
|
|
125
|
+
nudged: false,
|
|
126
|
+
undecided: false,
|
|
127
|
+
scrolled: false,
|
|
128
|
+
aimed: Number.NaN,
|
|
129
|
+
quiet: void 0,
|
|
130
|
+
settled: () => void 0,
|
|
131
|
+
lastScrollLeft: physicalScrollLeft(strip),
|
|
132
|
+
pointerDownAt: Number.NaN,
|
|
133
|
+
pointerMoved: false,
|
|
134
|
+
touchDownAt: Number.NaN,
|
|
135
|
+
touchMoved: false
|
|
136
|
+
};
|
|
137
|
+
const settle = () => {
|
|
138
|
+
if (!state.undecided) return;
|
|
139
|
+
state.undecided = false;
|
|
140
|
+
state.nudged = false;
|
|
141
|
+
if (!restsOnAim(strip, state.aimed)) state.scrolled = true;
|
|
142
|
+
state.settled();
|
|
143
|
+
};
|
|
144
|
+
const onScroll = () => {
|
|
145
|
+
const now = physicalScrollLeft(strip);
|
|
146
|
+
const movedFarEnough = Math.abs(now - state.lastScrollLeft) > SCROLL_DELTA_EPSILON;
|
|
147
|
+
state.lastScrollLeft = now;
|
|
148
|
+
const pointerDrag = state.pointer && state.pointerMoved && movedFarEnough;
|
|
149
|
+
const touchDrag = state.touch && state.touchMoved && movedFarEnough;
|
|
150
|
+
if (pointerDrag || touchDrag || state.nudged) state.undecided = true;
|
|
151
|
+
if (!state.undecided || hasScrollEnd) return;
|
|
152
|
+
clearTimeout(state.quiet);
|
|
153
|
+
state.quiet = setTimeout(settle, QUIET_BEFORE_SETTLED_MS);
|
|
154
|
+
};
|
|
155
|
+
const gestures = createGestureListeners(state);
|
|
156
|
+
const onStrip = [...gestures.onStrip, ["scroll", onScroll], ["scrollend", settle]];
|
|
157
|
+
const onView = gestures.onView;
|
|
158
|
+
for (const [type, listener] of onStrip) strip.addEventListener(type, listener, { passive: true });
|
|
159
|
+
for (const [type, listener] of onView) view?.addEventListener(type, listener, { passive: true });
|
|
160
|
+
return {
|
|
161
|
+
hasScrolled: () => state.scrolled,
|
|
162
|
+
isUndecided: () => state.undecided,
|
|
163
|
+
aimedAt: () => state.aimed,
|
|
164
|
+
beforeOwnScroll: (left) => {
|
|
165
|
+
state.aimed = left;
|
|
166
|
+
},
|
|
167
|
+
onSettled: (listener) => {
|
|
168
|
+
state.settled = listener;
|
|
169
|
+
},
|
|
170
|
+
detach: () => {
|
|
171
|
+
clearTimeout(state.quiet);
|
|
172
|
+
for (const [type, listener] of onStrip) strip.removeEventListener(type, listener);
|
|
173
|
+
for (const [type, listener] of onView) view?.removeEventListener(type, listener);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export {
|
|
179
|
+
isRtlStrip,
|
|
180
|
+
physicalScrollLeft,
|
|
181
|
+
toRawScrollLeft,
|
|
182
|
+
watchVisitorScroll
|
|
183
|
+
};
|
|
184
|
+
//# sourceMappingURL=chunk-GT2RCOHM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/layout/SettingsLayout/SettingsSectionChips.scroll.ts"],"sourcesContent":["/**\n * Telling the strip's own scrolls from the visitor's (FUT-2606).\n *\n * Split from `SettingsSectionChips.tsx` so the chips stay a component file and\n * the rule for \"who moved the strip\" can be read in one place.\n */\n\n/**\n * How near to where the strip aimed itself it has to come to rest for the scroll\n * to count as the strip's own. A smooth scroll lands on a device pixel, and the\n * target it was given is fractional.\n */\nconst LANDED_SLACK = 1;\n\n/**\n * Where `scrollend` is missing: how long the strip has to go without a `scroll`\n * before it counts as settled. Generous on purpose — a busy main thread can go\n * several frames between ticks of a smooth scroll, and judging one mid-flight\n * would read the strip's own animation as the visitor's. Too long only delays a\n * re-centre; too short can latch the strip for good.\n */\nconst QUIET_BEFORE_SETTLED_MS = 250;\n\n/**\n * How much `scrollLeft` has to move, tick to tick, before a `scroll` event is\n * even a CANDIDATE for arming (FUT-2775). Below this, a browser's own rounding\n * or a repeated event carrying no real motion cannot arm anything by itself.\n *\n * This alone does not stop the false latch the ticket describes: the strip's\n * own `scrollTo` produces real per-tick deltas well past this line, same as a\n * drag would. It only rules out a scroll event that moved nothing.\n */\nconst SCROLL_DELTA_EPSILON = 2;\n\n/**\n * How far a pointer or touch has to travel from where it went down before it\n * counts as having MOVED, rather than merely resting (FUT-2775). Below this,\n * an held-still finger's sub-pixel tremor does not count as a drag.\n */\nconst POINTER_MOVE_EPSILON = 2;\n\ninterface VisitorScrollWatch {\n /** True once the visitor has moved the strip themselves. */\n hasScrolled: () => boolean;\n /**\n * True while a scroll the visitor MAY be making has not come to rest yet. The\n * strip must not scroll itself under it: that would yank a drag in progress.\n */\n isUndecided: () => boolean;\n /**\n * Where the strip last aimed itself, PHYSICAL pixels (see {@link physicalScrollLeft}) —\n * direction-blind, like every other geometry read in this file. `NaN` before it has.\n */\n aimedAt: () => number;\n /**\n * The strip is about to scroll itself to `left` (physical pixels). Records the\n * aim and NOTHING\n * else: it used to disarm too, and a re-centre landing between a visitor's key\n * press (or wheel, or pan) and the first tick of the scroll it causes wiped\n * the arming — their scroll went unclaimed, read as the strip's own. Left\n * armed, the worst a stale arming does is put the strip's OWN next scroll\n * under judgement, which rests on its aim, is not latched, and disarms.\n */\n beforeOwnScroll: (left: number) => void;\n /** Called once an undecided scroll has come to rest and been judged. */\n onSettled: (listener: () => void) => void;\n detach: () => void;\n}\n\ntype Listeners = Array<[string, (event: Event) => void]>;\n\n/** A wheel's sideways travel: `deltaX`, or `deltaY` with Shift held, as browsers read it. */\nfunction horizontalDelta(event: Event): number {\n if (!(event instanceof WheelEvent)) return 0;\n return event.deltaX !== 0 ? event.deltaX : event.shiftKey ? event.deltaY : 0;\n}\n\ninterface WatchState {\n pointer: boolean;\n touch: boolean;\n nudged: boolean;\n undecided: boolean;\n scrolled: boolean;\n aimed: number;\n quiet: ReturnType<typeof setTimeout> | undefined;\n settled: () => void;\n /** `scrollLeft` as of the last `scroll` tick, updated every tick regardless of arming. */\n lastScrollLeft: number;\n /** Where a `pointerdown` on the strip landed, in viewport `clientX`. `NaN` while up. */\n pointerDownAt: number;\n /** True once that pointer has travelled past {@link POINTER_MOVE_EPSILON} from `pointerDownAt`. */\n pointerMoved: boolean;\n /** Same pair, for `touchstart`/`touchmove` — a distinct event stream on some engines. */\n touchDownAt: number;\n touchMoved: boolean;\n}\n\ntype RtlScrollType = 'default' | 'negative' | 'reverse';\n\nlet cachedRtlScrollType: RtlScrollType | undefined;\n\n/**\n * Which of the three incompatible conventions this engine reports an RTL\n * scroller's `scrollLeft` in, probed once and cached (FUT-2775).\n *\n * Per the CSSOM View spec, an RTL scroller's `scrollLeft` is `0` at its\n * (right-hand) start and goes NEGATIVE toward the end — `'negative'` below,\n * what every current evergreen engine implements. Older WebKit mirrored that\n * (`'reverse'`: `0` at the start, growing toward `+max`), and older\n * Chromium/Safari ignored `dir` altogether and kept the plain left-to-right\n * numbering (`'default'`). A hidden probe, not a version sniff, tells them\n * apart — the same technique `@mui/utils`'s `detectScrollType` uses for\n * `Tabs`; reimplemented here rather than taking a new dependency for one\n * probe.\n */\nfunction detectRtlScrollType(doc: Document): RtlScrollType {\n if (cachedRtlScrollType) return cachedRtlScrollType;\n // The exact pixel values below are the probe's mechanism, not a design size:\n // what matters is only that the INNER box is wider than the OUTER one, so the\n // outer one has something to scroll — same technique `@mui/utils` uses,\n // detached and off-screen either way.\n const probe = doc.createElement('div');\n const inner = doc.createElement('div');\n inner.style.width = '10px';\n probe.appendChild(inner);\n probe.dir = 'rtl';\n probe.style.width = '4px';\n probe.style.position = 'absolute';\n probe.style.top = '-1000px';\n probe.style.overflow = 'scroll';\n doc.body.appendChild(probe);\n let type: RtlScrollType = 'reverse';\n if (probe.scrollLeft > 0) {\n type = 'default';\n } else {\n probe.scrollLeft = 1;\n if (probe.scrollLeft === 0) type = 'negative';\n }\n doc.body.removeChild(probe);\n cachedRtlScrollType = type;\n return type;\n}\n\n/** True when the strip's own computed direction is right-to-left. */\nexport function isRtlStrip(strip: HTMLElement): boolean {\n const view = strip.ownerDocument.defaultView;\n const getComputedStyle = view?.getComputedStyle ?? globalThis.getComputedStyle;\n return getComputedStyle(strip).direction === 'rtl';\n}\n\n/**\n * `strip.scrollLeft`, renumbered so `0` is always the strip's physical LEFT\n * edge and larger is always further physically right — whatever `direction`\n * and whatever convention this engine uses to report it raw (FUT-2775).\n *\n * Every geometry read in this file (`getBoundingClientRect`) is already in\n * that same physical, direction-blind coordinate space, so this is what makes\n * `scrollLeft` combinable with it at all.\n */\nexport function physicalScrollLeft(strip: HTMLElement): number {\n const raw = strip.scrollLeft;\n if (!isRtlStrip(strip)) return raw;\n const max = strip.scrollWidth - strip.clientWidth;\n const type = detectRtlScrollType(strip.ownerDocument);\n if (type === 'negative') return raw + max;\n if (type === 'reverse') return max - raw;\n return raw;\n}\n\n/** The inverse of {@link physicalScrollLeft}: a physical offset back to this engine's raw `scrollLeft`. */\nexport function toRawScrollLeft(strip: HTMLElement, physical: number): number {\n if (!isRtlStrip(strip)) return physical;\n const max = strip.scrollWidth - strip.clientWidth;\n const type = detectRtlScrollType(strip.ownerDocument);\n if (type === 'negative') return physical - max;\n if (type === 'reverse') return max - physical;\n return physical;\n}\n\n/** Whether the strip came to rest where it last aimed itself — clamped as the browser would. */\nfunction restsOnAim(strip: HTMLElement, aimed: number): boolean {\n const reachable = Math.min(aimed, strip.scrollWidth - strip.clientWidth);\n // Written so that `NaN` — the strip never aimed — reads as \"not on aim\".\n return Math.abs(physicalScrollLeft(strip) - reachable) <= LANDED_SLACK;\n}\n\n/** The pointer/touch/keydown/wheel listeners that arm `state`, split out of `watchVisitorScroll` (line budget). */\nfunction createGestureListeners(state: WatchState): { onStrip: Listeners; onView: Listeners } {\n // `MouseEvent`, not `PointerEvent`: a real `PointerEvent` IS one (it extends\n // `MouseEvent`), so this reads `clientX` off it just the same in a browser —\n // but jsdom (this file's own test environment) has never implemented\n // `PointerEvent` at all, and the bare identifier throws a `ReferenceError`\n // the moment anything evaluates `instanceof PointerEvent`, pointer event or\n // not. Same reasoning as feature-checking `scrollTo` elsewhere in this file:\n // nothing in here is worth a crash over which constructor a probe prefers.\n const onPointerDown = (event: Event): void => {\n state.pointer = true;\n state.pointerMoved = false;\n state.pointerDownAt = event instanceof MouseEvent ? event.clientX : Number.NaN;\n };\n const onPointerMove = (event: Event): void => {\n if (!(event instanceof MouseEvent) || Number.isNaN(state.pointerDownAt)) return;\n if (Math.abs(event.clientX - state.pointerDownAt) > POINTER_MOVE_EPSILON) state.pointerMoved = true;\n };\n const onPointerUp = (): void => {\n state.pointer = false;\n state.pointerDownAt = Number.NaN;\n };\n const onTouchStart = (event: Event): void => {\n state.touch = true;\n state.touchMoved = false;\n state.touchDownAt = event instanceof TouchEvent ? (event.touches[0]?.clientX ?? Number.NaN) : Number.NaN;\n };\n const onTouchMove = (event: Event): void => {\n if (!(event instanceof TouchEvent) || Number.isNaN(state.touchDownAt)) return;\n const clientX = event.touches[0]?.clientX;\n if (clientX !== undefined && Math.abs(clientX - state.touchDownAt) > POINTER_MOVE_EPSILON) {\n state.touchMoved = true;\n }\n };\n const onTouchEnd = (): void => {\n state.touch = false;\n state.touchDownAt = Number.NaN;\n };\n const onPointerCancel = (): void => {\n state.nudged = true;\n onPointerUp();\n };\n const onKeydown = (): void => {\n state.nudged = true;\n };\n const onWheel = (event: Event): void => {\n if (horizontalDelta(event) !== 0) state.nudged = true;\n };\n return {\n onStrip: [\n ['pointerdown', onPointerDown],\n ['pointermove', onPointerMove],\n ['touchstart', onTouchStart],\n ['touchmove', onTouchMove],\n ['pointercancel', onPointerCancel],\n ['keydown', onKeydown],\n ['wheel', onWheel],\n ],\n // A gesture can END off the strip, so its end is heard on the window.\n onView: [\n ['pointerup', onPointerUp],\n ['pointercancel', onPointerUp],\n ['touchend', onTouchEnd],\n ['touchcancel', onTouchEnd],\n ],\n };\n}\n\n/**\n * Tell a scroll the VISITOR made from every other one.\n *\n * The `scroll` event cannot say: the strip's own `scrollTo` fires it, and so does\n * the browser clamping a strip whose content shrank. So a scroll is only a\n * CANDIDATE when it arrives during something only a visitor does:\n *\n * - a finger held on the strip (`touchstart` until `touchend`) — a drag;\n * - a pointer held on it (`pointerdown` until `pointerup`);\n * - a key press, a SIDEWAYS wheel, or the browser taking a pointer over to pan\n * it (`pointercancel`), each armed until the next scroll under judgement has\n * been judged — whoever's it turns out to be.\n *\n * and the verdict waits until the strip comes to REST (`scrollend`, or a quiet\n * spell where the browser has no `scrollend`): it is the visitor's only if the\n * strip rests somewhere other than where it last aimed itself.\n *\n * Judged at rest rather than per `scroll` because the strip's own smooth scroll\n * fires `scroll` for a third of a second, and a visitor who presses Tab or puts\n * a finger on a chip to scroll the PAGE in that window is not scrolling the\n * strip. Every tick of that animation used to count as theirs, the strip stopped\n * re-centring for good, and the open chip could be left clipped (FUT-2606\n * again, by another door). A visitor who really drags or wheels the strip\n * mid-animation cancels it, so the strip rests where THEY left it — and that\n * still counts. The one loss: a visitor who happens to leave it within a pixel\n * of the strip's own aim is not told apart from it, and the strip there is\n * already where it would have put itself.\n *\n * A tap is a pointer held with no scroll under it, so it never counts. A\n * vertical wheel scrolls the PAGE — the strip is `overflowY: hidden` — and is\n * not armed at all.\n */\nexport function watchVisitorScroll(strip: HTMLElement): VisitorScrollWatch {\n const view = strip.ownerDocument.defaultView;\n const hasScrollEnd = 'onscrollend' in strip;\n const state: WatchState = {\n pointer: false,\n touch: false,\n nudged: false,\n undecided: false,\n scrolled: false,\n aimed: Number.NaN,\n quiet: undefined,\n settled: () => undefined,\n lastScrollLeft: physicalScrollLeft(strip),\n pointerDownAt: Number.NaN,\n pointerMoved: false,\n touchDownAt: Number.NaN,\n touchMoved: false,\n };\n const settle = (): void => {\n // Only a scroll that was UNDER JUDGEMENT disarms. Chromium can end the\n // strip's own smooth scroll with a `scrollend` when another scroll cuts it\n // off, fired BEFORE that scroll's first `scroll` (seen with an instant one);\n // disarming there would hand the visitor's scroll to nobody.\n if (!state.undecided) return;\n state.undecided = false;\n state.nudged = false;\n if (!restsOnAim(strip, state.aimed)) state.scrolled = true;\n state.settled();\n };\n const onScroll = (): void => {\n const now = physicalScrollLeft(strip);\n const movedFarEnough = Math.abs(now - state.lastScrollLeft) > SCROLL_DELTA_EPSILON;\n state.lastScrollLeft = now;\n // Pointer/touch need BOTH signals (FUT-2775): the pointer/finger must have\n // itself MOVED since going down, AND this tick's delta must be real. Either\n // alone still latches on the other's shape — a pointer merely resting on\n // the strip while its OWN `scrollTo` produces real per-tick deltas would\n // arm under a delta-only check (`pointerMoved`/`touchMoved` rules that out);\n // a pointer that drifts a sub-epsilon amount while resting would arm under\n // a moved-only check with no delta floor (`movedFarEnough` rules that out).\n const pointerDrag = state.pointer && state.pointerMoved && movedFarEnough;\n const touchDrag = state.touch && state.touchMoved && movedFarEnough;\n // `nudged` (a keypress, a sideways wheel, the browser taking the pointer\n // over to pan) is already a discrete, one-shot gesture with no \"resting\n // pointer coincides with an unrelated animation\" shape to rule out — unlike\n // pointer/touch, requiring a delta on the SAME tick that arms it would only\n // race the strip's own scroll ending before a qualifying tick arrives (seen:\n // it broke the existing \"keeps a wheel/drag scroll\" stories against a real\n // browser's `scrollend` timing). So it arms as it always has.\n if (pointerDrag || touchDrag || state.nudged) state.undecided = true;\n if (!state.undecided || hasScrollEnd) return;\n // Every tick while undecided, armed or not: a quiet spell that began while\n // the strip was still moving would judge it mid-flight, away from its aim.\n clearTimeout(state.quiet);\n state.quiet = setTimeout(settle, QUIET_BEFORE_SETTLED_MS);\n };\n const gestures = createGestureListeners(state);\n const onStrip: Listeners = [...gestures.onStrip, ['scroll', onScroll], ['scrollend', settle]];\n const onView = gestures.onView;\n for (const [type, listener] of onStrip) strip.addEventListener(type, listener, { passive: true });\n for (const [type, listener] of onView) view?.addEventListener(type, listener, { passive: true });\n return {\n hasScrolled: () => state.scrolled,\n isUndecided: () => state.undecided,\n aimedAt: () => state.aimed,\n beforeOwnScroll: (left) => {\n state.aimed = left;\n },\n onSettled: (listener) => {\n state.settled = listener;\n },\n detach: () => {\n clearTimeout(state.quiet);\n for (const [type, listener] of onStrip) strip.removeEventListener(type, listener);\n for (const [type, listener] of onView) view?.removeEventListener(type, listener);\n },\n };\n}\n"],"mappings":";AAYA,IAAM,eAAe;AASrB,IAAM,0BAA0B;AAWhC,IAAM,uBAAuB;AAO7B,IAAM,uBAAuB;AAiC7B,SAAS,gBAAgB,OAAsB;AAC7C,MAAI,EAAE,iBAAiB,YAAa,QAAO;AAC3C,SAAO,MAAM,WAAW,IAAI,MAAM,SAAS,MAAM,WAAW,MAAM,SAAS;AAC7E;AAwBA,IAAI;AAgBJ,SAAS,oBAAoB,KAA8B;AACzD,MAAI,oBAAqB,QAAO;AAKhC,QAAM,QAAQ,IAAI,cAAc,KAAK;AACrC,QAAM,QAAQ,IAAI,cAAc,KAAK;AACrC,QAAM,MAAM,QAAQ;AACpB,QAAM,YAAY,KAAK;AACvB,QAAM,MAAM;AACZ,QAAM,MAAM,QAAQ;AACpB,QAAM,MAAM,WAAW;AACvB,QAAM,MAAM,MAAM;AAClB,QAAM,MAAM,WAAW;AACvB,MAAI,KAAK,YAAY,KAAK;AAC1B,MAAI,OAAsB;AAC1B,MAAI,MAAM,aAAa,GAAG;AACxB,WAAO;AAAA,EACT,OAAO;AACL,UAAM,aAAa;AACnB,QAAI,MAAM,eAAe,EAAG,QAAO;AAAA,EACrC;AACA,MAAI,KAAK,YAAY,KAAK;AAC1B,wBAAsB;AACtB,SAAO;AACT;AAGO,SAAS,WAAW,OAA6B;AACtD,QAAM,OAAO,MAAM,cAAc;AACjC,QAAM,mBAAmB,MAAM,oBAAoB,WAAW;AAC9D,SAAO,iBAAiB,KAAK,EAAE,cAAc;AAC/C;AAWO,SAAS,mBAAmB,OAA4B;AAC7D,QAAM,MAAM,MAAM;AAClB,MAAI,CAAC,WAAW,KAAK,EAAG,QAAO;AAC/B,QAAM,MAAM,MAAM,cAAc,MAAM;AACtC,QAAM,OAAO,oBAAoB,MAAM,aAAa;AACpD,MAAI,SAAS,WAAY,QAAO,MAAM;AACtC,MAAI,SAAS,UAAW,QAAO,MAAM;AACrC,SAAO;AACT;AAGO,SAAS,gBAAgB,OAAoB,UAA0B;AAC5E,MAAI,CAAC,WAAW,KAAK,EAAG,QAAO;AAC/B,QAAM,MAAM,MAAM,cAAc,MAAM;AACtC,QAAM,OAAO,oBAAoB,MAAM,aAAa;AACpD,MAAI,SAAS,WAAY,QAAO,WAAW;AAC3C,MAAI,SAAS,UAAW,QAAO,MAAM;AACrC,SAAO;AACT;AAGA,SAAS,WAAW,OAAoB,OAAwB;AAC9D,QAAM,YAAY,KAAK,IAAI,OAAO,MAAM,cAAc,MAAM,WAAW;AAEvE,SAAO,KAAK,IAAI,mBAAmB,KAAK,IAAI,SAAS,KAAK;AAC5D;AAGA,SAAS,uBAAuB,OAA8D;AAQ5F,QAAM,gBAAgB,CAAC,UAAuB;AAC5C,UAAM,UAAU;AAChB,UAAM,eAAe;AACrB,UAAM,gBAAgB,iBAAiB,aAAa,MAAM,UAAU,OAAO;AAAA,EAC7E;AACA,QAAM,gBAAgB,CAAC,UAAuB;AAC5C,QAAI,EAAE,iBAAiB,eAAe,OAAO,MAAM,MAAM,aAAa,EAAG;AACzE,QAAI,KAAK,IAAI,MAAM,UAAU,MAAM,aAAa,IAAI,qBAAsB,OAAM,eAAe;AAAA,EACjG;AACA,QAAM,cAAc,MAAY;AAC9B,UAAM,UAAU;AAChB,UAAM,gBAAgB,OAAO;AAAA,EAC/B;AACA,QAAM,eAAe,CAAC,UAAuB;AAC3C,UAAM,QAAQ;AACd,UAAM,aAAa;AACnB,UAAM,cAAc,iBAAiB,aAAc,MAAM,QAAQ,CAAC,GAAG,WAAW,OAAO,MAAO,OAAO;AAAA,EACvG;AACA,QAAM,cAAc,CAAC,UAAuB;AAC1C,QAAI,EAAE,iBAAiB,eAAe,OAAO,MAAM,MAAM,WAAW,EAAG;AACvE,UAAM,UAAU,MAAM,QAAQ,CAAC,GAAG;AAClC,QAAI,YAAY,UAAa,KAAK,IAAI,UAAU,MAAM,WAAW,IAAI,sBAAsB;AACzF,YAAM,aAAa;AAAA,IACrB;AAAA,EACF;AACA,QAAM,aAAa,MAAY;AAC7B,UAAM,QAAQ;AACd,UAAM,cAAc,OAAO;AAAA,EAC7B;AACA,QAAM,kBAAkB,MAAY;AAClC,UAAM,SAAS;AACf,gBAAY;AAAA,EACd;AACA,QAAM,YAAY,MAAY;AAC5B,UAAM,SAAS;AAAA,EACjB;AACA,QAAM,UAAU,CAAC,UAAuB;AACtC,QAAI,gBAAgB,KAAK,MAAM,EAAG,OAAM,SAAS;AAAA,EACnD;AACA,SAAO;AAAA,IACL,SAAS;AAAA,MACP,CAAC,eAAe,aAAa;AAAA,MAC7B,CAAC,eAAe,aAAa;AAAA,MAC7B,CAAC,cAAc,YAAY;AAAA,MAC3B,CAAC,aAAa,WAAW;AAAA,MACzB,CAAC,iBAAiB,eAAe;AAAA,MACjC,CAAC,WAAW,SAAS;AAAA,MACrB,CAAC,SAAS,OAAO;AAAA,IACnB;AAAA;AAAA,IAEA,QAAQ;AAAA,MACN,CAAC,aAAa,WAAW;AAAA,MACzB,CAAC,iBAAiB,WAAW;AAAA,MAC7B,CAAC,YAAY,UAAU;AAAA,MACvB,CAAC,eAAe,UAAU;AAAA,IAC5B;AAAA,EACF;AACF;AAkCO,SAAS,mBAAmB,OAAwC;AACzE,QAAM,OAAO,MAAM,cAAc;AACjC,QAAM,eAAe,iBAAiB;AACtC,QAAM,QAAoB;AAAA,IACxB,SAAS;AAAA,IACT,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,UAAU;AAAA,IACV,OAAO,OAAO;AAAA,IACd,OAAO;AAAA,IACP,SAAS,MAAM;AAAA,IACf,gBAAgB,mBAAmB,KAAK;AAAA,IACxC,eAAe,OAAO;AAAA,IACtB,cAAc;AAAA,IACd,aAAa,OAAO;AAAA,IACpB,YAAY;AAAA,EACd;AACA,QAAM,SAAS,MAAY;AAKzB,QAAI,CAAC,MAAM,UAAW;AACtB,UAAM,YAAY;AAClB,UAAM,SAAS;AACf,QAAI,CAAC,WAAW,OAAO,MAAM,KAAK,EAAG,OAAM,WAAW;AACtD,UAAM,QAAQ;AAAA,EAChB;AACA,QAAM,WAAW,MAAY;AAC3B,UAAM,MAAM,mBAAmB,KAAK;AACpC,UAAM,iBAAiB,KAAK,IAAI,MAAM,MAAM,cAAc,IAAI;AAC9D,UAAM,iBAAiB;AAQvB,UAAM,cAAc,MAAM,WAAW,MAAM,gBAAgB;AAC3D,UAAM,YAAY,MAAM,SAAS,MAAM,cAAc;AAQrD,QAAI,eAAe,aAAa,MAAM,OAAQ,OAAM,YAAY;AAChE,QAAI,CAAC,MAAM,aAAa,aAAc;AAGtC,iBAAa,MAAM,KAAK;AACxB,UAAM,QAAQ,WAAW,QAAQ,uBAAuB;AAAA,EAC1D;AACA,QAAM,WAAW,uBAAuB,KAAK;AAC7C,QAAM,UAAqB,CAAC,GAAG,SAAS,SAAS,CAAC,UAAU,QAAQ,GAAG,CAAC,aAAa,MAAM,CAAC;AAC5F,QAAM,SAAS,SAAS;AACxB,aAAW,CAAC,MAAM,QAAQ,KAAK,QAAS,OAAM,iBAAiB,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC;AAChG,aAAW,CAAC,MAAM,QAAQ,KAAK,OAAQ,OAAM,iBAAiB,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC;AAC/F,SAAO;AAAA,IACL,aAAa,MAAM,MAAM;AAAA,IACzB,aAAa,MAAM,MAAM;AAAA,IACzB,SAAS,MAAM,MAAM;AAAA,IACrB,iBAAiB,CAAC,SAAS;AACzB,YAAM,QAAQ;AAAA,IAChB;AAAA,IACA,WAAW,CAAC,aAAa;AACvB,YAAM,UAAU;AAAA,IAClB;AAAA,IACA,QAAQ,MAAM;AACZ,mBAAa,MAAM,KAAK;AACxB,iBAAW,CAAC,MAAM,QAAQ,KAAK,QAAS,OAAM,oBAAoB,MAAM,QAAQ;AAChF,iBAAW,CAAC,MAAM,QAAQ,KAAK,OAAQ,OAAM,oBAAoB,MAAM,QAAQ;AAAA,IACjF;AAAA,EACF;AACF;","names":[]}
|
|
@@ -16,7 +16,20 @@ var EN_US_LIGHTBOX_COPY = {
|
|
|
16
16
|
zoomOut: "Zoom out",
|
|
17
17
|
resetZoom: "Reset zoom",
|
|
18
18
|
play: "Start the slideshow",
|
|
19
|
-
pause: "Pause the slideshow"
|
|
19
|
+
pause: "Pause the slideshow",
|
|
20
|
+
dialogLabel: "Lightbox",
|
|
21
|
+
itemPosition: (index, total) => `Item ${index} of ${total}`,
|
|
22
|
+
videoFallback: (index, total) => `Video ${index} of ${total}`,
|
|
23
|
+
imageFallback: (index, total) => `Image ${index} of ${total}`,
|
|
24
|
+
thumbnailFallback: (index) => `Thumbnail ${index}`
|
|
25
|
+
};
|
|
26
|
+
var EN_US_DATA_GRID_COPY = {
|
|
27
|
+
sortBy: (header) => `Sort by ${header}`,
|
|
28
|
+
selectRow: (rowNumber) => `Select row ${rowNumber}`,
|
|
29
|
+
selectAllRows: "Select all rows",
|
|
30
|
+
expandRow: "Expand row",
|
|
31
|
+
collapseRow: "Collapse row",
|
|
32
|
+
gridLabel: "Data grid"
|
|
20
33
|
};
|
|
21
34
|
var EN_US_MAP_PREVIEW_COPY = {
|
|
22
35
|
zoomIn: "Zoom in",
|
|
@@ -32,7 +45,14 @@ var EN_US_CAROUSEL_COPY = {
|
|
|
32
45
|
};
|
|
33
46
|
var EN_US_TIMING_DIAGRAM_COPY = {
|
|
34
47
|
regionLabel: "Timing diagram",
|
|
35
|
-
heading: "Request timing"
|
|
48
|
+
heading: "Request timing",
|
|
49
|
+
dns: "DNS Lookup",
|
|
50
|
+
connect: "Connection",
|
|
51
|
+
ssl: "SSL/TLS",
|
|
52
|
+
request: "Request",
|
|
53
|
+
response: "Response",
|
|
54
|
+
total: (formatted) => `Total: ${formatted}`,
|
|
55
|
+
totalTime: (formatted) => `Total Time: ${formatted}`
|
|
36
56
|
};
|
|
37
57
|
var EN_US_DATA_STATE_COPY = {
|
|
38
58
|
empty: "Nothing here",
|
|
@@ -145,6 +165,7 @@ var EN_US_DATA_VIEWS_COPY = {
|
|
|
145
165
|
},
|
|
146
166
|
tableFilter: EN_US_TABLE_FILTER_COPY,
|
|
147
167
|
grid: {
|
|
168
|
+
...EN_US_DATA_GRID_COPY,
|
|
148
169
|
rowActions: "Actions",
|
|
149
170
|
bulkActions: (selectedCount) => `Actions (${selectedCount}) \u25BE`,
|
|
150
171
|
emptyFilteredTitle: "No results for these filters",
|
|
@@ -228,10 +249,11 @@ var EN_US_DATA_VIEWS_COPY = {
|
|
|
228
249
|
|
|
229
250
|
export {
|
|
230
251
|
EN_US_LIGHTBOX_COPY,
|
|
252
|
+
EN_US_DATA_GRID_COPY,
|
|
231
253
|
EN_US_MAP_PREVIEW_COPY,
|
|
232
254
|
EN_US_CAROUSEL_COPY,
|
|
233
255
|
EN_US_TIMING_DIAGRAM_COPY,
|
|
234
256
|
EN_US_DATA_STATE_COPY,
|
|
235
257
|
EN_US_DATA_VIEWS_COPY
|
|
236
258
|
};
|
|
237
|
-
//# sourceMappingURL=chunk-
|
|
259
|
+
//# sourceMappingURL=chunk-GXQDWHPN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/en-US.data-display.ts"],"sourcesContent":["/**\n * The en-US pack for the data-display family. Split the same way\n * `pt-BR.data-display.ts` is — see `en-US.ts` for why.\n */\nimport type { DataViewsCopy } from \"./components/data-display/DataViews/data-views-copy\";\nimport type {\n CarouselCopy,\n DataGridCopy,\n DataStateCopy,\n LightboxCopy,\n MapPreviewCopy,\n TimingDiagramCopy,\n} from './copy';\nimport { EN_US_TABLE_FILTER_COPY } from './en-US.layout';\nimport {\n EN_US_CATEGORY_SELECT_COPY,\n EN_US_CONFIRM_ACTION_COPY,\n EN_US_SAVED_VIEWS_LABELS,\n} from './en-US.shared';\n\nexport const EN_US_LIGHTBOX_COPY: LightboxCopy = {\n close: \"Close\",\n previous: \"Previous\",\n next: \"Next\",\n zoomIn: \"Zoom in\",\n zoomOut: \"Zoom out\",\n resetZoom: \"Reset zoom\",\n play: \"Start the slideshow\",\n pause: \"Pause the slideshow\",\n dialogLabel: \"Lightbox\",\n itemPosition: (index, total) => `Item ${index} of ${total}`,\n videoFallback: (index, total) => `Video ${index} of ${total}`,\n imageFallback: (index, total) => `Image ${index} of ${total}`,\n thumbnailFallback: (index) => `Thumbnail ${index}`,\n};\n\nexport const EN_US_DATA_GRID_COPY: DataGridCopy = {\n sortBy: (header) => `Sort by ${header}`,\n selectRow: (rowNumber) => `Select row ${rowNumber}`,\n selectAllRows: \"Select all rows\",\n expandRow: \"Expand row\",\n collapseRow: \"Collapse row\",\n gridLabel: \"Data grid\",\n};\n\nexport const EN_US_MAP_PREVIEW_COPY: MapPreviewCopy = {\n zoomIn: \"Zoom in\",\n zoomOut: \"Zoom out\",\n center: \"Centre the map\",\n mapType: \"Change the map type\",\n fullscreen: \"Full screen\",\n search: \"Search for an address\",\n};\n\nexport const EN_US_CAROUSEL_COPY: CarouselCopy = {\n previous: \"Previous\",\n next: \"Next\",\n};\n\nexport const EN_US_TIMING_DIAGRAM_COPY: TimingDiagramCopy = {\n regionLabel: \"Timing diagram\",\n heading: \"Request timing\",\n dns: \"DNS Lookup\",\n connect: \"Connection\",\n ssl: \"SSL/TLS\",\n request: \"Request\",\n response: \"Response\",\n total: (formatted) => `Total: ${formatted}`,\n totalTime: (formatted) => `Total Time: ${formatted}`,\n};\n\nexport const EN_US_DATA_STATE_COPY: DataStateCopy = {\n empty: \"Nothing here\",\n loading: \"Loading…\",\n endOfList: \"No more items to load\",\n dismissAlert: \"Dismiss\",\n dismissBanner: \"Dismiss this banner\",\n};\n\nexport const EN_US_DATA_VIEWS_COPY: DataViewsCopy = {\n savedViewsMenu: EN_US_SAVED_VIEWS_LABELS,\n confirmAction: EN_US_CONFIRM_ACTION_COPY,\n categorySelect: EN_US_CATEGORY_SELECT_COPY,\n board: {\n countOnPage: (label, count) => `${label}: ${count} on this page`,\n onThisPage: (count) => `${count} on this page`,\n pageSum: (sum) => `This page totals ${sum}`,\n emptyColumn: \"Nothing at this stage\",\n pageScopeNote: \"The counts and totals below cover only the items on this page.\",\n },\n deleteView: {\n title: \"Delete view\",\n target: (viewName) => `Delete \"${viewName}\"?`,\n sharedWarning: \"This view is shared — the team will lose access to it.\",\n // `entityLabel` is the HOST's word for what the rows are, so the sentence is\n // built around it rather than naming a noun of its own.\n rowsUnaffected: (entityLabel) =>\n `${entityLabel} are not affected; only the saved slice is removed.`,\n confirm: \"Delete view\",\n cancel: \"Cancel\",\n },\n manageViews: {\n title: \"Manage views\",\n empty: \"No saved views.\",\n edit: \"Edit\",\n defaultTag: \"Default\",\n otherUserTag: \"Another user's\",\n deleteTitle: \"Delete this saved view?\",\n deleteBody: \"The filters and columns it holds are lost. This cannot be undone.\",\n deleteConfirm: \"Delete\",\n },\n saveView: {\n sharedDescription: \"Anyone in the store will be able to open and use this view.\",\n setDefaultTitle: \"Set as default\",\n setDefaultDescription: \"This screen opens on this view instead of the Main view.\",\n previewHeading: \"What this view holds\",\n previewUnchanged: \"Nothing has changed — this view will match the Main view.\",\n sortRowLabel: \"Sorting\",\n saveFailed: \"Could not save the view.\",\n titleEditing: \"Edit view\",\n titleCreating: \"Save view\",\n descriptionLabel: \"Description — optional\",\n descriptionPlaceholder: \"What this view is for\",\n submitEditing: \"Save changes\",\n submitCreating: \"Save view\",\n nameLabel: \"Name\",\n cancel: \"Cancel\",\n pinnedTitle: \"Pin to the sidebar\",\n pinnedDescription: \"Appears as a shortcut in the menu, under this screen.\",\n sharedTitle: \"Share with the team\",\n namePlaceholder: \"e.g. Declined card payments this week\",\n previewFilters: \"Filters\",\n previewHiddenColumns: \"Hidden columns\",\n },\n columns: {\n visibleCount: (visible, total) => `${visible} of ${total} visible`,\n reset: \"Default\",\n showAll: \"Show all\",\n dragHint: \"Drag to reorder the columns.\",\n moveUp: (columnLabel) => `Move ${columnLabel} up`,\n moveDown: (columnLabel) => `Move ${columnLabel} down`,\n },\n display: {\n sortTab: \"Sort\",\n columnsTab: \"Columns\",\n panelTab: \"Display\",\n direction: \"Direction\",\n layoutHints: {\n table: \"Comparable columns, good for scanning numbers.\",\n list: \"One row per item, with the key fields.\",\n cards: \"Larger blocks, good for a handful of items.\",\n board: \"A column per stage, for tracking what is where.\",\n },\n densityHeadings: {\n table: \"Row height\",\n list: \"Row height\",\n cards: \"Cards per row\",\n board: \"Column width\",\n },\n densityLabels: {\n table: { compact: \"Low\", cozy: \"Medium\", comfortable: \"High\" },\n list: { compact: \"Low\", cozy: \"Medium\", comfortable: \"High\" },\n cards: { compact: \"Many\", cozy: \"Some\", comfortable: \"Few\" },\n board: { compact: \"Narrow\", cozy: \"Medium\", comfortable: \"Wide\" },\n },\n boardUnavailable: \"This screen declares no stages, so it offers no board.\",\n densityUnavailableNarrow:\n \"One card per row at this width — density returns on larger screens.\",\n trigger: \"Display\",\n fieldHeading: \"Field\",\n formatHeading: \"Format\",\n cardZoom: \"Card size\",\n },\n export: {\n formats: {\n // The extension is the file's, not a word: it stays as it is written on\n // disk in every language.\n json: { label: \"JSON (.json)\", hint: \"For integrations\" },\n },\n visibleColumns: (columnCount) => `${columnCount} visible columns, in their current order`,\n trigger: \"Export\",\n triggerLabel: \"Export\",\n },\n tableFilter: EN_US_TABLE_FILTER_COPY,\n grid: {\n ...EN_US_DATA_GRID_COPY,\n rowActions: \"Actions\",\n bulkActions: (selectedCount) => `Actions (${selectedCount}) ▾`,\n emptyFilteredTitle: \"No results for these filters\",\n emptyFilteredHint: \"Adjust or remove the filters.\",\n emptyFilteredAction: \"Clear filters\",\n },\n filters: {\n moreFilters: (count) => `More filters: ${count} did not fit in the bar`,\n moreFiltersApplied: (count, appliedCount) =>\n `More filters: ${count} did not fit in the bar, ${appliedCount} applied`,\n moreTriggerLabel: \"More\",\n moreHeading: \"More filters\",\n overflowNote: \"did not fit in the bar\",\n rangeEnd: \"To\",\n rangeInvalid: \"The start must be earlier than the end.\",\n rangeInclusiveNote: \"Both dates are included in the result.\",\n rangeStart: \"From\",\n // The mask is what the reader TYPES, so it follows their own date order\n // rather than being carried over. A translated label above an unchanged\n // mask is the shape that gets a date entered backwards.\n dayMask: \"mm/dd/yyyy\",\n clearAllFilters: \"Clear all filters\",\n // The KEYS are the package's own preset ids and stay as they are — the\n // surface matches on them. Only the labels beside them are words.\n rangePresets: {\n hoje: \"Today\",\n ontem: \"Yesterday\",\n semana: \"This week\",\n mes: \"This month\",\n ano: \"This year\",\n },\n scopesLabel: \"Status\",\n panelTitle: \"Filters\",\n clear: \"Clear\",\n clearAll: \"Clear filters\",\n clearRange: (label) => `Clear ${label}`,\n allOption: \"All\",\n optionSearchPlaceholder: \"Search…\",\n optionsEmpty: \"No results\",\n optionsHeading: \"Options\",\n },\n selection: {\n selectAllOnPage: \"Select all on this page\",\n clearSelection: \"Clear selection\",\n selectAll: \"Select all\",\n onThisPage: (count) => `${count} on this page`,\n selectRow: \"Select\",\n expandRow: \"Expand details\",\n collapseRow: \"Collapse details\",\n },\n nav: {\n mainView: \"Main view\",\n defaultTag: \"Default\",\n viewOptions: (viewName) => `${viewName} options`,\n emptyHint: \"No saved views. Adjust filters, columns or sorting and save below.\",\n setDefault: \"Set as default\",\n deleteView: \"Delete view\",\n unsavedChanges: \"Unsaved changes\",\n label: \"View\",\n update: \"Update view\",\n save: \"Save view\",\n saveAs: \"Save as new\",\n reset: \"Reset\",\n updateFailed: \"Could not update the view\",\n dismissError: \"Dismiss\",\n goBack: \"Back\",\n pageSize: \"Show:\",\n saveFailed: \"Could not save the change to the view.\",\n editView: \"Rename and edit\",\n pinToSidebar: \"Pin to the sidebar\",\n shareWithTeam: \"Share with the team\",\n },\n search: {\n placeholder: \"Search…\",\n allColumnsLabel: \"Search every column\",\n keywordPlaceholder: \"Press Enter to filter\",\n open: \"Search\",\n close: \"Close search\",\n clear: \"Clear search\",\n },\n};\n"],"mappings":"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","names":[]}
|
|
@@ -45,7 +45,8 @@ function HeaderCell({
|
|
|
45
45
|
sortable,
|
|
46
46
|
stickyHeader,
|
|
47
47
|
headerHeight,
|
|
48
|
-
onSort
|
|
48
|
+
onSort,
|
|
49
|
+
copy
|
|
49
50
|
}) {
|
|
50
51
|
const theme = useTheme();
|
|
51
52
|
const content = column.headerCell ? column.headerCell(column) : column.header;
|
|
@@ -79,7 +80,7 @@ function HeaderCell({
|
|
|
79
80
|
"&:hover": { backgroundColor: "transparent", opacity: 0.8 }
|
|
80
81
|
},
|
|
81
82
|
endIcon: /* @__PURE__ */ jsx(SortIcon, { dir: sort?.dir }),
|
|
82
|
-
"aria-label": column.ariaLabel ??
|
|
83
|
+
"aria-label": column.ariaLabel ?? copy.sortBy(String(column.header)),
|
|
83
84
|
children: content
|
|
84
85
|
}
|
|
85
86
|
) : /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", fontWeight: 500, children: content })
|
|
@@ -140,7 +141,7 @@ function RowControls({
|
|
|
140
141
|
{
|
|
141
142
|
checked: isSelected,
|
|
142
143
|
onChange: (event) => model.onToggleRow(rowId, event.target.checked),
|
|
143
|
-
inputProps: { "aria-label":
|
|
144
|
+
inputProps: { "aria-label": props.copy.selectRow(index + 1) }
|
|
144
145
|
}
|
|
145
146
|
) }),
|
|
146
147
|
expansion && /* @__PURE__ */ jsx(TableCell, { padding: "checkbox", children: expansion.isRowExpandable?.(row) === false ? null : /* @__PURE__ */ jsx(
|
|
@@ -152,7 +153,7 @@ function RowControls({
|
|
|
152
153
|
model.onToggleExpansion(rowId);
|
|
153
154
|
},
|
|
154
155
|
"aria-expanded": isExpanded,
|
|
155
|
-
"aria-label": isExpanded ? expansion.collapseLabel ??
|
|
156
|
+
"aria-label": isExpanded ? expansion.collapseLabel ?? props.copy.collapseRow : expansion.expandLabel ?? props.copy.expandRow,
|
|
156
157
|
"data-slot": "expand-toggle",
|
|
157
158
|
children: isExpanded ? /* @__PURE__ */ jsx(ExpandLess, {}) : /* @__PURE__ */ jsx(ExpandMore, {})
|
|
158
159
|
}
|
|
@@ -204,4 +205,4 @@ export {
|
|
|
204
205
|
DataCell,
|
|
205
206
|
GridRow
|
|
206
207
|
};
|
|
207
|
-
//# sourceMappingURL=chunk-
|
|
208
|
+
//# sourceMappingURL=chunk-ICDAYOJ6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/DataGrid/DataGrid.cells.tsx"],"sourcesContent":["/**\n * The DataGrid's cell and row renderers.\n *\n * Components rather than closures over the grid's scope: as inline `render*`\n * functions they could reach every piece of the component's state, which is how\n * the body grew past 700 lines. Each one now states exactly what it needs.\n */\nimport ArrowDownward from '@mui/icons-material/ArrowDownward';\nimport ArrowUpward from '@mui/icons-material/ArrowUpward';\nimport ExpandLess from '@mui/icons-material/ExpandLess';\nimport ExpandMore from '@mui/icons-material/ExpandMore';\nimport UnfoldMore from '@mui/icons-material/UnfoldMore';\nimport Button from '@mui/material/Button/index.js';\nimport Checkbox from '@mui/material/Checkbox/index.js';\nimport IconButton from '@mui/material/IconButton/index.js';\nimport TableCell from '@mui/material/TableCell/index.js';\nimport TableRow from '@mui/material/TableRow/index.js';\nimport Typography from '@mui/material/Typography/index.js';\nimport { useTheme, type Theme } from '@mui/material/styles/index.js';\nimport React from 'react';\n\nimport { rem } from '../../../tokens/relative';\n\nimport { cellValue } from './DataGrid.rows';\nimport type { DataGridModel } from './DataGrid.model';\nimport type { DataGridProps, GridColumn, GridSort } from './DataGrid.types';\nimport type { DataGridCopy } from '../../../copy';\n\n/** The glyph for a column's current sort state — unsorted included. */\nfunction SortIcon({ dir }: { dir: GridSort['dir'] | undefined }): React.JSX.Element {\n if (!dir) return <UnfoldMore fontSize=\"small\" sx={{ opacity: 0.5 }} />;\n return dir === 'asc' ? <ArrowUpward fontSize=\"small\" /> : <ArrowDownward fontSize=\"small\" />;\n}\n\n/** `aria-sort`'s three values, which are not the same words as `SortDirection`. */\nfunction ariaSort(dir: GridSort['dir'] | undefined): 'none' | 'ascending' | 'descending' {\n if (!dir) return 'none';\n return dir === 'asc' ? 'ascending' : 'descending';\n}\n\n/**\n * One of a column's `width`/`minWidth`/`maxWidth` as CSS. A number is design\n * px through the type scale — except 1 or less, which `sx` has always read as a\n * fraction of the table and still does; a string (`'312px'`, `'20%'`) is used as\n * given.\n */\nfunction columnLength(theme: Theme, value: number | string | undefined): string | undefined {\n if (typeof value !== 'number') return value;\n return value <= 1 && value !== 0 ? `${value * 100}%` : rem(theme, value);\n}\n\n/** A column's size constraints, as the `sx` of its header and its cells. */\nfunction columnBox<T extends Record<string, unknown>>(\n theme: Theme,\n column: GridColumn<T>,\n): { minWidth?: string; maxWidth?: string; width?: string } {\n return {\n minWidth: columnLength(theme, column.minWidth),\n maxWidth: columnLength(theme, column.maxWidth),\n width: columnLength(theme, column.width),\n };\n}\n\nexport interface HeaderCellProps<T extends Record<string, unknown>> {\n column: GridColumn<T>;\n sort: GridSort | undefined;\n sortable: boolean;\n stickyHeader: boolean;\n /** The header row's height, as CSS. */\n headerHeight: string;\n onSort: (columnId: string) => void;\n copy: DataGridCopy;\n}\n\nexport function HeaderCell<T extends Record<string, unknown>>({\n column,\n sort,\n sortable,\n stickyHeader,\n headerHeight,\n onSort,\n copy,\n}: HeaderCellProps<T>): React.JSX.Element {\n const theme = useTheme();\n const content = column.headerCell ? column.headerCell(column) : column.header;\n return (\n <TableCell\n data-slot=\"header-cell\"\n data-sort={sort?.dir ?? 'none'}\n sx={{\n position: stickyHeader ? 'sticky' : 'static',\n top: 0,\n zIndex: 1,\n backgroundColor: theme.palette.background.paper,\n borderBottom: `1px solid ${theme.palette.divider}`,\n height: headerHeight,\n ...columnBox(theme, column),\n }}\n role=\"columnheader\"\n aria-sort={ariaSort(sort?.dir)}\n >\n {sortable ? (\n <Button\n onClick={() => onSort(column.id)}\n sx={{\n justifyContent: 'flex-start',\n textTransform: 'none',\n fontWeight: 500,\n color: 'inherit',\n p: 0,\n minWidth: 0,\n '&:hover': { backgroundColor: 'transparent', opacity: 0.8 },\n }}\n endIcon={<SortIcon dir={sort?.dir} />}\n aria-label={column.ariaLabel ?? copy.sortBy(String(column.header))}\n >\n {content}\n </Button>\n ) : (\n <Typography variant=\"subtitle2\" fontWeight={500}>\n {content}\n </Typography>\n )}\n </TableCell>\n );\n}\n\nexport interface DataCellProps<T extends Record<string, unknown>> {\n row: T;\n rowIndex: number;\n rowId: string | number;\n column: GridColumn<T>;\n /** The row's height, as CSS — `DataGridModel.rowHeight`. */\n rowHeight: string;\n editing: NonNullable<DataGridProps<T>['editing']>;\n model: Pick<DataGridModel<T>, 'editingCell' | 'setEditingCell'>;\n}\n\nexport function DataCell<T extends Record<string, unknown>>({\n row,\n rowIndex,\n rowId,\n column,\n rowHeight,\n editing,\n model,\n}: DataCellProps<T>): React.JSX.Element {\n const theme = useTheme();\n const value = cellValue(row, column);\n const isEditing =\n model.editingCell?.rowId === rowId && model.editingCell?.colId === column.id;\n const content = column.cell\n ? column.cell({ value, row, rowIndex, col: column })\n : String(value ?? '');\n return (\n <TableCell\n data-slot=\"cell\"\n data-col-id={column.id}\n data-editing={isEditing}\n sx={{\n ...columnBox(theme, column),\n height: rowHeight,\n }}\n role=\"gridcell\"\n tabIndex={-1}\n >\n {isEditing && column.editor\n ? column.editor({\n value,\n row,\n onChange: () => undefined,\n commit: () => {\n editing.onEditCommit?.({ rowId, colId: column.id, value, row });\n model.setEditingCell(null);\n },\n cancel: () => model.setEditingCell(null),\n })\n : content}\n </TableCell>\n );\n}\n\nexport interface GridRowProps<T extends Record<string, unknown>> {\n row: T;\n index: number;\n rowId: string | number;\n isSelected: boolean;\n isExpanded: boolean;\n totalColumns: number;\n model: DataGridModel<T>;\n props: DataGridProps<T>;\n}\n\n/** The leading checkbox / chevron cells, which exist only for enabled features. */\nfunction RowControls<T extends Record<string, unknown>>({\n row,\n index,\n rowId,\n isSelected,\n isExpanded,\n model,\n props,\n}: GridRowProps<T>): React.JSX.Element {\n const { selection = { mode: 'none' }, expansion } = props;\n return (\n <>\n {selection.mode !== 'none' && (\n <TableCell padding=\"checkbox\">\n <Checkbox\n checked={isSelected}\n onChange={(event) => model.onToggleRow(rowId, event.target.checked)}\n inputProps={{ 'aria-label': props.copy.selectRow(index + 1) }}\n />\n </TableCell>\n )}\n {expansion && (\n <TableCell padding=\"checkbox\">\n {expansion.isRowExpandable?.(row) === false ? null : (\n <IconButton\n size=\"small\"\n // Stopped so a host that opens the record on a row click does not\n // ALSO open it here: the chevron is its own control.\n onClick={(event) => {\n event.stopPropagation();\n model.onToggleExpansion(rowId);\n }}\n aria-expanded={isExpanded}\n aria-label={\n isExpanded\n ? (expansion.collapseLabel ?? props.copy.collapseRow)\n : (expansion.expandLabel ?? props.copy.expandRow)\n }\n data-slot=\"expand-toggle\"\n >\n {isExpanded ? <ExpandLess /> : <ExpandMore />}\n </IconButton>\n )}\n </TableCell>\n )}\n </>\n );\n}\n\nexport function GridRow<T extends Record<string, unknown>>(\n rowProps: GridRowProps<T>,\n): React.JSX.Element {\n const { row, index, rowId, isSelected, isExpanded, totalColumns, model, props } = rowProps;\n const theme = useTheme();\n const expansion = props.expansion;\n return (\n <React.Fragment>\n <TableRow\n data-slot=\"row\"\n data-selected={isSelected}\n data-expanded={isExpanded}\n sx={{\n '&:hover': { backgroundColor: theme.palette.action.hover },\n ...(isSelected && { backgroundColor: theme.palette.action.selected }),\n height: model.rowHeight,\n }}\n role=\"row\"\n aria-selected={isSelected}\n >\n <RowControls {...rowProps} />\n {model.visibleColumns.map((column) => (\n <DataCell\n key={column.id}\n row={row}\n rowIndex={index}\n rowId={rowId}\n column={column}\n rowHeight={model.rowHeight}\n editing={props.editing ?? { mode: 'none' }}\n model={model}\n />\n ))}\n </TableRow>\n {expansion && isExpanded && expansion.isRowExpandable?.(row) !== false && (\n <TableRow data-slot=\"row-detail\">\n <TableCell colSpan={totalColumns}>{expansion.render(row, index)}</TableCell>\n </TableRow>\n )}\n </React.Fragment>\n );\n}\n"],"mappings":"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","names":[]}
|