diff --git a/package.json b/package.json index adc6362b8a1..fd3fd03518a 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "@sentry/tracing": "^7.0.0", "@testing-library/react-hooks": "^8.0.1", "@vector-im/compound-design-tokens": "^0.0.3", - "@vector-im/compound-web": "^0.2.3", + "@vector-im/compound-web": "^0.2.4", "await-lock": "^2.1.0", "blurhash": "^1.1.3", "classnames": "^2.2.6", diff --git a/res/css/views/avatars/_BaseAvatar.pcss b/res/css/views/avatars/_BaseAvatar.pcss index 70c41d0b251..5d0ece53bee 100644 --- a/res/css/views/avatars/_BaseAvatar.pcss +++ b/res/css/views/avatars/_BaseAvatar.pcss @@ -14,57 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_BaseAvatar { - position: relative; - /* In at least Firefox, the case of relative positioned inline elements */ - /* (such as mx_BaseAvatar) with absolute positioned children (such as */ - /* mx_BaseAvatar_initial) is a dark corner full of spider webs. It will give */ - /* different results during full reflow of the page vs. incremental reflow */ - /* of small portions. While that's surely a browser bug, we can avoid it by */ - /* using `inline-block` instead of the default `inline`. */ - /* https://github.com/vector-im/element-web/issues/5594 */ - /* https://bugzilla.mozilla.org/show_bug.cgi?id=1535053 */ - /* https://bugzilla.mozilla.org/show_bug.cgi?id=255139 */ - display: inline-block; - user-select: none; - - &.mx_RoomAvatar_isSpaceRoom { - &.mx_BaseAvatar_image, - .mx_BaseAvatar_image { - border-radius: 8px; - } - } -} - -.mx_BaseAvatar_initial { - position: absolute; - left: 0; - color: $avatar-initial-color; - text-align: center; - speak: none; - pointer-events: none; - font-weight: normal; -} - -.mx_BaseAvatar_image { - object-fit: cover; - aspect-ratio: 1; - border-radius: 125px; - vertical-align: top; - background-color: $background; -} - /* Percy screenshot test specific CSS */ @media only percy { /* Stick the default room avatar colour, so it doesn't cause a false diff on the screenshot */ - .mx_BaseAvatar_initial { + .mx_BaseAvatar { background-color: var(--percy-color-avatar) !important; - border-radius: 125px; - } - .mx_RoomAvatar_isSpaceRoom .mx_BaseAvatar_initial { - border-radius: 8px; - } - .mx_BaseAvatar_initial + .mx_BaseAvatar_image { - visibility: hidden; } } diff --git a/res/css/views/avatars/_DecoratedRoomAvatar.pcss b/res/css/views/avatars/_DecoratedRoomAvatar.pcss index a0770c3ca0b..a2ad52a90fa 100644 --- a/res/css/views/avatars/_DecoratedRoomAvatar.pcss +++ b/res/css/views/avatars/_DecoratedRoomAvatar.pcss @@ -29,9 +29,9 @@ limitations under the License. .mx_DecoratedRoomAvatar_icon { position: absolute; /* the following percentage based sizings are to match the scalable svg mask for the cutout */ - bottom: -6.25%; - right: -6.25%; - margin: 12.5%; + bottom: 0; + right: 0; + transform: translate(-25%, -70%); width: 25%; height: 25%; border-radius: 50%; diff --git a/src/components/views/avatars/BaseAvatar.tsx b/src/components/views/avatars/BaseAvatar.tsx index e96bf1333a4..8d879fe709d 100644 --- a/src/components/views/avatars/BaseAvatar.tsx +++ b/src/components/views/avatars/BaseAvatar.tsx @@ -20,33 +20,36 @@ limitations under the License. import React, { useCallback, useContext, useEffect, useState } from "react"; import classNames from "classnames"; import { ResizeMethod, ClientEvent } from "matrix-js-sdk/src/matrix"; +import { Avatar } from "@vector-im/compound-web"; -import * as AvatarLogic from "../../../Avatar"; import SettingsStore from "../../../settings/SettingsStore"; -import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton"; +import { ButtonEvent } from "../elements/AccessibleButton"; import RoomContext from "../../../contexts/RoomContext"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import { useTypedEventEmitter } from "../../../hooks/useEventEmitter"; -import { toPx } from "../../../utils/units"; import { _t } from "../../../languageHandler"; interface IProps { - name?: string; // The name (first initial used as default) - idName?: string; // ID for generating hash colours + name?: React.ComponentProps["name"]; // The name (first initial used as default) + idName?: React.ComponentProps["id"]; // ID for generating hash colours title?: string; // onHover title text url?: string | null; // highest priority of them all, shortcut to set in urls[0] urls?: string[]; // [highest_priority, ... , lowest_priority] + type?: React.ComponentProps["type"]; width: number; + /** + * @deprecated use `width` only, avatars have a 1:1 aspect ratio + */ height: number; - // XXX: resizeMethod not actually used. + /** + * @deprecated only uses `crop` + */ resizeMethod?: ResizeMethod; - defaultToInitialLetter?: boolean; // true to add default url onClick?: (ev: ButtonEvent) => void; - inputRef?: React.RefObject; + inputRef?: React.RefObject; className?: string; tabIndex?: number; altText?: string; - ariaLabel?: string; } const calculateUrls = (url?: string | null, urls?: string[], lowBandwidth = false): string[] => { @@ -108,119 +111,32 @@ const BaseAvatar: React.FC = (props) => { url, urls, width = 40, - height = 40, resizeMethod = "crop", // eslint-disable-line @typescript-eslint/no-unused-vars - defaultToInitialLetter = true, onClick, inputRef, className, + type = "round", altText = _t("Avatar"), - ariaLabel = _t("Avatar"), ...otherProps } = props; const [imageUrl, onError] = useImageUrl({ url, urls }); - if (!imageUrl && defaultToInitialLetter && name) { - const initialLetter = AvatarLogic.getInitialLetter(name); - const textNode = ( - - ); - const imgNode = ( - - ); - - if (onClick) { - return ( - - {textNode} - {imgNode} - - ); - } else { - return ( - - {textNode} - {imgNode} - - ); - } - } - - if (onClick) { - return ( - - ); - } else { - return ( - - ); - } + return ( + + ); }; export default BaseAvatar; diff --git a/src/components/views/avatars/MemberAvatar.tsx b/src/components/views/avatars/MemberAvatar.tsx index 6546a0ff4ef..09ae13ba380 100644 --- a/src/components/views/avatars/MemberAvatar.tsx +++ b/src/components/views/avatars/MemberAvatar.tsx @@ -104,7 +104,6 @@ export default function MemberAvatar({ : props.onClick } altText={_t("Profile picture")} - ariaLabel={_t("Profile picture")} /> ); } diff --git a/src/components/views/avatars/RoomAvatar.tsx b/src/components/views/avatars/RoomAvatar.tsx index 85a2d4929cc..9d08fed198f 100644 --- a/src/components/views/avatars/RoomAvatar.tsx +++ b/src/components/views/avatars/RoomAvatar.tsx @@ -16,7 +16,6 @@ limitations under the License. import React, { ComponentProps } from "react"; import { Room, RoomStateEvent, MatrixEvent, EventType, RoomType } from "matrix-js-sdk/src/matrix"; -import classNames from "classnames"; import BaseAvatar from "./BaseAvatar"; import ImageView from "../elements/ImageView"; @@ -140,9 +139,7 @@ export default class RoomAvatar extends React.Component { return ( { className="mx_RoomAvatarEvent_avatar" onClick={this.onAvatarClick} > - + ), }, diff --git a/yarn.lock b/yarn.lock index 3d0f5319bd1..1ffb2cb3e3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1265,7 +1265,14 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.6", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.9", "@babel/runtime@^7.20.7", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.9", "@babel/runtime@^7.20.7", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" + integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/runtime@^7.13.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682" integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ== @@ -2886,14 +2893,15 @@ dependencies: svg2vectordrawable "^2.9.1" -"@vector-im/compound-web@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@vector-im/compound-web/-/compound-web-0.2.3.tgz#9dd4ed80109c614666103d05cd66723d1fad4d6c" - integrity sha512-7FI6Q1LN8dXur2sarP7UeMtAKcejuFw6AppM9Lu9fFjwLlbuIX2ZEprw1qa+EzgzUTysTU1TTdo7fxNqQwAQcA== +"@vector-im/compound-web@^0.2.4": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@vector-im/compound-web/-/compound-web-0.2.7.tgz#146b353af0625b450616309d7c1cd8635cdd1bde" + integrity sha512-rqC6jcyKdNKnroqwN9GdmrmyBp0LEarzXkuucVPmCzsXZg5vSRo751oNngGQuDYx49ywLbKlv+B1/mgdCqC1Jw== dependencies: "@radix-ui/react-form" "^0.0.3" classnames "^2.3.2" - lodash "^4.17.21" + graphemer "^1.4.0" + rimraf "^3.0.1" abab@^2.0.6: version "2.0.6" @@ -8133,10 +8141,15 @@ regenerator-runtime@^0.14.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== -regenerator-transform@^0.15.2: - version "0.15.2" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" - integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + +regenerator-transform@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" + integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== dependencies: "@babel/runtime" "^7.8.4" @@ -8291,7 +8304,7 @@ rfdc@^1.3.0: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@^3.0.0, rimraf@^3.0.1, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==