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

feat(ui5-li): add text wrapping support #11108

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open

feat(ui5-li): add text wrapping support #11108

wants to merge 11 commits into from

Conversation

kgogov
Copy link
Member

@kgogov kgogov commented Mar 14, 2025

Description

The standard list item ui5-li now supports content wrapping through a publicly available wrappingType property. When set to "Normal", long text content (title and description) will wrap to multiple lines instead of truncating with an ellipsis.

Key features:

  • Responsive behavior based on screen size:
    • On mobile (size S): Text truncates after 100 characters
    • On tablets/desktop (size M/L): Text truncates after 300 characters
  • "Show More/Less" functionality for very long content using ui5-expandable-text
  • Works for both title and description fields
  • CSS styling to ensure proper layout in different states

Implementation details:

  • Made wrappingType property public available with options "None" (default) and "Normal"
  • Conditionally render content using ui5-expandable-text component when wrappingType is "Normal"
  • Added _maxCharacters getter to determine truncation point based on media range
  • Updated ListItemStandardTemplate to handle wrapped content rendering
  • Updated CSS selectors to use wrapping-type attribute
  • Updated HTML test page with examples

Documentation:

  • Added new section in List.mdx explaining the wrapping behavior
  • Created a sample in WrappingBehavior folder
  • Added JSDoc descriptions for the new property
  • ⭐ Added note about deprecated usage of default slot in favor of text property

Tests:

  • Added desktop test for 300 character limit
  • Added mobile-specific test for 100 character limit
  • Added test for toggling wrappingType property

NOTE: This change also promotes the use of the text property (added in v2.9.0) instead of the default slot content for setting list item text. The default slot usage is now deprecated and will be removed in a future version.

Implements: #9745

@kgogov kgogov force-pushed the feat-list-wrapping branch from bf65704 to 10f7b58 Compare March 17, 2025 15:31
@kgogov kgogov changed the title feat(ui5-list): add wrapping to list items feat(ui5-li): add text wrapping support with expandable text Mar 17, 2025
@kgogov kgogov changed the title feat(ui5-li): add text wrapping support with expandable text feat(ui5-li): add text wrapping support Mar 17, 2025
@kgogov kgogov force-pushed the feat-list-wrapping branch 2 times, most recently from 7060ff3 to 166940b Compare March 18, 2025 12:07
@kgogov kgogov requested a review from NakataCode March 19, 2025 08:13
@property()
declare accessibleName?: string;
@property({ type: Boolean })
wrapping = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use the wrappingType here instead, perhaps making it public?

Copy link
Member Author

@kgogov kgogov Mar 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course! I actually considered doing it that way, but for some reason, I didn’t. 😆

@kgogov kgogov force-pushed the feat-list-wrapping branch from 07401f2 to 9a78e32 Compare March 25, 2025 15:08
@kgogov kgogov requested a review from dobrinyonkov March 25, 2025 15:10
@@ -494,6 +502,7 @@ class List extends UI5Element {
resizeListenerAttached: boolean;
listEndObserved: boolean;
_handleResize: ResizeObserverCallback;
_handleMediaRangeUpdateBound: ResizeObserverCallback;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to re-use the already defined resize handler _handleResize and wrap the current logic and the _handleMediaRangeUpdate call in a method? This way we won't need to register another resize handler.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* @private
*/
@property({ type: String })
mediaRange!: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to assign type in the decorator, the default one is string. Also, try to provide a default value and move away from the non-null assertion operator (!), perhaps assign a default value "S".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* @private
*/
@property({ type: String })
mediaRange!: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as for List.ts

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -89,6 +80,27 @@ class ListItemStandard extends ListItem implements IAccessibleListItem {
@property()
additionalTextState: `${ValueState}` = "None";

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Looks like there’s a lot of "noise" changes in this diff due to property reordering and some JSDoc updates.
The icon and iconEnd properties were moved to a different part of the class, leading to big diff blocks. If possible, could you review that for improvements to keep the class history more clean.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* @private
*/
get _maxCharacters(): number {
return this.mediaRange === "S" ? 100 : 300;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract those values in a consts, e.g, MAX_CHARACTARES_SIZE_S, MAX_CHARACTARES_SIZE_M

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

function renderTitle(this: ListItemStandard) {
if (this.wrappingType === WrappingType.Normal) {
return (
<span part="title" class="ui5-li-title">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, this part will no longer work to restyle the text provided in by the expandable component. What should we do is to introduce a part in the expandable text and use exportparts here to provide it through the list item, you can check if that work in a sample and add the onwers for a review. We can also look into it together.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

if (this.wrappingType === WrappingType.Normal) {
return (
<div class="ui5-li-description-info-wrapper">
<span part="description" class="ui5-li-desc">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, check if exportparts could be used.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@kgogov kgogov force-pushed the feat-list-wrapping branch from ca17734 to 8cbd2a5 Compare March 26, 2025 14:01
kgogov added 8 commits March 28, 2025 14:53
The standard list item now supports content wrapping through a new "wrapping"
property. When enabled, long text content (title and description) will wrap to
multiple lines instead of truncating with an ellipsis.

Key features:
- Responsive behavior based on screen size:
  - On mobile (size S): Text truncates after 100 characters
  - On tablets/desktop (size M/L): Text truncates after 300 characters
- "Show More/Less" functionality for very long content using ui5-expandable-text
- Works for both title and description fields
- CSS styling to ensure proper layout in different states

Implementation details:
- Added "wrapping" boolean property to ListItemStandard component
- Conditionally render content using ExpandableText component when wrapping is enabled
- Added _maxCharacters getter to determine truncation point based on media range
- Updated ListItemStandardTemplate to handle wrapped content rendering
- Added CSS styles to support proper wrapping behavior
- Updated HTML test page with examples

Documentation:
- Added new section in List.mdx explaining the wrapping behavior
- Created detailed sample in WrappingBehavior folder
- Added JSDoc descriptions for the new property
- Added note about deprecated usage of default slot in favor of text property

Tests:
- Added desktop test for 300 character limit
- Added mobile-specific test for 100 character limit
- Added test for toggling wrapping property

NOTE: This change also promotes the use of the "text" property (added in v2.9.0)
instead of the default slot content for setting list item text. The default slot
usage is now deprecated and will be removed in a future version.
- Updated the ListItemStandard class and ListItemStandardTemplate
- Updated CSS selectors to work with wrapping-type="Normal" attribute
- Updated the available test cases
- Updated the documentation
- Updated the samples
@kgogov kgogov force-pushed the feat-list-wrapping branch from 6ab4f6b to 744e6f1 Compare March 28, 2025 12:53
@kgogov kgogov requested a review from dobrinyonkov March 28, 2025 13:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants