Improve link preview look and feel (#33981)

* Update link previews to match design

* Preview updates

* snap update for pw

* Retain tall image snap

* Move icon to the right.

* cleanup

* Fix bubbles

* resnappening
This commit is contained in:
Will Hunt
2026-06-29 18:50:20 +00:00
committed by GitHub
parent 3e40e58b12
commit 6ce24e2668
25 changed files with 192 additions and 195 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 170 KiB

@@ -6,20 +6,22 @@
*/
button.preview {
background: #fff;
background-color: #fff;
}
.preview {
display: flex;
position: relative;
width: 100%;
max-width: 100%;
width: 478px;
height: 200px;
background-size: cover;
background-position: center;
border: none;
padding: 0;
> img {
width: 100%;
height: 200px;
width: 478px;
object-fit: cover;
}
.playButton[data-kind="primary"] {
@@ -37,9 +39,10 @@ button.preview {
}
.container {
max-width: 478px;
max-width: 100%;
width: 478px;
display: flex;
border: 1px solid var(--cpd-color-bg-subtle-secondary);
border: 1px solid var(--cpd-color-border-interactive-primary);
border-radius: 12px; /* Get radius from cpd */
flex-direction: column;
color: var(--cpd-color-gray-900);
@@ -87,29 +90,20 @@ button.preview {
.title,
.description {
display: inline-block;
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
white-space: normal;
line-clamp: 2;
-webkit-line-clamp: 2;
margin: 0;
}
.title {
display: inline-block;
line-clamp: 2;
-webkit-line-clamp: 2;
color: var(--cpd-color-text-primary);
text-decoration-line: none;
}
.description {
margin: 0;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
line-clamp: 2;
overflow: hidden;
}
.siteName {
margin-top: var(--cpd-space-1x);
vertical-align: middle;
@@ -13,6 +13,7 @@ import { LinkPreview } from "./LinkPreview";
import { LinkedTextContext } from "../../../../../core/utils/LinkedText";
import imageFile from "../../../../../../static/element.png";
import imageFileWide from "../../../../../../static/wideImage.png";
import imageFileTall from "../../../../../../static/tallImage.png";
export default {
title: "EventTiles/LinkPreview",
@@ -167,3 +168,17 @@ WithVeryLongText.args = {
playable: false,
},
};
export const WithTallImage = Template.bind({});
WithTallImage.args = {
title: "A simple title",
description: "A simple description",
link: "https://matrix.org",
siteName: "Site name",
image: {
imageThumb: imageFileTall,
imageFull: imageFileTall,
alt: "Element logo",
playable: false,
},
};
@@ -135,12 +135,13 @@ export function LinkPreview({ onImageClick, ...preview }: LinkPreviewProps): JSX
// Otherwise, the preview can be clicked on.
img = (
<button
style={{
backgroundImage: `url('${preview.image.imageThumb}')`,
}}
className={styles.preview}
onClick={onImageClickHandler}
aria-label={_t("timeline|url_preview|view_image")}
>
<img src={preview.image.imageThumb} alt={preview.image.alt} title={preview.image.alt} />
</button>
/>
);
}
}
@@ -71,13 +71,8 @@ exports[`LinkPreview > renders a preview 1`] = `
<button
aria-label="View image"
class="LinkPreview-module_preview"
>
<img
alt="Element logo"
src="/static/element.png"
title="Element logo"
/>
</button>
style="background-image: url("/static/element.png");"
/>
<div
class="LinkPreview-module_textContent"
>
@@ -5,13 +5,20 @@
* Please see LICENSE files in the repository root for full details.
*/
.hideButton {
position: absolute;
top: var(--cpd-space-2x);
right: var(--cpd-space-2x);
z-index: 1;
}
.wrapper {
margin-top: var(--cpd-space-4x);
display: flex;
flex-direction: row;
position: relative;
width: fit-content;
max-width: 100%;
.previewGroup {
flex: 1;
display: flex;
flex-direction: column;
gap: var(--cpd-space-4x);
@@ -54,6 +54,22 @@ export interface UrlPreviewGroupViewActions {
/** View model contract for the URL preview group view. */
export type UrlPreviewGroupViewModel = ViewModel<UrlPreviewGroupViewSnapshot, UrlPreviewGroupViewActions>;
function HideButton({ onHideClick }: { onHideClick: UrlPreviewGroupViewActions["onHideClick"] }): JSX.Element {
const { translate: _t } = useI18n();
return (
<div className={styles.hideButton}>
<IconButton
kind="secondary"
size="28px"
onClick={onHideClick}
aria-label={_t("timeline|url_preview|close")}
>
<CloseIcon />
</IconButton>
</div>
);
}
/**
* Renders the URL preview group attached to a single event.
*
@@ -81,20 +97,13 @@ export function UrlPreviewGroupView({ vm, className }: UrlPreviewGroupViewProps)
return (
<div className={classNames(className, styles.wrapper)} {...eventPresentationAttributes}>
<HideButton onHideClick={vm.onHideClick} />
<div className={styles.previewGroup}>
{previews.map((preview) => (
<LinkPreview key={preview.link} onImageClick={() => vm.onImageClick(preview)} {...preview} />
))}
{toggleButton}
</div>
<IconButton
kind="secondary"
size="28px"
onClick={vm.onHideClick}
aria-label={_t("timeline|url_preview|close")}
>
<CloseIcon />
</IconButton>
</div>
);
}
@@ -7,6 +7,35 @@ exports[`UrlPreviewGroupView > renders a single preview 1`] = `
data-event-density="default"
data-event-layout="group"
>
<div
class="UrlPreviewGroupView-module_hideButton"
>
<button
aria-label="Close preview"
class="_icon-button_1215g_8"
data-kind="secondary"
role="button"
style="--cpd-icon-button-size: 28px;"
tabindex="0"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.293 6.293a1 1 0 0 1 1.414 0L12 10.586l4.293-4.293a1 1 0 1 1 1.414 1.414L13.414 12l4.293 4.293a1 1 0 0 1-1.414 1.414L12 13.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L10.586 12 6.293 7.707a1 1 0 0 1 0-1.414"
/>
</svg>
</div>
</button>
</div>
<div
class="UrlPreviewGroupView-module_previewGroup"
>
@@ -16,13 +45,8 @@ exports[`UrlPreviewGroupView > renders a single preview 1`] = `
<button
aria-label="View image"
class="LinkPreview-module_preview"
>
<img
alt="The element logo"
src="/static/element.png"
title="The element logo"
/>
</button>
style="background-image: url("/static/element.png");"
/>
<div
class="LinkPreview-module_textContent"
>
@@ -51,31 +75,6 @@ exports[`UrlPreviewGroupView > renders a single preview 1`] = `
</div>
</div>
</div>
<button
aria-label="Close preview"
class="_icon-button_1215g_8"
data-kind="secondary"
role="button"
style="--cpd-icon-button-size: 28px;"
tabindex="0"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.293 6.293a1 1 0 0 1 1.414 0L12 10.586l4.293-4.293a1 1 0 1 1 1.414 1.414L13.414 12l4.293 4.293a1 1 0 0 1-1.414 1.414L12 13.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L10.586 12 6.293 7.707a1 1 0 0 1 0-1.414"
/>
</svg>
</div>
</button>
</div>
</div>
`;
@@ -87,6 +86,35 @@ exports[`UrlPreviewGroupView > renders multiple previews 1`] = `
data-event-density="default"
data-event-layout="group"
>
<div
class="UrlPreviewGroupView-module_hideButton"
>
<button
aria-label="Close preview"
class="_icon-button_1215g_8"
data-kind="secondary"
role="button"
style="--cpd-icon-button-size: 28px;"
tabindex="0"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.293 6.293a1 1 0 0 1 1.414 0L12 10.586l4.293-4.293a1 1 0 1 1 1.414 1.414L13.414 12l4.293 4.293a1 1 0 0 1-1.414 1.414L12 13.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L10.586 12 6.293 7.707a1 1 0 0 1 0-1.414"
/>
</svg>
</div>
</button>
</div>
<div
class="UrlPreviewGroupView-module_previewGroup"
>
@@ -96,13 +124,8 @@ exports[`UrlPreviewGroupView > renders multiple previews 1`] = `
<button
aria-label="View image"
class="LinkPreview-module_preview"
>
<img
alt="The element logo"
src="/static/element.png"
title="The element logo"
/>
</button>
style="background-image: url("/static/element.png");"
/>
<div
class="LinkPreview-module_textContent"
>
@@ -136,13 +159,8 @@ exports[`UrlPreviewGroupView > renders multiple previews 1`] = `
<button
aria-label="View image"
class="LinkPreview-module_preview"
>
<img
alt="A dog"
src="/static/tallImage.png"
title="A dog"
/>
</button>
style="background-image: url("/static/tallImage.png");"
/>
<div
class="LinkPreview-module_textContent"
>
@@ -176,13 +194,8 @@ exports[`UrlPreviewGroupView > renders multiple previews 1`] = `
<button
aria-label="View image"
class="LinkPreview-module_preview"
>
<img
alt="The element logo"
src="/static/element.png"
title="The element logo"
/>
</button>
style="background-image: url("/static/element.png");"
/>
<div
class="LinkPreview-module_textContent"
>
@@ -220,31 +233,6 @@ exports[`UrlPreviewGroupView > renders multiple previews 1`] = `
Collapse
</button>
</div>
<button
aria-label="Close preview"
class="_icon-button_1215g_8"
data-kind="secondary"
role="button"
style="--cpd-icon-button-size: 28px;"
tabindex="0"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.293 6.293a1 1 0 0 1 1.414 0L12 10.586l4.293-4.293a1 1 0 1 1 1.414 1.414L13.414 12l4.293 4.293a1 1 0 0 1-1.414 1.414L12 13.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L10.586 12 6.293 7.707a1 1 0 0 1 0-1.414"
/>
</svg>
</div>
</button>
</div>
</div>
`;
@@ -256,6 +244,35 @@ exports[`UrlPreviewGroupView > renders multiple previews which are hidden 1`] =
data-event-density="default"
data-event-layout="group"
>
<div
class="UrlPreviewGroupView-module_hideButton"
>
<button
aria-label="Close preview"
class="_icon-button_1215g_8"
data-kind="secondary"
role="button"
style="--cpd-icon-button-size: 28px;"
tabindex="0"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.293 6.293a1 1 0 0 1 1.414 0L12 10.586l4.293-4.293a1 1 0 1 1 1.414 1.414L13.414 12l4.293 4.293a1 1 0 0 1-1.414 1.414L12 13.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L10.586 12 6.293 7.707a1 1 0 0 1 0-1.414"
/>
</svg>
</div>
</button>
</div>
<div
class="UrlPreviewGroupView-module_previewGroup"
>
@@ -265,13 +282,8 @@ exports[`UrlPreviewGroupView > renders multiple previews which are hidden 1`] =
<button
aria-label="View image"
class="LinkPreview-module_preview"
>
<img
alt="The element logo"
src="/static/element.png"
title="The element logo"
/>
</button>
style="background-image: url("/static/element.png");"
/>
<div
class="LinkPreview-module_textContent"
>
@@ -309,31 +321,6 @@ exports[`UrlPreviewGroupView > renders multiple previews which are hidden 1`] =
Show 9 other previews
</button>
</div>
<button
aria-label="Close preview"
class="_icon-button_1215g_8"
data-kind="secondary"
role="button"
style="--cpd-icon-button-size: 28px;"
tabindex="0"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.293 6.293a1 1 0 0 1 1.414 0L12 10.586l4.293-4.293a1 1 0 1 1 1.414 1.414L13.414 12l4.293 4.293a1 1 0 0 1-1.414 1.414L12 13.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L10.586 12 6.293 7.707a1 1 0 0 1 0-1.414"
/>
</svg>
</div>
</button>
</div>
</div>
`;
@@ -345,6 +332,35 @@ exports[`UrlPreviewGroupView > renders with compact density 1`] = `
data-event-density="compact"
data-event-layout="group"
>
<div
class="UrlPreviewGroupView-module_hideButton"
>
<button
aria-label="Close preview"
class="_icon-button_1215g_8"
data-kind="secondary"
role="button"
style="--cpd-icon-button-size: 28px;"
tabindex="0"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.293 6.293a1 1 0 0 1 1.414 0L12 10.586l4.293-4.293a1 1 0 1 1 1.414 1.414L13.414 12l4.293 4.293a1 1 0 0 1-1.414 1.414L12 13.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L10.586 12 6.293 7.707a1 1 0 0 1 0-1.414"
/>
</svg>
</div>
</button>
</div>
<div
class="UrlPreviewGroupView-module_previewGroup"
>
@@ -354,13 +370,8 @@ exports[`UrlPreviewGroupView > renders with compact density 1`] = `
<button
aria-label="View image"
class="LinkPreview-module_preview"
>
<img
alt="The element logo"
src="/static/element.png"
title="The element logo"
/>
</button>
style="background-image: url("/static/element.png");"
/>
<div
class="LinkPreview-module_textContent"
>
@@ -394,13 +405,8 @@ exports[`UrlPreviewGroupView > renders with compact density 1`] = `
<button
aria-label="View image"
class="LinkPreview-module_preview"
>
<img
alt="A dog"
src="/static/tallImage.png"
title="A dog"
/>
</button>
style="background-image: url("/static/tallImage.png");"
/>
<div
class="LinkPreview-module_textContent"
>
@@ -434,13 +440,8 @@ exports[`UrlPreviewGroupView > renders with compact density 1`] = `
<button
aria-label="View image"
class="LinkPreview-module_preview"
>
<img
alt="The element logo"
src="/static/element.png"
title="The element logo"
/>
</button>
style="background-image: url("/static/element.png");"
/>
<div
class="LinkPreview-module_textContent"
>
@@ -478,31 +479,6 @@ exports[`UrlPreviewGroupView > renders with compact density 1`] = `
Collapse
</button>
</div>
<button
aria-label="Close preview"
class="_icon-button_1215g_8"
data-kind="secondary"
role="button"
style="--cpd-icon-button-size: 28px;"
tabindex="0"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.293 6.293a1 1 0 0 1 1.414 0L12 10.586l4.293-4.293a1 1 0 1 1 1.414 1.414L13.414 12l4.293 4.293a1 1 0 0 1-1.414 1.414L12 13.414l-4.293 4.293a1 1 0 0 1-1.414-1.414L10.586 12 6.293 7.707a1 1 0 0 1 0-1.414"
/>
</svg>
</div>
</button>
</div>
</div>
`;