h2oai / wave

Realtime Web Apps and Dashboards for Python and R
https://wave.h2o.ai
Apache License 2.0
3.98k stars 327 forks source link

`header_card` won't resize according to window size #1978

Closed Venkat-Rajgopal closed 1 year ago

Venkat-Rajgopal commented 1 year ago

Wave SDK Version, OS

Actual behavior

At the moment the card is cut towards the end since cards don't seem to resize.

image

Expected behaviour

It would be nice if the header card resizes when a window is resized. Is this possible to fix somehow with the current version ?

image

Steps To Reproduce

async def serve(q: Q):
  q.page['header'] = ui.header_card(
          box='1 1 10 1',
          title='Wave App',
          subtitle='',
          icon='FlashAuto',
          color="card",
          items=[ui.menu(image=image, items=[
              ui.command(name='profile', label='Profile', icon='Contact'),
              ui.command(name='preferences', label='Preferences',
                         icon='Settings'),
              ui.command(name='logout', label='Logout', icon='SignOut'),
          ])]
      )
   await q.page.save()
mturoci commented 1 year ago

Hi @Venkat-Rajgopal. The reason your code above is not working is because you have used a fixed grid layout (box='1 1 10 1'). If you want to achieve responsiveness, you need to reach for flex layout instead.

# Layout / Responsive
# How to create a #responsive #layout.
# ---
from h2o_wave import main, app, Q, ui

@app('/')
async def serve(q: Q):
    content = '![Wave University](https://raw.githubusercontent.com/h2oai/wave/master/assets/brand/wave-university-wide.png)'

    # The meta card's 'zones' attribute defines placeholder zones to lay out cards for different viewport sizes.
    # We define three layout schemes here.
    q.page['meta'] = ui.meta_card(box='', layouts=[
        ui.layout(
            # If the viewport width >= 0:
            breakpoint='xs',
            zones=[
                # 80px high header
                ui.zone('header', size='80px'),
                # Use remaining space for content
                ui.zone('content')
            ]
        ),
    ])

    q.page['header'] = ui.header_card(
        # Place card in the header zone, regardless of viewport size.
        box='header',
        title='Lorem Ipsum',
        subtitle='Excepteur sint occaecat cupidatat',
        nav=[
            ui.nav_group('Menu', items=[
                ui.nav_item(name='#menu/spam', label='Spam'),
                ui.nav_item(name='#menu/ham', label='Ham'),
                ui.nav_item(name='#menu/eggs', label='Eggs'),
            ]),
            ui.nav_group('Help', items=[
                ui.nav_item(name='#about', label='About'),
                ui.nav_item(name='#support', label='Support'),
            ])
        ],
    )
    q.page['controls'] = ui.markdown_card(
        # If the viewport width >= 0, place in content zone.
        # If the viewport width >= 768, place in sidebar zone.
        # If the viewport width >= 1200, place in sidebar zone.
        box='content',
        title='Controls',
        content=content,
    )
    await q.page.save()
Venkat-Rajgopal commented 1 year ago

Hi @Venkat-Rajgopal. The reason your code above is not working is because you have used a fixed grid layout (box='1 1 10 1'). If you want to achieve responsiveness, you need to reach for flex layout instead.

# Layout / Responsive
# How to create a #responsive #layout.
# ---
from h2o_wave import main, app, Q, ui

@app('/')
async def serve(q: Q):
    content = '![Wave University](https://raw.githubusercontent.com/h2oai/wave/master/assets/brand/wave-university-wide.png)'

    # The meta card's 'zones' attribute defines placeholder zones to lay out cards for different viewport sizes.
    # We define three layout schemes here.
    q.page['meta'] = ui.meta_card(box='', layouts=[
        ui.layout(
            # If the viewport width >= 0:
            breakpoint='xs',
            zones=[
                # 80px high header
                ui.zone('header', size='80px'),
                # Use remaining space for content
                ui.zone('content')
            ]
        ),
    ])

    q.page['header'] = ui.header_card(
        # Place card in the header zone, regardless of viewport size.
        box='header',
        title='Lorem Ipsum',
        subtitle='Excepteur sint occaecat cupidatat',
        nav=[
            ui.nav_group('Menu', items=[
                ui.nav_item(name='#menu/spam', label='Spam'),
                ui.nav_item(name='#menu/ham', label='Ham'),
                ui.nav_item(name='#menu/eggs', label='Eggs'),
            ]),
            ui.nav_group('Help', items=[
                ui.nav_item(name='#about', label='About'),
                ui.nav_item(name='#support', label='Support'),
            ])
        ],
    )
    q.page['controls'] = ui.markdown_card(
        # If the viewport width >= 0, place in content zone.
        # If the viewport width >= 768, place in sidebar zone.
        # If the viewport width >= 1200, place in sidebar zone.
        box='content',
        title='Controls',
        content=content,
    )
    await q.page.save()

Thanks that would work. Can I resize the cards which are then placed in the content box. ?

For eg this here occupies the whole window.

labels = ['foo', 'bar', 'bla']
q.page['fleet-option'] = ui.form_card(box='content',
                                          items=[
                                              ui.dropdown(name='dropdown',
                                                          label='Fleets',
                                                          choices=[ui.choice(
                                                              name=fleet,
                                                              label=fleet) for
                                                                   fleet in
                                                                   labels],
                                                          )])
mturoci commented 1 year ago

Can I resize the cards which are then placed in the content box. ?

Yes, everything you need is in the docs.