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

Introducing EuiSearchBar #379

Merged
merged 8 commits into from
Feb 15, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- Added importAction and exportAction icons ([#394](https://github.com/elastic/eui/pull/394))
- Added `EuiCard` for UI patterns that need an icon/image, title and description with some sort of action. ([#380](https://github.com/elastic/eui/pull/380))
- Add TypeScript definitions for the `<EuiHealth>` component. ([#403](https://github.com/elastic/eui/pull/403))
- Added `SearchBar` component - introduces a simple yet rich query language to search for objects + search box and filter controls to construct/manipulate it. ([#379](https://github.com/elastic/eui/pull/379))

**Bug fixes**

Expand Down
2 changes: 1 addition & 1 deletion docs/bundle.js.map

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"moment": "2.13.0",
"node-sass": "^4.5.3",
"npm-run": "^4.1.2",
"pegjs": "^0.9.0",
"postcss-cli": "^4.1.1",
"postcss-inline-svg": "^3.0.0",
"postcss-loader": "^2.0.8",
Expand Down
45 changes: 22 additions & 23 deletions src-docs/src/components/guide_section/guide_section.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@ import {
EuiLink
} from '../../../../src/components';

function markup(text) {
const regex = /(#[a-zA-Z]+)|(`[^`]+`)/g;
return text.split(regex).map((token, index) => {
if (!token) {
return '';
}
if (token.startsWith('#')) {
const id = token.substring(1);
const onClick = () => {
document.getElementById(id).scrollIntoView();
};
return <EuiLink key={`markup-${index}`} onClick={onClick}>{id}</EuiLink>;
}
if (token.startsWith('`')) {
const code = token.substring(1, token.length - 1);
return <EuiCode key={`markup-${index}`}>{code}</EuiCode>;
}
return token;

});
}

const humanizeType = type => {
if (!type) {
Expand Down Expand Up @@ -170,28 +191,6 @@ export class GuideSection extends Component {

const humanizedType = humanizeType(type);

function markup(text) {
const regex = /(#[a-zA-Z]+)|(`[^`]+`)/g;
return text.split(regex).map((token, index) => {
if (!token) {
return '';
}
if (token.startsWith('#')) {
const id = token.substring(1);
const onClick = () => {
document.getElementById(id).scrollIntoView();
};
return <EuiLink key={`markup-${index}`} onClick={onClick}>{id}</EuiLink>;
}
if (token.startsWith('`')) {
const code = token.substring(1, token.length - 1);
return <EuiCode key={`markup-${index}`}>{code}</EuiCode>;
}
return token;

});
}

const typeMarkup = markup(humanizedType);
const descriptionMarkup = markup(propDescription);
let defaultValueMarkup = '';
Expand Down Expand Up @@ -238,7 +237,7 @@ export class GuideSection extends Component {
descriptionElement = (
<div key={`description-${componentName}`}>
<EuiText>
<p>{description}</p>
<p>{markup(description)}</p>
</EuiText>
<EuiSpacer size="m" key={`propsSpacer-${componentName}`} />
</div>
Expand Down
8 changes: 8 additions & 0 deletions src-docs/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ import { ErrorBoundaryExample }
import { ExpressionExample }
from './views/expression/expression_example';

import { FilterGroupExample }
from './views/filter_group/filter_group_example';

import { FlexExample }
from './views/flex/flex_example';

Expand Down Expand Up @@ -127,6 +130,9 @@ import { PopoverExample }
import { ProgressExample }
from './views/progress/progress_example';

import { SearchBarExample }
from './views/search_bar/search_bar_example';

import { SideNavExample }
from './views/side_nav/side_nav_example';

Expand Down Expand Up @@ -223,6 +229,7 @@ const components = [
DescriptionListExample,
ErrorBoundaryExample,
ExpressionExample,
FilterGroupExample,
FlexExample,
FlyoutExample,
FormExample,
Expand All @@ -241,6 +248,7 @@ const components = [
PanelExample,
PopoverExample,
ProgressExample,
SearchBarExample,
SideNavExample,
SpacerExample,
StepsExample,
Expand Down
129 changes: 129 additions & 0 deletions src-docs/src/views/filter_group/filter_group.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@

import React, {
Component,
} from 'react';

import {
EuiPopover,
EuiPopoverTitle,
EuiFieldSearch,
EuiFilterSelectItem,
EuiLoadingChart,
EuiSpacer,
EuiIcon,
EuiFilterGroup,
EuiFilterButton,
} from '../../../../src/components';

export default class extends Component {
constructor(props) {
super(props);

this.state = {
isPopoverOpen: false,
};
}

onButtonClick() {
this.setState({
isPopoverOpen: !this.state.isPopoverOpen,
});
}

closePopover() {
this.setState({
isPopoverOpen: false,
});
}

render() {

const items = [
{ name: 'Johann Sebastian Bach', checked: 'on' },
{ name: 'Wolfgang Amadeus Mozart', checked: 'on' },
{ name: 'Antonín Dvořák', checked: 'off' },
{ name: 'Dmitri Shostakovich' },
{ name: 'Felix Mendelssohn-Bartholdy' },
{ name: 'Franz Liszt' },
{ name: 'Franz Schubert' },
{ name: 'Frédéric Chopin' },
{ name: 'Georg Friedrich Händel' },
{ name: 'Giuseppe Verdi' },
{ name: 'Gustav Mahler' },
{ name: 'Igor Stravinsky' },
{ name: 'Johannes Brahms' },
{ name: 'Joseph Haydn' },
{ name: 'Ludwig van Beethoven' },
{ name: 'Piotr Illitch Tchaïkovsky' },
{ name: 'Robert Schumann' },
{ name: 'Sergej S. Prokofiew' },
{ name: 'Wolfgang Amadeus Mozart' },
];

const button = (
<EuiFilterButton
iconType="arrowDown"
onClick={this.onButtonClick.bind(this)}
isSelected={this.state.isPopoverOpen}
hasActiveFilters={true}
>
Composers
</EuiFilterButton>
);

return (
<EuiFilterGroup>
<EuiFilterButton>
Filter on
</EuiFilterButton>
<EuiFilterButton>
Filter off
</EuiFilterButton>
<EuiPopover
id="popover"
ownFocus
button={button}
isOpen={this.state.isPopoverOpen}
closePopover={this.closePopover.bind(this)}
panelPaddingSize="none"
withTitle
panelClassName="euiFilterGroup__popoverPanel"
>
<EuiPopoverTitle>
<EuiFieldSearch />
</EuiPopoverTitle>
<div className="euiFilterSelect__items">
{items.map((item, index) => (
<EuiFilterSelectItem
checked={item.checked}
key={index}
>
{item.name}
</EuiFilterSelectItem>
))}
{/*
Use when loading items initially
*/}
<div className="euiFilterSelect__note">
<div className="euiFilterSelect__noteContent">
<EuiLoadingChart size="m" />
<EuiSpacer size="xs" />
<p>Loading filters</p>
</div>
</div>
{/*
Use when no results are returned
*/}
<div className="euiFilterSelect__note">
<div className="euiFilterSelect__noteContent">
<EuiIcon type="minusInCircle" />
<EuiSpacer size="xs" />
<p>No filters found</p>
</div>
</div>
</div>
</EuiPopover>
</EuiFilterGroup>
);
}
}
65 changes: 65 additions & 0 deletions src-docs/src/views/filter_group/filter_group_example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from 'react';

import { renderToHtml } from '../../services';

import {
GuideSectionTypes,
} from '../../components';

import {
EuiCallOut,
EuiCode,
EuiFilterGroup,
EuiFilterButton,
EuiFilterSelectItem,
EuiSpacer,
} from '../../../../src/components';

import FilterGroup from './filter_group';
const filterGroupSource = require('!!raw-loader!./filter_group');
const filterGroupHtml = renderToHtml(FilterGroup);

export const FilterGroupExample = {
title: 'FilterGroup',
intro: (
<div>
<EuiCallOut
title="Demo of visual pattern only"
color="warning"
>
<p>
This documents a visual pattern used for filtering (usually page heads next to search).
The individual components themselves are very simple
and do not have much functionality on their own. If you are looking for expanded usage
examples please check out the Table of Records component which uses this more fully and
can give you a better example of its usage when applied to filtering.
</p>
</EuiCallOut>

<EuiSpacer size="l" />
</div>
),
sections: [{
title: 'FilterGroup',
source: [{
type: GuideSectionTypes.JS,
code: filterGroupSource,
}, {
type: GuideSectionTypes.HTML,
code: filterGroupHtml,
}],
text: (
<p>
Use <EuiCode>EuiFilterGroup</EuiCode> to wrap <EuiCode>EuiFilterButton</EuiCode>s
into a container that looks nice against form fields (like search). These buttons
are used in two different patterns. The first, as a simple on/off pattern to show
whether a setting is on. The second is as delivery for a popover for filtering an
array of passed items. This mostly uses standard popover mechanics, but the
component <EuiCode>EuiFilterSelectItem</EuiCode> is used for the items themselves.
</p>
),
components: { EuiFilterGroup },
props: { EuiFilterGroup, EuiFilterButton, EuiFilterSelectItem },
demo: <FilterGroup />,
}],
};
Loading