Skip to content

Commit 835e3d6

Browse files
committed
Closes #19 - fixed autofocus bug
1 parent ff99d98 commit 835e3d6

File tree

5 files changed

+60
-186
lines changed

5 files changed

+60
-186
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
12+
- autofocus bug ([#19](https://github.com/codewithkyle/notifyjs/issues/19))
13+
1014
## [2.1.1] - 2021-01-21
1115

1216
### Fixed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@codewithkyle/notifyjs",
3-
"version": "2.1.1",
3+
"version": "3.0.0",
44
"description": "A simple JavaScript library for creating and managing toaster & snackbar notifications",
55
"main": "notify.js",
66
"files": [

src/notifier.ts

Lines changed: 49 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
import { SnackbarNotification, ToasterNotification, NotificationButton } from "./types";
1+
import { SnackbarNotification, ToasterNotification } from "./types";
22
import { SnackbarComponent } from "./snackbar-component";
33
import { ToastComponent } from "./toast-component";
44

55
export class Notifier {
66
private snackbarQueue: Array<SnackbarNotification>;
77
private toaster: Array<ToasterNotification>;
88
private time: number;
9+
private shell: HTMLElement;
910

1011
constructor() {
12+
this.shell = document.createElement("toaster-component");
13+
document.body.appendChild(this.shell);
1114
this.snackbarQueue = [];
1215
this.toaster = [];
1316
this.time = performance.now();
@@ -61,209 +64,70 @@ export class Notifier {
6164
}
6265

6366
public snackbar(settings: Partial<SnackbarNotification>) {
64-
const snackbar: Partial<SnackbarNotification> = {};
67+
const snackbar: SnackbarNotification = Object.assign({
68+
message: "Snackbar notificaitons require a message",
69+
uid: this.uid(),
70+
el: null,
71+
duration: 30,
72+
closeable: true,
73+
buttons: [],
74+
force: true,
75+
classes: [],
76+
autofocus: true,
77+
}, settings);
6578

66-
if (!settings?.message || settings?.message?.length === 0) {
67-
console.error("Snackbar notificaitons require a message");
68-
return;
79+
if (!Array.isArray(snackbar.buttons)) {
80+
snackbar.buttons = [snackbar.buttons];
6981
}
7082

71-
snackbar.message = settings.message;
72-
snackbar.uid = this.uid();
73-
snackbar.el = null;
74-
75-
let classes: Array<string> = [];
76-
if (settings?.classes) {
77-
if (Array.isArray(settings.classes)) {
78-
classes = settings.classes;
79-
} else {
80-
classes = [settings.classes];
81-
}
82-
}
83-
snackbar.classes = classes;
84-
85-
if (typeof settings?.duration === "number" || settings?.duration === Infinity) {
86-
snackbar.duration = settings.duration;
87-
} else {
88-
snackbar.duration = 3;
89-
}
90-
91-
if (typeof settings?.closeable !== "undefined" && typeof settings?.closeable === "boolean") {
92-
snackbar.closeable = settings?.closeable;
93-
} else {
94-
snackbar.closeable = true;
95-
}
96-
97-
if (typeof settings?.force !== "undefined" && typeof settings?.force === "boolean") {
98-
snackbar.force = settings?.force;
99-
} else {
100-
snackbar.force = false;
101-
}
102-
103-
if (typeof settings?.autofocus !== "undefined" && typeof settings?.autofocus === "boolean"){
104-
snackbar.autofocus = settings.autofocus;
105-
}else{
106-
snackbar.autofocus = true;
107-
}
108-
109-
let buttons: Array<NotificationButton> = [];
110-
if (settings?.buttons) {
111-
if (Array.isArray(settings.buttons)) {
112-
buttons = settings.buttons;
113-
} else {
114-
buttons = [settings.buttons];
115-
}
116-
}
117-
snackbar.buttons = buttons;
118-
for (let i = 0; i < snackbar.buttons.length; i++) {
119-
if (snackbar.buttons[i]?.classes) {
120-
if (Array.isArray(snackbar.buttons[i].classes)) {
121-
snackbar.buttons[i].classes = snackbar.buttons[i].classes;
122-
} else {
123-
// @ts-ignore
124-
snackbar.buttons[i].classes = [snackbar.buttons[i].classes];
125-
}
126-
} else {
127-
snackbar.buttons[i].classes = [];
128-
}
129-
if (!snackbar.buttons[i]?.ariaLabel) {
130-
snackbar.buttons[i].ariaLabel = null;
131-
}
132-
if (!snackbar.buttons[i]?.label) {
133-
console.error("Snackbar buttons require a label");
134-
snackbar.buttons[i].label = null;
135-
}
136-
if (!snackbar.buttons[i]?.callback) {
137-
console.error("Snackbar buttons require a callback function");
138-
snackbar.buttons[i].callback = () => {};
139-
}
140-
if (!snackbar.buttons[i]?.autofocus){
141-
snackbar.buttons[i].autofocus = false;
142-
}else{
143-
snackbar.autofocus = false;
144-
}
83+
if (!Array.isArray(snackbar.classes)) {
84+
snackbar.classes = [snackbar.classes];
14585
}
14686

14787
if (snackbar.force && this.snackbarQueue.length) {
14888
if (this.snackbarQueue[0]?.el?.isConnected){
14989
this.snackbarQueue[0].el.remove();
15090
}
151-
this.snackbarQueue.splice(0, 1, snackbar as SnackbarNotification);
91+
this.snackbarQueue.splice(0, 1, snackbar);
15292
} else {
153-
this.snackbarQueue.push(snackbar as SnackbarNotification);
93+
this.snackbarQueue.push(snackbar);
15494
}
15595
}
15696

15797
public toast(settings: Partial<ToasterNotification>) {
158-
const toast: Partial<ToasterNotification> = {};
159-
160-
if (!settings?.message || settings?.message?.length === 0) {
161-
console.error("Toast notificaitons require a message");
162-
return;
163-
} else if (!settings?.title || settings?.title?.length === 0) {
164-
console.error("Toast notificaitons require a title");
165-
return;
166-
}
167-
168-
toast.title = settings.title;
169-
toast.message = settings.message;
170-
toast.uid = this.uid();
171-
172-
let classes: Array<string> = [];
173-
if (settings?.classes) {
174-
if (Array.isArray(settings.classes)) {
175-
classes = settings.classes;
176-
} else {
177-
classes = [settings.classes];
178-
}
179-
}
180-
toast.classes = classes;
181-
182-
if (typeof settings?.duration === "number" || settings?.duration === Infinity) {
183-
toast.duration = settings.duration;
184-
} else {
185-
toast.duration = 3;
186-
}
187-
188-
if (typeof settings?.closeable !== "undefined" && typeof settings?.closeable === "boolean") {
189-
toast.closeable = settings.closeable;
190-
} else {
191-
toast.closeable = true;
192-
}
193-
194-
if (settings?.icon && typeof settings?.icon === "string") {
195-
toast.icon = settings.icon;
196-
} else {
197-
toast.icon = null;
198-
}
199-
200-
if (typeof settings?.autofocus !== "undefined" && typeof settings?.autofocus === "boolean"){
201-
toast.autofocus = settings.autofocus;
202-
}else{
203-
toast.autofocus = false;
204-
}
205-
206-
let buttons: Array<NotificationButton> = [];
207-
if (settings?.buttons) {
208-
if (Array.isArray(settings.buttons)) {
209-
buttons = settings.buttons;
210-
} else {
211-
buttons = [settings.buttons];
212-
}
213-
}
214-
toast.buttons = buttons;
215-
for (let i = 0; i < toast.buttons.length; i++) {
216-
if (toast.buttons[i]?.classes) {
217-
if (Array.isArray(toast.buttons[i].classes)) {
218-
toast.buttons[i].classes = toast.buttons[i].classes;
219-
} else {
220-
// @ts-ignore
221-
toast.buttons[i].classes = [toast.buttons[i].classes];
222-
}
223-
} else {
224-
toast.buttons[i].classes = [];
225-
}
226-
if (!toast.buttons[i]?.ariaLabel) {
227-
toast.buttons[i].ariaLabel = null;
228-
}
229-
if (!toast.buttons[i]?.label) {
230-
console.error("Toaster buttons require a label");
231-
toast.buttons[i].label = null;
232-
}
233-
if (!toast.buttons[i]?.callback) {
234-
console.error("Toaster buttons require a callback function");
235-
toast.buttons[i].callback = () => {};
236-
}
237-
if (!toast.buttons[i]?.autofocus){
238-
toast.buttons[i].autofocus = false;
239-
}else{
240-
toast.autofocus = false;
241-
}
242-
}
243-
244-
if (settings?.timer && toast.duration !== Infinity){
245-
if (settings.timer === "vertical" || settings.timer === "horizontal"){
246-
toast.timer = settings.timer;
247-
}else{
248-
console.error("Toaster timer value only accpets 'vertical' or 'horizontal'");
249-
toast.timer = null;
250-
}
98+
const toast: ToasterNotification = Object.assign({
99+
title: "Title Required",
100+
message: "Toast notificaitons require a message",
101+
closeable: true,
102+
icon: null,
103+
duration: 30,
104+
classes: [],
105+
uid: this.uid(),
106+
el: null,
107+
timerEl: null,
108+
autofocus: true,
109+
buttons: [],
110+
timer: null,
111+
timerDuration: 30,
112+
}, settings);
113+
114+
if (!Array.isArray(toast.buttons)) {
115+
toast.buttons = [toast.buttons];
116+
}
117+
118+
if (!Array.isArray(toast.classes)) {
119+
toast.classes = [toast.classes];
120+
}
121+
122+
if (toast.duration !== Infinity && toast.timer === "vertical" || toast.timer === "horizontal"){
251123
toast.timerDuration = toast.duration;
252-
}else{
253-
toast.timer = null;
254124
}
255125

256-
toast.el = new ToastComponent(toast as ToasterNotification);
126+
toast.el = new ToastComponent(toast);
257127
if (toast.timer){
258128
toast.timerEl = toast.el.querySelector("toast-timer");
259129
}
260-
this.toaster.push(toast as ToasterNotification);
261-
262-
let shell = document.body.querySelector("toaster-component") || null;
263-
if (!shell) {
264-
shell = document.createElement("toaster-component");
265-
document.body.appendChild(shell);
266-
}
267-
shell.appendChild(toast.el);
130+
this.toaster.push(toast);
131+
this.shell.appendChild(toast.el);
268132
}
269133
}

src/snackbar-component.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ export class SnackbarComponent extends HTMLElement {
7575
if (this.settings.autofocus){
7676
const closeButton:HTMLButtonElement = this.querySelector(".js-snackbar-close");
7777
if (closeButton){
78+
// @ts-ignore
79+
document.activeElement.blur();
7880
closeButton.focus();
7981
}
8082
}
@@ -83,6 +85,8 @@ export class SnackbarComponent extends HTMLElement {
8385
if (this.settings.buttons[i].autofocus){
8486
const button:HTMLButtonElement = this.querySelector(`button[data-index="${i}"]`);
8587
if (button){
88+
// @ts-ignore
89+
document.activeElement.blur();
8690
button.focus();
8791
break;
8892
}

src/toast-component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ export class ToastComponent extends HTMLElement {
9797
if (this.settings.autofocus){
9898
const closeButton:HTMLButtonElement = this.querySelector(".js-toast-close");
9999
if (closeButton){
100+
// @ts-ignore
101+
document.activeElement.blur();
100102
closeButton.focus();
101103
}
102104
}

0 commit comments

Comments
 (0)