| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,7 +18,7 @@ | |||
| 18 | 18 | import org.jboss.elemento.Elements; | |
| 19 | 19 | import org.jboss.elemento.HTMLContainerBuilder; | |
| 20 | 20 | import org.patternfly.core.Aria; | |
| 21 | - import org.patternfly.core.Callback; | ||
| 21 | + import org.patternfly.handler.Callback; | ||
| 22 | 22 | import org.patternfly.core.Modifiers; | |
| 23 | 23 | import org.patternfly.layout.Classes; | |
| 24 | 24 | ||
@@ -29,6 +29,7 @@ | |||
| 29 | 29 | import static org.jboss.elemento.Elements.i; | |
| 30 | 30 | import static org.jboss.elemento.Elements.span; | |
| 31 | 31 | import static org.jboss.elemento.EventType.click; | |
| 32 | + import static org.patternfly.component.icon.InlineIcon.inlineIcon; | ||
| 32 | 33 | import static org.patternfly.layout.Classes.active; | |
| 33 | 34 | import static org.patternfly.layout.Classes.block; | |
| 34 | 35 | import static org.patternfly.layout.Classes.component; | |
@@ -105,11 +106,11 @@ public static Button link(HTMLElement element, String href, String target) { | |||
| 105 | 106 | } | |
| 106 | 107 | ||
| 107 | 108 | public static Button icon(String iconClass) { | |
| 108 | - return new Button(Elements.button().css(modifier(plain)).add(i().css(iconClass))); | ||
| 109 | + return new Button(Elements.button().css(modifier(plain)).add(inlineIcon(iconClass))); | ||
| 109 | 110 | } | |
| 110 | 111 | ||
| 111 | 112 | public static Button icon(String iconClass, String label) { | |
| 112 | - return new Button(Elements.button().css(modifier(plain)).aria("label", label).add(i().css(iconClass))); | ||
| 113 | + return new Button(Elements.button().css(modifier(plain)).aria("label", label).add(inlineIcon(iconClass))); | ||
| 113 | 114 | } | |
| 114 | 115 | ||
| 115 | 116 | public static Button icon(Icon icon) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,7 +18,7 @@ | |||
| 18 | 18 | import org.jboss.elemento.HTMLContainerBuilder; | |
| 19 | 19 | import org.jboss.elemento.Id; | |
| 20 | 20 | import org.patternfly.component.badge.Badge; | |
| 21 | - import org.patternfly.core.Callback; | ||
| 21 | + import org.patternfly.handler.Callback; | ||
| 22 | 22 | import org.patternfly.layout.Classes; | |
| 23 | 23 | ||
| 24 | 24 | import elemental2.dom.HTMLElement; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,7 +16,7 @@ | |||
| 16 | 16 | package org.patternfly.component; | |
| 17 | 17 | ||
| 18 | 18 | import org.patternfly.component.title.Title; | |
| 19 | - import org.patternfly.core.Callback; | ||
| 19 | + import org.patternfly.handler.Callback; | ||
| 20 | 20 | import org.patternfly.layout.Classes; | |
| 21 | 21 | ||
| 22 | 22 | import elemental2.dom.HTMLDivElement; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,7 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | 20 | import org.jboss.elemento.EventType; | |
| 21 | 21 | import org.jboss.elemento.HTMLContainerBuilder; | |
| 22 | - import org.patternfly.core.Callback; | ||
| 22 | + import org.patternfly.handler.Callback; | ||
| 23 | 23 | import org.patternfly.core.Modifiers; | |
| 24 | 24 | import org.patternfly.dataprovider.PageInfo; | |
| 25 | 25 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,7 +21,7 @@ | |||
| 21 | 21 | import org.patternfly.component.Button; | |
| 22 | 22 | import org.patternfly.component.ComponentType; | |
| 23 | 23 | import org.patternfly.core.Aria; | |
| 24 | - import org.patternfly.core.Callback; | ||
| 24 | + import org.patternfly.handler.Callback; | ||
| 25 | 25 | import org.patternfly.layout.Classes; | |
| 26 | 26 | ||
| 27 | 27 | import elemental2.dom.HTMLDivElement; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,30 +15,43 @@ | |||
| 15 | 15 | */ | |
| 16 | 16 | package org.patternfly.component.code; | |
| 17 | 17 | ||
| 18 | + import org.jboss.elemento.Attachable; | ||
| 18 | 19 | import org.jboss.elemento.Elements; | |
| 20 | + import org.jboss.elemento.Id; | ||
| 19 | 21 | import org.patternfly.component.BaseComponent; | |
| 20 | - import org.patternfly.component.Button; | ||
| 21 | 22 | import org.patternfly.component.ComponentType; | |
| 23 | + import org.patternfly.component.expandable.ExpandableSection; | ||
| 22 | 24 | import org.patternfly.layout.Classes; | |
| 23 | 25 | ||
| 24 | 26 | import elemental2.dom.HTMLDivElement; | |
| 25 | 27 | import elemental2.dom.HTMLElement; | |
| 28 | + import elemental2.dom.MutationRecord; | ||
| 26 | 29 | ||
| 30 | + import static java.util.Arrays.copyOfRange; | ||
| 27 | 31 | import static org.jboss.elemento.Elements.div; | |
| 32 | + import static org.jboss.elemento.Elements.failSafeRemoveFromParent; | ||
| 33 | + import static org.jboss.elemento.Elements.insertAfter; | ||
| 34 | + import static org.jboss.elemento.Elements.insertFirst; | ||
| 28 | 35 | import static org.jboss.elemento.Elements.pre; | |
| 36 | + import static org.jboss.elemento.Elements.removeChildrenFrom; | ||
| 37 | + import static org.jboss.elemento.Elements.wrapHtmlContainer; | ||
| 38 | + import static org.patternfly.component.code.CodeBlockActions.codeBlockActions; | ||
| 29 | 39 | import static org.patternfly.component.code.CodeBlockHeader.codeBlockHeader; | |
| 40 | + import static org.patternfly.component.expandable.ExpandableSection.expandableSection; | ||
| 41 | + import static org.patternfly.component.expandable.ExpandableSectionContent.expandableSectionContent; | ||
| 42 | + import static org.patternfly.component.expandable.ExpandableSectionToggle.expandableSectionToggle; | ||
| 30 | 43 | import static org.patternfly.layout.Classes.codeBlock; | |
| 31 | 44 | import static org.patternfly.layout.Classes.component; | |
| 32 | 45 | import static org.patternfly.layout.Classes.content; | |
| 33 | 46 | import static org.patternfly.layout.Classes.pre; | |
| 34 | 47 | ||
| 35 | 48 | /** | |
| 36 | - * A code block is a component that contains 2 or more lines of read-only code. The code in a code block can be copied to the | ||
| 37 | - * clipboard. | ||
| 49 | + * A code block is a component that contains 2 or more lines of read-only code. The code in a code block can be copied | ||
| 50 | + * to the clipboard. | ||
| 38 | 51 | * | |
| 39 | 52 | * @see <a href= "https://www.patternfly.org/components/code-block">https://www.patternfly.org/components/code-block</a> | |
| 40 | 53 | */ | |
| 41 | - public class CodeBlock extends BaseComponent<HTMLDivElement, CodeBlock> { | ||
| 54 | + public class CodeBlock extends BaseComponent<HTMLDivElement, CodeBlock> implements Attachable { | ||
| 42 | 55 | ||
| 43 | 56 | // ------------------------------------------------------ factory methods | |
| 44 | 57 | ||
@@ -52,20 +65,40 @@ public static CodeBlock codeBlock(String code) { | |||
| 52 | 65 | ||
| 53 | 66 | // ------------------------------------------------------ instance | |
| 54 | 67 | ||
| 55 | - private CodeBlockHeader header; | ||
| 68 | + public static final int DEFAULT_TRUNCATE = 3; | ||
| 69 | + | ||
| 70 | + private final HTMLElement preElement; | ||
| 56 | 71 | private final HTMLElement codeElement; | |
| 72 | + private String code; | ||
| 73 | + private int truncate; | ||
| 74 | + private CodeBlockHeader header; | ||
| 75 | + private ExpandableSection esCode; | ||
| 76 | + private ExpandableSection esTrigger; | ||
| 57 | 77 | ||
| 58 | 78 | CodeBlock(String code) { | |
| 59 | 79 | super(div().css(component(codeBlock)).element(), ComponentType.CodeBlock); | |
| 60 | 80 | ||
| 61 | 81 | add(div().css(component(codeBlock, content)) | |
| 62 | - .add(pre().css(component(codeBlock, pre)) | ||
| 82 | + .add(preElement = pre().css(component(codeBlock, pre)) | ||
| 63 | 83 | .add(codeElement = Elements.code().css(component(codeBlock, Classes.code)) | |
| 64 | - .element()))); | ||
| 84 | + .element()) | ||
| 85 | + .element())); | ||
| 65 | 86 | ||
| 66 | 87 | if (code != null) { | |
| 67 | 88 | codeElement.textContent = code; | |
| 68 | 89 | } | |
| 90 | + | ||
| 91 | + Attachable.register(this, this); | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + @Override | ||
| 95 | + public void attach(MutationRecord mutationRecord) { | ||
| 96 | + if (header != null) { | ||
| 97 | + header.passComponent(this); | ||
| 98 | + } | ||
| 99 | + if (mustSplitCode()) { | ||
| 100 | + splitCode(); | ||
| 101 | + } | ||
| 69 | 102 | } | |
| 70 | 103 | ||
| 71 | 104 | @Override | |
@@ -82,26 +115,94 @@ public CodeBlock addHeader(CodeBlockHeader header) { | |||
| 82 | 115 | // override to assure internal wiring | |
| 83 | 116 | public CodeBlock add(CodeBlockHeader header) { | |
| 84 | 117 | this.header = header; | |
| 85 | - add(header.element()); | ||
| 118 | + insertFirst(element(), header.element()); | ||
| 86 | 119 | return this; | |
| 87 | 120 | } | |
| 88 | 121 | ||
| 89 | - public CodeBlock addAction(Button action) { | ||
| 122 | + public CodeBlock addAction(CodeBlockAction action) { | ||
| 90 | 123 | if (header == null) { | |
| 91 | 124 | addHeader(codeBlockHeader()); | |
| 92 | 125 | } | |
| 93 | - header.addAction(action); | ||
| 126 | + if (header.actions == null) { | ||
| 127 | + header.addActions(codeBlockActions()); | ||
| 128 | + } | ||
| 129 | + header.actions.addAction(action); | ||
| 130 | + return this; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + // ------------------------------------------------------ modifiers | ||
| 134 | + | ||
| 135 | + /** Same as {@linkplain #truncate(int) truncate(3)} */ | ||
| 136 | + public CodeBlock truncate() { | ||
| 137 | + return truncate(DEFAULT_TRUNCATE); | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + public CodeBlock truncate(int truncate) { | ||
| 141 | + this.truncate = truncate; | ||
| 94 | 142 | return this; | |
| 95 | 143 | } | |
| 96 | 144 | ||
| 97 | 145 | // ------------------------------------------------------ public API | |
| 98 | 146 | ||
| 99 | 147 | public CodeBlock code(String code) { | |
| 100 | - codeElement.textContent = code; | ||
| 148 | + this.code = code; | ||
| 149 | + if (element().isConnected) { // already attached? | ||
| 150 | + if (mustSplitCode()) { | ||
| 151 | + splitCode(); | ||
| 152 | + } else { | ||
| 153 | + unsplitCode(); | ||
| 154 | + codeElement.textContent = code; | ||
| 155 | + } | ||
| 156 | + } else { | ||
| 157 | + codeElement.textContent = code; | ||
| 158 | + } | ||
| 101 | 159 | return this; | |
| 102 | 160 | } | |
| 103 | 161 | ||
| 104 | 162 | public String code() { | |
| 105 | - return codeElement.textContent; | ||
| 163 | + return code; | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + // ------------------------------------------------------ internals | ||
| 167 | + | ||
| 168 | + private String[] lines() { | ||
| 169 | + return code != null && !code.trim().isEmpty() ? code.split("\n") : new String[0]; | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + private boolean mustSplitCode() { | ||
| 173 | + return truncate > 0 && truncate < lines().length; | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + private void splitCode() { | ||
| 177 | + String visibleCode = String.join("\n", copyOfRange(lines(), 0, truncate)); | ||
| 178 | + String moreCode = String.join("\n", copyOfRange(lines(), truncate, lines().length)); | ||
| 179 | + | ||
| 180 | + if (esCode == null && esTrigger == null) { | ||
| 181 | + String codeId = Id.unique(componentType().id, "es-code"); | ||
| 182 | + String triggerId = Id.unique(componentType().id, "es-trigger"); | ||
| 183 | + esCode = expandableSection(codeId) | ||
| 184 | + .detachedFrom(triggerId) | ||
| 185 | + .addContent(expandableSectionContent().textContent(moreCode)); | ||
| 186 | + esTrigger = expandableSection(triggerId) | ||
| 187 | + .detachedFrom(codeId) | ||
| 188 | + .addToggle(expandableSectionToggle("Show more", "Show less")); | ||
| 189 | + | ||
| 190 | + removeChildrenFrom(codeElement); | ||
| 191 | + wrapHtmlContainer(codeElement) | ||
| 192 | + .add(visibleCode) | ||
| 193 | + .add(esCode); | ||
| 194 | + insertAfter(esTrigger.element(), preElement); | ||
| 195 | + | ||
| 196 | + } else if (esCode != null) { | ||
| 197 | + codeElement.textContent = visibleCode; | ||
| 198 | + esCode.content().textContent(moreCode); | ||
| 199 | + } | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + private void unsplitCode() { | ||
| 203 | + failSafeRemoveFromParent(esCode); | ||
| 204 | + failSafeRemoveFromParent(esTrigger); | ||
| 205 | + esCode = null; | ||
| 206 | + esTrigger = null; | ||
| 106 | 207 | } | |
| 107 | 208 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,32 +15,84 @@ | |||
| 15 | 15 | */ | |
| 16 | 16 | package org.patternfly.component.code; | |
| 17 | 17 | ||
| 18 | + import org.patternfly.component.Button; | ||
| 19 | + import org.patternfly.component.ComponentReference; | ||
| 18 | 20 | import org.patternfly.component.SubComponent; | |
| 21 | + import org.patternfly.core.Aria; | ||
| 22 | + import org.patternfly.layout.Classes; | ||
| 23 | + import org.patternfly.layout.PredefinedIcon; | ||
| 19 | 24 | ||
| 20 | 25 | import elemental2.dom.HTMLDivElement; | |
| 26 | + import elemental2.dom.HTMLElement; | ||
| 21 | 27 | ||
| 22 | 28 | import static org.jboss.elemento.Elements.div; | |
| 29 | + import static org.jboss.elemento.EventType.click; | ||
| 30 | + import static org.patternfly.js.ExtendedDomGlobal.navigator; | ||
| 23 | 31 | import static org.patternfly.layout.Classes.actions; | |
| 24 | - import static org.patternfly.layout.Classes.codeBlock; | ||
| 25 | 32 | import static org.patternfly.layout.Classes.component; | |
| 26 | 33 | import static org.patternfly.layout.Classes.item; | |
| 34 | + import static org.patternfly.layout.PredefinedIcon.copy; | ||
| 27 | 35 | ||
| 28 | - public class CodeBlockAction extends SubComponent<HTMLDivElement, CodeBlockAction> { | ||
| 36 | + public class CodeBlockAction extends SubComponent<HTMLDivElement, CodeBlockAction> implements | ||
| 37 | + ComponentReference<CodeBlock> { | ||
| 29 | 38 | ||
| 30 | 39 | // ------------------------------------------------------ factory methods | |
| 31 | 40 | ||
| 32 | 41 | public static CodeBlockAction codeBlockAction() { | |
| 33 | - return new CodeBlockAction(); | ||
| 42 | + return new CodeBlockAction(null); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + public static CodeBlockAction codeBlockAction(PredefinedIcon icon) { | ||
| 46 | + return new CodeBlockAction(icon.className); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + public static CodeBlockAction codeBlockAction(String iconClass) { | ||
| 50 | + return new CodeBlockAction(iconClass); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + public static CodeBlockAction codeBlockCopyToClipboardAction() { | ||
| 54 | + return new CodeBlockAction(copy.className) | ||
| 55 | + .ariaLabel("Copy to clipboard") | ||
| 56 | + .onAction((action, codeBlock) -> navigator.clipboard.writeText(codeBlock.code())); | ||
| 34 | 57 | } | |
| 35 | 58 | ||
| 36 | 59 | // ------------------------------------------------------ instance | |
| 37 | 60 | ||
| 38 | - CodeBlockAction() { | ||
| 39 | - super(div().css(component(codeBlock, actions, item)).element()); | ||
| 61 | + private HTMLElement buttonElement; | ||
| 62 | + private CodeBlockActionHandler handler; | ||
| 63 | + | ||
| 64 | + CodeBlockAction(String iconClass) { | ||
| 65 | + super(div().css(component(Classes.codeBlock, actions, item)).element()); | ||
| 66 | + if (iconClass != null) { | ||
| 67 | + add(buttonElement = Button.icon(iconClass).element()); | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + @Override | ||
| 72 | + public void passComponent(CodeBlock codeBlock) { | ||
| 73 | + if (handler != null && buttonElement != null) { | ||
| 74 | + buttonElement.addEventListener(click.name, e -> handler.onAction(this, codeBlock)); | ||
| 75 | + } | ||
| 40 | 76 | } | |
| 41 | 77 | ||
| 42 | 78 | @Override | |
| 43 | 79 | public CodeBlockAction that() { | |
| 44 | 80 | return this; | |
| 45 | 81 | } | |
| 82 | + | ||
| 83 | + // ------------------------------------------------------ public API | ||
| 84 | + | ||
| 85 | + public CodeBlockAction ariaLabel(String label) { | ||
| 86 | + if (buttonElement != null) { | ||
| 87 | + buttonElement.setAttribute(Aria.label, label); | ||
| 88 | + } | ||
| 89 | + return this; | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + // ------------------------------------------------------ events | ||
| 93 | + | ||
| 94 | + public CodeBlockAction onAction(CodeBlockActionHandler handler) { | ||
| 95 | + this.handler = handler; | ||
| 96 | + return this; | ||
| 97 | + } | ||
| 46 | 98 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,7 @@ | |||
| 1 | + package org.patternfly.component.code; | ||
| 2 | + | ||
| 3 | + @FunctionalInterface | ||
| 4 | + public interface CodeBlockActionHandler { | ||
| 5 | + | ||
| 6 | + void onAction(CodeBlockAction action, CodeBlock codeBlock); | ||
| 7 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments