Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: pageheader subtitle truncation visibility #6551

Merged
merged 12 commits into from
Dec 13, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -538,14 +538,8 @@ $right-section-alt-width: 100% - $left-section-alt-width;
}

.#{$block-class}__subtitle-row {
display: -webkit-box;
overflow: hidden;
max-width: 100%;
margin-top: $spacing-03;

-webkit-box-orient: vertical;
-webkit-line-clamp: 2;

@include breakpoint-up('md') {
max-width: $left-section-std-width;
}
Expand All @@ -559,6 +553,28 @@ $right-section-alt-width: 100% - $left-section-alt-width;
@include type.type-style('body-01');
}

.#{$block-class}__subtitle-tooltip .cds--definition-term {
matthewgallo marked this conversation as resolved.
Show resolved Hide resolved
border-bottom: 0;
letter-spacing: inherit;
}

.#{$block-class}__subtitle-tooltip
.cds--popover-content.cds--definition-tooltip {
max-inline-size: fit-content;
}

.#{$block-class}__subtitle-text {
display: block;
white-space: nowrap;
}

.#{$block-class}__subtitle-text--long {
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}

.#{$block-class}__available-row {
@include type.type-style('body-01');

Expand Down
38 changes: 34 additions & 4 deletions packages/ibm-products/src/components/PageHeader/PageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
usePrefix,
ButtonProps,
PopoverAlignment,
DefinitionTooltip,
} from '@carbon/react';
import { TagProps } from '@carbon/react/lib/components/Tag/Tag';
import React, {
Expand Down Expand Up @@ -51,6 +52,7 @@
import { getDevtoolsProps } from '../../global/js/utils/devtools';
import { pkg } from '../../settings';
import { useResizeObserver } from '../../global/js/hooks/useResizeObserver';
import useOverflow from './hooks/useOverflow';

const componentName = 'PageHeader';

Expand Down Expand Up @@ -901,12 +903,21 @@

const displayedBreadcrumbs = getBreadcrumbs();

const longTitleRef = useRef<HTMLSpanElement>(null);
const titleRef = useRef<HTMLSpanElement>(null);

const isEllipsisApplied = useOverflow({
longRef: longTitleRef,
shortRef: titleRef,
text: subtitle,
});

return (
<>
<div
className={`${blockClass}--offset-top-measuring-element`}
ref={offsetTopMeasuringRef}
></div>
/>
<section
{...rest}
className={cx([
Expand Down Expand Up @@ -1035,13 +1046,32 @@
</Row>
) : null}

{subtitle ? (
{subtitle && (
<Row className={`${blockClass}__subtitle-row`}>
<Column className={`${blockClass}__subtitle`}>
{subtitle}
{isEllipsisApplied ? (
<DefinitionTooltip

Check warning on line 1053 in packages/ibm-products/src/components/PageHeader/PageHeader.tsx

View check run for this annotation

Codecov / codecov/patch

packages/ibm-products/src/components/PageHeader/PageHeader.tsx#L1053

Added line #L1053 was not covered by tests
definition={subtitle}
className={`${blockClass}__subtitle-tooltip`}
>
<span
ref={titleRef}
className={`${blockClass}__subtitle-text--long`}
>
{subtitle}
</span>
</DefinitionTooltip>
) : (
<span
ref={longTitleRef}
className={`${blockClass}__subtitle-text`}
>
{subtitle}
</span>
)}
</Column>
</Row>
) : null}
)}

{children ? (
<Row className={`${blockClass}__available-row`}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/

import React, { useLayoutEffect, useRef, useState } from 'react';
import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { DefinitionTooltip, SkeletonText } from '@carbon/react';
import { EditInPlace } from '../EditInPlace';
import useOverflow from './hooks/useOverflow';

/**
*
Expand Down Expand Up @@ -39,25 +40,14 @@ export const PageHeaderTitle = ({ blockClass, hasBreadcrumbRow, title }) => {
let titleText;
let isEditable = !!onSave;

const [isEllipsisApplied, setIsEllipsisApplied] = useState();
const longTitleRef = useRef(undefined);
const titleRef = useRef(undefined);

useLayoutEffect(() => {
setIsEllipsisApplied(isEllipsisActive());
}, [longTitleRef, titleRef, title]);

const isEllipsisActive = () => {
if (longTitleRef.current) {
return (
longTitleRef.current?.offsetWidth < longTitleRef.current?.scrollWidth
);
} else if (titleRef.current) {
return titleRef.current?.offsetWidth < titleRef.current?.scrollWidth;
}

return false;
};
const isEllipsisApplied = useOverflow({
longRef: longTitleRef,
shortRef: titleRef,
text,
});

if (text || !content) {
if (text === undefined && typeof title === 'string') {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright IBM Corp. 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import { useLayoutEffect, useState, RefObject, ReactNode } from 'react';

interface Props {
longRef: RefObject<HTMLElement>;
shortRef: RefObject<HTMLElement>;
text: string | ReactNode;
}

const useOverflow = (props: Props): boolean => {
const { longRef, shortRef, text } = props;
const [isEllipsisApplied, setIsEllipsisApplied] = useState<boolean>(false);

useLayoutEffect(() => {
const isEllipsisActive = () => {
if (longRef?.current) {
return longRef.current?.offsetWidth < longRef.current?.scrollWidth;
} else if (shortRef.current) {
return shortRef.current?.offsetWidth < shortRef.current?.scrollWidth;
}

return false;
};
setIsEllipsisApplied(isEllipsisActive());
}, [longRef, shortRef, text]);

return isEllipsisApplied;
};

export default useOverflow;
Loading