Skip to content

Commit

Permalink
fix(Pageheader,Tearsheet,Notifications): resolves CSP violations (#6340)
Browse files Browse the repository at this point in the history
* feat: adds codecov

* fix: adds codecov token

* feat: adds codecov badge to README.mc

* fix: removes community package

* chore: adds violated components to forbid config

* feat(notifications): fixes csp violations

* feat(tearsheet): fixes csp violations

* feat: draft 1 adding isomorphic styles hook

* chore: reverts to prev changes

* fix: package.json error

* fix: linting issues

* refactor(pageheader): tests

* feat(ts): adds props namespace

* feat: adds types to module declaration

* fix: module declarations

* fix: module declarations

* fix: type declarations

* fix: type declarations

* fix: type declarations

* fix: type declarations

* fix: type declarations

* fix: type declarations

* fix: type declarations

* fix(pageheader): styles that broke

* fix: changed icon import

* fix: type declarations

* fix(notifications-panel): animation

* chore: removes console.log

* fix: removes comment

* fix(tearsheet): styles

* chore: remove console.log

---------

Co-authored-by: elysia <[email protected]>
  • Loading branch information
AlexanderMelox and elycheea authored Jan 14, 2025
1 parent 24eeecc commit 4e11b90
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import { TextAreaProps, TextInputProps } from '@carbon/react';
import { CarbonIconType } from '@carbon/react/icons';
import { CarbonIconType } from '@carbon/icons-react';
import { NumberInputProps } from '@carbon/react/lib/components/NumberInput/NumberInput';
import {
Dispatch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -789,16 +789,16 @@ export const DataSpreadsheetBody = forwardRef(
[
prepareRow,
renderRowHeader,
renderRowHeaderDirection,
rows,
hasCustomRowHeader,
activeCellCoordinates?.row,
selectionAreas,
handleRowHeaderClickEvent,
handleBodyCellClickEvent,
handleBodyCellHoverEvent,
defaultColumn,
columns,
defaultColumn,
renderRowHeaderDirection,
]
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ import { getDevtoolsProps } from '../../global/js/utils/devtools';
import { pkg } from '../../settings';
import { prepareProps } from '../../global/js/utils/props-helper';
import { timeAgo } from './utils';
import { useClickOutside, usePreviousValue } from '../../global/js/hooks';
import {
useClickOutside,
useIsomorphicEffect,
usePreviousValue,
} from '../../global/js/hooks';
import usePrefersReducedMotion from '../../global/js/hooks/usePrefersReducedMotion';
import wrapFocus from '../../global/js/utils/wrapFocus';

Expand Down Expand Up @@ -646,6 +650,18 @@ export let NotificationsPanel = React.forwardRef(
},
]);

useIsomorphicEffect(() => {
// setTimeout ensures that this gets run
const timeout = setTimeout(() => {
if (notificationPanelRef.current && !reducedMotion) {
notificationPanelRef.current.style.animation = open
? 'fade-in 250ms'
: 'fade-out forwards 250ms';
}
}, 0);
return () => clearTimeout(timeout);
}, [open, reducedMotion]);

return shouldRender ? (
<>
<button
Expand All @@ -668,11 +684,6 @@ export let NotificationsPanel = React.forwardRef(
}
id={blockClass}
className={cx(blockClass, className, `${blockClass}__container`)}
style={{
animation: !reducedMotion
? `${open ? 'fade-in 250ms' : 'fade-out forwards 250ms'}`
: undefined,
}}
onAnimationEnd={onAnimationEnd}
ref={
(ref as MutableRefObject<HTMLDivElement | null>) ||
Expand Down
27 changes: 15 additions & 12 deletions packages/ibm-products/src/components/PageHeader/PageHeader.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint react/forbid-component-props: 0 */

/**
* Copyright IBM Corp. 2020, 2023
*
Expand Down Expand Up @@ -337,10 +339,11 @@ describe('PageHeader', () => {
).toHaveLength(1);

// When withoutBackground is false this should result in the value 1 for opacity
const regStyle = new RegExp(
`--${prefix}--page-header--background-opacity: 1`
);
expect(header.getAttribute('style')).toMatch(regStyle);
const backgroundOpacity = window
.getComputedStyle(header)
.getPropertyValue(`--${prefix}--page-header--background-opacity`);

expect(backgroundOpacity).toBe('1');
});

const dataTestId = 'data-testid';
Expand Down Expand Up @@ -711,10 +714,10 @@ describe('PageHeader', () => {
const header = screen.getByTestId(dataTestId);

// When withoutBackground is true this should result in the value 0 for opacity
const regStyle = new RegExp(
`--${prefix}--page-header--background-opacity: 0`
);
expect(header.getAttribute('style')).toMatch(regStyle);
const backgroundOpacity = window
.getComputedStyle(header)
.getPropertyValue(`--${prefix}--page-header--background-opacity`);
expect(backgroundOpacity).toBe('0');
});

it('Works, for now, with deprecated props', async () =>
Expand All @@ -731,10 +734,10 @@ describe('PageHeader', () => {
const header = screen.getByTestId(dataTestId);

// When hasBackgroundAlways is false this should result in the value 0 for opacity
const regStyle = new RegExp(
`--${prefix}--page-header--background-opacity: 0`
);
expect(header.getAttribute('style')).toMatch(regStyle);
const backgroundOpacity = window
.getComputedStyle(header)
.getPropertyValue(`--${prefix}--page-header--background-opacity`);
expect(backgroundOpacity).toBe('0');
}));

it('PageHeader grid settings narrow and fullWidth', async () => {
Expand Down
27 changes: 23 additions & 4 deletions packages/ibm-products/src/components/PageHeader/PageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ import {
deprecateProp,
prepareProps,
} from '../../global/js/utils/props-helper';
import { useNearestScroll, useWindowResize } from '../../global/js/hooks';
import {
useIsomorphicEffect,
useNearestScroll,
useWindowResize,
} from '../../global/js/hooks';

import { ActionBar } from '../ActionBar/';
import { BreadcrumbWithOverflow } from '../BreadcrumbWithOverflow';
Expand Down Expand Up @@ -421,6 +425,10 @@ interface Metrics {
navigationRowHeight?: number;
}

interface HTMLElementStyled extends HTMLElement {
style: CSSStyleDeclaration;
}

export let PageHeader = React.forwardRef(
(
{
Expand Down Expand Up @@ -476,8 +484,9 @@ export let PageHeader = React.forwardRef(
});

// refs
const localHeaderRef = useRef(null);
const headerRef = ref || localHeaderRef;
const localHeaderRef = useRef<HTMLDivElement | null>(null);
const headerRef = (ref ||
localHeaderRef) as MutableRefObject<HTMLElementStyled>;
const sizingContainerRef: MutableRefObject<HTMLDivElement | null> =
useRef(null);
const offsetTopMeasuringRef = useRef(null);
Expand Down Expand Up @@ -903,6 +912,17 @@ export let PageHeader = React.forwardRef(

const displayedBreadcrumbs = getBreadcrumbs();

useIsomorphicEffect(() => {
Object.keys(pageHeaderStyles).forEach((key) => {
// check if style is a css var
if (key.startsWith('--')) {
headerRef.current.style.setProperty(key, pageHeaderStyles[key]);
} else {
headerRef.current.style[key] = pageHeaderStyles[key];
}
});
}, [headerRef, pageHeaderStyles]);

const subtitleRef = useRef<HTMLSpanElement>(null);
const isOverflowing = checkHeightOverflow(subtitleRef.current);
const subtitleContent = (
Expand All @@ -928,7 +948,6 @@ export let PageHeader = React.forwardRef(
[`${blockClass}--has-navigation-tags-only`]: !navigation && tags,
},
])}
style={pageHeaderStyles}
ref={headerRef}
{...getDevtoolsProps(componentName)}
>
Expand Down
37 changes: 23 additions & 14 deletions packages/ibm-products/src/components/Tearsheet/TearsheetShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ import {
import { ActionSet } from '../ActionSet';
import { Wrap } from '../../global/js/utils/Wrap';
import { usePortalTarget } from '../../global/js/hooks/usePortalTarget';
import { useIsomorphicEffect, usePreviousValue } from '../../global/js/hooks';
import { claimFocus, useFocus } from '../../global/js/hooks/useFocus';
import { usePreviousValue } from '../../global/js/hooks';
import { TearsheetAction } from './Tearsheet';

// The block part of our conventional BEM class names (bc__E--M).
Expand Down Expand Up @@ -384,6 +384,28 @@ export const TearsheetShell = React.forwardRef(
};
}, [open, size]);

const areAllSameSizeVariant = () => new Set(stack.sizes).size === 1;

useIsomorphicEffect(() => {
const setScaleValues = () => {
if (!areAllSameSizeVariant()) {
return {
[`--${bc}--stacking-scale-factor-single`]: 1,
[`--${bc}--stacking-scale-factor-double`]: 1,
};
}
return {
[`--${bc}--stacking-scale-factor-single`]: (width - 32) / width,
[`--${bc}--stacking-scale-factor-double`]: (width - 64) / width,
};
};
if (modalRef.current) {
Object.entries(setScaleValues()).map(([key, value]) => {
modalRef.current.style.setProperty(key, String(value));
});
}
}, [modalRef, width]);

if (position <= depth) {
// Include a modal header if and only if one or more of these is given.
// We can't use a Wrap for the ModalHeader because ComposedModal requires
Expand All @@ -401,18 +423,6 @@ export const TearsheetShell = React.forwardRef(

const areAllSameSizeVariant = () => new Set(stack.sizes).size === 1;

const setScaleValues = () => {
if (!areAllSameSizeVariant()) {
return {
[`--${bc}--stacking-scale-factor-single`]: 1,
[`--${bc}--stacking-scale-factor-double`]: 1,
};
}
return {
[`--${bc}--stacking-scale-factor-single`]: (width - 32) / width,
[`--${bc}--stacking-scale-factor-double`]: (width - 64) / width,
};
};
return renderPortalUse(
<FeatureFlags enableExperimentalFocusWrapWithoutSentinels>
<ComposedModal
Expand All @@ -435,7 +445,6 @@ export const TearsheetShell = React.forwardRef(
[`${bc}--has-close`]: effectiveHasCloseIcon,
})}
decorator={decorator || deprecated_slug}
style={setScaleValues()}
containerClassName={cx(`${bc}__container`, {
[`${bc}__container--lower`]: verticalPosition === 'lower',
[`${bc}__container--mixed-size-stacking`]:
Expand Down
1 change: 0 additions & 1 deletion packages/ibm-products/src/custom-typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ declare module '@carbon/react' {
usePrefix,
} from '@carbon/react';
}

declare module '@carbon/colors';
declare module '@carbon/motion';
declare module '@carbon/feature-flags';

0 comments on commit 4e11b90

Please sign in to comment.