Skip to content

Commit

Permalink
New Widget Style
Browse files Browse the repository at this point in the history
  • Loading branch information
PatrickCleary committed Jul 15, 2023
1 parent ae2c82b commit 4578d69
Show file tree
Hide file tree
Showing 25 changed files with 309 additions and 762 deletions.
19 changes: 0 additions & 19 deletions common/components/charts/Legend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,8 @@ import { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Disclosure } from '@headlessui/react';
import React from 'react';
import { useBreakpoint } from '../../hooks/useBreakpoint';

export const LegendSingleDay: React.FC = () => {
const isMobile = !useBreakpoint('md');
if (isMobile) return <LegendMobile />;
return <LegendDesktop />;
};

const LegendMobile: React.FC = () => {
return (
<Disclosure>
{({ open }) => (
Expand All @@ -37,18 +30,6 @@ const LegendMobile: React.FC = () => {
);
};

const LegendDesktop: React.FC = () => {
return (
<div
className={
'grid w-full grid-cols-2 items-baseline p-1 text-left text-xs lg:flex lg:flex-row lg:gap-4'
}
>
<LegendSingle />
</div>
);
};

const LegendSingle: React.FC = () => {
return (
<>
Expand Down
20 changes: 20 additions & 0 deletions common/components/general/DataPair.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import classNames from 'classnames';
import React from 'react';

interface DataPairProps {
children: React.ReactNode;
last?: boolean;
}

export const DataPair: React.FC<DataPairProps> = ({ children, last }) => {
return (
<div
className={classNames(
last ? 'border-0' : 'border-r',
'flex h-full min-w-[12rem] max-w-[18rem] flex-col gap-2 px-2 md:min-w-[12rem]'
)}
>
{children}
</div>
);
};
44 changes: 44 additions & 0 deletions common/components/widgets/MiniWidgetCreator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import type { WidgetValueInterface } from '../../types/basicWidgets';
import { DataPair } from '../general/DataPair';
import { SmallDelta } from './internal/SmallDelta';
import { SmallData } from './internal/SmallData';

interface MiniWidgetObject {
type: 'delta' | 'data' | string;
widgetValue: WidgetValueInterface;
text: string;
}
[];

interface MiniWidgetCreatorProps {
widgetObjects: MiniWidgetObject[];
}

const getDeltaOrDataComponent = (widgetObject: MiniWidgetObject) => {
if (widgetObject.type === 'delta') {
return <SmallDelta analysis={widgetObject.text} widgetValue={widgetObject.widgetValue} />;
}
return <SmallData analysis={widgetObject.text} widgetValue={widgetObject.widgetValue} />;
};

const getWidgets = (widgetObject: MiniWidgetObject[]) => {
const widgets: React.ReactNode[] = [];
for (let x = 0; x < widgetObject.length; x += 2) {
widgets.push(
<DataPair last={x + 3 > widgetObject.length}>
{getDeltaOrDataComponent(widgetObject[x])}
{x + 1 < widgetObject.length ? getDeltaOrDataComponent(widgetObject[x + 1]) : null}
</DataPair>
);
}
return widgets;
};

export const MiniWidgetCreator: React.FC<MiniWidgetCreatorProps> = ({ widgetObjects }) => {
return (
<div className="flex w-full flex-row gap-y-4 overflow-x-auto py-2">
{getWidgets(widgetObjects)}
</div>
);
};
21 changes: 21 additions & 0 deletions common/components/widgets/internal/SmallData.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import classNames from 'classnames';
import type { WidgetValueInterface } from '../../../types/basicWidgets';

type SmallDataProps = {
analysis: React.ReactNode;
widgetValue: WidgetValueInterface;
};

export const SmallData: React.FC<SmallDataProps> = ({ analysis, widgetValue }) => {
return (
<div className=" flex flex-row items-end justify-between">
<p
className={classNames('truncate text-xs leading-tight text-design-subtitleGrey sm:text-sm')}
>
{analysis}
</p>
<div className="flex flex-row items-baseline gap-x-1">{widgetValue.getFormattedValue()}</div>
</div>
);
};
38 changes: 38 additions & 0 deletions common/components/widgets/internal/SmallDelta.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import classNames from 'classnames';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faArrowTrendDown, faArrowTrendUp } from '@fortawesome/free-solid-svg-icons';
import type { WidgetValueInterface } from '../../../types/basicWidgets';

type SmallDeltaProps = {
analysis: React.ReactNode;
widgetValue: WidgetValueInterface;
};

export const SmallDelta: React.FC<SmallDeltaProps> = ({ analysis, widgetValue }) => {
return (
<div className=" flex flex-row items-end justify-between">
<p
className={classNames('truncate text-xs leading-tight text-design-subtitleGrey sm:text-sm')}
>
{analysis}
</p>
{widgetValue.value !== undefined && (
<div className={classNames('flex flex-row items-center gap-1 rounded-md px-2')}>
{widgetValue.value !== 0 && (
<FontAwesomeIcon
icon={widgetValue.value > 0 ? faArrowTrendUp : faArrowTrendDown}
className={widgetValue.value > 0 ? 'text-[#e84e3b]' : 'text-[#35c759]'}
/>
)}
<p className="flex flex-row">
<span className="pr-1 font-bold text-gray-900">
{widgetValue.value < 0 ? '-' : '+'}
</span>
{widgetValue.getFormattedValue(false)}
</p>
</div>
)}
</div>
);
};
10 changes: 8 additions & 2 deletions common/components/widgets/internal/UnitText.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import classNames from 'classnames';
import React from 'react';
export interface UnitTextProps {
text: string;
light?: boolean;
}
export const UnitText: React.FC<UnitTextProps> = ({ text }) => {
return <span className="text-base text-design-subtitleGrey">{text}</span>;
export const UnitText: React.FC<UnitTextProps> = ({ text, light }) => {
return (
<span className={classNames(light ? 'text-stone-200' : 'text-stone-700', 'text-base ')}>
{text}
</span>
);
};
12 changes: 10 additions & 2 deletions common/components/widgets/internal/WidgetText.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import classNames from 'classnames';
import React from 'react';

export interface WidgetTextProps {
text: string;
light?: boolean;
}
export const WidgetText: React.FC<WidgetTextProps> = ({ text }) => {
return <span className="text-2xl font-semibold text-gray-900">{text}</span>;
export const WidgetText: React.FC<WidgetTextProps> = ({ text, light }) => {
return (
<span
className={classNames(light ? 'text-stone-100' : 'text-stone-900', 'text-base font-semibold')}
>
{text}
</span>
);
};
44 changes: 23 additions & 21 deletions common/types/basicWidgets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface WidgetValueInterface {
readonly percentChange?: number;

getUnits: () => string;
getFormattedValue: () => React.ReactNode;
getFormattedValue: (light?: boolean) => React.ReactNode;
getFormattedDelta: () => string;
getFormattedPercentChange: () => string;
}
Expand Down Expand Up @@ -43,9 +43,9 @@ export class DeltaTimeWidgetValue extends BaseWidgetValue implements WidgetValue
if (this.delta === undefined) return '...';
return getTimeUnit(this.delta);
}
getFormattedValue() {
getFormattedValue(light) {
if (this.delta === undefined) return '...';
return getFormattedTimeValue(this.delta);
return getFormattedTimeValue(this.delta, light);
}
getFormattedDelta() {
new Error('DeltaWidgets should use `getFormattedValue`');
Expand All @@ -57,12 +57,12 @@ export class DeltaZonesWidgetValue extends BaseWidgetValue implements WidgetValu
getUnits() {
return 'zones';
}
getFormattedValue() {
getFormattedValue(light) {
if (this.delta === undefined) return '...';
return (
<p>
<WidgetText text={`${this.delta >= 0 ? '+' : '-'}${Math.abs(this.delta)}`} />{' '}
<UnitText text={this.getUnits()} />
<WidgetText light={light} text={`${this.delta >= 0 ? '+' : '-'}${Math.abs(this.delta)}`} />{' '}
<UnitText light={light} text={this.getUnits()} />
</p>
);
}
Expand All @@ -79,9 +79,9 @@ export class TimeWidgetValue extends BaseWidgetValue implements WidgetValueInter
return getTimeUnit(this.value);
}

getFormattedValue() {
getFormattedValue(light?: boolean) {
if (this.value === undefined) return '...';
return getFormattedTimeValue(this.value);
return getFormattedTimeValue(this.value, light);
}

getFormattedDelta() {
Expand All @@ -104,12 +104,12 @@ export class SZWidgetValue extends BaseWidgetValue implements WidgetValueInterfa
getUnits() {
return 'zones';
}
getFormattedValue() {
getFormattedValue(light) {
if (typeof this.value === 'undefined') return '...';
return (
<p className="">
<WidgetText text={`${Math.abs(this.value).toString()}`} />{' '}
<UnitText text={this.getUnits()} />
<WidgetText light={light} text={`${Math.abs(this.value).toString()}`} />{' '}
<UnitText light={light} text={this.getUnits()} />
</p>
);
}
Expand All @@ -124,12 +124,12 @@ export class PercentageWidgetValue extends BaseWidgetValue implements WidgetValu
return '%';
}

getFormattedValue() {
getFormattedValue(light) {
if (this.value === undefined) return '...';
return (
<p>
<WidgetText text={`${Math.round(100 * this.value).toString()}`} />{' '}
<UnitText text={this.getUnits()} />
<WidgetText light={light} text={`${Math.round(100 * this.value).toString()}`} />{' '}
<UnitText light={light} text={this.getUnits()} />
</p>
);
}
Expand All @@ -145,11 +145,12 @@ export class TripsWidgetValue extends BaseWidgetValue implements WidgetValueInte
return 'Trips';
}

getFormattedValue() {
getFormattedValue(light) {
if (this.value === undefined) return '...';
return (
<p>
<WidgetText text={Math.abs(this.value).toFixed(0)} /> <UnitText text={this.getUnits()} />
<WidgetText light={light} text={Math.abs(this.value).toFixed(0)} />{' '}
<UnitText light={light} text={this.getUnits()} />
</p>
);
}
Expand All @@ -165,11 +166,12 @@ export class MPHWidgetValue extends BaseWidgetValue implements WidgetValueInterf
return 'MPH';
}

getFormattedValue() {
getFormattedValue(light) {
if (typeof this.value === 'undefined') return '...';
return (
<p>
<WidgetText text={this.value.toFixed(1)} /> <UnitText text={this.getUnits()} />
<WidgetText light={light} text={this.value.toFixed(1)} />{' '}
<UnitText light={light} text={this.getUnits()} />
</p>
);
}
Expand All @@ -186,12 +188,12 @@ export class RidersWidgetValue extends BaseWidgetValue implements WidgetValueInt
return 'Riders';
}

getFormattedValue() {
getFormattedValue(light) {
if (this.value === undefined) return '...';
return (
<p>
<WidgetText text={`${(this.value / 1000).toFixed(1)}k`} />{' '}
<UnitText text={this.getUnits()} />
<WidgetText light={light} text={`${(this.value / 1000).toFixed(1)}k`} />{' '}
<UnitText light={light} text={this.getUnits()} />
</p>
);
}
Expand Down
62 changes: 0 additions & 62 deletions common/utils/dwells.ts

This file was deleted.

Loading

0 comments on commit 4578d69

Please sign in to comment.