Quick Start Labels
https://vanillawebdev.blogspot.com/search/label/coding-tips
Coding Tips
4
https://vanillawebdev.blogspot.com/search/label/project-setup
Project Setup
6
https://vanillawebdev.blogspot.com/search/label/starter-code
Starter Code
6
Reading List
https://jackwhiting.co.uk/posts/lazy-loading-vanilla-js-with-webpack-laravel-mix
https://medium.com/free-code-camp/reducing-css-bundle-size-70-by-cutting-the-class-names-and-using-scope-isolation-625440de600b
Libraries
https://github.com/verlok/vanilla-lazyload
Developer Resources
https://webpack.js.org/configuration/output/
https://web.dev/articles/preload-critical-assets
Reading List
https://www.codemzy.com/blog/how-to-name-webpack-chunk
How to name a webpack chunk (including split and common chunks)
Reading List
Featured Post
https://vanillawebdev.blogspot.com/2024/02/installable-web-app.html
Make Your Web App Installable
February 16, 2025How to make your web app installable.
true
https://vanillawebdev.blogspot.com/search/label/homepage
homepage
https://vanillawebdev.blogspot.com/search/label/project-setup
project-setup
Featured Post
Sidebar Labels
https://vanillawebdev.blogspot.com/search/label/app-component
App Component
1
https://vanillawebdev.blogspot.com/search/label/coding-tips
Coding Tips
4
https://vanillawebdev.blogspot.com/search/label/css-tips
CSS Tips
4
https://vanillawebdev.blogspot.com/search/label/data-server
Data Server
2
https://vanillawebdev.blogspot.com/search/label/layout
Layout
1
https://vanillawebdev.blogspot.com/search/label/project-setup
Project Setup
6
https://vanillawebdev.blogspot.com/2025/02/starting-new-project.html
https://vanillawebdev.blogspot.com/2025/02/file-caching.html
https://vanillawebdev.blogspot.com/
https://vanillawebdev.blogspot.com/2025/02/dialog-builder.html
Dialog Builder
February 03, 2025
2025
February
03
09:06 AM
Build custom dialog with lazy load.
HTML
index.html
<!DOCTYPE html>
<html>
<head>
<link href="style.css" rel="stylesheet"/>
</head>
<body>
[btn 'Open dialog' onclick="openDialog()"]
<div class="_dialogTemplates" hidden>
<!-- # dialogs -->
<!-- ========= -->
<template class="_dialogLoading">
[dialog .wg-windog data-empty="true"
[ .backdrop data-backdrop
[ .loading
<svg viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg"><circle cx="25" cy="25" r="20" fill="none" stroke="#ffffffaa" stroke-dasharray="100" stroke-dashoffset="75" stroke-width="4"/></svg>
]
]
]
</template>
</div>
<script src="https://cdn.jsdelivr.net/gh/tmpmachine/vanilla-framework@7ea8ba5/js/infrastructure/libs/windog.js"></script>
<script src="https://cdn.jsdelivr.net/gh/tmpmachine/vanilla-framework@7ea8ba5/js/infrastructure/factories/dialog-factory.js"></script>
<script src="dialogs.js"></script>
</body>
</html>
dialogs.html
<template class="_dialogPromptTextarea">
[dialog .wg-windog
<!-- # textarea -->
[ .backdrop]
<div class="inner">
[ .wrapper
[br]
<form method="dialog" data-ref="form">
[l data-slot="message" for="i1"]
[t data-slot="input" name="input" #i1]
[br]
[br]
[ .flex .justify-between .gap-1
[btn 'Reset' type="reset" data-onclick="reset"]
[
[btn 'Ok' value="ok" .primary]
[btn 'Cancel' .outline]
]
]
</form>
]
</div>
]
</template>
CSS
style.css
/* # windog */
.wg-windog {
& {
--sec: 250ms;
}
& {
transition: display var(--sec) allow-discrete, overlay var(--sec) allow-discrete, opacity var(--sec);
padding: 0;
background: transparent;
border: 0;
overflow: hidden;
height: 100%;
width: 100%;
}
&:not(.transitionless)::backdrop {
transition: opacity var(--sec);
opacity: 0;
}
&::backdrop {
background: rgb(0 0 0 / 60%);
}
.inner {
height: 100%;
display: flex;
overflow: hidden;
width: 100%;
}
.wrapper {
&{
transition: opacity var(--sec), transform var(--sec);
opacity: 0;
transform: scale(0.95);
min-width: 360px;
overflow: auto;
max-height: 100%;
max-width: 100%;
margin: auto;
position: relative;
}
&:not([class*="skin"]) {
border: 3px solid;
border-radius: 0.4rem;
background: white;
padding: 1rem;
}
&.varian-h100 {
height: 100%;
}
&.varian-flex{
&{
display: flex;
flex-direction: column;
}
.body{
flex: 1;
overflow: auto;
}
}
}
&[open] .wrapper {
& {
transform: scale(1);
opacity: 1;
}
@starting-style {
opacity: 0;
transform: scale(0.95);
}
}
&[open] {
&::backdrop {
opacity: 1;
}
@starting-style {
&::backdrop{
opacity: 0;
}
}
}
.backdrop {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
}
button:focus {
border-color: #4CAF50;
box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.3);
}
.loading {
float: right;
position: relative;
display: flex;
align-items: center;
flex-direction: column;
gap: 4px;
margin: 8px;
}
.loading svg {
animation: loading-rotate-NjM2MTA3MjM 3s linear infinite;
}
.loading::after{
content: 'Loading';
color: white;
font-size: 0.6rem;
}
}
@keyframes loading-rotate-NjM2MTA3MjM {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
JS
index.js
const dialogTextarea = DialogFactory({
src: 'dialogs.html',
templateSelector: '._dialogPromptTextarea',
});
async function openDialog() {
let dialogFormResult = await dialogTextarea.Show_();
console.log(dialogFormResult);
alert('Check console for output');
}
https://www.blogger.com/comment/fullpage/post/8166404610182826392/754449700877012436
true
https://vanillawebdev.blogspot.com/search/label/%40lvc
@lvc
https://vanillawebdev.blogspot.com/2025/02/starting-new-project.html
https://vanillawebdev.blogspot.com/2025/02/file-caching.html
https://vanillawebdev.blogspot.com/