| @@ -5,8 +5,9 @@ | ||
| 5 | 5 | exit; |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | use ABlocks\Classes\AtomicBlockBase; |
| 9 | +use ABlocks\Classes\AtomicStyles; | |
| 9 | 10 | |
| 10 | 11 | /** |
| 11 | 12 | * atomic-svg — inline SVG with the atomic style system (fill / stroke / size). |
| 12 | 13 | * Static markup; only the scoped CSS is rendered here. |
| @@ -12,5 +13,102 @@ | ||
| 12 | 13 | * Static markup; only the scoped CSS is rendered here. |
| 13 | 14 | */ |
| 14 | 15 | class Block extends AtomicBlockBase { |
| 15 | 16 | protected $block_name = 'atomic-svg'; |
| 17 | + | |
| 18 | + /** | |
| 19 | + * The graphic fills its wrapper by default — that is what makes the Size | |
| 20 | + * panel's width resize the icon, since the wrapper shrink-wraps it. | |
| 21 | + * | |
| 22 | + * `justify-content` asks for the opposite: it positions content inside the | |
| 23 | + * box, which needs the graphic to be SMALLER than the box. While the | |
| 24 | + * graphic was filling, there was never any free space to distribute, so | |
| 25 | + * the control silently did nothing — measured, a 300px-wide block with | |
| 26 | + * `justify-content: center` painted a 300px graphic flush to the left edge. | |
| 27 | + * | |
| 28 | + * So when the author has set it, the graphic takes its own intrinsic size | |
| 29 | + * and the wrapper positions it. Emitted per bucket, so it follows the | |
| 30 | + * breakpoint and state the author set it in. | |
| 31 | + * | |
| 32 | + * Skipped for a bucket that ALSO sets Width there: Custom Width is the more | |
| 33 | + * specific, more deliberate choice — it is what makes the Size panel resize | |
| 34 | + * the icon at all — and must keep winning even once justify-content is set, | |
| 35 | + * or reducing it silently stopped doing anything the moment the author also | |
| 36 | + * centred the icon: the graphic reverted to its intrinsic size instead of | |
| 37 | + * shrinking, and with it the space it occupies inside the wrapper (what | |
| 38 | + * Align items / Justify content actually position), so both kept reading | |
| 39 | + * the icon's PREVIOUS, unshrunk size. | |
| 40 | + */ | |
| 41 | + protected function extra_css( $base, $attributes ) { | |
| 42 | + $styles = isset( $attributes['styles'] ) && is_array( $attributes['styles'] ) | |
| 43 | + ? $attributes['styles'] | |
| 44 | + : []; | |
| 45 | + | |
| 46 | + return AtomicStyles::conditional_rules( | |
| 47 | + $styles, | |
| 48 | + $base, | |
| 49 | + 'justify-content', | |
| 50 | + ' svg', | |
| 51 | + 'width:auto;max-width:100%;', | |
| 52 | + 'width' | |
| 53 | + ) | |
| 54 | + . $this->cancel_flex_item_centering( $styles, $base ); | |
| 55 | + } | |
| 56 | + | |
| 57 | + /** | |
| 58 | + * Cancel the shared width guard's `margin-left:auto;margin-right:auto` | |
| 59 | + * (see StylesSchema::state_declarations()) wherever it actually fired. | |
| 60 | + * | |
| 61 | + * That guard exists to centre a narrower TOP-LEVEL block — a plain block | |
| 62 | + * box, the only shape it was written for. This wrapper is `display: | |
| 63 | + * inline-flex`, so in that normal-flow case the auto margins do nothing at | |
| 64 | + * all: inline-level boxes never centre on their own horizontal margins. | |
| 65 | + * They start doing something only once the wrapper becomes a Flex/Grid | |
| 66 | + * ITEM of an Atomic Div/Flex/Grid parent — every value for a flex item's | |
| 67 | + * own `display` computes to a block-level "outer display" regardless of | |
| 68 | + * what was authored, which is exactly the size at which auto margins | |
| 69 | + * start responding. And what they do there is take over the item's | |
| 70 | + * position on the main axis outright — a flex item's own auto margins are | |
| 71 | + * consulted before `justify-content` ever runs, so the parent's | |
| 72 | + * Left/Center/Right stopped choosing anything: measured, `justify-content: | |
| 73 | + * flex-start` and `flex-end` on the SAME 50px-wide icon with a Custom | |
| 74 | + * Width rendered at the IDENTICAL centred position (277px from the left in | |
| 75 | + * a 604px row either way) the moment the icon carried a width of its own. | |
| 76 | + * | |
| 77 | + * So the guard is worth exactly nothing for this block in the case it was | |
| 78 | + * built for, and actively wrong in the one case it can ever reach. Rather | |
| 79 | + * than touch the shared compiler both other guards on this block already | |
| 80 | + * come from — and risk every OTHER atomic block that relies on it staying | |
| 81 | + * centred inside a normal, non-flex parent — this walks the SAME compiled | |
| 82 | + * buckets and, only where the guard actually wrote `auto` (never where an | |
| 83 | + * author's OWN margin is what is there instead — `has_horizontal_margin()` | |
| 84 | + * is what stopped the guard writing anything in that case, and this must | |
| 85 | + * agree with it or an author's margin would be overwritten right back to | |
| 86 | + * zero), resets it to `0` on the very same selector. Same specificity, | |
| 87 | + * later in this block's own <style> tag, so it is this declaration that | |
| 88 | + * wins — the shared rule is untouched, and the outcome is identical to it | |
| 89 | + * never having fired here at all. | |
| 90 | + * | |
| 91 | + * @param array $styles The block's styles object. | |
| 92 | + * @param string $base The block's own selector. | |
| 93 | + * @return string CSS, or ''. | |
| 94 | + */ | |
| 95 | + private function cancel_flex_item_centering( $styles, $base ) { | |
| 96 | + $css = ''; | |
| 97 | + foreach ( AtomicStyles::compile_rules( $styles ) as $rule ) { | |
| 98 | + list( $media, $state, $pairs ) = $rule; | |
| 99 | + $centred = false; | |
| 100 | + foreach ( $pairs as $pair ) { | |
| 101 | + if ( 'margin-left' === $pair[0] && 'auto' === $pair[1] ) { | |
| 102 | + $centred = true; | |
| 103 | + break; | |
| 104 | + } | |
| 105 | + } | |
| 106 | + if ( ! $centred ) { | |
| 107 | + continue; | |
| 108 | + } | |
| 109 | + $body = $base . $state . '{margin-left:0;margin-right:0;}'; | |
| 110 | + $css .= ( '' !== $media ) ? $media . '{' . $body . '}' : $body; | |
| 111 | + } | |
| 112 | + return $css; | |
| 113 | + } | |
| 16 | 114 | } |