Skip to content

Commit ccc11c8

Browse files
authored
Merge pull request #2222 from tf/teaser-list-buttons
Add display buttons option for external links
2 parents 148f0af + f2d72ca commit ccc11c8

File tree

12 files changed

+186
-65
lines changed

12 files changed

+186
-65
lines changed

Diff for: entry_types/scrolled/config/locales/new/ext-link-options.de.yml

+4
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,7 @@ de:
6868
small: Klein
6969
medium: Mittel
7070
large: Groß
71+
displayButtons:
72+
label: "Buttons anzeigen"
73+
inline_help: |-
74+
Zeige Buttons an, um die Links zu öffnen.

Diff for: entry_types/scrolled/config/locales/new/ext-link-options.en.yml

+4
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,7 @@ en:
6666
small: Small
6767
medium: Medium
6868
large: Large
69+
displayButtons:
70+
label: "Display buttons"
71+
inline_help: |-
72+
Display buttons to open the links.

Diff for: entry_types/scrolled/package/src/contentElements/externalLinkList/editor/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {editor} from 'pageflow-scrolled/editor';
22
import {features} from 'pageflow/frontend';
3-
import {SelectInputView, SliderInputView, SeparatorView} from 'pageflow/ui';
3+
import {SelectInputView, SliderInputView, SeparatorView, CheckBoxInputView} from 'pageflow/ui';
44

55
import {SidebarRouter} from './SidebarRouter';
66
import {SidebarController} from './SidebarController';
@@ -81,6 +81,7 @@ editor.contentElementTypes.register('externalLinkList', {
8181
this.input('textSize', SelectInputView, {
8282
values: ['small', 'medium', 'large']
8383
});
84+
this.input('displayButtons', CheckBoxInputView);
8485
});
8586
}
8687
});

Diff for: entry_types/scrolled/package/src/contentElements/externalLinkList/frontend/ExternalLink.js

+19-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
useContentElementConfigurationUpdate,
1212
useContentElementEditorState,
1313
useI18n,
14-
utils
14+
utils,
15+
LinkButton
1516
} from 'pageflow-scrolled/frontend';
1617

1718
import {Thumbnail} from './Thumbnail';
@@ -89,21 +90,21 @@ export function ExternalLink({id, configuration, ...props}) {
8990
return (
9091
<li className={classNames(styles.item,
9192
styles[`textPosition-${props.textPosition}`],
92-
{[styles.link]: !!href},
93+
{[styles.link]: !!href && !configuration.displayButtons},
9394
{[styles.outlined]: props.outlined},
9495
{[styles.highlighted]: props.highlighted},
9596
{[styles.selected]: props.selected})}
9697
onClick={props.onClick}>
97-
<Link isEditable={isEditable}
98+
<Link isEnabled={!configuration.displayButtons}
99+
isEditable={isEditable}
98100
actionButtonVisible={props.selected}
99101
href={href}
100102
openInNewTab={openInNewTab}
101103
onChange={handleLinkChange}>
102104
<div className={classNames(
103105
styles.card,
104-
styles[`thumbnailSize-${props.thumbnailSize}`],
105-
{[styles.invert]: props.invert
106-
})}>
106+
styles[`thumbnailSize-${props.thumbnailSize}`]
107+
)}>
107108
<div className={styles.thumbnail}>
108109
<Thumbnail imageFile={thumbnailImageFile}
109110
aspectRatio={props.thumbnailAspectRatio}
@@ -112,7 +113,8 @@ export function ExternalLink({id, configuration, ...props}) {
112113
<InlineFileRights context="insideElement" items={[{file: thumbnailImageFile, label: 'image'}]} />
113114
</Thumbnail>
114115
</div>
115-
<div className={styles.background}
116+
<div className={classNames(styles.background,
117+
props.darkBackground ? styles.light : styles.dark)}
116118
style={{pointerEvents: !isEditable || isSelected ? undefined : 'none'}}>
117119
<InlineFileRights context="afterElement" items={[{file: thumbnailImageFile, label: 'image'}]} />
118120
<div className={styles.details}>
@@ -134,6 +136,14 @@ export function ExternalLink({id, configuration, ...props}) {
134136
placeholder={t('pageflow_scrolled.inline_editing.type_text')}
135137
onChange={value => handleTextChange('description', value)} />
136138
</div>}
139+
{configuration.displayButtons && presentOrEditing('link') &&
140+
<LinkButton href={href}
141+
openInNewTab={openInNewTab}
142+
value={itemTexts[id]?.link}
143+
linkPreviewDisabled={true}
144+
actionButtonVisible={false}
145+
onTextChange={value => handleTextChange('link', value)}
146+
onLinkChange={value => handleLinkChange(value)} />}
137147
</div>
138148
</div>
139149
</div>
@@ -142,8 +152,8 @@ export function ExternalLink({id, configuration, ...props}) {
142152
);
143153
}
144154

145-
function Link(props) {
146-
if (props.href || props.isEditable) {
155+
function Link({isEnabled, isEditable, ...props}) {
156+
if ((isEnabled && props.href) || isEditable) {
147157
return (
148158
<EditableLink {...props}
149159
actionButtonVisible={props.actionButtonVisible}

Diff for: entry_types/scrolled/package/src/contentElements/externalLinkList/frontend/ExternalLink.module.css

+12-7
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,27 @@
8383
width: 100%;
8484
}
8585

86-
.background {
87-
--padding-inline: var(--theme-external-links-card-padding-inline, 15px);
86+
.light {
87+
composes: scope-darkContent from global;
8888
--content-text-color: var(--theme-external-links-card-text-color, darkContentTextColor);
8989
--card-surface-color: var(--theme-external-links-card-surface-color, lightContentSurfaceColor);
90+
}
91+
92+
.dark {
93+
composes: scope-lightContent from global;
94+
--content-text-color: var(--theme-external-links-card-text-color, lightContentTextColor);
95+
--card-surface-color: var(--theme-external-links-card-surface-color, darkContentSurfaceColor);
96+
}
97+
98+
.background {
99+
--padding-inline: var(--theme-external-links-card-padding-inline, 15px);
90100
color: var(--content-text-color);
91101
background-color: var(--card-surface-color);
92102
flex: 1;
93103
padding-left: min(var(--padding-inline), 5px);
94104
padding-right: min(var(--padding-inline), 5px);
95105
}
96106

97-
.invert > .background {
98-
--card-surface-color: var(--theme-external-links-card-surface-color, darkContentSurfaceColor);
99-
--content-text-color: var(--theme-external-links-card-text-color, lightContentTextColor);
100-
}
101-
102107
.textPosition-overlay .background {
103108
position: absolute;
104109
bottom: 0;

Diff for: entry_types/scrolled/package/src/contentElements/externalLinkList/frontend/ExternalLinkList.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export function ExternalLinkList(props) {
9898
thumbnailSize={props.configuration.thumbnailSize || 'small'}
9999
textPosition={props.configuration.textPosition || 'below'}
100100
textSize={props.configuration.textSize || 'small'}
101-
invert={!darkBackground}
101+
darkBackground={darkBackground}
102102
loadImages={shouldLoad}
103103
outlined={isSelected}
104104
highlighted={highlightedIndex === index}

Diff for: entry_types/scrolled/package/src/contentElements/externalLinkList/stories.js

+36
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,42 @@ storiesOfContentElement(module, {
160160
]
161161
},
162162
},
163+
{
164+
name: 'With buttons',
165+
configuration: {
166+
displayButtons: true,
167+
itemTexts: {
168+
1: {
169+
title: editableTextValue('Item 1'),
170+
description: editableTextValue('This is description'),
171+
link: editableTextValue('Read more')
172+
},
173+
2: {
174+
title: editableTextValue('Item 2'),
175+
description: editableTextValue('This is another description'),
176+
link: editableTextValue('Read more')
177+
}
178+
},
179+
itemLinks: {
180+
1: {
181+
href: 'https://www.pageflow.io/'
182+
},
183+
2: {
184+
href: 'https://www.pageflow.io/'
185+
}
186+
},
187+
links: [
188+
{
189+
id: '1',
190+
thumbnail: filePermaId('imageFiles', 'turtle')
191+
},
192+
{
193+
id: '2',
194+
thumbnail: filePermaId('imageFiles', 'turtle')
195+
}
196+
]
197+
}
198+
},
163199
{
164200
name: 'With legacy external links',
165201
configuration: {

Diff for: entry_types/scrolled/package/src/contentElements/hotspots/Tooltip.js

+10-15
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import {
2525
useDarkBackground,
2626
useFileWithInlineRights,
2727
useI18n,
28-
utils
28+
utils,
29+
LinkButton
2930
} from 'pageflow-scrolled/frontend';
3031

3132
import {getTooltipInlineStyles} from './getTooltipInlineStyles';
@@ -177,8 +178,7 @@ export function Tooltip({
177178
styles[`maxWidth-${maxWidth}`],
178179
styles[`align-${area.tooltipTextAlign}`],
179180
light ? styles.light : styles.dark,
180-
{[styles.editable]: isEditable,
181-
[styles.paddingForScrollButtons]: keepInViewport,
181+
{[styles.paddingForScrollButtons]: keepInViewport,
182182
[styles.minWidth]: presentOrEditing('link')})}
183183
onMouseEnter={onMouseEnter}
184184
onMouseLeave={onMouseLeave}
@@ -214,18 +214,13 @@ export function Tooltip({
214214
scaleCategory="hotspotsTooltipDescription"
215215
placeholder={t('pageflow_scrolled.inline_editing.type_text')} />}
216216
{presentOrEditing('link') &&
217-
<Text inline scaleCategory="hotspotsTooltipLink">
218-
<EditableLink href={tooltipLinks[area.id]?.href}
219-
openInNewTab={tooltipLinks[area.id]?.openInNewTab}
220-
linkPreviewDisabled={utils.isBlankEditableTextValue(tooltipTexts[area.id]?.link)}
221-
className={styles.link}
222-
onChange={value => handleLinkChange(value)}>
223-
<EditableInlineText value={tooltipTexts[area.id]?.link}
224-
onChange={value => handleTextChange('link', value)}
225-
placeholder={t('pageflow_scrolled.inline_editing.type_text')} />
226-
227-
</EditableLink>
228-
</Text>}
217+
<LinkButton className={styles.link}
218+
scaleCategory="hotspotsTooltipLink"
219+
href={tooltipLinks[area.id]?.href}
220+
openInNewTab={tooltipLinks[area.id]?.openInNewTab}
221+
value={tooltipTexts[area.id]?.link}
222+
onTextChange={value => handleTextChange('link', value)}
223+
onLinkChange={value => handleLinkChange(value)} />}
229224
</div>
230225
</div>
231226
</div>

Diff for: entry_types/scrolled/package/src/contentElements/hotspots/Tooltip.module.css

+3-32
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,17 @@
4747
}
4848

4949
.light {
50+
composes: scope-darkContent from global;
5051
background-color: lightContentSurfaceColor;
5152
color: darkContentTextColor;
5253
--content-text-color: darkContentTextColor;
5354
--content-link-color: darkContentLinkColor;
5455
box-shadow: 0px 3px 3px -2px rgba(0,0,0,0.2), 0px 3px 4px 0px rgba(0,0,0,0.14), 0px 1px 8px 0px rgba(0,0,0,0.12);
56+
--theme-link-button-on-surface-color: var(--theme-widget-primary-color);
5557
}
5658

5759
.dark {
60+
composes: scope-lightContent from global;
5861
background-color: darkContentSurfaceColor;
5962
color: lightContentTextColor;
6063
--content-text-color: lightContentTextColor;
@@ -122,42 +125,10 @@
122125
margin-bottom: 0;
123126
}
124127

125-
.link {
126-
display: flex;
127-
justify-content: center;
128-
gap: 0.5em;
129-
border-radius: 5px;
130-
text-decoration: none;
131-
padding: 0.5rem;
132-
background-color: transparent;
133-
color: inherit;
134-
margin-top: 1rem;
135-
font-weight: bold;
136-
border: solid 1px color-mix(in srgb, currentColor, transparent);
137-
}
138-
139128
.textWrapper > :first-child .link {
140129
margin-top: 0;
141130
}
142131

143-
.link:hover,
144-
.link:active {
145-
border: solid 1px currentColor;
146-
}
147-
148-
.light .link {
149-
color: var(--theme-widget-primary-color);
150-
}
151-
152132
.box > :first-child .link {
153133
margin-top: 0;
154134
}
155-
156-
.editable .link {
157-
opacity: 0.5;
158-
}
159-
160-
.editable .link:has([data-slate-string]),
161-
.editable .link:focus-within {
162-
opacity: 1;
163-
}
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from 'react';
2+
import classNames from 'classnames';
3+
import styles from './LinkButton.module.css';
4+
import {EditableLink} from './EditableLink';
5+
import {EditableInlineText} from './EditableInlineText';
6+
import {Text} from './Text';
7+
import {utils} from './utils';
8+
import {useI18n} from './i18n';
9+
import {useContentElementEditorState} from './useContentElementEditorState';
10+
11+
export function LinkButton({
12+
href,
13+
openInNewTab,
14+
value,
15+
onTextChange,
16+
onLinkChange,
17+
scaleCategory,
18+
className,
19+
actionButtonVisible,
20+
linkPreviewPosition,
21+
linkPreviewDisabled,
22+
children,
23+
...props
24+
}) {
25+
const {t} = useI18n({locale: 'ui'});
26+
const {isEditable} = useContentElementEditorState();
27+
28+
return (
29+
<Text inline scaleCategory={scaleCategory}>
30+
<EditableLink href={href}
31+
openInNewTab={openInNewTab}
32+
linkPreviewPosition={linkPreviewPosition}
33+
linkPreviewDisabled={utils.isBlankEditableTextValue(value) || linkPreviewDisabled}
34+
actionButtonVisible={actionButtonVisible}
35+
className={classNames(styles.button, className, {[styles.editable]: isEditable})}
36+
onChange={onLinkChange}
37+
{...props}>
38+
<EditableInlineText value={value}
39+
onChange={onTextChange}
40+
placeholder={t('pageflow_scrolled.inline_editing.type_text')} />
41+
{children}
42+
</EditableLink>
43+
</Text>
44+
);
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
:global .scope-lightContent {
2+
--link-button-on-surface-color: var(--theme-light-content-link-button-on-surface-color,
3+
currentColor);
4+
--link-button-surface-color: var(--theme-light-content-link-button-surface-color);
5+
}
6+
7+
:global .scope-darkContent {
8+
--link-button-on-surface-color: var(--theme-dark-content-link-button-on-surface-color,
9+
var(--theme-widget-primary-color));
10+
--link-button-surface-color: var(--theme-dark-content-link-button-surface-color);
11+
}
12+
13+
.button {
14+
display: flex;
15+
width: var(--theme-link-button-width);
16+
justify-content: center;
17+
gap: 0.5em;
18+
border-radius: var(--theme-link-button-border-radius, 5px);
19+
text-decoration: none;
20+
padding: var(--theme-link-button-padding, 0.5rem);
21+
background-color: var(--link-button-surface-color, transparent);
22+
color: var(--link-button-on-surface-color);
23+
margin-top: 1rem;
24+
font-weight: bold;
25+
border: solid 1px var(--link-button-surface-color,
26+
color-mix(in srgb,
27+
var(--link-button-on-surface-color),
28+
transparent));
29+
cursor: pointer;
30+
}
31+
32+
.button::after {
33+
content: var(--theme-link-button-symbol, "›");
34+
}
35+
36+
.button:hover,
37+
.button:active {
38+
border: solid 1px var(--link-button-surface-color, var(--link-button-on-surface-color));
39+
}
40+
41+
.editable {
42+
opacity: 0.5;
43+
}
44+
45+
.editable:has([data-slate-string]),
46+
.editable:focus-within {
47+
opacity: 1;
48+
}

0 commit comments

Comments
 (0)