xref: /plugin/combo/ComboStrap/Position.php (revision 37748cd8654635afbeca80942126742f0f4cc346)
1<?php
2/**
3 * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved.
4 *
5 * This source code is licensed under the GPL license found in the
6 * COPYING  file in the root directory of this source tree.
7 *
8 * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
9 * @author   ComboStrap <support@combostrap.com>
10 *
11 */
12
13namespace ComboStrap;
14
15/**
16 * Class Sticky
17 * Manage the stickiness of component
18 * with https://sticksy.js.org/
19 * @package ComboStrap
20 */
21class Position
22{
23    const STICKY_ATTRIBUTE = "sticky";
24    const STICKY = "sticky";
25    const STICKY_CLASS = "combo-sticky";
26
27    const POSITION_ATTRIBUTE = "position";
28    const POSITION_SNIPPET_ID = "position";
29    const POSITION_QUARTILE_SNIPPET_ID = "position-quartile";
30
31    /**
32     * Process stickiness
33     * @param TagAttributes $attributes
34     */
35    public static function processStickiness(&$attributes)
36    {
37        if ($attributes->hasComponentAttribute(self::STICKY_ATTRIBUTE)) {
38            $sticky = strtolower($attributes->getValueAndRemove(self::STICKY_ATTRIBUTE));
39            if ($sticky == "true") {
40                $stickyClass = self::STICKY_CLASS;
41                $attributes->addClassName($stickyClass);
42                $snippetManager = PluginUtility::getSnippetManager();
43                $snippetManager->upsertTagsForBar(self::STICKY,
44                    array(
45                        "script" => [
46                            array(
47                                "src" => "https://cdn.jsdelivr.net/npm/sticksy@0.2.0/dist/sticksy.min.js",
48                                "integrity" => "sha256-H6uQ878/jyt6w1oBNhL6s01iAfWxACrWvVXCBjZsrGM=",
49                                "crossorigin" => "anonymous"
50                            )]
51                    ));
52                /**
53                 * If top bar
54                 */
55                $jsSnippet = <<<EOF
56let fixedNavbar = document.querySelector(".navbar.fixed-top");
57let topSpacing = fixedNavbar.offsetHeight;
58var stickyElements = Sticksy.initializeAll('.$stickyClass',{topSpacing: topSpacing})
59EOF;
60                $snippetManager
61                    ->attachJavascriptSnippetForBar(self::STICKY)
62                    ->setContent($jsSnippet);
63            }
64
65        }
66
67    }
68
69    /**
70     * @param TagAttributes $attributes
71     */
72    public static function processPosition(&$attributes)
73    {
74        if ($attributes->hasComponentAttribute(self::POSITION_ATTRIBUTE)) {
75            $position = strtolower($attributes->getValueAndRemove(self::POSITION_ATTRIBUTE));
76            if (Bootstrap::getBootStrapMajorVersion() < Bootstrap::BootStrapFiveMajorVersion) {
77                $snippetManager = PluginUtility::getSnippetManager();
78                $snippetManager->attachCssSnippetForBar(self::POSITION_SNIPPET_ID);
79            }
80
81            // Class value comes from
82            // https://getbootstrap.com/docs/5.0/utilities/position/#center-elements
83            switch ($position) {
84                case "top-left":
85                case "left-top":
86                    $attributes->addClassName("position-absolute top-0 start-0 translate-middle");
87                    break;
88                case "top-quartile-1":
89                case "quartile-1-top":
90                    self::addQuartileCss();
91                    $attributes->addClassName("position-absolute top-0 start-25 translate-middle");
92                    break;
93                case "top-center":
94                case "center-top":
95                    $attributes->addClassName("position-absolute top-0 start-50 translate-middle");
96                    break;
97                case "top-quartile-3":
98                case "quartile-3-top":
99                    self::addQuartileCss();
100                    $attributes->addClassName("position-absolute top-0 start-75 translate-middle");
101                    break;
102                case "top-right":
103                case "right-top":
104                    $attributes->addClassName("position-absolute top-0 start-100 translate-middle");
105                    break;
106                case "left-quartile-1":
107                case "quartile-1-left":
108                    self::addQuartileCss();
109                    $attributes->addClassName("position-absolute top-25 start-0 translate-middle");
110                    break;
111                case "left-center":
112                case "center-left":
113                    $attributes->addClassName("position-absolute top-50 start-0 translate-middle");
114                    break;
115                case "center-center":
116                case "center":
117                    $attributes->addClassName("position-absolute top-50 start-50 translate-middle");
118                    break;
119                case "right-center":
120                case "center-right":
121                    $attributes->addClassName("position-absolute top-50 start-100 translate-middle");
122                    break;
123                case "bottom-left":
124                case "left-bottom":
125                    $attributes->addClassName("position-absolute top-100 start-0 translate-middle");
126                    break;
127                case "bottom-center":
128                case "center-bottom":
129                    $attributes->addClassName("position-absolute top-100 start-50 translate-middle");
130                    break;
131                case "bottom-right":
132                case "right-bottom":
133                    $attributes->addClassName("position-absolute top-100 start-100 translate-middle");
134                    break;
135                case "relative":
136                case "absolute":
137                case "fixed":
138                case "static":
139                    /**
140                     * The css value are also supported
141                     * (to define that for instance the parent of a background should be at minimum relative)
142                     */
143                    $attributes->addStyleDeclaration("position", $position);
144                    break;
145
146            }
147        }
148
149    }
150
151    private static function addQuartileCss()
152    {
153        $snippetManager = PluginUtility::getSnippetManager();
154        $snippetManager->attachCssSnippetForBar(self::POSITION_QUARTILE_SNIPPET_ID);
155    }
156}
157