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