diff --git a/.storybook/main.js b/.storybook/main.js index 74cc60861ab..c2b18054dd9 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,7 +1,5 @@ -const { highlightLog } = require('../scripts/utils'); const path = require('path'); const PATHS = require('../config/paths'); -const dedent = require('dedent'); require('dotenv').config({ path: path.join(PATHS.root, '.env') }); @@ -15,7 +13,12 @@ const DEPENDENCY_REGEX = BUILD_FOR_IE11 module.exports = { stories: ['../docs/**/*.stories.mdx', '../packages/**/*.stories.mdx', '../packages/**/*.stories.[tj]sx'], - addons: ['@storybook/addon-knobs', '@storybook/addon-docs', '@storybook/addon-actions'], + addons: [ + '@storybook/addon-toolbars', + '@storybook/addon-docs', + '@storybook/addon-controls', + '@storybook/addon-actions' + ], webpack: async (config, { configType }) => { // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION' // You can change the configuration based on that. @@ -27,35 +30,6 @@ module.exports = { type: 'javascript/auto' }); - const tsLoader = { - test: /\.tsx?$/, - include: PATHS.packages, - use: [ - { - loader: require.resolve('babel-loader'), - options: { - envName: 'esm', - configFile: path.resolve(PATHS.root, 'babel.config.js') - } - } - ] - }; - - if (IS_RELEASE_BUILD) { - highlightLog('Warning: Prop Types Table Generation is active'); - tsLoader.use.push(require.resolve('react-docgen-typescript-loader')); - } else { - highlightLog('Info: Prop Types Table Generation is disabled'); - console.log(dedent` - The Prop Table Generation is very expensive during build-time and therefore disabled by default. - If you need Prop-Tables, you can activate it by adding a '.env' file to the root of the project with the following content: - - UI5_WEBCOMPONENTS_FOR_REACT_RELEASE_BUILD=true\n\n - `); - } - - config.module.rules.push(tsLoader); - if ((IS_RELEASE_BUILD && configType === 'PRODUCTION') || BUILD_FOR_IE11) { config.module.rules.push({ test: /\.(js|mjs)$/, @@ -102,8 +76,6 @@ module.exports = { } }); } - - config.resolve.extensions.push('.ts', '.tsx'); config.resolve.alias = { ...config.resolve.alias, '@shared': path.join(PATHS.root, 'shared'), diff --git a/.storybook/preview.js b/.storybook/preview.js index 9e5bf4ebe36..8e9eed36757 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,4 +1,3 @@ -import { select, withKnobs } from '@storybook/addon-knobs'; import { makeDecorator } from '@storybook/addons'; import { addDecorator, addParameters } from '@storybook/react'; import { setTheme } from '@ui5/webcomponents-base/dist/config/Theme'; @@ -23,11 +22,11 @@ addParameters({ : a[1].id.localeCompare(b[1].id, undefined, { numeric: true, caseFirst: 'upper' }); }, showRoots: true - } + }, + passArgsFirst: true, + actions: { argTypesRegex: '^on.*' } }); -addDecorator(withKnobs); - const ThemeContainer = ({ theme, contentDensity, children, direction }) => { useEffect(() => { if (contentDensity === ContentDensity.Compact) { @@ -37,9 +36,9 @@ const ThemeContainer = ({ theme, contentDensity, children, direction }) => { } }, [contentDensity]); - // useEffect(() => { - // document.querySelector('html').setAttribute('dir', direction.toLowerCase()); - // }, [direction]); + useEffect(() => { + document.querySelector('html').setAttribute('dir', direction); + }, [direction]); useEffect(() => { setTheme(theme); @@ -54,9 +53,9 @@ const withQuery = makeDecorator({ wrapper: (getStory, context) => { return ( {getStory(context)} @@ -65,3 +64,74 @@ const withQuery = makeDecorator({ }); addDecorator(withQuery); + +export const globalArgTypes = { + theme: { + name: 'Theme', + description: 'Fiori Theme', + defaultValue: Themes.sap_fiori_3, + toolbar: { + icon: 'paintbrush', + items: [ + { + value: Themes.sap_fiori_3, + title: Themes.sap_fiori_3 + }, + { + value: Themes.sap_fiori_3_dark, + title: Themes.sap_fiori_3_dark + }, + { + value: Themes.sap_belize, + title: Themes.sap_belize + }, + { + value: Themes.sap_belize_hcb, + title: Themes.sap_belize_hcb + }, + { + value: Themes.sap_belize_hcw, + title: Themes.sap_belize_hcw + } + ] + } + }, + contentDensity: { + name: 'Content Density', + description: 'Content Density', + defaultValue: ContentDensity.Cozy, + toolbar: { + icon: 'component', + items: [ + { + value: ContentDensity.Cozy, + title: ContentDensity.Cozy + }, + { + value: ContentDensity.Compact, + title: ContentDensity.Compact + } + ] + } + }, + direction: { + name: 'Direction', + description: 'Text Direction', + defaultValue: 'ltr', + toolbar: { + icon: 'transfer', + items: [ + { + value: 'ltr', + title: 'LTR', + icon: 'arrowrightalt' + }, + { + value: 'rtl', + title: 'RTL', + icon: 'arrowleftalt' + } + ] + } + } +}; diff --git a/CHANGELOG.md b/CHANGELOG.md index c61b3d8c5be..d2dbfa9ec51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,23 +3,6 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. -# [0.10.0-rc.1](https://github.com/SAP/ui5-webcomponents-react/compare/v0.10.0-rc.0...v0.10.0-rc.1) (2020-05-25) - - -### Bug Fixes - -* **AnalyticalTable:** remove padding and scrollbar from select-all header cell ([#536](https://github.com/SAP/ui5-webcomponents-react/issues/536)) ([97158a3](https://github.com/SAP/ui5-webcomponents-react/commit/97158a39663cf40c424829a86962df7070a0dacb)), closes [#532](https://github.com/SAP/ui5-webcomponents-react/issues/532) -* **DurationPicker:** use correct value for defaultProp maxValue ([#529](https://github.com/SAP/ui5-webcomponents-react/issues/529)) ([888d069](https://github.com/SAP/ui5-webcomponents-react/commit/888d069a86784c4833f9257abc67e569be3dd231)) - - -### Features - -* **StyleClassHelper:** add putIfPresent method ([#539](https://github.com/SAP/ui5-webcomponents-react/issues/539)) ([0ae0785](https://github.com/SAP/ui5-webcomponents-react/commit/0ae078554dd0e7e6a1424de6755ec02fa15bb12e)) - - - - - # [0.10.0-rc.0](https://github.com/SAP/ui5-webcomponents-react/compare/v0.9.5...v0.10.0-rc.0) (2020-05-19) diff --git a/config/jestsetup.ts b/config/jestsetup.ts index bb44aba718c..12522411d5c 100644 --- a/config/jestsetup.ts +++ b/config/jestsetup.ts @@ -6,7 +6,6 @@ import { createSerializer } from 'enzyme-to-json'; import ResizeObserver from 'resize-observer-polyfill'; import 'intersection-observer'; import '@ui5/webcomponents/dist/generated/json-imports/i18n'; -import 'whatwg-fetch'; // React 16 Enzyme adapter Enzyme.configure({ adapter: new Adapter() }); diff --git a/lerna.json b/lerna.json index efe573f0380..3309cb0e6b1 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/*" ], - "version": "0.10.0-rc.1", + "version": "0.10.0-rc.0", "npmClient": "yarn", "useWorkspaces": true, "command": { diff --git a/package.json b/package.json index 079e6d09d69..6942c4b254c 100644 --- a/package.json +++ b/package.json @@ -101,8 +101,7 @@ "targz": "^1.0.1", "tmp": "^0.1.0", "tslint": "^6.1.2", - "typescript": "^3.8.3", - "whatwg-fetch": "^3.0.0" + "typescript": "^3.8.3" }, "resolutions": { "@types/react": "16.9.34", diff --git a/packages/base/CHANGELOG.md b/packages/base/CHANGELOG.md index 304b5bdda76..29e2e81875f 100644 --- a/packages/base/CHANGELOG.md +++ b/packages/base/CHANGELOG.md @@ -3,17 +3,6 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. -# [0.10.0-rc.1](https://github.com/SAP/ui5-webcomponents-react/compare/v0.10.0-rc.0...v0.10.0-rc.1) (2020-05-25) - - -### Features - -* **StyleClassHelper:** add putIfPresent method ([#539](https://github.com/SAP/ui5-webcomponents-react/issues/539)) ([0ae0785](https://github.com/SAP/ui5-webcomponents-react/commit/0ae078554dd0e7e6a1424de6755ec02fa15bb12e)) - - - - - # [0.10.0-rc.0](https://github.com/SAP/ui5-webcomponents-react/compare/v0.9.5...v0.10.0-rc.0) (2020-05-19) diff --git a/packages/base/package.json b/packages/base/package.json index 7cf939a9555..ca42f6434d1 100644 --- a/packages/base/package.json +++ b/packages/base/package.json @@ -1,6 +1,6 @@ { "name": "@ui5/webcomponents-react-base", - "version": "0.10.0-rc.1", + "version": "0.10.0-rc.0", "description": "Base for ui5-webcomponents-react", "main": "index.cjs.js", "module": "index.esm.js", diff --git a/packages/base/src/hooks/useI18nBundle.ts b/packages/base/src/hooks/useI18nBundle.ts index ca0eed4f89c..1a614a26004 100644 --- a/packages/base/src/hooks/useI18nBundle.ts +++ b/packages/base/src/hooks/useI18nBundle.ts @@ -1,40 +1,20 @@ import { fetchI18nBundle, getI18nBundle } from '@ui5/webcomponents-base/dist/i18nBundle'; import { useEffect, useState } from 'react'; -type TextWithDefault = { key: string; defaultText: string }; -type TextWithPlaceholders = [TextWithDefault, ...string[]]; - interface I18nBundle { - getText: (textObj: TextWithDefault, ...args: any) => string; + getText: (textObj: { key: string; defaultText: string }, ...args: any) => string; } -const resolveTranslations = (bundle, texts) => { - return texts.map((text) => { - if (Array.isArray(text)) { - const [key, ...replacements] = text; - return bundle.getText(key, replacements); - } - return bundle.getText(text); - }); -}; - -export const useI18nText = (bundleName: string, ...texts: (TextWithDefault | TextWithPlaceholders)[]): string[] => { - const i18nBundle: I18nBundle = getI18nBundle(bundleName); - const [translations, setTranslations] = useState(resolveTranslations(i18nBundle, texts)); +export const useI18nBundle = (bundleName): I18nBundle => { + const [bundle, setBundle] = useState(getI18nBundle(bundleName)); useEffect(() => { const fetchAndLoadBundle = async () => { await fetchI18nBundle(bundleName); - setTranslations((prev) => { - const next = resolveTranslations(i18nBundle, texts); - if (prev.length === next.length && prev.every((translation, index) => next[index] === translation)) { - return prev; - } - return next; - }); + setBundle(getI18nBundle(bundleName)); }; fetchAndLoadBundle(); - }, [fetchI18nBundle, bundleName, texts]); + }, []); - return translations; + return bundle; }; diff --git a/packages/base/src/lib/hooks.ts b/packages/base/src/lib/hooks.ts index 56cbe7a0aa8..962bc294c5c 100644 --- a/packages/base/src/lib/hooks.ts +++ b/packages/base/src/lib/hooks.ts @@ -1,6 +1,6 @@ import { useConsolidatedRef } from '../hooks/useConsolidatedRef'; -import { useI18nText } from '../hooks/useI18nBundle'; +import { useI18nBundle } from '../hooks/useI18nBundle'; import { usePassThroughHtmlProps } from '../hooks/usePassThroughHtmlProps'; import { useViewportRange } from '../hooks/useViewportRange'; -export { useConsolidatedRef, usePassThroughHtmlProps, useViewportRange, useI18nText }; +export { useConsolidatedRef, usePassThroughHtmlProps, useViewportRange, useI18nBundle }; diff --git a/packages/base/src/styling/CssSizeVariables.ts b/packages/base/src/styling/CssSizeVariables.ts index 6c4965f4d9f..6b34b12a4d8 100644 --- a/packages/base/src/styling/CssSizeVariables.ts +++ b/packages/base/src/styling/CssSizeVariables.ts @@ -14,7 +14,6 @@ export enum CssSizeVariablesNames { sapWcrAnalyticalTableTreePaddingLevel1 = 'sapWcrAnalyticalTableTreePaddingLevel1', sapWcrAnalyticalTableTreePaddingLevel2 = 'sapWcrAnalyticalTableTreePaddingLevel2', sapWcrAnalyticalTableTreePaddingLevel3 = 'sapWcrAnalyticalTableTreePaddingLevel3', - sapWcrCheckBoxWidthHeight = 'sapWcrCheckBoxWidthHeight', sapWcrAnalyticalTableSelectionColumnWidth = 'sapWcrAnalyticalTableSelectionColumnWidth' } @@ -43,7 +42,6 @@ export const cssVariablesStyles = ` --${CssSizeVariablesNames.sapWcrAnalyticalTableTreePaddingLevel1}:1.5rem; --${CssSizeVariablesNames.sapWcrAnalyticalTableTreePaddingLevel2}:2.25rem; --${CssSizeVariablesNames.sapWcrAnalyticalTableTreePaddingLevel3}:2.75rem; - --${CssSizeVariablesNames.sapWcrCheckBoxWidthHeight}:2.75rem; --${CssSizeVariablesNames.sapWcrAnalyticalTableSelectionColumnWidth}:55px; } @@ -65,7 +63,6 @@ export const cssVariablesStyles = ` --${CssSizeVariablesNames.sapWcrAnalyticalTableTreePaddingLevel1}:1rem; --${CssSizeVariablesNames.sapWcrAnalyticalTableTreePaddingLevel2}:1.5rem; --${CssSizeVariablesNames.sapWcrAnalyticalTableTreePaddingLevel3}:2rem; - --${CssSizeVariablesNames.sapWcrCheckBoxWidthHeight}:2rem; --${CssSizeVariablesNames.sapWcrAnalyticalTableSelectionColumnWidth}:40px; } `; diff --git a/packages/base/src/styling/StyleClassHelper.test.ts b/packages/base/src/styling/StyleClassHelper.test.ts deleted file mode 100644 index f1c00729f5e..00000000000 --- a/packages/base/src/styling/StyleClassHelper.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { StyleClassHelper } from './StyleClassHelper'; - -describe('StyleClassHelper', () => { - test('add class names', () => { - const helper = StyleClassHelper.of('class1', 'class2'); - expect(helper.className).toEqual(`class1 class2`); - }); - - test('put new classes', () => { - const helper = StyleClassHelper.of('firstClass'); - helper.put('secondClass'); - expect(helper.className).toEqual(`firstClass secondClass`); - }); - - test('putIfPresent', () => { - const helper = StyleClassHelper.of('firstClass'); - helper.put('secondClass'); - helper.putIfPresent('ifPresent1'); - helper.putIfPresent('ifPresent2', 'ifPresent3'); - helper.putIfPresent(true === false && 'shouldNotBeThere1', 'a' === 'a' && 'ifPresent4'); - - expect(helper.className).toEqual('firstClass secondClass ifPresent1 ifPresent2 ifPresent3 ifPresent4'); - }); - - test('className, toString and valueOf return same value', () => { - const helper = StyleClassHelper.of('class1', 'class2'); - expect(helper.toString()).toEqual(`class1 class2`); - expect(helper.valueOf()).toEqual(`class1 class2`); - expect(helper.className).toEqual(`class1 class2`); - }); -}); diff --git a/packages/base/src/styling/StyleClassHelper.ts b/packages/base/src/styling/StyleClassHelper.ts index eb71c7b4724..199ef0c0500 100644 --- a/packages/base/src/styling/StyleClassHelper.ts +++ b/packages/base/src/styling/StyleClassHelper.ts @@ -2,40 +2,28 @@ * Created by d059190 at 16.03.18 */ -class StyleClassHelper { +class StyleClassHelper extends String { private classes: string[] = []; constructor(...classes: string[]) { + super(); this.classes = [...classes]; } - put(...clazz: string[]): StyleClassHelper { + put(...clazz: string[]) { this.classes.push(...clazz); return this; } - putIfPresent(...clazzes: (string | null | undefined)[]): StyleClassHelper { - for (const clazz of clazzes) { - if (clazz) { - this.classes.push(clazz); - } - } - return this; - } - - valueOf(): string { - return this.className; - } - - toString(): string { - return this.className; + valueOf() { + return this.classes.join(' '); } - get className(): string { - return this.classes.join(' '); + toString() { + return this.valueOf(); } - static of(...classes: string[]): StyleClassHelper { + static of(...classes: string[]) { return new StyleClassHelper().put(...classes); } } diff --git a/packages/main/CHANGELOG.md b/packages/main/CHANGELOG.md index d434499c45b..635b5eba361 100644 --- a/packages/main/CHANGELOG.md +++ b/packages/main/CHANGELOG.md @@ -3,18 +3,6 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. -# [0.10.0-rc.1](https://github.com/SAP/ui5-webcomponents-react/compare/v0.10.0-rc.0...v0.10.0-rc.1) (2020-05-25) - - -### Bug Fixes - -* **AnalyticalTable:** remove padding and scrollbar from select-all header cell ([#536](https://github.com/SAP/ui5-webcomponents-react/issues/536)) ([97158a3](https://github.com/SAP/ui5-webcomponents-react/commit/97158a39663cf40c424829a86962df7070a0dacb)), closes [#532](https://github.com/SAP/ui5-webcomponents-react/issues/532) -* **DurationPicker:** use correct value for defaultProp maxValue ([#529](https://github.com/SAP/ui5-webcomponents-react/issues/529)) ([888d069](https://github.com/SAP/ui5-webcomponents-react/commit/888d069a86784c4833f9257abc67e569be3dd231)) - - - - - # [0.10.0-rc.0](https://github.com/SAP/ui5-webcomponents-react/compare/v0.9.5...v0.10.0-rc.0) (2020-05-19) diff --git a/packages/main/package.json b/packages/main/package.json index f7cb5e525d3..b76b1d55659 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -1,6 +1,6 @@ { "name": "@ui5/webcomponents-react", - "version": "0.10.0-rc.1", + "version": "0.10.0-rc.0", "description": "React Wrapper for UI5 Web Components and additional components", "main": "index.cjs.js", "module": "index.esm.js", @@ -32,7 +32,7 @@ }, "dependencies": { "@babel/runtime": "7.9.6", - "@ui5/webcomponents-react-base": "^0.10.0-rc.1", + "@ui5/webcomponents-react-base": "^0.10.0-rc.0", "lodash.debounce": "^4.0.8", "react-content-loader": "^5.0.4", "react-jss": "10.1.1", diff --git a/packages/main/src/components/AnalyticalCardHeader/index.tsx b/packages/main/src/components/AnalyticalCardHeader/index.tsx index aa8f3361d24..8acc1a22d47 100644 --- a/packages/main/src/components/AnalyticalCardHeader/index.tsx +++ b/packages/main/src/components/AnalyticalCardHeader/index.tsx @@ -1,5 +1,5 @@ import { createComponentStyles } from '@ui5/webcomponents-react-base/lib/createComponentStyles'; -import { useI18nText, usePassThroughHtmlProps } from '@ui5/webcomponents-react-base/lib/hooks'; +import { useI18nBundle, usePassThroughHtmlProps } from '@ui5/webcomponents-react-base/lib/hooks'; import { StyleClassHelper } from '@ui5/webcomponents-react-base/lib/StyleClassHelper'; import { enrichEventWithDetails } from '@ui5/webcomponents-react-base/lib/Utils'; import { DEVIATION, TARGET } from '@ui5/webcomponents-react/dist/assets/i18n/i18n-defaults'; @@ -126,7 +126,7 @@ export const AnalyticalCardHeader: FC = forwardRe const passThroughProps = usePassThroughHtmlProps(props, ['onHeaderPress']); - const [targetText, deviationText] = useI18nText('@ui5/webcomponents-react', TARGET, DEVIATION); + const i18nBundle = useI18nBundle('@ui5/webcomponents-react'); return (
= forwardRe className={classes.targetAndDeviationColumn} wrap={FlexBoxWrap.NoWrap} > - {targetText} + {i18nBundle.getText(TARGET)} {target} )} @@ -182,7 +182,7 @@ export const AnalyticalCardHeader: FC = forwardRe className={classes.targetAndDeviationColumn} wrap={FlexBoxWrap.NoWrap} > - {deviationText} + {i18nBundle.getText(DEVIATION)} {deviation} )} diff --git a/packages/main/src/components/AnalyticalTable/AnayticalTable.jss.ts b/packages/main/src/components/AnalyticalTable/AnayticalTable.jss.ts index 8f44b6b68d4..b1f36b339a8 100644 --- a/packages/main/src/components/AnalyticalTable/AnayticalTable.jss.ts +++ b/packages/main/src/components/AnalyticalTable/AnayticalTable.jss.ts @@ -22,6 +22,7 @@ const styles = { th: { backgroundColor: ThemingParameters.sapList_HeaderBackground, height: CssSizeVariables.sapWcrAnalyticalTableRowHeight, + fontWeight: 'normal', color: ThemingParameters.sapList_HeaderTextColor, borderTop: `1px solid ${ThemingParameters.sapList_BorderColor}`, borderBottom: `1px solid ${ThemingParameters.sapList_BorderColor}`, @@ -40,50 +41,37 @@ const styles = { }, tbody: { position: 'relative', + zIndex: 0, backgroundColor: ThemingParameters.sapList_Background, overflowX: 'hidden', overflowY: 'auto' }, alternateRowColor: { - backgroundColor: ThemingParameters.sapList_AlternatingBackground + backgroundColor: ThemingParameters.sapList_HeaderBackground }, + emptyRow: {}, tr: { position: 'absolute', top: 0, left: 0, width: '100%', + zIndex: 0, color: ThemingParameters.sapList_TextColor, borderBottom: `1px solid ${ThemingParameters.sapList_BorderColor}`, boxSizing: 'border-box', display: 'flex', height: CssSizeVariables.sapWcrAnalyticalTableRowHeight, - '&:hover': { - backgroundColor: ThemingParameters.sapList_Hover_Background - }, '&[data-is-selected]': { borderBottom: `1px solid ${ThemingParameters.sapList_SelectionBorderColor}`, - backgroundColor: ThemingParameters.sapList_SelectionBackgroundColor + backgroundColor: `${ThemingParameters.sapList_SelectionBackgroundColor} !important` }, '&[data-is-selected]:hover': { - backgroundColor: ThemingParameters.sapList_Hover_SelectionBackground - } - }, - trActive: { - '&:hover': { - cursor: 'pointer' - }, - '&:active': { - backgroundColor: ThemingParameters.sapList_Active_Background, - '& $tableCell': { - borderRight: `1px solid ${ThemingParameters.sapList_Active_Background}`, - color: `${ThemingParameters.sapList_Active_TextColor}`, - '--sapTextColor': ThemingParameters.sapList_Active_TextColor - } + backgroundColor: `${ThemingParameters.sapList_Hover_SelectionBackground} !important` } }, tableGroupHeader: { '&$tr': { - backgroundColor: `${ThemingParameters.sapList_TableGroupHeaderBackground}`, + backgroundColor: `${ThemingParameters.sapList_TableGroupHeaderBackground} !important`, border: `1px solid ${ThemingParameters.sapList_TableGroupHeaderBorderColor}`, color: ThemingParameters.sapList_TextColor, '& $tableCell': { @@ -91,6 +79,23 @@ const styles = { } } }, + selectable: { + '& $tr:hover:not($emptyRow)': { + backgroundColor: ThemingParameters.sapList_Hover_Background, + '&:not($selectionModeRowSelector)': { + cursor: 'pointer' + } + }, + '& $tr:active:not([data-is-selected]):not($tableGroupHeader):not($emptyRow):not($selectionModeRowSelector)': { + backgroundColor: ThemingParameters.sapList_Active_Background, + '& $tableCell': { + borderRight: `1px solid ${ThemingParameters.sapList_Active_Background}`, + color: `${ThemingParameters.sapList_Active_TextColor}`, + '--sapTextColor': ThemingParameters.sapList_Active_TextColor + } + } + }, + selectionModeRowSelector: {}, tableCell: { height: CssSizeVariables.sapWcrAnalyticalTableRowHeight, boxSizing: 'border-box', diff --git a/packages/main/src/components/AnalyticalTable/ColumnHeader/ColumnHeaderModal.tsx b/packages/main/src/components/AnalyticalTable/ColumnHeader/ColumnHeaderModal.tsx index 80b3f6da9bc..65505729f91 100644 --- a/packages/main/src/components/AnalyticalTable/ColumnHeader/ColumnHeaderModal.tsx +++ b/packages/main/src/components/AnalyticalTable/ColumnHeader/ColumnHeaderModal.tsx @@ -1,5 +1,5 @@ import '@ui5/webcomponents-icons/dist/icons/decline'; -import { useI18nText } from '@ui5/webcomponents-react-base/lib/hooks'; +import { useI18nBundle } from '@ui5/webcomponents-react-base/lib/hooks'; import { ThemingParameters } from '@ui5/webcomponents-react-base/lib/ThemingParameters'; import { enrichEventWithDetails } from '@ui5/webcomponents-react-base/lib/Utils'; import { @@ -38,14 +38,7 @@ export const ColumnHeaderModal = forwardRef((props: ColumnHeaderModalProperties, const { Filter } = column; - const [clearSortingText, sortAscendingText, sortDescendingText, groupText, ungroupText] = useI18nText( - '@ui5/webcomponents-react', - CLEAR_SORTING, - SORT_ASCENDING, - SORT_DESCENDING, - GROUP, - UNGROUP - ); + const i18nBundle = useI18nBundle('@ui5/webcomponents-react'); const handleSort = useCallback( (e) => { @@ -119,22 +112,22 @@ export const ColumnHeaderModal = forwardRef((props: ColumnHeaderModalProperties, {isSortedAscending && ( - {clearSortingText} + {i18nBundle.getText(CLEAR_SORTING)} )} {showSort && !isSortedAscending && ( - {sortAscendingText} + {i18nBundle.getText(SORT_ASCENDING)} )} {showSort && !isSortedDescending && ( - {sortDescendingText} + {i18nBundle.getText(SORT_DESCENDING)} )} {isSortedDescending && ( - {clearSortingText} + {i18nBundle.getText(CLEAR_SORTING)} )} {showFilter && !column.isGrouped && ( @@ -152,7 +145,7 @@ export const ColumnHeaderModal = forwardRef((props: ColumnHeaderModalProperties, )} {showGroup && ( - {column.isGrouped ? ungroupText : groupText} + {i18nBundle.getText(column.isGrouped ? UNGROUP : GROUP)} )} diff --git a/packages/main/src/components/AnalyticalTable/__snapshots__/AnalyticalTable.test.tsx.snap b/packages/main/src/components/AnalyticalTable/__snapshots__/AnalyticalTable.test.tsx.snap index f307850e4c5..887e191c699 100644 --- a/packages/main/src/components/AnalyticalTable/__snapshots__/AnalyticalTable.test.tsx.snap +++ b/packages/main/src/components/AnalyticalTable/__snapshots__/AnalyticalTable.test.tsx.snap @@ -398,7 +398,7 @@ exports[`AnalyticalTable Alternate Row Color 1`] = `
@@ -433,7 +433,7 @@ exports[`AnalyticalTable Alternate Row Color 1`] = `
@@ -468,7 +468,7 @@ exports[`AnalyticalTable Alternate Row Color 1`] = `
@@ -905,7 +905,7 @@ exports[`AnalyticalTable Loading - Loader 1`] = `
@@ -940,7 +940,7 @@ exports[`AnalyticalTable Loading - Loader 1`] = `
@@ -975,7 +975,7 @@ exports[`AnalyticalTable Loading - Loader 1`] = `
@@ -1848,7 +1848,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
@@ -1949,7 +1949,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
@@ -2033,7 +2033,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
@@ -2075,7 +2075,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
@@ -2117,7 +2117,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
@@ -2561,7 +2561,7 @@ exports[`AnalyticalTable custom row height 1`] = `
@@ -2596,7 +2596,7 @@ exports[`AnalyticalTable custom row height 1`] = `
@@ -2631,7 +2631,7 @@ exports[`AnalyticalTable custom row height 1`] = `
@@ -3340,7 +3340,7 @@ exports[`AnalyticalTable test Asc desc 1`] = `
@@ -3375,7 +3375,7 @@ exports[`AnalyticalTable test Asc desc 1`] = `
@@ -3410,7 +3410,7 @@ exports[`AnalyticalTable test Asc desc 1`] = `
@@ -3847,7 +3847,7 @@ exports[`AnalyticalTable test Asc desc 2`] = `
@@ -3882,7 +3882,7 @@ exports[`AnalyticalTable test Asc desc 2`] = `
@@ -3917,7 +3917,7 @@ exports[`AnalyticalTable test Asc desc 2`] = `
@@ -4354,7 +4354,7 @@ exports[`AnalyticalTable test Asc desc 3`] = `
@@ -4389,7 +4389,7 @@ exports[`AnalyticalTable test Asc desc 3`] = `
@@ -4424,7 +4424,7 @@ exports[`AnalyticalTable test Asc desc 3`] = `
@@ -4861,7 +4861,7 @@ exports[`AnalyticalTable test drag and drop of a draggable column 1`] = `
@@ -4896,7 +4896,7 @@ exports[`AnalyticalTable test drag and drop of a draggable column 1`] = `
@@ -4931,7 +4931,7 @@ exports[`AnalyticalTable test drag and drop of a draggable column 1`] = `
@@ -5277,7 +5277,7 @@ exports[`AnalyticalTable with highlight row 1`] = `
@@ -5371,7 +5371,7 @@ exports[`AnalyticalTable with highlight row 1`] = `
@@ -5454,7 +5454,7 @@ exports[`AnalyticalTable with highlight row 1`] = `
@@ -5503,7 +5503,7 @@ exports[`AnalyticalTable with highlight row 1`] = `
@@ -5552,7 +5552,7 @@ exports[`AnalyticalTable with highlight row 1`] = `
@@ -5868,7 +5868,7 @@ exports[`AnalyticalTable without selection Column 1`] = `
@@ -5940,7 +5940,7 @@ exports[`AnalyticalTable without selection Column 1`] = `
@@ -6003,7 +6003,7 @@ exports[`AnalyticalTable without selection Column 1`] = `
@@ -6038,7 +6038,7 @@ exports[`AnalyticalTable without selection Column 1`] = `
@@ -6073,7 +6073,7 @@ exports[`AnalyticalTable without selection Column 1`] = `
diff --git a/packages/main/src/components/AnalyticalTable/hooks/useStyling.ts b/packages/main/src/components/AnalyticalTable/hooks/useStyling.ts index ca3b771aea6..9c4b1cbc3cb 100644 --- a/packages/main/src/components/AnalyticalTable/hooks/useStyling.ts +++ b/packages/main/src/components/AnalyticalTable/hooks/useStyling.ts @@ -61,27 +61,30 @@ const getRowProps = (rowProps, { instance, row }) => { const { classes, selectionBehavior, selectionMode, alternateRowColor } = webComponentsReactProperties; const isEmptyRow = row.original?.emptyRow; let className = classes.tr; - const rowCanBeSelected = - [TableSelectionMode.SINGLE_SELECT, TableSelectionMode.MULTI_SELECT].includes(selectionMode) && !isEmptyRow; if (row.isGrouped) { className += ` ${classes.tableGroupHeader}`; } + if (isEmptyRow) { + className += ` ${classes.emptyRow}`; + } + if (alternateRowColor && row.index % 2 !== 0) { className += ` ${classes.alternateRowColor}`; } + if (TableSelectionBehavior.ROW_SELECTOR === selectionBehavior) { + className += ` ${classes.selectionModeRowSelector}`; + } + const newRowProps = { className, role: 'row', 'aria-rowindex': row.index }; - if (rowCanBeSelected) { - if (TableSelectionBehavior.ROW_SELECTOR !== selectionBehavior) { - newRowProps.className += ` ${classes.trActive}`; - } + if ([TableSelectionMode.SINGLE_SELECT, TableSelectionMode.MULTI_SELECT].includes(selectionMode) && !isEmptyRow) { if (row.isSelected) { newRowProps[ROW_SELECTION_ATTRIBUTE] = ''; } diff --git a/packages/main/src/components/AnalyticalTable/virtualization/VirtualTableBody.tsx b/packages/main/src/components/AnalyticalTable/virtualization/VirtualTableBody.tsx index ed04e476b52..80a2bdb5d9e 100644 --- a/packages/main/src/components/AnalyticalTable/virtualization/VirtualTableBody.tsx +++ b/packages/main/src/components/AnalyticalTable/virtualization/VirtualTableBody.tsx @@ -64,6 +64,9 @@ export const VirtualTableBody = (props: VirtualTableBodyProps) => { }; const classNames = StyleClassHelper.of(classes.tbody, GlobalStyleClasses.sapScrollBar); + if (selectionMode === TableSelectionMode.SINGLE_SELECT || selectionMode === TableSelectionMode.MULTI_SELECT) { + classNames.put(classes.selectable); + } const lastScrollTop = useRef(0); diff --git a/packages/main/src/components/FilterBar/FilterBar.jss.ts b/packages/main/src/components/FilterBar/FilterBar.jss.ts index 9606b8a4c19..c696b1c210f 100644 --- a/packages/main/src/components/FilterBar/FilterBar.jss.ts +++ b/packages/main/src/components/FilterBar/FilterBar.jss.ts @@ -44,18 +44,29 @@ const styles = { headerRowRight: { display: 'flex', justifyContent: 'flex-end', - flexGrow: 1, - '& ui5-button': { - marginLeft: '0.5rem' - } - }, - showFiltersBtn: { minWidth: '108px' }, - loadingContainer: { - marginBottom: '0.5rem', - display: 'flex', - width: '100%', - justifyContent: 'center' - } + flexGrow: 1 + }, + // is being applied to the span which represents the InfoLabel Text + label: { + fontSize: ThemingParameters.sapFontSmallSize, + fontFamily: ThemingParameters.sapFontFamily, + lineHeight: '1.125rem', + fontWeight: 600, + letterSpacing: '0.0125rem', + textTransform: 'uppercase', + textAlign: 'center', + verticalAlign: 'top', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + display: 'inline-block', + color: ThemingParameters.sapTextColor + }, + // specific padding needed for purely numeric input + numeric: {}, + // specific padding needed for text input + text: {}, + // displayOnly mode + displayOnly: {} }; export default styles; diff --git a/packages/main/src/components/FilterBar/FilterBar.test.tsx b/packages/main/src/components/FilterBar/FilterBar.test.tsx index 0258f8c08b2..a139d33cbff 100644 --- a/packages/main/src/components/FilterBar/FilterBar.test.tsx +++ b/packages/main/src/components/FilterBar/FilterBar.test.tsx @@ -1,287 +1,124 @@ import { createPassThroughPropsTest } from '@shared/tests/utils'; -import { Bar } from '@ui5/webcomponents-react/lib/Bar'; -import { Button } from '@ui5/webcomponents-react/lib/Button'; -import { CheckBox } from '@ui5/webcomponents-react/lib/CheckBox'; -import { DatePicker } from '@ui5/webcomponents-react/lib/DatePicker'; +import { mount } from 'enzyme'; import { FilterBar } from '@ui5/webcomponents-react/lib/FilterBar'; -import { FilterGroupItem } from '@ui5/webcomponents-react/lib/FilterGroupItem'; +import { FilterItem } from '@ui5/webcomponents-react/lib/FilterItem'; +import { FilterType } from '@ui5/webcomponents-react/lib/FilterType'; import { Input } from '@ui5/webcomponents-react/lib/Input'; -import { MultiComboBox } from '@ui5/webcomponents-react/lib/MultiComboBox'; -import { Option } from '@ui5/webcomponents-react/lib/Option'; -import { Select } from '@ui5/webcomponents-react/lib/Select'; import { Switch } from '@ui5/webcomponents-react/lib/Switch'; import { VariantManagement } from '@ui5/webcomponents-react/lib/VariantManagement'; -import { MultiComboBoxItem } from '@ui5/webcomponents-react/lib/MultiComboBoxItem'; -import { mount } from 'enzyme'; import React from 'react'; -import { act } from 'react-dom/test-utils'; const variantItems = [ { label: 'Variant 1', key: '1' }, { label: 'Variant 2', key: '2' } ]; +const filterItems = [ + { text: 'Text 1', key: '1' }, + { text: 'Text 2', key: '2' } +]; const variants = ; const search = ; describe('FilterBar', () => { - it('Render without crashing - default props', () => { - const wrapper = mount( - - - - - - ); - expect(wrapper.render()).toMatchSnapshot(); - }); - - it('Render without crashing - w/ filter dialog', () => { + it('Render without crashing', () => { const wrapper = mount( - - - - - + + alert(e.getParameter('selectedItem').key)} + filterItems={filterItems} + label="Classification" + key="classification" + type={FilterType.Select} + /> + - - - - - - - - - - - - - - - - - - + ); expect(wrapper.render()).toMatchSnapshot(); }); - it('Hide FilterBar', () => { + it('Hide Filter Bar', () => { const wrapper = mount( - - - - - - ); - const toggleBtn = wrapper.find('Button'); - const toggleBtnBefore = toggleBtn.render(); - act(() => { - toggleBtn.getElement().props.onClick(); - }); - expect(toggleBtn.render()).not.toBe(toggleBtnBefore); - expect(wrapper.render()).toMatchSnapshot(); - }); - - it('Toggle Filters Dialog', () => { - const wrapper = mount( - - - - - + + alert(e.getParameter('selectedItem').key)} + filterItems={filterItems} + label="Classification" + key="classification" + type={FilterType.Select} + /> + - - - - - - - - - - - - - - - - - - + + + + ); - const openFiltersDialogBtn = wrapper.find('.FilterBar-headerRowRight-0-2-7').childAt(3); - act(() => { - openFiltersDialogBtn.prop('onClick')(); - }); - wrapper.update(); - expect(wrapper.find('ui5-dialog').exists()).toBeTruthy(); - expect(wrapper.render()).toMatchSnapshot(); - const filtersDialogBtns = (index) => wrapper.find(Bar).find(Button).at(index); - act(() => { - //@ts-ignore - filtersDialogBtns(0).prop('onClick')(); - }); - wrapper.update(); - expect(wrapper.find('ui5-dialog').exists()).toBeFalsy(); + const component = wrapper.find('ui5-button').last().instance() as any; + component.fireEvent('click'); expect(wrapper.render()).toMatchSnapshot(); - act(() => { - openFiltersDialogBtn.prop('onClick')(); - }); - wrapper.update(); - expect(wrapper.find('ui5-dialog').exists()).toBeTruthy(); - act(() => { - //@ts-ignore - filtersDialogBtns(3).prop('onClick')(); - }); - wrapper.update(); - expect(wrapper.find('ui5-dialog').exists()).toBeFalsy(); - act(() => { - openFiltersDialogBtn.prop('onClick')(); - }); - wrapper.update(); - expect(wrapper.find('ui5-dialog').exists()).toBeTruthy(); - act(() => { - //@ts-ignore - filtersDialogBtns(4).prop('onClick')(); - }); - wrapper.update(); - expect(wrapper.find('ui5-dialog').exists()).toBeFalsy(); }); - it('Group Filter Items mounted in Dialog', () => { + it('Select Filter Item', () => { const wrapper = mount( - - - - - - - - - - + + alert(e.getParameter('selectedItem').key)} + filterItems={filterItems} + label="Classification" + key="classification" + type={FilterType.Select} + /> + alert(e.getParameter('selectedItem').key)} + loading + filterItems={filterItems} + label="Classification" + key="classification2" + type={FilterType.Select} + /> + alert(e.getParameter('selectedItem').key)} + // filterItems={filterItems} + label="Classification" + key="classification3" + type={FilterType.Default} + /> + alert(e.getParameter('selectedItem').key)} + filterItems={filterItems} + label="Classification" + key="classification3" + type={FilterType.MultiSelect} + /> ); - const filterItemsFB = wrapper.find(FilterGroupItem); - const openFiltersDialogBtn = wrapper.find('.FilterBar-headerRowRight-0-2-7').childAt(3); - act(() => { - openFiltersDialogBtn.prop('onClick')(); - }); - wrapper.update(); + wrapper.find('ui5-option').at(1).simulate('change'); - const filterItemsDialog = wrapper.find('ui5-dialog').find(FilterGroupItem); - - const filterItemsDialogString = filterItemsDialog.debug({ ignoreProps: true }); - const filterItemsFBString = filterItemsFB.debug({ ignoreProps: true }); - // @ts-ignore - expect(filterItemsDialogString).toEqual(filterItemsFBString); - const filterItemMandatory = filterItemsDialog.at(2); - expect(filterItemMandatory.prop('required')).toBeTruthy(); - const checkbox = filterItemMandatory.parents().find(CheckBox).at(0); - expect(checkbox.prop('disabled')).toBeTruthy(); + expect(wrapper.render()).toMatchSnapshot(); }); createPassThroughPropsTest(FilterBar); diff --git a/packages/main/src/components/FilterBar/FilterBarDialog.jss.ts b/packages/main/src/components/FilterBar/FilterBarDialog.jss.ts deleted file mode 100644 index 74093d4deab..00000000000 --- a/packages/main/src/components/FilterBar/FilterBarDialog.jss.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { CssSizeVariables } from '@ui5/webcomponents-react-base/lib/CssSizeVariables'; -import { sapUiContentPadding } from '@ui5/webcomponents-react-base/lib/spacing'; - -const styles = { - dialog: { - ...sapUiContentPadding, - display: 'flex', - flexDirection: 'column', - maxWidth: '960px', - width: '80vw', - maxHeight: '70vh' - }, - header: { - padding: '0.25rem 1rem 0 1rem', - '& *': { - margin: '0.25rem 0 0.25rem 0' - }, - '& ui5-input': { - width: '100%' - } - }, - footer: { - '& :not(:last-child)': { - marginRight: '0.25rem' - } - }, - groupContainer: { - display: 'flex', - flexDirection: 'column' - }, - groupTitle: { - maxWidth: '85%', - marginRight: '0.5rem' - }, - filters: { - padding: '1rem 0 2rem 0' - }, - singleFilter: { - display: 'grid', - gridTemplateColumns: `auto minmax(${CssSizeVariables.sapWcrCheckBoxWidthHeight},7%)`, - gridTemplateRows: 'auto', - gridColumnGap: '0.5rem', - '@media(max-width:700px)': { - marginTop: '0.5rem' - }, - '& ui5-checkbox': { - placeSelf: 'center start', - '@media(max-width:700px)': { - marginTop: '0.8rem', - paddingLeft: 0, - placeSelf: 'end start' - } - } - }, - - fbSearch: { - '@media(min-width:700px)': { - display: 'grid', - gridTemplateColumns: '20% auto 7%', - gridTemplateRows: 'auto', - gridRowGap: '0.5rem', - gridColumnGap: '0.5rem' - }, - paddingBottom: '2rem', - width: '100%', - '& ui5-input': { - width: '100%' - } - } -}; - -export default styles; diff --git a/packages/main/src/components/FilterBar/FilterDialog.tsx b/packages/main/src/components/FilterBar/FilterDialog.tsx deleted file mode 100644 index 491b999ef45..00000000000 --- a/packages/main/src/components/FilterBar/FilterDialog.tsx +++ /dev/null @@ -1,283 +0,0 @@ -import '@ui5/webcomponents-icons/dist/icons/search'; -import { createComponentStyles } from '@ui5/webcomponents-react-base/lib/createComponentStyles'; -import { useI18nText } from '@ui5/webcomponents-react-base/lib/hooks'; -import { enrichEventWithDetails } from '@ui5/webcomponents-react-base/lib/Utils'; -import { - BASIC, - CANCEL, - CLEAR, - RESTORE, - SAVE, - SEARCH_FOR_FILTERS, - SHOW_ON_FILTER_BAR -} from '@ui5/webcomponents-react/dist/assets/i18n/i18n-defaults'; -import { Bar } from '@ui5/webcomponents-react/lib/Bar'; -import { BarDesign } from '@ui5/webcomponents-react/lib/BarDesign'; -import { Button } from '@ui5/webcomponents-react/lib/Button'; -import { ButtonDesign } from '@ui5/webcomponents-react/lib/ButtonDesign'; -import { CheckBox } from '@ui5/webcomponents-react/lib/CheckBox'; -import { Dialog } from '@ui5/webcomponents-react/lib/Dialog'; -import { FlexBox } from '@ui5/webcomponents-react/lib/FlexBox'; -import { FlexBoxAlignItems } from '@ui5/webcomponents-react/lib/FlexBoxAlignItems'; -import { FlexBoxDirection } from '@ui5/webcomponents-react/lib/FlexBoxDirection'; -import { FlexBoxJustifyContent } from '@ui5/webcomponents-react/lib/FlexBoxJustifyContent'; -import { Icon } from '@ui5/webcomponents-react/lib/Icon'; -import { Input } from '@ui5/webcomponents-react/lib/Input'; -import { Text } from '@ui5/webcomponents-react/lib/Text'; -import { Title } from '@ui5/webcomponents-react/lib/Title'; -import { TitleLevel } from '@ui5/webcomponents-react/lib/TitleLevel'; -import React, { Children, cloneElement, ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import styles from './FilterBarDialog.jss'; -import { filterValue, renderSearchWithValue } from './utils'; - -const useStyles = createComponentStyles(styles, { name: 'FilterBarDialog' }); -export const FilterDialog = (props) => { - const { - filterBarRefs, - open, - handleDialogClose, - children, - showClearButton, - showRestoreButton, - showGoButton, - showSearch, - renderFBSearch, - handleClearFilters, - handleRestoreFilters, - handleDialogSave, - searchValue, - handleSearchValueChange, - onGo, - handleSelectionChange, - handleDialogSearch, - handleDialogCancel - } = props; - const classes = useStyles(); - const [searchString, setSearchString] = useState(''); - const searchRef = useRef(null); - const [toggledFilters, setToggledFilters] = useState({}); - const dialogRefs = useRef({}); - const dialogRef = useRef(); - - const [ - basicText, - cancelText, - clearText, - restoreText, - saveText, - searchForFiltersText, - showOnFilterBarText - ] = useI18nText( - '@ui5/webcomponents-react', - BASIC, - CANCEL, - CLEAR, - RESTORE, - SAVE, - SEARCH_FOR_FILTERS, - SHOW_ON_FILTER_BAR - ); - - useEffect(() => { - if (open) { - dialogRef.current.open(); - } - }, [open]); - - const handleSearch = useCallback( - (e) => { - if (handleDialogSearch) { - handleDialogSearch(enrichEventWithDetails(e, { value: e.target.value })); - } - setSearchString(e.target.value); - }, - [setSearchString, handleDialogSearch] - ); - const handleSave = useCallback( - (e) => { - if (renderFBSearch) { - handleSearchValueChange(searchRef.current?.children[1].value); - } - handleDialogSave(e, dialogRefs.current, toggledFilters); - }, - [renderFBSearch, handleSearchValueChange, searchRef, handleDialogSave, toggledFilters, dialogRefs] - ); - - const handleClose = useCallback( - (e) => { - if (!showGoButton) { - handleSave(e); - return; - } - handleDialogClose(e); - }, - [showGoButton, handleSave, handleDialogClose] - ); - - const handleDialogGo = useCallback( - (e) => { - if (onGo) { - onGo(enrichEventWithDetails(e)); - } - handleDialogClose(e); - }, - [onGo, handleDialogClose] - ); - - const handleRestore = useCallback( - (e) => { - handleRestoreFilters(e, 'dialog'); - }, - [handleRestoreFilters] - ); - - const handleCancel = useCallback( - (e) => { - if (handleDialogCancel) { - handleDialogCancel(enrichEventWithDetails(e)); - } - handleDialogClose(e); - }, - [handleDialogCancel] - ); - - const footerContentRight = useMemo( - () => ( - - {showGoButton && ( - - )} - {showClearButton && } - {showRestoreButton && } - - - - ), - [ - showGoButton, - classes.footer, - handleDialogGo, - showClearButton, - handleClearFilters, - showRestoreButton, - handleRestore, - handleSave, - handleCancel - ] - ); - - const renderFooter = useCallback(() => { - return ; - }, [footerContentRight]); - - const renderHeader = useCallback( - () => ( - - Filters - {showSearch && ( - } /> - )} - - ), - [classes.header, showSearch, handleSearch] - ); - - const renderChildren = useCallback(() => { - return children - .filter((item) => { - if (item.type.displayName !== 'FilterGroupItem') return true; //needed for deprecated FilterItem or custom elements - return ( - !!item?.props && - item.props?.visible && - (item.props?.label?.toLowerCase().includes(searchString.toLowerCase()) || searchString.length === 0) - ); - }) - .map((child) => { - if (child.type.displayName !== 'FilterGroupItem') return child; //needed for deprecated FilterItem or custom elements - const filterBarItemRef = filterBarRefs.current[child.key]; - let filterItemProps = {}; - if (filterBarItemRef) { - filterItemProps = filterValue(filterBarItemRef, child); - } - if (!child.props.children) return child; - return cloneElement(child as ReactElement, { - children: { - ...child.props.children, - props: { - ...child.props.children.props, - ...filterItemProps - }, - ref: (node) => { - dialogRefs.current[child.key] = node; - } - } - }); - }); - }, [children, searchString, filterBarRefs]); - - const handleCheckBoxChange = useCallback( - (element, toggledFilters) => (e) => { - if (handleSelectionChange) { - handleSelectionChange(enrichEventWithDetails(e, { element, checked: e.target.checked })); - } - setToggledFilters({ ...toggledFilters, [element.key]: e.target.checked }); - }, - [setToggledFilters, handleSelectionChange] - ); - const renderGroups = useCallback(() => { - let groups = {}; - Children.forEach(renderChildren(), (child) => { - const childGroups = child.props.groupName ?? 'default'; - if (groups[childGroups]) { - groups[childGroups].push(child); - } else { - groups[childGroups] = [child]; - } - }); - return Object.keys(groups) - .sort((x, y) => (x === 'default' ? -1 : y === 'role' ? 1 : 0)) - .map((item, index) => { - const filters = groups[item].map((el) => { - return ( -
- {el} - -
- ); - }); - return ( -
- - - {item === 'default' ? basicText : item} - - {index === 0 && {showOnFilterBarText}} - -
{filters}
-
- ); - }); - }, [renderChildren, toggledFilters, handleCheckBoxChange]); - - return ( - -
- {renderFBSearch && ( -
- - {renderSearchWithValue(renderFBSearch, searchValue)} -
- )} - {renderGroups()} -
-
- ); -}; diff --git a/packages/main/src/components/FilterBar/__snapshots__/FilterBar.test.tsx.snap b/packages/main/src/components/FilterBar/__snapshots__/FilterBar.test.tsx.snap index 9c136e6c121..a0c775f1c03 100644 --- a/packages/main/src/components/FilterBar/__snapshots__/FilterBar.test.tsx.snap +++ b/packages/main/src/components/FilterBar/__snapshots__/FilterBar.test.tsx.snap @@ -1,17 +1,66 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`FilterBar Hide FilterBar 1`] = ` +exports[`FilterBar Hide Filter Bar 1`] = `
+
+ + Variant 1 + + + + + Cancel + + + + Variant 1 + + + Variant 2 + + + +
Show Filter Bar @@ -22,107 +71,72 @@ exports[`FilterBar Hide FilterBar 1`] = ` class="FilterBar-filterArea-0 FilterBar-filterAreaClosed-0" >
-
- - + Classification - -
+ - - Option 1 - - Option 2 + Text 1 - - Option 3 - - - Option 4 + + Text 2
-
-
-`; - -exports[`FilterBar Render without crashing - default props 1`] = ` -
-
- - Hide Filter Bar - +
+ + Custom Filter 1 + +
+ +
+
-
-
+ + Custom Filter 1 +
- - - Classification - +
- - - Option 1 - - - Option 2 - - - Option 3 - - - Option 4 - -
`; -exports[`FilterBar Render without crashing - w/ filter dialog 1`] = ` +exports[`FilterBar Render without crashing 1`] = `
@@ -182,921 +196,74 @@ exports[`FilterBar Render without crashing - w/ filter dialog 1`] = `
+ +
- Clear - - - Restore - - Hide Filter Bar - - Filters (1337) - - - Go -
-
- - - Input - -
- -
-
-
-
-
- - - Switch - -
- -
-
-
-
-
- - - SELECT w/ initial selected - -
- - - Option 1 - - - Option 2 - - - Option 3 - - - Option 4 - - -
-
-
-
-
- - - SELECT w/o initial selected - -
+ + Classification + - Test 1 - - - Test 2 - - - Test 3 - - - Test 4 + Text 1 - Test 5 + Text 2
-
- - Group 2: - MultBox - -
- - - + + Custom Filter 1 + +
+ - - - -
-
-
-
-
- - Group 2: - Date Picker -
-
`; -exports[`FilterBar Toggle Filters Dialog 1`] = ` -Array [ - -
- - Filters - - - - -
-