Skip to content

Commit 4ff6870

Browse files
authored
Merge pull request #539 from StackExchange/feature/auto-arrows
Popover automatic arrow placement
2 parents fb12692 + 34b5bc7 commit 4ff6870

File tree

5 files changed

+100
-45
lines changed

5 files changed

+100
-45
lines changed

dist/js/stacks.js

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/js/stacks.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/product/components/popovers.html

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
</tbody>
8282
</table>
8383
</div>
84+
8485
{% header "h3", "Interactive Events" %}
8586
<div class="overflow-x-auto mb32">
8687
<table class="wmn4 s-table s-table__bx-simple">
@@ -168,27 +169,36 @@
168169
<button class="s-btn s-btn__filled">Link an account</button>
169170
</div>
170171
</div>
172+
<button class="grid--cell s-btn s-btn__muted p4"
173+
data-controller="s-popover"
174+
data-s-popover-toggle-class="is-selected"
175+
data-s-popover-placement="top"
176+
data-action="s-popover#toggle"
177+
aria-controls="popover-example-4">
178+
{% icon "HelpSm" %}
179+
</button>
180+
<div id="popover-example-4" class="s-popover" role="menu">
181+
<div class="s-popover--arrow"></div>
182+
<p>We know you hate spam, and we do too. That’s why we make it easy for you to update your email preferences or unsubscribe at anytime.</p>
183+
<p class="mb0">We never share your email address with third parties for marketing purposes.</p>
184+
</div>
171185
<div class="grid--cell ml-auto sm:ml0 sm:mt12"
172186
data-controller="s-popover"
173187
data-s-popover-reference-selector="#reference-element"
174-
data-s-popover-placement="bottom-end">
188+
data-s-popover-placement="auto">
175189
<a id="reference-element" class="s-link s-link__inherit"
176190
aria-controls="popover-example-3">
177191
Follow question
178192
</a>
179-
<div id="popover-example-3" class="s-popover is-visible ws2" role="menu">
193+
<div id="popover-example-3" class="s-popover is-visible wmx3" role="menu">
180194
<div class="s-popover--arrow"></div>
181195
<button class="s-popover--close s-btn s-btn__muted" aria-label="Close" data-action="s-popover#toggle">{% icon "ClearSm" %}</button>
182196

183-
<div class="grid ai-start">
184-
<div class="grid--cell mr12 fc-orange-400 sm:d-none">
197+
<div class="grid ai-center">
198+
<div class="grid--cell mr12 fc-orange-400">
185199
{% spot "Bell" %}
186200
</div>
187201

188-
<div class="grid--cell mr8 fc-orange-400 sm:d-block d-none">
189-
{% icon "Bell" %}
190-
</div>
191-
192202
<div class="grid--cell">
193203
Get updates on questions and answers
194204
</div>

lib/css/components/_stacks-popovers.less

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,36 @@
3939
display: block;
4040
}
4141

42-
// Auto adjust margins for auto-placed popovers
43-
&[data-popper-placement^="top"] {
44-
margin-bottom: @su8 + 2px;
42+
&[data-popper-placement^="top"] > .s-popover--arrow {
43+
bottom: -@su6;
44+
45+
&:after {
46+
bottom: 1px;
47+
}
4548
}
4649

47-
&[data-popper-placement^="right"] {
48-
margin-left: @su8 + 2px;
50+
&[data-popper-placement^="bottom"] > .s-popover--arrow {
51+
top: -@su6;
52+
53+
&:after {
54+
top: 1px;
55+
}
4956
}
5057

51-
&[data-popper-placement^="bottom"] {
52-
margin-top: @su8 + 2px;
58+
&[data-popper-placement^="left"] > .s-popover--arrow {
59+
right: -@su6;
60+
61+
&:after {
62+
right: 1px;
63+
}
5364
}
5465

55-
&[data-popper-placement^="left"] {
56-
margin-right: @su8 + 2px;
66+
&[data-popper-placement^="right"] > .s-popover--arrow {
67+
left: -@su6;
68+
69+
&:after {
70+
left: 1px;
71+
}
5772
}
5873
}
5974

@@ -92,7 +107,44 @@
92107
// $ BASE STYLE
93108
// Sets the base arrow style for tooltips, popovers, and dropdowns.
94109
// ----------------------------------------------------------------------------
110+
95111
.s-popover--arrow,
112+
.s-popover--arrow:before,
113+
.s-popover--arrow:after {
114+
position: absolute;
115+
width: @su12;
116+
height: @su12;
117+
z-index: -1;
118+
}
119+
120+
.s-popover--arrow {
121+
color: var(--white);
122+
}
123+
124+
#stacks-internals #darkmode('', {
125+
.s-popover--arrow {
126+
color: var(--black-075);
127+
}
128+
129+
.s-popover--arrow:before {
130+
background: currentColor;
131+
}
132+
});
133+
134+
.s-popover--arrow:before {
135+
// This renders our border
136+
content: '';
137+
transform: rotate(45deg);
138+
background: var(--black-150);
139+
}
140+
141+
.s-popover--arrow:after {
142+
// This renders our foreground color
143+
content: '';
144+
transform: rotate(45deg);
145+
background: currentColor;
146+
}
147+
96148
.s-popover--arrow__tl,
97149
.s-popover--arrow__tc,
98150
.s-popover--arrow__tr,
@@ -118,7 +170,6 @@
118170
}
119171

120172
#stacks-internals #darkmode('', {
121-
.s-popover--arrow,
122173
.s-popover--arrow__tl,
123174
.s-popover--arrow__tc,
124175
.s-popover--arrow__tr,
@@ -140,7 +191,6 @@
140191
// ============================================================================
141192
// $$ TOP
142193
// ----------------------------------------------------------------------------
143-
.s-popover[data-popper-placement^="bottom"] .s-popover--arrow,
144194
.s-popover--arrow__tl,
145195
.s-popover--arrow__tc,
146196
.s-popover--arrow__tr {
@@ -150,7 +200,7 @@
150200
}
151201
&:before {
152202
top: -(@su8);
153-
border-bottom-color: var(--black-100);
203+
border-bottom-color: var(--black-150);
154204
}
155205
&:after {
156206
top: -(@su8 - 1);
@@ -160,7 +210,6 @@
160210

161211
// $$ BOTTOM
162212
// ----------------------------------------------------------------------------
163-
.s-popover[data-popper-placement^="top"] .s-popover--arrow,
164213
.s-popover--arrow__bl,
165214
.s-popover--arrow__bc,
166215
.s-popover--arrow__br {
@@ -170,7 +219,7 @@
170219
}
171220
&:before {
172221
bottom: -(@su8);
173-
border-top-color: var(--black-100);
222+
border-top-color: var(--black-150);
174223
}
175224
&:after {
176225
bottom: -(@su8 - 1);
@@ -180,8 +229,6 @@
180229

181230
// $$ TOP & BOTTOM LEFT
182231
// ----------------------------------------------------------------------------
183-
.s-popover[data-popper-placement="top-start"] .s-popover--arrow,
184-
.s-popover[data-popper-placement="bottom-start"] .s-popover--arrow,
185232
.s-popover--arrow__tl,
186233
.s-popover--arrow__bl {
187234
&:before,
@@ -192,8 +239,6 @@
192239

193240
// $$ TOP & BOTTOM CENTER
194241
// ----------------------------------------------------------------------------
195-
.s-popover[data-popper-placement="top"] .s-popover--arrow,
196-
.s-popover[data-popper-placement="bottom"] .s-popover--arrow,
197242
.s-popover--arrow__tc,
198243
.s-popover--arrow__bc {
199244
&:before,
@@ -205,8 +250,6 @@
205250

206251
// $$ TOP & BOTTOM RIGHT
207252
// ----------------------------------------------------------------------------
208-
.s-popover[data-popper-placement="top-end"] .s-popover--arrow,
209-
.s-popover[data-popper-placement="bottom-end"] .s-popover--arrow,
210253
.s-popover--arrow__tr,
211254
.s-popover--arrow__br {
212255
&:before,
@@ -217,7 +260,6 @@
217260

218261
// $$ LEFT
219262
// ----------------------------------------------------------------------------
220-
.s-popover[data-popper-placement^="right"] .s-popover--arrow,
221263
.s-popover--arrow__lt,
222264
.s-popover--arrow__lc,
223265
.s-popover--arrow__lb {
@@ -227,7 +269,7 @@
227269
}
228270
&:before {
229271
left: -(@su8);
230-
border-right-color: var(--black-100);
272+
border-right-color: var(--black-150);
231273
}
232274
&:after {
233275
left: -(@su8 - 1);
@@ -237,7 +279,6 @@
237279

238280
// $$ RIGHT
239281
// ----------------------------------------------------------------------------
240-
.s-popover[data-popper-placement^="left"] .s-popover--arrow,
241282
.s-popover--arrow__rt,
242283
.s-popover--arrow__rc,
243284
.s-popover--arrow__rb {
@@ -247,7 +288,7 @@
247288
}
248289
&:before {
249290
right: -(@su8);
250-
border-left-color: var(--black-100);
291+
border-left-color: var(--black-150);
251292
}
252293
&:after {
253294
right: -(@su8 - 1);
@@ -257,8 +298,6 @@
257298

258299
// $$ LEFT & RIGHT TOP
259300
// ----------------------------------------------------------------------------
260-
.s-popover[data-popper-placement="left-start"] .s-popover--arrow,
261-
.s-popover[data-popper-placement="right-start"] .s-popover--arrow,
262301
.s-popover--arrow__lt,
263302
.s-popover--arrow__rt {
264303
&:before,
@@ -269,8 +308,6 @@
269308

270309
// $$ LEFT & RIGHT CENTER
271310
// ----------------------------------------------------------------------------
272-
.s-popover[data-popper-placement="left"] .s-popover--arrow,
273-
.s-popover[data-popper-placement="right"] .s-popover--arrow,
274311
.s-popover--arrow__lc,
275312
.s-popover--arrow__rc {
276313
&:before,
@@ -282,8 +319,6 @@
282319

283320
// $$ LEFT & RIGHT BOTTOM
284321
// ----------------------------------------------------------------------------
285-
.s-popover[data-popper-placement="left-end"] .s-popover--arrow,
286-
.s-popover[data-popper-placement="right-end"] .s-popover--arrow,
287322
.s-popover--arrow__lb,
288323
.s-popover--arrow__rb {
289324
&:before,

lib/ts/controllers/s-popover.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,15 @@ namespace Stacks {
146146
{
147147
name: "offset",
148148
options: {
149-
// Popperjs does not respect margins on the element, so set the offset here
150-
// NOTE: this value matches the CSS value of auto-placed popovers margins (@su8 + 2)
151-
offset: [0, 10]
149+
offset: [0, 10], // The entire popover should be 10px away from the element
152150
}
153-
}
151+
},
152+
{
153+
name: "arrow",
154+
options: {
155+
element: ".s-popover--arrow"
156+
},
157+
},
154158
]
155159
});
156160
}

0 commit comments

Comments
 (0)