@12-apps/ui 6.22.0 → 6.23.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/NATIVE.md +1 -1
- package/components-catalog.md +7 -0
- package/dist/_internal/components/data-display/AsyncStateContainer/AsyncStateContainer.js +3 -3
- package/dist/_internal/components/data-display/Avatar/Avatar.js +2 -2
- package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +1 -1
- package/dist/_internal/components/data-display/CardKit/use-row-confirm.js +1 -1
- package/dist/_internal/components/data-display/Carousel/Carousel.js +2 -2
- package/dist/_internal/components/data-display/Chart/Chart.js +4 -4
- package/dist/_internal/components/data-display/Chart/SpecChart.js +5 -5
- package/dist/_internal/components/data-display/Chart/chart-context.js +2 -2
- package/dist/_internal/components/data-display/Chart/chart-renderers.js +3 -3
- package/dist/_internal/components/data-display/Chip/Chip.js +3 -3
- package/dist/_internal/components/data-display/Chip/Chip.styles.js +2 -2
- package/dist/_internal/components/data-display/DataGrid/DataGrid.js +1 -1
- package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +26 -26
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +30 -30
- package/dist/_internal/components/data-display/DataViews/ManageViewsDialog.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-category-pill.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +10 -10
- package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +1 -1
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +22 -22
- package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +10 -10
- package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +4 -4
- package/dist/_internal/components/data-display/DataViews/data-views-pagination.js +3 -3
- package/dist/_internal/components/data-display/DataViews/data-views-range-pill.js +2 -2
- package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +3 -3
- package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +3 -3
- package/dist/_internal/components/data-display/FleetMap/FleetBody.js +31 -0
- package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +23 -0
- package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js.map +1 -0
- package/dist/_internal/components/data-display/FleetMap/FleetMap.fixtures.js +57 -0
- package/dist/_internal/components/data-display/FleetMap/FleetMap.fixtures.js.map +1 -0
- package/dist/_internal/components/data-display/FleetMap/FleetMap.helpers.js +14 -0
- package/dist/_internal/components/data-display/FleetMap/FleetMap.helpers.js.map +1 -0
- package/dist/_internal/components/data-display/FleetMap/FleetMap.hooks.js +9 -0
- package/dist/_internal/components/data-display/FleetMap/FleetMap.hooks.js.map +1 -0
- package/dist/_internal/components/data-display/FleetMap/FleetMap.js +46 -0
- package/dist/_internal/components/data-display/FleetMap/FleetMap.js.map +1 -0
- package/dist/_internal/components/data-display/FleetMap/FleetMap.types.js +1 -0
- package/dist/_internal/components/data-display/FleetMap/FleetMap.types.js.map +1 -0
- package/dist/_internal/components/data-display/FleetMap/FleetRoster.js +14 -0
- package/dist/_internal/components/data-display/FleetMap/FleetRoster.js.map +1 -0
- package/dist/_internal/components/data-display/HoverCard/HoverCard.js +2 -2
- package/dist/_internal/components/data-display/Lightbox/Lightbox.js +2 -2
- package/dist/_internal/components/data-display/MapPreview/MapLayers.js +2 -2
- package/dist/_internal/components/data-display/MapPreview/MapPreview.js +6 -6
- package/dist/_internal/components/data-display/Sheet/Sheet.hooks.js +2 -2
- package/dist/_internal/components/data-display/Sheet/Sheet.js +3 -3
- package/dist/_internal/components/data-display/Table/Table.js +3 -3
- package/dist/_internal/components/data-display/index.js +82 -62
- package/dist/_internal/components/feedback/Modal/Modal.js +2 -2
- package/dist/_internal/components/feedback/StackedModal/StackedModal.js +2 -2
- package/dist/_internal/components/feedback/index.js +14 -14
- package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.hooks.js +3 -3
- package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.js +5 -5
- package/dist/_internal/components/form/AddressAutocomplete/AddressAutocompleteField.js +2 -2
- package/dist/_internal/components/form/CategorySelect/CategoryPanel.js +2 -2
- package/dist/_internal/components/form/CategorySelect/CategorySelect.js +4 -4
- package/dist/_internal/components/form/Command/Command.js +2 -2
- package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +3 -3
- package/dist/_internal/components/form/PhoneInput/PhoneInput.hooks.js +2 -2
- package/dist/_internal/components/form/PhoneInput/PhoneInput.js +3 -3
- package/dist/_internal/components/form/index.js +30 -30
- package/dist/_internal/components/form/total-form/Fields/CategoryField.js +5 -5
- package/dist/_internal/components/form/total-form/Fields/index.js +9 -9
- package/dist/_internal/components/index.js +152 -133
- package/dist/_internal/components/layout/SettingsLayout/SettingsLayout.js +2 -2
- package/dist/_internal/components/layout/index.js +20 -20
- package/dist/_internal/components/navigation/AppHeader/AppHeader.details.js +4 -4
- package/dist/_internal/components/navigation/Pagination/Pagination.js +2 -2
- package/dist/_internal/components/navigation/index.js +12 -12
- package/dist/_internal/components/utility/index.js +4 -4
- package/dist/_internal/pt-BR.data-display.js +2 -2
- package/dist/_internal/user-avatar/user-avatar.js +3 -3
- package/dist/charts.js +5 -5
- package/dist/chunk-2RQINU5T.js +41 -0
- package/dist/chunk-2RQINU5T.js.map +1 -0
- package/dist/{chunk-VLHGBFR6.js → chunk-2UGJIKVA.js} +2 -2
- package/dist/{chunk-WMALDOF5.js → chunk-4G3FGCWX.js} +4 -4
- package/dist/{chunk-ZKR5B6YJ.js → chunk-4LRFGB3K.js} +2 -2
- package/dist/{chunk-ZOUWHGV3.js → chunk-4MGFUPQT.js} +4 -4
- package/dist/{chunk-VQAM2XZV.js → chunk-4XZXLB4I.js} +3 -3
- package/dist/chunk-5V4UPOWK.js +36 -0
- package/dist/chunk-5V4UPOWK.js.map +1 -0
- package/dist/{chunk-VIK3HAUQ.js → chunk-73NJCGQG.js} +2 -2
- package/dist/{chunk-PFV6RL4Q.js → chunk-ACFGEZ4Q.js} +3 -3
- package/dist/{chunk-U2YJCNRU.js → chunk-AJGYHDA5.js} +4 -4
- package/dist/{chunk-HKV4MQ2W.js → chunk-BLBOYCOV.js} +5 -5
- package/dist/{chunk-QZBUGUOY.js → chunk-BZTFPSWT.js} +4 -4
- package/dist/{chunk-7TZ6OC5T.js → chunk-CBTY36TU.js} +2 -2
- package/dist/chunk-CDCTLPMD.js +1 -0
- package/dist/chunk-CDCTLPMD.js.map +1 -0
- package/dist/chunk-CF3FAAPC.js +79 -0
- package/dist/chunk-CF3FAAPC.js.map +1 -0
- package/dist/{chunk-PMS3H3OO.js → chunk-DF2FFYZ7.js} +4 -4
- package/dist/{chunk-FPWB5ILF.js → chunk-DRHIIUDO.js} +5 -5
- package/dist/{chunk-WLQTHPMX.js → chunk-EJQW2IYW.js} +2 -2
- package/dist/{chunk-XFUNJYFT.js → chunk-EPNUVSNK.js} +7 -7
- package/dist/{chunk-MSUSZLRE.js → chunk-EWT3WMVY.js} +5 -5
- package/dist/chunk-F7VBGS4C.js +64 -0
- package/dist/chunk-F7VBGS4C.js.map +1 -0
- package/dist/{chunk-Q75SJ35X.js → chunk-GMTM6EN7.js} +3 -3
- package/dist/{chunk-6NZTYZP5.js → chunk-GVA5CYKP.js} +2 -2
- package/dist/{chunk-VR5HDUBK.js → chunk-HP2ODXNA.js} +2 -2
- package/dist/{chunk-7BYFC2MR.js → chunk-I7HYGIEJ.js} +6 -6
- package/dist/{chunk-UVGRRI7N.js → chunk-IPVYEPXO.js} +4 -4
- package/dist/{chunk-5ZTUP65G.js → chunk-JM64OEU6.js} +5 -5
- package/dist/{chunk-QFJRB27Q.js → chunk-KHWCX4LI.js} +2 -2
- package/dist/{chunk-TLMLEC4F.js → chunk-KW7H5O3K.js} +6 -6
- package/dist/{chunk-UU3QAKG6.js → chunk-L4U23SBX.js} +4 -4
- package/dist/chunk-MQNKRIGC.js +205 -0
- package/dist/chunk-MQNKRIGC.js.map +1 -0
- package/dist/{chunk-QWDEOITU.js → chunk-MYGNIFZC.js} +2 -2
- package/dist/{chunk-2MMEIN4T.js → chunk-N2TUX4A5.js} +4 -4
- package/dist/{chunk-KTK4A3IF.js → chunk-OIKQO73C.js} +7 -7
- package/dist/{chunk-REMK55JI.js → chunk-OLZTGVBT.js} +4 -4
- package/dist/{chunk-ZIYMBR7K.js → chunk-OTH7H3IP.js} +2 -2
- package/dist/{chunk-J4W4TQPC.js → chunk-QJRDDVZ2.js} +5 -5
- package/dist/{chunk-VNDOQEJ7.js → chunk-QRX5BYUQ.js} +4 -4
- package/dist/{chunk-XT7HMNBW.js → chunk-R6SNYC3D.js} +5 -5
- package/dist/{chunk-W2UTDN4T.js → chunk-RBGOGTT2.js} +4 -4
- package/dist/chunk-RQWZYD6H.js +1 -0
- package/dist/chunk-RQWZYD6H.js.map +1 -0
- package/dist/{chunk-EXJBPKGW.js → chunk-SHDIZSN5.js} +5 -5
- package/dist/{chunk-23FCBIUN.js → chunk-TNVO2DTB.js} +8 -8
- package/dist/{chunk-AGSBIUPV.js → chunk-TPLKJHNN.js} +4 -4
- package/dist/{chunk-U2AC4AQX.js → chunk-TU5EIKJA.js} +4 -4
- package/dist/chunk-TWQYDKCA.js +113 -0
- package/dist/chunk-TWQYDKCA.js.map +1 -0
- package/dist/{chunk-BGYLL467.js → chunk-TXHJX2NG.js} +4 -4
- package/dist/{chunk-E46PG577.js → chunk-URXT5TOY.js} +4 -4
- package/dist/{chunk-5NKUYCZD.js → chunk-VON4BFK4.js} +4 -4
- package/dist/{chunk-FL54G7PV.js → chunk-WIT3Y7JT.js} +2 -2
- package/dist/{chunk-DVUPIVI2.js → chunk-WQA4LIIK.js} +2 -2
- package/dist/{chunk-2UYR2OOE.js → chunk-YRUCIKPO.js} +4 -4
- package/dist/{chunk-QKIJ6YXZ.js → chunk-ZA4U5GDU.js} +4 -4
- package/dist/{chunk-OXQP3N6X.js → chunk-ZTZ6S5Q6.js} +4 -4
- package/dist/data-display/AsyncStateContainer.js +3 -3
- package/dist/data-display/Avatar.js +2 -2
- package/dist/data-display/CardKit.js +8 -8
- package/dist/data-display/Carousel.js +2 -2
- package/dist/data-display/Chart.js +5 -5
- package/dist/data-display/Chip.js +3 -3
- package/dist/data-display/DataGrid.js +1 -1
- package/dist/data-display/DataViews.js +33 -33
- package/dist/data-display/FleetMap.js +54 -0
- package/dist/data-display/FleetMap.js.map +1 -0
- package/dist/data-display/HoverCard.js +2 -2
- package/dist/data-display/Lightbox.js +2 -2
- package/dist/data-display/MapPreview.js +6 -6
- package/dist/data-display/Sheet.js +3 -3
- package/dist/data-display/Table.js +3 -3
- package/dist/feedback/ConfirmAction.js +3 -3
- package/dist/feedback/Modal.js +2 -2
- package/dist/feedback/StackedModal.js +2 -2
- package/dist/form/AddressAutocomplete.js +5 -5
- package/dist/form/CategorySelect.js +4 -4
- package/dist/form/Command.js +2 -2
- package/dist/form/DateRangePicker.js +5 -5
- package/dist/form/PhoneInput.js +3 -3
- package/dist/form/total-form.js +9 -9
- package/dist/layout/SettingsLayout.js +2 -2
- package/dist/locales.js +4 -4
- package/dist/navigation/AppHeader.js +6 -6
- package/dist/navigation/Pagination.js +2 -2
- package/dist/pt-BR.js +4 -4
- package/dist/types/components/data-display/FleetMap/FleetBody.d.ts +22 -0
- package/dist/types/components/data-display/FleetMap/FleetBody.d.ts.map +1 -0
- package/dist/types/components/data-display/FleetMap/FleetCanvas.d.ts +50 -0
- package/dist/types/components/data-display/FleetMap/FleetCanvas.d.ts.map +1 -0
- package/dist/types/components/data-display/FleetMap/FleetMap.d.ts +32 -0
- package/dist/types/components/data-display/FleetMap/FleetMap.d.ts.map +1 -0
- package/dist/types/components/data-display/FleetMap/FleetMap.fixtures.d.ts +23 -0
- package/dist/types/components/data-display/FleetMap/FleetMap.fixtures.d.ts.map +1 -0
- package/dist/types/components/data-display/FleetMap/FleetMap.helpers.d.ts +45 -0
- package/dist/types/components/data-display/FleetMap/FleetMap.helpers.d.ts.map +1 -0
- package/dist/types/components/data-display/FleetMap/FleetMap.hooks.d.ts +54 -0
- package/dist/types/components/data-display/FleetMap/FleetMap.hooks.d.ts.map +1 -0
- package/dist/types/components/data-display/FleetMap/FleetMap.types.d.ts +145 -0
- package/dist/types/components/data-display/FleetMap/FleetMap.types.d.ts.map +1 -0
- package/dist/types/components/data-display/FleetMap/FleetRoster.d.ts +15 -0
- package/dist/types/components/data-display/FleetMap/FleetRoster.d.ts.map +1 -0
- package/dist/types/components/data-display/FleetMap/index.d.ts +5 -0
- package/dist/types/components/data-display/FleetMap/index.d.ts.map +1 -0
- package/dist/types/components/data-display/index.d.ts +1 -0
- package/dist/types/components/data-display/index.d.ts.map +1 -1
- package/dist/user-avatar.js +3 -3
- package/package.json +5 -1
- package/src/components/data-display/FleetMap/FleetBody.tsx +96 -0
- package/src/components/data-display/FleetMap/FleetCanvas.tsx +80 -0
- package/src/components/data-display/FleetMap/FleetMap.fixtures.ts +70 -0
- package/src/components/data-display/FleetMap/FleetMap.helpers.ts +85 -0
- package/src/components/data-display/FleetMap/FleetMap.hooks.ts +164 -0
- package/src/components/data-display/FleetMap/FleetMap.md +182 -0
- package/src/components/data-display/FleetMap/FleetMap.tsx +169 -0
- package/src/components/data-display/FleetMap/FleetMap.types.ts +148 -0
- package/src/components/data-display/FleetMap/FleetRoster.tsx +321 -0
- package/src/components/data-display/FleetMap/index.ts +9 -0
- package/src/components/data-display/FleetMap/tests.md +79 -0
- package/src/components/data-display/FleetMap/track.md +50 -0
- package/src/components/data-display/index.ts +1 -0
- package/src/components/feedback/ConfirmAction/ConfirmAction.md +10 -4
- package/dist/chunk-X3HL5C6H.js +0 -1
- /package/dist/{chunk-X3HL5C6H.js.map → _internal/components/data-display/FleetMap/FleetBody.js.map} +0 -0
- /package/dist/{chunk-VLHGBFR6.js.map → chunk-2UGJIKVA.js.map} +0 -0
- /package/dist/{chunk-WMALDOF5.js.map → chunk-4G3FGCWX.js.map} +0 -0
- /package/dist/{chunk-ZKR5B6YJ.js.map → chunk-4LRFGB3K.js.map} +0 -0
- /package/dist/{chunk-ZOUWHGV3.js.map → chunk-4MGFUPQT.js.map} +0 -0
- /package/dist/{chunk-VQAM2XZV.js.map → chunk-4XZXLB4I.js.map} +0 -0
- /package/dist/{chunk-VIK3HAUQ.js.map → chunk-73NJCGQG.js.map} +0 -0
- /package/dist/{chunk-PFV6RL4Q.js.map → chunk-ACFGEZ4Q.js.map} +0 -0
- /package/dist/{chunk-U2YJCNRU.js.map → chunk-AJGYHDA5.js.map} +0 -0
- /package/dist/{chunk-HKV4MQ2W.js.map → chunk-BLBOYCOV.js.map} +0 -0
- /package/dist/{chunk-QZBUGUOY.js.map → chunk-BZTFPSWT.js.map} +0 -0
- /package/dist/{chunk-7TZ6OC5T.js.map → chunk-CBTY36TU.js.map} +0 -0
- /package/dist/{chunk-PMS3H3OO.js.map → chunk-DF2FFYZ7.js.map} +0 -0
- /package/dist/{chunk-FPWB5ILF.js.map → chunk-DRHIIUDO.js.map} +0 -0
- /package/dist/{chunk-WLQTHPMX.js.map → chunk-EJQW2IYW.js.map} +0 -0
- /package/dist/{chunk-XFUNJYFT.js.map → chunk-EPNUVSNK.js.map} +0 -0
- /package/dist/{chunk-MSUSZLRE.js.map → chunk-EWT3WMVY.js.map} +0 -0
- /package/dist/{chunk-Q75SJ35X.js.map → chunk-GMTM6EN7.js.map} +0 -0
- /package/dist/{chunk-6NZTYZP5.js.map → chunk-GVA5CYKP.js.map} +0 -0
- /package/dist/{chunk-VR5HDUBK.js.map → chunk-HP2ODXNA.js.map} +0 -0
- /package/dist/{chunk-7BYFC2MR.js.map → chunk-I7HYGIEJ.js.map} +0 -0
- /package/dist/{chunk-UVGRRI7N.js.map → chunk-IPVYEPXO.js.map} +0 -0
- /package/dist/{chunk-5ZTUP65G.js.map → chunk-JM64OEU6.js.map} +0 -0
- /package/dist/{chunk-QFJRB27Q.js.map → chunk-KHWCX4LI.js.map} +0 -0
- /package/dist/{chunk-TLMLEC4F.js.map → chunk-KW7H5O3K.js.map} +0 -0
- /package/dist/{chunk-UU3QAKG6.js.map → chunk-L4U23SBX.js.map} +0 -0
- /package/dist/{chunk-QWDEOITU.js.map → chunk-MYGNIFZC.js.map} +0 -0
- /package/dist/{chunk-2MMEIN4T.js.map → chunk-N2TUX4A5.js.map} +0 -0
- /package/dist/{chunk-KTK4A3IF.js.map → chunk-OIKQO73C.js.map} +0 -0
- /package/dist/{chunk-REMK55JI.js.map → chunk-OLZTGVBT.js.map} +0 -0
- /package/dist/{chunk-ZIYMBR7K.js.map → chunk-OTH7H3IP.js.map} +0 -0
- /package/dist/{chunk-J4W4TQPC.js.map → chunk-QJRDDVZ2.js.map} +0 -0
- /package/dist/{chunk-VNDOQEJ7.js.map → chunk-QRX5BYUQ.js.map} +0 -0
- /package/dist/{chunk-XT7HMNBW.js.map → chunk-R6SNYC3D.js.map} +0 -0
- /package/dist/{chunk-W2UTDN4T.js.map → chunk-RBGOGTT2.js.map} +0 -0
- /package/dist/{chunk-EXJBPKGW.js.map → chunk-SHDIZSN5.js.map} +0 -0
- /package/dist/{chunk-23FCBIUN.js.map → chunk-TNVO2DTB.js.map} +0 -0
- /package/dist/{chunk-AGSBIUPV.js.map → chunk-TPLKJHNN.js.map} +0 -0
- /package/dist/{chunk-U2AC4AQX.js.map → chunk-TU5EIKJA.js.map} +0 -0
- /package/dist/{chunk-BGYLL467.js.map → chunk-TXHJX2NG.js.map} +0 -0
- /package/dist/{chunk-E46PG577.js.map → chunk-URXT5TOY.js.map} +0 -0
- /package/dist/{chunk-5NKUYCZD.js.map → chunk-VON4BFK4.js.map} +0 -0
- /package/dist/{chunk-FL54G7PV.js.map → chunk-WIT3Y7JT.js.map} +0 -0
- /package/dist/{chunk-DVUPIVI2.js.map → chunk-WQA4LIIK.js.map} +0 -0
- /package/dist/{chunk-2UYR2OOE.js.map → chunk-YRUCIKPO.js.map} +0 -0
- /package/dist/{chunk-QKIJ6YXZ.js.map → chunk-ZA4U5GDU.js.map} +0 -0
- /package/dist/{chunk-OXQP3N6X.js.map → chunk-ZTZ6S5Q6.js.map} +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FleetMapState } from './FleetMap.hooks';
|
|
3
|
+
import type { FleetMapCopy } from './FleetMap.types';
|
|
4
|
+
export interface FleetBodyProps extends Pick<FleetMapState, 'ordered' | 'centre' | 'markers' | 'select' | 'onKeyDown'> {
|
|
5
|
+
copy: FleetMapCopy;
|
|
6
|
+
selectedId: string | null | undefined;
|
|
7
|
+
laggingAfterSeconds: number;
|
|
8
|
+
staleAfterSeconds: number;
|
|
9
|
+
height: string;
|
|
10
|
+
loading: boolean;
|
|
11
|
+
testId: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The two halves side by side: the roster that reads the fleet, and the map.
|
|
15
|
+
*
|
|
16
|
+
* A component rather than JSX inside {@link import('./FleetMap').FleetMap}
|
|
17
|
+
* because the layout is where every responsive decision lives, and keeping it
|
|
18
|
+
* here is what leaves the exported component short enough to read in one
|
|
19
|
+
* screen — which the complexity ledger enforces rather than merely suggests.
|
|
20
|
+
*/
|
|
21
|
+
export declare function FleetBody({ ordered, centre, markers, select, onKeyDown, copy, selectedId, laggingAfterSeconds, staleAfterSeconds, height, loading, testId, }: FleetBodyProps): React.JSX.Element;
|
|
22
|
+
//# sourceMappingURL=FleetBody.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FleetBody.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/FleetMap/FleetBody.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,MAAM,WAAW,cACf,SAAQ,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;IACtF,IAAI,EAAE,YAAY,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,MAAM,EACN,OAAO,EACP,MAAM,EACN,SAAS,EACT,IAAI,EACJ,UAAU,EACV,mBAAmB,EACnB,iBAAiB,EACjB,MAAM,EACN,OAAO,EACP,MAAM,GACP,EAAE,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAsDpC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FleetMarker } from './FleetMap.hooks';
|
|
3
|
+
import type { LatLng } from './FleetMap.helpers';
|
|
4
|
+
import type { FleetMapCopy } from './FleetMap.types';
|
|
5
|
+
export interface FleetCanvasProps {
|
|
6
|
+
copy: FleetMapCopy;
|
|
7
|
+
/** Where to point. `null` renders NOTHING — see the component's note. */
|
|
8
|
+
centre: LatLng | null;
|
|
9
|
+
markers: FleetMarker[];
|
|
10
|
+
height: string;
|
|
11
|
+
testId: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The map half — a NAMED LANDMARK, not an `aria-hidden` one.
|
|
15
|
+
*
|
|
16
|
+
* Its controls are focusable, and `aria-hidden` over a focusable subtree is the
|
|
17
|
+
* `aria-hidden-focus` violation: a keyboard user tabs into something a screen
|
|
18
|
+
* reader insists is not there. `role="region"` with a name is what puts it in a
|
|
19
|
+
* screen reader's landmark rotor, so it can be jumped PAST in one gesture;
|
|
20
|
+
* `role="group"` is not a landmark and would not.
|
|
21
|
+
*
|
|
22
|
+
* ## Skipping it does not silence it, and that is not ours to fix here
|
|
23
|
+
*
|
|
24
|
+
* `MapPreview` puts `aria-live="polite"` on its own root, with an English
|
|
25
|
+
* `aria-label` naming the centre coordinates and zoom. So re-centring the map —
|
|
26
|
+
* which every selection change does — announces something like "Map preview
|
|
27
|
+
* centered at -23.5505, -46.6333 with zoom level 15", in English, however
|
|
28
|
+
* thoroughly a reader has skipped the landmark. Two things follow, and neither
|
|
29
|
+
* is solved by anything this file can do:
|
|
30
|
+
*
|
|
31
|
+
* * a live region announces from wherever the reader is, so the landmark's
|
|
32
|
+
* skippability does not suppress it;
|
|
33
|
+
* * that string is the one piece of user-facing text in this component that
|
|
34
|
+
* does NOT come through `copy`.
|
|
35
|
+
*
|
|
36
|
+
* Fixing it means changing `MapPreview`, which every other consumer shares, so
|
|
37
|
+
* it is stated here rather than quietly claimed away.
|
|
38
|
+
*
|
|
39
|
+
* ## No centre, no map
|
|
40
|
+
*
|
|
41
|
+
* `mapCentre` answers `null` rather than a coordinate for an empty fleet, and
|
|
42
|
+
* that refusal has to survive the whole way down. `MapPreview` has no default
|
|
43
|
+
* centre — it resolves `center || coordinates || { lat: 0, lng: 0 }` — so
|
|
44
|
+
* forwarding `undefined` sails the map to the Gulf of Guinea and prints
|
|
45
|
+
* `Lat: 0.000000` under a default pin. That is exactly the render the helper
|
|
46
|
+
* exists to prevent, and it is reachable: a board that is `loading` with
|
|
47
|
+
* nothing yet reported skips the empty state by design and lands here.
|
|
48
|
+
*/
|
|
49
|
+
export declare function FleetCanvas({ copy, centre, markers, height, testId, }: FleetCanvasProps): React.JSX.Element | null;
|
|
50
|
+
//# sourceMappingURL=FleetCanvas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FleetCanvas.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/FleetMap/FleetCanvas.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,yEAAyE;IACzE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,MAAM,EACN,OAAO,EACP,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAmB7C"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FleetMapProps } from './FleetMap.types';
|
|
3
|
+
/**
|
|
4
|
+
* FleetMap — where a set of tracked units is right now, as a map beside the
|
|
5
|
+
* roster that reads it.
|
|
6
|
+
*
|
|
7
|
+
* Product-free by construction: it draws labelled dots with a freshness, and
|
|
8
|
+
* every word — the heading, the three freshness states, how a duration and a
|
|
9
|
+
* distance are written — arrives through {@link FleetMapProps.copy}. Couriers,
|
|
10
|
+
* service vans and field engineers are all the same picture.
|
|
11
|
+
*
|
|
12
|
+
* ## Three decisions worth knowing before changing it
|
|
13
|
+
*
|
|
14
|
+
* **The roster is the accessible representation, not a sidebar.** A map is a
|
|
15
|
+
* picture and a screen reader cannot read one, so the list carries the
|
|
16
|
+
* information: everything a sighted user gets from a pin — who, how recently,
|
|
17
|
+
* what they are carrying — is on the row. The map is a NAMED region rather than
|
|
18
|
+
* an `aria-hidden` one, because its controls are focusable and hiding a
|
|
19
|
+
* focusable subtree is the `aria-hidden-focus` violation.
|
|
20
|
+
*
|
|
21
|
+
* **Nothing here formats.** `lastSeen` and `accuracy` are functions on the copy
|
|
22
|
+
* object, the same line `StatCard` holds for its `value`: a duration and a
|
|
23
|
+
* distance are locale rules, and a component that wrote "2 min ago" would have
|
|
24
|
+
* made English the only language it could ever render.
|
|
25
|
+
*
|
|
26
|
+
* **An empty fleet is an empty STATE, not an empty map.** A map with no pins is
|
|
27
|
+
* indistinguishable from a map that failed to load, and the difference is the
|
|
28
|
+
* whole question a dispatcher is asking.
|
|
29
|
+
*/
|
|
30
|
+
export declare const FleetMap: React.FC<FleetMapProps>;
|
|
31
|
+
export default FleetMap;
|
|
32
|
+
//# sourceMappingURL=FleetMap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FleetMap.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/FleetMap/FleetMap.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAwDtD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAuE5C,CAAC;AAIF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { FleetMapCopy, FleetUnit } from './FleetMap.types';
|
|
2
|
+
/**
|
|
3
|
+
* The copy and the fleet every story and test story shares.
|
|
4
|
+
*
|
|
5
|
+
* A module rather than a per-story literal, so a change to the shape breaks in
|
|
6
|
+
* ONE place rather than in fourteen — and so the test stories assert against
|
|
7
|
+
* the same words the visual ones render.
|
|
8
|
+
*/
|
|
9
|
+
/** English, because stories are developer-facing. A consumer passes its own. */
|
|
10
|
+
export declare const FLEET_COPY: FleetMapCopy;
|
|
11
|
+
/**
|
|
12
|
+
* Three riders around São Paulo, one in each freshness state.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately NOT in staleness order, and the labels deliberately do not agree
|
|
15
|
+
* with it either. `rosterOrder` sorts on staleness and breaks ties on the
|
|
16
|
+
* label, so a fixture whose two orders coincide lets the roster's ordering
|
|
17
|
+
* assertion pass against a LABEL-only sort as readily as the real one — a test
|
|
18
|
+
* reporting coverage it does not have. Here the three orders are all different:
|
|
19
|
+
* declared is [ale, ana, bruno], alphabetical is the same, and the correct
|
|
20
|
+
* answer is [ana, bruno, ale].
|
|
21
|
+
*/
|
|
22
|
+
export declare const FLEET: FleetUnit[];
|
|
23
|
+
//# sourceMappingURL=FleetMap.fixtures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FleetMap.fixtures.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/FleetMap/FleetMap.fixtures.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEhE;;;;;;GAMG;AAEH,gFAAgF;AAChF,eAAO,MAAM,UAAU,EAAE,YAgBxB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,EAAE,SAAS,EA2B5B,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { FleetFreshness, FleetUnit } from './FleetMap.types';
|
|
2
|
+
/**
|
|
3
|
+
* How current a fix is, on the two thresholds the caller supplied.
|
|
4
|
+
*
|
|
5
|
+
* Inclusive at both boundaries in the direction that reads better on a screen:
|
|
6
|
+
* a unit exactly at the lagging threshold is already lagging. A boundary has to
|
|
7
|
+
* fall somewhere, and the conservative side is the one that does not tell a
|
|
8
|
+
* dispatcher somebody is live when they are on the edge of not being.
|
|
9
|
+
*/
|
|
10
|
+
export declare function freshnessOf(staleSeconds: number, laggingAfterSeconds: number, staleAfterSeconds: number): FleetFreshness;
|
|
11
|
+
/** A latitude/longitude pair, as the map wants its centre. */
|
|
12
|
+
export interface LatLng {
|
|
13
|
+
lat: number;
|
|
14
|
+
lng: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Where the map should point.
|
|
18
|
+
*
|
|
19
|
+
* The selected unit when there is one — a dispatcher who clicked a name is
|
|
20
|
+
* asking to look at them. Otherwise the fleet's own centroid, which keeps
|
|
21
|
+
* everybody in frame without the caller having to compute a bounding box.
|
|
22
|
+
*
|
|
23
|
+
* `null` for an empty fleet rather than a coordinate: (0, 0) is a real place in
|
|
24
|
+
* the Atlantic, and a map that quietly sails there is worse than one that says
|
|
25
|
+
* it has nothing to show.
|
|
26
|
+
*/
|
|
27
|
+
export declare function mapCentre(units: readonly FleetUnit[], selectedId?: string | null): LatLng | null;
|
|
28
|
+
/**
|
|
29
|
+
* The roster's order: freshest first, then alphabetically.
|
|
30
|
+
*
|
|
31
|
+
* Not the caller's order, deliberately. The one question this panel answers is
|
|
32
|
+
* *who is moving right now*, and a list sorted by anything else buries the
|
|
33
|
+
* answer under whoever happens to sort first. Ties break on the label so the
|
|
34
|
+
* list does not reshuffle between polls when two units share a staleness.
|
|
35
|
+
*/
|
|
36
|
+
export declare function rosterOrder(units: readonly FleetUnit[]): FleetUnit[];
|
|
37
|
+
/**
|
|
38
|
+
* Move the selection by one row, wrapping at both ends.
|
|
39
|
+
*
|
|
40
|
+
* Wrapping rather than stopping: this is a short list a dispatcher arrows
|
|
41
|
+
* through repeatedly, and a selection that sticks at the last row makes the
|
|
42
|
+
* keyboard path feel broken next to the mouse one.
|
|
43
|
+
*/
|
|
44
|
+
export declare function nextSelection(units: readonly FleetUnit[], currentId: string | null | undefined, step: 1 | -1): string | null;
|
|
45
|
+
//# sourceMappingURL=FleetMap.helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FleetMap.helpers.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/FleetMap/FleetMap.helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElE;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,YAAY,EAAE,MAAM,EACpB,mBAAmB,EAAE,MAAM,EAC3B,iBAAiB,EAAE,MAAM,GACxB,cAAc,CAIhB;AAED,8DAA8D;AAC9D,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GACzB,MAAM,GAAG,IAAI,CASf;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,CAIpE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,GACX,MAAM,GAAG,IAAI,CAQf"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type LatLng } from './FleetMap.helpers';
|
|
3
|
+
import type { FleetUnit } from './FleetMap.types';
|
|
4
|
+
/**
|
|
5
|
+
* Everything the board derives from its props, in one hook.
|
|
6
|
+
*
|
|
7
|
+
* Split out of the component so the component is layout and nothing else.
|
|
8
|
+
*
|
|
9
|
+
* The memos are honest about what they buy, which is less than it looks. `units`
|
|
10
|
+
* arrives as a fresh array on every poll, so `ordered` and `markers` are
|
|
11
|
+
* recomputed on every poll whatever these do — a new array is a new identity.
|
|
12
|
+
* What they buy is stability across the renders a poll does NOT cause: a parent
|
|
13
|
+
* re-render, a selection change (which re-runs `centre` but not `ordered`), a
|
|
14
|
+
* theme flip. Sorting a fleet is cheap either way; this is tidiness, not a
|
|
15
|
+
* measured win, and it should not be read as one.
|
|
16
|
+
*
|
|
17
|
+
* `centre` is the exception, and there it is load-bearing rather than tidy —
|
|
18
|
+
* see {@link useFleetMap}.
|
|
19
|
+
*
|
|
20
|
+
* ## Selection works with, without, or half-way through a handler
|
|
21
|
+
*
|
|
22
|
+
* `selectedId` and `onSelect` are both optional, so all four combinations
|
|
23
|
+
* arrive. Left purely controlled, the two useful ones broke: with neither prop
|
|
24
|
+
* the roster was a listbox that answered nothing, and arrowing it called
|
|
25
|
+
* `preventDefault` before a no-op `select`, so the keys did not move a
|
|
26
|
+
* selection AND did not scroll the page either.
|
|
27
|
+
*
|
|
28
|
+
* So the hook keeps its own selection and defers to `selectedId` only when the
|
|
29
|
+
* caller passes one — the ordinary controlled/uncontrolled split, the same one
|
|
30
|
+
* an `<input>` makes. `onSelect` still fires either way, so a consumer can
|
|
31
|
+
* observe the selection without owning it.
|
|
32
|
+
*/
|
|
33
|
+
/** One pin, in the shape `MapPreview` takes. */
|
|
34
|
+
export interface FleetMarker {
|
|
35
|
+
position: LatLng;
|
|
36
|
+
title: string;
|
|
37
|
+
onClick: () => void;
|
|
38
|
+
}
|
|
39
|
+
export interface FleetMapState {
|
|
40
|
+
/** The units, freshest first — see {@link rosterOrder}. */
|
|
41
|
+
ordered: FleetUnit[];
|
|
42
|
+
/**
|
|
43
|
+
* The selection in force — the caller's when they own it, this hook's when
|
|
44
|
+
* they do not. Everything downstream reads THIS and never the raw prop.
|
|
45
|
+
*/
|
|
46
|
+
active: string | null;
|
|
47
|
+
/** Where the map points, or `null` when there is nothing to show. */
|
|
48
|
+
centre: LatLng | null;
|
|
49
|
+
select: (id: string) => void;
|
|
50
|
+
markers: FleetMarker[];
|
|
51
|
+
onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void;
|
|
52
|
+
}
|
|
53
|
+
export declare function useFleetMap(units: readonly FleetUnit[], selectedId: string | null | undefined, onSelect: ((id: string) => void) | undefined): FleetMapState;
|
|
54
|
+
//# sourceMappingURL=FleetMap.hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FleetMap.hooks.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/FleetMap/FleetMap.hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAyC,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB;;;OAGG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,qEAAqE;IACrE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;CACjE;AAiDD,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACrC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,GAC3C,aAAa,CAuDf"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import type { MapPreviewCopy } from '../../../copy';
|
|
2
|
+
/**
|
|
3
|
+
* One tracked unit's newest position, as the caller resolved it.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately says nothing about WHAT is being tracked. A courier, a service
|
|
6
|
+
* van, a field engineer — the component draws a labelled dot with a freshness,
|
|
7
|
+
* and every word that names the domain arrives through {@link FleetMapCopy}.
|
|
8
|
+
*/
|
|
9
|
+
export interface FleetUnit {
|
|
10
|
+
id: string;
|
|
11
|
+
/** The name a human reads, on the pin and in the roster. */
|
|
12
|
+
label: string;
|
|
13
|
+
latitude: number;
|
|
14
|
+
longitude: number;
|
|
15
|
+
/**
|
|
16
|
+
* The fix's accuracy radius in metres, when the platform reported one.
|
|
17
|
+
*
|
|
18
|
+
* Kept because it is what separates a rooftop GPS fix from a cell-tower guess
|
|
19
|
+
* three blocks wide, and a map that draws both identically tells its reader
|
|
20
|
+
* something false.
|
|
21
|
+
*/
|
|
22
|
+
accuracyM?: number | null;
|
|
23
|
+
/**
|
|
24
|
+
* Seconds since the fix was ACCEPTED, on the server's clock.
|
|
25
|
+
*
|
|
26
|
+
* The caller computes it, and the distinction matters: a device whose own
|
|
27
|
+
* clock is an hour slow would otherwise report itself as an hour stale while
|
|
28
|
+
* reporting perfectly.
|
|
29
|
+
*/
|
|
30
|
+
staleSeconds: number;
|
|
31
|
+
/** A short pre-formatted badge beside the name, e.g. `"2 entregas"`. */
|
|
32
|
+
badge?: string;
|
|
33
|
+
}
|
|
34
|
+
/** How current a unit's newest fix is, derived from the thresholds below. */
|
|
35
|
+
export type FleetFreshness = 'live' | 'lagging' | 'stale';
|
|
36
|
+
/**
|
|
37
|
+
* Every word the board prints, and the two it FORMATS.
|
|
38
|
+
*
|
|
39
|
+
* `lastSeen` and `accuracy` are functions rather than strings because a
|
|
40
|
+
* duration and a distance are locale rules, and this package holds the same
|
|
41
|
+
* line `StatCard` does: presentation only, the caller owns the formatting. A
|
|
42
|
+
* `lastSeenMinutes: string` template would have made "há 2 min" the only
|
|
43
|
+
* shape any consumer could ever render.
|
|
44
|
+
*/
|
|
45
|
+
export interface FleetMapCopy {
|
|
46
|
+
/** The panel's heading. */
|
|
47
|
+
title: string;
|
|
48
|
+
/** What the roster says when nobody is reporting. */
|
|
49
|
+
emptyTitle: string;
|
|
50
|
+
emptyDescription?: string;
|
|
51
|
+
/** The roster list's accessible name — it is the map's readable half. */
|
|
52
|
+
rosterLabel: string;
|
|
53
|
+
/**
|
|
54
|
+
* What a screen reader hears while the roster reloads, e.g. "Atualizando a
|
|
55
|
+
* frota". OPTIONAL, and silence is the honest default: `aria-busy` marks the
|
|
56
|
+
* region stale without uttering anything, the skeletons are `aria-hidden`,
|
|
57
|
+
* and this component cannot invent the sentence in the reader's language.
|
|
58
|
+
* Set it and the panel announces politely; leave it and it stays quiet.
|
|
59
|
+
*
|
|
60
|
+
* Announced on a TRANSITION into loading. A board mounted already loading is
|
|
61
|
+
* silent — as any live region is at mount, since there is no change for a
|
|
62
|
+
* reader to observe.
|
|
63
|
+
*/
|
|
64
|
+
loading?: string;
|
|
65
|
+
/**
|
|
66
|
+
* The map region's accessible name.
|
|
67
|
+
*
|
|
68
|
+
* The map is NOT `aria-hidden`, and that is deliberate rather than an
|
|
69
|
+
* oversight: it carries focusable controls (zoom, centre, map type), and
|
|
70
|
+
* `aria-hidden` over a focusable subtree is the `aria-hidden-focus`
|
|
71
|
+
* violation — a keyboard user tabs into a region a screen reader insists is
|
|
72
|
+
* not there. So it is a NAMED region a reader can skip past instead, and the
|
|
73
|
+
* roster beside it carries every fact a pin does.
|
|
74
|
+
*
|
|
75
|
+
* Skipping it does not silence it: `MapPreview` carries its own
|
|
76
|
+
* `aria-live="polite"` and announces its centre in English on every
|
|
77
|
+
* re-centre. See `FleetCanvas` for why that is stated rather than fixed here.
|
|
78
|
+
*/
|
|
79
|
+
mapLabel: string;
|
|
80
|
+
/** The three freshness words, as a reader sees them on a row. */
|
|
81
|
+
freshness: Record<FleetFreshness, string>;
|
|
82
|
+
/** `(seconds) => "há 2 min"`. */
|
|
83
|
+
lastSeen: (staleSeconds: number) => string;
|
|
84
|
+
/** `(metres) => "±12 m"`. A unit with no accuracy renders none. */
|
|
85
|
+
accuracy: (metres: number) => string;
|
|
86
|
+
/** The map control bar's own six names. */
|
|
87
|
+
map: MapPreviewCopy;
|
|
88
|
+
}
|
|
89
|
+
/** Props for the {@link FleetMap} live board. */
|
|
90
|
+
export interface FleetMapProps {
|
|
91
|
+
/** Everyone currently reporting. An empty array renders the empty state. */
|
|
92
|
+
units: readonly FleetUnit[];
|
|
93
|
+
copy: FleetMapCopy;
|
|
94
|
+
/**
|
|
95
|
+
* Which unit is highlighted: the map centres on it and the roster marks it
|
|
96
|
+
* selected. `null` selects nobody and centres on the whole fleet.
|
|
97
|
+
*
|
|
98
|
+
* PASSING IT AT ALL IS THE DECISION. Present on the first render — `null`
|
|
99
|
+
* included — and the board is controlled for life: it renders what you pass
|
|
100
|
+
* and never moves the selection itself. Absent on the first render and it
|
|
101
|
+
* keeps its own, reporting each change through {@link onSelect}. The mode is
|
|
102
|
+
* latched on that first render, the way React latches an `<input>`, so the
|
|
103
|
+
* component cannot change its own semantics halfway through a session.
|
|
104
|
+
*
|
|
105
|
+
* A controlled board reads `undefined` as "nobody is selected", so
|
|
106
|
+
* `useState<string>()` in the caller behaves: clearing it clears the roster.
|
|
107
|
+
*/
|
|
108
|
+
selectedId?: string | null;
|
|
109
|
+
/**
|
|
110
|
+
* A click on a row or a pin, and each arrow-key move. Fires in both modes, so
|
|
111
|
+
* an uncontrolled board can still be observed.
|
|
112
|
+
*
|
|
113
|
+
* Passing {@link selectedId} WITHOUT this is a selection nothing can move:
|
|
114
|
+
* the arrow keys then decline to act and leave the page to scroll, rather
|
|
115
|
+
* than swallowing a keypress that would do nothing.
|
|
116
|
+
*/
|
|
117
|
+
onSelect?: (id: string) => void;
|
|
118
|
+
/**
|
|
119
|
+
* Seconds after which a unit stops reading as `live`, and then as `lagging`.
|
|
120
|
+
*
|
|
121
|
+
* Both carry a GENERIC default (90s and 300s, sized for a phone reporting
|
|
122
|
+
* every twenty seconds) and no domain one, because the answer is entirely a
|
|
123
|
+
* property of the fleet's own ping cadence: a phone reporting every twenty
|
|
124
|
+
* seconds is late at ninety, and a tracker reporting every five minutes is
|
|
125
|
+
* not. A component that picked one would be picking it for every consumer.
|
|
126
|
+
*/
|
|
127
|
+
laggingAfterSeconds?: number;
|
|
128
|
+
staleAfterSeconds?: number;
|
|
129
|
+
/** Map height, any CSS length. */
|
|
130
|
+
height?: string;
|
|
131
|
+
/**
|
|
132
|
+
* While true the map and roster are marked `aria-busy`, and the roster renders
|
|
133
|
+
* skeletons IF no units have landed yet — a poll over a populated roster keeps
|
|
134
|
+
* the list, because unmounting it throws away the focus inside it.
|
|
135
|
+
*
|
|
136
|
+
* It only ANNOUNCES if {@link FleetMapCopy.loading} is set — `aria-busy` is a
|
|
137
|
+
* state, not an utterance. The panel root is deliberately not the busy
|
|
138
|
+
* element, so that announcement sits outside the busy subtree.
|
|
139
|
+
*/
|
|
140
|
+
loading?: boolean;
|
|
141
|
+
className?: string;
|
|
142
|
+
/** Test id for the panel root; every child id is derived from it. */
|
|
143
|
+
dataTestId?: string;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=FleetMap.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FleetMap.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/FleetMap/FleetMap.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,6EAA6E;AAC7E,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAE1D;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;;;OAaG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC1C,iCAAiC;IACjC,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C,mEAAmE;IACnE,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,2CAA2C;IAC3C,GAAG,EAAE,cAAc,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC;;;;;;;;OAQG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FleetMapCopy, FleetUnit } from './FleetMap.types';
|
|
3
|
+
export interface FleetRosterProps {
|
|
4
|
+
units: readonly FleetUnit[];
|
|
5
|
+
copy: FleetMapCopy;
|
|
6
|
+
selectedId: string | null | undefined;
|
|
7
|
+
onSelect: (id: string) => void;
|
|
8
|
+
laggingAfterSeconds: number;
|
|
9
|
+
staleAfterSeconds: number;
|
|
10
|
+
loading: boolean;
|
|
11
|
+
testId: string;
|
|
12
|
+
onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function FleetRoster({ units, copy, selectedId, onSelect, laggingAfterSeconds, staleAfterSeconds, loading, testId, onKeyDown, }: FleetRosterProps): React.JSX.Element;
|
|
15
|
+
//# sourceMappingURL=FleetRoster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FleetRoster.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/FleetMap/FleetRoster.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EAAkB,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAsOhF,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;CACjE;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,mBAAmB,EACnB,iBAAiB,EACjB,OAAO,EACP,MAAM,EACN,SAAS,GACV,EAAE,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA2DtC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { FleetMap } from './FleetMap';
|
|
2
|
+
export { freshnessOf, mapCentre, nextSelection, rosterOrder } from './FleetMap.helpers';
|
|
3
|
+
export type { LatLng } from './FleetMap.helpers';
|
|
4
|
+
export type { FleetFreshness, FleetMapCopy, FleetMapProps, FleetUnit, } from './FleetMap.types';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/FleetMap/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACxF,YAAY,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EACV,cAAc,EACd,YAAY,EACZ,aAAa,EACb,SAAS,GACV,MAAM,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/data-display/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,uCAAuC,CAAC;AACtD,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/data-display/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,uCAAuC,CAAC;AACtD,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC"}
|
package/dist/user-avatar.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
UserAvatar,
|
|
3
3
|
UserMenu
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4LRFGB3K.js";
|
|
5
5
|
import "./chunk-UDQSIRAP.js";
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-3ZVUNSFF.js";
|
|
6
|
+
import "./chunk-I7HYGIEJ.js";
|
|
8
7
|
import "./chunk-4SQFO4GW.js";
|
|
9
8
|
import "./chunk-FAITHWIO.js";
|
|
9
|
+
import "./chunk-3ZVUNSFF.js";
|
|
10
10
|
import "./chunk-XRMZMBE3.js";
|
|
11
11
|
import "./chunk-VUHLNYAE.js";
|
|
12
12
|
import "./chunk-2GSIEDGN.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@12-apps/ui",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.23.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"packageManager": "pnpm@10.34.5",
|
|
6
6
|
"type": "module",
|
|
@@ -204,6 +204,10 @@
|
|
|
204
204
|
"types": "./dist/types/components/data-display/EmptyState/index.d.ts",
|
|
205
205
|
"default": "./dist/data-display/EmptyState.js"
|
|
206
206
|
},
|
|
207
|
+
"./data-display/FleetMap": {
|
|
208
|
+
"types": "./dist/types/components/data-display/FleetMap/index.d.ts",
|
|
209
|
+
"default": "./dist/data-display/FleetMap.js"
|
|
210
|
+
},
|
|
207
211
|
"./data-display/SectionOnboarding": {
|
|
208
212
|
"types": "./dist/types/components/data-display/SectionOnboarding/index.d.ts",
|
|
209
213
|
"default": "./dist/data-display/SectionOnboarding.js"
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import Box from '@mui/material/Box/index.js';
|
|
2
|
+
import Stack from '@mui/material/Stack/index.js';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
import { FleetCanvas } from './FleetCanvas';
|
|
6
|
+
import type { FleetMapState } from './FleetMap.hooks';
|
|
7
|
+
import type { FleetMapCopy } from './FleetMap.types';
|
|
8
|
+
import { FleetRoster } from './FleetRoster';
|
|
9
|
+
|
|
10
|
+
export interface FleetBodyProps
|
|
11
|
+
extends Pick<FleetMapState, 'ordered' | 'centre' | 'markers' | 'select' | 'onKeyDown'> {
|
|
12
|
+
copy: FleetMapCopy;
|
|
13
|
+
selectedId: string | null | undefined;
|
|
14
|
+
laggingAfterSeconds: number;
|
|
15
|
+
staleAfterSeconds: number;
|
|
16
|
+
height: string;
|
|
17
|
+
loading: boolean;
|
|
18
|
+
testId: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The two halves side by side: the roster that reads the fleet, and the map.
|
|
23
|
+
*
|
|
24
|
+
* A component rather than JSX inside {@link import('./FleetMap').FleetMap}
|
|
25
|
+
* because the layout is where every responsive decision lives, and keeping it
|
|
26
|
+
* here is what leaves the exported component short enough to read in one
|
|
27
|
+
* screen — which the complexity ledger enforces rather than merely suggests.
|
|
28
|
+
*/
|
|
29
|
+
export function FleetBody({
|
|
30
|
+
ordered,
|
|
31
|
+
centre,
|
|
32
|
+
markers,
|
|
33
|
+
select,
|
|
34
|
+
onKeyDown,
|
|
35
|
+
copy,
|
|
36
|
+
selectedId,
|
|
37
|
+
laggingAfterSeconds,
|
|
38
|
+
staleAfterSeconds,
|
|
39
|
+
height,
|
|
40
|
+
loading,
|
|
41
|
+
testId,
|
|
42
|
+
}: FleetBodyProps): React.JSX.Element {
|
|
43
|
+
return (
|
|
44
|
+
<Stack
|
|
45
|
+
direction={{ xs: 'column', md: 'row' }}
|
|
46
|
+
spacing={2}
|
|
47
|
+
// `aria-busy` belongs on the halves that are actually reloading, NOT on
|
|
48
|
+
// the panel root — the live region announcing the reload is a sibling up
|
|
49
|
+
// there, and a live region inside a busy subtree is exactly what
|
|
50
|
+
// `aria-busy` tells assistive tech to hold back. Marking the root busy
|
|
51
|
+
// would have silenced the announcement for the whole of the only window
|
|
52
|
+
// in which it has anything to say. `CepField` splits them the same way.
|
|
53
|
+
aria-busy={loading || undefined}
|
|
54
|
+
data-testid={`${testId}-body`}
|
|
55
|
+
sx={{ alignItems: 'stretch', minWidth: 0 }}
|
|
56
|
+
>
|
|
57
|
+
{/* The roster reads first on a phone and sits beside the map from md up.
|
|
58
|
+
It keeps a ceiling so thirty units scroll rather than push the map off
|
|
59
|
+
the screen.
|
|
60
|
+
|
|
61
|
+
It also WIDENS with the viewport rather than staying at its md width.
|
|
62
|
+
Held at 280px, a desktop gave the map 1600px for three pins while the
|
|
63
|
+
roster stayed too narrow for its own meta line — `Lagging · 2 min ago ·
|
|
64
|
+
±180 m` wrapped, at 1920px of all widths. The rungs below are the ones
|
|
65
|
+
the six-width pass was taken at. */}
|
|
66
|
+
<Box
|
|
67
|
+
sx={{
|
|
68
|
+
flexBasis: { md: '280px', lg: '320px', xl: '380px' },
|
|
69
|
+
flexShrink: 0,
|
|
70
|
+
minWidth: 0,
|
|
71
|
+
maxHeight: height,
|
|
72
|
+
display: 'flex',
|
|
73
|
+
}}
|
|
74
|
+
>
|
|
75
|
+
<FleetRoster
|
|
76
|
+
units={ordered}
|
|
77
|
+
copy={copy}
|
|
78
|
+
selectedId={selectedId}
|
|
79
|
+
onSelect={select}
|
|
80
|
+
laggingAfterSeconds={laggingAfterSeconds}
|
|
81
|
+
staleAfterSeconds={staleAfterSeconds}
|
|
82
|
+
loading={loading}
|
|
83
|
+
testId={testId}
|
|
84
|
+
onKeyDown={onKeyDown}
|
|
85
|
+
/>
|
|
86
|
+
</Box>
|
|
87
|
+
<FleetCanvas
|
|
88
|
+
copy={copy}
|
|
89
|
+
centre={centre}
|
|
90
|
+
markers={markers}
|
|
91
|
+
height={height}
|
|
92
|
+
testId={testId}
|
|
93
|
+
/>
|
|
94
|
+
</Stack>
|
|
95
|
+
);
|
|
96
|
+
}
|