Panels

Featured prominently in Asides, the Panel is simply a container with a scrollbar. But Panels can also be used to generate entire page layouts — such as this one.

We can position Panel elements as direct children of the body to autogenerate tabs in the TopBar. The tabs at the top of this page are created with the markup shown below.

<body>
	<header data-ts="TopBar"></header>
	<div data-ts="Panel" data-ts.label="Panel One">
		<main data-ts="Main">
			<div data-ts="MainContent"></div>
		</main>
	</div>
	<div data-ts="Panel" data-ts.label="Panel Two">
		<main data-ts="Main">
			<div data-ts="MainContent"></div>
		</main>
	</div>
	<div data-ts="Panel" data-ts.label="Panel Three">
		<main data-ts="Main">
			<div data-ts="MainContent"></div>
		</main>
	</div>
</body>

Note that the content of the three "pages" are each wrapped inside a nested Main element. It is possible to nest further Panel elements inside these Main elements to generate additional TabBars as seen in Panel Two.

When to use this?

Certainly when you are prototyping as a UX designer, but it will otherwise depend on your technology stack (since this may not a good fit for all frameworks) and on your requirements. If you app features highly dynamic navigation, it may be easier to approach this kind of multi-page layout programatically instead of declaratively.

History support

To avoid conflicts with your favorite routing library, Tradeshift UI will not attempt to update the history (via the address bar). You can however add history support if you manually intercept tab selection like this.

ts.ui.TopBar.tabs().onselect = function(newindex, oldindex) {
	// update history here
};

Panel Two A

Second level navigation is in danger of becoming deprecated, so please be cautious with this design pattern.

In this Panel, the nested Main contains two additional Panel elements to automatically generate the TabBar seen above.

<body>
	<!-- Panel One -->
	<div data-ts="Panel" data-ts.label="Panel Two">
		<main data-ts="Main">
			<div data-ts="MainContent">
				<div data-ts="Panel" data-ts.label="Panel Two A"></div>
				<div data-ts="Panel" data-ts.label="Panel Two B"></div>
			</div>
		</main>
	<div>
	<!-- Panel Three -->
</body>

Dynamic updates

You can add or remove tabs in this TabBar above by appending or detaching further Panel elements, but if you need to assign onselect callbacks or change the label of the tabs, you will need a programatic API that resembles the Main TabBar except you must involve the ordinal index of the root Panel (the Panel that is a child of body).

var index = 1; // the root panel index!!!
var tabs = ts.ui.TabBar.get(index).tabs();
tabs[1].label = 'Select Me!';
tabs[1].onselect = function() {
	ts.ui.Notification.success('Thanks!');
};

Panel Two B

Bacon ipsum Tradeshift döner, shoulder loin drumstick Pork Chop Express. Swine biltong pastrami fatback meatball ham rump boudin picanha. Ground round beef ribs doner boudin, brisket biltong t-bone capicola. Corned beef flank pancetta sirloin jowl meatball pork chop alcatra. Landjaeger biltong pork chop alcatra spare ribs, turducken strip steak bresaola shankle chicken pastrami doner salami brisket. Ham hock biltong t-bone, salami sausage pork spare ribs beef flank pig. Kevin meatloaf turducken short loin sausage spare ribs tongue ham hock leberkas ham strip steak pig jerky. Tenderloin alcatra leberkas shoulder sirloin pancetta short ribs pastrami t-bone tri-tip pork belly kevin.

Tenderloin filet mignon chicken, spare ribs meatball capicola ham jerky swine bresaola pork chop ribeye cupim t-bone bacon. Pork belly tail swine ham hock alcatra pork chop shoulder pastrami spare ribs venison hamburger beef drumstick pancetta. Kevin swine ham spare ribs strip steak andouille rump. Pork chop rump filet mignon, shankle pastrami ground round landjaeger ribeye shoulder strip steak chicken bresaola. Swine turkey bresaola, flank jerky salami bacon filet mignon. Turducken jowl pork chop, meatball pastrami swine ball tip leberkas.

Doner cow chicken, rump swine flank salami. Pork belly bacon tenderloin tongue cow, tri-tip alcatra short ribs turducken chicken biltong drumstick meatball. Drumstick frankfurter shank sausage andouille shankle. Strip steak flank brisket ham pastrami, shoulder hamburger chicken drumstick meatball tail. Brisket drumstick meatball leberkas beef ribs. Prosciutto bacon pork shoulder salami. Meatloaf salami beef chuck biltong.

Panel Three

In this Panel, we have a nested SideBar just to show that it must be positioned either before or after the Main element.

<body>
	<!-- Panel One -->
	<!-- Panel Two -->
	<div data-ts="Panel" data-ts.label="Panel Three">
		<aside data-ts="SideBar" data-ts.title="SideBar">
			<div data-ts="Panel"></div>
		</aside>
		<main data-ts="Main"></main>
	</div>
</body>