Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import static org.patternfly.style.Classes.plain;
import static org.patternfly.style.Classes.progress;
import static org.patternfly.style.Classes.small;
import static org.patternfly.style.Classes.stateful;
import static org.patternfly.style.Classes.tertiary;
import static org.patternfly.style.Classes.warning;
import static org.patternfly.style.Size.lg;
Expand Down Expand Up @@ -251,6 +252,10 @@ public Button control() {
return css(modifier(control));
}

public Button stateful() {
return css(modifier(stateful));
}

public Button block() {
return css(modifier(block));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
/*
* Copyright 2023 Red Hat
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.patternfly.component.notification.badge;

import java.util.Objects;

import org.jboss.elemento.logger.Logger;
import org.patternfly.component.BaseComponent;
import org.patternfly.component.ComponentIcon;
import org.patternfly.component.ComponentType;
import org.patternfly.component.button.Button;
import org.patternfly.core.Aria;
import org.patternfly.handler.ComponentHandler;
import org.patternfly.icon.PredefinedIcon;
import org.patternfly.style.Classes;

import elemental2.dom.Element;
import elemental2.dom.HTMLElement;

import static org.patternfly.component.button.Button.button;
import static org.patternfly.component.notification.badge.NotificationBadgeVariant.attention;
import static org.patternfly.component.notification.badge.NotificationBadgeVariant.read;
import static org.patternfly.component.notification.badge.NotificationBadgeVariant.unread;
import static org.patternfly.style.Classes.modifier;

/**
* A notification badge is a visual indicator that alerts users about incoming notifications.
* @see <a href="https://www.patternfly.org/components/notification-badge">PatternFly Notification Badge</a>
*/
public class NotificationBadge
extends BaseComponent<HTMLElement, NotificationBadge> implements ComponentIcon<HTMLElement, NotificationBadge> {

// ------------------------------------------------------ factory

public static NotificationBadge notificationBadge() {
return new NotificationBadge(button().stateful());
}

// ------------------------------------------------------ instance state

private static final Logger logger = Logger.getLogger(NotificationBadge.class.getName());

private final Button button;
private int count = 0;
private boolean expanded = false;
private NotificationBadgeVariant variant;
private Element customNormalIcon;
private Element customAttentionIcon;

private NotificationBadge(Button button) {
super(ComponentType.NotificationBadge, button.element());
this.button = button;
read();
ariaExpanded(false);
}

@Override
public NotificationBadge that() {
return this;
}

public boolean expanded() {
return expanded;
}

// ------------------------------------------------------ configuration API

public NotificationBadge ariaLabel(String ariaLabel) {
return aria(Aria.label, ariaLabel);
}

// ------------------------------------------------------ variants

public NotificationBadge read() {
return variant(read);
}

public NotificationBadge unread() {
return variant(unread);
}

public NotificationBadge attention() {
return variant(attention);
}

public NotificationBadge variant(NotificationBadgeVariant variant) {
if (variant == null) {
logger.warn("Variant cannot be null, ignoring.");
return this;
}
if (this.variant == variant) {
return this;
}
if (this.variant != null) {
classList().remove(this.variant.modifierClass);
}
this.variant = variant;
css(variant.modifierClass);
applyVariantIconForCurrentState();
return this;
}

@Override
public NotificationBadge icon(Element icon) {
if (icon == null) {
return removeIcon();
}
if (Objects.equals(customNormalIcon, icon)) {
return this;
}
customNormalIcon = icon;
if (variant != attention) {
button.icon(icon);
}
return this;
}

public NotificationBadge attentionIcon(Element icon) {
if (icon == null) {
return removeAttentionIcon();
}
if (Objects.equals(customAttentionIcon, icon)) {
return this;
}
customAttentionIcon = icon;
if (variant == attention) {
button.icon(icon);
}
return this;
}

public NotificationBadge attentionIcon(PredefinedIcon icon) {
return attentionIcon(icon != null ? icon.element() : null);
}

@Override
public NotificationBadge removeIcon() {
if (customNormalIcon == null) {
return this;
}
customNormalIcon = null;
if (variant != attention) {
button.removeIcon();
applyVariantIconForCurrentState();
}
return this;
}

public NotificationBadge removeAttentionIcon() {
if (customAttentionIcon == null) {
return this;
}
customAttentionIcon = null;
if (variant == attention) {
button.removeIcon();
applyVariantIconForCurrentState();
}
return this;
}

public NotificationBadge expand() {
return expand(true);
}

public NotificationBadge expand(boolean expand) {
if (this.expanded == expand) {
return this;
}
this.expanded = expand;
ariaExpanded(expand);
toggle(modifier(Classes.clicked), expand);
return this;
}

public NotificationBadge onClick(ComponentHandler<NotificationBadge> actionHandler) {
button.onClick((e, c) -> actionHandler.handle(e, this));
return this;
}

public NotificationBadge count(int count) {
if (count < 0) {
logger.warn("Count cannot be negative, ignoring.");
return this;
}
if (this.count == count) {
return this;
}
this.count = count;
updateContent();
return this;
}

// ------------------------------------------------------ internal helpers

private void updateContent() {
button.text((count > 0) ? String.valueOf(count) : "");
}

private void ariaExpanded(boolean expanded) {
button.aria(Aria.expanded, expanded);
}

private void applyVariantIconForCurrentState() {
button.icon(
(variant == attention) ? customAttentionIcon != null ? customAttentionIcon : variant.defaultIcon.get()
: customNormalIcon != null ? customNormalIcon : variant.defaultIcon.get());
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2023 Red Hat
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.patternfly.component.notification.badge;

import java.util.function.Supplier;

import org.patternfly.style.Classes;

import elemental2.dom.Element;

import static org.patternfly.icon.IconSets.patternfly.attentionBell;
import static org.patternfly.icon.IconSets.patternfly.bell;
import static org.patternfly.style.Classes.modifier;

public enum NotificationBadgeVariant {
read(modifier(Classes.read), () -> bell().element()),
unread(modifier(Classes.unread), () -> bell().element()),
attention(modifier(Classes.attention), () -> attentionBell().element());

public final String modifierClass;
public final Supplier<Element> defaultIcon;

NotificationBadgeVariant(String modifierClass, Supplier<Element> defaultIcon) {
this.modifierClass = modifierClass;
this.defaultIcon = defaultIcon;
}
}
3 changes: 3 additions & 0 deletions core/src/main/java/org/patternfly/style/Classes.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public interface Classes {
String animateCurrent = "animate-current";
String ariaDisabled = "aria-disabled";
String arrow = "arrow";
String attention = "attention";
String autoColumnWidths = "auto-column-widths";
String autoFit = "auto-fit";
String avatar = "avatar";
Expand Down Expand Up @@ -67,6 +68,7 @@ public interface Classes {
String chipContainer = "chip-container";
String chipGroup = "chip-group";
String clickable = "clickable";
String clicked = "clicked";
String close = "close";
String code = "code";
String codeBlock = "code-block";
Expand Down Expand Up @@ -252,6 +254,7 @@ public interface Classes {
String stack = "stack";
String standalone = "standalone";
String start = "start";
String stateful = "stateful";
String static_ = "static";
String status = "status";
String step = "step";
Expand Down
3 changes: 2 additions & 1 deletion core/version.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*/
///usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA 24+
//PREVIEW
//JAVAC_OPTIONS --enable-preview -source 24
//JAVA_OPTIONS --enable-preview

void main(String... args) throws IOException {
if (args.length != 3) {
Expand Down
5 changes: 3 additions & 2 deletions showcase/common/code.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*/
/// usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA 24+
//PREVIEW
//JAVAC_OPTIONS --enable-preview -source 24
//JAVA_OPTIONS --enable-preview

static class SourceSpec {

Expand Down Expand Up @@ -138,7 +139,7 @@ void addSnippet(StringBuilder out, String name, List<String> code) {
out.append("\n snippets.put(\"")
.append(escapeJava(name))
.append("\", \"")
.append(escapeJava(String.join("\\n", code)))
.append(escapeJava(String.join("\n", code)))
.append("\");");
}

Expand Down
3 changes: 2 additions & 1 deletion showcase/common/doc.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*/
/// usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA 24+
//PREVIEW
//JAVAC_OPTIONS --enable-preview -source 24
//JAVA_OPTIONS --enable-preview
//DEPS com.vladsch.flexmark:flexmark-all:0.64.8

import com.vladsch.flexmark.html.HtmlRenderer;
Expand Down
Loading