Move more controls to the HTML builder, and add some more bootstrap design helpers

This commit is contained in:
Aria 2023-06-19 23:01:29 -07:00
parent e58efecbff
commit 2fb00f1b13
12 changed files with 2316 additions and 154 deletions

View file

@ -1,39 +0,0 @@
package dev.zontreck.ariaslib.html;
import dev.zontreck.ariaslib.html.bootstrap.Color;
public class Background extends Element
{
public Background ( Color color, boolean subtle, boolean gradient) {
super ( "" );
bgColor=color;
isSubtle=subtle;
hasGradient=gradient;
}
public Color bgColor;
public boolean isSubtle = false;
public boolean hasGradient = false;
/**
* Generate a background string to be inserted into the class of a existing element
*/
@Override
public String toString()
{
return "bg-" + bgColor.name ().toLowerCase ( ) + (isSubtle ? "-subtle" : "") + (hasGradient ? ".bg-gradient" : "");
}
/**
* Generate a background string to be inserted into the class of a existing element
*/
public static String getBackgroundClass(Color color, boolean isSubtle, boolean hasGradient)
{
return "bg-"+color.name ().toLowerCase ( ) + (isSubtle ? "-subtle" : "") + (hasGradient ? ".bg-gradient" : "");
}
}

View file

@ -0,0 +1,250 @@
package dev.zontreck.ariaslib.html;
import dev.zontreck.ariaslib.html.bootstrap.Color;
import dev.zontreck.ariaslib.html.bootstrap.Icons;
import dev.zontreck.ariaslib.html.bootstrap.Size;
import dev.zontreck.ariaslib.util.Percent;
public class Bootstrap {
public static class Border {
public static Border make ( ) {
return new Border ( );
}
public enum Side {
Start,
End,
Top,
Bottom
}
public Side side;
public int width = 1;
public boolean usesSides = false;
public Colors colors;
public Border withColor ( Colors color ) {
this.colors = color.withPrefix ( "border" );
return this;
}
public Border widthSide ( Side side ) {
this.side = side;
usesSides = true;
return this;
}
public Border withWidth ( int width ) {
this.width = width;
return this;
}
public boolean invert;
/**
* Removes borders instead of adding
*/
public Border setInverted ( ) {
invert = true;
return this;
}
public void apply ( HTMLElementBuilder elem ) {
elem.addClass ( "border" );
colors.apply ( elem );
if ( usesSides ) {
elem.addClass ( "border-" + side.name ( ).toLowerCase ( ) + ( invert ? "-0" : "" ) );
}
else {
if ( invert ) elem.addClass ( "border-0" );
}
}
}
public static class Opacity {
public Percent value;
public String prefix;
public static Opacity make ( ) {
return new Opacity ( );
}
public Opacity withPercent ( Percent val ) {
value = val;
return this;
}
public Opacity withPrefix ( String pref ) {
this.prefix = pref;
return this;
}
public void apply ( HTMLElementBuilder builder ) {
builder.addClass ( ( prefix != "" ? prefix + "-" : "" ) + "opacity-" + value.get ( ) );
}
}
public static class Colors {
public static Colors make ( ) {
return new Colors ( );
}
public Color color;
public boolean emphasis;
public boolean subtle;
public String prefix;
public Colors withColor ( Color color ) {
this.color = color;
return this;
}
public Colors setEmphasis ( ) {
emphasis = true;
return this;
}
public Colors setSubtle ( ) {
subtle = true;
return this;
}
public Colors withPrefix ( String prefix ) {
this.prefix = prefix;
return this;
}
public void apply ( HTMLElementBuilder builder ) {
builder.addClass ( ( ( prefix != "" ) ? prefix + "-" : "" ) + color.name ( ).toLowerCase ( ) + ( emphasis ? "-emphasis" : "" ) + ( subtle ? "-subtle" : "" ) );
}
}
public static class Background {
public static Background make ( ) {
return new Background ( );
}
public Colors color;
public Opacity opacity;
public boolean gradient;
public Background withColor ( Colors color ) {
this.color = color.withPrefix ( "bg" );
return this;
}
public Background withOpacity ( Opacity op ) {
this.opacity = op.withPrefix ( "bg" );
return this;
}
public Background setGradient ( ) {
gradient = true;
return this;
}
public void apply ( HTMLElementBuilder builder ) {
color.apply ( builder );
opacity.apply ( builder );
if ( gradient )
builder.addClass ( ".bg-gradient" );
}
}
public static class Shadow {
public static Shadow make ( ) {
return new Shadow ( );
}
public Size size;
public Shadow withSize ( Size size ) {
this.size = size;
return this;
}
public void apply ( HTMLElementBuilder builder ) {
builder.addClass ( "shadow" + size.sizeText ( ) );
}
}
public static class FocusRing {
public static FocusRing make()
{
return new FocusRing ();
}
public Colors color;
public FocusRing withColor(Colors color)
{
this.color = color.withPrefix ( "focus-ring" );
return this;
}
public void apply(HTMLElementBuilder builder)
{
builder.addClass ( "focus-ring" );
color.apply ( builder );
}
}
public static class Link {
public static Link make()
{
return new Link ();
}
public Colors color;
public Link withColor(Colors color)
{
this.color=color.withPrefix ( "link" );
return this;
}
public void apply(HTMLElementBuilder builder)
{
color.apply ( builder );
}
}
public static class Toast {
public static Toast make()
{
return new Toast ();
}
public Icons icon;
public Toast withIcon(Icons icon)
{
this.icon=icon;
return this;
}
public Toast()
{
toastHeader = new HTMLElementBuilder ( "div" ).addClass ( "toast-header" );
toastHeader.addChild ( "svg" ).addClass ( "bi" ).addClass ( icon.getClassName() ).addClass ( "rounded" );
toastHeader.addChild ( "strong" ).addClass ( "me-auto" );
toastHeader.addChild ( "small" ).withText ( "Text?" );
toastHeader.addChild ( "button" ).withAttribute ( "type", "button" ).addClass ( "btn-close" ).withAttribute ( "data-bs-dismiss", "toast" ).withAttribute ( "aria-label", "Close" );
toastBody = new HTMLElementBuilder ( "div" ).addClass ( "toast-body" );
}
public HTMLElementBuilder toastHeader;
public HTMLElementBuilder toastBody;
public void apply(HTMLElementBuilder builder)
{
var toast = builder.addChild ( "div" ).addClass ( "toast" ).withAttribute ( "role", "alert" ).withAttribute ( "aria-live", "assertive" ).withAttribute ( "aria-atomic", "true" );
toast.addChild ( toastHeader );
toast.addChild ( toastBody );
}
}
}

View file

@ -1,37 +0,0 @@
package dev.zontreck.ariaslib.html;
import dev.zontreck.ariaslib.html.bootstrap.Color;
public class Border extends Element
{
public Border (Color color, boolean subtle) {
super ( "" );
borderColor=color;
isSubtle=subtle;
}
public Color borderColor;
public boolean isSubtle = false;
/**
* Generate a border string to be inserted into the class of a existing element
*/
@Override
public String toString()
{
return "border-" + borderColor.name ().toLowerCase ( ) + (isSubtle ? "-subtle" : "");
}
/**
* Generate a border string to be inserted into the class of a existing element
*/
public static String getBorderClass(Color color, boolean isSubtle)
{
return "border-"+color.name ().toLowerCase ( ) + (isSubtle ? "-subtle" : "");
}
}

View file

@ -0,0 +1,8 @@
package dev.zontreck.ariaslib.html;
// Class attribute class for HTML element classes
class ClassAttribute extends HTMLAttribute {
public ClassAttribute(String value) {
super("class", value);
}
}

View file

@ -42,7 +42,9 @@ public class DOM {
head.addChild ( "meta" ).withAttribute ( "name" , "viewport" ).withAttribute ( "content" , "width=device-width, initial-scale=1" );
head.getOrCreate ( "link" ).withAttribute ( "href" , "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" ).withAttribute ( "integrity" , "sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" ).withAttribute ( "crossorigin" , "anonymous" );
head.getOrCreate ( "link" ).withAttribute ( "href" , "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" ).withAttribute ( "integrity" , "sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" ).withAttribute ( "crossorigin" , "anonymous" ).withAttribute ( "rel", "stylesheet" );
head.addClass ( "link" ).withAttribute ( "rel", "stylesheet" ).withAttribute ( "href", "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" );
head.getOrCreate ( "title" ).withText ( pageTitle );

View file

@ -5,20 +5,20 @@ class HTMLAttribute {
private String name;
private String value;
public HTMLAttribute ( String name , String value ) {
public HTMLAttribute(String name, String value) {
this.name = name;
this.value = value;
}
public HTMLAttribute ( String name ) {
this ( name , null );
public HTMLAttribute(String name) {
this(name, null);
}
public String getName ( ) {
public String getName() {
return name;
}
public String getValue ( ) {
public String getValue() {
return value;
}
}

View file

@ -26,33 +26,32 @@ class HTMLElement {
public String generateHTML ( ) {
StringBuilder builder = new StringBuilder ( );
boolean addEndingTag = true;
if ( "!doctype".equalsIgnoreCase ( tagName ) ) {
builder.append ( "<!" ).append ( tagName ).append ( " " ).append ( text ).append ( ">" );
addEndingTag = false;
text = null;
}
else {
builder.append ( "<" ).append ( tagName );
for ( HTMLAttribute attribute : attributes ) {
builder.append ( " " )
.append ( attribute.getName ( ) );
String value = attribute.getValue ( );
if ( value != null ) {
builder.append ( "=\"" ).append ( value ).append ( "\"" );
}
for ( HTMLElement child : children ) {
builder.append ( child.generateHTML ( ) );
}
if ( isEmptyElement ) {
builder.append ( " />" );
return builder.toString ( );
}
builder.append ( ">" );
return builder.toString ( );
}
builder.append ( "<" ).append ( tagName );
for ( HTMLAttribute attribute : attributes ) {
builder.append ( " " )
.append ( attribute.getName ( ) );
String value = attribute.getValue ( );
if ( value != null ) {
builder.append ( "=\"" ).append ( value ).append ( "\"" );
}
}
if ( isEmptyElement ) {
builder.append ( " />" );
return builder.toString ( );
}
builder.append ( ">" );
if ( text != null ) {
builder.append ( text );
@ -63,8 +62,7 @@ class HTMLElement {
}
}
if ( addEndingTag )
builder.append ( "</" ).append ( tagName ).append ( ">" );
builder.append ( "</" ).append ( tagName ).append ( ">" );
return builder.toString ( );
}

View file

@ -8,13 +8,11 @@ class HTMLElementBuilder {
private String tagName;
private String text;
private List<HTMLAttribute> attributes;
private boolean isEmptyElement;
private List<HTMLElementBuilder> childElementBuilders;
public HTMLElementBuilder ( String tagName ) {
this.tagName = tagName;
this.attributes = new ArrayList<> ( );
this.isEmptyElement = false;
this.childElementBuilders = new ArrayList<> ( );
}
@ -35,11 +33,30 @@ class HTMLElementBuilder {
return this;
}
public HTMLElementBuilder setEmptyElement ( ) {
this.isEmptyElement = true;
public HTMLElementBuilder addClass ( String className ) {
ClassAttribute classAttribute = getClassAttribute ( );
if ( classAttribute == null ) {
classAttribute = new ClassAttribute ( className );
this.attributes.add ( classAttribute );
}
else {
String existingValue = classAttribute.getValue ( );
classAttribute = new ClassAttribute ( existingValue + " " + className );
this.attributes.removeIf ( attr -> attr.getName ( ).equalsIgnoreCase ( "class" ) );
this.attributes.add ( classAttribute );
}
return this;
}
private ClassAttribute getClassAttribute ( ) {
for ( HTMLAttribute attribute : attributes ) {
if ( attribute instanceof ClassAttribute ) {
return ( ClassAttribute ) attribute;
}
}
return null;
}
public HTMLElementBuilder addChild ( HTMLElementBuilder childBuilder ) {
childElementBuilders.add ( childBuilder );
return this;
@ -79,6 +96,16 @@ class HTMLElementBuilder {
return null;
}
private boolean hasTextOrChildren ( ) {
return text != null || ! childElementBuilders.isEmpty ( );
}
public HTMLElement build ( ) {
List<HTMLElement> children = buildChildren ( );
boolean isEmptyElement = ! hasTextOrChildren ( );
return new HTMLElement ( tagName , text , attributes , children , isEmptyElement );
}
private List<HTMLElement> buildChildren ( ) {
List<HTMLElement> children = new ArrayList<> ( );
@ -88,9 +115,4 @@ class HTMLElementBuilder {
return children;
}
public HTMLElement build ( ) {
List<HTMLElement> children = buildChildren ( );
return new HTMLElement ( tagName , text , attributes , children , isEmptyElement );
}
}

View file

@ -1,20 +0,0 @@
package dev.zontreck.ariaslib.html;
import dev.zontreck.ariaslib.util.Percent;
public class Opacity extends Element
{
public Opacity ( Percent val ) {
super ( "" );
value=val;
}
public Percent value;
@Override
public String toString()
{
return "bg-opacity-" + value.get();
}
}

View file

@ -1,19 +0,0 @@
package dev.zontreck.ariaslib.html;
import dev.zontreck.ariaslib.html.bootstrap.Color;
public class TextColor extends Element
{
public TextColor ( Color color ) {
super ( "" );
}
public Color color;
@Override
public String toString()
{
return "text-" + color.name ().toLowerCase ( );
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,28 @@
package dev.zontreck.ariaslib.html.bootstrap;
public enum Size
{
Small,
Regular,
Large,
None;
public String sizeText()
{
switch(this)
{
case Small -> {
return "-sm";
}
case None -> {
return "-none";
}
case Large -> {
return "-lg";
}
default -> {
return "";
}
}
}
}