Skip to content

Conversation

@taichi765
Copy link
Contributor

@taichi765 taichi765 commented Nov 17, 2025

Summary

This PR adds an orientation property to TabWidget (Material style only), allowing the tab bar to be displayed vertically.

Related issue: #3688

Example

TabWidget {
        orientation: Orientation.vertical;
        Tab {

        }
}

Notes

  • @children inside if is not yet supproted, so the implementation switches between two internal components at compile time.
export component TabBarImpl inherits TabBarBase {
    Flickable {
        if root.orientation==Orientation.vertical:VerticalLayout {
            @children// The @children placeholder cannot appear in a conditional element
        }
        if root.orientation==Orientation.horizontal:HorizontalLayout{
            @children
        }
    }
}
  • Because of this, runtime bindings for orientation are not supported.
    For example:
component MyTabs {
    in property <Orientation> orientation;

    TabWidget {
        orientation: root.orientation;// this will be ignored
    }
}

Questions

  • Is the compile-time switching approach acceptable for now?
  • Is there a better way to implement vertical tabbar?

@CLAassistant
Copy link

CLAassistant commented Nov 17, 2025

CLA assistant check
All committers have signed the CLA.

@ogoffart
Copy link
Member

Thanks for opening a PR.

I think this is a feature we should have.

Is the compile-time switching approach acceptable for now?

I'd say so, yes.

Is there a better way to implement vertical tabbar?

I'm afraid all the other ways would required change that would be more complicated (but that we probably still want)
Either:

  1. Add a OrientedLayout that has an orientation argument at runtime (name to be bikeshedded)
  2. Use a GridLayout and have the compiler set the row/col for the individual tab
  3. Not use a XXXLayout in TabBarImpl, but have the lower_tabwidget pass have the equivalent of a OrientedLayout despite that wouldn't be in the Slint language.

(Supporting @children in if would have the problem that it wouldn't be possible to reference the item anymore, unless we use other trick like a switch or something where we have @children on each branch or have a more complex language feature which is out of scope for this)

So thinking of it, the OrientedLayout seems to be the easier, and it could even be kept internal.
But as I said, I think it is fine to keep it compile-time constant for now.

Btw, if making it a const expression, we should also forbid assignement like so:

popup.properties.get_mut("close-policy").unwrap().property_visibility =
PropertyVisibility::Constexpr;

and make it an error when it is not specified at compile time.

@taichi765
Copy link
Contributor Author

taichi765 commented Nov 22, 2025

Thanks for the advice!
I've added it.

Remaining tasks:

  • Update Cosmic tabwidget
  • Update Cupertino tabwidget
  • Update Fluent tabwidget
  • Update Qt tabwidget
  • Write test

Is there anything else?

@taichi765
Copy link
Contributor Author

taichi765 commented Nov 27, 2025

With the Qt style, I was able to arrange the tabs vertically and put the tab bar to the left of the content, but the tab titles are missing.image

@taichi765
Copy link
Contributor Author

With Qt style, I was able to arrange the tabs vertically and put the tab bar to the left of the content, but the tab titles are missing.

Now I'm seeing the expected appearance.

Qt style:
image

However, tab alignment in Qt is very different from others (Qt is flex-start, others are stretch).
@ogoffart Should we make the same alignment across them?
If so, which one should we follow?
In my opinion, flex-start looks tidier for a vertical tab bar, so I'd like to use it in non-Qt styles —but making it the default would be a breaking change to existing behavior.
Alternatively, should we add an option to configure alignment?

Fluent style:
image

@ogoffart
Copy link
Member

From the description, I was thinking that the text would be rotated for the vertical tabs.
But Ok, it can be done like that too.

There is no such tab in the design file from the fluent design so i think we can make our own.

I think we should indeed align the tab to the top. But we don't need to change the behavior of the horizontal ones.

@NigelBreslaw Do you have opinions about that?

@taichi765
Copy link
Contributor Author

taichi765 commented Dec 1, 2025

Sorry for my late response.
I tried setting alignment to LayoutAlignment.start but it doesn't look good. (spacing, font size etc.)

export component TabBarVerticalImpl inherits FluentTabBarBase {
    Flickable {
        VerticalLayout {
            alignment: LayoutAlignment.start; //align to the top
            @children
        }
    }
}
image

 

There is no such tab in the design file from the fluent design so i think we can make our own.

NavigationView from WinUI 3 might provide similar functionality to TabWidget.

As explained in TabView's documentation, TabView is good for document tabs and NavigationView is good for static tabs.
I guess slint's TabWidget is commonly used as static tabe, following NavigationView's style seems reasonable.

@taichi765 taichi765 marked this pull request as ready for review December 1, 2025 12:15
Copy link
Member

@ogoffart ogoffart left a comment

Choose a reason for hiding this comment

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

Great, thank you!

@ogoffart
Copy link
Member

ogoffart commented Dec 1, 2025

I tried setting alignment to LayoutAlignment.start but it doesn't look good. (spacing, font size etc.)

I guess some adjustement to the implementation of the tab are needed in the vertical mode.

@taichi765
Copy link
Contributor Author

I agree.
Should I continue on this PR or create new one?

@ogoffart ogoffart merged commit 357423b into slint-ui:master Dec 1, 2025
41 checks passed
@ogoffart
Copy link
Member

ogoffart commented Dec 1, 2025

Should I continue on this PR or create new one?

Let's have it in a follow-up PR.
Would be great if you could do it.
Thanks for your contribution.

Another thing i forgot as well is the documentation. Could you add the new property to docs/astro/src/content/docs/reference/std-widgets/views/tabwidget.mdx in a follow up. Thanks.

@taichi765 taichi765 deleted the feature/tabwidget-tabbar-position branch December 2, 2025 02:23
ogoffart pushed a commit that referenced this pull request Dec 3, 2025
burhankhanzada pushed a commit to burhankhanzada/slint that referenced this pull request Dec 8, 2025
burhankhanzada pushed a commit to burhankhanzada/slint that referenced this pull request Dec 8, 2025
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.

3 participants