SAP / ui5-webcomponents

UI5 Web Components - the enterprise-flavored sugar on top of native APIs! Build SAP Fiori user interfaces with the technology of your choice.
https://sap.github.io/ui5-webcomponents/
Apache License 2.0
1.47k stars 254 forks source link

Tree: Overflowing of the content of TreeCustomItem #8877

Open mishalov opened 2 months ago

mishalov commented 2 months ago

Describe the bug

Long content of TreeItemCustom grows and overflows the component, even if it has fixed width:

image

Fix for the issue is adding width:100% (or calculated one in case there are icon or something else) to the .ui5-li-tree-text-wrapper class

image

Unfortunately this class is not accessible for modification, it is in shadow DOM.

Isolated Example

No response

Reproduction steps

  1. Create Tree with fixed width (300px ex.)
  2. Add a TreeItemCustom with long content (text with ellipsis when overflowing is OK)

Expected Behaviour

Couple of options:

  1. Elements in the content property of TreeItemCustom are fitted into header of the TreeItemCustom.
  2. I can add "width:100%" to the .ui5-li-tree-text-wrapper

Any of these two will enables me to build responsive Trees with this component. Right now, content is overfloating alwys unless I set max-width to it (but it is still bad responsiveness)

Screenshots or Videos

No response

UI5 Web Components for React Version

1.24

UI5 Web Components Version

1.24

Browser

Chrome

Operating System

MacOS: 14.4.1

Additional Context

No response

Relevant log output

No response

Organization

No response

Declaration

Lukas742 commented 2 months ago

Thanks for reporting! I'll forward this issue to our UI5 Web Components Colleagues as the affected component is developed in their repository.

PetyaMarkovaBogdanova commented 2 months ago

Hi colleagues, can you, please, evaluate what we can do from our side with the styles of the content of the Tree Custom Item, in order to achieve layout with not wrapped truncated text. Best regards, Petya Markova. (UI5 Dispatcher)

PetyaMarkovaBogdanova commented 2 months ago

Hi @Lukas742 , can I, kindly, ask you to provide a minimal sample of the content of the Tree Custom Item, that matches your setup, to be easier for my colleagues to test the solution.

Colleagues from @SAP/ui5-webcomponents-topic-p, we already discuss internally the possible solutions for this issue and we agreed on the approach of removing "ui5-li-tree-text-wrapper" , making sure the aligining of the items inside remains the same. With this, we a re giving more freedom to applications to style the layout of the custom item, using the part "content" directly as a parent element.

Best regards, Petya Markova. (UI5 Dispatcher)

Lukas742 commented 2 months ago

Hi @PetyaMarkovaBogdanova

did you mean to tag @mishalov? I can't really give an example as I also only have the context given in the issue ;)

mishalov commented 2 months ago

@PetyaMarkovaBogdanova Sure! Here is minimal setup of what you can find on my attached screenshots

<TreeItemCustom
    accessibleName={name}
    data-value={name}
    icon='number-sign'
    className={classes.attributePanel}
    content={
        <AttributeHeader
            attribute={attribute}
            countLabel={`300 / 988`}
        />
    }
    hasChildren={true}
>
    {children}
</TreeItemCustom >

AttributeHeader:

const AttributeHeader: React.FC<AttributeHeaderProps> = ({
    attribute,
    slot,
    countLabel
}) => {
    const { onCopy, isCopyIconVisible } = useCopyToClipboard()
    const iconRef = React.useRef<IconDomRef>(null)
    const exposedClasses = useContext(ExposedClassesContext)

    const handleCopy = (e?: MouseEvent) => {
      alert("Copied")
    }

    useEffect(() => {
        iconRef?.current?.addEventListener('click', handleCopy)
        return () => {
            iconRef?.current?.removeEventListener('click', handleCopy)
        }
    }, [handleCopy])

    const prettifiedText = replaceTechnicalNames(attribute.name)
    return (
        <FlexBox
            slot={slot}
            className={classes.attributeHeader}
            justifyContent="SpaceBetween"
            alignItems="Center"
        >
            <span
                className={classNames(
                    classes.attributeHeaderText,
                    exposedClasses.label,
                )}
            >{prettifiedText}</span>

            <FlexBox
                alignItems="Center"
                className={classes.attributeAction}
            >
                {!isCopyIconVisible ? (
                    <span className={classes.attributeActionCopied}>
                        Copied
                    </span>
                ) : (
                    <>
                        {countLabel}
                        <Icon
                            ref={iconRef}
                            name="copy"
                            className={classes.attributeActionButton}
                        />
                    </>
                )}
            </FlexBox>
        </FlexBox>
    )
}

Styles:

.attributeHeader {
    padding-right: 16px;
    cursor:pointer;

    &:hover .attributeActionButton{
        display: inline-block;

    }
    &:hover .attributeAction{
        padding-right: 0;
    }
}

.attributePanel{
    &::part(native-li) {
        padding: 0;
    }
}

.attributeHeaderText {
    flex-shrink: 1;
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.attributeAction {
    color: lightGray;
    height: 34px;
    font-size: 12px;
    flex-shrink: 0;
    padding-right: 4px;
}

.attributeActionButton {
    color: gray;
    height: 16px;
    display: none;
    max-width: 16px;
    min-width: 16px;
    background: transparent;
    margin-left: 12px;
    padding: 4px;
    &:hover {
        outline: 1px solid var(--sapList_HeaderBorderColor);
        background-color: var(--sapObjectHeader_Hover_Background);
        border-radius: 4px;
    }
}

.attributeActionCopied {
    color: var(--sapContent_DisabledTextColor);
    font-size: 12px;
    font-style: italic;
}
kineticjs commented 1 week ago

Hi @mishalov ,

Thank you for sharing this issue. I'll put for further internal discussion the proposal to change the internal css of the component. Meanwhile, can you please check sample https://codesandbox.io/p/sandbox/ui5-webcomponents-forked-hcdlz5 that sets .item::part(content) { display: block; } in my testing it has the same effect as the proposed width:100% to the .ui5-li-tree-text-wrapper element.

Thanks

rvsia commented 1 week ago

@kineticjs

Hello,

I have taken over this issue by @mishalov. 😊

This solution works well... but since that we have update our design to also include icons and with that its broken:

image

Without your solution

Snímek obrazovky 2024-06-26 v 9 10 50

The proposed solution from @mishalov still works when I hardcode the style there.

I am not able to run your preview and update it there - the codesandbox preview is blocked for me because of wrong SSL certificate.

dobrinyonkov commented 12 hours ago

Hi @rvsia,

you can find @kineticjs's sample here https://stackblitz.com/edit/js-hyrqzf?file=index.js

I'm not really sure how and where you're trying to include the icons. Would you be able to update the above example with your use case as to undestand the problem better?

Thanks!

rvsia commented 12 hours ago

@dobrinyonkov

Thank you for the example!

I have updated it with icon usage: https://stackblitz.com/edit/js-hdnq3a?file=index.html

The icon is now shown wrongly with the custom class.

Without item class

Snímek obrazovky 2024-07-04 v 16 53 56

With

Snímek obrazovky 2024-07-04 v 16 53 39