1<?php
2
3namespace ComboStrap;
4
5
6
7class Breakpoint
8{
9
10
11    /**
12     *
13     * When the container query are a thing, we may change the breakpoint
14     * https://twitter.com/addyosmani/status/1524039090655481857
15     * https://groups.google.com/a/chromium.org/g/blink-dev/c/gwzxnTJDLJ8
16     *
17     */
18    private const BREAKPOINTS_TO_PIXELS = array(
19        self::XS => 375,
20        self::SM => 576,
21        self::MD => 768,
22        self::LG => 992,
23        self::XL => 1200,
24        self::XXL => 1400
25    );
26
27    public const BREAKPOINTS_LONG_TO_SHORT_NAMES = array(
28        self::EXTRA_SMALL_NAME => self::XS,
29        self::BREAKPOINT_SMALL_NAME => self::SM,
30        self::BREAKPOINT_MEDIUM_NAME => self::MD,
31        self::BREAKPOINT_LARGE_NAME => self::LG,
32        self::BREAKPOINT_EXTRA_LARGE_NAME => self::XL,
33        self::EXTRA_EXTRA_LARGE_NAME => self::XXL,
34        self::NEVER_NAME => self::FLUID
35    );
36    public const BREAKPOINT_EXTRA_LARGE_NAME = "extra-large";
37    public const BREAKPOINT_LARGE_NAME = "large";
38    public const BREAKPOINT_SMALL_NAME = "small";
39    public const BREAKPOINT_MEDIUM_NAME = "medium";
40    /**
41     * Breakpoint naming
42     */
43    public const EXTRA_SMALL_NAME = "extra-small";
44    public const NEVER_NAME = "never";
45    public const EXTRA_EXTRA_LARGE_NAME = "extra-extra-large";
46    public const MD = "md";
47    const LG = "lg";
48    const XL = "xl";
49    const XXL = "xxl";
50    const FLUID = "fluid";
51    const SM = "sm";
52    const XS = "xs";
53
54    private string $shortBreakpointName;
55
56    public function __construct(string $shortBreakpointName)
57    {
58        $this->shortBreakpointName = $shortBreakpointName;
59    }
60
61
62    /**
63     * @param $name - the short name, the name used by bootstrap
64     * @return Breakpoint
65     */
66    public static function createFromShortName($name): Breakpoint
67    {
68        return new Breakpoint($name);
69    }
70
71    public static function createFromLongName($longName): Breakpoint
72    {
73        $breakpointShortName = self::BREAKPOINTS_LONG_TO_SHORT_NAMES[$longName];
74        if ($breakpointShortName === null) {
75            LogUtility::internalError("The breakpoint name ($longName) is unknown, defaulting to md");
76            $breakpointShortName = "md";
77        }
78        return new Breakpoint($breakpointShortName);
79    }
80
81    /**
82     * @return Breakpoint[];
83     */
84    public static function getBreakpoints(): array
85    {
86        $breakpoints = [];
87        foreach (array_keys(self::BREAKPOINTS_TO_PIXELS) as $shortName) {
88            $breakpoints[] = Breakpoint::createFromShortName($shortName);
89        }
90        $breakpoints[] = Breakpoint::createFromShortName(self::FLUID);
91        return $breakpoints;
92    }
93
94    /**
95     * @throws ExceptionInfinite
96     */
97    public function getWidth(): int
98    {
99        if (in_array($this->shortBreakpointName, [Breakpoint::NEVER_NAME, Breakpoint::FLUID])) {
100            // 100% on all viewport
101            // infinite with
102            throw new ExceptionInfinite();
103        }
104        $value = self::BREAKPOINTS_TO_PIXELS[$this->shortBreakpointName];
105        if ($value !== null) {
106            return $value;
107        }
108        LogUtility::internalError("The breakpoint short name ($this->shortBreakpointName) is unknown, defaulting to md");
109        return 768;
110    }
111
112    public function getShortName(): string
113    {
114        return $this->shortBreakpointName;
115    }
116
117    public function __toString()
118    {
119        return $this->shortBreakpointName;
120    }
121
122
123}
124