Skip to content

Commit

Permalink
Merge pull request #71 from performant-software/feature/basira2_physi…
Browse files Browse the repository at this point in the history
…cal_components

BASIRA #2 - Physical components
  • Loading branch information
dleadbetter authored Jun 1, 2021
2 parents ed6913a + 8cca65b commit 3d286cf
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 33 deletions.
32 changes: 32 additions & 0 deletions src/semantic-ui/NestedAccordion.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
.nested-accordion .ui.icon.button.accordion-button {
background-color: transparent;
display: inline-block;
}

.nested-accordion .ui.icon.button.accordion-button.hidden i {
visibility: hidden;
}

.nested-accordion .ui.icon.button.inverted.accordion-button {
box-shadow: none !important;
color: #fff;
}

.nested-accordion .title > .container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}

.nested-accordion .title > .container > div:first-child {
flex-grow: 1;
white-space: nowrap;
}

.nested-accordion .title > .container > div:first-child > .item-container {
display: inline-block;
width: 100%;
}

.nested-accordion .title > .container > div:first-child > .right-container {
margin-left: 1em;
text-align: right;
}
131 changes: 98 additions & 33 deletions src/semantic-ui/NestedAccordion.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
// @flow

import React, { Component } from 'react';
import React, { Component, type Element } from 'react';
import {
Accordion,
Button,
Grid
Button
} from 'semantic-ui-react';
import _ from 'underscore';
import './NestedAccordion.css';

type Props = {
defaultActive?: Array<number>,
getChildItems: (item: any) => Array<any>,
inverted?: boolean,
isItemActive?: (item: any) => boolean,
onItemClick?: (item: any) => void,
onItemToggle: (item: any) => void,
renderItem: (item: any) => string | Component<{}>,
renderRight?: (item: any) => string | Component<{}>,
renderItem: (item: any) => string | Element<any>,
renderRight?: (item: any) => string | Element<any>,
rootItems: Array<any>,
showToggle: (item: any) => boolean
showToggle: (item: any) => boolean,
styled?: boolean,
toggleOnClick?: boolean
};

type State = {
activeItems: Array<any>
}
};

class NestedAccordion extends Component<Props, State> {
static defaultProps: any;
Expand All @@ -39,6 +43,36 @@ class NestedAccordion extends Component<Props, State> {
};
}

/**
* Sets the activeItems on the state if the defaultActive prop changes.
*
* @param prevProps
*/
componentDidUpdate(prevProps: Props) {
if (prevProps.defaultActive !== this.props.defaultActive
&& this.props.defaultActive
&& this.props.defaultActive.length) {
this.setState({ activeItems: _.map(this.props.defaultActive, (id) => ({ id })) });
}
}

/**
* Returns the toggle button class names.
*
* @param item
*
* @returns {string}
*/
getButtonClass(item: any) {
const classNames = ['accordion-button'];

if (this.props.showToggle && !this.props.showToggle(item)) {
classNames.push('hidden');
}

return classNames.join(' ');
}

/**
* Returns true if the passed item is active.
*
Expand All @@ -50,6 +84,32 @@ class NestedAccordion extends Component<Props, State> {
return !!_.findWhere(this.state.activeItems, { id: item.id });
}

/**
* Returns true if the passed item is active.
*
* @param item
*
* @returns {*}
*/
isItemActive(item: any) {
return this.props.isItemActive && this.props.isItemActive(item);
}

/**
* Calls the onItemClick prop. Optionally toggles the item active.
*
* @param item
*/
onItemClick(item: any) {
if (this.props.toggleOnClick) {
this.onItemToggle(item);
}

if (this.props.onItemClick) {
this.props.onItemClick(item);
}
}

/**
* Toggles the passed item and calls the onItemToggle property.
*
Expand All @@ -70,8 +130,9 @@ class NestedAccordion extends Component<Props, State> {
<Accordion
className='nested-accordion'
fluid
inverted={this.props.inverted}
panels={_.map(this.props.rootItems, this.renderPanel.bind(this))}
styled
styled={this.props.styled}
/>
);
}
Expand Down Expand Up @@ -114,28 +175,30 @@ class NestedAccordion extends Component<Props, State> {
<>
<Accordion.Title
active={this.isActive(item)}
onClick={this.props.onItemClick && this.props.onItemClick.bind(this, item)}
onClick={this.onItemClick.bind(this, item)}
style={{
backgroundColor: this.isItemActive(item) ? 'rgba(255, 255, 255, 0.08)' : undefined
}}
>
<Grid
verticalAlign='middle'
<div
className='container'
>
<Grid.Column
width={1}
>
<div>
{ this.renderToggle(item) }
</Grid.Column>
<Grid.Column
width={13}
>
{ this.props.renderItem(item) }
</Grid.Column>
<Grid.Column
textAlign='right'
width={2}
>
{ this.props.renderRight && this.props.renderRight(item) }
</Grid.Column>
</Grid>
<div
className='item-container'
>
{ this.props.renderItem(item) }
</div>
</div>
{ this.props.renderRight && (
<div
className='right-container'
>
{ this.props.renderRight(item) }
</div>
)}
</div>
</Accordion.Title>
{ this.renderContent(item) }
</>
Expand All @@ -150,15 +213,12 @@ class NestedAccordion extends Component<Props, State> {
* @returns {null|*}
*/
renderToggle(item: any) {
if (!this.props.showToggle(item)) {
return null;
}

return (
<Button
compact
className='accordion-button'
className={this.getButtonClass(item)}
icon='dropdown'
inverted={this.props.inverted}
onClick={(e) => {
// Since the containing row also has an onclick, we'll want to prevent that from being triggered.
e.stopPropagation();
Expand All @@ -183,8 +243,13 @@ class NestedAccordion extends Component<Props, State> {
}

NestedAccordion.defaultProps = {
defaultActive: [],
inverted: false,
isItemActive: undefined,
onItemClick: () => {},
renderRight: () => {}
renderRight: () => {},
styled: true,
toggleOnClick: false
};

export default NestedAccordion;

0 comments on commit 3d286cf

Please sign in to comment.