1<?php 2 3namespace ComboStrap; 4 5use ComboStrap\TagAttribute\Shadow; 6use DokuWiki_Syntax_Plugin; 7use syntax_plugin_combo_link; 8use syntax_plugin_combo_menubar; 9 10/** 11 * ===== For the Geek ===== 12 * This is not the [[https://www.w3.org/TR/wai-aria-practices/#button|Button as describe by the Web Specification]] 13 * but a styling over a [[https://www.w3.org/TR/wai-aria-practices/#link|link]] 14 * 15 * ===== Documentation / Reference ===== 16 * https://material.io/components/buttons 17 * https://getbootstrap.com/docs/4.5/components/buttons/ 18 */ 19class ButtonTag 20{ 21 22 public const TYPES = [ 23 ColorRgb::PRIMARY_VALUE, 24 ColorRgb::SECONDARY_VALUE, 25 "success", 26 "danger", 27 "warning", 28 "info", 29 "light", 30 "dark", 31 "link" 32 ]; 33 public const MARKUP_LONG = "button"; 34 public const MARKUP_SHORT = "btn"; 35 const LOGICAL_TAG = self::MARKUP_LONG; 36 37 /** 38 * @param TagAttributes $tagAttributes 39 */ 40 public static function processButtonAttributesToHtmlAttributes(TagAttributes &$tagAttributes) 41 { 42 # A button 43 $btn = "btn"; 44 $tagAttributes->addClassName($btn); 45 46 $type = $tagAttributes->getValue(TagAttributes::TYPE_KEY, "primary"); 47 $skin = $tagAttributes->getValue(Skin::SKIN_ATTRIBUTE, Skin::FILLED_VALUE); 48 switch ($skin) { 49 case "contained": 50 { 51 $tagAttributes->addClassName("$btn-$type"); 52 $tagAttributes->addComponentAttributeValue(Shadow::CANONICAL, true); 53 break; 54 } 55 case "filled": 56 { 57 $tagAttributes->addClassName("$btn-$type"); 58 break; 59 } 60 case "outline": 61 { 62 $tagAttributes->addClassName("$btn-outline-$type"); 63 break; 64 } 65 case "text": 66 { 67 $tagAttributes->addClassName("$btn-link"); 68 $tagAttributes->addComponentAttributeValue(TextColor::TEXT_COLOR_ATTRIBUTE, $type); 69 break; 70 } 71 } 72 73 74 $sizeAttribute = "size"; 75 if ($tagAttributes->hasComponentAttribute($sizeAttribute)) { 76 $size = $tagAttributes->getValueAndRemove($sizeAttribute); 77 switch ($size) { 78 case "lg": 79 case "large": 80 $tagAttributes->addClassName("btn-lg"); 81 break; 82 case "sm": 83 case "small": 84 $tagAttributes->addClassName("btn-sm"); 85 break; 86 } 87 } 88 } 89 90 public static function getTags(): array 91 { 92 $elements[] = ButtonTag::MARKUP_LONG; 93 $elements[] = ButtonTag::MARKUP_SHORT; 94 return $elements; 95 } 96 97 public static function handleEnter(TagAttributes $attributes, \Doku_Handler $handler): array 98 { 99 /** 100 * Note: Branding color (primary and secondary) 101 * are set with the {@link Skin} 102 */ 103 104 /** 105 * The parent 106 * to apply automatically styling in a bar 107 */ 108 $callStack = CallStack::createFromHandler($handler); 109 $isInMenuBar = false; 110 while ($parent = $callStack->moveToParent()) { 111 if ($parent->getTagName() === syntax_plugin_combo_menubar::TAG) { 112 $isInMenuBar = true; 113 break; 114 } 115 } 116 if ($isInMenuBar) { 117 if (!$attributes->hasAttribute("class") && !$attributes->hasAttribute("spacing")) { 118 $attributes->addComponentAttributeValue("spacing", "mr-2 mb-2 mt-2 mb-lg-0 mt-lg-0"); 119 } 120 } 121 122 /** 123 * The context give set if this is a button 124 * or a link button 125 * The context is checked in the `exit` state 126 * Default context: This is not a link button 127 */ 128 $context = ButtonTag::MARKUP_LONG; 129 130 131 return array( 132 PluginUtility::CONTEXT => $context 133 ); 134 } 135 136 public static function handleExit(\Doku_Handler $handler): array 137 { 138 $callStack = CallStack::createFromHandler($handler); 139 $openingTag = $callStack->moveToPreviousCorrespondingOpeningCall(); 140 /** 141 * Button or link button 142 */ 143 $context = ButtonTag::MARKUP_LONG; 144 $descendant = $callStack->moveToFirstChildTag(); 145 if ($descendant !== false) { 146 if ($descendant->getTagName() === syntax_plugin_combo_link::TAG) { 147 $context = syntax_plugin_combo_link::TAG; 148 } 149 } 150 $openingTag->setContext($context); 151 152 return array( 153 PluginUtility::CONTEXT => $context 154 ); 155 } 156 157 public static function renderEnterXhtml(TagAttributes $tagAttributes, DokuWiki_Syntax_Plugin $plugin, array $data): string 158 { 159 /** 160 * CSS if dokuwiki class name for link 161 */ 162 if ($plugin->getConf(LinkMarkup::CONF_USE_DOKUWIKI_CLASS_NAME, false)) { 163 PluginUtility::getSnippetManager()->attachCssInternalStyleSheet(ButtonTag::MARKUP_LONG); 164 } 165 166 /** 167 * If this not a link button 168 * The context is set on the handle exit 169 */ 170 $context = $data[PluginUtility::CONTEXT]; 171 if ($context == ButtonTag::LOGICAL_TAG) { 172 $tagAttributes->setDefaultStyleClassShouldBeAdded(false); 173 ButtonTag::processButtonAttributesToHtmlAttributes($tagAttributes); 174 $tagAttributes->addOutputAttributeValue("type", "button"); 175 return $tagAttributes->toHtmlEnterTag('button'); 176 } 177 return ""; 178 179 } 180 181 public static function renderExitXhtml($data): string 182 { 183 $context = $data[PluginUtility::CONTEXT]; 184 /** 185 * If this is a button and not a link button 186 */ 187 if ($context === ButtonTag::MARKUP_LONG) { 188 return '</button>'; 189 } 190 return ""; 191 } 192} 193