@feugene/granularity 0.16.0 → 0.19.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/chunks/chevron-left-D8AUBAM7.js +23 -0
- package/dist/chunks/chevron-left-D8AUBAM7.js.map +1 -0
- package/dist/chunks/{chevron-right-BfqMVpbB.js → chevron-right-C6Z01h0X.js} +1 -22
- package/dist/chunks/chevron-right-C6Z01h0X.js.map +1 -0
- package/dist/chunks/config-8Pcutu1j2.js.map +1 -0
- package/dist/chunks/{config-K0C2tcLB.js → config-9PYRZlKE.js} +1 -1
- package/dist/chunks/{config-K0C2tcLB.js.map → config-9PYRZlKE.js.map} +1 -1
- package/dist/chunks/{config-Zc_bUvZY2.js → config-BDfTXHo12.js} +1 -1
- package/dist/chunks/{config-Zc_bUvZY2.js.map → config-BDfTXHo12.js.map} +1 -1
- package/dist/chunks/config-BE6n20np2.js.map +1 -0
- package/dist/chunks/config-BJ7Bv_G2.js +148 -0
- package/dist/chunks/config-BJ7Bv_G2.js.map +1 -0
- package/dist/chunks/config-BKvX0q102.js.map +1 -0
- package/dist/chunks/{config-CpwwkFBO.js → config-Baj7Wvx-.js} +1 -1
- package/dist/chunks/{config-CpwwkFBO.js.map → config-Baj7Wvx-.js.map} +1 -1
- package/dist/chunks/{config-D8tSR2uS.js → config-Be9k9bOf.js} +2 -8
- package/dist/chunks/config-Be9k9bOf.js.map +1 -0
- package/dist/chunks/config-BoNR7_PD2.js.map +1 -0
- package/dist/chunks/{config-DxCTVBfx.js → config-BsPDQ0dS.js} +2 -2
- package/dist/chunks/config-BsPDQ0dS.js.map +1 -0
- package/dist/chunks/{config-DpqOnJiz2.js → config-CDat1wXf2.js} +1 -1
- package/dist/chunks/config-CDat1wXf2.js.map +1 -0
- package/dist/chunks/config-CN2ULSQL.js.map +1 -0
- package/dist/chunks/{config-Cw6TDzWv2.js → config-COpuWGr_.js} +1 -1
- package/dist/chunks/config-COpuWGr_.js.map +1 -0
- package/dist/chunks/config-CY0_6cMi2.js.map +1 -0
- package/dist/chunks/{config-B-g6lT19.js → config-DA6SnEoy.js} +5 -2
- package/dist/chunks/config-DA6SnEoy.js.map +1 -0
- package/dist/chunks/config-DAX8Deh1.js +68 -0
- package/dist/chunks/config-DAX8Deh1.js.map +1 -0
- package/dist/chunks/config-DKdlqXiY.js.map +1 -1
- package/dist/chunks/{config-CvC0sX8p.js → config-MRvhUl-O.js} +1 -1
- package/dist/chunks/{config-CvC0sX8p.js.map → config-MRvhUl-O.js.map} +1 -1
- package/dist/chunks/config-Rw9OyW702.js.map +1 -0
- package/dist/chunks/config-ScuvHw6k2.js +42 -0
- package/dist/chunks/config-ScuvHw6k2.js.map +1 -0
- package/dist/chunks/config-T3qdQBgU2.js.map +1 -0
- package/dist/chunks/config-eXB87DOi.js.map +1 -0
- package/dist/chunks/context-BSYR7RZs.js.map +1 -1
- package/dist/chunks/{en-B3xMeswz.js → en-COdzxgAX.js} +30 -5
- package/dist/chunks/en-COdzxgAX.js.map +1 -0
- package/dist/chunks/{es-CA-mkU--.js → es-ClqJ-4hr.js} +30 -5
- package/dist/chunks/es-ClqJ-4hr.js.map +1 -0
- package/dist/chunks/{es-Bv8vvqdT.js → es-DGMHwknJ.js} +3 -3
- package/dist/chunks/{es-Bv8vvqdT.js.map → es-DGMHwknJ.js.map} +1 -1
- package/dist/chunks/generated-BRkbhyxk.js +3270 -0
- package/dist/chunks/generated-BRkbhyxk.js.map +1 -0
- package/dist/chunks/grKbdStyles-CeZhGQHr.js +43 -0
- package/dist/chunks/grKbdStyles-CeZhGQHr.js.map +1 -0
- package/dist/chunks/{grTextareaStyles-CWI2SqC8.js → grTextareaStyles-iOcHuVMM.js} +2 -2
- package/dist/chunks/{grTextareaStyles-CWI2SqC8.js.map → grTextareaStyles-iOcHuVMM.js.map} +1 -1
- package/dist/chunks/{granular-provider-CtrXGa7c.js → granular-provider-C6uAujdJ.js} +23 -21
- package/dist/chunks/granular-provider-C6uAujdJ.js.map +1 -0
- package/dist/chunks/grip-vertical-lRha2S7q.js +16 -0
- package/dist/chunks/grip-vertical-lRha2S7q.js.map +1 -0
- package/dist/chunks/icon-Dag2tIMs.js +21 -0
- package/dist/chunks/icon-Dag2tIMs.js.map +1 -0
- package/dist/chunks/{keyboard-zYvvyHd4.js → keyboard-DE2yhz_b.js} +10 -1
- package/dist/chunks/keyboard-DE2yhz_b.js.map +1 -0
- package/dist/chunks/{optionFilter-BVY988pC.js → optionFilter-DYw9XPPx.js} +1 -71
- package/dist/chunks/optionFilter-DYw9XPPx.js.map +1 -0
- package/dist/chunks/{useOverlayLayer-BupuP_hs.js → overlayStack-C8cfsqXa.js} +11 -61
- package/dist/chunks/overlayStack-C8cfsqXa.js.map +1 -0
- package/dist/chunks/{portalRoot-CWD4zHBm.js → portalRoot-CVhCgdG6.js} +10 -1
- package/dist/chunks/{portalRoot-CWD4zHBm.js.map → portalRoot-CVhCgdG6.js.map} +1 -1
- package/dist/chunks/{ru-COWxgh2A.js → ru-9z8ix45c.js} +30 -5
- package/dist/chunks/ru-9z8ix45c.js.map +1 -0
- package/dist/chunks/useDragSort-0l47h4yb.js +265 -0
- package/dist/chunks/useDragSort-0l47h4yb.js.map +1 -0
- package/dist/chunks/{useModalOverlay-DCM4d3yA.js → useModalOverlay-DrQVYwwA.js} +2 -2
- package/dist/chunks/{useModalOverlay-DCM4d3yA.js.map → useModalOverlay-DrQVYwwA.js.map} +1 -1
- package/dist/chunks/{usePortalTarget-RyzEgNTb.js → usePortalTarget-Cn-Wiz5d.js} +1 -1
- package/dist/chunks/{usePortalTarget-RyzEgNTb.js.map → usePortalTarget-Cn-Wiz5d.js.map} +1 -1
- package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-CQ9T7Lly.js → GrAutocomplete-gY4Xopza.js} +35 -26
- package/dist/components/GrAutocomplete/chunks/GrAutocomplete-gY4Xopza.js.map +1 -0
- package/dist/components/GrAutocomplete/index.js +1 -1
- package/dist/components/GrAutocomplete/styles.css +1 -1
- package/dist/components/GrBreadcrumbs/chunks/{GrBreadcrumbs-BCNGDS6k.js → GrBreadcrumbs-DS_-PBVt.js} +8 -7
- package/dist/components/GrBreadcrumbs/chunks/GrBreadcrumbs-DS_-PBVt.js.map +1 -0
- package/dist/components/GrBreadcrumbs/index.js +1 -1
- package/dist/components/GrCollapse/chunks/{GrCollapse-B2Fc6A9r.js.map → GrCollapse-Kk0DE8tb.js.map} +1 -1
- package/dist/components/GrCollapse/index.js +1 -1
- package/dist/components/GrColorPicker/chunks/{GrColorPicker-bnYBRGk8.js → GrColorPicker-CkBTzkqn.js} +4 -4
- package/dist/components/GrColorPicker/chunks/{GrColorPicker-bnYBRGk8.js.map → GrColorPicker-CkBTzkqn.js.map} +1 -1
- package/dist/components/GrColorPicker/index.js +2 -2
- package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-MWDYDPNC.js → GrCommandPalette-BugTlGdj.js} +41 -16
- package/dist/components/GrCommandPalette/chunks/GrCommandPalette-BugTlGdj.js.map +1 -0
- package/dist/components/GrCommandPalette/index.js +2 -2
- package/dist/components/GrCommandPalette/styles.css +1 -1
- package/dist/components/GrConfigProvider/index.js +2 -2
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-DaQmlp1_.js → GrConfirmDialog-Ds5T0GiR.js} +1 -1
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-DaQmlp1_.js.map → GrConfirmDialog-Ds5T0GiR.js.map} +1 -1
- package/dist/components/GrConfirmDialog/index.js +1 -1
- package/dist/components/GrDataTable/chunks/{GrDataTable-DVFho9Cj.js → GrDataTable-CYe2A2WA.js} +498 -48
- package/dist/components/GrDataTable/chunks/GrDataTable-CYe2A2WA.js.map +1 -0
- package/dist/components/GrDataTable/index.js +2 -2
- package/dist/components/GrDialog/chunks/{GrDialog-AE1gIZuz.js → GrDialog-C3tYaA8v.js} +1 -1
- package/dist/components/GrDialog/chunks/{GrDialog-AE1gIZuz.js.map → GrDialog-C3tYaA8v.js.map} +1 -1
- package/dist/components/GrDialog/index.js +1 -1
- package/dist/components/GrDialogService/chunks/{GrDialogService-B4DYWDkA.js → GrDialogService-CTBiiJDI.js} +3 -3
- package/dist/components/GrDialogService/chunks/{GrDialogService-B4DYWDkA.js.map → GrDialogService-CTBiiJDI.js.map} +1 -1
- package/dist/components/GrDialogService/index.js +1 -1
- package/dist/components/GrDivider/chunks/{GrDivider-B2Xwc_QO.js → GrDivider-xxq1_fIl.js} +1 -1
- package/dist/components/GrDivider/chunks/{GrDivider-B2Xwc_QO.js.map → GrDivider-xxq1_fIl.js.map} +1 -1
- package/dist/components/GrDivider/index.js +2 -2
- package/dist/components/GrDrawer/chunks/{GrDrawer-DQwi6aRw.js → GrDrawer-BSSuiNHU.js} +1 -1
- package/dist/components/GrDrawer/chunks/{GrDrawer-DQwi6aRw.js.map → GrDrawer-BSSuiNHU.js.map} +1 -1
- package/dist/components/GrDrawer/index.js +1 -1
- package/dist/components/GrDropdown/chunks/{GrDropdown-BLng6V1m.js → GrDropdown-Bh6UK2M5.js} +3 -3
- package/dist/components/GrDropdown/chunks/{GrDropdown-BLng6V1m.js.map → GrDropdown-Bh6UK2M5.js.map} +1 -1
- package/dist/components/GrDropdown/index.js +1 -1
- package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-BImk2Vs7.js → GrDropdownMenu-LyfEFUbg.js} +2 -2
- package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-BImk2Vs7.js.map → GrDropdownMenu-LyfEFUbg.js.map} +1 -1
- package/dist/components/GrDropdownMenu/index.js +2 -2
- package/dist/components/GrFileUpload/chunks/{GrFileUpload-D0B-BEsd.js → GrFileUpload-DuDzC43S.js} +2 -2
- package/dist/components/GrFileUpload/chunks/{GrFileUpload-D0B-BEsd.js.map → GrFileUpload-DuDzC43S.js.map} +1 -1
- package/dist/components/GrFileUpload/index.js +1 -1
- package/dist/components/GrImageViewer/chunks/{GrImageViewer-BeCnE8XQ.js → GrImageViewer-DfD4euH5.js} +48 -23
- package/dist/components/GrImageViewer/chunks/GrImageViewer-DfD4euH5.js.map +1 -0
- package/dist/components/GrImageViewer/index.js +1 -1
- package/dist/components/GrInput/chunks/{GrInput-DD2gYdqS.js → GrInput-2wd7Crs0.js} +1 -1
- package/dist/components/GrInput/chunks/GrInput-2wd7Crs0.js.map +1 -0
- package/dist/components/GrInput/index.js +1 -1
- package/dist/components/GrInputTag/chunks/{GrInputTag-DmNunixz.js → GrInputTag-CyV2eY7Z.js} +20 -33
- package/dist/components/GrInputTag/chunks/GrInputTag-CyV2eY7Z.js.map +1 -0
- package/dist/components/GrInputTag/index.js +1 -1
- package/dist/components/GrKbd/chunks/{GrKbd-DRFPvW3G.js → GrKbd-DU2lBkRV.js} +218 -52
- package/dist/components/GrKbd/chunks/GrKbd-DU2lBkRV.js.map +1 -0
- package/dist/components/GrKbd/index.js +3 -3
- package/dist/components/GrModal/chunks/{GrModal-B8I78T0N.js → GrModal-CbMMr6W1.js} +1 -1
- package/dist/components/GrModal/chunks/{GrModal-B8I78T0N.js.map → GrModal-CbMMr6W1.js.map} +1 -1
- package/dist/components/GrModal/index.js +1 -1
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-CZOyPz4J.js → GrNumberInput-B5CHZDBj.js} +2 -1
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-CZOyPz4J.js.map → GrNumberInput-B5CHZDBj.js.map} +1 -1
- package/dist/components/GrNumberInput/index.js +1 -1
- package/dist/components/GrPagination/chunks/{GrPagination-B6N0QZBf.js → GrPagination-BM4FrD6Q.js} +4 -4
- package/dist/components/GrPagination/chunks/GrPagination-BM4FrD6Q.js.map +1 -0
- package/dist/components/GrPagination/index.js +1 -1
- package/dist/components/GrPopover/chunks/{GrPopover-B1eRCOoO.js → GrPopover-DMH4Jjst.js} +1 -1
- package/dist/components/GrPopover/chunks/{GrPopover-B1eRCOoO.js.map → GrPopover-DMH4Jjst.js.map} +1 -1
- package/dist/components/GrPopover/index.js +1 -1
- package/dist/components/GrProgressBar/chunks/{GrProgressBar-BiHnaitu.js → GrProgressBar-xwbNM9QB.js} +1 -1
- package/dist/components/GrProgressBar/chunks/GrProgressBar-xwbNM9QB.js.map +1 -0
- package/dist/components/GrProgressBar/index.js +1 -1
- package/dist/components/GrProgressCircle/chunks/{GrProgressCircle-CTogjcHz.js → GrProgressCircle-B8olXRo5.js} +1 -1
- package/dist/components/GrProgressCircle/chunks/{GrProgressCircle-CTogjcHz.js.map → GrProgressCircle-B8olXRo5.js.map} +1 -1
- package/dist/components/GrProgressCircle/index.js +2 -2
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-Ct174NVD.js → GrPromptDialog-Pwr9NPxK.js} +3 -3
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-Ct174NVD.js.map → GrPromptDialog-Pwr9NPxK.js.map} +1 -1
- package/dist/components/GrPromptDialog/index.js +1 -1
- package/dist/components/GrRadio/chunks/{GrRadio-DksDro_U.js → GrRadio-DWiRaMzt.js} +8 -32
- package/dist/components/GrRadio/chunks/GrRadio-DWiRaMzt.js.map +1 -0
- package/dist/components/GrRadio/index.js +1 -1
- package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-BOIhejE6.js → GrRadioGroup-DIuBw0wk.js} +34 -27
- package/dist/components/GrRadioGroup/chunks/GrRadioGroup-DIuBw0wk.js.map +1 -0
- package/dist/components/GrRadioGroup/index.js +1 -1
- package/dist/components/GrRating/chunks/{GrRating-JrHXz0Rv.js → GrRating-DVFH3lYu.js} +10 -9
- package/dist/components/GrRating/chunks/GrRating-DVFH3lYu.js.map +1 -0
- package/dist/components/GrRating/index.js +2 -2
- package/dist/components/GrSegmented/chunks/{GrSegmented-BQIlH5KI.js → GrSegmented-CQw3ijqa.js} +47 -65
- package/dist/components/GrSegmented/chunks/GrSegmented-CQw3ijqa.js.map +1 -0
- package/dist/components/GrSegmented/index.js +1 -1
- package/dist/components/GrSelect/chunks/{GrSelect-aqkPCqjd.js → GrSelect-B-Voni7D.js} +69 -55
- package/dist/components/GrSelect/chunks/GrSelect-B-Voni7D.js.map +1 -0
- package/dist/components/GrSelect/index.js +1 -1
- package/dist/components/GrSelect/styles.css +1 -1
- package/dist/components/GrSidebar/chunks/{GrSidebar-DRGnnViw.js → GrSidebar-i7AxjhY_.js} +3 -2
- package/dist/components/GrSidebar/chunks/{GrSidebar-DRGnnViw.js.map → GrSidebar-i7AxjhY_.js.map} +1 -1
- package/dist/components/GrSidebar/index.js +2 -2
- package/dist/components/GrSkeleton/index.js +1 -1
- package/dist/components/GrSlider/chunks/{GrSlider-DkU9IQSX.js → GrSlider-CyhVsNKn.js} +21 -34
- package/dist/components/GrSlider/chunks/GrSlider-CyhVsNKn.js.map +1 -0
- package/dist/components/GrSlider/index.js +2 -2
- package/dist/components/GrSortableList/chunks/GrSortableList-XB7mXM1W.js +277 -0
- package/dist/components/GrSortableList/chunks/GrSortableList-XB7mXM1W.js.map +1 -0
- package/dist/components/GrSortableList/index.js +3 -0
- package/dist/components/GrSplitter/chunks/{GrSplitter-7To8jbJ8.js → GrSplitter-BzxVQwbY.js} +17 -37
- package/dist/components/GrSplitter/chunks/GrSplitter-BzxVQwbY.js.map +1 -0
- package/dist/components/GrSplitter/index.js +2 -2
- package/dist/components/GrStatistic/chunks/{GrStatistic-CttyoYPT.js → GrStatistic-DOsM6s5V.js} +54 -7
- package/dist/components/GrStatistic/chunks/GrStatistic-DOsM6s5V.js.map +1 -0
- package/dist/components/GrStatistic/index.js +2 -2
- package/dist/components/GrSwitch/chunks/{GrSwitch-B9TYbiih.js → GrSwitch-DpyvVrZG.js} +1 -1
- package/dist/components/GrSwitch/chunks/{GrSwitch-B9TYbiih.js.map → GrSwitch-DpyvVrZG.js.map} +1 -1
- package/dist/components/GrSwitch/index.js +2 -2
- package/dist/components/GrTabPanels/index.js +1 -1
- package/dist/components/GrTable/chunks/{GrTable-BB-mI_NM.js → GrTable-BfqgwETQ.js} +7 -1
- package/dist/components/GrTable/chunks/GrTable-BfqgwETQ.js.map +1 -0
- package/dist/components/GrTable/index.js +1 -1
- package/dist/components/GrTabs/chunks/{GrTabs-B8CDq2D9.js → GrTabs-f3-oQenu.js} +55 -65
- package/dist/components/GrTabs/chunks/GrTabs-f3-oQenu.js.map +1 -0
- package/dist/components/GrTabs/index.js +1 -1
- package/dist/components/GrTextarea/chunks/{GrTextarea-DUh5Tlo4.js → GrTextarea-DSvd1nSy.js} +1 -1
- package/dist/components/GrTextarea/chunks/{GrTextarea-DUh5Tlo4.js.map → GrTextarea-DSvd1nSy.js.map} +1 -1
- package/dist/components/GrTextarea/index.js +2 -2
- package/dist/components/GrTimeline/chunks/{GrTimeline-CE9b3s18.js → GrTimeline-B-h2Yanw.js} +1 -1
- package/dist/components/GrTimeline/chunks/{GrTimeline-CE9b3s18.js.map → GrTimeline-B-h2Yanw.js.map} +1 -1
- package/dist/components/GrTimeline/index.js +2 -2
- package/dist/components/GrToaster/chunks/{GrToaster-BKQy3Srm.js → GrToaster-Dqja0Lf9.js} +114 -13
- package/dist/components/GrToaster/chunks/GrToaster-Dqja0Lf9.js.map +1 -0
- package/dist/components/GrToaster/index.js +2 -2
- package/dist/components/GrToaster/styles.css +1 -1
- package/dist/components/GrTooltip/chunks/{GrTooltip-DEbejfhA.js → GrTooltip-Cn08heWz.js} +2 -2
- package/dist/components/GrTooltip/chunks/{GrTooltip-DEbejfhA.js.map → GrTooltip-Cn08heWz.js.map} +1 -1
- package/dist/components/GrTooltip/index.js +2 -2
- package/dist/components/GrTree/chunks/{GrTree-wfdbvygw.js → GrTree-BR9a2pay.js} +148 -111
- package/dist/components/GrTree/chunks/GrTree-BR9a2pay.js.map +1 -0
- package/dist/components/GrTree/index.js +2 -2
- package/dist/components/GrTree/styles.css +1 -1
- package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-lLWmAMtI.js → GrTreeSelect--muUeB0v.js} +28 -14
- package/dist/components/GrTreeSelect/chunks/GrTreeSelect--muUeB0v.js.map +1 -0
- package/dist/components/GrTreeSelect/index.js +1 -1
- package/dist/composables/useAnnouncer.js +1 -1
- package/dist/composables/useComboboxNavigation.js +71 -0
- package/dist/composables/useComboboxNavigation.js.map +1 -0
- package/dist/composables/useDismissible.js +1 -1
- package/dist/composables/useDragGesture.js +55 -0
- package/dist/composables/useDragGesture.js.map +1 -0
- package/dist/composables/useDragSort.js +2 -0
- package/dist/composables/useFloating.js +22 -1
- package/dist/composables/useFloating.js.map +1 -1
- package/dist/composables/useGrComponentConfig.js +2 -0
- package/dist/composables/useGranularityTranslations.js +2 -0
- package/dist/composables/useOverlayLayer.js +64 -1
- package/dist/composables/useOverlayLayer.js.map +1 -0
- package/dist/composables/usePortalTarget.js +1 -1
- package/dist/composables/useRovingFocus.js +150 -0
- package/dist/composables/useRovingFocus.js.map +1 -0
- package/dist/directives/hotkey.js +13 -7
- package/dist/directives/hotkey.js.map +1 -1
- package/dist/directives/loading.js +1 -1
- package/dist/granular-provider-node.js +1 -1
- package/dist/granular-provider.js +1 -1
- package/dist/i18n/all.js +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/index.js +77 -68
- package/dist/styles/themes/dark.css +6 -1
- package/dist/testing.js +199 -0
- package/dist/testing.js.map +1 -0
- package/dist/theme-apply.js +33 -0
- package/dist/theme-apply.js.map +1 -0
- package/dist/theme.js +501 -0
- package/dist/theme.js.map +1 -0
- package/dist/tokens.js +1 -3131
- package/dist/types/src/components/GrAlert/defaults.d.ts +1 -1
- package/dist/types/src/components/GrAutocomplete/defaults.d.ts +1 -1
- package/dist/types/src/components/GrAvatar/defaults.d.ts +1 -1
- package/dist/types/src/components/GrBadge/defaults.d.ts +1 -1
- package/dist/types/src/components/GrBottomNav/defaults.d.ts +1 -1
- package/dist/types/src/components/GrBreadcrumbs/defaults.d.ts +1 -1
- package/dist/types/src/components/GrBreadcrumbs/grBreadcrumbsStyles.d.ts +5 -2
- package/dist/types/src/components/GrButton/defaults.d.ts +1 -1
- package/dist/types/src/components/GrCard/defaults.d.ts +1 -1
- package/dist/types/src/components/GrCheckbox/defaults.d.ts +1 -1
- package/dist/types/src/components/GrCheckboxGroup/defaults.d.ts +1 -1
- package/dist/types/src/components/GrCollapse/defaults.d.ts +1 -1
- package/dist/types/src/components/GrColorPicker/defaults.d.ts +1 -1
- package/dist/types/src/components/GrColorPicker/grColorPickerStyles.d.ts +2 -2
- package/dist/types/src/components/GrCommandPalette/GrCommandPalette.vue.d.ts +6 -6
- package/dist/types/src/components/GrCommandPalette/defaults.d.ts +1 -1
- package/dist/types/src/components/GrCommandPalette/filtering.d.ts +6 -2
- package/dist/types/src/components/GrConfigProvider/context.d.ts +6 -22
- package/dist/types/src/components/GrConfigProvider/index.d.ts +1 -1
- package/dist/types/src/components/GrConfirmDialog/defaults.d.ts +1 -1
- package/dist/types/src/components/GrDataTable/GrDataTable.vue.d.ts +53 -0
- package/dist/types/src/components/GrDataTable/defaults.d.ts +1 -1
- package/dist/types/src/components/GrDataTable/grDataTableStyles.d.ts +38 -0
- package/dist/types/src/components/GrDialog/defaults.d.ts +1 -1
- package/dist/types/src/components/GrDivider/defaults.d.ts +1 -1
- package/dist/types/src/components/GrDrawer/defaults.d.ts +1 -1
- package/dist/types/src/components/GrEmptyState/defaults.d.ts +1 -1
- package/dist/types/src/components/GrFileUpload/defaults.d.ts +1 -1
- package/dist/types/src/components/GrFormField/defaults.d.ts +1 -1
- package/dist/types/src/components/GrFormFile/defaults.d.ts +1 -1
- package/dist/types/src/components/GrFormSection/defaults.d.ts +1 -1
- package/dist/types/src/components/GrIcon/defaults.d.ts +1 -1
- package/dist/types/src/components/GrImageViewer/composables/usePointerGestures.d.ts +1 -0
- package/dist/types/src/components/GrImageViewer/composables/useZoomPan.d.ts +1 -2
- package/dist/types/src/components/GrInput/defaults.d.ts +1 -1
- package/dist/types/src/components/GrInputTag/defaults.d.ts +1 -1
- package/dist/types/src/components/GrKbd/GrKbd.vue.d.ts +18 -3
- package/dist/types/src/components/GrKbd/defaults.d.ts +1 -1
- package/dist/types/src/components/GrKbd/grKbdStyles.d.ts +20 -3
- package/dist/types/src/components/GrKbd/index.d.ts +6 -0
- package/dist/types/src/components/GrLink/defaults.d.ts +1 -1
- package/dist/types/src/components/GrModal/defaults.d.ts +1 -1
- package/dist/types/src/components/GrNumberInput/defaults.d.ts +1 -1
- package/dist/types/src/components/GrPagination/defaults.d.ts +1 -1
- package/dist/types/src/components/GrPopover/GrPopover.vue.d.ts +1 -1
- package/dist/types/src/components/GrPopover/defaults.d.ts +1 -1
- package/dist/types/src/components/GrProgressBar/defaults.d.ts +1 -1
- package/dist/types/src/components/GrProgressCircle/defaults.d.ts +1 -1
- package/dist/types/src/components/GrProgressCircle/grProgressCircleStyles.d.ts +1 -1
- package/dist/types/src/components/GrPromptDialog/defaults.d.ts +1 -1
- package/dist/types/src/components/GrRadio/defaults.d.ts +1 -1
- package/dist/types/src/components/GrRadio/grRadioGroupContext.d.ts +12 -4
- package/dist/types/src/components/GrRadioGroup/defaults.d.ts +1 -1
- package/dist/types/src/components/GrRating/GrRating.vue.d.ts +9 -4
- package/dist/types/src/components/GrRating/defaults.d.ts +1 -1
- package/dist/types/src/components/GrSegmented/defaults.d.ts +1 -1
- package/dist/types/src/components/GrSelect/defaults.d.ts +1 -1
- package/dist/types/src/components/GrSlider/defaults.d.ts +1 -1
- package/dist/types/src/components/GrSortableList/GrSortableList.vue.d.ts +68 -0
- package/dist/types/src/components/GrSortableList/config.d.ts +1 -0
- package/dist/types/src/components/GrSortableList/grSortableListStyles.d.ts +37 -0
- package/dist/types/src/components/GrSortableList/index.d.ts +9 -0
- package/dist/types/src/components/GrSortableList/safelist.d.ts +1 -0
- package/dist/types/src/components/GrSplitter/defaults.d.ts +1 -1
- package/dist/types/src/components/GrStatistic/GrStatistic.vue.d.ts +12 -9
- package/dist/types/src/components/GrStatistic/defaults.d.ts +1 -1
- package/dist/types/src/components/GrStatistic/grStatisticStyles.d.ts +1 -2
- package/dist/types/src/components/GrSwitch/defaults.d.ts +1 -1
- package/dist/types/src/components/GrTable/GrTable.vue.d.ts +13 -0
- package/dist/types/src/components/GrTable/defaults.d.ts +1 -1
- package/dist/types/src/components/GrTabs/GrTabs.vue.d.ts +6 -2
- package/dist/types/src/components/GrTabs/defaults.d.ts +1 -1
- package/dist/types/src/components/GrTextarea/defaults.d.ts +1 -1
- package/dist/types/src/components/GrTextarea/grTextareaStyles.d.ts +2 -2
- package/dist/types/src/components/GrTimeline/defaults.d.ts +1 -1
- package/dist/types/src/components/GrTimeline/grTimelineStyles.d.ts +1 -1
- package/dist/types/src/components/GrToaster/GrToaster.vue.d.ts +8 -0
- package/dist/types/src/components/GrToaster/grToasterStyles.d.ts +27 -0
- package/dist/types/src/components/GrTooltip/defaults.d.ts +1 -1
- package/dist/types/src/components/GrTree/defaults.d.ts +1 -1
- package/dist/types/src/components/GrTree/grTreeInteractionContext.d.ts +0 -1
- package/dist/types/src/components/GrTree/grTreeProps.d.ts +11 -4
- package/dist/types/src/components/GrTree/safelist.d.ts +1 -1
- package/dist/types/src/components/GrTreeSelect/defaults.d.ts +1 -1
- package/dist/types/src/components/shared/hotkey.d.ts +7 -15
- package/dist/types/src/components/shared/hotkeyTokens.d.ts +37 -0
- package/dist/types/src/components/shared/icon.d.ts +13 -0
- package/dist/types/src/composables/internal/dragSortGeometry.d.ts +59 -0
- package/dist/types/src/composables/internal/overlayStack.d.ts +11 -0
- package/dist/types/src/composables/useDragGesture.d.ts +63 -0
- package/dist/types/src/composables/useDragSort.d.ts +80 -0
- package/dist/types/src/composables/useFloating.d.ts +5 -1
- package/dist/types/src/composables/useGrComponentConfig.d.ts +41 -0
- package/dist/types/src/composables/useGranularityTranslations.d.ts +13 -0
- package/dist/types/src/composables/useRovingFocus.d.ts +108 -0
- package/dist/types/src/granular-provider/shared.d.ts +1 -0
- package/dist/types/src/i18n/messages/en.d.ts +48 -0
- package/dist/types/src/i18n/messages/es.d.ts +48 -0
- package/dist/types/src/i18n/messages/ru.d.ts +48 -0
- package/dist/types/src/index.d.ts +12 -0
- package/dist/types/src/internal/keyboard.d.ts +6 -0
- package/dist/types/src/testing/announcer.d.ts +10 -0
- package/dist/types/src/testing/context.d.ts +36 -0
- package/dist/types/src/testing/env.d.ts +25 -0
- package/dist/types/src/testing/geometry.d.ts +23 -0
- package/dist/types/src/testing/index.d.ts +12 -0
- package/dist/types/src/testing/pointer.d.ts +31 -0
- package/dist/types/src/theme/apply.d.ts +27 -0
- package/dist/types/src/theme/color.d.ts +35 -0
- package/dist/types/src/theme/extendTheme.d.ts +63 -0
- package/dist/types/src/theme/index.d.ts +22 -0
- package/dist/types/src/theme/roles.d.ts +16 -0
- package/dist/types/src/theme/tone.d.ts +32 -0
- package/dist/types/src/theme/validate.d.ts +16 -0
- package/dist/types/src/tokens/types.d.ts +8 -0
- package/dist/web-types.json +214 -13
- package/package.json +47 -4
- package/tokens/themes/dark.json +2 -1
- package/dist/chunks/chevron-right-BfqMVpbB.js.map +0 -1
- package/dist/chunks/config-8Pcutu1j.js.map +0 -1
- package/dist/chunks/config-B-g6lT19.js.map +0 -1
- package/dist/chunks/config-BE6n20np.js.map +0 -1
- package/dist/chunks/config-BKvX0q10.js.map +0 -1
- package/dist/chunks/config-BNfQwyL4.js +0 -97
- package/dist/chunks/config-BNfQwyL4.js.map +0 -1
- package/dist/chunks/config-BoNR7_PD.js.map +0 -1
- package/dist/chunks/config-CN2ULSQL2.js.map +0 -1
- package/dist/chunks/config-CY0_6cMi.js.map +0 -1
- package/dist/chunks/config-Cw6TDzWv2.js.map +0 -1
- package/dist/chunks/config-D8tSR2uS.js.map +0 -1
- package/dist/chunks/config-DpqOnJiz2.js.map +0 -1
- package/dist/chunks/config-DxCTVBfx.js.map +0 -1
- package/dist/chunks/config-LGrZIdaZ.js +0 -21
- package/dist/chunks/config-LGrZIdaZ.js.map +0 -1
- package/dist/chunks/config-Rw9OyW70.js.map +0 -1
- package/dist/chunks/config-T3qdQBgU.js.map +0 -1
- package/dist/chunks/config-eXB87DOi2.js.map +0 -1
- package/dist/chunks/en-B3xMeswz.js.map +0 -1
- package/dist/chunks/es-CA-mkU--.js.map +0 -1
- package/dist/chunks/grKbdStyles-DAoxiytu.js +0 -31
- package/dist/chunks/grKbdStyles-DAoxiytu.js.map +0 -1
- package/dist/chunks/granular-provider-CtrXGa7c.js.map +0 -1
- package/dist/chunks/keyboard-zYvvyHd4.js.map +0 -1
- package/dist/chunks/optionFilter-BVY988pC.js.map +0 -1
- package/dist/chunks/ru-COWxgh2A.js.map +0 -1
- package/dist/chunks/useOverlayLayer-BupuP_hs.js.map +0 -1
- package/dist/components/GrAutocomplete/chunks/GrAutocomplete-CQ9T7Lly.js.map +0 -1
- package/dist/components/GrBreadcrumbs/chunks/GrBreadcrumbs-BCNGDS6k.js.map +0 -1
- package/dist/components/GrCommandPalette/chunks/GrCommandPalette-MWDYDPNC.js.map +0 -1
- package/dist/components/GrDataTable/chunks/GrDataTable-DVFho9Cj.js.map +0 -1
- package/dist/components/GrImageViewer/chunks/GrImageViewer-BeCnE8XQ.js.map +0 -1
- package/dist/components/GrInput/chunks/GrInput-DD2gYdqS.js.map +0 -1
- package/dist/components/GrInputTag/chunks/GrInputTag-DmNunixz.js.map +0 -1
- package/dist/components/GrKbd/chunks/GrKbd-DRFPvW3G.js.map +0 -1
- package/dist/components/GrPagination/chunks/GrPagination-B6N0QZBf.js.map +0 -1
- package/dist/components/GrProgressBar/chunks/GrProgressBar-BiHnaitu.js.map +0 -1
- package/dist/components/GrRadio/chunks/GrRadio-DksDro_U.js.map +0 -1
- package/dist/components/GrRadioGroup/chunks/GrRadioGroup-BOIhejE6.js.map +0 -1
- package/dist/components/GrRating/chunks/GrRating-JrHXz0Rv.js.map +0 -1
- package/dist/components/GrSegmented/chunks/GrSegmented-BQIlH5KI.js.map +0 -1
- package/dist/components/GrSelect/chunks/GrSelect-aqkPCqjd.js.map +0 -1
- package/dist/components/GrSlider/chunks/GrSlider-DkU9IQSX.js.map +0 -1
- package/dist/components/GrSplitter/chunks/GrSplitter-7To8jbJ8.js.map +0 -1
- package/dist/components/GrStatistic/chunks/GrStatistic-CttyoYPT.js.map +0 -1
- package/dist/components/GrTable/chunks/GrTable-BB-mI_NM.js.map +0 -1
- package/dist/components/GrTabs/chunks/GrTabs-B8CDq2D9.js.map +0 -1
- package/dist/components/GrToaster/chunks/GrToaster-BKQy3Srm.js.map +0 -1
- package/dist/components/GrTree/chunks/GrTree-wfdbvygw.js.map +0 -1
- package/dist/components/GrTreeSelect/chunks/GrTreeSelect-lLWmAMtI.js.map +0 -1
- package/dist/tokens.js.map +0 -1
- package/dist/chunks/{config-8Pcutu1j.js → config-8Pcutu1j2.js} +0 -0
- package/dist/chunks/{config-BE6n20np.js → config-BE6n20np2.js} +0 -0
- package/dist/chunks/{config-BKvX0q10.js → config-BKvX0q102.js} +0 -0
- package/dist/chunks/{config-BoNR7_PD.js → config-BoNR7_PD2.js} +0 -0
- package/dist/chunks/{config-CN2ULSQL2.js → config-CN2ULSQL.js} +0 -0
- package/dist/chunks/{config-CY0_6cMi.js → config-CY0_6cMi2.js} +0 -0
- package/dist/chunks/{config-Rw9OyW70.js → config-Rw9OyW702.js} +0 -0
- package/dist/chunks/{config-T3qdQBgU.js → config-T3qdQBgU2.js} +0 -0
- package/dist/chunks/{config-eXB87DOi2.js → config-eXB87DOi.js} +0 -0
- package/dist/components/GrCollapse/chunks/{GrCollapse-B2Fc6A9r.js → GrCollapse-Kk0DE8tb.js} +1 -1
- /package/dist/types/src/composables/{internal/useComboboxNavigation.d.ts → useComboboxNavigation.d.ts} +0 -0
package/dist/components/GrTimeline/chunks/{GrTimeline-CE9b3s18.js.map → GrTimeline-B-h2Yanw.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrTimeline-CE9b3s18.js","names":["$slots"],"sources":["../../../../src/components/GrTimeline/grTimelineContext.ts","../../../../src/components/GrTimeline/timelineGroups.ts","../../../../src/components/GrTimeline/GrTimeline.vue","../../../../src/components/GrTimeline/GrTimeline.vue","../../../../src/components/GrTimeline/GrTimelineItem.vue","../../../../src/components/GrTimeline/GrTimelineItem.vue"],"sourcesContent":["import type { ComputedRef, InjectionKey } from 'vue'\n\nimport type { GrTimelineDensity, GrTimelineLayout, GrTimelineOrientation } from './grTimelineStyles'\n\n/**\n * Уровень заголовка группы. Тот же довод, что у `GrCollapse`: лента в разделе\n * `<h4>` с захардкоженным `<h3>` рвёт навигацию по заголовкам.\n */\nexport const GR_TIMELINE_HEADING_LEVELS = [2, 3, 4, 5, 6] as const\n\nexport type GrTimelineHeadingLevel = typeof GR_TIMELINE_HEADING_LEVELS[number]\n\n/**\n * Пункт читает раскладку из контейнера, а не получает её пропом: иначе\n * `layout` пришлось бы дублировать на каждом `GrTimelineItem`.\n */\nexport interface GrTimelineContext {\n layout: ComputedRef<GrTimelineLayout>\n orientation: ComputedRef<GrTimelineOrientation>\n density: ComputedRef<GrTimelineDensity>\n}\n\nexport const GR_TIMELINE_CONTEXT: InjectionKey<GrTimelineContext> = Symbol('GR_TIMELINE_CONTEXT')\n","/**\n * Группировка ленты событий. Без Vue — чтобы проверялась без монтирования.\n */\n\nexport type GrTimelineGroupBy<T> = string | ((item: T, index: number) => string)\n\n/** Пункт вместе с его позицией в исходном наборе: ключи `v-for` считаются от неё. */\nexport interface GrTimelineEntry<T> {\n item: T\n index: number\n}\n\nexport interface GrTimelineGroup<T> {\n /** Ключ группы. Пустая строка — заголовка у группы нет. */\n key: string\n entries: GrTimelineEntry<T>[]\n}\n\nfunction keyOf<T>(item: T, index: number, groupBy: GrTimelineGroupBy<T>): string {\n if (typeof groupBy === 'function')\n return String(groupBy(item, index) ?? '')\n\n const value = (item as Record<string, unknown> | null | undefined)?.[groupBy]\n\n // `undefined` в поле — это «группы нет», а не группа с надписью «undefined».\n return value == null ? '' : String(value)\n}\n\n/**\n * Режет набор на группы, **не меняя порядок**: лента хронологична, и\n * пересортировать её компонент не вправе. Порядок групп — порядок первого\n * вхождения ключа; разорванная группа (`A B A`) собирается в одну.\n *\n * Без `groupBy` — одна безымянная группа: плоская лента остаётся частным\n * случаем, и второй ветки рендера у компонента не появляется.\n */\nexport function groupTimelineItems<T>(\n items: readonly T[],\n groupBy?: GrTimelineGroupBy<T>,\n): GrTimelineGroup<T>[] {\n const entries = items.map((item, index) => ({ item, index }))\n\n if (groupBy === undefined)\n return entries.length === 0 ? [] : [{ key: '', entries }]\n\n const byKey = new Map<string, GrTimelineGroup<T>>()\n\n for (const entry of entries) {\n const key = keyOf(entry.item, entry.index, groupBy)\n const group = byKey.get(key)\n\n if (group)\n group.entries.push(entry)\n else\n byKey.set(key, { key, entries: [entry] })\n }\n\n return [...byKey.values()]\n}\n","<script setup lang=\"ts\" generic=\"T = unknown\">\nimport { computed, provide, useSlots, watch } from 'vue'\n\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { hasMeaningfulSlotContent } from '../shared/slotNodes'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport { GR_TIMELINE_CONTEXT, type GrTimelineHeadingLevel } from './grTimelineContext'\nimport {\n emptyClass,\n groupTitleClass,\n loadingRowClass,\n type GrTimelineDensity,\n type GrTimelineLayout,\n type GrTimelineOrientation,\n} from './grTimelineStyles'\nimport { groupTimelineItems, type GrTimelineGroupBy } from './timelineGroups'\n\nexport type {\n GrTimelineDensity,\n GrTimelineLayout,\n GrTimelineOrientation,\n} from './grTimelineStyles'\nexport type { GrTimelineGroupBy } from './timelineGroups'\n\nexport interface GrTimelineProps<TItem = unknown> {\n /**\n * Данные ленты. С ними пункты рисует слот `#item` — и только так лента знает\n * состав набора, то есть может его группировать.\n */\n items?: TItem[]\n /** Ключ пункта для `v-for`: имя поля или функция. Без него — индекс. */\n itemKey?: string | ((item: TItem, index: number) => string | number)\n /** Группировка: имя поля или функция от пункта. Заголовок группы — слот `#group`. */\n groupBy?: GrTimelineGroupBy<TItem>\n /** Уровень заголовка группы: лента обязана вписаться в структуру заголовков страницы. */\n groupHeadingLevel?: GrTimelineHeadingLevel\n /** Раскладка: одна ось, колонка времени слева или чередование сторон. */\n layout?: GrTimelineLayout\n /** Направление оси. Горизонтальная лента — скроллер. */\n orientation?: GrTimelineOrientation\n /** Плотность вертикальных отступов пункта. */\n density?: GrTimelineDensity\n /** Идёт загрузка: вместо пунктов — заглушки, контейнер помечен `aria-busy`. */\n loading?: boolean\n /** Сколько строк-заглушек показать при `loading`. */\n loadingRows?: number\n /**\n * Лента пуста. По умолчанию определяется сама — по данным или по слоту; проп\n * нужен там, где потребитель знает лучше.\n */\n empty?: boolean\n /** Текст пустого состояния. Слот `#empty` сильнее. */\n emptyText?: string\n}\n\nconst props = withDefaults(defineProps<GrTimelineProps<T>>(), {\n items: undefined,\n itemKey: undefined,\n groupBy: undefined,\n // Настоящие дефолты живут в резолверах `useGrComponentProp`: объявленный здесь\n // дефолт неотличим от значения, переданного потребителем, и перебивал бы конфиг.\n groupHeadingLevel: undefined,\n layout: undefined,\n orientation: undefined,\n density: undefined,\n loading: false,\n loadingRows: 3,\n empty: undefined,\n emptyText: undefined,\n})\n\ndefineSlots<{\n /** Пункты ленты (`GrTimelineItem`), когда данные не переданы пропом. */\n default?: () => any\n /** Пункт в data-режиме. */\n item?: (props: { item: T, index: number }) => any\n /** Заголовок группы. По умолчанию — сам ключ. */\n group?: (props: { group: string, items: T[] }) => any\n /** Содержимое пустого состояния вместо текста по умолчанию. */\n empty?: () => any\n /** Заглушки загрузки вместо строк по умолчанию. */\n loading?: () => any\n}>()\n\nconst slots = useSlots()\nconst { t } = useGranularityTranslations()\n\nconst density = useGrComponentProp('GrTimeline', 'density', () => props.density, 'regular')\nconst orientation = useGrComponentProp('GrTimeline', 'orientation', () => props.orientation, 'vertical')\nconst headingLevel = useGrComponentProp('GrTimeline', 'groupHeadingLevel', () => props.groupHeadingLevel, 3)\nconst requestedLayout = useGrComponentProp('GrTimeline', 'layout', () => props.layout, 'stacked')\n\n/**\n * Горизонтальная лента знает одну раскладку: колонка времени и чередование\n * сторон — это вертикальные приёмы, у горизонтальной оси сторон нет.\n */\nconst layout = computed<GrTimelineLayout>(() => (\n orientation.value === 'horizontal' ? 'stacked' : requestedLayout.value\n))\n\nconst headingTag = computed(() => `h${headingLevel.value}`)\n\nconst dataMode = computed(() => props.items !== undefined)\n\nconst grouped = computed(() => dataMode.value && props.groupBy !== undefined)\n\nconst groups = computed(() => groupTimelineItems(props.items ?? [], props.groupBy))\n\n/** Единственная группа плоской ленты: тот же набор, что и в data-режиме без группировки. */\nconst entries = computed(() => groups.value[0]?.entries ?? [])\n\nconst resolvedEmptyText = computed(() => props.emptyText ?? t('gr.timeline.empty', 'Nothing here yet'))\n\nconst isEmpty = computed(() => {\n if (props.empty !== undefined) return props.empty\n\n if (dataMode.value) return props.items!.length === 0\n\n // `v-for` по пустому массиву оставляет фрагмент без узлов, `v-if` — комментарий,\n // и ни то ни другое пунктом ленты не является.\n return !hasMeaningfulSlotContent(slots.default?.() ?? [])\n})\n\nconst loadingRowCount = computed(() => Math.max(1, Math.trunc(props.loadingRows)))\n\nfunction keyOf(item: T, index: number): string | number {\n const key = props.itemKey\n if (typeof key === 'function') return key(item, index)\n if (typeof key === 'string') return (item as Record<string, unknown>)[key] as string | number\n\n return index\n}\n\nfunction itemsOf(group: { entries: { item: T }[] }): T[] {\n return group.entries.map(entry => entry.item)\n}\n\nprovide(GR_TIMELINE_CONTEXT, { layout, orientation, density })\n\nif (import.meta.env?.DEV) {\n watch(\n () => [dataMode.value, Boolean(slots.item)] as const,\n ([hasItems, hasSlot]) => {\n if (hasItems && !hasSlot) {\n console.warn(\n '[granularity] GrTimeline: с `items` пункты рисует слот `#item` — без него лента пуста.',\n )\n }\n },\n { immediate: true },\n )\n\n watch(\n () => [dataMode.value, props.groupBy !== undefined] as const,\n ([hasItems, hasGroupBy]) => {\n if (hasGroupBy && !hasItems) {\n console.warn(\n '[granularity] GrTimeline: `groupBy` работает только с `items` — пункты из слота по '\n + 'умолчанию лента не разбирает и сгруппировать их ей не из чего.',\n )\n }\n },\n { immediate: true },\n )\n\n watch(\n () => [orientation.value, requestedLayout.value] as const,\n ([axis, requested]) => {\n if (axis === 'horizontal' && requested !== 'stacked') {\n console.warn(\n `[granularity] GrTimeline: layout=\"${requested}\" — вертикальная раскладка, `\n + 'в горизонтальной ленте она игнорируется.',\n )\n }\n },\n { immediate: true },\n )\n}\n</script>\n\n<template>\n <div\n data-gr-timeline\n :data-layout=\"layout\"\n :data-orientation=\"orientation\"\n :aria-busy=\"loading ? 'true' : undefined\"\n >\n <template v-if=\"loading\">\n <slot name=\"loading\">\n <div\n v-for=\"row in loadingRowCount\"\n :key=\"row\"\n data-gr-timeline-loading-row\n :class=\"loadingRowClass\"\n >\n <GrSkeleton variant=\"circle\" width=\"var(--gr-timeline-marker-size, 10px)\" />\n <GrSkeleton />\n </div>\n </slot>\n </template>\n\n <div\n v-else-if=\"isEmpty\"\n data-gr-timeline-empty\n :class=\"emptyClass\"\n >\n <slot name=\"empty\">\n {{ resolvedEmptyText }}\n </slot>\n </div>\n\n <template v-else-if=\"grouped\">\n <!--\n Группа — секция с заголовком, а не пункт-заголовок внутри списка:\n `<li>` с датой попал бы в набор событий и был бы объявлен как одно из них.\n -->\n <section\n v-for=\"group in groups\"\n :key=\"group.key\"\n data-gr-timeline-group\n >\n <div\n v-if=\"group.key\"\n data-gr-timeline-group-header\n >\n <div data-gr-timeline-rail aria-hidden=\"true\">\n <span data-gr-timeline-line />\n </div>\n\n <component\n :is=\"headingTag\"\n data-gr-timeline-group-title\n :class=\"groupTitleClass\"\n >\n <slot name=\"group\" :group=\"group.key\" :items=\"itemsOf(group)\">\n {{ group.key }}\n </slot>\n </component>\n </div>\n\n <ol\n data-gr-timeline-list\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n >\n <template\n v-for=\"entry in group.entries\"\n :key=\"keyOf(entry.item, entry.index)\"\n >\n <slot name=\"item\" :item=\"entry.item\" :index=\"entry.index\" />\n </template>\n </ol>\n </section>\n </template>\n\n <ol\n v-else\n data-gr-timeline-list\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n >\n <template v-if=\"dataMode\">\n <template\n v-for=\"entry in entries\"\n :key=\"keyOf(entry.item, entry.index)\"\n >\n <slot name=\"item\" :item=\"entry.item\" :index=\"entry.index\" />\n </template>\n </template>\n\n <slot v-else />\n </ol>\n </div>\n</template>\n\n<style>\n/*\n * Геометрия ленты живёт здесь, а не в утилитах, по одной причине: сторона\n * пункта в `alternate` — это `nth-child`, а обрыв оси — `last-child`, и оба\n * вопроса утилитами не выражаются. Альтернатива — регистрация пунктов в\n * контексте на `onMounted` — дала бы порядок, зависящий от порядка монтирования,\n * и разъезжалась бы на `v-if` посреди ленты.\n */\n\n[data-gr-timeline] {\n --gr-timeline-columns: auto 1fr;\n}\n\n[data-gr-timeline][data-layout='time'] {\n --gr-timeline-columns: var(--gr-timeline-time-width, 5.5rem) auto 1fr;\n}\n\n[data-gr-timeline][data-layout='alternate'] {\n --gr-timeline-columns: 1fr auto 1fr;\n}\n\n[data-gr-timeline-list] {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n[data-gr-timeline-item],\n[data-gr-timeline-group-header] {\n display: grid;\n grid-template-columns: var(--gr-timeline-columns);\n column-gap: var(--gr-timeline-gap, 0.75rem);\n align-items: start;\n}\n\n[data-gr-timeline-aside] {\n text-align: end;\n}\n\n/*\n * Ось — отрезок у каждого пункта, а не одна длинная линия: соседние отрезки\n * смыкаются сами, и мерить высоту списка не приходится.\n */\n[data-gr-timeline-rail] {\n display: flex;\n flex-direction: column;\n align-items: center;\n align-self: stretch;\n padding-top: var(--gr-timeline-marker-top, 0.35rem);\n}\n\n[data-gr-timeline-rail] > :first-child {\n flex: none;\n}\n\n[data-gr-timeline-marker] {\n box-sizing: border-box;\n width: var(--gr-timeline-marker-size, 10px);\n height: var(--gr-timeline-marker-size, 10px);\n border-width: var(--gr-timeline-marker-ring, 2px);\n border-style: solid;\n border-color: transparent;\n}\n\n[data-gr-timeline-line] {\n flex: 1 1 auto;\n width: var(--gr-timeline-axis-width, 2px);\n min-height: var(--gr-timeline-line-min, 0.75rem);\n margin-top: 0.25rem;\n /* Ровно на столько следующая точка отступает от верха своей строки: без этого\n отрезок не доходит до неё, и ось выглядит пунктиром из длинных штрихов. */\n margin-bottom: calc(-1 * var(--gr-timeline-marker-top, 0.35rem));\n background-color: var(--gr-timeline-axis-color, var(--gr-brd));\n}\n\n/*\n * Пунктиром идёт участок, ведущий **к** незавершённому событию, и всё, что за\n * ним: непройденный путь. Отрезок после точки для этого не годится — обычно\n * незавершённое событие последнее, и его отрезка не видно вовсе.\n */\n[data-gr-timeline-item]:has(+ [data-gr-timeline-item][data-pending]) [data-gr-timeline-line],\n[data-gr-timeline-item][data-pending] [data-gr-timeline-line] {\n background-color: transparent;\n background-image: repeating-linear-gradient(\n to bottom,\n var(--gr-timeline-axis-color, var(--gr-brd)) 0 var(--gr-timeline-dash, 4px),\n transparent var(--gr-timeline-dash, 4px) calc(var(--gr-timeline-dash, 4px) * 2)\n );\n}\n\n/* Хвост после последнего события — линия в никуда. */\n[data-gr-timeline-item]:last-child [data-gr-timeline-line] {\n visibility: hidden;\n}\n\n/* Между группами ось не рвётся: разрыв читался бы как две разные ленты. */\n[data-gr-timeline-group]:not(:last-of-type) [data-gr-timeline-item]:last-child [data-gr-timeline-line] {\n visibility: visible;\n}\n\n[data-gr-timeline-group-header] [data-gr-timeline-rail] {\n padding-top: 0;\n}\n\n/* Воздух перед заголовком — отступом строки, а не полем: поле разорвало бы ось. */\n[data-gr-timeline-group] + [data-gr-timeline-group] [data-gr-timeline-group-header] {\n padding-top: 0.5rem;\n}\n\n[data-gr-timeline-group-header] [data-gr-timeline-line] {\n margin-top: 0;\n}\n\n/* Над первым заголовком оси ещё нет — линия висела бы в воздухе. */\n[data-gr-timeline-group]:first-of-type [data-gr-timeline-group-header] [data-gr-timeline-line] {\n visibility: hidden;\n}\n\n[data-gr-timeline][data-layout='time'] [data-gr-timeline-group-header] [data-gr-timeline-rail],\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-header] [data-gr-timeline-rail] {\n grid-column: 2;\n}\n\n[data-gr-timeline][data-layout='time'] [data-gr-timeline-group-title],\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-title] {\n grid-column: 3;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-rail] {\n grid-column: 2;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-content] {\n grid-column: 3;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-item]:nth-child(even) [data-gr-timeline-content] {\n grid-column: 1;\n grid-row: 1;\n text-align: end;\n}\n\n/* Двухсторонняя лента в узкой колонке нечитаема — там она односторонняя. */\n@media (max-width: 640px) {\n [data-gr-timeline][data-layout='alternate'] {\n --gr-timeline-columns: auto 1fr;\n }\n\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-rail],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-header] [data-gr-timeline-rail] {\n grid-column: 1;\n }\n\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-content],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-item]:nth-child(even) [data-gr-timeline-content],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-title] {\n grid-column: 2;\n text-align: start;\n }\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-list] {\n display: flex;\n flex-direction: row;\n overflow-x: auto;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item] {\n grid-template-columns: 1fr;\n min-width: var(--gr-timeline-item-min-width, 12rem);\n padding-inline-end: var(--gr-timeline-gap, 0.75rem);\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-content] {\n padding-bottom: 0;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-rail] {\n flex-direction: row;\n align-items: center;\n align-self: auto;\n padding-top: 0;\n padding-bottom: 0.25rem;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-line] {\n width: auto;\n height: var(--gr-timeline-axis-width, 2px);\n min-width: var(--gr-timeline-line-min, 0.75rem);\n min-height: 0;\n margin-top: 0;\n margin-inline-start: 0.25rem;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item]:has(+ [data-gr-timeline-item][data-pending]) [data-gr-timeline-line],\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item][data-pending] [data-gr-timeline-line] {\n background-image: repeating-linear-gradient(\n to right,\n var(--gr-timeline-axis-color, var(--gr-brd)) 0 var(--gr-timeline-dash, 4px),\n transparent var(--gr-timeline-dash, 4px) calc(var(--gr-timeline-dash, 4px) * 2)\n );\n}\n</style>\n","<script setup lang=\"ts\" generic=\"T = unknown\">\nimport { computed, provide, useSlots, watch } from 'vue'\n\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { hasMeaningfulSlotContent } from '../shared/slotNodes'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport { GR_TIMELINE_CONTEXT, type GrTimelineHeadingLevel } from './grTimelineContext'\nimport {\n emptyClass,\n groupTitleClass,\n loadingRowClass,\n type GrTimelineDensity,\n type GrTimelineLayout,\n type GrTimelineOrientation,\n} from './grTimelineStyles'\nimport { groupTimelineItems, type GrTimelineGroupBy } from './timelineGroups'\n\nexport type {\n GrTimelineDensity,\n GrTimelineLayout,\n GrTimelineOrientation,\n} from './grTimelineStyles'\nexport type { GrTimelineGroupBy } from './timelineGroups'\n\nexport interface GrTimelineProps<TItem = unknown> {\n /**\n * Данные ленты. С ними пункты рисует слот `#item` — и только так лента знает\n * состав набора, то есть может его группировать.\n */\n items?: TItem[]\n /** Ключ пункта для `v-for`: имя поля или функция. Без него — индекс. */\n itemKey?: string | ((item: TItem, index: number) => string | number)\n /** Группировка: имя поля или функция от пункта. Заголовок группы — слот `#group`. */\n groupBy?: GrTimelineGroupBy<TItem>\n /** Уровень заголовка группы: лента обязана вписаться в структуру заголовков страницы. */\n groupHeadingLevel?: GrTimelineHeadingLevel\n /** Раскладка: одна ось, колонка времени слева или чередование сторон. */\n layout?: GrTimelineLayout\n /** Направление оси. Горизонтальная лента — скроллер. */\n orientation?: GrTimelineOrientation\n /** Плотность вертикальных отступов пункта. */\n density?: GrTimelineDensity\n /** Идёт загрузка: вместо пунктов — заглушки, контейнер помечен `aria-busy`. */\n loading?: boolean\n /** Сколько строк-заглушек показать при `loading`. */\n loadingRows?: number\n /**\n * Лента пуста. По умолчанию определяется сама — по данным или по слоту; проп\n * нужен там, где потребитель знает лучше.\n */\n empty?: boolean\n /** Текст пустого состояния. Слот `#empty` сильнее. */\n emptyText?: string\n}\n\nconst props = withDefaults(defineProps<GrTimelineProps<T>>(), {\n items: undefined,\n itemKey: undefined,\n groupBy: undefined,\n // Настоящие дефолты живут в резолверах `useGrComponentProp`: объявленный здесь\n // дефолт неотличим от значения, переданного потребителем, и перебивал бы конфиг.\n groupHeadingLevel: undefined,\n layout: undefined,\n orientation: undefined,\n density: undefined,\n loading: false,\n loadingRows: 3,\n empty: undefined,\n emptyText: undefined,\n})\n\ndefineSlots<{\n /** Пункты ленты (`GrTimelineItem`), когда данные не переданы пропом. */\n default?: () => any\n /** Пункт в data-режиме. */\n item?: (props: { item: T, index: number }) => any\n /** Заголовок группы. По умолчанию — сам ключ. */\n group?: (props: { group: string, items: T[] }) => any\n /** Содержимое пустого состояния вместо текста по умолчанию. */\n empty?: () => any\n /** Заглушки загрузки вместо строк по умолчанию. */\n loading?: () => any\n}>()\n\nconst slots = useSlots()\nconst { t } = useGranularityTranslations()\n\nconst density = useGrComponentProp('GrTimeline', 'density', () => props.density, 'regular')\nconst orientation = useGrComponentProp('GrTimeline', 'orientation', () => props.orientation, 'vertical')\nconst headingLevel = useGrComponentProp('GrTimeline', 'groupHeadingLevel', () => props.groupHeadingLevel, 3)\nconst requestedLayout = useGrComponentProp('GrTimeline', 'layout', () => props.layout, 'stacked')\n\n/**\n * Горизонтальная лента знает одну раскладку: колонка времени и чередование\n * сторон — это вертикальные приёмы, у горизонтальной оси сторон нет.\n */\nconst layout = computed<GrTimelineLayout>(() => (\n orientation.value === 'horizontal' ? 'stacked' : requestedLayout.value\n))\n\nconst headingTag = computed(() => `h${headingLevel.value}`)\n\nconst dataMode = computed(() => props.items !== undefined)\n\nconst grouped = computed(() => dataMode.value && props.groupBy !== undefined)\n\nconst groups = computed(() => groupTimelineItems(props.items ?? [], props.groupBy))\n\n/** Единственная группа плоской ленты: тот же набор, что и в data-режиме без группировки. */\nconst entries = computed(() => groups.value[0]?.entries ?? [])\n\nconst resolvedEmptyText = computed(() => props.emptyText ?? t('gr.timeline.empty', 'Nothing here yet'))\n\nconst isEmpty = computed(() => {\n if (props.empty !== undefined) return props.empty\n\n if (dataMode.value) return props.items!.length === 0\n\n // `v-for` по пустому массиву оставляет фрагмент без узлов, `v-if` — комментарий,\n // и ни то ни другое пунктом ленты не является.\n return !hasMeaningfulSlotContent(slots.default?.() ?? [])\n})\n\nconst loadingRowCount = computed(() => Math.max(1, Math.trunc(props.loadingRows)))\n\nfunction keyOf(item: T, index: number): string | number {\n const key = props.itemKey\n if (typeof key === 'function') return key(item, index)\n if (typeof key === 'string') return (item as Record<string, unknown>)[key] as string | number\n\n return index\n}\n\nfunction itemsOf(group: { entries: { item: T }[] }): T[] {\n return group.entries.map(entry => entry.item)\n}\n\nprovide(GR_TIMELINE_CONTEXT, { layout, orientation, density })\n\nif (import.meta.env?.DEV) {\n watch(\n () => [dataMode.value, Boolean(slots.item)] as const,\n ([hasItems, hasSlot]) => {\n if (hasItems && !hasSlot) {\n console.warn(\n '[granularity] GrTimeline: с `items` пункты рисует слот `#item` — без него лента пуста.',\n )\n }\n },\n { immediate: true },\n )\n\n watch(\n () => [dataMode.value, props.groupBy !== undefined] as const,\n ([hasItems, hasGroupBy]) => {\n if (hasGroupBy && !hasItems) {\n console.warn(\n '[granularity] GrTimeline: `groupBy` работает только с `items` — пункты из слота по '\n + 'умолчанию лента не разбирает и сгруппировать их ей не из чего.',\n )\n }\n },\n { immediate: true },\n )\n\n watch(\n () => [orientation.value, requestedLayout.value] as const,\n ([axis, requested]) => {\n if (axis === 'horizontal' && requested !== 'stacked') {\n console.warn(\n `[granularity] GrTimeline: layout=\"${requested}\" — вертикальная раскладка, `\n + 'в горизонтальной ленте она игнорируется.',\n )\n }\n },\n { immediate: true },\n )\n}\n</script>\n\n<template>\n <div\n data-gr-timeline\n :data-layout=\"layout\"\n :data-orientation=\"orientation\"\n :aria-busy=\"loading ? 'true' : undefined\"\n >\n <template v-if=\"loading\">\n <slot name=\"loading\">\n <div\n v-for=\"row in loadingRowCount\"\n :key=\"row\"\n data-gr-timeline-loading-row\n :class=\"loadingRowClass\"\n >\n <GrSkeleton variant=\"circle\" width=\"var(--gr-timeline-marker-size, 10px)\" />\n <GrSkeleton />\n </div>\n </slot>\n </template>\n\n <div\n v-else-if=\"isEmpty\"\n data-gr-timeline-empty\n :class=\"emptyClass\"\n >\n <slot name=\"empty\">\n {{ resolvedEmptyText }}\n </slot>\n </div>\n\n <template v-else-if=\"grouped\">\n <!--\n Группа — секция с заголовком, а не пункт-заголовок внутри списка:\n `<li>` с датой попал бы в набор событий и был бы объявлен как одно из них.\n -->\n <section\n v-for=\"group in groups\"\n :key=\"group.key\"\n data-gr-timeline-group\n >\n <div\n v-if=\"group.key\"\n data-gr-timeline-group-header\n >\n <div data-gr-timeline-rail aria-hidden=\"true\">\n <span data-gr-timeline-line />\n </div>\n\n <component\n :is=\"headingTag\"\n data-gr-timeline-group-title\n :class=\"groupTitleClass\"\n >\n <slot name=\"group\" :group=\"group.key\" :items=\"itemsOf(group)\">\n {{ group.key }}\n </slot>\n </component>\n </div>\n\n <ol\n data-gr-timeline-list\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n >\n <template\n v-for=\"entry in group.entries\"\n :key=\"keyOf(entry.item, entry.index)\"\n >\n <slot name=\"item\" :item=\"entry.item\" :index=\"entry.index\" />\n </template>\n </ol>\n </section>\n </template>\n\n <ol\n v-else\n data-gr-timeline-list\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n >\n <template v-if=\"dataMode\">\n <template\n v-for=\"entry in entries\"\n :key=\"keyOf(entry.item, entry.index)\"\n >\n <slot name=\"item\" :item=\"entry.item\" :index=\"entry.index\" />\n </template>\n </template>\n\n <slot v-else />\n </ol>\n </div>\n</template>\n\n<style>\n/*\n * Геометрия ленты живёт здесь, а не в утилитах, по одной причине: сторона\n * пункта в `alternate` — это `nth-child`, а обрыв оси — `last-child`, и оба\n * вопроса утилитами не выражаются. Альтернатива — регистрация пунктов в\n * контексте на `onMounted` — дала бы порядок, зависящий от порядка монтирования,\n * и разъезжалась бы на `v-if` посреди ленты.\n */\n\n[data-gr-timeline] {\n --gr-timeline-columns: auto 1fr;\n}\n\n[data-gr-timeline][data-layout='time'] {\n --gr-timeline-columns: var(--gr-timeline-time-width, 5.5rem) auto 1fr;\n}\n\n[data-gr-timeline][data-layout='alternate'] {\n --gr-timeline-columns: 1fr auto 1fr;\n}\n\n[data-gr-timeline-list] {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n[data-gr-timeline-item],\n[data-gr-timeline-group-header] {\n display: grid;\n grid-template-columns: var(--gr-timeline-columns);\n column-gap: var(--gr-timeline-gap, 0.75rem);\n align-items: start;\n}\n\n[data-gr-timeline-aside] {\n text-align: end;\n}\n\n/*\n * Ось — отрезок у каждого пункта, а не одна длинная линия: соседние отрезки\n * смыкаются сами, и мерить высоту списка не приходится.\n */\n[data-gr-timeline-rail] {\n display: flex;\n flex-direction: column;\n align-items: center;\n align-self: stretch;\n padding-top: var(--gr-timeline-marker-top, 0.35rem);\n}\n\n[data-gr-timeline-rail] > :first-child {\n flex: none;\n}\n\n[data-gr-timeline-marker] {\n box-sizing: border-box;\n width: var(--gr-timeline-marker-size, 10px);\n height: var(--gr-timeline-marker-size, 10px);\n border-width: var(--gr-timeline-marker-ring, 2px);\n border-style: solid;\n border-color: transparent;\n}\n\n[data-gr-timeline-line] {\n flex: 1 1 auto;\n width: var(--gr-timeline-axis-width, 2px);\n min-height: var(--gr-timeline-line-min, 0.75rem);\n margin-top: 0.25rem;\n /* Ровно на столько следующая точка отступает от верха своей строки: без этого\n отрезок не доходит до неё, и ось выглядит пунктиром из длинных штрихов. */\n margin-bottom: calc(-1 * var(--gr-timeline-marker-top, 0.35rem));\n background-color: var(--gr-timeline-axis-color, var(--gr-brd));\n}\n\n/*\n * Пунктиром идёт участок, ведущий **к** незавершённому событию, и всё, что за\n * ним: непройденный путь. Отрезок после точки для этого не годится — обычно\n * незавершённое событие последнее, и его отрезка не видно вовсе.\n */\n[data-gr-timeline-item]:has(+ [data-gr-timeline-item][data-pending]) [data-gr-timeline-line],\n[data-gr-timeline-item][data-pending] [data-gr-timeline-line] {\n background-color: transparent;\n background-image: repeating-linear-gradient(\n to bottom,\n var(--gr-timeline-axis-color, var(--gr-brd)) 0 var(--gr-timeline-dash, 4px),\n transparent var(--gr-timeline-dash, 4px) calc(var(--gr-timeline-dash, 4px) * 2)\n );\n}\n\n/* Хвост после последнего события — линия в никуда. */\n[data-gr-timeline-item]:last-child [data-gr-timeline-line] {\n visibility: hidden;\n}\n\n/* Между группами ось не рвётся: разрыв читался бы как две разные ленты. */\n[data-gr-timeline-group]:not(:last-of-type) [data-gr-timeline-item]:last-child [data-gr-timeline-line] {\n visibility: visible;\n}\n\n[data-gr-timeline-group-header] [data-gr-timeline-rail] {\n padding-top: 0;\n}\n\n/* Воздух перед заголовком — отступом строки, а не полем: поле разорвало бы ось. */\n[data-gr-timeline-group] + [data-gr-timeline-group] [data-gr-timeline-group-header] {\n padding-top: 0.5rem;\n}\n\n[data-gr-timeline-group-header] [data-gr-timeline-line] {\n margin-top: 0;\n}\n\n/* Над первым заголовком оси ещё нет — линия висела бы в воздухе. */\n[data-gr-timeline-group]:first-of-type [data-gr-timeline-group-header] [data-gr-timeline-line] {\n visibility: hidden;\n}\n\n[data-gr-timeline][data-layout='time'] [data-gr-timeline-group-header] [data-gr-timeline-rail],\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-header] [data-gr-timeline-rail] {\n grid-column: 2;\n}\n\n[data-gr-timeline][data-layout='time'] [data-gr-timeline-group-title],\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-title] {\n grid-column: 3;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-rail] {\n grid-column: 2;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-content] {\n grid-column: 3;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-item]:nth-child(even) [data-gr-timeline-content] {\n grid-column: 1;\n grid-row: 1;\n text-align: end;\n}\n\n/* Двухсторонняя лента в узкой колонке нечитаема — там она односторонняя. */\n@media (max-width: 640px) {\n [data-gr-timeline][data-layout='alternate'] {\n --gr-timeline-columns: auto 1fr;\n }\n\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-rail],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-header] [data-gr-timeline-rail] {\n grid-column: 1;\n }\n\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-content],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-item]:nth-child(even) [data-gr-timeline-content],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-title] {\n grid-column: 2;\n text-align: start;\n }\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-list] {\n display: flex;\n flex-direction: row;\n overflow-x: auto;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item] {\n grid-template-columns: 1fr;\n min-width: var(--gr-timeline-item-min-width, 12rem);\n padding-inline-end: var(--gr-timeline-gap, 0.75rem);\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-content] {\n padding-bottom: 0;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-rail] {\n flex-direction: row;\n align-items: center;\n align-self: auto;\n padding-top: 0;\n padding-bottom: 0.25rem;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-line] {\n width: auto;\n height: var(--gr-timeline-axis-width, 2px);\n min-width: var(--gr-timeline-line-min, 0.75rem);\n min-height: 0;\n margin-top: 0;\n margin-inline-start: 0.25rem;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item]:has(+ [data-gr-timeline-item][data-pending]) [data-gr-timeline-line],\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item][data-pending] [data-gr-timeline-line] {\n background-image: repeating-linear-gradient(\n to right,\n var(--gr-timeline-axis-color, var(--gr-brd)) 0 var(--gr-timeline-dash, 4px),\n transparent var(--gr-timeline-dash, 4px) calc(var(--gr-timeline-dash, 4px) * 2)\n );\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, inject, useSlots } from 'vue'\n\nimport { GR_TIMELINE_CONTEXT } from './grTimelineContext'\nimport {\n descriptionClass,\n grTimelineDensityClass,\n grTimelineMarkerClass,\n timeClass,\n titleClass,\n type GrTimelineMarkerVariant,\n type GrTimelineTone,\n} from './grTimelineStyles'\n\nexport type { GrTimelineMarkerVariant, GrTimelineTone } from './grTimelineStyles'\n\nexport interface GrTimelineItemProps {\n /** Метка времени. Слот `#time` сильнее. */\n time?: string\n /** Машиночитаемое значение метки: попадает в `datetime` тега `<time>`. */\n datetime?: string\n /** Заголовок события. Слот `#title` сильнее. */\n title?: string\n /** Пояснение под заголовком. Слот `#description` сильнее. */\n description?: string\n /** Цвет маркера из палитры пакета. */\n tone?: GrTimelineTone\n /** Заполненная точка — событие случилось, полая — запланировано. */\n variant?: GrTimelineMarkerVariant\n /**\n * Событие ещё не произошло: точка полая, а отрезок оси **после** неё —\n * пунктирный. Перебивает `variant`.\n */\n pending?: boolean\n}\n\nconst props = withDefaults(defineProps<GrTimelineItemProps>(), {\n time: undefined,\n datetime: undefined,\n title: undefined,\n description: undefined,\n tone: 'neutral',\n variant: 'filled',\n pending: false,\n})\n\ndefineSlots<{\n /** Содержимое события под заголовком и описанием. */\n default?: () => any\n /** Маркер вместо точки: иконка статуса, аватар автора, номер шага. */\n marker?: () => any\n /** Метка времени. */\n time?: () => any\n /** Заголовок события. */\n title?: () => any\n /** Пояснение под заголовком. */\n description?: () => any\n}>()\n\nconst slots = useSlots()\n\n/**\n * Раскладку пункт читает из контейнера. Вне `GrTimeline` — дефолты: пункт\n * остаётся рабочей строкой, а не падает.\n */\nconst timeline = inject(GR_TIMELINE_CONTEXT, null)\n\nconst layout = computed(() => timeline?.layout.value ?? 'stacked')\nconst density = computed(() => timeline?.density.value ?? 'regular')\n\nconst markerClass = computed(() => grTimelineMarkerClass(\n props.tone,\n props.pending ? 'outlined' : props.variant,\n))\n\nconst hasTime = computed(() => !!slots.time || !!props.time)\nconst hasTitle = computed(() => !!slots.title || !!props.title)\nconst hasDescription = computed(() => !!slots.description || !!props.description)\n\n/** В `layout=\"time\"` метка уезжает в свою колонку, во всех остальных — в содержимое. */\nconst timeInAside = computed(() => layout.value === 'time')\n</script>\n\n<template>\n <li\n data-gr-timeline-item\n :data-tone=\"tone\"\n :data-pending=\"pending ? '' : undefined\"\n >\n <div\n v-if=\"timeInAside\"\n data-gr-timeline-aside\n >\n <time\n v-if=\"hasTime\"\n :datetime=\"datetime\"\n :class=\"timeClass\"\n >\n <slot name=\"time\">{{ time }}</slot>\n </time>\n </div>\n\n <!-- Ось и точка декоративны: смысл события несёт текст рядом. -->\n <div\n data-gr-timeline-rail\n aria-hidden=\"true\"\n >\n <slot name=\"marker\">\n <span data-gr-timeline-marker :class=\"markerClass\" />\n </slot>\n <span data-gr-timeline-line />\n </div>\n\n <!--\n Вертикальный отступ живёт на содержимом, а не на строке: ось растянута по\n строке грид-ячейкой, и её поля в высоту ячейки не входят — линия обрывалась\n бы, не доходя до следующей точки.\n -->\n <div data-gr-timeline-content :class=\"grTimelineDensityClass(density)\">\n <time\n v-if=\"hasTime && !timeInAside\"\n data-gr-timeline-time\n :datetime=\"datetime\"\n :class=\"timeClass\"\n >\n <slot name=\"time\">{{ time }}</slot>\n </time>\n\n <div v-if=\"hasTitle\" data-gr-timeline-title :class=\"titleClass\">\n <slot name=\"title\">\n{{ title }}\n</slot>\n </div>\n\n <div v-if=\"hasDescription\" :class=\"descriptionClass\">\n <slot name=\"description\">\n{{ description }}\n</slot>\n </div>\n\n <div v-if=\"$slots.default\" data-gr-timeline-body>\n <slot />\n </div>\n </div>\n </li>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, useSlots } from 'vue'\n\nimport { GR_TIMELINE_CONTEXT } from './grTimelineContext'\nimport {\n descriptionClass,\n grTimelineDensityClass,\n grTimelineMarkerClass,\n timeClass,\n titleClass,\n type GrTimelineMarkerVariant,\n type GrTimelineTone,\n} from './grTimelineStyles'\n\nexport type { GrTimelineMarkerVariant, GrTimelineTone } from './grTimelineStyles'\n\nexport interface GrTimelineItemProps {\n /** Метка времени. Слот `#time` сильнее. */\n time?: string\n /** Машиночитаемое значение метки: попадает в `datetime` тега `<time>`. */\n datetime?: string\n /** Заголовок события. Слот `#title` сильнее. */\n title?: string\n /** Пояснение под заголовком. Слот `#description` сильнее. */\n description?: string\n /** Цвет маркера из палитры пакета. */\n tone?: GrTimelineTone\n /** Заполненная точка — событие случилось, полая — запланировано. */\n variant?: GrTimelineMarkerVariant\n /**\n * Событие ещё не произошло: точка полая, а отрезок оси **после** неё —\n * пунктирный. Перебивает `variant`.\n */\n pending?: boolean\n}\n\nconst props = withDefaults(defineProps<GrTimelineItemProps>(), {\n time: undefined,\n datetime: undefined,\n title: undefined,\n description: undefined,\n tone: 'neutral',\n variant: 'filled',\n pending: false,\n})\n\ndefineSlots<{\n /** Содержимое события под заголовком и описанием. */\n default?: () => any\n /** Маркер вместо точки: иконка статуса, аватар автора, номер шага. */\n marker?: () => any\n /** Метка времени. */\n time?: () => any\n /** Заголовок события. */\n title?: () => any\n /** Пояснение под заголовком. */\n description?: () => any\n}>()\n\nconst slots = useSlots()\n\n/**\n * Раскладку пункт читает из контейнера. Вне `GrTimeline` — дефолты: пункт\n * остаётся рабочей строкой, а не падает.\n */\nconst timeline = inject(GR_TIMELINE_CONTEXT, null)\n\nconst layout = computed(() => timeline?.layout.value ?? 'stacked')\nconst density = computed(() => timeline?.density.value ?? 'regular')\n\nconst markerClass = computed(() => grTimelineMarkerClass(\n props.tone,\n props.pending ? 'outlined' : props.variant,\n))\n\nconst hasTime = computed(() => !!slots.time || !!props.time)\nconst hasTitle = computed(() => !!slots.title || !!props.title)\nconst hasDescription = computed(() => !!slots.description || !!props.description)\n\n/** В `layout=\"time\"` метка уезжает в свою колонку, во всех остальных — в содержимое. */\nconst timeInAside = computed(() => layout.value === 'time')\n</script>\n\n<template>\n <li\n data-gr-timeline-item\n :data-tone=\"tone\"\n :data-pending=\"pending ? '' : undefined\"\n >\n <div\n v-if=\"timeInAside\"\n data-gr-timeline-aside\n >\n <time\n v-if=\"hasTime\"\n :datetime=\"datetime\"\n :class=\"timeClass\"\n >\n <slot name=\"time\">{{ time }}</slot>\n </time>\n </div>\n\n <!-- Ось и точка декоративны: смысл события несёт текст рядом. -->\n <div\n data-gr-timeline-rail\n aria-hidden=\"true\"\n >\n <slot name=\"marker\">\n <span data-gr-timeline-marker :class=\"markerClass\" />\n </slot>\n <span data-gr-timeline-line />\n </div>\n\n <!--\n Вертикальный отступ живёт на содержимом, а не на строке: ось растянута по\n строке грид-ячейкой, и её поля в высоту ячейки не входят — линия обрывалась\n бы, не доходя до следующей точки.\n -->\n <div data-gr-timeline-content :class=\"grTimelineDensityClass(density)\">\n <time\n v-if=\"hasTime && !timeInAside\"\n data-gr-timeline-time\n :datetime=\"datetime\"\n :class=\"timeClass\"\n >\n <slot name=\"time\">{{ time }}</slot>\n </time>\n\n <div v-if=\"hasTitle\" data-gr-timeline-title :class=\"titleClass\">\n <slot name=\"title\">\n{{ title }}\n</slot>\n </div>\n\n <div v-if=\"hasDescription\" :class=\"descriptionClass\">\n <slot name=\"description\">\n{{ description }}\n</slot>\n </div>\n\n <div v-if=\"$slots.default\" data-gr-timeline-body>\n <slot />\n </div>\n </div>\n </li>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GrTimeline-B-h2Yanw.js","names":["$slots"],"sources":["../../../../src/components/GrTimeline/grTimelineContext.ts","../../../../src/components/GrTimeline/timelineGroups.ts","../../../../src/components/GrTimeline/GrTimeline.vue","../../../../src/components/GrTimeline/GrTimeline.vue","../../../../src/components/GrTimeline/GrTimelineItem.vue","../../../../src/components/GrTimeline/GrTimelineItem.vue"],"sourcesContent":["import type { ComputedRef, InjectionKey } from 'vue'\n\nimport type { GrTimelineDensity, GrTimelineLayout, GrTimelineOrientation } from './grTimelineStyles'\n\n/**\n * Уровень заголовка группы. Тот же довод, что у `GrCollapse`: лента в разделе\n * `<h4>` с захардкоженным `<h3>` рвёт навигацию по заголовкам.\n */\nexport const GR_TIMELINE_HEADING_LEVELS = [2, 3, 4, 5, 6] as const\n\nexport type GrTimelineHeadingLevel = typeof GR_TIMELINE_HEADING_LEVELS[number]\n\n/**\n * Пункт читает раскладку из контейнера, а не получает её пропом: иначе\n * `layout` пришлось бы дублировать на каждом `GrTimelineItem`.\n */\nexport interface GrTimelineContext {\n layout: ComputedRef<GrTimelineLayout>\n orientation: ComputedRef<GrTimelineOrientation>\n density: ComputedRef<GrTimelineDensity>\n}\n\nexport const GR_TIMELINE_CONTEXT: InjectionKey<GrTimelineContext> = Symbol('GR_TIMELINE_CONTEXT')\n","/**\n * Группировка ленты событий. Без Vue — чтобы проверялась без монтирования.\n */\n\nexport type GrTimelineGroupBy<T> = string | ((item: T, index: number) => string)\n\n/** Пункт вместе с его позицией в исходном наборе: ключи `v-for` считаются от неё. */\nexport interface GrTimelineEntry<T> {\n item: T\n index: number\n}\n\nexport interface GrTimelineGroup<T> {\n /** Ключ группы. Пустая строка — заголовка у группы нет. */\n key: string\n entries: GrTimelineEntry<T>[]\n}\n\nfunction keyOf<T>(item: T, index: number, groupBy: GrTimelineGroupBy<T>): string {\n if (typeof groupBy === 'function')\n return String(groupBy(item, index) ?? '')\n\n const value = (item as Record<string, unknown> | null | undefined)?.[groupBy]\n\n // `undefined` в поле — это «группы нет», а не группа с надписью «undefined».\n return value == null ? '' : String(value)\n}\n\n/**\n * Режет набор на группы, **не меняя порядок**: лента хронологична, и\n * пересортировать её компонент не вправе. Порядок групп — порядок первого\n * вхождения ключа; разорванная группа (`A B A`) собирается в одну.\n *\n * Без `groupBy` — одна безымянная группа: плоская лента остаётся частным\n * случаем, и второй ветки рендера у компонента не появляется.\n */\nexport function groupTimelineItems<T>(\n items: readonly T[],\n groupBy?: GrTimelineGroupBy<T>,\n): GrTimelineGroup<T>[] {\n const entries = items.map((item, index) => ({ item, index }))\n\n if (groupBy === undefined)\n return entries.length === 0 ? [] : [{ key: '', entries }]\n\n const byKey = new Map<string, GrTimelineGroup<T>>()\n\n for (const entry of entries) {\n const key = keyOf(entry.item, entry.index, groupBy)\n const group = byKey.get(key)\n\n if (group)\n group.entries.push(entry)\n else\n byKey.set(key, { key, entries: [entry] })\n }\n\n return [...byKey.values()]\n}\n","<script setup lang=\"ts\" generic=\"T = unknown\">\nimport { computed, provide, useSlots, watch } from 'vue'\n\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { hasMeaningfulSlotContent } from '../shared/slotNodes'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport { GR_TIMELINE_CONTEXT, type GrTimelineHeadingLevel } from './grTimelineContext'\nimport {\n emptyClass,\n groupTitleClass,\n loadingRowClass,\n type GrTimelineDensity,\n type GrTimelineLayout,\n type GrTimelineOrientation,\n} from './grTimelineStyles'\nimport { groupTimelineItems, type GrTimelineGroupBy } from './timelineGroups'\n\nexport type {\n GrTimelineDensity,\n GrTimelineLayout,\n GrTimelineOrientation,\n} from './grTimelineStyles'\nexport type { GrTimelineGroupBy } from './timelineGroups'\n\nexport interface GrTimelineProps<TItem = unknown> {\n /**\n * Данные ленты. С ними пункты рисует слот `#item` — и только так лента знает\n * состав набора, то есть может его группировать.\n */\n items?: TItem[]\n /** Ключ пункта для `v-for`: имя поля или функция. Без него — индекс. */\n itemKey?: string | ((item: TItem, index: number) => string | number)\n /** Группировка: имя поля или функция от пункта. Заголовок группы — слот `#group`. */\n groupBy?: GrTimelineGroupBy<TItem>\n /** Уровень заголовка группы: лента обязана вписаться в структуру заголовков страницы. */\n groupHeadingLevel?: GrTimelineHeadingLevel\n /** Раскладка: одна ось, колонка времени слева или чередование сторон. */\n layout?: GrTimelineLayout\n /** Направление оси. Горизонтальная лента — скроллер. */\n orientation?: GrTimelineOrientation\n /** Плотность вертикальных отступов пункта. */\n density?: GrTimelineDensity\n /** Идёт загрузка: вместо пунктов — заглушки, контейнер помечен `aria-busy`. */\n loading?: boolean\n /** Сколько строк-заглушек показать при `loading`. */\n loadingRows?: number\n /**\n * Лента пуста. По умолчанию определяется сама — по данным или по слоту; проп\n * нужен там, где потребитель знает лучше.\n */\n empty?: boolean\n /** Текст пустого состояния. Слот `#empty` сильнее. */\n emptyText?: string\n}\n\nconst props = withDefaults(defineProps<GrTimelineProps<T>>(), {\n items: undefined,\n itemKey: undefined,\n groupBy: undefined,\n // Настоящие дефолты живут в резолверах `useGrComponentProp`: объявленный здесь\n // дефолт неотличим от значения, переданного потребителем, и перебивал бы конфиг.\n groupHeadingLevel: undefined,\n layout: undefined,\n orientation: undefined,\n density: undefined,\n loading: false,\n loadingRows: 3,\n empty: undefined,\n emptyText: undefined,\n})\n\ndefineSlots<{\n /** Пункты ленты (`GrTimelineItem`), когда данные не переданы пропом. */\n default?: () => any\n /** Пункт в data-режиме. */\n item?: (props: { item: T, index: number }) => any\n /** Заголовок группы. По умолчанию — сам ключ. */\n group?: (props: { group: string, items: T[] }) => any\n /** Содержимое пустого состояния вместо текста по умолчанию. */\n empty?: () => any\n /** Заглушки загрузки вместо строк по умолчанию. */\n loading?: () => any\n}>()\n\nconst slots = useSlots()\nconst { t } = useGranularityTranslations()\n\nconst density = useGrComponentProp('GrTimeline', 'density', () => props.density, 'regular')\nconst orientation = useGrComponentProp('GrTimeline', 'orientation', () => props.orientation, 'vertical')\nconst headingLevel = useGrComponentProp('GrTimeline', 'groupHeadingLevel', () => props.groupHeadingLevel, 3)\nconst requestedLayout = useGrComponentProp('GrTimeline', 'layout', () => props.layout, 'stacked')\n\n/**\n * Горизонтальная лента знает одну раскладку: колонка времени и чередование\n * сторон — это вертикальные приёмы, у горизонтальной оси сторон нет.\n */\nconst layout = computed<GrTimelineLayout>(() => (\n orientation.value === 'horizontal' ? 'stacked' : requestedLayout.value\n))\n\nconst headingTag = computed(() => `h${headingLevel.value}`)\n\nconst dataMode = computed(() => props.items !== undefined)\n\nconst grouped = computed(() => dataMode.value && props.groupBy !== undefined)\n\nconst groups = computed(() => groupTimelineItems(props.items ?? [], props.groupBy))\n\n/** Единственная группа плоской ленты: тот же набор, что и в data-режиме без группировки. */\nconst entries = computed(() => groups.value[0]?.entries ?? [])\n\nconst resolvedEmptyText = computed(() => props.emptyText ?? t('gr.timeline.empty', 'Nothing here yet'))\n\nconst isEmpty = computed(() => {\n if (props.empty !== undefined) return props.empty\n\n if (dataMode.value) return props.items!.length === 0\n\n // `v-for` по пустому массиву оставляет фрагмент без узлов, `v-if` — комментарий,\n // и ни то ни другое пунктом ленты не является.\n return !hasMeaningfulSlotContent(slots.default?.() ?? [])\n})\n\nconst loadingRowCount = computed(() => Math.max(1, Math.trunc(props.loadingRows)))\n\nfunction keyOf(item: T, index: number): string | number {\n const key = props.itemKey\n if (typeof key === 'function') return key(item, index)\n if (typeof key === 'string') return (item as Record<string, unknown>)[key] as string | number\n\n return index\n}\n\nfunction itemsOf(group: { entries: { item: T }[] }): T[] {\n return group.entries.map(entry => entry.item)\n}\n\nprovide(GR_TIMELINE_CONTEXT, { layout, orientation, density })\n\nif (import.meta.env?.DEV) {\n watch(\n () => [dataMode.value, Boolean(slots.item)] as const,\n ([hasItems, hasSlot]) => {\n if (hasItems && !hasSlot) {\n console.warn(\n '[granularity] GrTimeline: с `items` пункты рисует слот `#item` — без него лента пуста.',\n )\n }\n },\n { immediate: true },\n )\n\n watch(\n () => [dataMode.value, props.groupBy !== undefined] as const,\n ([hasItems, hasGroupBy]) => {\n if (hasGroupBy && !hasItems) {\n console.warn(\n '[granularity] GrTimeline: `groupBy` работает только с `items` — пункты из слота по '\n + 'умолчанию лента не разбирает и сгруппировать их ей не из чего.',\n )\n }\n },\n { immediate: true },\n )\n\n watch(\n () => [orientation.value, requestedLayout.value] as const,\n ([axis, requested]) => {\n if (axis === 'horizontal' && requested !== 'stacked') {\n console.warn(\n `[granularity] GrTimeline: layout=\"${requested}\" — вертикальная раскладка, `\n + 'в горизонтальной ленте она игнорируется.',\n )\n }\n },\n { immediate: true },\n )\n}\n</script>\n\n<template>\n <div\n data-gr-timeline\n :data-layout=\"layout\"\n :data-orientation=\"orientation\"\n :aria-busy=\"loading ? 'true' : undefined\"\n >\n <template v-if=\"loading\">\n <slot name=\"loading\">\n <div\n v-for=\"row in loadingRowCount\"\n :key=\"row\"\n data-gr-timeline-loading-row\n :class=\"loadingRowClass\"\n >\n <GrSkeleton variant=\"circle\" width=\"var(--gr-timeline-marker-size, 10px)\" />\n <GrSkeleton />\n </div>\n </slot>\n </template>\n\n <div\n v-else-if=\"isEmpty\"\n data-gr-timeline-empty\n :class=\"emptyClass\"\n >\n <slot name=\"empty\">\n {{ resolvedEmptyText }}\n </slot>\n </div>\n\n <template v-else-if=\"grouped\">\n <!--\n Группа — секция с заголовком, а не пункт-заголовок внутри списка:\n `<li>` с датой попал бы в набор событий и был бы объявлен как одно из них.\n -->\n <section\n v-for=\"group in groups\"\n :key=\"group.key\"\n data-gr-timeline-group\n >\n <div\n v-if=\"group.key\"\n data-gr-timeline-group-header\n >\n <div data-gr-timeline-rail aria-hidden=\"true\">\n <span data-gr-timeline-line />\n </div>\n\n <component\n :is=\"headingTag\"\n data-gr-timeline-group-title\n :class=\"groupTitleClass\"\n >\n <slot name=\"group\" :group=\"group.key\" :items=\"itemsOf(group)\">\n {{ group.key }}\n </slot>\n </component>\n </div>\n\n <ol\n data-gr-timeline-list\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n >\n <template\n v-for=\"entry in group.entries\"\n :key=\"keyOf(entry.item, entry.index)\"\n >\n <slot name=\"item\" :item=\"entry.item\" :index=\"entry.index\" />\n </template>\n </ol>\n </section>\n </template>\n\n <ol\n v-else\n data-gr-timeline-list\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n >\n <template v-if=\"dataMode\">\n <template\n v-for=\"entry in entries\"\n :key=\"keyOf(entry.item, entry.index)\"\n >\n <slot name=\"item\" :item=\"entry.item\" :index=\"entry.index\" />\n </template>\n </template>\n\n <slot v-else />\n </ol>\n </div>\n</template>\n\n<style>\n/*\n * Геометрия ленты живёт здесь, а не в утилитах, по одной причине: сторона\n * пункта в `alternate` — это `nth-child`, а обрыв оси — `last-child`, и оба\n * вопроса утилитами не выражаются. Альтернатива — регистрация пунктов в\n * контексте на `onMounted` — дала бы порядок, зависящий от порядка монтирования,\n * и разъезжалась бы на `v-if` посреди ленты.\n */\n\n[data-gr-timeline] {\n --gr-timeline-columns: auto 1fr;\n}\n\n[data-gr-timeline][data-layout='time'] {\n --gr-timeline-columns: var(--gr-timeline-time-width, 5.5rem) auto 1fr;\n}\n\n[data-gr-timeline][data-layout='alternate'] {\n --gr-timeline-columns: 1fr auto 1fr;\n}\n\n[data-gr-timeline-list] {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n[data-gr-timeline-item],\n[data-gr-timeline-group-header] {\n display: grid;\n grid-template-columns: var(--gr-timeline-columns);\n column-gap: var(--gr-timeline-gap, 0.75rem);\n align-items: start;\n}\n\n[data-gr-timeline-aside] {\n text-align: end;\n}\n\n/*\n * Ось — отрезок у каждого пункта, а не одна длинная линия: соседние отрезки\n * смыкаются сами, и мерить высоту списка не приходится.\n */\n[data-gr-timeline-rail] {\n display: flex;\n flex-direction: column;\n align-items: center;\n align-self: stretch;\n padding-top: var(--gr-timeline-marker-top, 0.35rem);\n}\n\n[data-gr-timeline-rail] > :first-child {\n flex: none;\n}\n\n[data-gr-timeline-marker] {\n box-sizing: border-box;\n width: var(--gr-timeline-marker-size, 10px);\n height: var(--gr-timeline-marker-size, 10px);\n border-width: var(--gr-timeline-marker-ring, 2px);\n border-style: solid;\n border-color: transparent;\n}\n\n[data-gr-timeline-line] {\n flex: 1 1 auto;\n width: var(--gr-timeline-axis-width, 2px);\n min-height: var(--gr-timeline-line-min, 0.75rem);\n margin-top: 0.25rem;\n /* Ровно на столько следующая точка отступает от верха своей строки: без этого\n отрезок не доходит до неё, и ось выглядит пунктиром из длинных штрихов. */\n margin-bottom: calc(-1 * var(--gr-timeline-marker-top, 0.35rem));\n background-color: var(--gr-timeline-axis-color, var(--gr-brd));\n}\n\n/*\n * Пунктиром идёт участок, ведущий **к** незавершённому событию, и всё, что за\n * ним: непройденный путь. Отрезок после точки для этого не годится — обычно\n * незавершённое событие последнее, и его отрезка не видно вовсе.\n */\n[data-gr-timeline-item]:has(+ [data-gr-timeline-item][data-pending]) [data-gr-timeline-line],\n[data-gr-timeline-item][data-pending] [data-gr-timeline-line] {\n background-color: transparent;\n background-image: repeating-linear-gradient(\n to bottom,\n var(--gr-timeline-axis-color, var(--gr-brd)) 0 var(--gr-timeline-dash, 4px),\n transparent var(--gr-timeline-dash, 4px) calc(var(--gr-timeline-dash, 4px) * 2)\n );\n}\n\n/* Хвост после последнего события — линия в никуда. */\n[data-gr-timeline-item]:last-child [data-gr-timeline-line] {\n visibility: hidden;\n}\n\n/* Между группами ось не рвётся: разрыв читался бы как две разные ленты. */\n[data-gr-timeline-group]:not(:last-of-type) [data-gr-timeline-item]:last-child [data-gr-timeline-line] {\n visibility: visible;\n}\n\n[data-gr-timeline-group-header] [data-gr-timeline-rail] {\n padding-top: 0;\n}\n\n/* Воздух перед заголовком — отступом строки, а не полем: поле разорвало бы ось. */\n[data-gr-timeline-group] + [data-gr-timeline-group] [data-gr-timeline-group-header] {\n padding-top: 0.5rem;\n}\n\n[data-gr-timeline-group-header] [data-gr-timeline-line] {\n margin-top: 0;\n}\n\n/* Над первым заголовком оси ещё нет — линия висела бы в воздухе. */\n[data-gr-timeline-group]:first-of-type [data-gr-timeline-group-header] [data-gr-timeline-line] {\n visibility: hidden;\n}\n\n[data-gr-timeline][data-layout='time'] [data-gr-timeline-group-header] [data-gr-timeline-rail],\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-header] [data-gr-timeline-rail] {\n grid-column: 2;\n}\n\n[data-gr-timeline][data-layout='time'] [data-gr-timeline-group-title],\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-title] {\n grid-column: 3;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-rail] {\n grid-column: 2;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-content] {\n grid-column: 3;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-item]:nth-child(even) [data-gr-timeline-content] {\n grid-column: 1;\n grid-row: 1;\n text-align: end;\n}\n\n/* Двухсторонняя лента в узкой колонке нечитаема — там она односторонняя. */\n@media (max-width: 640px) {\n [data-gr-timeline][data-layout='alternate'] {\n --gr-timeline-columns: auto 1fr;\n }\n\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-rail],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-header] [data-gr-timeline-rail] {\n grid-column: 1;\n }\n\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-content],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-item]:nth-child(even) [data-gr-timeline-content],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-title] {\n grid-column: 2;\n text-align: start;\n }\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-list] {\n display: flex;\n flex-direction: row;\n overflow-x: auto;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item] {\n grid-template-columns: 1fr;\n min-width: var(--gr-timeline-item-min-width, 12rem);\n padding-inline-end: var(--gr-timeline-gap, 0.75rem);\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-content] {\n padding-bottom: 0;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-rail] {\n flex-direction: row;\n align-items: center;\n align-self: auto;\n padding-top: 0;\n padding-bottom: 0.25rem;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-line] {\n width: auto;\n height: var(--gr-timeline-axis-width, 2px);\n min-width: var(--gr-timeline-line-min, 0.75rem);\n min-height: 0;\n margin-top: 0;\n margin-inline-start: 0.25rem;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item]:has(+ [data-gr-timeline-item][data-pending]) [data-gr-timeline-line],\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item][data-pending] [data-gr-timeline-line] {\n background-image: repeating-linear-gradient(\n to right,\n var(--gr-timeline-axis-color, var(--gr-brd)) 0 var(--gr-timeline-dash, 4px),\n transparent var(--gr-timeline-dash, 4px) calc(var(--gr-timeline-dash, 4px) * 2)\n );\n}\n</style>\n","<script setup lang=\"ts\" generic=\"T = unknown\">\nimport { computed, provide, useSlots, watch } from 'vue'\n\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { hasMeaningfulSlotContent } from '../shared/slotNodes'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport { GR_TIMELINE_CONTEXT, type GrTimelineHeadingLevel } from './grTimelineContext'\nimport {\n emptyClass,\n groupTitleClass,\n loadingRowClass,\n type GrTimelineDensity,\n type GrTimelineLayout,\n type GrTimelineOrientation,\n} from './grTimelineStyles'\nimport { groupTimelineItems, type GrTimelineGroupBy } from './timelineGroups'\n\nexport type {\n GrTimelineDensity,\n GrTimelineLayout,\n GrTimelineOrientation,\n} from './grTimelineStyles'\nexport type { GrTimelineGroupBy } from './timelineGroups'\n\nexport interface GrTimelineProps<TItem = unknown> {\n /**\n * Данные ленты. С ними пункты рисует слот `#item` — и только так лента знает\n * состав набора, то есть может его группировать.\n */\n items?: TItem[]\n /** Ключ пункта для `v-for`: имя поля или функция. Без него — индекс. */\n itemKey?: string | ((item: TItem, index: number) => string | number)\n /** Группировка: имя поля или функция от пункта. Заголовок группы — слот `#group`. */\n groupBy?: GrTimelineGroupBy<TItem>\n /** Уровень заголовка группы: лента обязана вписаться в структуру заголовков страницы. */\n groupHeadingLevel?: GrTimelineHeadingLevel\n /** Раскладка: одна ось, колонка времени слева или чередование сторон. */\n layout?: GrTimelineLayout\n /** Направление оси. Горизонтальная лента — скроллер. */\n orientation?: GrTimelineOrientation\n /** Плотность вертикальных отступов пункта. */\n density?: GrTimelineDensity\n /** Идёт загрузка: вместо пунктов — заглушки, контейнер помечен `aria-busy`. */\n loading?: boolean\n /** Сколько строк-заглушек показать при `loading`. */\n loadingRows?: number\n /**\n * Лента пуста. По умолчанию определяется сама — по данным или по слоту; проп\n * нужен там, где потребитель знает лучше.\n */\n empty?: boolean\n /** Текст пустого состояния. Слот `#empty` сильнее. */\n emptyText?: string\n}\n\nconst props = withDefaults(defineProps<GrTimelineProps<T>>(), {\n items: undefined,\n itemKey: undefined,\n groupBy: undefined,\n // Настоящие дефолты живут в резолверах `useGrComponentProp`: объявленный здесь\n // дефолт неотличим от значения, переданного потребителем, и перебивал бы конфиг.\n groupHeadingLevel: undefined,\n layout: undefined,\n orientation: undefined,\n density: undefined,\n loading: false,\n loadingRows: 3,\n empty: undefined,\n emptyText: undefined,\n})\n\ndefineSlots<{\n /** Пункты ленты (`GrTimelineItem`), когда данные не переданы пропом. */\n default?: () => any\n /** Пункт в data-режиме. */\n item?: (props: { item: T, index: number }) => any\n /** Заголовок группы. По умолчанию — сам ключ. */\n group?: (props: { group: string, items: T[] }) => any\n /** Содержимое пустого состояния вместо текста по умолчанию. */\n empty?: () => any\n /** Заглушки загрузки вместо строк по умолчанию. */\n loading?: () => any\n}>()\n\nconst slots = useSlots()\nconst { t } = useGranularityTranslations()\n\nconst density = useGrComponentProp('GrTimeline', 'density', () => props.density, 'regular')\nconst orientation = useGrComponentProp('GrTimeline', 'orientation', () => props.orientation, 'vertical')\nconst headingLevel = useGrComponentProp('GrTimeline', 'groupHeadingLevel', () => props.groupHeadingLevel, 3)\nconst requestedLayout = useGrComponentProp('GrTimeline', 'layout', () => props.layout, 'stacked')\n\n/**\n * Горизонтальная лента знает одну раскладку: колонка времени и чередование\n * сторон — это вертикальные приёмы, у горизонтальной оси сторон нет.\n */\nconst layout = computed<GrTimelineLayout>(() => (\n orientation.value === 'horizontal' ? 'stacked' : requestedLayout.value\n))\n\nconst headingTag = computed(() => `h${headingLevel.value}`)\n\nconst dataMode = computed(() => props.items !== undefined)\n\nconst grouped = computed(() => dataMode.value && props.groupBy !== undefined)\n\nconst groups = computed(() => groupTimelineItems(props.items ?? [], props.groupBy))\n\n/** Единственная группа плоской ленты: тот же набор, что и в data-режиме без группировки. */\nconst entries = computed(() => groups.value[0]?.entries ?? [])\n\nconst resolvedEmptyText = computed(() => props.emptyText ?? t('gr.timeline.empty', 'Nothing here yet'))\n\nconst isEmpty = computed(() => {\n if (props.empty !== undefined) return props.empty\n\n if (dataMode.value) return props.items!.length === 0\n\n // `v-for` по пустому массиву оставляет фрагмент без узлов, `v-if` — комментарий,\n // и ни то ни другое пунктом ленты не является.\n return !hasMeaningfulSlotContent(slots.default?.() ?? [])\n})\n\nconst loadingRowCount = computed(() => Math.max(1, Math.trunc(props.loadingRows)))\n\nfunction keyOf(item: T, index: number): string | number {\n const key = props.itemKey\n if (typeof key === 'function') return key(item, index)\n if (typeof key === 'string') return (item as Record<string, unknown>)[key] as string | number\n\n return index\n}\n\nfunction itemsOf(group: { entries: { item: T }[] }): T[] {\n return group.entries.map(entry => entry.item)\n}\n\nprovide(GR_TIMELINE_CONTEXT, { layout, orientation, density })\n\nif (import.meta.env?.DEV) {\n watch(\n () => [dataMode.value, Boolean(slots.item)] as const,\n ([hasItems, hasSlot]) => {\n if (hasItems && !hasSlot) {\n console.warn(\n '[granularity] GrTimeline: с `items` пункты рисует слот `#item` — без него лента пуста.',\n )\n }\n },\n { immediate: true },\n )\n\n watch(\n () => [dataMode.value, props.groupBy !== undefined] as const,\n ([hasItems, hasGroupBy]) => {\n if (hasGroupBy && !hasItems) {\n console.warn(\n '[granularity] GrTimeline: `groupBy` работает только с `items` — пункты из слота по '\n + 'умолчанию лента не разбирает и сгруппировать их ей не из чего.',\n )\n }\n },\n { immediate: true },\n )\n\n watch(\n () => [orientation.value, requestedLayout.value] as const,\n ([axis, requested]) => {\n if (axis === 'horizontal' && requested !== 'stacked') {\n console.warn(\n `[granularity] GrTimeline: layout=\"${requested}\" — вертикальная раскладка, `\n + 'в горизонтальной ленте она игнорируется.',\n )\n }\n },\n { immediate: true },\n )\n}\n</script>\n\n<template>\n <div\n data-gr-timeline\n :data-layout=\"layout\"\n :data-orientation=\"orientation\"\n :aria-busy=\"loading ? 'true' : undefined\"\n >\n <template v-if=\"loading\">\n <slot name=\"loading\">\n <div\n v-for=\"row in loadingRowCount\"\n :key=\"row\"\n data-gr-timeline-loading-row\n :class=\"loadingRowClass\"\n >\n <GrSkeleton variant=\"circle\" width=\"var(--gr-timeline-marker-size, 10px)\" />\n <GrSkeleton />\n </div>\n </slot>\n </template>\n\n <div\n v-else-if=\"isEmpty\"\n data-gr-timeline-empty\n :class=\"emptyClass\"\n >\n <slot name=\"empty\">\n {{ resolvedEmptyText }}\n </slot>\n </div>\n\n <template v-else-if=\"grouped\">\n <!--\n Группа — секция с заголовком, а не пункт-заголовок внутри списка:\n `<li>` с датой попал бы в набор событий и был бы объявлен как одно из них.\n -->\n <section\n v-for=\"group in groups\"\n :key=\"group.key\"\n data-gr-timeline-group\n >\n <div\n v-if=\"group.key\"\n data-gr-timeline-group-header\n >\n <div data-gr-timeline-rail aria-hidden=\"true\">\n <span data-gr-timeline-line />\n </div>\n\n <component\n :is=\"headingTag\"\n data-gr-timeline-group-title\n :class=\"groupTitleClass\"\n >\n <slot name=\"group\" :group=\"group.key\" :items=\"itemsOf(group)\">\n {{ group.key }}\n </slot>\n </component>\n </div>\n\n <ol\n data-gr-timeline-list\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n >\n <template\n v-for=\"entry in group.entries\"\n :key=\"keyOf(entry.item, entry.index)\"\n >\n <slot name=\"item\" :item=\"entry.item\" :index=\"entry.index\" />\n </template>\n </ol>\n </section>\n </template>\n\n <ol\n v-else\n data-gr-timeline-list\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n >\n <template v-if=\"dataMode\">\n <template\n v-for=\"entry in entries\"\n :key=\"keyOf(entry.item, entry.index)\"\n >\n <slot name=\"item\" :item=\"entry.item\" :index=\"entry.index\" />\n </template>\n </template>\n\n <slot v-else />\n </ol>\n </div>\n</template>\n\n<style>\n/*\n * Геометрия ленты живёт здесь, а не в утилитах, по одной причине: сторона\n * пункта в `alternate` — это `nth-child`, а обрыв оси — `last-child`, и оба\n * вопроса утилитами не выражаются. Альтернатива — регистрация пунктов в\n * контексте на `onMounted` — дала бы порядок, зависящий от порядка монтирования,\n * и разъезжалась бы на `v-if` посреди ленты.\n */\n\n[data-gr-timeline] {\n --gr-timeline-columns: auto 1fr;\n}\n\n[data-gr-timeline][data-layout='time'] {\n --gr-timeline-columns: var(--gr-timeline-time-width, 5.5rem) auto 1fr;\n}\n\n[data-gr-timeline][data-layout='alternate'] {\n --gr-timeline-columns: 1fr auto 1fr;\n}\n\n[data-gr-timeline-list] {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n[data-gr-timeline-item],\n[data-gr-timeline-group-header] {\n display: grid;\n grid-template-columns: var(--gr-timeline-columns);\n column-gap: var(--gr-timeline-gap, 0.75rem);\n align-items: start;\n}\n\n[data-gr-timeline-aside] {\n text-align: end;\n}\n\n/*\n * Ось — отрезок у каждого пункта, а не одна длинная линия: соседние отрезки\n * смыкаются сами, и мерить высоту списка не приходится.\n */\n[data-gr-timeline-rail] {\n display: flex;\n flex-direction: column;\n align-items: center;\n align-self: stretch;\n padding-top: var(--gr-timeline-marker-top, 0.35rem);\n}\n\n[data-gr-timeline-rail] > :first-child {\n flex: none;\n}\n\n[data-gr-timeline-marker] {\n box-sizing: border-box;\n width: var(--gr-timeline-marker-size, 10px);\n height: var(--gr-timeline-marker-size, 10px);\n border-width: var(--gr-timeline-marker-ring, 2px);\n border-style: solid;\n border-color: transparent;\n}\n\n[data-gr-timeline-line] {\n flex: 1 1 auto;\n width: var(--gr-timeline-axis-width, 2px);\n min-height: var(--gr-timeline-line-min, 0.75rem);\n margin-top: 0.25rem;\n /* Ровно на столько следующая точка отступает от верха своей строки: без этого\n отрезок не доходит до неё, и ось выглядит пунктиром из длинных штрихов. */\n margin-bottom: calc(-1 * var(--gr-timeline-marker-top, 0.35rem));\n background-color: var(--gr-timeline-axis-color, var(--gr-brd));\n}\n\n/*\n * Пунктиром идёт участок, ведущий **к** незавершённому событию, и всё, что за\n * ним: непройденный путь. Отрезок после точки для этого не годится — обычно\n * незавершённое событие последнее, и его отрезка не видно вовсе.\n */\n[data-gr-timeline-item]:has(+ [data-gr-timeline-item][data-pending]) [data-gr-timeline-line],\n[data-gr-timeline-item][data-pending] [data-gr-timeline-line] {\n background-color: transparent;\n background-image: repeating-linear-gradient(\n to bottom,\n var(--gr-timeline-axis-color, var(--gr-brd)) 0 var(--gr-timeline-dash, 4px),\n transparent var(--gr-timeline-dash, 4px) calc(var(--gr-timeline-dash, 4px) * 2)\n );\n}\n\n/* Хвост после последнего события — линия в никуда. */\n[data-gr-timeline-item]:last-child [data-gr-timeline-line] {\n visibility: hidden;\n}\n\n/* Между группами ось не рвётся: разрыв читался бы как две разные ленты. */\n[data-gr-timeline-group]:not(:last-of-type) [data-gr-timeline-item]:last-child [data-gr-timeline-line] {\n visibility: visible;\n}\n\n[data-gr-timeline-group-header] [data-gr-timeline-rail] {\n padding-top: 0;\n}\n\n/* Воздух перед заголовком — отступом строки, а не полем: поле разорвало бы ось. */\n[data-gr-timeline-group] + [data-gr-timeline-group] [data-gr-timeline-group-header] {\n padding-top: 0.5rem;\n}\n\n[data-gr-timeline-group-header] [data-gr-timeline-line] {\n margin-top: 0;\n}\n\n/* Над первым заголовком оси ещё нет — линия висела бы в воздухе. */\n[data-gr-timeline-group]:first-of-type [data-gr-timeline-group-header] [data-gr-timeline-line] {\n visibility: hidden;\n}\n\n[data-gr-timeline][data-layout='time'] [data-gr-timeline-group-header] [data-gr-timeline-rail],\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-header] [data-gr-timeline-rail] {\n grid-column: 2;\n}\n\n[data-gr-timeline][data-layout='time'] [data-gr-timeline-group-title],\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-title] {\n grid-column: 3;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-rail] {\n grid-column: 2;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-content] {\n grid-column: 3;\n}\n\n[data-gr-timeline][data-layout='alternate'] [data-gr-timeline-item]:nth-child(even) [data-gr-timeline-content] {\n grid-column: 1;\n grid-row: 1;\n text-align: end;\n}\n\n/* Двухсторонняя лента в узкой колонке нечитаема — там она односторонняя. */\n@media (max-width: 640px) {\n [data-gr-timeline][data-layout='alternate'] {\n --gr-timeline-columns: auto 1fr;\n }\n\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-rail],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-header] [data-gr-timeline-rail] {\n grid-column: 1;\n }\n\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-content],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-item]:nth-child(even) [data-gr-timeline-content],\n [data-gr-timeline][data-layout='alternate'] [data-gr-timeline-group-title] {\n grid-column: 2;\n text-align: start;\n }\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-list] {\n display: flex;\n flex-direction: row;\n overflow-x: auto;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item] {\n grid-template-columns: 1fr;\n min-width: var(--gr-timeline-item-min-width, 12rem);\n padding-inline-end: var(--gr-timeline-gap, 0.75rem);\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-content] {\n padding-bottom: 0;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-rail] {\n flex-direction: row;\n align-items: center;\n align-self: auto;\n padding-top: 0;\n padding-bottom: 0.25rem;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-line] {\n width: auto;\n height: var(--gr-timeline-axis-width, 2px);\n min-width: var(--gr-timeline-line-min, 0.75rem);\n min-height: 0;\n margin-top: 0;\n margin-inline-start: 0.25rem;\n}\n\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item]:has(+ [data-gr-timeline-item][data-pending]) [data-gr-timeline-line],\n[data-gr-timeline][data-orientation='horizontal'] [data-gr-timeline-item][data-pending] [data-gr-timeline-line] {\n background-image: repeating-linear-gradient(\n to right,\n var(--gr-timeline-axis-color, var(--gr-brd)) 0 var(--gr-timeline-dash, 4px),\n transparent var(--gr-timeline-dash, 4px) calc(var(--gr-timeline-dash, 4px) * 2)\n );\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, inject, useSlots } from 'vue'\n\nimport { GR_TIMELINE_CONTEXT } from './grTimelineContext'\nimport {\n descriptionClass,\n grTimelineDensityClass,\n grTimelineMarkerClass,\n timeClass,\n titleClass,\n type GrTimelineMarkerVariant,\n type GrTimelineTone,\n} from './grTimelineStyles'\n\nexport type { GrTimelineMarkerVariant, GrTimelineTone } from './grTimelineStyles'\n\nexport interface GrTimelineItemProps {\n /** Метка времени. Слот `#time` сильнее. */\n time?: string\n /** Машиночитаемое значение метки: попадает в `datetime` тега `<time>`. */\n datetime?: string\n /** Заголовок события. Слот `#title` сильнее. */\n title?: string\n /** Пояснение под заголовком. Слот `#description` сильнее. */\n description?: string\n /** Цвет маркера из палитры пакета. */\n tone?: GrTimelineTone\n /** Заполненная точка — событие случилось, полая — запланировано. */\n variant?: GrTimelineMarkerVariant\n /**\n * Событие ещё не произошло: точка полая, а отрезок оси **после** неё —\n * пунктирный. Перебивает `variant`.\n */\n pending?: boolean\n}\n\nconst props = withDefaults(defineProps<GrTimelineItemProps>(), {\n time: undefined,\n datetime: undefined,\n title: undefined,\n description: undefined,\n tone: 'neutral',\n variant: 'filled',\n pending: false,\n})\n\ndefineSlots<{\n /** Содержимое события под заголовком и описанием. */\n default?: () => any\n /** Маркер вместо точки: иконка статуса, аватар автора, номер шага. */\n marker?: () => any\n /** Метка времени. */\n time?: () => any\n /** Заголовок события. */\n title?: () => any\n /** Пояснение под заголовком. */\n description?: () => any\n}>()\n\nconst slots = useSlots()\n\n/**\n * Раскладку пункт читает из контейнера. Вне `GrTimeline` — дефолты: пункт\n * остаётся рабочей строкой, а не падает.\n */\nconst timeline = inject(GR_TIMELINE_CONTEXT, null)\n\nconst layout = computed(() => timeline?.layout.value ?? 'stacked')\nconst density = computed(() => timeline?.density.value ?? 'regular')\n\nconst markerClass = computed(() => grTimelineMarkerClass(\n props.tone,\n props.pending ? 'outlined' : props.variant,\n))\n\nconst hasTime = computed(() => !!slots.time || !!props.time)\nconst hasTitle = computed(() => !!slots.title || !!props.title)\nconst hasDescription = computed(() => !!slots.description || !!props.description)\n\n/** В `layout=\"time\"` метка уезжает в свою колонку, во всех остальных — в содержимое. */\nconst timeInAside = computed(() => layout.value === 'time')\n</script>\n\n<template>\n <li\n data-gr-timeline-item\n :data-tone=\"tone\"\n :data-pending=\"pending ? '' : undefined\"\n >\n <div\n v-if=\"timeInAside\"\n data-gr-timeline-aside\n >\n <time\n v-if=\"hasTime\"\n :datetime=\"datetime\"\n :class=\"timeClass\"\n >\n <slot name=\"time\">{{ time }}</slot>\n </time>\n </div>\n\n <!-- Ось и точка декоративны: смысл события несёт текст рядом. -->\n <div\n data-gr-timeline-rail\n aria-hidden=\"true\"\n >\n <slot name=\"marker\">\n <span data-gr-timeline-marker :class=\"markerClass\" />\n </slot>\n <span data-gr-timeline-line />\n </div>\n\n <!--\n Вертикальный отступ живёт на содержимом, а не на строке: ось растянута по\n строке грид-ячейкой, и её поля в высоту ячейки не входят — линия обрывалась\n бы, не доходя до следующей точки.\n -->\n <div data-gr-timeline-content :class=\"grTimelineDensityClass(density)\">\n <time\n v-if=\"hasTime && !timeInAside\"\n data-gr-timeline-time\n :datetime=\"datetime\"\n :class=\"timeClass\"\n >\n <slot name=\"time\">{{ time }}</slot>\n </time>\n\n <div v-if=\"hasTitle\" data-gr-timeline-title :class=\"titleClass\">\n <slot name=\"title\">\n{{ title }}\n</slot>\n </div>\n\n <div v-if=\"hasDescription\" :class=\"descriptionClass\">\n <slot name=\"description\">\n{{ description }}\n</slot>\n </div>\n\n <div v-if=\"$slots.default\" data-gr-timeline-body>\n <slot />\n </div>\n </div>\n </li>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, useSlots } from 'vue'\n\nimport { GR_TIMELINE_CONTEXT } from './grTimelineContext'\nimport {\n descriptionClass,\n grTimelineDensityClass,\n grTimelineMarkerClass,\n timeClass,\n titleClass,\n type GrTimelineMarkerVariant,\n type GrTimelineTone,\n} from './grTimelineStyles'\n\nexport type { GrTimelineMarkerVariant, GrTimelineTone } from './grTimelineStyles'\n\nexport interface GrTimelineItemProps {\n /** Метка времени. Слот `#time` сильнее. */\n time?: string\n /** Машиночитаемое значение метки: попадает в `datetime` тега `<time>`. */\n datetime?: string\n /** Заголовок события. Слот `#title` сильнее. */\n title?: string\n /** Пояснение под заголовком. Слот `#description` сильнее. */\n description?: string\n /** Цвет маркера из палитры пакета. */\n tone?: GrTimelineTone\n /** Заполненная точка — событие случилось, полая — запланировано. */\n variant?: GrTimelineMarkerVariant\n /**\n * Событие ещё не произошло: точка полая, а отрезок оси **после** неё —\n * пунктирный. Перебивает `variant`.\n */\n pending?: boolean\n}\n\nconst props = withDefaults(defineProps<GrTimelineItemProps>(), {\n time: undefined,\n datetime: undefined,\n title: undefined,\n description: undefined,\n tone: 'neutral',\n variant: 'filled',\n pending: false,\n})\n\ndefineSlots<{\n /** Содержимое события под заголовком и описанием. */\n default?: () => any\n /** Маркер вместо точки: иконка статуса, аватар автора, номер шага. */\n marker?: () => any\n /** Метка времени. */\n time?: () => any\n /** Заголовок события. */\n title?: () => any\n /** Пояснение под заголовком. */\n description?: () => any\n}>()\n\nconst slots = useSlots()\n\n/**\n * Раскладку пункт читает из контейнера. Вне `GrTimeline` — дефолты: пункт\n * остаётся рабочей строкой, а не падает.\n */\nconst timeline = inject(GR_TIMELINE_CONTEXT, null)\n\nconst layout = computed(() => timeline?.layout.value ?? 'stacked')\nconst density = computed(() => timeline?.density.value ?? 'regular')\n\nconst markerClass = computed(() => grTimelineMarkerClass(\n props.tone,\n props.pending ? 'outlined' : props.variant,\n))\n\nconst hasTime = computed(() => !!slots.time || !!props.time)\nconst hasTitle = computed(() => !!slots.title || !!props.title)\nconst hasDescription = computed(() => !!slots.description || !!props.description)\n\n/** В `layout=\"time\"` метка уезжает в свою колонку, во всех остальных — в содержимое. */\nconst timeInAside = computed(() => layout.value === 'time')\n</script>\n\n<template>\n <li\n data-gr-timeline-item\n :data-tone=\"tone\"\n :data-pending=\"pending ? '' : undefined\"\n >\n <div\n v-if=\"timeInAside\"\n data-gr-timeline-aside\n >\n <time\n v-if=\"hasTime\"\n :datetime=\"datetime\"\n :class=\"timeClass\"\n >\n <slot name=\"time\">{{ time }}</slot>\n </time>\n </div>\n\n <!-- Ось и точка декоративны: смысл события несёт текст рядом. -->\n <div\n data-gr-timeline-rail\n aria-hidden=\"true\"\n >\n <slot name=\"marker\">\n <span data-gr-timeline-marker :class=\"markerClass\" />\n </slot>\n <span data-gr-timeline-line />\n </div>\n\n <!--\n Вертикальный отступ живёт на содержимом, а не на строке: ось растянута по\n строке грид-ячейкой, и её поля в высоту ячейки не входят — линия обрывалась\n бы, не доходя до следующей точки.\n -->\n <div data-gr-timeline-content :class=\"grTimelineDensityClass(density)\">\n <time\n v-if=\"hasTime && !timeInAside\"\n data-gr-timeline-time\n :datetime=\"datetime\"\n :class=\"timeClass\"\n >\n <slot name=\"time\">{{ time }}</slot>\n </time>\n\n <div v-if=\"hasTitle\" data-gr-timeline-title :class=\"titleClass\">\n <slot name=\"title\">\n{{ title }}\n</slot>\n </div>\n\n <div v-if=\"hasDescription\" :class=\"descriptionClass\">\n <slot name=\"description\">\n{{ description }}\n</slot>\n </div>\n\n <div v-if=\"$slots.default\" data-gr-timeline-body>\n <slot />\n </div>\n </div>\n </li>\n</template>\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { i as GR_TIMELINE_HEADING_LEVELS, n as GrTimeline_default, r as groupTimelineItems, t as GrTimelineItem_default } from "./chunks/GrTimeline-
|
|
2
|
-
import { n as grTimelineSafelist, t as grTimelineConfig } from "../../chunks/config-
|
|
1
|
+
import { i as GR_TIMELINE_HEADING_LEVELS, n as GrTimeline_default, r as groupTimelineItems, t as GrTimelineItem_default } from "./chunks/GrTimeline-B-h2Yanw.js";
|
|
2
|
+
import { n as grTimelineSafelist, t as grTimelineConfig } from "../../chunks/config-COpuWGr_.js";
|
|
3
3
|
export { GR_TIMELINE_HEADING_LEVELS, GrTimeline_default as GrTimeline, GrTimeline_default as default, GrTimelineItem_default as GrTimelineItem, grTimelineConfig, grTimelineSafelist, groupTimelineItems };
|
|
@@ -3,17 +3,23 @@ import { t as info_default } from "../../../chunks/info-Be2OccTu.js";
|
|
|
3
3
|
import { t as x_default } from "../../../chunks/x-2KXnqxiD.js";
|
|
4
4
|
import { c as useGrThemeAttrs } from "../../../chunks/context-BSYR7RZs.js";
|
|
5
5
|
import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
|
|
6
|
-
import { t as usePortalTarget } from "../../../chunks/usePortalTarget-
|
|
6
|
+
import { t as usePortalTarget } from "../../../chunks/usePortalTarget-Cn-Wiz5d.js";
|
|
7
7
|
import { vHotkey } from "../../../directives/hotkey.js";
|
|
8
8
|
import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-BvA2ZGXP.js";
|
|
9
9
|
import { t as _plugin_vue_export_helper_default } from "../../../chunks/_plugin-vue_export-helper-BOaGB7Aw.js";
|
|
10
10
|
import { t as GrButton_default } from "../../GrButton/chunks/GrButton-D0m_z0XW.js";
|
|
11
|
+
import { useDragGesture } from "../../../composables/useDragGesture.js";
|
|
11
12
|
import { useToast } from "../../../composables/useToast.js";
|
|
12
|
-
import { r as PLACEMENT_CLASS } from "../../../chunks/config-
|
|
13
|
-
import { Fragment, Teleport, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, normalizeStyle, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useSlots, watchEffect, withCtx, withDirectives } from "vue";
|
|
13
|
+
import { a as SWIPE_THRESHOLD_RATIO, i as SWIPE_DIRECTION, o as swipeOpacity, r as PLACEMENT_CLASS } from "../../../chunks/config-ScuvHw6k2.js";
|
|
14
|
+
import { Fragment, Teleport, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, nextTick, normalizeClass, normalizeStyle, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useSlots, watchEffect, withCtx, withDirectives } from "vue";
|
|
14
15
|
import '../styles.css';//#region src/components/GrToaster/GrToaster.vue?vue&type=script&setup=true&lang.ts
|
|
15
16
|
var _hoisted_1 = ["aria-label"];
|
|
16
|
-
var _hoisted_2 = [
|
|
17
|
+
var _hoisted_2 = [
|
|
18
|
+
"data-tone",
|
|
19
|
+
"data-toast-id",
|
|
20
|
+
"role",
|
|
21
|
+
"onKeydown"
|
|
22
|
+
];
|
|
17
23
|
var _hoisted_3 = { class: "flex items-start gap-3" };
|
|
18
24
|
var _hoisted_4 = { class: "min-w-0 flex-1" };
|
|
19
25
|
var _hoisted_5 = { class: "text-[length:var(--gr-text-sm)] font-700" };
|
|
@@ -38,6 +44,10 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
38
44
|
focusHotkey: {
|
|
39
45
|
type: [String, Boolean],
|
|
40
46
|
default: "F6"
|
|
47
|
+
},
|
|
48
|
+
swipeDismiss: {
|
|
49
|
+
type: Boolean,
|
|
50
|
+
default: true
|
|
41
51
|
}
|
|
42
52
|
},
|
|
43
53
|
setup(__props, { expose: __expose }) {
|
|
@@ -132,7 +142,95 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
132
142
|
const visibleIds = computed(() => new Set(visibleToasts.value.map((toast) => toast.id)));
|
|
133
143
|
const hovered = ref(false);
|
|
134
144
|
const focusWithin = ref(false);
|
|
135
|
-
const
|
|
145
|
+
const containerEl = ref(null);
|
|
146
|
+
const swipingId = ref(null);
|
|
147
|
+
const swipeOffset = ref(0);
|
|
148
|
+
let swipeStartX = 0;
|
|
149
|
+
let swipeThreshold = 56;
|
|
150
|
+
const paused = computed(() => hovered.value || focusWithin.value || swipingId.value !== null);
|
|
151
|
+
function toastElement(id) {
|
|
152
|
+
return containerEl.value?.querySelector(`[data-gr-toast][data-toast-id="${id}"]`) ?? null;
|
|
153
|
+
}
|
|
154
|
+
/** Жест отпущен и тост закрывается: переход снова разрешён (см. `releaseSwiped`). */
|
|
155
|
+
const swipeReleased = ref(false);
|
|
156
|
+
function resetSwipe() {
|
|
157
|
+
swipingId.value = null;
|
|
158
|
+
swipeOffset.value = 0;
|
|
159
|
+
swipeReleased.value = false;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Отпущенный тост уезжает за свой край и только потом закрывается.
|
|
163
|
+
*
|
|
164
|
+
* Два кадра здесь обязательны, и оба по одной причине: уходящий элемент Vue
|
|
165
|
+
* больше не перерисовывает — он уезжает с тем стилем, что был на последнем
|
|
166
|
+
* рендере. Значит и разрешение перехода, и конечную точку нужно успеть отдать
|
|
167
|
+
* до закрытия: первый кадр снимает инлайновый `transition: none` (во время
|
|
168
|
+
* жеста он нужен, иначе переходы группы борются с пальцем), второй задаёт точку
|
|
169
|
+
* отлёта — с этого момента анимация уже идёт, и `leave` подхватывает её на ходу.
|
|
170
|
+
*
|
|
171
|
+
* Закрыв тост сразу, получили бы не отлёт, а мгновенное исчезновение: элемент
|
|
172
|
+
* ушёл бы в `leave` с запрещённым переходом.
|
|
173
|
+
*/
|
|
174
|
+
async function releaseSwiped(id) {
|
|
175
|
+
swipeReleased.value = true;
|
|
176
|
+
await nextTick();
|
|
177
|
+
swipeOffset.value = SWIPE_DIRECTION[props.placement] * 600;
|
|
178
|
+
await nextTick();
|
|
179
|
+
dismiss(id);
|
|
180
|
+
resetSwipe();
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Движение к своему краю идёт один к одному, в обратную сторону — с
|
|
184
|
+
* сопротивлением: тост едет за пальцем, но закрыть его «наоборот» нельзя.
|
|
185
|
+
*/
|
|
186
|
+
function resistOffset(delta) {
|
|
187
|
+
const toEdge = SWIPE_DIRECTION[props.placement];
|
|
188
|
+
return Math.sign(delta) === toEdge ? delta : delta / 4;
|
|
189
|
+
}
|
|
190
|
+
const swipe = useDragGesture({
|
|
191
|
+
disabled: () => !props.swipeDismiss,
|
|
192
|
+
onStart: (event) => {
|
|
193
|
+
const target = event.target;
|
|
194
|
+
if (target?.closest("button, a[href]")) return false;
|
|
195
|
+
const host = target?.closest("[data-gr-toast]");
|
|
196
|
+
const id = host?.dataset.toastId;
|
|
197
|
+
if (!host || !id) return false;
|
|
198
|
+
swipingId.value = id;
|
|
199
|
+
swipeOffset.value = 0;
|
|
200
|
+
swipeStartX = event.clientX;
|
|
201
|
+
swipeThreshold = Math.max(56, host.getBoundingClientRect().width * SWIPE_THRESHOLD_RATIO);
|
|
202
|
+
},
|
|
203
|
+
onMove: (event) => {
|
|
204
|
+
event.preventDefault();
|
|
205
|
+
swipeOffset.value = resistOffset(event.clientX - swipeStartX);
|
|
206
|
+
},
|
|
207
|
+
onEnd: () => {
|
|
208
|
+
const id = swipingId.value;
|
|
209
|
+
if (id !== null && Math.sign(swipeOffset.value) === SWIPE_DIRECTION[props.placement] && Math.abs(swipeOffset.value) >= swipeThreshold) releaseSwiped(id);
|
|
210
|
+
else resetSwipe();
|
|
211
|
+
},
|
|
212
|
+
onCancel: resetSwipe
|
|
213
|
+
});
|
|
214
|
+
function swipeStyle(toast) {
|
|
215
|
+
if (swipingId.value !== toast.id) return void 0;
|
|
216
|
+
return {
|
|
217
|
+
transform: `translateX(${swipeOffset.value}px)`,
|
|
218
|
+
opacity: String(swipeOpacity(swipeOffset.value, swipeThreshold)),
|
|
219
|
+
...swipeReleased.value ? {} : { transition: "none" }
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Клавиатурный эквивалент смахивания. `Escape` намеренно не берём: тостер не
|
|
224
|
+
* модальный слой, и перехват закрывал бы уведомление вместо диалога под ним.
|
|
225
|
+
*/
|
|
226
|
+
function onToastKeydown(event, toast) {
|
|
227
|
+
if (event.key !== "Delete" && event.key !== "Backspace") return;
|
|
228
|
+
event.preventDefault();
|
|
229
|
+
const index = visibleToasts.value.findIndex((item) => item.id === toast.id);
|
|
230
|
+
const next = visibleToasts.value[index + 1] ?? visibleToasts.value[index - 1];
|
|
231
|
+
dismiss(toast.id);
|
|
232
|
+
if (next) nextTick(() => toastElement(next.id)?.focus());
|
|
233
|
+
}
|
|
136
234
|
watchEffect(() => {
|
|
137
235
|
for (const toast of list.value) if (toast.timeoutMs > 0 && visibleIds.value.has(toast.id) && !paused.value) resume(toast.id);
|
|
138
236
|
else pause(toast.id);
|
|
@@ -145,7 +243,6 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
145
243
|
if (props.width === void 0) return void 0;
|
|
146
244
|
return { "--gr-toaster-width": typeof props.width === "number" ? `${props.width}px` : props.width };
|
|
147
245
|
});
|
|
148
|
-
const containerEl = ref(null);
|
|
149
246
|
/**
|
|
150
247
|
* Переводит фокус на верхний тост. Тост фокусируем только программно
|
|
151
248
|
* (`tabindex="-1"`): собственной остановкой `Tab` стек быть не должен, иначе
|
|
@@ -182,10 +279,10 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
182
279
|
"aria-label": resolvedRegionLabel.value,
|
|
183
280
|
class: ["fixed z-[var(--gr-z-toast)] w-[var(--gr-toaster-width,360px)] max-w-[calc(100vw-2rem)]", containerClass.value],
|
|
184
281
|
style: containerStyle.value,
|
|
185
|
-
onMouseenter: _cache[
|
|
186
|
-
onMouseleave: _cache[
|
|
187
|
-
onFocusin: _cache[
|
|
188
|
-
onFocusout: _cache[
|
|
282
|
+
onMouseenter: _cache[1] || (_cache[1] = ($event) => hovered.value = true),
|
|
283
|
+
onMouseleave: _cache[2] || (_cache[2] = ($event) => hovered.value = false),
|
|
284
|
+
onFocusin: _cache[3] || (_cache[3] = ($event) => focusWithin.value = true),
|
|
285
|
+
onFocusout: _cache[4] || (_cache[4] = ($event) => focusWithin.value = false)
|
|
189
286
|
}), [createVNode(TransitionGroup, {
|
|
190
287
|
tag: "div",
|
|
191
288
|
class: "grid gap-3",
|
|
@@ -202,10 +299,14 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
202
299
|
key: toast.id,
|
|
203
300
|
"data-gr-toast": "",
|
|
204
301
|
"data-tone": toast.tone,
|
|
302
|
+
"data-toast-id": toast.id,
|
|
205
303
|
role: metaFor(toast.tone).role,
|
|
206
304
|
"aria-atomic": "true",
|
|
207
305
|
tabindex: "-1",
|
|
208
|
-
class: "relative overflow-hidden rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] px-4 py-3 shadow-[var(--gr-shadow-2)] focus-visible:outline-none focus-visible:shadow-[var(--gr-shadow-2),0_0_0_2px_var(--gr-ring)]"
|
|
306
|
+
class: normalizeClass(["relative overflow-hidden rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] px-4 py-3 shadow-[var(--gr-shadow-2)] focus-visible:outline-none focus-visible:shadow-[var(--gr-shadow-2),0_0_0_2px_var(--gr-ring)]", __props.swipeDismiss ? "[touch-action:pan-y]" : ""]),
|
|
307
|
+
style: normalizeStyle(swipeStyle(toast)),
|
|
308
|
+
onPointerdown: _cache[0] || (_cache[0] = (...args) => unref(swipe).start && unref(swipe).start(...args)),
|
|
309
|
+
onKeydown: ($event) => onToastKeydown($event, toast)
|
|
209
310
|
}, [createElementVNode("div", _hoisted_3, [
|
|
210
311
|
createVNode(unref(GrIcon_default), {
|
|
211
312
|
size: "md",
|
|
@@ -261,12 +362,12 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
261
362
|
animationDuration: `${toast.timeoutMs}ms`,
|
|
262
363
|
animationPlayState: paused.value ? "paused" : "running"
|
|
263
364
|
})
|
|
264
|
-
}, null, 4)) : createCommentVNode("", true)],
|
|
365
|
+
}, null, 4)) : createCommentVNode("", true)], 46, _hoisted_2);
|
|
265
366
|
}), 128))]),
|
|
266
367
|
_: 3
|
|
267
368
|
})], 16, _hoisted_1)), [[unref(vHotkey), hotkeyBinding.value]])], 8, ["to", "disabled"]);
|
|
268
369
|
};
|
|
269
370
|
}
|
|
270
|
-
}), [["__scopeId", "data-v-
|
|
371
|
+
}), [["__scopeId", "data-v-3ad9ca7d"]]);
|
|
271
372
|
//#endregion
|
|
272
373
|
export { GrToaster_default as t };
|