Skip to content
Open
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
14 changes: 7 additions & 7 deletions .storybook/config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { configure, addDecorator, addParameters } from '@storybook/react';
import { withConsole } from '@storybook/addon-console';
import { withKnobs } from '@storybook/addon-knobs'
import { withInfo } from '@storybook/addon-info'
import {configure as configureEnzyme} from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';
import { configure, addDecorator, addParameters } from "@storybook/react";
import { withConsole } from "@storybook/addon-console";
import { withKnobs } from "@storybook/addon-knobs";
import { withInfo } from "@storybook/addon-info";
import {configure as configureEnzyme} from "enzyme";
import * as Adapter from "enzyme-adapter-react-16";

//THIS IS NEEDED ONLY IF YOU ARE USING MOCHA AS A TEST RUNNER

Expand All @@ -13,7 +13,7 @@ import {allViewports} from "./viewports/allViewports";
import {withA11y} from "@storybook/addon-a11y";

function loadStories() {
require('../components');
require("../components/index.stories.tsx");
}

addParameters(customTheme);
Expand Down
12 changes: 12 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
language: node_js
node_js: 11.12

before_script:
- npm ci

script:
- npm test

cache:
directories:
- "node_modules"
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from "react";
import {DefaultComponentProps} from "../../../core/interfaces/DefaultComponentProps";
import {Statement} from "../../../core/Statement";
import {DefaultComponentProps} from "../../../../core/interfaces/DefaultComponentProps";
import {Statement} from "../../../../core/Statement";

export interface ButtonState {

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import * as React from "react";
import {DefaultComponentProps} from "../../../core/interfaces/DefaultComponentProps";
import "../../../core/scss/theme.scss";
import {DefaultComponentProps} from "../../../../core/interfaces/DefaultComponentProps";
import {Button, ButtonState} from "../../button";

export class PrimaryButton extends React.Component<DefaultComponentProps, ButtonState> {
public render() {
return (
<Button className={`${this.props.className} primary-button text text--uppercase`}>
<Button
onClick={this.props.onClick}
className={`${this.props.className} primary-button text text--uppercase`}>
{this.props.children}
</Button>
);
Expand Down
139 changes: 139 additions & 0 deletions components/basic/dropdowns/dropdown/components/BasicDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import * as React from "react";
import {DefaultComponentProps} from "../../../../core/interfaces/DefaultComponentProps";
import {ImagesRepository} from "../../../../core/interfaces/ImagesRepository";
import {IconFilenames} from "../../../../core/repositories/DefaultImagesRepository";
import {Icon} from "../../../icons/icon/components/Icon";
import {DropdownConfiguration} from "../configurations/DropdownConfiguration";
import {DropdownObservable} from "../observables/DropdownObservable";
import {DropdownItemDetails} from "../observables/SimpleDropdownObservable";
import {DropdownItem} from "./DropdownItem";

export interface BasicDropdownProps extends DefaultComponentProps {
dropdownObservable: DropdownObservable;
dropdownConfiguration?: DropdownConfiguration;
activeItem?: DropdownItemDetails;
imagesRepository: ImagesRepository;
}

export interface BasicDropdownState {
items: DropdownItemDetails[];
activeItem: DropdownItemDetails;
isOpened: boolean;
}

export class BasicDropdown extends React.Component<BasicDropdownProps, BasicDropdownState> {
private dropdownObservable: DropdownObservable;

public componentWillMount(): void {
this.onKeyPress = this.onKeyPress.bind(this);

this.dropdownObservable = this.props.dropdownObservable;
this.dropdownObservable.getObservableItems().subscribe((items: DropdownItemDetails[]) => {
this.setState({
items,
});
});

this.dropdownObservable.getObservableActiveItem().subscribe((activeItem: DropdownItemDetails) => {
this.setState({
activeItem,
});
});

this.dropdownObservable.getObservableIsOpened().subscribe((isOpened: boolean) => {
this.setState({
isOpened,
});
});

if (this.props.activeItem !== undefined) {
this.dropdownObservable.setActiveItem(this.props.activeItem);
} else {
this.setState({
activeItem: this.dropdownObservable.getActiveItem(),
});
}

this.setState({
isOpened: this.dropdownObservable.isOpened(),
items: this.dropdownObservable.getItems(),
});
}

public render() {
const imagesRepository = this.props.imagesRepository;
return (
<div className={`dropdown ${this.props.className || ""} ${this.getActiveStyleClass()}`}>
{this.renderActiveItemContainer()}
{this.renderItemsContainer()}
<button
className="button--no-style dropdown__arrow"
onClick={() => {
this.toggleDropdown();
}}>
<Icon
iconName={IconFilenames.ARROW_DOWN}
alt="Arrow down"
imagesRepository={imagesRepository}/>
</button>
</div>
);
}

private getActiveStyleClass(): string {
return this.state.isOpened ? "dropdown--active" : "";
}

private renderItemsContainer() {
if (this.state.isOpened === false) {
return "";
}

return <div className={`dropdown__items`}>
{this.state.items.map((dropdownItemDetails: DropdownItemDetails) => {
return (
<DropdownItem
onClick={() => this.setActiveItem(dropdownItemDetails)}
key={dropdownItemDetails.key}>
{dropdownItemDetails.name}
</DropdownItem>
);
})}
</div>;
}

private renderActiveItemContainer() {
return <div
onClick={() => {
this.dropdownObservable.toggle();
}}
className={`dropdown__active-item dropdown__box`}>
{this.state.activeItem.name}
</div>;
}

private setActiveItem(dropdownItemDetails: DropdownItemDetails) {
this.dropdownObservable.setActiveItem(dropdownItemDetails);
this.dropdownObservable.close();
}

private onKeyPress(e) {
if (e.key !== "Enter") {
return;
}

if (this.state.items.length === 0) {
return;
}

this.setActiveItem(this.state.items[0]);
}

private toggleDropdown() {
if (this.dropdownObservable.isOpened()) {
return this.dropdownObservable.close();
}

this.dropdownObservable.open();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import {DefaultComponentProps} from "../../../core/interfaces/DefaultComponentProps";
import {DefaultComponentProps} from "../../../../core/interfaces/DefaultComponentProps";

export interface DropdownItemProps extends DefaultComponentProps {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import * as React from "react";
import {DefaultComponentProps} from "../../../core/interfaces/DefaultComponentProps";
import {DefaultComponentProps} from "../../../../core/interfaces/DefaultComponentProps";
import {IconFilenames} from "../../../../core/repositories/DefaultImagesRepository";
import {Icon} from "../../../icons/icon/components/Icon";
import {IconName} from "../../../icons/icon/components/IconContent";
import {SearchableDropdownObservable} from "../observables/SearchableDropdownObservable";
import {DropdownItemDetails} from "../observables/SimpleDropdownObservable";
import {DropdownItem} from "./DropdownItem";
import {ImagesRepository} from "../../../../core/interfaces/ImagesRepository";

export interface DropdownProps extends DefaultComponentProps {
searchableDropdownObservable: SearchableDropdownObservable;
activeItem: DropdownItemDetails;
imagesRepository: ImagesRepository;
}

export interface DropdownState {
Expand All @@ -17,7 +19,7 @@ export interface DropdownState {
isOpened: boolean;
}

export class Dropdown extends React.Component<DropdownProps, DropdownState> {
export class SearchableDropdown extends React.Component<DropdownProps, DropdownState> {
private dropdownObservable: SearchableDropdownObservable;

public componentWillMount(): void {
Expand Down Expand Up @@ -62,7 +64,8 @@ export class Dropdown extends React.Component<DropdownProps, DropdownState> {
this.toggleDropdown();
}}>
<Icon
iconName={IconName.ARROW_DOWN}
imagesRepository={this.props.imagesRepository}
iconName={IconFilenames.ARROW_DOWN}
alt="Arrow down"/>
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {DropdownConfiguration, DropdownConfigurationIcons} from "./DropdownConfiguration";

export class BasicDropdownConfiguration implements DropdownConfiguration {
public getIcons(): DropdownConfigurationIcons {
return undefined;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface DropdownConfigurationIcons {
[key: string]: string;
}
export interface DropdownConfiguration {
getIcons(): DropdownConfigurationIcons;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface DropdownObservable {
close(): void;
isOpened(): boolean;
setActiveItem(active: DropdownItemDetails): void;
getActiveItem(): DropdownItemDetails;
setItems(items: DropdownItemDetails[]): void;
getItems(): DropdownItemDetails[];
getObservableItems(): Subject<DropdownItemDetails[]>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ export class SearchableDropdownObservable implements DropdownObservable {
return this.allItems;
}

public getActiveItem(): DropdownItemDetails {
return this.simpleDropdownObservable.getActiveItem();
}

private getFilteredItemsByName(text: string) {
return this.allItems.filter((item: DropdownItemDetails) => {
return RegExp(`${text.toLowerCase()}*`).test(item.name.toLowerCase());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export interface DropdownItemDetails {
name: string;
}

export class SimpleDropdownObservable implements DropdownObservable{
export class SimpleDropdownObservable implements DropdownObservable {
private observableItems: Subject<DropdownItemDetails[]> = new Subject();
private observableActiveItem: Subject<DropdownItemDetails> = new Subject();
private observableIsOpened: Subject<boolean> = new Subject();
Expand Down Expand Up @@ -71,4 +71,8 @@ export class SimpleDropdownObservable implements DropdownObservable{
public getItems(): DropdownItemDetails[] {
return this.items;
}

public getActiveItem(): DropdownItemDetails {
return this.activeItem;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
font-family: $font-family;
font-size: 18px;
position: relative;
background: $color5;
cursor: pointer;

&--active {
border-bottom: 0;
Expand Down Expand Up @@ -56,6 +58,7 @@
border-top: 0;
background-color: white;
max-height: 222px;
z-index: 2;
}

&__search {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
describe("components/Dropdown", () => {
describe("components/BasicDropdown", () => {
it("should return true", () => {
expect(true).toEqual(false);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import * as React from "react";
import {DefaultComponentProps} from "../../../core/interfaces/DefaultComponentProps";
import {Statement} from "../../../core/Statement";
import {DefaultComponentProps} from "../../../../core/interfaces/DefaultComponentProps";
import {Statement} from "../../../../core/Statement";

export enum HeaderType {
h1 = "h1",
h2 = "h2",
h3 = "h3",
h4 = "h4",
}
export interface HeaderProps extends DefaultComponentProps {
type?: HeaderType;
Expand Down Expand Up @@ -50,6 +51,12 @@ export class Header extends React.Component<HeaderProps, HeaderState> {
</h3>;
});

Statement.runIfTrue(this.type === HeaderType.h4, () => {
headerElement = <h4 {...headerProps}>
{this.props.children}
</h4>;
});

return headerElement;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ h2.header {
h3.header {
font-size: 18px;
}

h4.header {
font-size: 16px;
}
25 changes: 25 additions & 0 deletions components/basic/icons/icon/components/Icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as React from "react";
import {IconFilenames} from "../../../../core";
import {DefaultComponentProps} from "../../../../core/interfaces/DefaultComponentProps";
import {ImagesRepository} from "../../../../core/interfaces/ImagesRepository";

export interface IconProps extends DefaultComponentProps {
iconName: IconFilenames;
alt: string;
size?: number;
imagesRepository: ImagesRepository;
}
export class Icon extends React.Component<IconProps, {}> {

public render() {
const { iconName, className, alt } = this.props;
const imagesRepository = this.props.imagesRepository;

return (
<i
className={`icon ${className || ""}`}>
<img src={imagesRepository.getIcon(iconName)} alt={alt}/>
</i>
);
}
}
12 changes: 12 additions & 0 deletions components/basic/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export {Icon, IconProps} from "./icons/icon/components/Icon";
export {
SearchableDropdown,
DropdownProps,
} from "./dropdowns/dropdown/components/SearchableDropdown";
export {
SearchableDropdownObservable,
} from "./dropdowns/dropdown/observables/SearchableDropdownObservable";
export {
SimpleDropdownObservable,
DropdownItemDetails,
} from "./dropdowns/dropdown/observables/SimpleDropdownObservable";
Loading