Skip to content

Conversation

evnchn
Copy link
Collaborator

@evnchn evnchn commented May 15, 2025

This PR addresses the most basic demand highlighted in #2508, that is to color individual lines in ui.log.

Implementation details

Note that, the user may have already styled the ui.label via default_classes, default_style and/or default_props.

Since:

  • It would be way too much parameters if we allow 3 (add/remove/replace) * 3 (classes/style/props) = 9 parameters to skip into log.push
  • Users are not supposed to receive the ui.label instances and style it themselves since
    • Function returns None, and,
    • They will be deleted automatically via self.remove(0)

I have elected to make the classes, style, and props, should they be passed in, replace existing one and be final.

Test script

from nicegui import ui

ui.label.default_classes('text-gray-500')
ui.label.default_style('font-size: 2rem')
ui.label.default_props('my_label_props')

ui.add_css('''
*[my_label_props] {
    font-style: italic;
}
*[my_log_props] {
    font-weight: bold;
}
''')

ui.label('This is how a normal label looks like')

ui.log().push('This is how a log label looks like', classes='text-red-500', style='font-size: 1rem', props='my_log_props')

ui.run()
{3B0DEA0A-E006-4A54-950E-58F06FBD5E3D} {F0E4BAC4-A13B-494A-A350-7D0F8560B501}

What this PR doesn't do

  • Let you style individual characters in each line
  • Let you put custom HTML in ui.log
  • Accept ANSI escape sequences and display as colors appropriately
  • Be a replacement to Xterm.js in Add Xterm element #4520

To-do

  • Pytest?
  • Documentation?
    • Drafted documentation text

Questions left on the table, which is best if we can answer them

  • Why no replace for props, and I had to do label.props.clear()?
    • Considered a missing future feature for NiceGUI

@evnchn evnchn added feature Type/scope: New feature or enhancement ⚪️ minor Priority: Low impact, nice-to-have labels May 15, 2025
@evnchn
Copy link
Collaborator Author

evnchn commented May 17, 2025

Proposed Documentation text

Styling lines

On the basis that individual lines in ui.log are ui.label instances, it is possible to style the inserted lines via classes, style and props. One notable use would be colored logs. (INSERT DEMO HERE)

Note that if applied, this would clear any existing classes/style/props currently set as default on ui.label

@falkoschindler
Copy link
Contributor

Two quick questions:

  • Do we really need props? ui.label is no Quasar element, so there are no props we pre-defined meaning. Is it just for symmetry and to cover all possible edge cases?
  • Why did you chose to use replace=? I can see arguments for both add and replace. But initially I thought the "most basic" implementation would be to use the default behavior of .classes() which adds classes.

@evnchn
Copy link
Collaborator Author

evnchn commented May 17, 2025

props has no visual function

Yes. It is for symmetry and maximum flexibility (aka "just in case"). It also may be useful to select/filter those elements via looking for the data-* properties, but yes that's also an edge case

Why replace

But otherwise, if I set default style text-red-500, other than setting !text-green-500, I don't see how I can override the existing classes, and that seems more confusing.

I fear ui.log may become excessively difficult to use, if the user already styled their labels to be very pretty by default.

Especially, I don't think the ui.log text would look much like text outside in the first place, so I think starting from square-one and doing replace on class/style/prop is the way to go.

@falkoschindler
Copy link
Contributor

Ok, I agree. Just because log lines happen to be implemented using ui.label, they don't need to look like every other ui.label. We're just using them as a tool to add text to a container element.

As a demo for the documentation I could imaging something like this:

log = ui.log(max_lines=10).classes('w-full h-20')

ui.button('Log debug', on_click=lambda: log.push('Some detail information', classes='text-gray-600'))
ui.button('Log info', on_click=lambda: log.push('Everything is fine', classes='text-blue-600'))
ui.button('Log warning', on_click=lambda: log.push('Something is fishy', classes='text-yellow-600'))
ui.button('Log error', on_click=lambda: log.push('Something is wrong', classes='text-red-600'))

Why no replace for props, and I had to do label.props.clear()?

Good question. I can't remember why the .props() method doesn't have a replace parameter. It could simply call clear() and continue like for add.

@falkoschindler falkoschindler added the in progress Status: Someone is working on it label May 17, 2025
@falkoschindler falkoschindler modified the milestones: 2.18, 2.x May 17, 2025
@evnchn
Copy link
Collaborator Author

evnchn commented May 17, 2025

7951808

I think the h-20 originally proposed is too short. The initial demo should be short to encourage scrolling to the bottom, but the rest of the demos can take up reasonable space for visual clarity.

Added an unstyled text so as to make it more clear.

Introduced the use of ui.row as well. You could argue that we are making the demo slightly more complex, but come on! It's a ui.row, you got to learn it at some point?

@evnchn evnchn requested a review from falkoschindler May 17, 2025 21:45
@evnchn
Copy link
Collaborator Author

evnchn commented May 17, 2025

My first pytest. Review with care!

@evnchn evnchn removed their assignment May 17, 2025
@WolfgangFahl
Copy link

@evnchn
Copy link
Collaborator Author

evnchn commented May 19, 2025

Let's keep this PR focused on the minimum functionality as requested in #2508

If you find these approaches interesting for inclusion into NiceGUI, you can head to https://github.com/zauberzeug/nicegui/discussions/categories/ideas-feature-requests and start a thread. I'd love to discuss more when I have time after exams!

@falkoschindler falkoschindler added review Status: PR is open and needs review and removed in progress Status: Someone is working on it labels May 19, 2025
Copy link
Contributor

@falkoschindler falkoschindler left a comment

Choose a reason for hiding this comment

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

Thanks for the pull request, @evnchn!
I just added the new parameters to the docstrings, cleaned up the pytest and shortened the demo lines for better readablity.
Ready to merge! 🚀

@falkoschindler falkoschindler removed this from the 2.x milestone May 19, 2025
@falkoschindler falkoschindler added this to the 2.18 milestone May 19, 2025
@falkoschindler falkoschindler merged commit dfb78e8 into zauberzeug:main May 19, 2025
1 check passed
@evnchn evnchn deleted the log-label-customization branch May 26, 2025 10:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Type/scope: New feature or enhancement ⚪️ minor Priority: Low impact, nice-to-have review Status: PR is open and needs review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants