From 05976ac8d6ecc6fd8ac2a04646f6919d0abea455 Mon Sep 17 00:00:00 2001 From: Lukas Harbarth Date: Thu, 4 Jul 2024 09:37:04 +0200 Subject: [PATCH 01/10] feat: move depreacted `Loader` to `compat` package & replace with `BusyIndicator` --- .../charts/src/internal/ChartContainer.tsx | 14 +- .../src/components/Loader/Loader.cy.tsx | 7 +- .../src/components/Loader/Loader.mdx | 0 .../src/components/Loader/Loader.module.css | 42 ++- .../src/components/Loader/Loader.stories.tsx | 13 +- .../src/components/Loader/index.tsx | 16 +- .../{main => compat}/src/enums/LoaderType.ts | 0 packages/compat/src/index.ts | 3 + .../DefaultLoadingComponent.module.css | 7 - .../defaults/LoadingComponent/index.tsx | 12 - .../src/components/AnalyticalTable/index.tsx | 277 +++++++++--------- .../main/src/components/Loader/Loader.cy.tsx | 32 -- .../src/components/Loader/Loader.module.css | 41 --- packages/main/src/enums/index.ts | 1 - packages/main/src/index.ts | 1 - 15 files changed, 209 insertions(+), 257 deletions(-) rename packages/{main => compat}/src/components/Loader/Loader.mdx (100%) rename packages/{main => compat}/src/components/Loader/Loader.stories.tsx (82%) rename packages/{main => compat}/src/components/Loader/index.tsx (77%) rename packages/{main => compat}/src/enums/LoaderType.ts (100%) delete mode 100644 packages/main/src/components/AnalyticalTable/defaults/LoadingComponent/DefaultLoadingComponent.module.css delete mode 100644 packages/main/src/components/AnalyticalTable/defaults/LoadingComponent/index.tsx delete mode 100644 packages/main/src/components/Loader/Loader.cy.tsx delete mode 100644 packages/main/src/components/Loader/Loader.module.css diff --git a/packages/charts/src/internal/ChartContainer.tsx b/packages/charts/src/internal/ChartContainer.tsx index 4add5f01fee..2e1773d9c51 100644 --- a/packages/charts/src/internal/ChartContainer.tsx +++ b/packages/charts/src/internal/ChartContainer.tsx @@ -1,7 +1,7 @@ -import { type CommonProps, Label, Loader } from '@ui5/webcomponents-react'; +import { type CommonProps, Label } from '@ui5/webcomponents-react'; import { useStylesheet } from '@ui5/webcomponents-react-base'; import { clsx } from 'clsx'; -import type { ComponentType, CSSProperties, ReactElement, ReactNode } from 'react'; +import type { ComponentType, ReactElement, ReactNode } from 'react'; import { Component, forwardRef } from 'react'; import { ResponsiveContainer } from 'recharts'; import { classNames, styleData } from './ChartContainer.module.css.js'; @@ -14,13 +14,6 @@ export interface ContainerProps extends CommonProps { resizeDebounce: number; } -const loaderStyles: CSSProperties = { - position: 'absolute', - top: 0, - left: 0, - right: 0 -}; - class ErrorBoundary extends Component<{ children: ReactNode }, { errorCount: number }> { state = { errorCount: 0 @@ -49,7 +42,8 @@ const ChartContainer = forwardRef((props, ref) =
{dataset?.length > 0 ? ( <> - {loading && } + {/*todo replace with BusyIndicator*/} + {loading && 'Loading...'} {children} diff --git a/packages/compat/src/components/Loader/Loader.cy.tsx b/packages/compat/src/components/Loader/Loader.cy.tsx index bf0de0e0def..bc24a99d998 100644 --- a/packages/compat/src/components/Loader/Loader.cy.tsx +++ b/packages/compat/src/components/Loader/Loader.cy.tsx @@ -1,9 +1,8 @@ +import { LoaderType } from '../../enums/index.js'; +import { Loader } from './index.js'; import { cypressPassThroughTestsFactory } from '@/cypress/support/utils'; -import type { LoaderType } from '@/packages/main'; -import { Loader } from '@/packages/main'; -// skip until component is moved to this package -describe.skip('Loader', () => { +describe('Loader', () => { it('indeterminate', () => { cy.mount(); cy.findByTestId('loader').should('have.css', 'animation-duration', '1.2s'); diff --git a/packages/main/src/components/Loader/Loader.mdx b/packages/compat/src/components/Loader/Loader.mdx similarity index 100% rename from packages/main/src/components/Loader/Loader.mdx rename to packages/compat/src/components/Loader/Loader.mdx diff --git a/packages/compat/src/components/Loader/Loader.module.css b/packages/compat/src/components/Loader/Loader.module.css index ae519ad00d1..c5cb405c9d3 100644 --- a/packages/compat/src/components/Loader/Loader.module.css +++ b/packages/compat/src/components/Loader/Loader.module.css @@ -1,3 +1,41 @@ -.dummy { - background-color: red; +.loader { + position: relative; + height: 0.25rem; + width: 100%; + + &:before { + content: ''; + position: absolute; + left: 0; + width: 100%; + height: 100%; + background-color: var(--sapContent_BusyColor); + opacity: 0.15; + } + + &.loaderDeterminate { + background: linear-gradient(to right, var(--sapContent_BusyColor), var(--sapContent_BusyColor)) repeat-y; + } + + &.loaderIndeterminate { + background-size: 40%; + background: linear-gradient( + to right, + transparent 0px, + var(--sapContent_BusyColor) calc(50% - 2rem), + var(--sapContent_BusyColor) calc(50% + 2rem), + transparent 100% + ) + repeat-y; + animation: scroll 1.2s linear infinite; + } +} + +@keyframes scroll { + 0% { + background-position: -100% 0; + } + 100% { + background-position: 200% 0; + } } diff --git a/packages/main/src/components/Loader/Loader.stories.tsx b/packages/compat/src/components/Loader/Loader.stories.tsx similarity index 82% rename from packages/main/src/components/Loader/Loader.stories.tsx rename to packages/compat/src/components/Loader/Loader.stories.tsx index 3b9d0b7b981..c19943b568d 100644 --- a/packages/main/src/components/Loader/Loader.stories.tsx +++ b/packages/compat/src/components/Loader/Loader.stories.tsx @@ -1,22 +1,19 @@ import type { Meta, StoryObj } from '@storybook/react'; import activateIcon from '@ui5/webcomponents-icons/dist/activate.js'; +import { Card, CardHeader, FlexBox, FlexBoxDirection, Icon, Text } from '@ui5/webcomponents-react'; import { useEffect, useRef, useState } from 'react'; -import { FlexBoxDirection, LoaderType } from '../../enums/index.js'; -import { Card } from '../../webComponents/Card/index.js'; -import { CardHeader } from '../../webComponents/CardHeader/index.js'; -import { Icon } from '../../webComponents/Icon/index.js'; -import { Text } from '../../webComponents/Text/index.js'; -import { FlexBox } from '../FlexBox/index.js'; +import { LoaderType } from '../../enums/LoaderType.js'; import { Loader } from './index.js'; const meta = { - title: 'User Feedback / Loader', + title: 'Loader', component: Loader, argTypes: {}, args: { type: LoaderType.Indeterminate, progress: '60%' - } + }, + tags: ['package:@ui5/webcomponents-compat'] } satisfies Meta; export default meta; diff --git a/packages/main/src/components/Loader/index.tsx b/packages/compat/src/components/Loader/index.tsx similarity index 77% rename from packages/main/src/components/Loader/index.tsx rename to packages/compat/src/components/Loader/index.tsx index 9cb3daddeb9..5957db828bc 100644 --- a/packages/main/src/components/Loader/index.tsx +++ b/packages/compat/src/components/Loader/index.tsx @@ -1,12 +1,14 @@ 'use client'; +import type { CommonProps } from '@ui5/webcomponents-react'; import { deprecationNotice, useI18nBundle, useStylesheet } from '@ui5/webcomponents-react-base'; import { clsx } from 'clsx'; import type { CSSProperties } from 'react'; import { forwardRef, useEffect, useState } from 'react'; -import { LoaderType } from '../../enums/index.js'; -import { PLEASE_WAIT } from '../../i18n/i18n-defaults.js'; -import type { CommonProps } from '../../types/index.js'; +// todo: sb won't start with this (maybe because of vite.config alias paths?) +// import { PLEASE_WAIT } from '@ui5/webcomponents-react/dist/i18n/i18n-defaults.js'; +import { PLEASE_WAIT } from '../../../../main/src/i18n/i18n-defaults.js'; +import { LoaderType } from '../../enums/LoaderType.js'; import { classNames, styleData } from './Loader.module.css.js'; export interface LoaderPropTypes extends CommonProps { @@ -35,12 +37,10 @@ export interface LoaderPropTypes extends CommonProps { } /** - * The `Loader` signals that an operation is currently being executed. It uses as little space as possible to allow the user to interact with the UI.
- * It can be used to signal a data update on an already existing dataset, or where an expansion will happen. - * - * __Note:__ This component is __deprecated__ and will be removed with our next major release (v2.0.0)! Please use the [BusyIndicator](https://sap.github.io/ui5-webcomponents-react/?path=/docs/user-feedback-busyindicator--docs) instead. + * __Note__: There is no longer a concept of a Loader component defined by the UX guidelines! To indicate a loading state, please use the `BusyIndicator` instead. For backwards compatibility, the Loader is still available in the `@ui5/webcomponents-react-compat` package, but it may lack accessibility features and no longer receives feature updates. * - * @deprecated This component is deprecated and will be removed with our next major release (v2.0.0)! Please use the [BusyIndicator](https://sap.github.io/ui5-webcomponents-react/?path=/docs/user-feedback-busyindicator--docs) instead. + * The `Loader` signals that an operation is currently being executed. It uses as little space as possible to allow the user to interact with the UI. + * It can be used to signal a data update on an already existing dataset, or where an expansion will happen. */ const Loader = forwardRef((props, ref) => { const { className, type = LoaderType.Indeterminate, progress = '0px', slot, style, delay = 0, ...rest } = props; diff --git a/packages/main/src/enums/LoaderType.ts b/packages/compat/src/enums/LoaderType.ts similarity index 100% rename from packages/main/src/enums/LoaderType.ts rename to packages/compat/src/enums/LoaderType.ts diff --git a/packages/compat/src/index.ts b/packages/compat/src/index.ts index bc3b8049e89..eddc7052577 100644 --- a/packages/compat/src/index.ts +++ b/packages/compat/src/index.ts @@ -3,3 +3,6 @@ export * from './components/TableCell/index.js'; export * from './components/TableColumn/index.js'; export * from './components/TableGroupRow/index.js'; export * from './components/TableRow/index.js'; +export * from './components/Loader/index.js'; + +export { LoaderType } from './enums/LoaderType.js'; diff --git a/packages/main/src/components/AnalyticalTable/defaults/LoadingComponent/DefaultLoadingComponent.module.css b/packages/main/src/components/AnalyticalTable/defaults/LoadingComponent/DefaultLoadingComponent.module.css deleted file mode 100644 index 32f66e17e9a..00000000000 --- a/packages/main/src/components/AnalyticalTable/defaults/LoadingComponent/DefaultLoadingComponent.module.css +++ /dev/null @@ -1,7 +0,0 @@ -.loader { - position: absolute; - inset-block-start: --_ui5wcr-AnalyticalTableHeaderRowHeight; - inset-inline-start: 0; - inset-inline-end: 0; - z-index: 1; -} diff --git a/packages/main/src/components/AnalyticalTable/defaults/LoadingComponent/index.tsx b/packages/main/src/components/AnalyticalTable/defaults/LoadingComponent/index.tsx deleted file mode 100644 index a24eef10354..00000000000 --- a/packages/main/src/components/AnalyticalTable/defaults/LoadingComponent/index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { useStylesheet } from '@ui5/webcomponents-react-base'; -import { Loader } from '../../../Loader/index.js'; -import { classNames, styleData } from './DefaultLoadingComponent.module.css.js'; - -const DefaultLoadingComponent = ({ style }) => { - useStylesheet(styleData, DefaultLoadingComponent.displayName); - return ; -}; - -DefaultLoadingComponent.displayName = 'DefaultLoadingComponent'; - -export { DefaultLoadingComponent }; diff --git a/packages/main/src/components/AnalyticalTable/index.tsx b/packages/main/src/components/AnalyticalTable/index.tsx index 73718677726..ed652369137 100644 --- a/packages/main/src/components/AnalyticalTable/index.tsx +++ b/packages/main/src/components/AnalyticalTable/index.tsx @@ -48,12 +48,13 @@ import { SELECT_PRESS_SPACE, UNSELECT_PRESS_SPACE } from '../../i18n/i18n-defaults.js'; +import { addCustomCSSWithScoping } from '../../internal/addCustomCSSWithScoping.js'; +import { BusyIndicator } from '../../webComponents/BusyIndicator/index.js'; import { Text } from '../../webComponents/Text/index.js'; import { FlexBox } from '../FlexBox/index.js'; import { classNames, styleData } from './AnalyticalTable.module.css.js'; import { ColumnHeaderContainer } from './ColumnHeader/ColumnHeaderContainer.js'; import { DefaultColumn } from './defaults/Column/index.js'; -import { DefaultLoadingComponent } from './defaults/LoadingComponent/index.js'; import { TablePlaceholder } from './defaults/LoadingComponent/TablePlaceholder.js'; import { DefaultNoDataComponent } from './defaults/NoDataComponent/index.js'; import { useA11y } from './hooks/useA11y.js'; @@ -96,6 +97,20 @@ const measureElement = (el: HTMLElement) => { return el.offsetHeight; }; +//todo: add feature request for parts or even a fix if this turns out to be a bug +addCustomCSSWithScoping( + 'ui5-busy-indicator', + ` +:host([data-component-name="AnalyticalTableBusyIndicator"]) .ui5-busy-indicator-root { + display: initial; +} +:host([data-component-name="AnalyticalTableBusyIndicator"]) .ui5-busy-indicator-busy-area:focus { +border-radius: 0; +} + + ` +); + /** * The `AnalyticalTable` provides a set of convenient functions for responsive table design, including virtualization of rows and columns, infinite scrolling and customizable columns that will, unless otherwise defined, distribute the available space equally among themselves. * It also provides several possibilities for working with the data, including sorting, filtering, grouping and aggregation. @@ -155,7 +170,6 @@ const AnalyticalTable = forwardRef )} {extension &&
{extension}
} - - {showOverlay && ( - <> - - {invalidTableA11yText} - -
- - )} -
+ -
-
- {headerGroups.map((headerGroup) => { - let headerProps: Record = {}; - if (headerGroup.getHeaderGroupProps) { - headerProps = headerGroup.getHeaderGroupProps(); - } - return ( - tableRef.current && ( - + + {invalidTableA11yText} + +
+ + )} +
+
+
+ {headerGroups.map((headerGroup) => { + let headerProps: Record = {}; + if (headerGroup.getHeaderGroupProps) { + headerProps = headerGroup.getHeaderGroupProps(); + } + return ( + tableRef.current && ( + + ) + ); + })} + {loading && rows?.length === 0 && ( + + )} + {!loading && rows?.length === 0 && ( + + )} + {rows?.length > 0 && tableRef.current && ( + + - ) - ); - })} - {loading && rows?.length > 0 && } - {loading && rows?.length === 0 && ( - - )} - {!loading && rows?.length === 0 && ( - - )} - {rows?.length > 0 && tableRef.current && ( - + )} +
+ {(additionalEmptyRowsCount || tableState.isScrollable === undefined || tableState.isScrollable) && ( + - - + nativeScrollbar={className?.includes('ui5-content-native-scrollbars')} + /> )} -
- {(additionalEmptyRowsCount || tableState.isScrollable === undefined || tableState.isScrollable) && ( - + {visibleRowCountMode === AnalyticalTableVisibleRowCountMode.Interactive && ( + 0} + analyticalTableRef={analyticalTableRef} + dispatch={dispatch} + extensionsHeight={extensionsHeight} + internalRowHeight={internalRowHeight} + portalContainer={portalContainer} + rowsLength={rows.length} + visibleRows={internalVisibleRowCount} + handleOnLoadMore={handleOnLoadMore} /> )} - - {visibleRowCountMode === AnalyticalTableVisibleRowCountMode.Interactive && ( - 0} - analyticalTableRef={analyticalTableRef} - dispatch={dispatch} - extensionsHeight={extensionsHeight} - internalRowHeight={internalRowHeight} - portalContainer={portalContainer} - rowsLength={rows.length} - visibleRows={internalVisibleRowCount} - handleOnLoadMore={handleOnLoadMore} - /> - )} +