-
-
Notifications
You must be signed in to change notification settings - Fork 683
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
Introduce QSlideItem element #4358
base: main
Are you sure you want to change the base?
Conversation
Hi @thetableman, thanks for yet another awesome pull request! Just some quick feedback (haven't looked at all the code yet):
|
Maybe we can make the predefined slots callable to assign color and event handler... with slide_item.left(color='green', on_slide=lambda: ui.notify('Left')):
ui.item_label('Left')
with slide_item.right(color='red', on_slide=lambda: ui.notify('Right')):
ui.item_label('Right') Or |
Thanks for reviewing @falkoschindler
Are you suggesting here that a
I did play with this idea too but ultimately found it restrictive.
I think I like this alternative approach best but wouldn't this example create two Surely usage would need to be as follows... but then this is almost as before: with ui.slide_item as slide_item:
ui.item('Slide me')
with slide_item.left(color='green', on_slide=lambda: ui.notify('Left')):
ui.item_label('Left')
with slide_item.right(color='green', on_slide=lambda: ui.notify('Right')):
ui.item_label('Right')
Indeed! I had a lot of fun approaching this one. For such a simple element there are a lot ways to approach. |
I've had a play with two different approaches to the class SlideItem(DisableableElement):
def __init__(self,
on_change: Optional[Handler[ClickEventArguments]] = None):
super().__init__(tag='q-slide-item')
self._active_slides: list[str] = []
if on_change:
self.on_change(on_change)
self._left_slide: LeftSlide = None
class right_slide(SlideSide):
def __init__(self,
on_slide: Optional[Handler[GenericEventArguments]] = None,
color: Optional[str] = 'primary',
) -> None:
super().__init__('right', color=color, on_slide=on_slide)
@property
def left_slide(self) -> LeftSlide:
if self._left_slide:
return self._left_slide
self._left_slide = LeftSlide
return self._left_slide
def reset(self) -> None:
"""Reset the Slide Item to initial state"""
self.run_method('reset') from nicegui import ui
with ui.list().props('dense separator'):
with ui.slide_item() as slide_item:
with ui.item_section().classes('h-20'):
ui.item_label('Slide me Up or Down')
with slide_item.left_slide(on_slide=lambda: ui.notify('Left')):
ui.item_label('Left')
with slide_item.right_slide(on_slide=lambda: ui.notify('Right')):
ui.item_label('Right')
ui.button('Reset Slide Item', on_click=lambda: slide_item.reset())
ui.run(reload=False) |
No, I was referring to your main demo. If ui.item('Item A')
Good point! We don't want them to be always created.
Yes, ignored "top" and "bottom". But they are a good example for optional slots that definitely need to stay optional.
Agreed.
Ah, I omitted the wrapping So I think we can agree on a usage like this: with ui.slide_item as slide_item:
ui.item('Slide me')
with slide_item.left(color='green', on_slide=lambda: ui.notify('Left')):
ui.item_label('Left')
with slide_item.right(color='green', on_slide=lambda: ui.notify('Right')):
ui.item_label('Right')
I think we can simplify it by defining
Oh yes, I love tinkering with such API decisions as well. Often you end up with nice solutions you haven't thought of in the beginning. And ultimately those solutions make a great library. 🙂 |
Ah, yes, you're right! How about this approach with methods then? We can add class SlideItem(DisableableElement):
def __init__(self,
on_change: Optional[Handler[ClickEventArguments]] = None):
super().__init__(tag='q-slide-item')
self._active_slides: list[str] = []
if on_change:
self.on_change(on_change)
def slide(self,
side: SlideSides, *,
on_slide: Optional[Handler[GenericEventArguments]] = None,
color: Optional[str] = 'primary',
) -> Self:
if color:
self._props[f'{side}-color'] = color
if on_slide:
self.on_slide(side, on_slide)
if side not in self._active_slides:
self._active_slides.append(side)
return self.add_slot(side)
def on_change(self, callback: Handler[ClickEventArguments]) -> Self:
"""Add a callback to be invoked when the Slide Item is changed."""
self.on('action', lambda _: handle_event(callback, ClickEventArguments(sender=self, client=self.client)))
return self
def on_slide(self, side: SlideSides, callback: Handler[GenericEventArguments]) -> Self:
"""Add a callback to be invoked when a Slide Side is activated."""
self.on(side, lambda _: handle_event(callback, GenericEventArguments(sender=self, client=self.client, args=side)))
return self
def reset(self) -> None:
"""Reset the Slide Item to initial state"""
self.run_method('reset')
@property
def active_slides(self) -> list:
"""Returns a list of active Slide Sides"""
return self._active_slides from nicegui import ui
with ui.list().props('dense separator'):
with ui.slide_item() as slide_item:
ui.item('Slide Me Left or Right').classes('h-20')
with slide_item.slide(side='left', color='positive', on_slide=lambda: ui.notify('Left')):
ui.label('Left')
with slide_item.slide(side='right', color='negative', on_slide=lambda: ui.notify('Right')):
ui.label('Right')
ui.button('Reset Slide Item', on_click=lambda: slide_item.reset())
ui.run() |
@thetableman Looks great! 👍🏻 |
Done! I'll leave it to you to decide whether creating 'left', 'right', etc methods are necessary. |
Nice! Quick question: What is the use case for the |
You can remove |
This PR introduces a Slide Item element based on Quasar's QSlideItem https://quasar.dev/vue-components/slide-item
@falkoschindler and @rodja I would be keen to hear your feedback on how I handled the
LeftSlide
,RightSlide
, etc relationship withSlideItem
, I feel there may be a better way to add the association of their slot to the parent element.I'm also interested to hear your feedback on whether an
on_change
callback is really needed if each slot already has anon_slide
callback.I was undecided whether creating
LeftSlide
,RightSlide
, etc classes were truly necessary, a user could just useSlideSide
with theside
parameter, but noted the style ofDrawer
,LeftDrawer
,RightDrawer
so aligned to this.Feature request: #4282