Skip to content

Commit

Permalink
add isSelected and isHighlighted to render prop
Browse files Browse the repository at this point in the history
  • Loading branch information
vutran authored and adnasa committed Dec 21, 2017
1 parent 5e20576 commit b5a6f4c
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 48 deletions.
2 changes: 1 addition & 1 deletion __tests__/ResultsItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('ResultsItem', () => {
.create(
React.createElement(ResultsItem, {
item,
highlighted: true,
selected: true,
children: null,
})
)
Expand Down
2 changes: 1 addition & 1 deletion src/Results.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default function Results<T>(props: Props<T>) {
React.createElement(ResultsItem, {
key,
children: props.children,
highlighted: props.selectedIndex === key,
selected: props.selectedIndex === key,
item,
onMouseEnter:
props.onMouseEnterItem &&
Expand Down
41 changes: 10 additions & 31 deletions src/ResultsItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import { COLORS, DEFAULT_HEIGHT } from './constants';
import { AnchorItem } from './modifiers/anchor';
import AnchorRenderer from './modifiers/anchor/AnchorRenderer';

Expand All @@ -14,71 +13,51 @@ interface Props<T> {
onMouseLeave?: (e: any /* Event */) => void;
// onClick callback
onClickItem?: (e: any /* Event */) => void;
// set to true to highlight the given item
highlighted?: boolean;
// set to true if the item is currently selected
selected?: boolean;
// optional style override
style?: React.CSSProperties;
}

interface State {
// set to true to highlight
hover: boolean;
highlighted: boolean;
}

const ITEM_STYLE: React.CSSProperties = {
height: DEFAULT_HEIGHT,
lineHeight: `${DEFAULT_HEIGHT}px`,
fontSize: 24,
borderStyle: 'solid',
borderColor: COLORS.DARKGRAY,
borderTopWidth: 0,
borderLeftWidth: 1,
borderRightWidth: 1,
borderBottomWidth: 1,
boxSizing: 'border-box',
};

const ITEM_HOVER_STYLE: React.CSSProperties = {
backgroundColor: COLORS.GRAY,
};

export default class ResultRenderer<T> extends React.PureComponent<
Props<T>,
State
> {
static defaultProps = {
highlighted: false,
selected: false,
};

state: State = {
hover: false,
highlighted: false,
};

handleMouseEnter = (evt: any /* Event */) => {
this.setState({ hover: true });
this.setState({ highlighted: true });
this.props.onMouseEnter && this.props.onMouseEnter(evt);
};

handleMouseLeave = (evt: any /* Event */) => {
this.setState({ hover: false });
this.setState({ highlighted: false });
this.props.onMouseLeave && this.props.onMouseLeave(evt);
};

render() {
const item = this.props.item;
let style: React.CSSProperties = { ...ITEM_STYLE, ...this.props.style };

if (this.props.highlighted || this.state.hover) {
style = { ...style, ...ITEM_HOVER_STYLE };
}

const renderer = this.props.children
? this.props.children
: (AnchorRenderer as Omnibar.ResultRenderer<T>);

return renderer({
style,
style: this.props.style,
item,
isSelected: this.props.selected,
isHighlighted: this.state.highlighted,
onMouseEnter: this.handleMouseEnter,
onMouseLeave: this.handleMouseLeave,
onClick: this.props.onClickItem,
Expand Down
37 changes: 31 additions & 6 deletions src/modifiers/anchor/AnchorRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,50 @@
import * as React from 'react';
import { AnchorItem } from './';
import { COLORS } from '../../constants';
import { COLORS, DEFAULT_HEIGHT } from '../../constants';

interface Props<T> {
// the item
item: AnchorItem & T;
isSelected?: boolean;
isHighlighted?: boolean;
}

const ANCHOR_STYLE: React.CSSProperties = {
display: 'block',
textDecoration: 'none',
const ITEM_STYLE: React.CSSProperties = {
borderBottomWidth: 1,
borderColor: COLORS.DARKGRAY,
borderLeftWidth: 1,
borderRightWidth: 1,
borderStyle: 'solid',
borderTopWidth: 0,
boxSizing: 'border-box',
color: COLORS.BLACK,
display: 'block',
fontSize: 24,
height: DEFAULT_HEIGHT,
lineHeight: `${DEFAULT_HEIGHT}px`,
paddingLeft: 15,
paddingRight: 15,
textDecoration: 'none',
};

const ITEM_HOVER_STYLE: React.CSSProperties = {
backgroundColor: COLORS.GRAY,
};

export default function AnchorRenderer<T>(
props: Props<T> & React.HTMLAttributes<HTMLAnchorElement>
) {
const { item, style, ...rest } = props;
const mergedStyle = { ...ANCHOR_STYLE, ...style };
const { item, isSelected, isHighlighted, style, ...rest } = props;

const mergedStyle = { ...ITEM_STYLE, ...style };

if (isSelected) {
mergedStyle.backgroundColor = COLORS.GRAY;
}

if (isHighlighted) {
mergedStyle.backgroundColor = COLORS.DARKGRAY;
}

return (
<a href={item.url} style={mergedStyle} {...rest}>
Expand Down
14 changes: 5 additions & 9 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,13 @@ declare namespace Omnibar {
type ResultRenderer<T> = (
{
item,
style,
onMouseEnter,
onMouseLeave,
onClick,
isSelected,
isHighlighted,
}: {
item: T;
style?: React.CSSProperties;
onMouseEnter?: MouseEvent;
onMouseLeave?: MouseEvent;
onClick?: MouseEvent;
}
isSelected: boolean;
isHighlighted: boolean;
} & React.HTMLAttributes<HTMLElement>
) => JSX.Element;

interface Props<T> {
Expand Down

0 comments on commit b5a6f4c

Please sign in to comment.