mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
chore: add new avatar component (#15882)
Related to https://github.com/coder/coder/issues/14997 - Add a new `Avatar` component based on the [new avatar design](https://www.figma.com/design/WfqIgsTFXN2BscBSSyXWF8/Coder-kit?node-id=711-383&t=xqxOSUk48GvDsjGK-0). - Deprecate existent `Avatar` component.
This commit is contained in:
@ -50,6 +50,7 @@
|
|||||||
"@mui/system": "5.16.7",
|
"@mui/system": "5.16.7",
|
||||||
"@mui/utils": "5.16.6",
|
"@mui/utils": "5.16.6",
|
||||||
"@mui/x-tree-view": "7.18.0",
|
"@mui/x-tree-view": "7.18.0",
|
||||||
|
"@radix-ui/react-avatar": "1.1.2",
|
||||||
"@radix-ui/react-dialog": "1.1.2",
|
"@radix-ui/react-dialog": "1.1.2",
|
||||||
"@radix-ui/react-label": "2.1.0",
|
"@radix-ui/react-label": "2.1.0",
|
||||||
"@radix-ui/react-slider": "1.2.1",
|
"@radix-ui/react-slider": "1.2.1",
|
||||||
|
82
site/pnpm-lock.yaml
generated
82
site/pnpm-lock.yaml
generated
@ -63,6 +63,9 @@ importers:
|
|||||||
'@mui/x-tree-view':
|
'@mui/x-tree-view':
|
||||||
specifier: 7.18.0
|
specifier: 7.18.0
|
||||||
version: 7.18.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 7.18.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@radix-ui/react-avatar':
|
||||||
|
specifier: 1.1.2
|
||||||
|
version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
'@radix-ui/react-dialog':
|
'@radix-ui/react-dialog':
|
||||||
specifier: 1.1.2
|
specifier: 1.1.2
|
||||||
version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@ -1550,6 +1553,19 @@ packages:
|
|||||||
'@radix-ui/primitive@1.1.0':
|
'@radix-ui/primitive@1.1.0':
|
||||||
resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==}
|
resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==}
|
||||||
|
|
||||||
|
'@radix-ui/react-avatar@1.1.2':
|
||||||
|
resolution: {integrity: sha512-GaC7bXQZ5VgZvVvsJ5mu/AEbjYLnhhkoidOboC50Z6FFlLA03wG2ianUoH+zgDQ31/9gCF59bE4+2bBgTyMiig==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@radix-ui/react-collection@1.1.0':
|
'@radix-ui/react-collection@1.1.0':
|
||||||
resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==}
|
resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -1581,6 +1597,15 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-compose-refs@1.1.1':
|
||||||
|
resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@radix-ui/react-context@1.0.1':
|
'@radix-ui/react-context@1.0.1':
|
||||||
resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==}
|
resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -1822,6 +1847,19 @@ packages:
|
|||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-primitive@2.0.1':
|
||||||
|
resolution: {integrity: sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@radix-ui/react-slider@1.2.1':
|
'@radix-ui/react-slider@1.2.1':
|
||||||
resolution: {integrity: sha512-bEzQoDW0XP+h/oGbutF5VMWJPAl/UU8IJjr7h02SOHDIIIxq+cep8nItVNoBV+OMmahCdqdF38FTpmXoqQUGvw==}
|
resolution: {integrity: sha512-bEzQoDW0XP+h/oGbutF5VMWJPAl/UU8IJjr7h02SOHDIIIxq+cep8nItVNoBV+OMmahCdqdF38FTpmXoqQUGvw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -1853,6 +1891,15 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-slot@1.1.1':
|
||||||
|
resolution: {integrity: sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@radix-ui/react-switch@1.1.1':
|
'@radix-ui/react-switch@1.1.1':
|
||||||
resolution: {integrity: sha512-diPqDDoBcZPSicYoMWdWx+bCPuTRH4QSp9J+65IvtdS0Kuzt67bI6n32vCj8q6NZmYW/ah+2orOtMwcX5eQwIg==}
|
resolution: {integrity: sha512-diPqDDoBcZPSicYoMWdWx+bCPuTRH4QSp9J+65IvtdS0Kuzt67bI6n32vCj8q6NZmYW/ah+2orOtMwcX5eQwIg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -3513,7 +3560,6 @@ packages:
|
|||||||
eslint@8.52.0:
|
eslint@8.52.0:
|
||||||
resolution: {integrity: sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==}
|
resolution: {integrity: sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
|
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
espree@9.6.1:
|
espree@9.6.1:
|
||||||
@ -7213,6 +7259,18 @@ snapshots:
|
|||||||
|
|
||||||
'@radix-ui/primitive@1.1.0': {}
|
'@radix-ui/primitive@1.1.0': {}
|
||||||
|
|
||||||
|
'@radix-ui/react-avatar@1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@18.3.1)
|
||||||
|
'@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 18.3.12
|
||||||
|
'@types/react-dom': 18.3.1
|
||||||
|
|
||||||
'@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1)
|
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1)
|
||||||
@ -7238,6 +7296,12 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 18.3.12
|
'@types/react': 18.3.12
|
||||||
|
|
||||||
|
'@radix-ui/react-compose-refs@1.1.1(@types/react@18.3.12)(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
react: 18.3.1
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 18.3.12
|
||||||
|
|
||||||
'@radix-ui/react-context@1.0.1(@types/react@18.3.12)(react@18.3.1)':
|
'@radix-ui/react-context@1.0.1(@types/react@18.3.12)(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.25.6
|
'@babel/runtime': 7.25.6
|
||||||
@ -7455,6 +7519,15 @@ snapshots:
|
|||||||
'@types/react': 18.3.12
|
'@types/react': 18.3.12
|
||||||
'@types/react-dom': 18.3.1
|
'@types/react-dom': 18.3.1
|
||||||
|
|
||||||
|
'@radix-ui/react-primitive@2.0.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/react-slot': 1.1.1(@types/react@18.3.12)(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 18.3.12
|
||||||
|
'@types/react-dom': 18.3.1
|
||||||
|
|
||||||
'@radix-ui/react-slider@1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@radix-ui/react-slider@1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/number': 1.1.0
|
'@radix-ui/number': 1.1.0
|
||||||
@ -7489,6 +7562,13 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 18.3.12
|
'@types/react': 18.3.12
|
||||||
|
|
||||||
|
'@radix-ui/react-slot@1.1.1(@types/react@18.3.12)(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.12)(react@18.3.1)
|
||||||
|
react: 18.3.1
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 18.3.12
|
||||||
|
|
||||||
'@radix-ui/react-switch@1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@radix-ui/react-switch@1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/primitive': 1.1.0
|
'@radix-ui/primitive': 1.1.0
|
||||||
|
@ -1,59 +1,73 @@
|
|||||||
import PauseIcon from "@mui/icons-material/PauseOutlined";
|
|
||||||
import type { Meta, StoryObj } from "@storybook/react";
|
import type { Meta, StoryObj } from "@storybook/react";
|
||||||
import { Avatar, AvatarIcon } from "./Avatar";
|
import { Avatar, AvatarFallback, AvatarImage } from "./Avatar";
|
||||||
|
|
||||||
const meta: Meta<typeof Avatar> = {
|
const meta: Meta<typeof Avatar> = {
|
||||||
title: "components/Avatar",
|
title: "components/Avatar",
|
||||||
component: Avatar,
|
component: Avatar,
|
||||||
|
args: {
|
||||||
|
children: <AvatarImage src="https://github.com/kylecarbs.png" />,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default meta;
|
export default meta;
|
||||||
type Story = StoryObj<typeof Avatar>;
|
type Story = StoryObj<typeof Avatar>;
|
||||||
|
|
||||||
export const WithLetter: Story = {
|
export const ImageLgSize: Story = {
|
||||||
|
args: { size: "lg" },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ImageDefaultSize: Story = {};
|
||||||
|
|
||||||
|
export const ImageSmSize: Story = {
|
||||||
|
args: { size: "sm" },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const IconLgSize: Story = {
|
||||||
args: {
|
args: {
|
||||||
children: "Coder",
|
size: "lg",
|
||||||
|
variant: "icon",
|
||||||
|
children: (
|
||||||
|
<AvatarImage src="https://em-content.zobj.net/source/apple/391/billed-cap_1f9e2.png" />
|
||||||
|
),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WithLetterXL = {
|
export const IconDefaultSize: Story = {
|
||||||
args: {
|
args: {
|
||||||
children: "Coder",
|
variant: "icon",
|
||||||
size: "xl",
|
children: (
|
||||||
|
<AvatarImage src="https://em-content.zobj.net/source/apple/391/billed-cap_1f9e2.png" />
|
||||||
|
),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WithImage = {
|
export const IconSmSize: Story = {
|
||||||
args: {
|
args: {
|
||||||
src: "https://avatars.githubusercontent.com/u/95932066?s=200&v=4",
|
variant: "icon",
|
||||||
|
size: "sm",
|
||||||
|
children: (
|
||||||
|
<AvatarImage src="https://em-content.zobj.net/source/apple/391/billed-cap_1f9e2.png" />
|
||||||
|
),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WithImageXL = {
|
export const FallbackLgSize: Story = {
|
||||||
args: {
|
args: {
|
||||||
src: "https://avatars.githubusercontent.com/u/95932066?s=200&v=4",
|
size: "lg",
|
||||||
size: "xl",
|
|
||||||
|
children: <AvatarFallback>AR</AvatarFallback>,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WithMuiIcon = {
|
export const FallbackDefaultSize: Story = {
|
||||||
args: {
|
args: {
|
||||||
background: true,
|
children: <AvatarFallback>AR</AvatarFallback>,
|
||||||
children: <PauseIcon />,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WithMuiIconXL = {
|
export const FallbackSmSize: Story = {
|
||||||
args: {
|
args: {
|
||||||
background: true,
|
size: "sm",
|
||||||
children: <PauseIcon />,
|
children: <AvatarFallback>AR</AvatarFallback>,
|
||||||
size: "xl",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const WithAvatarIcon = {
|
|
||||||
args: {
|
|
||||||
background: true,
|
|
||||||
children: <AvatarIcon src="/icon/database.svg" alt="Database" />,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,116 +1,94 @@
|
|||||||
import { type Interpolation, type Theme, css, useTheme } from "@emotion/react";
|
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
||||||
import MuiAvatar, {
|
import { type VariantProps, cva } from "class-variance-authority";
|
||||||
type AvatarProps as MuiAvatarProps,
|
|
||||||
// biome-ignore lint/nursery/noRestrictedImports: Used as base component
|
|
||||||
} from "@mui/material/Avatar";
|
|
||||||
import { visuallyHidden } from "@mui/utils";
|
|
||||||
import { type FC, useId } from "react";
|
|
||||||
import { getExternalImageStylesFromUrl } from "theme/externalImages";
|
|
||||||
|
|
||||||
export type AvatarProps = MuiAvatarProps & {
|
|
||||||
size?: "xs" | "sm" | "md" | "xl";
|
|
||||||
background?: boolean;
|
|
||||||
fitImage?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
const sizeStyles = {
|
|
||||||
xs: {
|
|
||||||
width: 16,
|
|
||||||
height: 16,
|
|
||||||
fontSize: 8,
|
|
||||||
fontWeight: 700,
|
|
||||||
},
|
|
||||||
sm: {
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: 600,
|
|
||||||
},
|
|
||||||
md: {},
|
|
||||||
xl: {
|
|
||||||
width: 48,
|
|
||||||
height: 48,
|
|
||||||
fontSize: 24,
|
|
||||||
},
|
|
||||||
} satisfies Record<string, Interpolation<Theme>>;
|
|
||||||
|
|
||||||
const fitImageStyles = css`
|
|
||||||
& .MuiAvatar-img {
|
|
||||||
object-fit: contain;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const Avatar: FC<AvatarProps> = ({
|
|
||||||
size = "md",
|
|
||||||
fitImage,
|
|
||||||
children,
|
|
||||||
background,
|
|
||||||
...muiProps
|
|
||||||
}) => {
|
|
||||||
const fromName = !muiProps.src && typeof children === "string";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<MuiAvatar
|
|
||||||
{...muiProps}
|
|
||||||
css={[
|
|
||||||
sizeStyles[size],
|
|
||||||
fitImage && fitImageStyles,
|
|
||||||
(theme) => ({
|
|
||||||
background:
|
|
||||||
background || fromName ? theme.palette.divider : undefined,
|
|
||||||
color: theme.palette.text.primary,
|
|
||||||
}),
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
{typeof children === "string" ? firstLetter(children) : children}
|
|
||||||
</MuiAvatar>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ExternalAvatar: FC<AvatarProps> = (props) => {
|
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Avatar
|
|
||||||
css={getExternalImageStylesFromUrl(theme.externalImages, props.src)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
type AvatarIconProps = {
|
|
||||||
src: string;
|
|
||||||
alt: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use it to make an img element behaves like a MaterialUI Icon component
|
* Copied from shadc/ui on 12/16/2024
|
||||||
|
* @see {@link https://ui.shadcn.com/docs/components/avatar}
|
||||||
|
*
|
||||||
|
* This component was updated to support the variants and match the styles from
|
||||||
|
* the Figma design:
|
||||||
|
* @see {@link https://www.figma.com/design/WfqIgsTFXN2BscBSSyXWF8/Coder-kit?node-id=711-383&t=xqxOSUk48GvDsjGK-0}
|
||||||
*/
|
*/
|
||||||
export const AvatarIcon: FC<AvatarIconProps> = ({ src, alt }) => {
|
import * as React from "react";
|
||||||
const hookId = useId();
|
import { cn } from "utils/cn";
|
||||||
const avatarId = `${hookId}-avatar`;
|
|
||||||
|
|
||||||
// We use a `visuallyHidden` element instead of setting `alt` to avoid
|
const avatarVariants = cva(
|
||||||
// splatting the text out on the screen if the image fails to load.
|
"relative flex shrink-0 overflow-hidden rounded border border-solid bg-surface-secondary text-content-secondary",
|
||||||
return (
|
{
|
||||||
<>
|
variants: {
|
||||||
<img
|
size: {
|
||||||
src={src}
|
lg: "h-10 w-10 rounded-[6px] text-sm font-medium",
|
||||||
alt=""
|
default: "h-6 w-6 text-2xs",
|
||||||
css={{ maxWidth: "50%" }}
|
sm: "h-[18px] w-[18px] text-[8px]",
|
||||||
aria-labelledby={avatarId}
|
},
|
||||||
/>
|
variant: {
|
||||||
<div id={avatarId} css={{ ...visuallyHidden }}>
|
default: "",
|
||||||
{alt}
|
icon: "",
|
||||||
</div>
|
},
|
||||||
</>
|
},
|
||||||
);
|
defaultVariants: {
|
||||||
};
|
size: "default",
|
||||||
|
},
|
||||||
|
compoundVariants: [
|
||||||
|
{
|
||||||
|
size: "lg",
|
||||||
|
variant: "icon",
|
||||||
|
className: "p-[9px]",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: "default",
|
||||||
|
variant: "icon",
|
||||||
|
className: "p-[3px]",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size: "sm",
|
||||||
|
variant: "icon",
|
||||||
|
className: "p-[2px]",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const firstLetter = (str: string): string => {
|
export interface AvatarProps
|
||||||
if (str.length > 0) {
|
extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>,
|
||||||
return str[0].toLocaleUpperCase();
|
VariantProps<typeof avatarVariants> {}
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
const Avatar = React.forwardRef<
|
||||||
};
|
React.ElementRef<typeof AvatarPrimitive.Root>,
|
||||||
|
AvatarProps
|
||||||
|
>(({ className, size, variant, ...props }, ref) => (
|
||||||
|
<AvatarPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(avatarVariants({ size, variant, className }))}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
||||||
|
|
||||||
|
const AvatarImage = React.forwardRef<
|
||||||
|
React.ElementRef<typeof AvatarPrimitive.Image>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<AvatarPrimitive.Image
|
||||||
|
ref={ref}
|
||||||
|
className={cn("aspect-square h-full w-full", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
||||||
|
|
||||||
|
const AvatarFallback = React.forwardRef<
|
||||||
|
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<AvatarPrimitive.Fallback
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-full w-full items-center justify-center rounded-full",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
||||||
|
|
||||||
|
export { Avatar, AvatarImage, AvatarFallback };
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { type CSSObject, useTheme } from "@emotion/react";
|
import { type CSSObject, useTheme } from "@emotion/react";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import type { FC, ReactNode } from "react";
|
import type { FC, ReactNode } from "react";
|
||||||
|
|
||||||
type AvatarCardProps = {
|
type AvatarCardProps = {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useTheme } from "@emotion/react";
|
import { useTheme } from "@emotion/react";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import type { FC, ReactNode } from "react";
|
import type { FC, ReactNode } from "react";
|
||||||
|
|
||||||
export interface AvatarDataProps {
|
export interface AvatarDataProps {
|
||||||
|
@ -2,8 +2,8 @@ import { css, cx } from "@emotion/css";
|
|||||||
import { useTheme } from "@emotion/react";
|
import { useTheme } from "@emotion/react";
|
||||||
import Badge from "@mui/material/Badge";
|
import Badge from "@mui/material/Badge";
|
||||||
import type { WorkspaceBuild } from "api/typesGenerated";
|
import type { WorkspaceBuild } from "api/typesGenerated";
|
||||||
import { Avatar, type AvatarProps } from "components/Avatar/Avatar";
|
|
||||||
import { BuildIcon } from "components/BuildIcon/BuildIcon";
|
import { BuildIcon } from "components/BuildIcon/BuildIcon";
|
||||||
|
import { Avatar, type AvatarProps } from "components/deprecated/Avatar/Avatar";
|
||||||
import { useClassName } from "hooks/useClassName";
|
import { useClassName } from "hooks/useClassName";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
import { getDisplayWorkspaceBuildStatus } from "utils/workspace";
|
import { getDisplayWorkspaceBuildStatus } from "utils/workspace";
|
||||||
|
@ -2,7 +2,10 @@ import { css } from "@emotion/css";
|
|||||||
import { useTheme } from "@emotion/react";
|
import { useTheme } from "@emotion/react";
|
||||||
import Button, { type ButtonProps } from "@mui/material/Button";
|
import Button, { type ButtonProps } from "@mui/material/Button";
|
||||||
import IconButton, { type IconButtonProps } from "@mui/material/IconButton";
|
import IconButton, { type IconButtonProps } from "@mui/material/IconButton";
|
||||||
import { type AvatarProps, ExternalAvatar } from "components/Avatar/Avatar";
|
import {
|
||||||
|
type AvatarProps,
|
||||||
|
ExternalAvatar,
|
||||||
|
} from "components/deprecated/Avatar/Avatar";
|
||||||
import {
|
import {
|
||||||
type FC,
|
type FC,
|
||||||
type ForwardedRef,
|
type ForwardedRef,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import Group from "@mui/icons-material/Group";
|
import Group from "@mui/icons-material/Group";
|
||||||
import Badge from "@mui/material/Badge";
|
import Badge from "@mui/material/Badge";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { type ClassName, useClassName } from "hooks/useClassName";
|
import { type ClassName, useClassName } from "hooks/useClassName";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ import TextField from "@mui/material/TextField";
|
|||||||
import { checkAuthorization } from "api/queries/authCheck";
|
import { checkAuthorization } from "api/queries/authCheck";
|
||||||
import { organizations } from "api/queries/organizations";
|
import { organizations } from "api/queries/organizations";
|
||||||
import type { AuthorizationCheck, Organization } from "api/typesGenerated";
|
import type { AuthorizationCheck, Organization } from "api/typesGenerated";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { useDebouncedFunction } from "hooks/debounce";
|
import { useDebouncedFunction } from "hooks/debounce";
|
||||||
import {
|
import {
|
||||||
type ChangeEvent,
|
type ChangeEvent,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { Template } from "api/typesGenerated";
|
import type { Template } from "api/typesGenerated";
|
||||||
import { Avatar, type AvatarProps } from "components/Avatar/Avatar";
|
import { Avatar, type AvatarProps } from "components/deprecated/Avatar/Avatar";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
|
|
||||||
interface TemplateAvatarProps extends AvatarProps {
|
interface TemplateAvatarProps extends AvatarProps {
|
||||||
|
@ -6,8 +6,8 @@ import { getErrorMessage } from "api/errors";
|
|||||||
import { organizationMembers } from "api/queries/organizations";
|
import { organizationMembers } from "api/queries/organizations";
|
||||||
import { users } from "api/queries/users";
|
import { users } from "api/queries/users";
|
||||||
import type { OrganizationMemberWithUserData, User } from "api/typesGenerated";
|
import type { OrganizationMemberWithUserData, User } from "api/typesGenerated";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { useDebouncedFunction } from "hooks/debounce";
|
import { useDebouncedFunction } from "hooks/debounce";
|
||||||
import {
|
import {
|
||||||
type ChangeEvent,
|
type ChangeEvent,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Avatar, type AvatarProps } from "components/Avatar/Avatar";
|
import { Avatar, type AvatarProps } from "components/deprecated/Avatar/Avatar";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
|
|
||||||
export type UserAvatarProps = {
|
export type UserAvatarProps = {
|
||||||
|
59
site/src/components/deprecated/Avatar/Avatar.stories.tsx
Normal file
59
site/src/components/deprecated/Avatar/Avatar.stories.tsx
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import PauseIcon from "@mui/icons-material/PauseOutlined";
|
||||||
|
import type { Meta, StoryObj } from "@storybook/react";
|
||||||
|
import { Avatar, AvatarIcon } from "./Avatar";
|
||||||
|
|
||||||
|
const meta: Meta<typeof Avatar> = {
|
||||||
|
title: "components/DeprecatedAvatar",
|
||||||
|
component: Avatar,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof Avatar>;
|
||||||
|
|
||||||
|
export const WithLetter: Story = {
|
||||||
|
args: {
|
||||||
|
children: "Coder",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WithLetterXL = {
|
||||||
|
args: {
|
||||||
|
children: "Coder",
|
||||||
|
size: "xl",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WithImage = {
|
||||||
|
args: {
|
||||||
|
src: "https://avatars.githubusercontent.com/u/95932066?s=200&v=4",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WithImageXL = {
|
||||||
|
args: {
|
||||||
|
src: "https://avatars.githubusercontent.com/u/95932066?s=200&v=4",
|
||||||
|
size: "xl",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WithMuiIcon = {
|
||||||
|
args: {
|
||||||
|
background: true,
|
||||||
|
children: <PauseIcon />,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WithMuiIconXL = {
|
||||||
|
args: {
|
||||||
|
background: true,
|
||||||
|
children: <PauseIcon />,
|
||||||
|
size: "xl",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WithAvatarIcon = {
|
||||||
|
args: {
|
||||||
|
background: true,
|
||||||
|
children: <AvatarIcon src="/icon/database.svg" alt="Database" />,
|
||||||
|
},
|
||||||
|
};
|
124
site/src/components/deprecated/Avatar/Avatar.tsx
Normal file
124
site/src/components/deprecated/Avatar/Avatar.tsx
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import { type Interpolation, type Theme, css, useTheme } from "@emotion/react";
|
||||||
|
import MuiAvatar, {
|
||||||
|
type AvatarProps as MuiAvatarProps,
|
||||||
|
// biome-ignore lint/nursery/noRestrictedImports: Used as base component
|
||||||
|
} from "@mui/material/Avatar";
|
||||||
|
import { visuallyHidden } from "@mui/utils";
|
||||||
|
import { type FC, useId } from "react";
|
||||||
|
import { getExternalImageStylesFromUrl } from "theme/externalImages";
|
||||||
|
|
||||||
|
export type AvatarProps = MuiAvatarProps & {
|
||||||
|
size?: "xs" | "sm" | "md" | "xl";
|
||||||
|
background?: boolean;
|
||||||
|
fitImage?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const sizeStyles = {
|
||||||
|
xs: {
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
fontSize: 8,
|
||||||
|
fontWeight: 700,
|
||||||
|
},
|
||||||
|
sm: {
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: 600,
|
||||||
|
},
|
||||||
|
md: {},
|
||||||
|
xl: {
|
||||||
|
width: 48,
|
||||||
|
height: 48,
|
||||||
|
fontSize: 24,
|
||||||
|
},
|
||||||
|
} satisfies Record<string, Interpolation<Theme>>;
|
||||||
|
|
||||||
|
const fitImageStyles = css`
|
||||||
|
& .MuiAvatar-img {
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use `Avatar` from `@components/Avatar` instead.
|
||||||
|
*/
|
||||||
|
export const Avatar: FC<AvatarProps> = ({
|
||||||
|
size = "md",
|
||||||
|
fitImage,
|
||||||
|
children,
|
||||||
|
background,
|
||||||
|
...muiProps
|
||||||
|
}) => {
|
||||||
|
const fromName = !muiProps.src && typeof children === "string";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MuiAvatar
|
||||||
|
{...muiProps}
|
||||||
|
css={[
|
||||||
|
sizeStyles[size],
|
||||||
|
fitImage && fitImageStyles,
|
||||||
|
(theme) => ({
|
||||||
|
background:
|
||||||
|
background || fromName ? theme.palette.divider : undefined,
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
}),
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{typeof children === "string" ? firstLetter(children) : children}
|
||||||
|
</MuiAvatar>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use `Avatar` from `@components/Avatar` instead.
|
||||||
|
*/
|
||||||
|
export const ExternalAvatar: FC<AvatarProps> = (props) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Avatar
|
||||||
|
css={getExternalImageStylesFromUrl(theme.externalImages, props.src)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type AvatarIconProps = {
|
||||||
|
src: string;
|
||||||
|
alt: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use it to make an img element behaves like a MaterialUI Icon component
|
||||||
|
*
|
||||||
|
* @deprecated Use `AvatarIcon` from `@components/Avatar` instead.
|
||||||
|
*/
|
||||||
|
export const AvatarIcon: FC<AvatarIconProps> = ({ src, alt }) => {
|
||||||
|
const hookId = useId();
|
||||||
|
const avatarId = `${hookId}-avatar`;
|
||||||
|
|
||||||
|
// We use a `visuallyHidden` element instead of setting `alt` to avoid
|
||||||
|
// splatting the text out on the screen if the image fails to load.
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<img
|
||||||
|
src={src}
|
||||||
|
alt=""
|
||||||
|
css={{ maxWidth: "50%" }}
|
||||||
|
aria-labelledby={avatarId}
|
||||||
|
/>
|
||||||
|
<div id={avatarId} css={{ ...visuallyHidden }}>
|
||||||
|
{alt}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const firstLetter = (str: string): string => {
|
||||||
|
if (str.length > 0) {
|
||||||
|
return str[0].toLocaleUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
};
|
@ -1,7 +1,7 @@
|
|||||||
import { visuallyHidden } from "@mui/utils";
|
import { visuallyHidden } from "@mui/utils";
|
||||||
import type { WorkspaceResource } from "api/typesGenerated";
|
import type { WorkspaceResource } from "api/typesGenerated";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { ExternalImage } from "components/ExternalImage/ExternalImage";
|
import { ExternalImage } from "components/ExternalImage/ExternalImage";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { type FC, useId } from "react";
|
import { type FC, useId } from "react";
|
||||||
import { getResourceIconPath } from "utils/workspace";
|
import { getResourceIconPath } from "utils/workspace";
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import TextField from "@mui/material/TextField";
|
|||||||
import type * as TypesGen from "api/typesGenerated";
|
import type * as TypesGen from "api/typesGenerated";
|
||||||
import { Alert } from "components/Alert/Alert";
|
import { Alert } from "components/Alert/Alert";
|
||||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import {
|
import {
|
||||||
FormFields,
|
FormFields,
|
||||||
FormFooter,
|
FormFooter,
|
||||||
@ -22,6 +21,7 @@ import { Pill } from "components/Pill/Pill";
|
|||||||
import { RichParameterInput } from "components/RichParameterInput/RichParameterInput";
|
import { RichParameterInput } from "components/RichParameterInput/RichParameterInput";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete";
|
import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { type FormikContextType, useFormik } from "formik";
|
import { type FormikContextType, useFormik } from "formik";
|
||||||
import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName";
|
import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName";
|
||||||
import { type FC, useCallback, useEffect, useMemo, useState } from "react";
|
import { type FC, useCallback, useEffect, useMemo, useState } from "react";
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { Interpolation, Theme } from "@emotion/react";
|
import type { Interpolation, Theme } from "@emotion/react";
|
||||||
import type { Template, TemplateExample } from "api/typesGenerated";
|
import type { Template, TemplateExample } from "api/typesGenerated";
|
||||||
import { ExternalAvatar } from "components/Avatar/Avatar";
|
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
|
import { ExternalAvatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
|
|
||||||
export interface SelectedTemplateProps {
|
export interface SelectedTemplateProps {
|
||||||
|
@ -10,11 +10,11 @@ import TableHead from "@mui/material/TableHead";
|
|||||||
import TableRow from "@mui/material/TableRow";
|
import TableRow from "@mui/material/TableRow";
|
||||||
import type * as TypesGen from "api/typesGenerated";
|
import type * as TypesGen from "api/typesGenerated";
|
||||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||||
import { SettingsHeader } from "components/SettingsHeader/SettingsHeader";
|
import { SettingsHeader } from "components/SettingsHeader/SettingsHeader";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
import { TableLoader } from "components/TableLoader/TableLoader";
|
import { TableLoader } from "components/TableLoader/TableLoader";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { useClickableTableRow } from "hooks/useClickableTableRow";
|
import { useClickableTableRow } from "hooks/useClickableTableRow";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
@ -8,10 +8,10 @@ import Tooltip from "@mui/material/Tooltip";
|
|||||||
import type { ApiErrorResponse } from "api/errors";
|
import type { ApiErrorResponse } from "api/errors";
|
||||||
import type { ExternalAuth, ExternalAuthDevice } from "api/typesGenerated";
|
import type { ExternalAuth, ExternalAuthDevice } from "api/typesGenerated";
|
||||||
import { Alert, AlertDetail } from "components/Alert/Alert";
|
import { Alert, AlertDetail } from "components/Alert/Alert";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { CopyButton } from "components/CopyButton/CopyButton";
|
import { CopyButton } from "components/CopyButton/CopyButton";
|
||||||
import { SignInLayout } from "components/SignInLayout/SignInLayout";
|
import { SignInLayout } from "components/SignInLayout/SignInLayout";
|
||||||
import { Welcome } from "components/Welcome/Welcome";
|
import { Welcome } from "components/Welcome/Welcome";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import type { FC, ReactNode } from "react";
|
import type { FC, ReactNode } from "react";
|
||||||
|
|
||||||
export interface ExternalAuthPageViewProps {
|
export interface ExternalAuthPageViewProps {
|
||||||
|
@ -11,7 +11,6 @@ import type {
|
|||||||
Template,
|
Template,
|
||||||
TemplateVersion,
|
TemplateVersion,
|
||||||
} from "api/typesGenerated";
|
} from "api/typesGenerated";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog";
|
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog";
|
||||||
import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog";
|
import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog";
|
||||||
import { Margins } from "components/Margins/Margins";
|
import { Margins } from "components/Margins/Margins";
|
||||||
@ -30,6 +29,7 @@ import {
|
|||||||
} from "components/PageHeader/PageHeader";
|
} from "components/PageHeader/PageHeader";
|
||||||
import { Pill } from "components/Pill/Pill";
|
import { Pill } from "components/Pill/Pill";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { linkToTemplate, useLinks } from "modules/navigation";
|
import { linkToTemplate, useLinks } from "modules/navigation";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
import { useQuery } from "react-query";
|
import { useQuery } from "react-query";
|
||||||
|
@ -3,12 +3,12 @@ import SecurityIcon from "@mui/icons-material/LockOutlined";
|
|||||||
import GeneralIcon from "@mui/icons-material/SettingsOutlined";
|
import GeneralIcon from "@mui/icons-material/SettingsOutlined";
|
||||||
import ScheduleIcon from "@mui/icons-material/TimerOutlined";
|
import ScheduleIcon from "@mui/icons-material/TimerOutlined";
|
||||||
import type { Template } from "api/typesGenerated";
|
import type { Template } from "api/typesGenerated";
|
||||||
import { ExternalAvatar } from "components/Avatar/Avatar";
|
|
||||||
import {
|
import {
|
||||||
Sidebar as BaseSidebar,
|
Sidebar as BaseSidebar,
|
||||||
SidebarHeader,
|
SidebarHeader,
|
||||||
SidebarNavItem,
|
SidebarNavItem,
|
||||||
} from "components/Sidebar/Sidebar";
|
} from "components/Sidebar/Sidebar";
|
||||||
|
import { ExternalAvatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { linkToTemplate, useLinks } from "modules/navigation";
|
import { linkToTemplate, useLinks } from "modules/navigation";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ import TableRow from "@mui/material/TableRow";
|
|||||||
import { hasError, isApiValidationError } from "api/errors";
|
import { hasError, isApiValidationError } from "api/errors";
|
||||||
import type { Template, TemplateExample } from "api/typesGenerated";
|
import type { Template, TemplateExample } from "api/typesGenerated";
|
||||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||||
import { ExternalAvatar } from "components/Avatar/Avatar";
|
|
||||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||||
import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton";
|
import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton";
|
||||||
import { DeprecatedBadge } from "components/Badges/Badges";
|
import { DeprecatedBadge } from "components/Badges/Badges";
|
||||||
@ -37,6 +36,7 @@ import {
|
|||||||
TableLoaderSkeleton,
|
TableLoaderSkeleton,
|
||||||
TableRowSkeleton,
|
TableRowSkeleton,
|
||||||
} from "components/TableLoader/TableLoader";
|
} from "components/TableLoader/TableLoader";
|
||||||
|
import { ExternalAvatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { useClickableTableRow } from "hooks/useClickableTableRow";
|
import { useClickableTableRow } from "hooks/useClickableTableRow";
|
||||||
import { linkToTemplate, useLinks } from "modules/navigation";
|
import { linkToTemplate, useLinks } from "modules/navigation";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
|
@ -20,7 +20,6 @@ import type {
|
|||||||
ListUserExternalAuthResponse,
|
ListUserExternalAuthResponse,
|
||||||
} from "api/typesGenerated";
|
} from "api/typesGenerated";
|
||||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||||
import { Avatar, ExternalAvatar } from "components/Avatar/Avatar";
|
|
||||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||||
import { Loader } from "components/Loader/Loader";
|
import { Loader } from "components/Loader/Loader";
|
||||||
import {
|
import {
|
||||||
@ -31,6 +30,7 @@ import {
|
|||||||
ThreeDotsButton,
|
ThreeDotsButton,
|
||||||
} from "components/MoreMenu/MoreMenu";
|
} from "components/MoreMenu/MoreMenu";
|
||||||
import { TableEmpty } from "components/TableEmpty/TableEmpty";
|
import { TableEmpty } from "components/TableEmpty/TableEmpty";
|
||||||
|
import { Avatar, ExternalAvatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import type { ExternalAuthPollingState } from "pages/CreateWorkspacePage/CreateWorkspacePage";
|
import type { ExternalAuthPollingState } from "pages/CreateWorkspacePage/CreateWorkspacePage";
|
||||||
import { type FC, useCallback, useEffect, useState } from "react";
|
import { type FC, useCallback, useEffect, useState } from "react";
|
||||||
import { useQuery } from "react-query";
|
import { useQuery } from "react-query";
|
||||||
|
@ -7,9 +7,9 @@ import TableHead from "@mui/material/TableHead";
|
|||||||
import TableRow from "@mui/material/TableRow";
|
import TableRow from "@mui/material/TableRow";
|
||||||
import type * as TypesGen from "api/typesGenerated";
|
import type * as TypesGen from "api/typesGenerated";
|
||||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||||
import { TableLoader } from "components/TableLoader/TableLoader";
|
import { TableLoader } from "components/TableLoader/TableLoader";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
|
|
||||||
export type OAuth2ProviderPageViewProps = {
|
export type OAuth2ProviderPageViewProps = {
|
||||||
|
@ -2,7 +2,6 @@ import { useTheme } from "@emotion/react";
|
|||||||
import TableCell from "@mui/material/TableCell";
|
import TableCell from "@mui/material/TableCell";
|
||||||
import TableRow from "@mui/material/TableRow";
|
import TableRow from "@mui/material/TableRow";
|
||||||
import type { Region, WorkspaceProxy } from "api/typesGenerated";
|
import type { Region, WorkspaceProxy } from "api/typesGenerated";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||||
import {
|
import {
|
||||||
HealthyBadge,
|
HealthyBadge,
|
||||||
@ -10,6 +9,7 @@ import {
|
|||||||
NotReachableBadge,
|
NotReachableBadge,
|
||||||
NotRegisteredBadge,
|
NotRegisteredBadge,
|
||||||
} from "components/Badges/Badges";
|
} from "components/Badges/Badges";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import type { ProxyLatencyReport } from "contexts/useProxyLatency";
|
import type { ProxyLatencyReport } from "contexts/useProxyLatency";
|
||||||
import type { FC, ReactNode } from "react";
|
import type { FC, ReactNode } from "react";
|
||||||
import { getLatencyColor } from "utils/latency";
|
import { getLatencyColor } from "utils/latency";
|
||||||
|
@ -4,7 +4,6 @@ import List from "@mui/material/List";
|
|||||||
import ListItem from "@mui/material/ListItem";
|
import ListItem from "@mui/material/ListItem";
|
||||||
import TableCell from "@mui/material/TableCell";
|
import TableCell from "@mui/material/TableCell";
|
||||||
import type { Group } from "api/typesGenerated";
|
import type { Group } from "api/typesGenerated";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { OverflowY } from "components/OverflowY/OverflowY";
|
import { OverflowY } from "components/OverflowY/OverflowY";
|
||||||
import {
|
import {
|
||||||
Popover,
|
Popover,
|
||||||
@ -12,6 +11,7 @@ import {
|
|||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
} from "components/Popover/Popover";
|
} from "components/Popover/Popover";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
|
|
||||||
type GroupsCellProps = {
|
type GroupsCellProps = {
|
||||||
|
@ -6,7 +6,6 @@ import CircularProgress from "@mui/material/CircularProgress";
|
|||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import type { Template, TemplateVersion } from "api/typesGenerated";
|
import type { Template, TemplateVersion } from "api/typesGenerated";
|
||||||
import { Alert } from "components/Alert/Alert";
|
import { Alert } from "components/Alert/Alert";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||||
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog";
|
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog";
|
||||||
import type { DialogProps } from "components/Dialogs/Dialog";
|
import type { DialogProps } from "components/Dialogs/Dialog";
|
||||||
@ -14,6 +13,7 @@ import { FormFields } from "components/Form/Form";
|
|||||||
import { Loader } from "components/Loader/Loader";
|
import { Loader } from "components/Loader/Loader";
|
||||||
import { Pill } from "components/Pill/Pill";
|
import { Pill } from "components/Pill/Pill";
|
||||||
import { Stack } from "components/Stack/Stack";
|
import { Stack } from "components/Stack/Stack";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { TemplateUpdateMessage } from "modules/templates/TemplateUpdateMessage";
|
import { TemplateUpdateMessage } from "modules/templates/TemplateUpdateMessage";
|
||||||
import { type FC, useRef, useState } from "react";
|
import { type FC, useRef, useState } from "react";
|
||||||
import { createDayString } from "utils/createDayString";
|
import { createDayString } from "utils/createDayString";
|
||||||
|
@ -6,7 +6,6 @@ import Link from "@mui/material/Link";
|
|||||||
import Tooltip from "@mui/material/Tooltip";
|
import Tooltip from "@mui/material/Tooltip";
|
||||||
import { workspaceQuota } from "api/queries/workspaceQuota";
|
import { workspaceQuota } from "api/queries/workspaceQuota";
|
||||||
import type * as TypesGen from "api/typesGenerated";
|
import type * as TypesGen from "api/typesGenerated";
|
||||||
import { ExternalAvatar } from "components/Avatar/Avatar";
|
|
||||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||||
import {
|
import {
|
||||||
Topbar,
|
Topbar,
|
||||||
@ -19,6 +18,7 @@ import {
|
|||||||
import { HelpTooltipContent } from "components/HelpTooltip/HelpTooltip";
|
import { HelpTooltipContent } from "components/HelpTooltip/HelpTooltip";
|
||||||
import { Popover, PopoverTrigger } from "components/Popover/Popover";
|
import { Popover, PopoverTrigger } from "components/Popover/Popover";
|
||||||
import { UserAvatar } from "components/UserAvatar/UserAvatar";
|
import { UserAvatar } from "components/UserAvatar/UserAvatar";
|
||||||
|
import { ExternalAvatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { useDashboard } from "modules/dashboard/useDashboard";
|
import { useDashboard } from "modules/dashboard/useDashboard";
|
||||||
import { linkToTemplate, useLinks } from "modules/navigation";
|
import { linkToTemplate, useLinks } from "modules/navigation";
|
||||||
import { WorkspaceStatusBadge } from "modules/workspaces/WorkspaceStatusBadge/WorkspaceStatusBadge";
|
import { WorkspaceStatusBadge } from "modules/workspaces/WorkspaceStatusBadge/WorkspaceStatusBadge";
|
||||||
|
@ -2,12 +2,12 @@ import ParameterIcon from "@mui/icons-material/CodeOutlined";
|
|||||||
import GeneralIcon from "@mui/icons-material/SettingsOutlined";
|
import GeneralIcon from "@mui/icons-material/SettingsOutlined";
|
||||||
import ScheduleIcon from "@mui/icons-material/TimerOutlined";
|
import ScheduleIcon from "@mui/icons-material/TimerOutlined";
|
||||||
import type { Workspace } from "api/typesGenerated";
|
import type { Workspace } from "api/typesGenerated";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import {
|
import {
|
||||||
Sidebar as BaseSidebar,
|
Sidebar as BaseSidebar,
|
||||||
SidebarHeader,
|
SidebarHeader,
|
||||||
SidebarNavItem,
|
SidebarNavItem,
|
||||||
} from "components/Sidebar/Sidebar";
|
} from "components/Sidebar/Sidebar";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
|
|
||||||
interface SidebarProps {
|
interface SidebarProps {
|
||||||
|
@ -3,7 +3,6 @@ import OpenIcon from "@mui/icons-material/OpenInNewOutlined";
|
|||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import Link from "@mui/material/Link";
|
import Link from "@mui/material/Link";
|
||||||
import type { Template } from "api/typesGenerated";
|
import type { Template } from "api/typesGenerated";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { Loader } from "components/Loader/Loader";
|
import { Loader } from "components/Loader/Loader";
|
||||||
import { MenuSearch } from "components/Menu/MenuSearch";
|
import { MenuSearch } from "components/Menu/MenuSearch";
|
||||||
import { OverflowY } from "components/OverflowY/OverflowY";
|
import { OverflowY } from "components/OverflowY/OverflowY";
|
||||||
@ -13,6 +12,7 @@ import {
|
|||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
} from "components/Popover/Popover";
|
} from "components/Popover/Popover";
|
||||||
import { SearchEmpty, searchStyles } from "components/Search/Search";
|
import { SearchEmpty, searchStyles } from "components/Search/Search";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { linkToTemplate, useLinks } from "modules/navigation";
|
import { linkToTemplate, useLinks } from "modules/navigation";
|
||||||
import { type FC, type ReactNode, useState } from "react";
|
import { type FC, type ReactNode, useState } from "react";
|
||||||
import type { UseQueryResult } from "react-query";
|
import type { UseQueryResult } from "react-query";
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import ArrowForwardOutlined from "@mui/icons-material/ArrowForwardOutlined";
|
import ArrowForwardOutlined from "@mui/icons-material/ArrowForwardOutlined";
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import type { Template } from "api/typesGenerated";
|
import type { Template } from "api/typesGenerated";
|
||||||
import { Avatar } from "components/Avatar/Avatar";
|
|
||||||
import { TableEmpty } from "components/TableEmpty/TableEmpty";
|
import { TableEmpty } from "components/TableEmpty/TableEmpty";
|
||||||
|
import { Avatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { linkToTemplate, useLinks } from "modules/navigation";
|
import { linkToTemplate, useLinks } from "modules/navigation";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
@ -11,7 +11,6 @@ import TableHead from "@mui/material/TableHead";
|
|||||||
import TableRow from "@mui/material/TableRow";
|
import TableRow from "@mui/material/TableRow";
|
||||||
import { visuallyHidden } from "@mui/utils";
|
import { visuallyHidden } from "@mui/utils";
|
||||||
import type { Template, Workspace } from "api/typesGenerated";
|
import type { Template, Workspace } from "api/typesGenerated";
|
||||||
import { ExternalAvatar } from "components/Avatar/Avatar";
|
|
||||||
import { AvatarData } from "components/AvatarData/AvatarData";
|
import { AvatarData } from "components/AvatarData/AvatarData";
|
||||||
import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton";
|
import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton";
|
||||||
import { InfoTooltip } from "components/InfoTooltip/InfoTooltip";
|
import { InfoTooltip } from "components/InfoTooltip/InfoTooltip";
|
||||||
@ -20,6 +19,7 @@ import {
|
|||||||
TableLoaderSkeleton,
|
TableLoaderSkeleton,
|
||||||
TableRowSkeleton,
|
TableRowSkeleton,
|
||||||
} from "components/TableLoader/TableLoader";
|
} from "components/TableLoader/TableLoader";
|
||||||
|
import { ExternalAvatar } from "components/deprecated/Avatar/Avatar";
|
||||||
import { useClickableTableRow } from "hooks/useClickableTableRow";
|
import { useClickableTableRow } from "hooks/useClickableTableRow";
|
||||||
import { useDashboard } from "modules/dashboard/useDashboard";
|
import { useDashboard } from "modules/dashboard/useDashboard";
|
||||||
import { WorkspaceDormantBadge } from "modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge";
|
import { WorkspaceDormantBadge } from "modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge";
|
||||||
|
Reference in New Issue
Block a user