Skip to content

Commit f4da92b

Browse files
authored
Infotip - Add Icon tab
Add controls to place an Icon beside the anchor text in the Infotip component
2 parents 5c6ee81 + bc33222 commit f4da92b

File tree

4 files changed

+378
-29
lines changed

4 files changed

+378
-29
lines changed

assets/infotip/infotip-web-component.js

Lines changed: 117 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,43 @@
33
*/
44
class BlaBlaBlocksInfotip extends HTMLElement {
55
static get observedAttributes() {
6-
return [ 'content', 'underline' ];
6+
return [
7+
'content',
8+
'underline',
9+
'icon-enabled',
10+
'icon-position',
11+
'icon-color',
12+
'icon-type',
13+
];
714
}
815

916
connectedCallback() {
1017
const template = this.renderElement();
1118
this.attachShadow( { mode: 'open' } );
1219
this.shadowRoot.appendChild( template.content.cloneNode( true ) );
20+
21+
// Add this section to handle initial icon state
22+
const iconEnabled = this.getAttribute( 'icon-enabled' ) === 'true';
23+
if ( iconEnabled ) {
24+
const icon = this.shadowRoot.querySelector( '.icon' );
25+
icon.innerHTML = this.renderIcon(
26+
this.getAttribute( 'icon-type' ) || 'info'
27+
);
28+
}
1329
requestAnimationFrame( () => {
1430
// Wait for the element to be attached to the DOM.
15-
this.initializeFloatingUI();
31+
this.updatePosition();
1632
this.initializeEventListeners();
1733
} );
1834
}
1935

20-
initializeFloatingUI() {
21-
this.updatePosition();
22-
}
23-
2436
updatePosition() {
37+
// Prevent the infotip overlay from showing when content is blank.
38+
if ( this.getAttribute( 'content' ) === '' ) {
39+
this.hideTooltip();
40+
return;
41+
}
42+
2543
const floatingUIDOM = window.FloatingUIDOM;
2644
const anchorText = this.shadowRoot.querySelector( '.text' );
2745
const infotip = this.shadowRoot.querySelector( '.infotip' );
@@ -85,14 +103,21 @@ class BlaBlaBlocksInfotip extends HTMLElement {
85103

86104
renderStyle() {
87105
const showUnderline = this.getAttribute( 'underline' ) !== 'false';
106+
const iconEnabled = this.getAttribute( 'icon-enabled' ) === 'true';
107+
const iconPosition = this.getAttribute( 'icon-position' ) ?? 'left';
108+
const iconColor = this.getAttribute( 'icon-color' ) ?? 'currentColor';
88109

89-
const style = `
110+
let style = `
90111
.wrapper {
91112
position: relative;
92113
}
93114
.text {
94115
text-decoration: ${ showUnderline ? 'dotted underline' : 'none' };
95116
cursor: pointer;
117+
display: inline-flex;
118+
vertical-align: bottom;
119+
gap: 2px;
120+
flex-direction: ${ iconPosition === 'right' ? 'row-reverse' : 'row' };
96121
}
97122
.infotip {
98123
display: none;
@@ -102,7 +127,7 @@ class BlaBlaBlocksInfotip extends HTMLElement {
102127
left: 0px;
103128
background: #222;
104129
color: white;
105-
padding: 5px;
130+
padding: 10px;
106131
border-radius: 4px;
107132
font-size: 90%;
108133
}
@@ -115,9 +140,64 @@ class BlaBlaBlocksInfotip extends HTMLElement {
115140
}
116141
`;
117142

143+
if ( iconEnabled ) {
144+
style += `
145+
.icon {
146+
display: inline-flex;
147+
align-items: center;
148+
}
149+
.icon svg {
150+
width: 24px;
151+
height: 24px;
152+
fill: ${ iconColor };
153+
}
154+
`;
155+
}
156+
118157
return style;
119158
}
120159

160+
renderIcon( iconType = 'info' ) {
161+
const iconPaths = {
162+
info: `<path
163+
fill-rule="evenodd"
164+
clip-rule="evenodd"
165+
d="M5.5 12a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm.75 4v1.5h-1.5V8h1.5Zm0 8v-5h-1.5v5h1.5Z"
166+
/>`,
167+
168+
help: `<path
169+
d="M12 4.75a7.25 7.25 0 100 14.5 7.25 7.25 0 000-14.5zM3.25 12a8.75 8.75 0 1117.5 0 8.75 8.75 0 01-17.5 0zM12 8.75a1.5 1.5 0 01.167 2.99c-.465.052-.917.44-.917 1.01V14h1.5v-.845A3 3 0 109 10.25h1.5a1.5 1.5 0 011.5-1.5zM11.25 15v1.5h1.5V15h-1.5z"
170+
/>`,
171+
172+
caution: `<path
173+
fill-rule="evenodd"
174+
clip-rule="evenodd"
175+
d="M5.5 12a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0ZM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm-.75 12v-1.5h1.5V16h-1.5Zm0-8v5h1.5V8h-1.5Z"
176+
/>`,
177+
178+
error: `<path
179+
fill-rule="evenodd"
180+
clip-rule="evenodd"
181+
d="M12.218 5.377a.25.25 0 0 0-.436 0l-7.29 12.96a.25.25 0 0 0 .218.373h14.58a.25.25 0 0 0 .218-.372l-7.29-12.96Zm-1.743-.735c.669-1.19 2.381-1.19 3.05 0l7.29 12.96a1.75 1.75 0 0 1-1.525 2.608H4.71a1.75 1.75 0 0 1-1.525-2.608l7.29-12.96ZM12.75 17.46h-1.5v-1.5h1.5v1.5Zm-1.5-3h1.5v-5h-1.5v5Z"
182+
/>`,
183+
184+
notAllowed: `<path
185+
fill-rule="evenodd"
186+
clip-rule="evenodd"
187+
d="M12 18.5A6.5 6.5 0 0 1 6.93 7.931l9.139 9.138A6.473 6.473 0 0 1 12 18.5Zm5.123-2.498a6.5 6.5 0 0 0-9.124-9.124l9.124 9.124ZM4 12a8 8 0 1 1 16 0 8 8 0 0 1-16 0Z"
188+
/>`,
189+
190+
starEmpty: `<path
191+
fill-rule="evenodd"
192+
d="M9.706 8.646a.25.25 0 01-.188.137l-4.626.672a.25.25 0 00-.139.427l3.348 3.262a.25.25 0 01.072.222l-.79 4.607a.25.25 0 00.362.264l4.138-2.176a.25.25 0 01.233 0l4.137 2.175a.25.25 0 00.363-.263l-.79-4.607a.25.25 0 01.072-.222l3.347-3.262a.25.25 0 00-.139-.427l-4.626-.672a.25.25 0 01-.188-.137l-2.069-4.192a.25.25 0 00-.448 0L9.706 8.646zM12 7.39l-.948 1.921a1.75 1.75 0 01-1.317.957l-2.12.308 1.534 1.495c.412.402.6.982.503 1.55l-.362 2.11 1.896-.997a1.75 1.75 0 011.629 0l1.895.997-.362-2.11a1.75 1.75 0 01.504-1.55l1.533-1.495-2.12-.308a1.75 1.75 0 01-1.317-.957L12 7.39z"
193+
clip-rule="evenodd"
194+
/>`,
195+
};
196+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" role="img">
197+
${ iconPaths[ iconType ] }
198+
</svg>`;
199+
}
200+
121201
renderElement() {
122202
const content = this.getAttribute( 'content' );
123203
const template = document.createElement( 'template' );
@@ -126,11 +206,14 @@ class BlaBlaBlocksInfotip extends HTMLElement {
126206
${ this.renderStyle() }
127207
</style>
128208
<span class="wrapper">
129-
<span class="text" tabindex="0" role="button" aria-describedby="infotip-content">
130-
<slot></slot>
209+
<span class="text" tabindex="0" role="button" aria-describedby="infotip-popover">
210+
<span class="icon"></span>
211+
<slot></slot>
131212
</span>
132-
<div class="infotip" id="infotip-content">
133-
${ content }
213+
<div class="infotip" id="infotip-popover">
214+
<div class="infotip-popover-content">
215+
${ content }
216+
</div>
134217
<div class="arrow"></div>
135218
</div>
136219
</span>
@@ -146,17 +229,33 @@ class BlaBlaBlocksInfotip extends HTMLElement {
146229
}
147230

148231
if ( name === 'content' ) {
149-
const infotip = shadow.querySelector( '.infotip' );
232+
const infotip = shadow.querySelector( '.infotip-popover-content' );
150233
infotip.innerHTML = newValue;
151234

152-
if ( ! infotip.querySelector( '.arrow' ) ) {
153-
infotip
154-
.appendChild( document.createElement( 'div' ) )
155-
.classList.add( 'arrow' );
235+
this.updatePosition();
236+
this.showTooltip();
237+
}
238+
239+
if ( name === 'icon-enabled' ) {
240+
const icon = shadow.querySelector( '.icon' );
241+
242+
if ( newValue === 'true' ) {
243+
icon.innerHTML = this.renderIcon(
244+
this.getAttribute( 'icon-type' ) || 'info'
245+
);
246+
} else {
247+
icon.innerHTML = '';
156248
}
157249

158250
this.updatePosition();
159-
this.showTooltip();
251+
}
252+
253+
if ( name === 'icon-type' ) {
254+
const icon = shadow.querySelector( '.icon' );
255+
if ( this.getAttribute( 'icon-enabled' ) === 'true' ) {
256+
icon.innerHTML = this.renderIcon( newValue );
257+
}
258+
this.updatePosition();
160259
}
161260

162261
const style = shadow.querySelector( 'style' );

src/infotip/editor.scss

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,26 @@ blablablocks-infotip {
99
.block-editor-format-toolbar__blablablocks-infotip-popover {
1010

1111
.components-popover__content {
12-
min-width: 20.625rem;
12+
min-width: 23rem;
1313
}
1414

1515
.components-tab-panel__tab-content {
1616
padding: 1rem;
17+
18+
.icon-tab-label {
19+
font-weight: 500;
20+
text-transform: uppercase;
21+
font-size: 0.6875rem;
22+
}
23+
24+
.icon-color-settings {
25+
border-top: none;
26+
padding: 0;
27+
28+
.block-editor-tools-panel-color-gradient-settings__item:first-child {
29+
margin-top: 0;
30+
}
31+
}
1732
}
1833
}
34+

src/infotip/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,9 @@ export const infotip = {
6161
attributes: {
6262
content: 'content',
6363
underline: 'underline',
64+
'icon-enabled': 'icon-enabled',
65+
'icon-position': 'icon-position',
66+
'icon-color': 'icon-color',
67+
'icon-type': 'icon-type',
6468
},
6569
};

0 commit comments

Comments
 (0)