mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-10-26 19:15:09 +00:00
Refine dialog component (#26033)
* Init * push * Refine * Format * Refine * Update index.js
This commit is contained in:
1 parent
f972b9d819
commit
a3f2c15bc2
7 files changed
+90
-45
No files matched your search
@@ -17,5 +17,6 @@ module.exports = {
|
||||
"number-max-precision": 5,
|
||||
"no-duplicate-selectors": null,
|
||||
"hue-degree-notation": "number",
|
||||
"scss/operator-no-newline-after": null,
|
||||
},
|
||||
};
|
||||
@@ -28,9 +28,13 @@ THE SOFTWARE.
|
||||
Creates a button bar at the bottom of the page for things like "Submit".
|
||||
The actual buttons should be specified as the body of this tag.
|
||||
This area will always be visible at the bottom of the screen.
|
||||
|
||||
<st:attribute name="borderless">
|
||||
Hides the border of the bottom app bar unless its overlaying content.
|
||||
</st:attribute>
|
||||
</st:documentation>
|
||||
|
||||
<div class="jenkins-bottom-app-bar__shadow"></div>
|
||||
<div class="jenkins-bottom-app-bar__shadow ${attrs.borderless ? 'jenkins-bottom-app-bar__shadow--borderless' : ''}"></div>
|
||||
<div id="bottom-sticker">
|
||||
<div class="bottom-sticker-inner jenkins-buttons-row jenkins-buttons-row--equal-width">
|
||||
<d:invokeBody />
|
||||
|
||||
@@ -13,6 +13,7 @@ let _defaults = {
|
||||
hideCloseButton: false,
|
||||
allowEmpty: false,
|
||||
submitButton: false,
|
||||
preventCloseOnOutsideClick: false,
|
||||
};
|
||||
|
||||
let _typeClassMap = {
|
||||
@@ -39,11 +40,12 @@ Dialog.prototype.init = function () {
|
||||
this.dialog.style.minWidth = this.options.minWidth;
|
||||
document.body.appendChild(this.dialog);
|
||||
|
||||
if (this.options.title != null) {
|
||||
const title = createElementFromHtml(`<div class='jenkins-dialog__title'/>`);
|
||||
// Append title element
|
||||
const title = createElementFromHtml(
|
||||
`<div class='jenkins-dialog__title'><span></span></div>`,
|
||||
);
|
||||
this.dialog.appendChild(title);
|
||||
title.innerText = this.options.title;
|
||||
}
|
||||
title.querySelector("span").innerText = this.options.title;
|
||||
|
||||
if (this.dialogType === "modal") {
|
||||
if (this.options.content != null) {
|
||||
@@ -55,22 +57,24 @@ Dialog.prototype.init = function () {
|
||||
}
|
||||
if (this.options.hideCloseButton !== true) {
|
||||
const closeButton = createElementFromHtml(`
|
||||
<button class="jenkins-dialog__close-button jenkins-button">
|
||||
<button class="jenkins-dialog__title__button jenkins-dialog__title__close-button jenkins-button">
|
||||
<span class="jenkins-visually-hidden">Close</span>
|
||||
${CLOSE}
|
||||
</button>
|
||||
`);
|
||||
this.dialog.appendChild(closeButton);
|
||||
title.append(closeButton);
|
||||
closeButton.addEventListener("click", () =>
|
||||
this.dialog.dispatchEvent(new Event("cancel")),
|
||||
);
|
||||
}
|
||||
if (!this.options.preventCloseOnOutsideClick) {
|
||||
this.dialog.addEventListener("click", function (e) {
|
||||
if (e.target !== e.currentTarget) {
|
||||
return;
|
||||
}
|
||||
this.dispatchEvent(new Event("cancel"));
|
||||
});
|
||||
}
|
||||
this.ok = null;
|
||||
} else {
|
||||
this.form = null;
|
||||
|
||||
@@ -77,6 +77,7 @@ $semantics: (
|
||||
--header-height: 4.125rem;
|
||||
|
||||
// App bar
|
||||
--bottom-app-bar-padding: 0.875rem;
|
||||
--bottom-app-bar-shadow: color-mix(
|
||||
in sRGB,
|
||||
var(--text-color-secondary) 8%,
|
||||
@@ -201,8 +202,7 @@ $semantics: (
|
||||
--dialog-background: var(--card-background);
|
||||
--dialog-box-shadow:
|
||||
var(--jenkins-border--subtle-shadow), 0 5px 25px rgb(0 0 10 / 0.025),
|
||||
0 0 1.5px color-mix(in sRGB, var(--black) 20%, transparent),
|
||||
inset 0 0 0 1px rgb(255 255 255 / 0.05);
|
||||
0 0 1.5px color-mix(in sRGB, var(--black) 20%, transparent);
|
||||
|
||||
::backdrop {
|
||||
--dialog-backdrop-backdrop-filter: blur(0.25px);
|
||||
|
||||
@@ -125,25 +125,16 @@
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
$bottom-app-bar-padding: 0.875rem;
|
||||
|
||||
.jenkins-bottom-app-bar__shadow {
|
||||
--semi-translucent: color-mix(in sRGB, var(--background) 75%, transparent);
|
||||
--semi-translucent: color-mix(in sRGB, var(--background) 70%, transparent);
|
||||
|
||||
position: sticky;
|
||||
height: calc(
|
||||
2.375rem + ($bottom-app-bar-padding * 2) + 1px + var(--jenkins-border-width)
|
||||
2.375rem + (var(--bottom-app-bar-padding) * 2) + 1px +
|
||||
var(--jenkins-border-width)
|
||||
);
|
||||
bottom: -1px;
|
||||
margin-bottom: calc((2.375rem + $bottom-app-bar-padding) * -1);
|
||||
backdrop-filter: blur(20px);
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
var(--background),
|
||||
var(--semi-translucent) 3rem,
|
||||
var(--semi-translucent) calc(100% - 3rem),
|
||||
var(--background)
|
||||
);
|
||||
margin-bottom: calc((2.375rem + var(--bottom-app-bar-padding)) * -1);
|
||||
border-top: var(--jenkins-border-width) solid var(--jenkins-border-color);
|
||||
z-index: 997;
|
||||
|
||||
@@ -167,7 +158,33 @@ $bottom-app-bar-padding: 0.875rem;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&--borderless:not(&--stuck) {
|
||||
border-top-color: transparent;
|
||||
}
|
||||
|
||||
&--borderless {
|
||||
margin-top: calc(
|
||||
(var(--bottom-app-bar-padding) + var(--jenkins-border-width)) * -1
|
||||
);
|
||||
}
|
||||
|
||||
&--stuck {
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
var(--background),
|
||||
var(--background) 3rem,
|
||||
var(--semi-translucent),
|
||||
var(--background) calc(100% - 3rem),
|
||||
var(--background)
|
||||
);
|
||||
|
||||
&::after {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
@@ -183,5 +200,5 @@ $bottom-app-bar-padding: 0.875rem;
|
||||
|
||||
.bottom-sticker-inner {
|
||||
position: relative;
|
||||
padding: $bottom-app-bar-padding 0;
|
||||
padding: var(--bottom-app-bar-padding) 0;
|
||||
}
|
||||
@@ -2,6 +2,8 @@ $jenkins-dialog-padding: 1.25rem;
|
||||
|
||||
.jenkins-dialog {
|
||||
--background: var(--dialog-background);
|
||||
--section-padding: #{$jenkins-dialog-padding};
|
||||
--bottom-app-bar-padding: #{$jenkins-dialog-padding};
|
||||
|
||||
border-radius: 1rem;
|
||||
border: none;
|
||||
@@ -9,11 +11,12 @@ $jenkins-dialog-padding: 1.25rem;
|
||||
box-shadow: var(--dialog-box-shadow);
|
||||
animation: jenkins-dialog-animate-in 0.25s cubic-bezier(0, 0.68, 0.5, 1.5);
|
||||
overflow: hidden;
|
||||
padding: $jenkins-dialog-padding 0 0 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $jenkins-dialog-padding;
|
||||
outline: none;
|
||||
|
||||
// Thin highlight for dark themes to differentiate the dialog from its backdrop
|
||||
outline: 1px solid rgb(255 255 255 / 0.05);
|
||||
|
||||
&::backdrop {
|
||||
background: color-mix(
|
||||
@@ -26,13 +29,26 @@ $jenkins-dialog-padding: 1.25rem;
|
||||
}
|
||||
|
||||
&__title {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
font-size: 1rem;
|
||||
font-weight: var(--font-bold-weight);
|
||||
padding: 0 $jenkins-dialog-padding;
|
||||
padding: $jenkins-dialog-padding;
|
||||
color: var(--text-color);
|
||||
overflow-wrap: anywhere;
|
||||
text-box: cap alphabetic;
|
||||
margin-top: 0.5625rem;
|
||||
|
||||
&__button {
|
||||
padding: 0;
|
||||
width: 2rem;
|
||||
min-height: 2rem;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
&__close-button {
|
||||
margin-left: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
&__contents {
|
||||
@@ -62,7 +78,7 @@ $jenkins-dialog-padding: 1.25rem;
|
||||
|
||||
&__buttons {
|
||||
display: flex;
|
||||
padding: 0 $jenkins-dialog-padding $jenkins-dialog-padding;
|
||||
padding: $jenkins-dialog-padding;
|
||||
justify-content: right;
|
||||
flex-direction: row-reverse;
|
||||
gap: 1.25rem;
|
||||
@@ -80,16 +96,6 @@ $jenkins-dialog-padding: 1.25rem;
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
&__close-button {
|
||||
position: absolute;
|
||||
top: $jenkins-dialog-padding;
|
||||
right: $jenkins-dialog-padding;
|
||||
padding: 0;
|
||||
width: 2rem;
|
||||
min-height: 2rem;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
&[closing] {
|
||||
animation: jenkins-dialog-animate-out 0.1s linear;
|
||||
|
||||
@@ -97,6 +103,12 @@ $jenkins-dialog-padding: 1.25rem;
|
||||
animation: jenkins-dialog-backdrop-animate-out 0.1s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.jenkins-bottom-app-bar__shadow {
|
||||
margin-bottom: calc(
|
||||
(2.375rem + calc(var(--bottom-app-bar-padding) * 2)) * -1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes jenkins-dialog-backdrop-animate-in {
|
||||
|
||||
@@ -1781,22 +1781,29 @@ function rowvgStartEachRow(recursive, f) {
|
||||
},
|
||||
);
|
||||
|
||||
window.addEventListener("load", function () {
|
||||
// Add a class to the bottom bar when it's stuck to the bottom of the screen
|
||||
const el = document.querySelector(".jenkins-bottom-app-bar__shadow");
|
||||
if (el) {
|
||||
Behaviour.specify(
|
||||
".jenkins-bottom-app-bar__shadow",
|
||||
"jenkins-bottom-app-bar__shadow",
|
||||
0,
|
||||
function (el) {
|
||||
const dialog = el.closest("dialog");
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([e]) =>
|
||||
e.target.classList.toggle(
|
||||
"jenkins-bottom-app-bar__shadow--stuck",
|
||||
e.intersectionRatio < 1,
|
||||
),
|
||||
{ threshold: [1] },
|
||||
{
|
||||
threshold: [1],
|
||||
root: dialog || null,
|
||||
},
|
||||
);
|
||||
|
||||
observer.observe(el);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Function that provides compatibility to the checkboxes without title on an f:entry
|
||||
|
||||
Reference in new issue
Block a user