@planningcenter/sweetalert2
A Planning Center theme for SweetAlert2.
This theme supports products using SweetAlert2 at v10 or higher.
In addition to a theme stylesheet, icons and common options are provided via JS objects.
Install package
Add this package and its dependency, sweetalert2, to your project.
yarn add @planningcenter/sweetalert2 sweetalert2
Import SweetAlert2 without the default theme
Out of the box, SweetAlert2 injects a default theme stylesheet. To disable the default behavior, import SweetAlert2 from the nested /dist directory.
import Swal from "sweetalert2/dist/sweetalert2";
The sweetalert2/dist/sweetalert2 path does not inject the default stylesheet.
Apply CSS theme
This stylesheet handles the basics - font styles, colors, padding, margins - outlined in the specification. If you've already implemented the updated icons then this stylesheet may be all you need to ensure parity with the spec.
Import the Planning Center SweetAlert2 theme
CSS
@import "@planningcenter/sweetalert2/css/sweetalert2.css";
SCSS
@import "@planningcenter/sweetalert2/css/sweetalert2";
In Sass, be sure to omit the .css file extension.
Sass @import directives are tricky. Sass decides whether to use Sass import or CSS import based on the presence of a .css extension. In our environments, you want to force the Sass import by omitting the .css extension.
Example
https://codesandbox.io/s/planningcentersweetalert2-swal-v10-minimal-fv71h?file=/src/index.js
Apply JS options objects for icons and button colors
planningcenter/sweetalert2 exposes configuration objects for standard alerts and confirm SweetAlerts.
The options are imported and spread over SweetAlert calls for consistency.
import Swal from "sweetalert2/dist/sweetalert2";
import { standardConfirmOptions } from "@planningcenter/sweetalert2";
Swal.fire({
...standardConfirmOptions,
titleText: `This site uses cookies`,
text: `We use cookies to store your personal preferences. Please accept use of cookies for optimal performance.`,
confirmButtonText: `Yes, I accept cookies`,
cancelButtonText: `No, don't use cookies`,
});
Live example
https://codesandbox.io/s/planningcentersweetalert2-swal-v10-9qvwr
Available options
These are options objects available from this library.
The most up-to-date resource is always source.
import {
standardAlertOptions,
successAlertOptions,
errorAlertOptions,
standardConfirmOptions,
createConfirmOptions,
destroyConfirmOptions,
} from "@planningcenter/sweetalert2";
Create convenience functions using mixin() (recommended)
You may prefer the ergonomics of a localized functions over multiple imports and option spreading. Here's how we suggest making those convenience functions available to your app.
alert.js
import Swal from "sweetalert2/dist/sweetalert2";
import {
standardAlertOptions,
successAlertOptions,
errorAlertOptions,
standardConfirmOptions,
createConfirmOptions,
destroyConfirmOptions,
} from "@planningcenter/sweetalert2";
export const alert = Swal.mixin(standardAlertOptions);
export const alertSuccess = Swal.mixin(successAlertOptions);
export const alertError = Swal.mixin(errorAlertOptions);
export const confirm = Swal.mixin(standardConfirmOptions);
export const confirmDestroy = Swal.mixin(destroyConfirmOptions);
export const confirmCreate = Swal.mixin(createConfirmOptions);
some-app-module.js
import * as alerts from "./alerts";
alerts.confirm.fire({
titleText: `This site uses cookies`,
text: `We use cookies to store your personal preferences. Please accept use of cookies for optimal performance.`,
confirmButtonText: `Yes, I accept cookies`,
cancelButtonText: `No, don't use cookies`,
});
return alerts.alert.fire(
"This site uses cookies",
"We use cookies to store your personal preferences. Please accept use of cookies for optimal performance."
);
Example
https://codesandbox.io/s/planningcentersweetalert2-swal-v10-0qx9i?file=/src/alerts.js
Wrapping .fire() for migration ease
If you're migrating a lot of code and want to preserve an old fire method, you can wrap the call — passing arguments — like so:
export const fire = (...args) =>
Swal.mixin({
}).fire(...args);
Using global window.Swal
Examples above use modules. If you're app uses Swal as a global, your implementation might look something like this:
import sweetalert from "sweetalert2/dist/sweetalert2";
window.Swal = {
alert: sweetalert.mixin(standardAlertOptions),
alertSuccess: sweetalert.mixin(successAlertOptions),
alertError: sweetalert.mixin(errorAlertOptions),
confirm: sweetalert.mixin(standardConfirmOptions),
confirmDestroy: sweetalert.mixin(destroyConfirmOptions),
confirmCreate: sweetalert.mixin(createConfirmOptions),
fire: (...args) =>
sweetalert
.mixin({ reverseButtons: true, showCancelButton: true })
.fire(...args),
};
Create an alert facade (not recommended)
Implementing a facade is an option. It's helpful in three cases:
- Switching between SweetAlert* versions
- Switching between SweetAlert* and alternative alert library
- Strategic selection/elimination of SweetAlert* features
The primary downside of a facade is that implementors take on the full burdon of documentation, testing, and implementation.
People implementas Alert, which a trasparent facade.
If you implement a facade, implement an opaque facade — not exposing access to the underlying fire method. This will prevent it from becoming a [leaky abstraction] where — in an effort to unexposed library features — consumers reach thru the facade to manipulate the dependency directly. This completely eliminates the value of a facade for transitioning from one library/API to another.
If not actively transitioning between libraries, create convenience functions using mixin instead.
Why this theme doesn't expose a facade
Library facades that live behind a module boundary are difficult to maintain in a multi-app ecosystem. It shifts the library dependency from peerDependency to dependency. This means that a local (app) changes can't be made without library intervention. These interventions might demand consensus from other apps — which is difficult (if not impossible) to get.
Maintaining a peerDependency allows apps to retain full local control over local dependencies while utilizing the theme and shared options.
Further Reading
SweetAlert2
Planning Center
Code