Comments (7)
I've found out the problem:
- Both
@flasher/flasher
and@flasher/flasher-sweetalert
contain CSS imports in the JS files, causing it to add 2 additional styling elements to the DOM: one for.fl-main-container
and one for.swal2-popup.swal2-toast
. @flasher/flasher-sweetalert
hasimport Swal from 'sweetalert2'
, which adds another additional style element to the DOM.- This is why I initially had a total of 3 additional
.swal2-popup.swal2-toast
style elements. - This should (for minified version) be
import Swal from 'sweetalert2/src/sweetalert2.min'
instead.
- This is why I initially had a total of 3 additional
What "worked" in the meantime was extracting partial contents from flasher-sweetalert/dist/index.js
to create the SweetAlertFactory
, and pass that to flasher
.
main.js
import flasher from "@flasher/flasher";
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
var SweetAlertFactory = (function () {
function SweetAlertFactory() {
this.queue = [];
}
SweetAlertFactory.prototype.success = function (message, title, options) {
this.flash('success', message, title, options);
};
SweetAlertFactory.prototype.info = function (message, title, options) {
this.flash('info', message, title, options);
};
SweetAlertFactory.prototype.warning = function (message, title, options) {
this.flash('warning', message, title, options);
};
SweetAlertFactory.prototype.error = function (message, title, options) {
this.flash('error', message, title, options);
};
SweetAlertFactory.prototype.flash = function (type, message, title, options) {
var notification = this.createNotification(type, message, title, options);
this.renderOptions({});
this.render({ notification: notification });
};
SweetAlertFactory.prototype.createNotification = function (type, message, title, options) {
if (typeof type === 'object') {
options = type;
type = options.type;
}
if (typeof message === 'object') {
options = message;
message = options.message;
}
if (typeof title === 'object') {
options = title;
title = options.title;
}
if (undefined === message) {
throw new Error('message option is required');
}
return {
type: type || 'info',
message: message,
title: title,
options: options
};
};
SweetAlertFactory.prototype.render = function (envelope) {
var _a;
var notification = envelope.notification;
var options = notification.options;
notification.type = notification.type || 'info';
options = __assign(__assign({}, options), { icon: ((options === null || options === void 0 ? void 0 : options.icon) || notification.type), text: ((options === null || options === void 0 ? void 0 : options.text) || notification.message) });
return (_a = this.swalToastr) === null || _a === void 0 ? void 0 : _a.fire(options).then(function (promise) {
window.dispatchEvent(new CustomEvent('flasher:sweetalert:promise', {
detail: {
promise: promise,
envelope: envelope
}
}));
});
};
SweetAlertFactory.prototype.renderOptions = function (options) {
this.swalToastr = this.swalToastr || Swal.mixin(__assign({ timer: (options.timer || 5000), timerProgressBar: (options.timerProgressBar || true) }, options));
document.addEventListener('turbo:before-cache', function () {
var _a;
if (Swal.isVisible()) {
(_a = Swal.getPopup()) === null || _a === void 0 ? void 0 : _a.style.setProperty('animation-duration', '0ms');
Swal.close();
}
});
};
SweetAlertFactory.prototype.addEnvelope = function (envelope) {
var _a;
(_a = this.queue) === null || _a === void 0 ? void 0 : _a.push(envelope);
};
SweetAlertFactory.prototype.resetQueue = function () {
this.queue = [];
};
SweetAlertFactory.prototype.renderQueue = function () {
return __awaiter(this, void 0, void 0, function () {
var i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
i = 0;
_a.label = 1;
case 1:
if (!(i < this.queue.length)) return [3, 4];
return [4, this.render(this.queue[i])];
case 2:
_a.sent();
_a.label = 3;
case 3:
i++;
return [3, 1];
case 4: return [2];
}
});
});
};
return SweetAlertFactory;
}());
flasher.addFactory("sweetalert", new SweetAlertFactory());
global.flasher = flasher;
Now if I add @sweetalert2/theme-dark
and import it, it shows the correctly styled dark SweetAlert2 toast. The additional inline CSS is no longer there, but the flasher inline style tag (with .fl-main-container
) is still in the DOM (as I could not easily figure out how to extract that part).
This is a really convoluted workaround for a problem which could be solved if the JS did not contain any CSS imports.
@yoeunes I propose to separate JS and CSS for all the packages (not just SweetAlert2).
from flasher-js.
Hey @ToshY 👋,
I wanted to reach out and let you know that I've just released v1.15.1
which I believe resolves the issue we've been discussing. Now, you'll find much more flexibility to adjust and override PHPFlasher
styles in a way that aligns better with your specific needs.
You can find a demo here. I truly hope you'll find this update beneficial!
I apologize if this took a bit longer than anticipated. Balancing my regular commitments with open-source work sometimes stretches my time a bit thin, but your patience is genuinely appreciated.
Please don't hesitate to dive into the demo and the updated version. I'm eager to hear your thoughts and any feedback you might have to improve this solution.
from flasher-js.
Hello @yoeunes 👋
I've looked at the demo and it's easy to understand, and while it doesn't fully correspond to my use case, after updating flasher to v1.15.1
I no longer have additional styles in the DOM and the dark styling is now correctly applied.
Please don't hesitate to dive into the demo and the updated version. I'm eager to hear your thoughts and any feedback you might have to improve this solution.
My use case is slightly different as I already had SweetAlert2 in my application (I'm not sure if this was clear from the initial problem statement). Therefore I also initially had the scripts and basic styles imported (in assets/js/main.js
and asssets/styles/global.scss
resp.) for SweetAlert and were already getting bundled by webpack.
Maybe seeing some code makes more sense than the explanation above so I will post my simplified setup here for you (and possible future readers).
assets/js/main.js
// SweetAlert (which was already being used in the application)
import Swal from 'sweetalert2/dist/sweetalert2.min' //note: this contains only JS
global.Swal = Swal;
// Flasher
import flasher from "@flasher/flasher";
import sweetalert from '@flasher/flasher-sweetalert';
flasher.addFactory("sweetalert", sweetalert);
global.flasher = flasher
assets/styles/global.scss
@import "~sweetalert2/dist/sweetalert2.min.css";
@import "~@sweetalert2/theme-dark/dark";
webpack.config.js
const Encore = require('@symfony/webpack-encore');
if (!Encore.isRuntimeEnvironmentConfigured()) {
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}
Encore
.setOutputPath('public/build/')
.setPublicPath('/build')
.addEntry('js/app', './assets/js/main.js')
.addStyleEntry('css/app', './assets/styles/global.scss')
.splitEntryChunks()
.enableSingleRuntimeChunk()
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
.enableVersioning(Encore.isProduction())
.configureBabel((config) => {})
.configureBabelPresetEnv((config) => {
config.useBuiltIns = 'usage';
config.corejs = 3;
})
.enableIntegrityHashes(Encore.isProduction())
.autoProvidejQuery()
;
module.exports = Encore.getWebpackConfig();
Note: In contrary to the demo, I now don't have to manually
.copyFiles
for the dark theme as it was already imported inassets/styles/global.scss
.
config/packages/flasher.yaml
flasher:
default: sweetalert
use_cdn: false
auto_translate: true
auto_render: true
flash_bag:
enabled: true
mapping:
success: [ 'success' ]
error: [ 'error', 'danger' ]
warning: [ 'warning', 'alarm' ]
info: [ 'info', 'notice', 'alert' ]
filter_criteria:
limit: 5
presets:
login:
type: 'info'
message: 'Welcome back'
options:
toast: true
position: bottom-end
showConfirmButton: false
timer: 30000
logout:
type: 'info'
message: 'Have a nice day'
options:
toast: true
position: bottom-end
showConfirmButton: false
timer: 30000
flasher_sweetalert:
scripts: ~
styles: ~
Note: In contrary to the demo, I now also don't have to set the
styles
key inflasher_sweetalert
, as no additional files were copied.
Result (disregard the symfony debug icon):
In conclusion: it works now 🙂
I apologize if this took a bit longer than anticipated. Balancing my regular commitments with open-source work sometimes stretches my time a bit thin, but your patience is genuinely appreciated.
The effort you've put into it is also much appreciated 🥇
from flasher-js.
@yoeunes Could you take a look at this issue and care to discuss the proposal?
from flasher-js.
Hello @ToshY,
Thank you for reporting this issue and investigate it.
I will examine it over the weekend and make the necessary improvements to ensure a cleaner version.
If you have the time and would like to contribute, please feel free to create a merge request with your proposed changes. I would be glad to review it and merge it into the codebase.
Thank you for your patience and for helping improve the package.
Best regards,
Younes
from flasher-js.
Hey @yoeunes 👋
Thank you for the response.
I would help if I could, but this is somewhat beyond my comfort zone as I have zero experience with typescript (or how to even compile it) at the moment of writing. That being said, I'm open to manually testing the final (compiled) results if that would be of any help. 🙂
To further elaborate on the proposed solution: I think the least intensive approach (to not cause any breaking changes for existing application) would be to keep the existing files that contain both the JS and CSS (as you have now), and create additional files separating both of them1. That way newer applications, using Webpack or other bundlers, can benefit from separately importing the JS and CSS, which solves the main issue described here. Think SweetAlert2 takes a similar approach,
I'll await your next response after examination. Keep up the good work! PHP Flasher is really nice and easy to use 👍
Footnotes
from flasher-js.
Thank you for your feedback, I'm glad that everything is working now!
from flasher-js.
Related Issues (3)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from flasher-js.