FIX: uses tippy for popover (#15409)

Note this commit also introduce a new {{d-popover}} component, example usage:

```hbs
{{#d-popover |state|}}
  {{d-button label="foo.things" class="d-popover-trigger"}}

  <div class="d-popover-content">
    Some content
  <div>
{{/d-popover}}
```
This commit is contained in:
Joffrey JAFFEUX 2022-05-02 17:10:26 +02:00 committed by GitHub
parent 4885a2535a
commit fad94160c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 2801 additions and 307 deletions

View File

@ -25,6 +25,10 @@ define("@popperjs/core", ["exports"], function (__exports__) {
__exports__.popperGenerator = window.Popper.popperGenerator; __exports__.popperGenerator = window.Popper.popperGenerator;
}); });
define("tippy.js", ["exports"], function (__exports__) {
__exports__.default = window.tippy;
});
define("@uppy/core", ["exports"], function (__exports__) { define("@uppy/core", ["exports"], function (__exports__) {
__exports__.default = window.Uppy.Core; __exports__.default = window.Uppy.Core;
__exports__.BasePlugin = window.Uppy.Core.BasePlugin; __exports__.BasePlugin = window.Uppy.Core.BasePlugin;

View File

@ -0,0 +1,61 @@
import Component from "@ember/component";
import { iconHTML } from "discourse-common/lib/icon-library";
import tippy from "tippy.js";
import { guidFor } from "@ember/object/internals";
export default class DiscoursePopover extends Component {
tagName = "";
isExpanded = false;
options = null;
didInsertElement() {
this._super(...arguments);
this._setupTippy();
}
get componentId() {
return guidFor(this);
}
_setupTippy() {
const baseOptions = {
trigger: "click",
zIndex: 1400,
arrow: iconHTML("tippy-rounded-arrow"),
interactive: true,
allowHTML: false,
appendTo: "parent",
content:
this.options?.content ||
document
.getElementById(this.componentId)
.querySelector(
":scope > .d-popover-content, :scope > div, :scope > ul"
),
onShow: () => {
if (this.isDestroyed || this.isDestroying) {
return;
}
this.set("isExpanded", true);
},
onHide: () => {
if (this.isDestroyed || this.isDestroying) {
return;
}
this.set("isExpanded", false);
},
};
tippy(
document
.getElementById(this.componentId)
.querySelector(
':scope > .d-popover-trigger, :scope > .btn, :scope > [role="button"]'
),
Object.assign({}, baseOptions, this.options || {})
);
}
}

View File

@ -1,20 +1,19 @@
import { import { showPopover } from "discourse/lib/d-popover";
POPOVER_SELECTORS,
hidePopover,
showPopover,
} from "discourse/lib/d-popover";
export default { export default {
name: "d-popover", name: "d-popover",
initialize(container) { initialize() {
const router = container.lookup("router:main"); ["click", "mouseover"].forEach((eventType) => {
router.on("routeWillChange", hidePopover); document.addEventListener(eventType, (e) => {
if (e.target.dataset.tooltip || e.target.dataset.popover) {
$("#main") showPopover(e, {
.on("click.d-popover mouseenter.d-popover", POPOVER_SELECTORS, (e) => interactive: false,
showPopover(e) content: (reference) =>
) reference.dataset.tooltip || reference.dataset.popover,
.on("mouseleave.d-popover", POPOVER_SELECTORS, (e) => hidePopover(e)); });
}
});
});
}, },
}; };

View File

@ -1,168 +1,48 @@
import { siteDir } from "discourse/lib/text-direction"; import { isLegacyEmber } from "discourse-common/config/environment";
import { run } from "@ember/runloop";
import tippy from "tippy.js";
import { iconHTML } from "discourse-common/lib/icon-library";
const D_POPOVER_ID = "d-popover"; export function hidePopover(event) {
if (event?.target?._tippy) {
const D_POPOVER_TEMPLATE = ` showPopover(event);
<div id="${D_POPOVER_ID}" class="is-under"> }
<div class="d-popover-arrow d-popover-top-arrow"></div>
<div class="d-popover-content">
<div class="spinner small"></div>
</div>
<div class="d-popover-arrow d-popover-bottom-arrow"></div>
</div>
`;
const D_ARROW_HEIGHT = 10;
const D_HORIZONTAL_MARGIN = 5;
export const POPOVER_SELECTORS = "[data-popover], [data-tooltip]";
export function hidePopover() {
getPopover().fadeOut().remove();
return getPopover();
} }
// options accepts all tippy.js options as defined in their documentation
// https://atomiks.github.io/tippyjs/v6/all-props/
export function showPopover(event, options = {}) { export function showPopover(event, options = {}) {
let $enteredElement = $(event.target).closest(POPOVER_SELECTORS).first(); const tippyOptions = Object.assign(
{
arrow: iconHTML("tippy-rounded-arrow"),
content: options.textContent || options.htmlContent,
allowHTML: options?.htmlContent?.length,
trigger: "mouseenter click",
hideOnClick: true,
zIndex: 1400,
},
options
);
if (!$enteredElement.length) { // legacy support
$enteredElement = $(event.target); delete tippyOptions.textContent;
delete tippyOptions.htmlContent;
const instance = event.target._tippy
? event.target._tippy
: tippy(event.target, tippyOptions);
// hangs on legacy ember
if (!isLegacyEmber) {
run.begin();
instance.popper.addEventListener("transitionend", run.end, {
once: true,
});
} }
if (isRetina()) { if (instance.state.isShown) {
getPopover().addClass("retina"); instance.hide();
}
if (!getPopover().length) {
$("body").append($(D_POPOVER_TEMPLATE));
}
setPopoverHtmlContent($enteredElement, options.htmlContent);
setPopoverTextContent($enteredElement, options.textContent);
getPopover().fadeIn();
positionPopover($enteredElement);
return {
html: (content) => replaceHtmlContent($enteredElement, content),
text: (content) => replaceTextContent($enteredElement, content),
hide: hidePopover,
};
}
function setPopoverHtmlContent($enteredElement, content) {
replaceHtmlContent($enteredElement, content);
}
function setPopoverTextContent($enteredElement, content) {
content =
content ||
$enteredElement.attr("data-popover") ||
$enteredElement.attr("data-tooltip");
replaceTextContent($enteredElement, content);
}
function replaceTextContent($enteredElement, content) {
if (content) {
getPopover().find(".d-popover-content").text(content);
window.requestAnimationFrame(() => positionPopover($enteredElement));
}
}
function replaceHtmlContent($enteredElement, content) {
if (content) {
getPopover().find(".d-popover-content").html(content);
window.requestAnimationFrame(() => positionPopover($enteredElement));
}
}
function positionPopover($element) {
const $popover = getPopover();
$popover.removeClass("is-above is-under is-left-aligned is-right-aligned");
const $dHeader = $(".d-header");
const windowRect = {
left: 0,
top: $dHeader.length ? $dHeader[0].getBoundingClientRect().bottom : 0,
width: $(window).width(),
height: $(window).height(),
};
const popoverRect = {
width: $popover.width(),
height: $popover.height(),
left: null,
right: null,
};
if (popoverRect.width > windowRect.width - D_HORIZONTAL_MARGIN * 2) {
popoverRect.width = windowRect.width - D_HORIZONTAL_MARGIN * 2;
$popover.width(popoverRect.width);
}
const targetRect = $element[0].getBoundingClientRect();
const underSpace = windowRect.height - targetRect.bottom - D_ARROW_HEIGHT;
const topSpace = targetRect.top - windowRect.top - D_ARROW_HEIGHT;
if (
underSpace > popoverRect.height + D_HORIZONTAL_MARGIN ||
underSpace > topSpace
) {
$popover
.css("top", targetRect.bottom + window.pageYOffset + D_ARROW_HEIGHT)
.addClass("is-under");
} else { } else {
$popover instance.show();
.css(
"top",
targetRect.top +
window.pageYOffset -
popoverRect.height -
D_ARROW_HEIGHT
)
.addClass("is-above");
} }
const leftSpace = targetRect.left + targetRect.width / 2;
if (siteDir() === "ltr") {
if (leftSpace > popoverRect.width / 2 + D_HORIZONTAL_MARGIN) {
popoverRect.left = leftSpace - popoverRect.width / 2;
$popover.css("left", popoverRect.left);
} else {
popoverRect.left = D_HORIZONTAL_MARGIN;
$popover.css("left", popoverRect.left).addClass("is-left-aligned");
}
} else {
const rightSpace = windowRect.width - targetRect.right;
if (rightSpace > popoverRect.width / 2 + D_HORIZONTAL_MARGIN) {
popoverRect.left = leftSpace - popoverRect.width / 2;
$popover.css("left", popoverRect.left);
} else {
popoverRect.left =
windowRect.width - popoverRect.width - D_HORIZONTAL_MARGIN * 2;
$popover.css("left", popoverRect.left).addClass("is-right-aligned");
}
}
let arrowPosition;
if (siteDir() === "ltr") {
arrowPosition = Math.abs(targetRect.left - popoverRect.left);
} else {
arrowPosition = targetRect.left - popoverRect.left + targetRect.width / 2;
}
$popover.find(".d-popover-arrow").css("left", arrowPosition);
}
function isRetina() {
return window.devicePixelRatio && window.devicePixelRatio > 1;
}
function getPopover() {
return $(document.getElementById(D_POPOVER_ID));
} }

View File

@ -0,0 +1,3 @@
<div id={{componentId}} class="d-popover {{if isExpanded "is-expanded"}}">
{{yield (hash isExpanded=isExpanded)}}
</div>

View File

@ -23,6 +23,7 @@
"@ember/test-helpers": "^2.2.0", "@ember/test-helpers": "^2.2.0",
"@glimmer/component": "^1.0.4", "@glimmer/component": "^1.0.4",
"@glimmer/tracking": "^1.0.4", "@glimmer/tracking": "^1.0.4",
"tippy.js": "^6.3.7",
"@popperjs/core": "2.10.2", "@popperjs/core": "2.10.2",
"@uppy/aws-s3": "^2.0.8", "@uppy/aws-s3": "^2.0.8",
"@uppy/aws-s3-multipart": "^2.2.1", "@uppy/aws-s3-multipart": "^2.2.1",

View File

@ -0,0 +1,76 @@
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import {
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import { showPopover } from "discourse/lib/d-popover";
import { click } from "@ember/test-helpers";
discourseModule("Integration | Component | d-popover", function (hooks) {
setupRenderingTest(hooks);
componentTest("show/hide popover from lib", {
template: hbs`{{d-button translatedLabel="test" action=onButtonClick forwardEvent=true}}`,
beforeEach() {
this.set("onButtonClick", (_, event) => {
showPopover(event, { content: "test", trigger: "click", duration: 0 });
});
},
async test(assert) {
assert.notOk(document.querySelector("div[data-tippy-root]"));
await click(".btn");
assert.equal(
document.querySelector("div[data-tippy-root]").innerText.trim(),
"test"
);
await click(".btn");
assert.notOk(document.querySelector("div[data-tippy-root]"));
},
});
componentTest("show/hide popover from component", {
template: hbs`{{#d-popover}}{{d-button icon="chevron-down"}}<ul><li class="test">foo</li></ul>{{/d-popover}}`,
async test(assert) {
assert.notOk(exists(".d-popover.is-expanded"));
assert.notOk(exists(".test"));
await click(".btn");
assert.ok(exists(".d-popover.is-expanded"));
assert.equal(query(".test").innerText.trim(), "foo");
},
});
componentTest("using options with component", {
template: hbs`{{#d-popover options=(hash content="bar")}}{{d-button icon="chevron-down"}}{{/d-popover}}`,
async test(assert) {
await click(".btn");
assert.equal(query(".tippy-content").innerText.trim(), "bar");
},
});
componentTest("d-popover component accepts a block", {
template: hbs`{{#d-popover as |state|}}{{d-button icon=(if state.isExpanded "chevron-up" "chevron-down")}}{{/d-popover}}`,
async test(assert) {
assert.ok(exists(".d-icon-chevron-down"));
await click(".btn");
assert.ok(exists(".d-icon-chevron-up"));
},
});
});

View File

@ -6,6 +6,7 @@
//= require Markdown.Converter.js //= require Markdown.Converter.js
//= require bootbox.js //= require bootbox.js
//= require popper.js //= require popper.js
//= require tippy.umd.js
//= require bootstrap-modal.js //= require bootstrap-modal.js
//= require caret_position //= require caret_position
//= require itsatrap.js //= require itsatrap.js

View File

@ -5,6 +5,10 @@ define("@popperjs/core", ["exports"], function (__exports__) {
__exports__.popperGenerator = window.Popper.popperGenerator; __exports__.popperGenerator = window.Popper.popperGenerator;
}); });
define("tippy.js", ["exports"], function (__exports__) {
__exports__.default = window.tippy;
});
define("@uppy/core", ["exports"], function (__exports__) { define("@uppy/core", ["exports"], function (__exports__) {
__exports__.default = window.Uppy.Core; __exports__.default = window.Uppy.Core;
__exports__.BasePlugin = window.Uppy.Core.BasePlugin; __exports__.BasePlugin = window.Uppy.Core.BasePlugin;

View File

@ -6,4 +6,5 @@
//= require virtual-dom //= require virtual-dom
//= require virtual-dom-amd //= require virtual-dom-amd
//= require popper.js //= require popper.js
//= require tippy.umd.js
//= require wizard-shims //= require wizard-shims

View File

@ -2120,6 +2120,11 @@
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.10.2.tgz#0798c03351f0dea1a5a4cabddf26a55a7cbee590" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.10.2.tgz#0798c03351f0dea1a5a4cabddf26a55a7cbee590"
integrity sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ== integrity sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==
"@popperjs/core@^2.9.0":
version "2.11.0"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.0.tgz#6734f8ebc106a0860dff7f92bf90df193f0935d7"
integrity sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==
"@simple-dom/interface@^1.4.0": "@simple-dom/interface@^1.4.0":
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f" resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f"
@ -12905,6 +12910,13 @@ tiny-lr@^2.0.0:
object-assign "^4.1.0" object-assign "^4.1.0"
qs "^6.4.0" qs "^6.4.0"
tippy.js@^6.3.7:
version "6.3.7"
resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c"
integrity sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==
dependencies:
"@popperjs/core" "^2.9.0"
tmp@0.0.28: tmp@0.0.28:
version "0.0.28" version "0.0.28"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120"

View File

@ -2,6 +2,8 @@
@import "vendor/normalize"; @import "vendor/normalize";
@import "vendor/normalize-ext"; @import "vendor/normalize-ext";
@import "vendor/pikaday"; @import "vendor/pikaday";
@import "vendor/tippy";
@import "vendor/svg-arrow";
@import "common/foundation/helpers"; @import "common/foundation/helpers";
@import "common/foundation/base"; @import "common/foundation/base";
@import "common/select-kit/_index"; @import "common/select-kit/_index";

View File

@ -1,112 +1,30 @@
$d-popover-background: var(--secondary); $d-popover-background: var(--secondary);
$d-popover-border: var(--primary-medium); $d-popover-border: var(--primary-medium);
@-webkit-keyframes popoverFadeIn { .tippy-box {
from { color: var(--primary);
opacity: 0; background: $d-popover-background;
box-shadow: shadow("card");
border: 1px solid $d-popover-border;
}
.tippy-box[data-placement^="top"] .tippy-svg-arrow > svg {
top: 12px;
}
.tippy-box[data-placement^="bottom"] .tippy-svg-arrow > svg {
top: -10px;
}
.tippy-rounded-arrow {
fill: $d-popover-background;
.svg-arrow {
fill: $d-popover-border;
} }
to { .svg-content {
opacity: 1; fill: $d-popover-background;
} }
} }
@keyframes popoverFadeIn { [data-tooltip] > *,
from { [data-popover] > * {
opacity: 0; pointer-events: none;
}
to {
opacity: 1;
}
}
#d-popover {
background-color: $d-popover-background;
position: absolute;
z-index: z("modal", "tooltip");
border-color: $d-popover-border;
border-style: solid;
border-width: 1px;
max-width: 300px;
-webkit-animation: popoverFadeIn 0.5s;
animation: popoverFadeIn 0.5s;
background-clip: padding-box;
display: block;
box-shadow: shadow("dropdown");
border-radius: 2px;
&.is-under {
margin-top: 0px;
.d-popover-top-arrow {
display: block;
}
.d-popover-bottom-arrow {
display: none;
}
}
&.is-above {
margin-top: 0px;
.d-popover-bottom-arrow {
display: block;
}
.d-popover-top-arrow {
display: none;
}
}
&.retina {
border-width: 0.5px;
}
.d-popover-content {
padding: 0.5em;
font-size: $font-down-1;
overflow-wrap: break-word;
-webkit-animation: popoverFadeIn 0.5s;
animation: popoverFadeIn 0.5s;
}
.d-popover-arrow {
border-style: solid;
color: transparent;
content: "";
position: absolute;
z-index: z("tooltip") - 100;
}
.d-popover-top-arrow {
border-color: transparent transparent $d-popover-border;
top: -8px;
border-width: 0 8px 8px;
&:after {
border-color: transparent transparent $d-popover-background;
border-style: solid;
border-width: 0 7px 7px;
bottom: -8.5px;
margin-left: -7px;
position: absolute;
content: "";
}
}
.d-popover-bottom-arrow {
border-color: $d-popover-border transparent transparent;
top: 100%;
border-width: 8px 8px 0;
&:after {
position: absolute;
content: "";
border-color: $d-popover-background transparent transparent;
border-style: solid;
border-width: 7px 7px 0;
bottom: 1.5px;
transform: translate(-7px, 0);
}
}
} }

View File

@ -2,7 +2,7 @@
margin-top: 2em; margin-top: 2em;
} }
#d-popover .download-calendar { div[data-tippy-root] .download-calendar {
color: var(--primary-med-or-secondary-med); color: var(--primary-med-or-secondary-med);
} }

View File

@ -0,0 +1 @@
.tippy-box[data-placement^=top]>.tippy-svg-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-svg-arrow:after,.tippy-box[data-placement^=top]>.tippy-svg-arrow>svg{top:16px;transform:rotate(180deg)}.tippy-box[data-placement^=bottom]>.tippy-svg-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:16px}.tippy-box[data-placement^=left]>.tippy-svg-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-svg-arrow:after,.tippy-box[data-placement^=left]>.tippy-svg-arrow>svg{transform:rotate(90deg);top:calc(50% - 3px);left:11px}.tippy-box[data-placement^=right]>.tippy-svg-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-svg-arrow:after,.tippy-box[data-placement^=right]>.tippy-svg-arrow>svg{transform:rotate(-90deg);top:calc(50% - 3px);right:11px}.tippy-svg-arrow{width:16px;height:16px;fill:#333;text-align:initial}.tippy-svg-arrow,.tippy-svg-arrow>svg{position:absolute}

View File

@ -0,0 +1 @@
.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}

View File

@ -213,7 +213,8 @@ module SvgSprite
"user-times", "user-times",
"users", "users",
"wrench", "wrench",
"spinner" "spinner",
"tippy-rounded-arrow"
]) ])
FA_ICON_MAP = { 'far fa-' => 'far-', 'fab fa-' => 'fab-', 'fas fa-' => '', 'fa-' => '' } FA_ICON_MAP = { 'far fa-' => 'far-', 'fab fa-' => 'fab-', 'fas fa-' => '', 'fa-' => '' }

View File

@ -148,8 +148,18 @@ def dependencies
}, { }, {
source: '@popperjs/core/dist/umd/popper.js.map', source: '@popperjs/core/dist/umd/popper.js.map',
public_root: true public_root: true
}, }, {
{ source: 'tippy.js/dist/tippy.umd.js'
}, {
source: 'tippy.js/dist/tippy.umd.js.map',
public_root: true
}, {
source: 'tippy.js/dist/tippy.css',
destination: '../../../app/assets/stylesheets/vendor'
}, {
source: 'tippy.js/dist/svg-arrow.css',
destination: '../../../app/assets/stylesheets/vendor'
}, {
source: 'route-recognizer/dist/route-recognizer.js' source: 'route-recognizer/dist/route-recognizer.js'
}, { }, {
source: 'route-recognizer/dist/route-recognizer.js.map', source: 'route-recognizer/dist/route-recognizer.js.map',
@ -206,6 +216,14 @@ def public_path_name(f)
f[:destination] || node_package_name(f) f[:destination] || node_package_name(f)
end end
def absolute_sourcemap(dest)
File.open(dest) do |file|
contents = file.read
contents.gsub!(/sourceMappingURL=(.*)/, 'sourceMappingURL=/\1')
File.open(dest, "w+") { |d| d.write(contents) }
end
end
task 'javascript:update_constants' => :environment do task 'javascript:update_constants' => :environment do
task_name = 'update_constants' task_name = 'update_constants'
@ -330,14 +348,12 @@ task 'javascript:update' => 'clean_up' do
FileUtils.cp_r(src, dest) FileUtils.cp_r(src, dest)
end end
# use absolute path for popper.js's sourcemap
# avoids noisy console warnings in dev environment for non-homepage paths # avoids noisy console warnings in dev environment for non-homepage paths
if dest.end_with? "popper.js" if dest.end_with? "popper.js"
File.open(dest) do |file| absolute_sourcemap(dest)
contents = file.read end
contents.gsub!("sourceMappingURL=popper", "sourceMappingURL=/popper") if dest.end_with? "tippy.umd.js"
File.open(dest, "w+") { |d| d.write(contents) } absolute_sourcemap(dest)
end
end end
end end

View File

@ -11,6 +11,7 @@
"@discourse/moment-timezone-names-translations": "^1.0.0", "@discourse/moment-timezone-names-translations": "^1.0.0",
"@highlightjs/cdn-assets": "^10.7.0", "@highlightjs/cdn-assets": "^10.7.0",
"@json-editor/json-editor": "^2.6.1", "@json-editor/json-editor": "^2.6.1",
"tippy.js": "^6.3.7",
"@popperjs/core": "v2.10.2", "@popperjs/core": "v2.10.2",
"@uppy/aws-s3": "^2.0.8", "@uppy/aws-s3": "^2.0.8",
"@uppy/aws-s3-multipart": "^2.2.1", "@uppy/aws-s3-multipart": "^2.2.1",

View File

@ -1,12 +1,12 @@
import deprecated from "discourse-common/lib/deprecated"; import deprecated from "discourse-common/lib/deprecated";
import { getOwner } from "discourse-common/lib/get-owner"; import { getOwner } from "discourse-common/lib/get-owner";
import { hidePopover, showPopover } from "discourse/lib/d-popover";
import LocalDateBuilder from "../lib/local-date-builder"; import LocalDateBuilder from "../lib/local-date-builder";
import { withPluginApi } from "discourse/lib/plugin-api"; import { withPluginApi } from "discourse/lib/plugin-api";
import showModal from "discourse/lib/show-modal"; import showModal from "discourse/lib/show-modal";
import { downloadCalendar } from "discourse/lib/download-calendar"; import { downloadCalendar } from "discourse/lib/download-calendar";
import { renderIcon } from "discourse-common/lib/icon-library"; import { renderIcon } from "discourse-common/lib/icon-library";
import I18n from "I18n"; import I18n from "I18n";
import { hidePopover, showPopover } from "discourse/lib/d-popover";
// Import applyLocalDates from discourse/lib/local-dates instead // Import applyLocalDates from discourse/lib/local-dates instead
export function applyLocalDates(dates, siteSettings) { export function applyLocalDates(dates, siteSettings) {
@ -238,39 +238,37 @@ export default {
return; return;
} }
const siteSettings = owner.lookup("site-settings:main"); if (event?.target?.classList?.contains("download-calendar")) {
if (event?.target?.classList?.contains("discourse-local-date")) {
if ($(document.getElementById("d-popover"))[0]) {
hidePopover(event);
} else {
showPopover(event, {
htmlContent: buildHtmlPreview(event.target, siteSettings),
});
}
} else if (event?.target?.classList?.contains("download-calendar")) {
const dataset = event.target.dataset; const dataset = event.target.dataset;
hidePopover(event);
downloadCalendar(dataset.title, [ downloadCalendar(dataset.title, [
{ {
startsAt: dataset.startsAt, startsAt: dataset.startsAt,
endsAt: dataset.endsAt, endsAt: dataset.endsAt,
}, },
]); ]);
} else { return;
hidePopover(event);
} }
if (!event?.target?.classList?.contains("discourse-local-date")) {
return;
}
const siteSettings = owner.lookup("site-settings:main");
showPopover(event, {
trigger: "click",
content: buildHtmlPreview(event.target, siteSettings),
allowHTML: true,
interactive: true,
appendTo: "parent",
});
}, },
hideDatePopover(event) { hideDatePopover(event) {
if (event?.target?.classList?.contains("discourse-local-date")) { hidePopover(event);
hidePopover(event);
}
}, },
initialize(container) { initialize(container) {
const router = container.lookup("router:main");
router.on("routeWillChange", hidePopover);
window.addEventListener("click", this.showDatePopover); window.addEventListener("click", this.showDatePopover);
const siteSettings = container.lookup("site-settings:main"); const siteSettings = container.lookup("site-settings:main");

View File

@ -23,7 +23,7 @@
} }
} }
#d-popover { div[data-tippy-root] {
.locale-dates-previews { .locale-dates-previews {
max-width: 360px; max-width: 360px;
.preview { .preview {

1
public/tippy.umd.js.map Normal file

File diff suppressed because one or more lines are too long

2496
vendor/assets/javascripts/tippy.umd.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -35,4 +35,9 @@ Additional SVG icons
<symbol id="discourse-emojis" viewBox="0 0 216.3 152.3"> <symbol id="discourse-emojis" viewBox="0 0 216.3 152.3">
<path d="M121.1 70.7c1.9 2 5.1 2.1 7.2.2l.2-.2 31.2-32.2c9.1-9.4 8.6-24.9-1.6-33.5-8.8-7.5-22-6.2-30.1 2.2l-3.2 3.3-3.2-3.3c-8.1-8.4-21.3-9.7-30.1-2.2-10.1 8.6-10.7 24.2-1.6 33.5l31.2 32.2zM53.5 45.3C23.9 45.3 0 69.2 0 98.8s23.9 53.5 53.5 53.5 53.5-24 53.5-53.5-23.9-53.5-53.5-53.5zm18.8 24.6c5.5 0 9.9 4.4 9.9 9.9s-4.4 9.9-9.9 9.9-9.9-4.4-9.9-9.9c-.1-5.5 4.4-9.9 9.9-9.9zm-38.2 0c5.5 0 9.9 4.4 9.9 9.9s-4.4 9.9-9.9 9.9-9.9-4.4-9.9-9.9 4.4-9.9 9.9-9.9zm52.4 45.4c-8.2 9.8-20.2 15.5-33.1 15.5s-24.9-5.6-33.1-15.5c-3.9-4.7 3.2-10.6 7.1-5.9 6.5 7.7 15.9 12.2 26 12.2s19.5-4.4 26-12.2c3.8-4.7 10.9 1.2 7.1 5.9zm129.8-22.5c0-6.4-6.3-9.5-13.3-9.5h-24c1.5-6 10.3-13.8 10.3-22.8 0-15.5-10.1-17.2-15.2-17.2-4.3 0-6.2 8.3-7.2 12.2-1.1 4.6-2.2 9.3-5.4 12.4-6.7 6.8-10.3 15.3-18.4 23.5-.7-1.8-2.6-3.1-4.7-3.1h-10.7c-2.8 0-5.1 2.2-5.1 4.9V142c0 2.7 2.3 4.9 5.1 4.9h10.7c2.8 0 5.1-2.2 5.1-4.9v-.9c.3.1.6.2.9.2 3.3.1 7.8 1.9 11.1 3.4 6.7 3 15.1 6.7 25.3 6.7h.6c9 0 19.7-.1 24-6.3 1.8-2.5 2.7-4.4.5-9.9 5-3 7-10 1-15 8-5 8-13 1-17 6.1-1.9 8.5-6.6 8.4-10.4z"></path> <path d="M121.1 70.7c1.9 2 5.1 2.1 7.2.2l.2-.2 31.2-32.2c9.1-9.4 8.6-24.9-1.6-33.5-8.8-7.5-22-6.2-30.1 2.2l-3.2 3.3-3.2-3.3c-8.1-8.4-21.3-9.7-30.1-2.2-10.1 8.6-10.7 24.2-1.6 33.5l31.2 32.2zM53.5 45.3C23.9 45.3 0 69.2 0 98.8s23.9 53.5 53.5 53.5 53.5-24 53.5-53.5-23.9-53.5-53.5-53.5zm18.8 24.6c5.5 0 9.9 4.4 9.9 9.9s-4.4 9.9-9.9 9.9-9.9-4.4-9.9-9.9c-.1-5.5 4.4-9.9 9.9-9.9zm-38.2 0c5.5 0 9.9 4.4 9.9 9.9s-4.4 9.9-9.9 9.9-9.9-4.4-9.9-9.9 4.4-9.9 9.9-9.9zm52.4 45.4c-8.2 9.8-20.2 15.5-33.1 15.5s-24.9-5.6-33.1-15.5c-3.9-4.7 3.2-10.6 7.1-5.9 6.5 7.7 15.9 12.2 26 12.2s19.5-4.4 26-12.2c3.8-4.7 10.9 1.2 7.1 5.9zm129.8-22.5c0-6.4-6.3-9.5-13.3-9.5h-24c1.5-6 10.3-13.8 10.3-22.8 0-15.5-10.1-17.2-15.2-17.2-4.3 0-6.2 8.3-7.2 12.2-1.1 4.6-2.2 9.3-5.4 12.4-6.7 6.8-10.3 15.3-18.4 23.5-.7-1.8-2.6-3.1-4.7-3.1h-10.7c-2.8 0-5.1 2.2-5.1 4.9V142c0 2.7 2.3 4.9 5.1 4.9h10.7c2.8 0 5.1-2.2 5.1-4.9v-.9c.3.1.6.2.9.2 3.3.1 7.8 1.9 11.1 3.4 6.7 3 15.1 6.7 25.3 6.7h.6c9 0 19.7-.1 24-6.3 1.8-2.5 2.7-4.4.5-9.9 5-3 7-10 1-15 8-5 8-13 1-17 6.1-1.9 8.5-6.6 8.4-10.4z"></path>
</symbol> </symbol>
<!-- Rounded svg arrow for tippy.js, allows to change border color -->
<symbol id="tippy-rounded-arrow" class="tippy-rounded-arrow" viewBox="0 0 16 6">
<path class="svg-arrow" d="M0 6s1.796-.013 4.67-3.615C5.851.9 6.93.006 8 0c1.07-.006 2.148.887 3.343 2.385C14.233 6.005 16 6 16 6H0z"/>
<path class="svg-content" d="m0 7s2 0 5-4c1-1 2-2 3-2 1 0 2 1 3 2 3 4 5 4 5 4h-16z"/>
</symbol>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -203,6 +203,11 @@
"@nodelib/fs.scandir" "2.1.3" "@nodelib/fs.scandir" "2.1.3"
fastq "^1.6.0" fastq "^1.6.0"
"@popperjs/core@^2.9.0":
version "2.11.0"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.0.tgz#6734f8ebc106a0860dff7f92bf90df193f0935d7"
integrity sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==
"@popperjs/core@v2.10.2": "@popperjs/core@v2.10.2":
version "2.10.2" version "2.10.2"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.10.2.tgz#0798c03351f0dea1a5a4cabddf26a55a7cbee590" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.10.2.tgz#0798c03351f0dea1a5a4cabddf26a55a7cbee590"
@ -4009,6 +4014,13 @@ timers-browserify@^1.0.1:
dependencies: dependencies:
process "~0.11.0" process "~0.11.0"
tippy.js@^6.3.7:
version "6.3.7"
resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c"
integrity sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==
dependencies:
"@popperjs/core" "^2.9.0"
tmp@^0.0.33: tmp@^0.0.33:
version "0.0.33" version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"