Skip to content

Commit

Permalink
feat(ModeButton, ModeSelector-first draft): Add ModeButton, ModeSelec…
Browse files Browse the repository at this point in the history
…tor, Trimet/Biketown icons

New ModeButton, first draft of ModeSelector (no events), add missing/unpublished TriMet and Biketown
icons.
  • Loading branch information
binh-dam-ibigroup committed Dec 20, 2019
1 parent dfc6d9e commit 193c08c
Show file tree
Hide file tree
Showing 10 changed files with 436 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/icons/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import TriMetLegIcon from "./trimet-leg-icon";
import TriMetModeIcon from "./trimet-mode-icon";

const {
Biketown,
Bird,
Bolt,
Car2go,
Expand Down Expand Up @@ -73,6 +74,7 @@ const {
StreetcarCircle,
Transittracker,
TransittrackerSolid,
TriMet,
TripPlanner,
TripPlannerSolid,
Walk,
Expand All @@ -96,6 +98,7 @@ export {
BikeLocker,
BikeParking,
BikeStaple,
Biketown,
Bird,
Bolt,
Bus,
Expand Down Expand Up @@ -146,6 +149,7 @@ export {
StreetcarCircle,
Transittracker,
TransittrackerSolid,
TriMet,
TriMetLegIcon,
TriMetModeIcon,
TripPlanner,
Expand Down
10 changes: 10 additions & 0 deletions packages/icons/src/index.story.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ storiesOf("Icons", module)
<Icons.BikeStaple />
</Container>
))
.add("Biketown", () => (
<Container>
<Icons.Biketown />
</Container>
))
.add("Bird", () => (
<Container>
<Icons.Bird />
Expand Down Expand Up @@ -328,6 +333,11 @@ storiesOf("Icons", module)
<Icons.TripPlanner />
</Container>
))
.add("TriMet", () => (
<Container>
<Icons.TriMet />
</Container>
))
.add("TripPlannerSolid", () => (
<Container>
<Icons.TripPlannerSolid />
Expand Down
28 changes: 28 additions & 0 deletions packages/icons/src/trimet/TriMet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";

const SvgTriMet = () => (
<svg viewBox="0 0 100.3 100.29" height="100%" width="100%">
<path
id="path15"
d="M100.3,50.15A50.15,50.15,0,1,1,50.15,0,50.15,50.15,0,0,1,100.3,50.15"
style={{ fill: "#e0651f" }}
/>
<path
id="path17"
d="M61.62,58.06A22.49,22.49,0,1,1,72.83,38.59"
style={{ fill: "none", stroke: "#fff", strokeWidth: "6.08px" }}
/>
<path
id="path19"
d="M50.88,37.61a22.49,22.49,0,1,1-22.32.1"
style={{ fill: "none", stroke: "#fff", strokeWidth: "6.08px" }}
/>
<path
id="path21"
d="M38.17,57.17A22.49,22.49,0,1,1,49.41,76.73"
style={{ fill: "none", stroke: "#fff", strokeWidth: "6.08px" }}
/>
</svg>
);

export default SvgTriMet;
2 changes: 2 additions & 0 deletions packages/icons/src/trimet/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import Streetcar from "./Streetcar";
import StreetcarCircle from "./StreetcarCircle";
import Transittracker from "./Transittracker";
import TransittrackerSolid from "./TransittrackerSolid";
import TriMet from "./TriMet";
import TripPlanner from "./TripPlanner";
import TripPlannerSolid from "./TripPlannerSolid";
import Walk from "./Walk";
Expand Down Expand Up @@ -83,6 +84,7 @@ export {
StreetcarCircle,
Transittracker,
TransittrackerSolid,
TriMet,
TripPlanner,
TripPlannerSolid,
Walk,
Expand Down
28 changes: 28 additions & 0 deletions packages/settings-selector/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "@opentripplanner/settings-selector",
"version": "0.0.1",
"description": "Trip Settings Selector and Related Components",
"author": "@binh-dam-ibigroup",
"homepage": "https://github.com/opentripplanner/otp-ui/#readme",
"license": "MIT",
"main": "index.js",
"module": "src/index.js",
"private": false,
"dependencies": {
"@opentripplanner/icons": "^0.0.1",
"@opentripplanner/core-utils": "^0.0.2"
},
"publishConfig": {
"registry": "https://registry.yarnpkg.com"
},
"repository": {
"type": "git",
"url": "git+https://github.com/opentripplanner/otp-ui.git"
},
"scripts": {
"test": "echo \"Error: run tests from root\" && exit 1"
},
"bugs": {
"url": "https://github.com/opentripplanner/otp-ui/issues"
}
}
76 changes: 76 additions & 0 deletions packages/settings-selector/src/mode-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React from "react";
import PropTypes from "prop-types";

import { ModeButtonContainer, ModeButtonBtn, ModeButtonTitle } from "./styled";

/**
* ModeButton lets the user pick a travel mode.
* It includes the actual button that supports HTML/React text and graphics,
* and a title displayed when hovering the mouse over the button, and, optionally, underneath it.
* A ModeButton can be enabled or disabled, active or inactive.
*/
const ModeButton = props => {
const { selected, children, enabled, showTitle, title, onClick } = props;

const activeClassName = selected ? "active" : "";
const disabledClassName = enabled ? "" : "disabled";

return (
<ModeButtonContainer>
<ModeButtonBtn
className={`${activeClassName} ${disabledClassName}`}
onClick={onClick}
title={title}
disabled={!enabled}
>
{children}
</ModeButtonBtn>

{showTitle && (
<ModeButtonTitle className={disabledClassName}>{title}</ModeButtonTitle>
)}
</ModeButtonContainer>
);
};

ModeButton.propTypes = {
/**
* The contents of the button. Can be any HTML/React content.
*/
children: PropTypes.oneOfType([
PropTypes.node,
PropTypes.arrayOf(PropTypes.node)
]),
/**
* Determines whether the button is currently enabled.
*/
enabled: PropTypes.bool,
/**
* Triggered when the user clicks the button.
*/
onClick: PropTypes.func,
/**
* Determines whether the button should appear selected.
*/
selected: PropTypes.bool,
/**
* Determines whether the title should be displayed (underneath the button).
*/
showTitle: PropTypes.bool,
/**
* A title text for the button, displayed as popup when the user hover the mouse over the button,
* and optionally displayed underneath the button if showTitle is true.
*/
title: PropTypes.string
};

ModeButton.defaultProps = {
children: null,
enabled: true,
onClick: null,
selected: false,
showTitle: true,
title: null
};

export default ModeButton;
76 changes: 76 additions & 0 deletions packages/settings-selector/src/mode-button.story.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React from "react";
import { action } from "@storybook/addon-actions";
import { withInfo } from "@storybook/addon-info";
import * as Icons from "@opentripplanner/icons";

import ModeButton from "./mode-button";

const background = story => (
<div
style={{
backgroundColor: "#F0F0F0",
height: "200px",
padding: "15px"
}}
>
{story()}
</div>
);

export default {
title: "Mode Button",
component: "ModeButton",
decorators: [withInfo, background],
parameters: {
info: {
text: `
ModeButton lets the user pick a travel mode.
It includes the actual button that supports HTML/React text and graphics,
and a title displayed when hovering the mouse over the button, and, optionally, underneath it.
A ModeButton can be enabled or disabled, and active or inactive.
`
}
}
};

const onClick = action("onClick");

export const normal = () => (
<ModeButton onClick={onClick} title="Normal">
<Icons.Max />
+
<Icons.Bike />
Go by train or bike
</ModeButton>
);

export const active = () => (
<ModeButton
selected
onClick={onClick}
title="Active modes are shown this way."
>
<Icons.Max />
Train
</ModeButton>
);

export const disabled = () => (
<ModeButton
enabled={false}
label="Can't Select!"
onClick={onClick}
title="Disabled"
>
<Icons.AlertSolid />
Can&apos;t select!
<Icons.Alert />
</ModeButton>
);

export const labelOnly = () => (
<ModeButton onClick={onClick} showTitle={false} title="Walk Only">
<Icons.Max />
Walk Only
</ModeButton>
);
94 changes: 94 additions & 0 deletions packages/settings-selector/src/mode-selector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React from "react";
import PropTypes from "prop-types";
import * as Icons from "@opentripplanner/icons";
import { isTransit } from "@opentripplanner/core-utils/lib/itinerary";

import { MainModeRow, SecondaryModeRow, TertiaryModeRow } from "./styled";
import ModeButton from "./mode-button";

/**
* ModeSelector is the control container where the OTP user selects
* the primary transportation modes, e.g. transit+bike, walk, micromobility...
*/
const ModeSelector = props => {
const { selectedModes } = props;
const modesHaveTransit = selectedModes.some(isTransit);

return (
<div>
<MainModeRow>
<ModeButton
selected={modesHaveTransit && selectedModes.includes("WALK")}
title="Take Transit"
showTitle={false}
>
<Icons.TriMet />
Take Transit
</ModeButton>
</MainModeRow>
<SecondaryModeRow>
<ModeButton
selected={modesHaveTransit && selectedModes.includes("BICYCLE")}
title="Transit + Personal Bike"
>
<Icons.TriMet />+<Icons.Bike />
</ModeButton>
<ModeButton
selected={modesHaveTransit && selectedModes.includes("BICYCLE_RENT")}
title="Transit + BIKETOWN"
>
<Icons.TriMet />+<Icons.Biketown />
</ModeButton>
<ModeButton
selected={modesHaveTransit && selectedModes.includes("MICROMOBILITY")}
title="Transit + E-Scooter"
>
<Icons.TriMet />+<Icons.Micromobility />
</ModeButton>
<ModeButton
selected={modesHaveTransit && selectedModes.includes("CAR")}
title="Park &amp; Ride"
>
<Icons.TriMet />+<Icons.Car />
</ModeButton>
<ModeButton
selected={modesHaveTransit && selectedModes.includes("CAR_HAIL")}
title="Transit + Uber"
>
<Icons.TriMet />+<Icons.Uber />
</ModeButton>
</SecondaryModeRow>
<TertiaryModeRow>
<ModeButton
selected={selectedModes === ["WALK"]}
title="Walk Only"
showTitle={false}
>
<Icons.Walk />
Walk Only
</ModeButton>
<ModeButton
selected={selectedModes === ["BICYCLE"]}
title="Bike Only"
showTitle={false}
>
<Icons.Bike />
Bike Only
</ModeButton>
</TertiaryModeRow>
</div>
);
};

ModeSelector.propTypes = {
/**
* An array of strings, each representing one transportation mode used for OTP queries.
*/
selectedModes: PropTypes.arrayOf(PropTypes.string)
};

ModeSelector.defaultProps = {
selectedModes: null
};

export default ModeSelector;
Loading

0 comments on commit 193c08c

Please sign in to comment.