diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9b4c4fc6..56b25e8b 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,7 +14,7 @@ "@urql/exchange-graphcache": "^6.0.4", "@urql/exchange-refocus": "^1.0.2", "@urql/exchange-request-policy": "^1.0.2", - "@vector-im/compound-web": "https://github.com/vector-im/compound-web.git#5208d2d442587efb9938265841574f73ce97dff1", + "@vector-im/compound-web": "https://github.com/vector-im/compound-web.git", "date-fns": "^2.30.0", "graphql": "^16.6.0", "jotai": "^2.1.0", @@ -62,6 +62,7 @@ "vite": "^4.3.8", "vite-plugin-eslint": "^1.8.1", "vite-plugin-graphql-codegen": "^3.2.2", + "vite-plugin-svgr": "^3.2.0", "vitest": "^0.31.1" } }, @@ -6872,6 +6873,257 @@ "url": "https://opencollective.com/storybook" } }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-7.0.0.tgz", + "integrity": "sha512-khWbXesWIP9v8HuKCl2NU2HNAyqpSQ/vkIl36Nbn4HIwEYSRWL0H7Gs6idJdha2DkpFDWlsqMELvoCE8lfFY6Q==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-7.0.0.tgz", + "integrity": "sha512-iiZaIvb3H/c7d3TH2HBeK91uI2rMhZNwnsIrvd7ZwGLkFw6mmunOCoVnjdYua662MqGFxlN9xTq4fv9hgR4VXQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-7.0.0.tgz", + "integrity": "sha512-sQQmyo+qegBx8DfFc04PFmIO1FP1MHI1/QEpzcIcclo5OAISsOJPW76ZIs0bDyO/DBSJEa/tDa1W26pVtt0FRw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-7.0.0.tgz", + "integrity": "sha512-i6MaAqIZXDOJeikJuzocByBf8zO+meLwfQ/qMHIjCcvpnfvWf82PFvredEZElErB5glQFJa2KVKk8N2xV6tRRA==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-7.0.0.tgz", + "integrity": "sha512-BoVSh6ge3SLLpKC0pmmN9DFlqgFy4NxNgdZNLPNJWBUU7TQpDWeBuyVuDW88iXydb5Cv0ReC+ffa5h3VrKfk1w==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-7.0.0.tgz", + "integrity": "sha512-tNDcBa+hYn0gO+GkP/AuNKdVtMufVhU9fdzu+vUQsR18RIJ9RWe7h/pSBY338RO08wArntwbDk5WhQBmhf2PaA==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-7.0.0.tgz", + "integrity": "sha512-qw54u8ljCJYL2KtBOjI5z7Nzg8LnSvQOP5hPKj77H4VQL4+HdKbAT5pnkkZLmHKYwzsIHSYKXxHouD8zZamCFQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-7.0.0.tgz", + "integrity": "sha512-CcFECkDj98daOg9jE3Bh3uyD9kzevCAnZ+UtzG6+BQG/jOQ2OA3jHnX6iG4G1MCJkUQFnUvEv33NvQfqrb/F3A==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-7.0.0.tgz", + "integrity": "sha512-EX/NHeFa30j5UjldQGVQikuuQNHUdGmbh9kEpBKofGUtF0GUPJ4T4rhoYiqDAOmBOxojyot36JIFiDUHUK1ilQ==", + "dev": true, + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^7.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^7.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^7.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^7.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "^7.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "^7.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "^7.0.0", + "@svgr/babel-plugin-transform-svg-component": "^7.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-7.0.0.tgz", + "integrity": "sha512-ztAoxkaKhRVloa3XydohgQQCb0/8x9T63yXovpmHzKMkHO6pkjdsIAWKOS4bE95P/2quVh1NtjSKlMRNzSBffw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "^7.0.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/core/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@svgr/core/node_modules/cosmiconfig": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", + "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "dev": true, + "dependencies": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-7.0.0.tgz", + "integrity": "sha512-42Ej9sDDEmsJKjrfQ1PHmiDiHagh/u9AHO9QWbeNx4KmD9yS5d1XHmXUNINfUcykAU+4431Cn+k6Vn5mWBYimQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-7.0.0.tgz", + "integrity": "sha512-SWlTpPQmBUtLKxXWgpv8syzqIU8XgFRvyhfkam2So8b3BE0OS0HPe5UfmlJ2KIC+a7dpuuYovPR2WAQuSyMoPw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "^7.0.0", + "@svgr/hast-util-to-babel-ast": "^7.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, "node_modules/@tabler/icons": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-2.17.0.tgz", @@ -7697,8 +7949,7 @@ }, "node_modules/@vector-im/compound-web": { "version": "0.0.1", - "resolved": "git+ssh://git@github.com/vector-im/compound-web.git#5208d2d442587efb9938265841574f73ce97dff1", - "integrity": "sha512-qtJEPOjPeKgFX0YpPaddo4aqqYwQnzzSWE+TUl55a6XF3eupR3iOCZ4V+XR78gDJGlXmRLbg57rqqE3I53vd8A==", + "resolved": "git+ssh://git@github.com/vector-im/compound-web.git#51c611e84658c3d9a3bc8fecf97ceac7d45c5838", "license": "Apache-2.0", "dependencies": { "@radix-ui/react-form": "^0.0.2", @@ -17611,6 +17862,12 @@ "resolved": "https://registry.npmjs.org/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz", "integrity": "sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g==" }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true + }, "node_modules/svg-path-bounds": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/svg-path-bounds/-/svg-path-bounds-1.0.2.tgz", @@ -18855,6 +19112,48 @@ "vite": "^2.7.0 || ^3.0.0 || ^4.0.0" } }, + "node_modules/vite-plugin-svgr": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-3.2.0.tgz", + "integrity": "sha512-Uvq6niTvhqJU6ga78qLKBFJSDvxWhOnyfQSoKpDPMAGxJPo5S3+9hyjExE5YDj6Lpa4uaLkGc1cBgxXov+LjSw==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.2", + "@svgr/core": "^7.0.0", + "@svgr/plugin-jsx": "^7.0.0" + }, + "peerDependencies": { + "vite": "^2.6.0 || 3 || 4" + } + }, + "node_modules/vite-plugin-svgr/node_modules/@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/vite-plugin-svgr/node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, "node_modules/vitest": { "version": "0.31.1", "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.31.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index 52533531..ae4a9c0d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -22,7 +22,7 @@ "@urql/exchange-graphcache": "^6.0.4", "@urql/exchange-refocus": "^1.0.2", "@urql/exchange-request-policy": "^1.0.2", - "@vector-im/compound-web": "https://github.com/vector-im/compound-web.git#5208d2d442587efb9938265841574f73ce97dff1", + "@vector-im/compound-web": "https://github.com/vector-im/compound-web.git", "date-fns": "^2.30.0", "graphql": "^16.6.0", "jotai": "^2.1.0", @@ -70,6 +70,7 @@ "vite": "^4.3.8", "vite-plugin-eslint": "^1.8.1", "vite-plugin-graphql-codegen": "^3.2.2", + "vite-plugin-svgr": "^3.2.0", "vitest": "^0.31.1" } } diff --git a/frontend/src/Router.tsx b/frontend/src/Router.tsx index a4c9044f..1791168f 100644 --- a/frontend/src/Router.tsx +++ b/frontend/src/Router.tsx @@ -149,11 +149,15 @@ export const Link: React.FC< return ( { - e.preventDefault(); - startTransition(() => { - setRoute(route); - }); + onClick={(e: React.MouseEvent) => { + // Local links should be handled by the internal routers + // external links do not require a transition + if (!path.startsWith("http")) { + e.preventDefault(); + startTransition(() => { + setRoute(route); + }); + } }} {...props} > diff --git a/frontend/src/components/Block.tsx b/frontend/src/components/Block.tsx index c1670017..62f80bd1 100644 --- a/frontend/src/components/Block.tsx +++ b/frontend/src/components/Block.tsx @@ -20,13 +20,7 @@ type Props = { const Block: React.FC = ({ children, highlight, className }) => { return ( -
+
{children}
); diff --git a/frontend/src/components/BlockList.tsx b/frontend/src/components/BlockList.tsx index e92da492..0ef2f2d9 100644 --- a/frontend/src/components/BlockList.tsx +++ b/frontend/src/components/BlockList.tsx @@ -17,9 +17,7 @@ type Props = { }; const BlockList: React.FC = ({ children }) => { - return ( -
{children}
- ); + return
{children}
; }; export default BlockList; diff --git a/frontend/src/components/BrowserSession.tsx b/frontend/src/components/BrowserSession.tsx index 9ce83f68..fc4d0bcb 100644 --- a/frontend/src/components/BrowserSession.tsx +++ b/frontend/src/components/BrowserSession.tsx @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Link } from "../Router"; +import IconWebBrowser from "@vector-im/compound-design-tokens/icons/web-browser.svg"; +import { Body } from "@vector-im/compound-web"; + import { FragmentType, graphql, useFragment } from "../gql"; import Block from "./Block"; import DateTime from "./DateTime"; -import { Body, Subtitle } from "./Typography"; const FRAGMENT = graphql(/* GraphQL */ ` fragment BrowserSession_session on BrowserSession { @@ -38,28 +39,33 @@ type Props = { const BrowserSession: React.FC = ({ session, isCurrent }) => { const data = useFragment(FRAGMENT, session); - const lastAuthentication = data.lastAuthentication?.createdAt; + // const lastAuthentication = data.lastAuthentication?.createdAt; const createdAt = data.createdAt; return ( - - {isCurrent && Current session} - - - Started: - - - - Last authentication:{" "} - {lastAuthentication ? ( - + + + + {isCurrent ? ( + <> + Current browser session + ) : ( - "never" + <>Browser Session )} +
+ + Signed in + + + Sign out + +
); }; diff --git a/frontend/src/components/Button.stories.ts b/frontend/src/components/Button.stories.ts deleted file mode 100644 index f1b732d9..00000000 --- a/frontend/src/components/Button.stories.ts +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2022 The Matrix.org Foundation C.I.C. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import type { Meta, StoryObj } from "@storybook/react"; - -import Button from "./Button"; - -const meta = { - title: "UI/Button", - component: Button, - tags: ["autodocs"], - argTypes: { - onClick: { action: true }, - compact: { - defaultValue: false, - }, - ghost: { - defaultValue: false, - }, - disabled: { - defaultValue: false, - }, - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Basic: Story = { - args: { - children: "Button", - }, -}; - -export const Regular: Story = { - args: { - children: "Button", - compact: false, - ghost: false, - disabled: false, - }, -}; - -export const Compact: Story = { - args: { - children: "Compact", - compact: true, - ghost: false, - disabled: false, - }, -}; - -export const Disabled: Story = { - args: { - children: "Disabled", - compact: false, - ghost: false, - disabled: true, - }, -}; - -export const Ghost: Story = { - args: { - children: "Ghost", - compact: false, - ghost: true, - disabled: false, - }, -}; - -export const GhostDisabled: Story = { - args: { - children: "Ghost", - compact: false, - ghost: true, - disabled: true, - }, -}; diff --git a/frontend/src/components/Button.tsx b/frontend/src/components/Button.tsx deleted file mode 100644 index 13c6de11..00000000 --- a/frontend/src/components/Button.tsx +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2022 The Matrix.org Foundation C.I.C. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -type Props = { - /** The label of the button */ - children: string; - - /** Additional classes to apply to the button */ - className?: string; - - /** Makes the button more compact */ - compact?: boolean; - - /** Uses the 'ghost' (outline) alternative */ - ghost?: boolean; - - /** Disables all interactions with the button */ - disabled?: boolean; - - /** The type of the button */ - type?: "button" | "submit" | "reset"; -} & React.HTMLProps; - -const Button: React.FC = ({ - children, - className: extraClassName, - compact, - ghost, - disabled, - type, - ...props -}) => { - const sizeClass = compact ? "py-1 px-3" : "py-1 px-5"; - - let ghostClass; - let normalClass; - - if (disabled) { - ghostClass = "opacity-30 border border-accent text-accent"; - normalClass = "opacity-30 border border-accent bg-accent text-white"; - } else { - ghostClass = "border-accent border hover:bg-accent/10 text-accent"; - normalClass = - "bg-accent border border-accent hover:bg-accent/75 hover:border-accent/75 text-white"; - } - - const colors = ghost ? ghostClass : normalClass; - - return ( - - ); -}; - -export default Button; diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx index eaa53d99..09707f15 100644 --- a/frontend/src/components/Layout.tsx +++ b/frontend/src/components/Layout.tsx @@ -17,14 +17,40 @@ import NavItem from "./NavItem"; const Layout: React.FC<{ children?: React.ReactNode }> = ({ children }) => { return ( -
- + <> + Home My Account -
{children}
-
+
+ +
{children}
+ +
+ +
+ ); }; diff --git a/frontend/src/components/NavBar.tsx b/frontend/src/components/NavBar.tsx index 3184f2b9..50df1a44 100644 --- a/frontend/src/components/NavBar.tsx +++ b/frontend/src/components/NavBar.tsx @@ -17,7 +17,7 @@ const NavBar: React.FC<{ children: React.ReactNode; }> = ({ className, children }) => ( ); diff --git a/frontend/src/components/NavItem.tsx b/frontend/src/components/NavItem.tsx index a82e651d..8cc8b0dd 100644 --- a/frontend/src/components/NavItem.tsx +++ b/frontend/src/components/NavItem.tsx @@ -16,24 +16,35 @@ import { useAtomValue } from "jotai"; import { Link, Route, routeAtom } from "../Router"; -const NavItem: React.FC<{ route: Route; children: React.ReactNode }> = ({ - route, - children, -}) => { +type NavItemProps = { + children: React.ReactNode; +} & ({ route: Route; href?: never } | { route?: never; href: string }); + +function isRoute(route: Route | undefined): route is Route { + return !!route?.type; +} + +function isHref(href: string | undefined): href is string { + return typeof href === "string"; +} + +const NavItem: React.FC = ({ route, href, children }) => { const currentRoute = useAtomValue(routeAtom); return (
  • - - {children} - + {isRoute(route) && ( + + {children} + + )} + {isHref(href) && ( + + {children} + + )}
  • ); }; diff --git a/frontend/src/components/PaginationControls.tsx b/frontend/src/components/PaginationControls.tsx index a847a918..6ad40422 100644 --- a/frontend/src/components/PaginationControls.tsx +++ b/frontend/src/components/PaginationControls.tsx @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import Button from "./Button"; +import { Button } from "@vector-im/compound-web"; type Props = { onNext: (() => void) | null; @@ -28,30 +28,24 @@ const PaginationControls: React.FC = ({ disabled, }) => { return ( -
    - {onPrev ? ( - - ) : ( - - )} - {count !== undefined ? ( -
    Total: {count}
    - ) : ( -
    - )} - {onNext ? ( - - ) : ( - - )} +
    + +
    {count && <>Total: {count}}
    +
    ); }; diff --git a/frontend/src/components/UserEmail.tsx b/frontend/src/components/UserEmail.tsx index cf0bbd05..ed0677af 100644 --- a/frontend/src/components/UserEmail.tsx +++ b/frontend/src/components/UserEmail.tsx @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +import { Button } from "@vector-im/compound-web"; import { atom, useAtom, useSetAtom } from "jotai"; import { atomFamily } from "jotai/utils"; import { atomWithMutation } from "jotai-urql"; @@ -20,7 +21,6 @@ import { useRef, useTransition } from "react"; import { FragmentType, graphql, useFragment } from "../gql"; import Block from "./Block"; -import Button from "./Button"; import DateTime from "./DateTime"; import Input from "./Input"; import Typography from "./Typography"; @@ -237,18 +237,12 @@ const UserEmail: React.FC<{ )} - diff --git a/frontend/src/components/UserGreeting.tsx b/frontend/src/components/UserGreeting.tsx index b931ce6e..91053760 100644 --- a/frontend/src/components/UserGreeting.tsx +++ b/frontend/src/components/UserGreeting.tsx @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +import { Heading, Body } from "@vector-im/compound-web"; import { useAtomValue } from "jotai"; import { atomFamily } from "jotai/utils"; import { atomWithQuery } from "jotai-urql"; import { graphql } from "../gql"; -import Typography from "./Typography"; - const QUERY = graphql(/* GraphQL */ ` query UserGreeting($userId: ID!) { user(id: $userId) { @@ -43,9 +42,12 @@ const UserGreeting: React.FC<{ userId: string }> = ({ userId }) => { if (result.data?.user) { return ( - - Hello, {result.data.user.username}! - +
    + + John Doe + + {result.data.user.username} +
    ); } diff --git a/frontend/src/gql/schema.ts b/frontend/src/gql/schema.ts index a735c214..2304d889 100644 --- a/frontend/src/gql/schema.ts +++ b/frontend/src/gql/schema.ts @@ -1,4 +1,3 @@ -/* eslint-disable */ import { IntrospectionQuery } from "graphql"; export default { __schema: { diff --git a/frontend/src/index.css b/frontend/src/index.css index 3f769cce..8ad416ce 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -19,6 +19,60 @@ @tailwind components; @tailwind utilities; -body, .docs-story { - @apply bg-grey-25 text-black-900 dark:bg-black-800 dark:text-white; +body { + font: var(--cpd-font-body-md-regular); + background: var(--cpd-color-bg-canvas-default); + + width: 378px; + margin: var(--cpd-space-10x) auto var(--cpd-space-6x) auto; +} + +.oidc_Header { + text-align: center; +} + +.oidc_Header > * { + margin: 0; +} + +.secondary-text { + color: var(--cpd-color-text-secondary); +} + +a { + text-decoration: underline; +} + +a:hover { + text-decoration: none; +} + +[data-kind="critical"] { + color: var(--cpd-color-text-critical-primary); +} + +.nav-bar a { + color: var(--cpd-color-text-action-primary); +} + +.nav-bar .active { + font-weight: var(--cpd-font-weight-semibold); +} + +.nav-bar li:not(:first-child) { + list-style-type: disc; + color: var(--cpd-color-text-secondary); +} + +hr { + border: 0; + height: 1px; + background: var(--cpd-color-gray-400); +} + +.session-icon { + color: var(--cpd-color-icon-secondary); + background: var(--cpd-color-bg-subtle-secondary); + padding: var(--cpd-space-1x); + border-radius: 4px; } diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 3e0ae481..ca4b5412 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -17,6 +17,7 @@ import react from "@vitejs/plugin-react"; import { defineConfig } from "vite"; import eslint from "vite-plugin-eslint"; import codegen from "vite-plugin-graphql-codegen"; +import svgr from "vite-plugin-svgr"; export default defineConfig({ base: "/app/", @@ -39,6 +40,18 @@ export default defineConfig({ // Explicitly set the config file, else storybook gets confused overrideConfigFile: "./.eslintrc.cjs", }), + svgr({ + exportAsDefault: true, + svgrOptions: { + // Using 1em in order to make SVG size inherits from text size. + icon: "1em", + svgProps: { + // Adding a class in case we want to add global overrides, but one + // should probably stick to using CSS modules most of the time + class: "cpd-icon", + }, + }, + }), ], server: { proxy: {