This commit is contained in:
Keith Fung 2020-10-01 19:45:17 -04:00
Π ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ e3f33440e7
ΠšΠΎΠΌΠΌΠΈΡ‚ 224d1d3b9d
7 ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ²: 96 Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΉ ΠΈ 47 ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΉ

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -14,9 +14,7 @@ const Template: Story<AppBarProps> = (props) => {
const theme = useTheme();
return (
<Stack verticalFill styles={{ root: { backgroundColor: theme.palette.neutralLighterAlt } }}>
<AppBar {...props}>
<PrimaryButton text="Change Election" />
</AppBar>
<AppBar {...props} />
</Stack>
);
};
@ -26,10 +24,12 @@ StandardAppBar.storyName = 'App Bar';
StandardAppBar.args = {
logoImageUrl: 'https://themingdesigner.blob.core.windows.net/$web/MicrosoftLogo.png',
appName: 'ElectionGuard Ballot Tracker',
logoUrl: 'https://www.microsoft.com',
};
export const NoLogoAppBar = Template.bind({});
NoLogoAppBar.storyName = 'No Logo App Bar';
NoLogoAppBar.args = {
export const NoLinkAppBar = Template.bind({});
NoLinkAppBar.storyName = 'No Link App Bar';
NoLinkAppBar.args = {
logoImageUrl: 'https://themingdesigner.blob.core.windows.net/$web/MicrosoftLogo.png',
appName: 'ElectionGuard Ballot Tracker',
};

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -2,13 +2,38 @@ import React from 'react';
import { Image, Stack, Text } from '@fluentui/react';
import { Depths } from '@fluentui/theme';
import { useTheme } from '@fluentui/react-theme-provider';
import { useMediaQuery } from 'react-responsive';
export interface AppBarProps {
logoImageUrl?: string;
appName: string;
export interface MobileAppBarProps {
logoImageUrl: string;
logoUrl?: string;
}
const AppBar: React.FunctionComponent<AppBarProps> = ({ logoImageUrl, appName, children }) => {
const MobileAppBar: React.FunctionComponent<MobileAppBarProps> = ({ logoImageUrl, logoUrl }) => {
const theme = useTheme();
return (
<Stack
horizontal
verticalAlign="center"
horizontalAlign="center"
styles={{
root: {
marginBottom: 2,
padding: '0px 32px',
minHeight: 47,
boxShadow: Depths.depth8,
backgroundColor: theme.palette.white,
},
}}
>
<a href={logoUrl ?? ''}>
<Image styles={{ image: { width: '120px', display: 'block' } }} alt="logo" src={logoImageUrl} />
</a>
</Stack>
);
};
const DesktopAppBar: React.FunctionComponent<AppBarProps> = ({ logoImageUrl, logoUrl, appName, children }) => {
const theme = useTheme();
return (
<Stack
@ -26,18 +51,12 @@ const AppBar: React.FunctionComponent<AppBarProps> = ({ logoImageUrl, appName, c
}}
>
<Stack horizontal verticalAlign="center">
{logoImageUrl ? (
<>
<Image styles={{ image: { width: '120px', display: 'block' } }} alt="logo" src={logoImageUrl} />
<Text as="span" styles={{ root: { fontWeight: 600 } }}>
{`| ${appName}`}
</Text>
</>
) : (
<Text as="span" styles={{ root: { fontWeight: 600 } }}>
{appName}
</Text>
)}
<a href={logoUrl ?? ''}>
<Image styles={{ image: { width: '120px', display: 'block' } }} alt="logo" src={logoImageUrl} />
</a>
<Text as="span" styles={{ root: { fontWeight: 600 } }}>
{`| ${appName}`}
</Text>
</Stack>
<Stack horizontal verticalAlign="center">
{children || null}
@ -46,4 +65,22 @@ const AppBar: React.FunctionComponent<AppBarProps> = ({ logoImageUrl, appName, c
);
};
export interface AppBarProps {
logoImageUrl: string;
logoUrl?: string;
appName: string;
}
const AppBar: React.FunctionComponent<AppBarProps> = ({ logoImageUrl, logoUrl, appName, children }) => {
const isMobile = useMediaQuery({ query: '(max-width: 480px)' });
return isMobile ? (
<MobileAppBar logoImageUrl={logoImageUrl} logoUrl={logoUrl} />
) : (
<DesktopAppBar logoImageUrl={logoImageUrl} logoUrl={logoUrl} appName={appName}>
{children || null}
</DesktopAppBar>
);
};
export default AppBar;

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -1,8 +1,8 @@
import React from 'react';
import { Text } from '@fluentui/react';
import moment from 'moment';
import { useTheme } from '@fluentui/react-theme-provider';
import Title from './Title';
import { useTheme } from '@fluentui/react-theme-provider';
// TODO #?? Resolve internalization of language using i18n
const defaultElectionName = 'Election';
@ -19,9 +19,9 @@ const ElectionTitle: React.FunctionComponent<ElectionTitleProps> = ({ electionNa
const theme = useTheme();
return (
<Title title={electionName ?? defaultElectionName}>
<Text as="span" styles={{ root: { color: theme.palette.neutralSecondary, marginLeft: theme.spacing.l1 } }}>
{`${moment(startDate).format(dateFormat)}-${moment(endDate).format(dateFormat)}`}
</Text>
<Text as="span" styles={{ root: { color: theme.palette.neutralSecondary } }}>{`${moment(startDate).format(
dateFormat
)}-${moment(endDate).format(dateFormat)}`}</Text>
</Title>
);
};

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -6,7 +6,6 @@ import LargeCard from './LargeCard';
export default {
title: 'Components/LargeCard',
component: LargeCard,
parameters: { layout: 'fullscreen' },
} as Meta;
const Template: Story = () => {

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -2,9 +2,11 @@ import React from 'react';
import { useTheme } from '@fluentui/react-theme-provider';
import { Card } from '@uifabric/react-cards';
export interface LargeCardProps {}
export interface LargeCardProps {
alignToStart?: boolean;
}
const LargeCard: React.FunctionComponent<LargeCardProps> = ({ children }) => {
const LargeCard: React.FunctionComponent<LargeCardProps> = ({ alignToStart, children }) => {
const theme = useTheme();
return (
<Card
@ -13,6 +15,8 @@ const LargeCard: React.FunctionComponent<LargeCardProps> = ({ children }) => {
padding: theme.spacing.l1,
backgroundColor: theme.palette.white,
marginBottom: theme.spacing.l1,
alignItems: alignToStart ? 'flex-start' : 'stretch',
height: 'auto',
maxWidth: 'auto',
},
}}

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -2,23 +2,10 @@ import React from 'react';
import { Stack } from '@fluentui/react';
import AppBar from './AppBar';
import { useTheme } from '@fluentui/react-theme-provider';
import { Dropdown, IDropdownStyles, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
// TODO Remove mock data
const appName = 'ElectionGuard Ballot Tracker';
const logoImageUrl = 'https://themingdesigner.blob.core.windows.net/$web/MicrosoftLogo.png';
const placeholder = 'Select Election';
const options: IDropdownOption[] = [
{ key: '1', text: 'Mock Election 1' },
{ key: '2', text: 'Mock Election 2' },
{ key: '3', text: 'Mock Election 3' },
{ key: '4', text: 'Mock Election 4' },
{ key: '5', text: 'Mock Election 5' },
];
const dropdownStyles: Partial<IDropdownStyles> = {
dropdown: { width: 300 },
};
export interface LayoutProps {}
@ -26,9 +13,7 @@ const Layout: React.FunctionComponent<LayoutProps> = ({ children }) => {
const theme = useTheme();
return (
<Stack verticalFill>
<AppBar appName={appName} logoImageUrl={logoImageUrl}>
<Dropdown placeholder={placeholder} ariaLabel={placeholder} options={options} styles={dropdownStyles} />
</AppBar>
<AppBar appName={appName} logoImageUrl={logoImageUrl} />
<Stack
verticalFill
styles={{

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -2,6 +2,15 @@ import React from 'react';
import { Text } from '@fluentui/react';
import styled from 'styled-components';
import { useTheme } from '@fluentui/react-theme-provider';
import { useMediaQuery } from 'react-responsive';
const MobileHeader = styled.header`
padding: 16px 0px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
`;
const Header = styled.header`
padding: 52px 0px;
@ -13,11 +22,26 @@ export interface TitleProps {
const Title: React.FunctionComponent<TitleProps> = ({ title, children }) => {
const theme = useTheme();
return (
const isMobile = useMediaQuery({ query: '(max-width: 480px)' });
return isMobile ? (
<MobileHeader>
<Text variant="xLargePlus" as="h1" styles={{ root: { color: theme.palette.neutralPrimary } }}>
{title}
</Text>
{children || null}
</MobileHeader>
) : (
<Header>
<Text variant="xxLargePlus" as="h1" styles={{ root: { color: theme.palette.neutralPrimary } }}>
{title}
{children || null}
<div
style={{
display: 'inline-block',
marginLeft: theme.spacing.l1,
}}
>
{children || null}
</div>
</Text>
</Header>
);