Skip to content

Commit 2529bd4

Browse files
authored
feat(ObjectStatus): simplify active state styling in lists & tables (#7930)
Fixes #7929
1 parent 66ea48b commit 2529bd4

File tree

7 files changed

+307
-63
lines changed

7 files changed

+307
-63
lines changed

.storybook/preview-head.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@
176176
padding-block: 0;
177177
}
178178

179+
/*ObjectStatus "InListOrTable" story */
180+
.interactive-table-row:active .object-status,
181+
.interactive-li[active] .object-status {
182+
--ui5wcr-object-status-icon-color: var(--sapList_Active_TextColor);
183+
color: var(--sapList_Active_TextColor);
184+
text-shadow: none;
185+
}
186+
179187
/* TODO remove this workaround as soon as https://github.com/storybookjs/storybook/issues/20497 is fixed */
180188
.docs-story > div > div[scale] {
181189
min-height: 20px;

packages/main/src/components/AnalyticalTable/AnalyticalTable.module.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,17 @@
183183
.tr[data-is-selected],
184184
.trActive:hover {
185185
& [data-component-name='ObjectStatus'][data-inverted='false']:not([data-state^='Indication']) {
186+
--ui5wcr-object-status-icon-color: var(--sapContent_ContrastTextColor);
186187
color: var(--sapContent_ContrastTextColor);
188+
text-shadow: none;
187189
}
188190
}
189191
}
192+
.trActive:active [data-component-name='ObjectStatus'][data-inverted='false'] {
193+
--ui5wcr-object-status-icon-color: var(--sapList_Active_TextColor);
194+
color: var(--sapList_Active_TextColor);
195+
text-shadow: none;
196+
}
190197

191198
.trActive {
192199
cursor: pointer;

packages/main/src/components/ObjectStatus/ObjectStatus.cy.tsx

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,16 @@ import ValueState from '@ui5/webcomponents-base/dist/types/ValueState.js';
88
import { ThemingParameters } from '@ui5/webcomponents-react-base';
99
import type { IndicationColor } from '../../enums/index.js';
1010
import { INDICATION_COLOR } from '../../i18n/i18n-defaults.js';
11-
import { Icon } from '../../webComponents/index.js';
11+
import { Icon } from '../../webComponents/Icon/index.js';
12+
import { List } from '../../webComponents/List/index.js';
13+
import { ListItemCustom } from '../../webComponents/ListItemCustom/index.js';
14+
import { Table } from '../../webComponents/Table/index.js';
15+
import { TableCell } from '../../webComponents/TableCell/index.js';
16+
import { TableHeaderCell } from '../../webComponents/TableHeaderCell/index.js';
17+
import { TableHeaderRow } from '../../webComponents/TableHeaderRow/index.js';
18+
import { TableRow } from '../../webComponents/TableRow/index.js';
19+
import { TableSelectionSingle } from '../../webComponents/TableSelectionSingle/index.js';
20+
import { AnalyticalTable } from '../AnalyticalTable/index.js';
1221
import { ObjectStatus } from './index.js';
1322
import { cssVarToRgb, cypressPassThroughTestsFactory } from '@/cypress/support/utils';
1423

@@ -324,5 +333,97 @@ describe('ObjectStatus', () => {
324333
cy.get('[ui5-icon]').should('have.css', 'height', '24px');
325334
});
326335

336+
it('active state in interactive lists and tables', () => {
337+
cy.document().then((doc) => {
338+
const style = doc.createElement('style');
339+
style.textContent = `
340+
.interactive-table-row:active .object-status,
341+
.interactive-li[active] .object-status {
342+
--ui5wcr-object-status-icon-color: var(--sapList_Active_TextColor);
343+
color: var(--sapList_Active_TextColor);
344+
text-shadow: none;
345+
}
346+
`;
347+
doc.head.appendChild(style);
348+
});
349+
350+
const activeTextColor = cssVarToRgb(ThemingParameters.sapList_Active_TextColor);
351+
const atData = [{ os1: 'ObjectStatus', os2: 'ObjectStatus' }];
352+
const args = { state: ValueState.Positive, inverted: false, showDefaultIcon: true, children: 'ObjectStatus' };
353+
const atCols = [
354+
{
355+
accessor: 'os1',
356+
Header: 'ObjectStatus (controllable)',
357+
Cell: () => <ObjectStatus {...args} data-testid="os-at" />,
358+
},
359+
{
360+
accessor: 'os2',
361+
Header: 'ObjectStatus ("Negative")',
362+
Cell: () => <ObjectStatus {...args} state={'Negative'} data-testid="os-at-negative" />,
363+
},
364+
];
365+
366+
cy.mount(
367+
<>
368+
<Table
369+
headerRow={
370+
<TableHeaderRow>
371+
<TableHeaderCell>ObjectStatus (controllable)</TableHeaderCell>
372+
<TableHeaderCell>ObjectStatus ("Negative")</TableHeaderCell>
373+
</TableHeaderRow>
374+
}
375+
features={<TableSelectionSingle behavior={'RowOnly'} />}
376+
>
377+
<TableRow rowKey={'0'} className={'interactive-table-row'}>
378+
<TableCell>
379+
<ObjectStatus {...args} className={'object-status'} data-testid="os-table" />
380+
</TableCell>
381+
<TableCell>
382+
<ObjectStatus {...args} className={'object-status'} state={'Negative'} data-testid="os-table-negative" />
383+
</TableCell>
384+
</TableRow>
385+
</Table>
386+
<List selectionMode="Single">
387+
<ListItemCustom className={'interactive-li'}>
388+
<ObjectStatus {...args} className={'object-status'} data-testid="os-list" />
389+
</ListItemCustom>
390+
</List>
391+
<AnalyticalTable
392+
data={atData}
393+
columns={atCols}
394+
minRows={1}
395+
selectionMode={'Single'}
396+
selectionBehavior={'RowOnly'}
397+
data-testid="at"
398+
/>
399+
</>,
400+
);
401+
402+
cy.get('.interactive-table-row').realMouseDown();
403+
cy.findByTestId('os-table').should('have.css', 'color', activeTextColor);
404+
cy.findByTestId('os-table')
405+
.find('[data-component-name="ObjectStatusDefaultIcon"]')
406+
.should('have.css', 'color', activeTextColor);
407+
cy.get('.interactive-table-row').realMouseUp();
408+
409+
cy.get('.interactive-li').realMouseDown();
410+
cy.findByTestId('os-list').should('have.css', 'color', activeTextColor);
411+
cy.findByTestId('os-list')
412+
.find('[data-component-name="ObjectStatusDefaultIcon"]')
413+
.should('have.css', 'color', activeTextColor);
414+
cy.get('.interactive-li').realMouseUp();
415+
416+
cy.get('[data-testid="at"] [role="row"]')
417+
.eq(1)
418+
.realMouseDown({ position: { x: 100, y: 10 } }); // don't click in the middle as there's the resizer
419+
cy.findByTestId('os-at').should('have.css', 'color', activeTextColor);
420+
cy.findByTestId('os-at')
421+
.find('[data-component-name="ObjectStatusDefaultIcon"]')
422+
.should('have.css', 'color', activeTextColor);
423+
cy.get('[data-testid="at"] [role="row"]')
424+
.eq(1)
425+
.realMouseUp({ position: { x: 100, y: 10 } });
426+
});
427+
327428
cypressPassThroughTestsFactory(ObjectStatus);
328429
});

packages/main/src/components/ObjectStatus/ObjectStatus.mdx

Lines changed: 98 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,116 @@ import * as ComponentStories from './ObjectStatus.stories';
2222

2323
<br />
2424

25-
## ObjectStatus with default icons
25+
## ObjectStatus With Default Icons
2626

2727
<Canvas of={ComponentStories.WithDefaultIcons} />
2828

29-
## ObjectStatus with custom Icon
29+
## ObjectStatus With Custom Icon
3030

3131
<Canvas of={ComponentStories.WithCustomIcon} />
3232

33-
## ObjectStatus with Icon only
33+
## ObjectStatus With Icon Only
3434

3535
<Canvas of={ComponentStories.WithIconOnly} />
3636

37-
## All ObjectStatus states
37+
## All ObjectStatus States
3838

3939
**Note:** Only the `inverted` `ObjectStatus` supports `IndicationColor`s 11-20. For non-inverted `ObjectStatus`, these colors default to the `"None"` `state` color and should **not** be used.
4040

4141
<Canvas of={ComponentStories.InvertedObjectStatus} />
4242

43+
## ObjectStatus in Interactive Lists or Tables
44+
45+
**Applicable since v2.17.0**
46+
47+
The `AnalyticalTable` component includes active state styling for `ObjectStatus` out of the box, as it is developed within project and can be styled accordingly.
48+
For lists or tables from `@ui5/webcomponents(-fiori/-ai/-compat)` (e.g., `List`, `Table`), custom CSS is required to override the text and icon `color` and `text-shadow` to ensure proper styling when rows are in active state:
49+
50+
```css
51+
.object-status {
52+
--ui5wcr-object-status-icon-color: var(--sapList_Active_TextColor);
53+
color: var(--sapList_Active_TextColor);
54+
text-shadow: none;
55+
}
56+
```
57+
58+
<Canvas of={ComponentStories.InListOrTable} />
59+
60+
<details>
61+
62+
<summary>Show Static Code</summary>
63+
64+
```css
65+
.interactive-table-row:active .object-status,
66+
.interactive-li[active] .object-status {
67+
--ui5wcr-object-status-icon-color: var(--sapList_Active_TextColor);
68+
color: var(--sapList_Active_TextColor);
69+
text-shadow: none;
70+
}
71+
```
72+
73+
```tsx
74+
function ObjectStatusInListOrTable(objectStatusProps: Omit<ObjectStatusPropTypes, 'inverted'>) {
75+
const atCols: AnalyticalTableColumnDefinition[] = useMemo(
76+
() => [
77+
{
78+
accessor: 'os1',
79+
Header: 'ObjectStatus (controllable)',
80+
Cell: () => <ObjectStatus {...objectStatusProps} />,
81+
},
82+
{
83+
accessor: 'os2',
84+
Header: 'ObjectStatus ("Negative")',
85+
Cell: () => <ObjectStatus {...objectStatusProps} state={'Negative'} />,
86+
},
87+
],
88+
[objectStatusProps],
89+
);
90+
return (
91+
<>
92+
Table
93+
<Table
94+
headerRow={
95+
<TableHeaderRow>
96+
<TableHeaderCell>ObjectStatus (controllable)</TableHeaderCell>
97+
<TableHeaderCell>ObjectStatus (&#34;Negative&#34;)</TableHeaderCell>
98+
</TableHeaderRow>
99+
}
100+
features={<TableSelectionSingle behavior={'RowOnly'} />}
101+
>
102+
<TableRow rowKey={'0'} className={'interactive-table-row'}>
103+
<TableCell>
104+
<ObjectStatus {...objectStatusProps} className={'object-status'} />
105+
</TableCell>
106+
<TableCell>
107+
<ObjectStatus {...objectStatusProps} className={'object-status'} state={'Negative'} />
108+
</TableCell>
109+
</TableRow>
110+
</Table>
111+
<hr />
112+
List
113+
<List selectionMode="Single">
114+
<ListItemCustom className={'interactive-li'}>
115+
<ObjectStatus {...objectStatusProps} className={'object-status'} />
116+
</ListItemCustom>
117+
</List>
118+
<hr />
119+
AnalyticalTable
120+
<AnalyticalTable
121+
data={atData}
122+
columns={atCols}
123+
minRows={1}
124+
selectionMode={'Single'}
125+
selectionBehavior={'RowOnly'}
126+
/>
127+
</>
128+
);
129+
}
130+
```
131+
132+
</details>
133+
134+
<br />
135+
<br />
136+
43137
<Footer />

0 commit comments

Comments
 (0)