Skip to content
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

Tabs2 ➡️ Tabs #1900

Merged
merged 7 commits into from
Dec 15, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions packages/core/src/common/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,6 @@ export const SLIDER_ZERO_STEP = ns + ` <Slider> stepSize must be greater than ze
export const SLIDER_ZERO_LABEL_STEP = ns + ` <Slider> labelStepSize must be greater than zero.`;
export const RANGESLIDER_NULL_VALUE = ns + ` <RangeSlider> value prop must be an array of two non-null numbers.`;

export const TABS_FIRST_CHILD = ns + ` First child of <Tabs> component must be a <TabList>`;
export const TABS_MISMATCH = ns + ` Number of <Tab> components must equal number of <TabPanel> components`;
export const TABS_WARN_DEPRECATED =
deprec +
` <Tabs> is deprecated since v1.11.0; consider upgrading to <Tabs2>.` +
" https://blueprintjs.com/#components.tabs.js";

export const TOASTER_WARN_INLINE = ns + ` Toaster.create() ignores inline prop as it always creates a new element.`;
export const TOASTER_WARN_LEFT_RIGHT = ns + ` Toaster does not support LEFT or RIGHT positions.`;

Expand Down
1 change: 0 additions & 1 deletion packages/core/src/components/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
@page sliders
@page table
@page tabs
@page tabs2
@page tag
@page tag-input
@page text
Expand Down
4 changes: 0 additions & 4 deletions packages/core/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ export * from "./spinner/spinner";
export * from "./spinner/svgSpinner";
export * from "./tabs/tab";
export * from "./tabs/tabs";
export * from "./tabs/tabList";
export * from "./tabs/tabPanel";
export * from "./tabs2/tab2";
export * from "./tabs2/tabs2";
export * from "./tag/tag";
export * from "./tag-input/tagInput";
export * from "./toast/toast";
Expand Down
50 changes: 23 additions & 27 deletions packages/core/src/components/tabs/tab.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015 Palantir Technologies, Inc. All rights reserved.
* Copyright 2017 Palantir Technologies, Inc. All rights reserved.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤔 original date?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm down to leave the original date.

Copy link
Contributor

Choose a reason for hiding this comment

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

I like to use 2015-present since it's never out of date

*
* Licensed under the terms of the LICENSE file distributed with this project.
*/
Expand All @@ -11,55 +11,51 @@ import * as React from "react";
import * as Classes from "../../common/classes";
import { IProps } from "../../common/props";

export type TabId = string | number;

export interface ITabProps extends IProps {
/**
* Element ID.
* @internal
* Whether the tab is disabled.
* @default false
*/
id?: string;
disabled?: boolean;

/**
* Whether the tab is disabled.
* @default false
* Unique identifier used to control which tab is selected
* and to generate ARIA attributes for accessibility.
*/
isDisabled?: boolean;
id: TabId;

/**
* Whether the tab is currently selected.
* @internal
* Panel content, rendered by the parent `Tabs` when this tab is active.
* If omitted, no panel will be rendered for this tab.
*/
isSelected?: boolean;
panel?: JSX.Element;

/**
* The ID of the tab panel which this tab corresponds to.
* @internal
* Content of tab title element, rendered in a list above the active panel.
* Can also be set via React `children`.
*/
panelId?: string;
title?: string | JSX.Element;
}

@PureRender
export class Tab extends React.Component<ITabProps, {}> {
public static defaultProps: ITabProps = {
isDisabled: false,
isSelected: false,
disabled: false,
id: undefined,
};

public static displayName = "Blueprint.Tab";

// this component is never rendered directly; see Tabs#renderTabPanel()
/* istanbul ignore next */
public render() {
const { className, panel } = this.props;
return (
<li
aria-controls={this.props.panelId}
aria-disabled={this.props.isDisabled}
aria-expanded={this.props.isSelected}
aria-selected={this.props.isSelected}
className={classNames(Classes.TAB, this.props.className)}
id={this.props.id}
role="tab"
tabIndex={this.props.isDisabled ? null : 0}
>
{this.props.children}
</li>
<div className={classNames(Classes.TAB_PANEL, className)} role="tablist">
{panel}
</div>
);
}
}
Expand Down
59 changes: 0 additions & 59 deletions packages/core/src/components/tabs/tabList.tsx

This file was deleted.

45 changes: 0 additions & 45 deletions packages/core/src/components/tabs/tabPanel.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import * as PureRender from "pure-render-decorator";
import * as React from "react";

import * as Classes from "../../common/classes";
import { ITab2Props, TabId } from "./tab2";
import { ITabProps, TabId } from "./tab";

export interface ITabTitleProps extends ITab2Props {
export interface ITabTitleProps extends ITabProps {
/** Handler invoked when this tab is clicked. */
onClick: (id: TabId, event: React.MouseEvent<HTMLElement>) => void;

Expand Down
104 changes: 39 additions & 65 deletions packages/core/src/components/tabs/tabs.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
@# Tabs

<div class="pt-callout pt-intent-danger pt-icon-error">
<h5>The `Tabs` JavaScript API is deprecated since v1.11.0</h5>
The following `Tabs` React components been deprecated in v1.11.0 favor of the [simpler and more flexible
`Tabs2` API](#core/components/tabs2). `Tabs2` will replace `Tabs` in version 2.0. The CSS API has not been changed.
</div>

@## CSS API

In addition to the [JavaScript API](#core/components/tabs2.javascript-api), Blueprint also offers tab styles with the
In addition to the [JavaScript API](#core/components/tabs.javascript-api), Blueprint also offers tab styles with the
class `pt-tabs`. You should add the proper accessibility attributes (`role`, `aria-selected`, and
`aria-hidden`) if you choose to implement tabs with CSS.

Expand All @@ -18,67 +12,56 @@ JavaScript component does this by default).

@css pt-tabs

@## Deprecated JavaScript API

<div class="pt-callout pt-intent-danger pt-icon-error">
These components are deprecated since v1.11.0. Please use the [`Tabs2` API](#core/components/tabs2) instead.
</div>
@## JavaScript API

The `Tabs`, `TabList`, `Tab`, and `TabPanel` components are available in the __@blueprintjs/core__
The `Tabs` and `Tab` components are available in the __@blueprintjs/core__
package. Make sure to review the [general usage docs for JS components](#blueprint.usage).

Four components are necessary to render tabs: `Tabs`, `TabList`, `Tab`, and `TabPanel`.

For performance reasons, only the currently active `TabPanel` is rendered into the DOM. When the
user switches tabs, data stored in the DOM is lost. This is not an issue in React applications
because of how the library manages the virtual DOM for you.
Tab selection is managed by `id`, much like the HTML `<select>` element respects `<option value>`. This is more reliable than using a numeric index (it's also deterministic), and
does not require translating between numbers and tab names. It does, however, require that
every `Tab` have a locally unique `id` prop.

@### Sample usage
Arbitrary elements are supported in the tab list, and order is respected. Yes, you can even
insert things _between_ `Tab`s.

```tsx
<Tabs>
<TabList>
<Tab>First tab</Tab>
<Tab>Second tab</Tab>
<Tab>Third tab</Tab>
<Tab isDisabled={true}>Fourth tab</Tab>
</TabList>
<TabPanel>
First panel
</TabPanel>
<TabPanel>
Second panel
</TabPanel>
<TabPanel>
Third panel
</TabPanel>
<TabPanel>
Fourth panel
</TabPanel>
import { Tab, Tabs } from "@blueprintjs/core";

<Tabs id="TabsExample" onChange={this.handleTabChange} selectedTabId="rx">
<Tab id="ng" title="Angular" panel={<AngularPanel />} />
<Tab id="mb" title="Ember" panel={<EmberPanel />} />
<Tab id="rx" title="React" panel={<ReactPanel />} />
<Tab id="bb" disabled title="Backbone" panel={<BackbonePanel />} />
<Tabs.Expander />
<input className="pt-input" type="text" placeholder="Search..." />
</Tabs>
```

Every component accepts a `className` prop that can be used to set additional classes on the
component's root element. You can get larger tabs by using the `pt-large` class on `TabList`.
@reactExample TabsExample

You can use the `Tabs` API in controlled or uncontrolled mode. The props you supply will differ
between these approaches.
@### Tabs

@reactExample TabsExample
`Tabs` is the top-level component responsible for rendering the tab list and coordinating selection.
It can be used in controlled mode by providing `selectedTabId` and `onChange` props, or in
uncontrolled mode by optionally providing `defaultSelectedTabId` and `onChange`.

@### Tabs props
Children of the `Tabs` are rendered in order in the tab list, which is a flex container.
`Tab` children are managed by the component; clicking one will change selection. Arbitrary other
children are simply rendered in order; interactions are your responsibility.

<div class="pt-callout pt-intent-danger pt-icon-error">
This component is deprecated since v1.11.0. Please use the [`Tabs2` API](#core/components/tabs2) instead.
</div>
Insert a `<Tabs.Expander />` between any two children to right-align all subsequent children (or bottom-align when `vertical`).

@interface ITabsProps

@### Tab props
@### Tab

`Tab` is a minimal wrapper with no functionality of its own&mdash;it is managed entirely by its
parent `Tabs` wrapper. Tab title text can be set either via `title` prop or via React children
(for more complex content).

<div class="pt-callout pt-intent-danger pt-icon-error">
This component is deprecated since v1.11.0. Please use the [`Tabs2` API](#core/components/tabs2) instead.
</div>
The associated tab `panel` will be visible when the `Tab` is active. Omitting `panel` is perfectly
safe and allows you to control exactly where the panel appears in the DOM (by rendering it yourself
as needed).

@interface ITabProps

Expand All @@ -91,27 +74,18 @@ applications. Here's how you might configure tabs to work with it:
```tsx
import { render } from "react-dom";
import { Router, Route } from "react-router";
import { Tabs, TabList, Tab, TabPanel } from "@blueprintjs/core";
import { Tabs, Tab } from "@blueprintjs/core";

const App = () => { ... };

// keys are necessary in JSX.Element lists to keep React happy
const contents = [
<TabList key={0}>
<Tab>Home</Tab>
<Tab>Projects</Tab>
</TabList>,
<TabPanel key={1}>
home things
</TabPanel>,
<TabPanel key={2}>
projects things
</TabPanel>,
<Tab key="home" id="home" title="Home" panel={<HomePanel />}>,
<Tab key="proj" id="projects" title="Projects" panel={<ProjectsPanel />}>,
];

// using SFCs from TS 1.8, but easy to do without them
export const Home = () => <Tabs selectedTabIndex={0}>{contents}</Tabs>;
export const Projects = () => <Tabs selectedTabIndex={1}>{contents}</Tabs>;
export const Home = () => <Tabs selectedTabId="home">{contents}</Tabs>;
export const Projects = () => <Tabs selectedTabId="projects">{contents}</Tabs>;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@adidahiya are these updates correct? is this section still useful?

Copy link
Contributor

Choose a reason for hiding this comment

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

hmm, we should probably remove this react router section because it probably doesn't work with react-router v4. we can add it back if requested by users.


render(
<Router path="/" component={App}>
Expand Down
Loading