Skip to content

Commit

Permalink
feat: use tailwind css
Browse files Browse the repository at this point in the history
  • Loading branch information
cevou committed Jun 16, 2024
1 parent e687bdc commit 67f7aa6
Show file tree
Hide file tree
Showing 41 changed files with 768 additions and 1,562 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"react/prop-types": "off",
"react/static-property-placement": ["error", "static public field"],
"react/function-component-definition": ["error", {
"namedComponents": "arrow-function",
"namedComponents": ["arrow-function", "function-declaration"],
"unnamedComponents": "function-expression"
}],
"react/require-default-props": "off",
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@
"markdown-loader": "^8.0.0",
"marked": "^12.0.2",
"postcss": "^8.4.38",
"postcss-custom-properties": "^13.3.10",
"postcss-import": "^16.1.0",
"postcss-loader": "^8.1.1",
"postcss-nesting": "^12.1.5",
"raw-loader": "^4.0.2",
"rimraf": "^3.0.2",
"style-loader": "^4.0.0",
"tailwindcss": "^3.4.4",
"ts-jest": "^29.1.4",
"typescript": "^5.4.5",
"webpack": "^5.91.0",
Expand Down
425 changes: 275 additions & 150 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
plugins: {
"postcss-nesting": {},
"postcss-custom-properties": {},
"postcss-import": {},
autoprefixer: {},
tailwindcss: {},
},
};
1 change: 1 addition & 0 deletions src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import AppShell from "./components/AppShell";
import i18n from "./i18n";
import PrivacyProvider from "./context/PrivacyProvider";
import {HelmetProvider} from "react-helmet-async";
import './styles.css';

if (process.env.NODE_ENV === "production") {
if ("serviceWorker" in navigator) {
Expand Down
38 changes: 0 additions & 38 deletions src/components/AppShell.css

This file was deleted.

33 changes: 5 additions & 28 deletions src/components/AppShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,9 @@ import { Route, Routes, useLocation } from "react-router";
import loadable from "@loadable/component";
import Menu from "./Menu";
import Loading from "./Loading";
import "./AppShell.css";
import LanguagePicker from "./LanguagePicker";
import Item from "./Item";
import TestDataProvider from "../context/TestDataProvider";
import About from "./Info";
import us from "../img/us.svg";
import de from "../img/de.svg";
import es from "../img/es.svg";
import fr from "../img/fr.svg";
import Tracking from "./Tracking";
import useAnalytics from "../hooks/useAnalytics";

Expand Down Expand Up @@ -42,31 +36,14 @@ const AppShell: FunctionComponent = () => {
}, [location]);

return (
<div id="page-wrapper">
<div id="page-wrapper" className="font-sans flex fixed top-0 bottom-0 left-0 right-0 bg-grey-100 flex-col-reverse md:flex-row">
<Helmet htmlAttributes={{ lang: i18n.language }} />
<Menu />
<div id="page-body">
<div id="page-body" className="flex flex-col flex-grow overflow-auto">
<Tracking />
<header>
<h1>{t("app.title")}</h1>
<LanguagePicker>
<Item code="en">
<img src={us} alt="English" />
<span>English</span>
</Item>
<Item code="de">
<img src={de} alt="Deutsch" />
<span>Deutsch</span>
</Item>
<Item code="fr">
<img src={fr} alt="Français" />
<span>Français</span>
</Item>
<Item code="es">
<img src={es} alt="Español" />
<span>Español</span>
</Item>
</LanguagePicker>
<header className="flex bg-blue-300 shadow basis-14">
<h1 className="mx-4 mt-4 mb-3 text-white text-xl grow">{t("app.title")}</h1>
<LanguagePicker />
</header>
<TestDataProvider>
<Routes>
Expand Down
15 changes: 15 additions & 0 deletions src/components/Box.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React, {FunctionComponent, PropsWithChildren} from "react";
import classnames from "classnames";

interface Props {
className?: string;
}

const Box: FunctionComponent<PropsWithChildren<Props>> = ({ className, children}) => {
const classNames = classnames("bg-white shadow p-4 mt-4 mx-4", className);
return (
<div className={classNames}>{children}</div>
);
}

export default Box;
39 changes: 0 additions & 39 deletions src/components/CheckBox.css

This file was deleted.

6 changes: 3 additions & 3 deletions src/components/CheckBox.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { FunctionComponent, KeyboardEvent } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheck } from "@fortawesome/free-solid-svg-icons";
import "./CheckBox.css";

interface Props {
checked: boolean;
Expand All @@ -24,7 +23,7 @@ const CheckBox: FunctionComponent<Props> = ({

return (
<div
className="checkbox"
className="checkbox relative select-none bg-white border border-blue-500 rounded w-5 h-5 box-border cursor-pointer hover:bg-blue-200 aria-checked:bg-blue-400"
role="checkbox"
aria-checked={checked}
tabIndex={0}
Expand All @@ -33,12 +32,13 @@ const CheckBox: FunctionComponent<Props> = ({
>
<input
type="checkbox"
className="absolute opacity-0 w-0 h-0 peer"
checked={checked}
onChange={onChange}
readOnly={readOnly}
aria-labelledby={labelledBy}
/>
<FontAwesomeIcon className="checkmark" icon={faCheck} />
<FontAwesomeIcon className="hidden absolute text-white pl-0.5 peer-checked:block" icon={faCheck} />
</div>
);
};
Expand Down
99 changes: 99 additions & 0 deletions src/components/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React, {
MouseEvent, KeyboardEvent, ReactElement, useState, PropsWithChildren,
} from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleDown } from "@fortawesome/free-solid-svg-icons";
import classNames from "classnames";
import { useTranslation } from "react-i18next";
import { ItemProps } from "./Item";

interface Props<T> {
selected: T;
children: Array<ReactElement<ItemProps<T>>>;
onSelect: (code: T) => void;
type?: "header" | "regular"
}

function Dropdown<T>({
children, selected, onSelect, type = "regular",
}: PropsWithChildren<Props<T>>) {
const [open, setOpen] = useState(false);
const { t } = useTranslation();

const handleTogglePopup = (event: MouseEvent) => {
event.preventDefault();
event.stopPropagation();

setOpen(!open);
};

const handleKeyDown = (event: KeyboardEvent) => {
if (event.keyCode === 32) {
setOpen(!open);
} else if (open) {
if (event.keyCode === 27 || event.keyCode === 9) {
setOpen(false);
} else {
return;
}
} else if (event.keyCode === 40) {
setOpen(true);
} else {
return;
}

event.preventDefault();
};

let content = null;
const items = React.Children.map(children, (item: ReactElement<ItemProps<T>>) => {
const isSelected = item.props.code === selected;
if (isSelected) {
content = item.props.children;
}

return React.cloneElement(item, {
type,
selected: isSelected,
onClick: () => onSelect(item.props.code),
});
});

const className = classNames("flex relative h-8 border border-blue-500 rounded-lg box-border cursor-pointer", {
"rounded-b-none": open,
"m-3 text-white bg-blue-400 hover:bg-blue-500": type === "header",
"text-black bg-white hover:bg-grey-100": type === "regular",
});

const popupClassName = classNames("absolute top-8 right-0 border border-blue-500 mt-[-2px] mr-[-1px] rounded-b min-w-full list-none z-10", {
block: open,
hidden: !open,
"bg-blue-500": type === "header",
"bg-white": type === "regular",
});

const contentClassName = classNames("flex-grow p-1 flex content-center");

return (
<div
className={className}
role="listbox"
aria-label={t("app.language")}
tabIndex={0}
onClick={handleTogglePopup}
onKeyDown={handleKeyDown}
>
<div className={contentClassName}>
{content}
</div>
<div className="flex text-2xl w-4 my-1 mx-2 text-blue-100">
<FontAwesomeIcon icon={faAngleDown} className="block" />
</div>
<ul className={popupClassName}>
{items}
</ul>
</div>
);
}

export default Dropdown;
9 changes: 0 additions & 9 deletions src/components/HandballRules.css

This file was deleted.

54 changes: 3 additions & 51 deletions src/components/HandballRules.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,10 @@
import React, { FunctionComponent } from "react";
import "./HandballRules.css";
import { useTranslation } from "react-i18next";
import React from "react";
import RulesSelector from "./RulesSelector";
import Item from "./Item";
import RulesText from "./rules/RulesText";

interface RuleItemProps {
textKey: string;
className?: string;
}

const RulesItem: FunctionComponent<RuleItemProps> = ({ textKey, className }) => {
const { t } = useTranslation();
const name = t(textKey);
const href = name.toLowerCase().replace(/\s/g, "-").replace(/,/g, "");
return (
<Item code={textKey} className={className}>
<a href={`#${href}`}>
{name}
</a>
</Item>
);
};

const HandballRules = () => (
<div id="rules">
<RulesSelector>
<RulesItem textKey="rules.foreword" />
<RulesItem textKey="rules.rules" />
<RulesItem textKey="rules.rule.rule1" className="indent" />
<RulesItem textKey="rules.rule.rule2" className="indent" />
<RulesItem textKey="rules.rule.rule3" className="indent" />
<RulesItem textKey="rules.rule.rule4" className="indent" />
<RulesItem textKey="rules.rule.rule5" className="indent" />
<RulesItem textKey="rules.rule.rule6" className="indent" />
<RulesItem textKey="rules.rule.rule7" className="indent" />
<RulesItem textKey="rules.rule.rule8" className="indent" />
<RulesItem textKey="rules.rule.rule9" className="indent" />
<RulesItem textKey="rules.rule.rule10" className="indent" />
<RulesItem textKey="rules.rule.rule11" className="indent" />
<RulesItem textKey="rules.rule.rule12" className="indent" />
<RulesItem textKey="rules.rule.rule13" className="indent" />
<RulesItem textKey="rules.rule.rule14" className="indent" />
<RulesItem textKey="rules.rule.rule15" className="indent" />
<RulesItem textKey="rules.rule.rule16" className="indent" />
<RulesItem textKey="rules.rule.rule17" className="indent" />
<RulesItem textKey="rules.rule.rule18" className="indent" />
<RulesItem textKey="rules.hand-signals" />
<RulesItem textKey="rules.clarifications" />
<RulesItem textKey="rules.sar" />
<RulesItem textKey="rules.guidelines" />
<RulesItem textKey="rules.new-guidelines" />
<RulesItem textKey="rules.playing-court" />
</RulesSelector>
<div id="rules" className="flex h-full overflow-auto flex-col md:flex-row">
<RulesSelector />
<RulesText />
</div>
);
Expand Down
Loading

0 comments on commit 67f7aa6

Please sign in to comment.