├── _config.php ├── .gitattributes ├── code-of-conduct.md ├── templates ├── Fractas │ └── ElementalStylings │ │ └── Forms │ │ ├── StylingOptionsetField.ss │ │ └── StylingOptionsetField_holder.ss └── SummaryStylingInfo.ss ├── .editorconfig ├── client └── dist │ ├── css │ ├── stylings.css │ ├── cms.css │ ├── sprite-active.svg │ └── sprite.svg │ └── js │ └── StylingOptionsetField.js ├── src ├── Forms │ └── StylingOptionsetField.php ├── StylingSize.php ├── StylingLimit.php ├── StylingWidth.php ├── StylingStyle.php ├── StylingHeight.php ├── StylingTextAlign.php ├── StylingHorizontalAlign.php └── StylingVerticalAlign.php ├── composer.json ├── CONTRIBUTING.md ├── LICENSE └── README.md /_config.php: -------------------------------------------------------------------------------- 1 | 2 | <% loop $Options %> 3 |
  • 4 | checked<% end_if %><% if $isDisabled %> disabled<% end_if %> <% if $Up.Required %>required<% end_if %> /> 5 |
    6 | 7 |
    8 | 9 |
  • 10 | <% end_loop %> 11 | 12 | -------------------------------------------------------------------------------- /templates/Fractas/ElementalStylings/Forms/StylingOptionsetField_holder.ss: -------------------------------------------------------------------------------- 1 |
    2 | <% if $Title %> 3 | 4 | <% end_if %> 5 |
    6 | $Field 7 |
    8 | <% if $RightTitle %><% end_if %> 9 | <% if $Message %>$Message<% end_if %> 10 | <% if $Description %>$Description<% end_if %> 11 |
    12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # For more information about the properties used in 2 | # this file, please see the EditorConfig documentation: 3 | # http://editorconfig.org/ 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 4 9 | indent_style = space 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | 16 | [*.{yml,json,js,scss}] 17 | # The indent size used in the `package.json` file cannot be changed 18 | # https://github.com/npm/npm/pull/3180#issuecomment-16336516 19 | indent_size = 2 20 | indent_style = space 21 | 22 | [composer.json] 23 | indent_size = 4 24 | -------------------------------------------------------------------------------- /templates/SummaryStylingInfo.ss: -------------------------------------------------------------------------------- 1 |
    2 | <% if $Image %> 3 |
    4 | <% with $Image %> 5 | $Title 6 | <% end_with %> 7 |
    8 | <% end_if %> 9 | <% if $Description %> 10 |
    $Description.RAW
    11 | <% end_if %> 12 | 13 | <% if $Styling %> 14 | 23 | <% end_if %> 24 |
    25 | -------------------------------------------------------------------------------- /client/dist/css/stylings.css: -------------------------------------------------------------------------------- 1 | .textalign-left { text-align: left; } 2 | 3 | .textalign-right { text-align: right; } 4 | 5 | .textalign-center { text-align: center; } 6 | 7 | .veralign { 8 | display: flex; 9 | align-items: center; 10 | justify-content: center; 11 | } 12 | 13 | .veralign-top { align-self: flex-start; } 14 | 15 | .veralign-bottom { align-self: flex-end; } 16 | 17 | .height-regular { height: 600px; } 18 | 19 | .height-small { height: 400px; } 20 | 21 | .height-large { height: 800px; } 22 | 23 | .height-xlarge { height: 100vh; } 24 | 25 | @media (min-width: 768px) { 26 | .horalign-center .col-sm-9 { 27 | margin-left: 12.5%; 28 | } 29 | 30 | .horalign-center .col-sm-6 { 31 | margin-left: 25%; 32 | } 33 | 34 | .horalign-center .col-sm-3 { 35 | margin-left: 37.5%; 36 | } 37 | 38 | .horalign-right div[class^="col-sm-"] { 39 | float: right; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Forms/StylingOptionsetField.php: -------------------------------------------------------------------------------- 1 | getSourceEmpty() as $value => $title) { 18 | $odd = !$odd; 19 | $options[] = $this->getFieldOption($value, $title, $odd); 20 | } 21 | 22 | $properties = array_merge($properties, [ 23 | 'Options' => new ArrayList($options), 24 | ]); 25 | 26 | Requirements::javascript('fractas/elemental-stylings:client/dist/js/StylingOptionsetField.js'); 27 | 28 | return FormField::Field($properties); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /client/dist/js/StylingOptionsetField.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $.entwine('ss', function($) { 3 | $('.stylingoptionset input').entwine({ 4 | onmatch: function() { 5 | if (this.is(':checked')) { 6 | this.check(); 7 | } else { 8 | this.uncheck(); 9 | } 10 | }, 11 | getLabel: function() { 12 | return $('label', this.parent()); 13 | }, 14 | onchange: function(e) { 15 | var $otherCheckboxes = $('input', this.closest('ul')).not(this); 16 | if (this.is(':checked')) { 17 | $otherCheckboxes.uncheck(); 18 | this.check(); 19 | } else { 20 | $otherCheckboxes.check(); 21 | this.uncheck(); 22 | } 23 | }, 24 | check: function() { 25 | this.parent().addClass('ischecked'); 26 | }, 27 | uncheck: function() { 28 | this.parent().removeClass('ischecked'); 29 | } 30 | }); 31 | }); 32 | })(jQuery); 33 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fractas/elemental-stylings", 3 | "type": "silverstripe-vendormodule", 4 | "description": "Collection of useful and reusable SilverStripe Elemental stylings properties", 5 | "homepage": "http://github.com/fractaslabs/silverstripe-elemental-stylings", 6 | "keywords": [ 7 | "silverstripe", 8 | "content management", 9 | "styling", 10 | "elemental", 11 | "silverstripe elemental", 12 | "content blocks" 13 | ], 14 | "license": "BSD-3-Clause", 15 | "support": { 16 | "issues": "http://github.com/fractaslabs/silverstripe-elemental-stylings/issues" 17 | }, 18 | "authors": [{ 19 | "name": "Milan Jelicanin", 20 | "email": "milan.jelicanin@fractas.com" 21 | }, { 22 | "name": "Petar Simic", 23 | "email": "petar.simic@fractas.com" 24 | }], 25 | "require": { 26 | "dnadesign/silverstripe-elemental": "^4 || ^5", 27 | "silverstripe/vendor-plugin": "^1 || ^2" 28 | }, 29 | "require-dev": {}, 30 | "config": { 31 | "process-timeout": 600 32 | }, 33 | "extra": { 34 | "branch-alias": { 35 | "dev-master": "2.x-dev" 36 | }, 37 | "expose": [ 38 | "client/dist" 39 | ] 40 | }, 41 | "autoload": { 42 | "psr-4": { 43 | "Fractas\\ElementalStylings\\": "src/" 44 | } 45 | }, 46 | "prefer-stable": true, 47 | "minimum-stability": "dev" 48 | } 49 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Any open source product is only as good as the community behind it. You can participate by sharing code, ideas, or 4 | simply helping others. No matter what your skill level is, every contribution counts. 5 | 6 | See our [high level overview](http://silverstripe.org/contributing-to-silverstripe) on silverstripe.org on how you can 7 | help out. 8 | 9 | Or, for more detailed guidance, read one of the following pages: 10 | 11 | * [Sharing your opinion and raising issues](http://docs.silverstripe.org/en/contributing/issues_and_bugs/) 12 | * [Providing code, whether it's creating a feature or fixing a bug](http://docs.silverstripe.org/en/contributing/code/) 13 | * [Writing and translating documentation](http://docs.silverstripe.org/en/contributing/translations/) 14 | * [Translating user-interface elements](http://docs.silverstripe.org/en/contributing/translation_process/) 15 | 16 | ## Copyright 17 | 18 | **IMPORTANT: By supplying code in patches, tickets and pull requests, you agree to assign copyright of that code to 19 | FractasLabs, on the condition that FractasLabs releases that code under 20 | the BSD license.** unless otherwise noted. 21 | 22 | We ask for this so that the ownership in the license is clear and unambiguous, and so that community involvement doesn't 23 | stop us from being able to continue supporting these projects. By releasing this code under a permissive license, this 24 | copyright assignment won't prevent you from using the code in any way you see fit. 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Fractas 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /src/StylingSize.php: -------------------------------------------------------------------------------- 1 | 'Varchar(255)', 14 | ]; 15 | 16 | /** 17 | * @var string 18 | */ 19 | private static $singular_name = 'Size'; 20 | 21 | /** 22 | * @var string 23 | */ 24 | private static $plural_name = 'Sizes'; 25 | 26 | /** 27 | * @config 28 | * 29 | * @var array 30 | */ 31 | private static $size = []; 32 | 33 | public function getStylingSizeNice($key) 34 | { 35 | return (!empty($this->owner->config()->get('size')[$key])) ? $this->owner->config()->get('size')[$key] : $key; 36 | } 37 | 38 | public function getStylingSizeData() 39 | { 40 | return ArrayData::create([ 41 | 'Label' => self::$singular_name, 42 | 'Value' => $this->getStylingSizeNice($this->owner->Size), 43 | ]); 44 | } 45 | 46 | /** 47 | * @return string 48 | */ 49 | public function getSizeVariant() 50 | { 51 | $size = $this->owner->Size; 52 | $sizes = $this->owner->config()->get('size'); 53 | 54 | if (isset($sizes[$size])) { 55 | $size = strtolower($size); 56 | } else { 57 | $size = ''; 58 | } 59 | 60 | return 'size-'.$size; 61 | } 62 | 63 | public function updateCMSFields(FieldList $fields) 64 | { 65 | $size = $this->owner->config()->get('size'); 66 | if ($size && count($size) > 1) { 67 | $fields->addFieldsToTab('Root.Styling', DropdownField::create('Size', _t(__CLASS__.'.SIZE', 'Size'), $size)); 68 | } else { 69 | $fields->removeByName('Size'); 70 | } 71 | 72 | return $fields; 73 | } 74 | 75 | public function populateDefaults() 76 | { 77 | $size = $this->owner->config()->get('size'); 78 | $size = reset($size); 79 | 80 | $this->owner->Size = $size; 81 | 82 | parent::populateDefaults(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/StylingLimit.php: -------------------------------------------------------------------------------- 1 | 'Varchar(255)', 14 | ]; 15 | 16 | /** 17 | * @var string 18 | */ 19 | private static $singular_name = 'Limit'; 20 | 21 | /** 22 | * @var string 23 | */ 24 | private static $plural_name = 'Limits'; 25 | 26 | /** 27 | * @config 28 | * 29 | * @var array 30 | */ 31 | private static $limit = []; 32 | 33 | public function getStylingLimitNice($key) 34 | { 35 | return (!empty($this->owner->config()->get('limit')[$key])) ? $this->owner->config()->get('limit')[$key] : $key; 36 | } 37 | 38 | public function getStylingLimitData() 39 | { 40 | return ArrayData::create([ 41 | 'Label' => self::$singular_name, 42 | 'Value' => $this->getStylingLimitNice($this->owner->Limit), 43 | ]); 44 | } 45 | 46 | /** 47 | * @return string 48 | */ 49 | public function getLimitVariant() 50 | { 51 | $limit = $this->owner->Limit; 52 | $limits = $this->owner->config()->get('limit'); 53 | 54 | if (isset($limits[$limit])) { 55 | $limit = strtolower($limit); 56 | } else { 57 | $limit = ''; 58 | } 59 | 60 | return 'limit-'.$limit; 61 | } 62 | 63 | public function updateCMSFields(FieldList $fields) 64 | { 65 | $limit = $this->owner->config()->get('limit'); 66 | if ($limit && count($limit) > 1) { 67 | $fields->addFieldsToTab('Root.Styling', DropdownField::create('Limit', _t(__CLASS__.'.LIMIT', 'Limit'), $limit)); 68 | } else { 69 | $fields->removeByName('Limit'); 70 | } 71 | 72 | return $fields; 73 | } 74 | 75 | public function populateDefaults() 76 | { 77 | $limit = $this->owner->config()->get('limit'); 78 | $limit = reset($limit); 79 | 80 | $this->owner->Limit = $limit; 81 | 82 | parent::populateDefaults(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/StylingWidth.php: -------------------------------------------------------------------------------- 1 | 'Varchar(255)', 15 | ]; 16 | 17 | /** 18 | * @var string 19 | */ 20 | private static $singular_name = 'Width'; 21 | 22 | /** 23 | * @var string 24 | */ 25 | private static $plural_name = 'Widths'; 26 | 27 | /** 28 | * @config 29 | * 30 | * @var array 31 | */ 32 | private static $width = []; 33 | 34 | public function getStylingWidthNice($key) 35 | { 36 | return (!empty($this->owner->config()->get('width')[$key])) ? $this->owner->config()->get('width')[$key] : $key; 37 | } 38 | 39 | public function getStylingWidthData() 40 | { 41 | return ArrayData::create([ 42 | 'Label' => self::$singular_name, 43 | 'Value' => $this->getStylingWidthNice($this->owner->Width), 44 | ]); 45 | } 46 | 47 | /** 48 | * @return string 49 | */ 50 | public function getWidthVariant() 51 | { 52 | $width = $this->owner->Width; 53 | $widths = $this->owner->config()->get('width'); 54 | 55 | if (isset($widths[$width])) { 56 | $width = strtolower($width); 57 | } else { 58 | $width = ''; 59 | } 60 | 61 | return $width; 62 | } 63 | 64 | public function updateCMSFields(FieldList $fields) 65 | { 66 | $width = $this->owner->config()->get('width'); 67 | if ($width && count($width) > 1) { 68 | $fields->addFieldsToTab('Root.Styling', StylingOptionsetField::create('Width', _t(__CLASS__.'.WIDTH', 'Width Size'), $width)); 69 | } else { 70 | $fields->removeByName('Width'); 71 | } 72 | 73 | return $fields; 74 | } 75 | 76 | public function populateDefaults() 77 | { 78 | $width = $this->owner->config()->get('width'); 79 | $width = reset($width); 80 | 81 | $this->owner->Width = $width; 82 | 83 | parent::populateDefaults(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/StylingStyle.php: -------------------------------------------------------------------------------- 1 | owner->config()->get('styles')[$key])) ? $this->owner->config()->get('styles')[$key] : $key; 32 | } 33 | 34 | public function getStylingStyleData() 35 | { 36 | return ArrayData::create([ 37 | 'Label' => self::$singular_name, 38 | 'Value' => $this->getStylingStyleNice($this->owner->Style), 39 | ]); 40 | } 41 | 42 | public function getStylingTitleData() 43 | { 44 | return ArrayData::create([ 45 | 'Label' => 'Title', 46 | 'Value' => $this->owner->obj('ShowTitle')->Nice(), 47 | ]); 48 | } 49 | 50 | /** 51 | * @return string 52 | */ 53 | public function updateStyleVariant(&$style) 54 | { 55 | if (isset($style)) { 56 | $style = strtolower($style); 57 | } else { 58 | $style = ''; 59 | } 60 | $style = 'style-'.$style; 61 | 62 | return $style; 63 | } 64 | 65 | public function updateCMSFields(FieldList $fields) 66 | { 67 | $style = $this->owner->config()->get('styles'); 68 | if ($style && count($style) > 1) { 69 | $fields->addFieldsToTab('Root.Styling', DropdownField::create('Style', _t(__CLASS__.'.STYLE', 'Style'), $style)); 70 | } else { 71 | $fields->removeByName('Style'); 72 | } 73 | 74 | return $fields; 75 | } 76 | 77 | public function populateDefaults() 78 | { 79 | $style = $this->owner->config()->get('styles'); 80 | $style = array_key_first($style); 81 | 82 | $this->owner->Style = $style; 83 | 84 | parent::populateDefaults(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/StylingHeight.php: -------------------------------------------------------------------------------- 1 | 'Varchar(255)', 15 | ]; 16 | 17 | /** 18 | * @var string 19 | */ 20 | private static $singular_name = 'Height'; 21 | 22 | /** 23 | * @var string 24 | */ 25 | private static $plural_name = 'Heights'; 26 | 27 | /** 28 | * @config 29 | * 30 | * @var array 31 | */ 32 | private static $height = []; 33 | 34 | public function getStylingHeightNice($key) 35 | { 36 | return (!empty($this->owner->config()->get('height')[$key])) ? $this->owner->config()->get('height')[$key] : $key; 37 | } 38 | 39 | public function getStylingHeightData() 40 | { 41 | return ArrayData::create([ 42 | 'Label' => self::$singular_name, 43 | 'Value' => $this->getStylingHeightNice($this->owner->Height), 44 | ]); 45 | } 46 | 47 | /** 48 | * @return string 49 | */ 50 | public function getHeightVariant() 51 | { 52 | $height = $this->owner->Height; 53 | $heights = $this->owner->config()->get('height'); 54 | 55 | if (isset($heights[$height])) { 56 | $height = strtolower($height); 57 | } else { 58 | $height = ''; 59 | } 60 | 61 | return 'height-'.$height; 62 | } 63 | 64 | public function updateCMSFields(FieldList $fields) 65 | { 66 | $height = $this->owner->config()->get('height'); 67 | if ($height && count($height) > 1) { 68 | $fields->addFieldsToTab('Root.Styling', StylingOptionsetField::create('Height', _t(__CLASS__.'.HEIGHT', 'Height Size'), $height)); 69 | } else { 70 | $fields->removeByName('Height'); 71 | } 72 | 73 | return $fields; 74 | } 75 | 76 | public function populateDefaults() 77 | { 78 | $height = $this->owner->config()->get('height'); 79 | $height = reset($height); 80 | 81 | $this->owner->Height = $height; 82 | 83 | parent::populateDefaults(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/StylingTextAlign.php: -------------------------------------------------------------------------------- 1 | 'Varchar(255)', 14 | ]; 15 | 16 | /** 17 | * @var string 18 | */ 19 | private static $singular_name = 'Text Align'; 20 | 21 | /** 22 | * @var string 23 | */ 24 | private static $plural_name = 'Text Aligns'; 25 | 26 | /** 27 | * @config 28 | * 29 | * @var array 30 | */ 31 | private static $textalign = []; 32 | 33 | public function getStylingTextAlignNice($key) 34 | { 35 | return (!empty($this->owner->config()->get('textalign')[$key])) ? $this->owner->config()->get('textalign')[$key] : $key; 36 | } 37 | 38 | public function getStylingTextAlignData() 39 | { 40 | return ArrayData::create([ 41 | 'Label' => self::$singular_name, 42 | 'Value' => $this->getStylingTextAlignNice($this->owner->TextAlign), 43 | ]); 44 | } 45 | 46 | /** 47 | * @return string 48 | */ 49 | public function getTextAlignVariant() 50 | { 51 | $textalign = $this->owner->TextAlign; 52 | $textaligns = $this->owner->config()->get('textalign'); 53 | 54 | if (isset($textaligns[$textalign])) { 55 | $textalign = strtolower($textalign); 56 | } else { 57 | $textalign = ''; 58 | } 59 | 60 | return 'textalign-'.$textalign; 61 | } 62 | 63 | public function updateCMSFields(FieldList $fields) 64 | { 65 | $fields->removeByName('TextAlign'); 66 | $textalign = $this->owner->config()->get('textalign'); 67 | if ($textalign && count($textalign) > 1) { 68 | $fields->addFieldsToTab( 69 | 'Root.Styling', 70 | StylingOptionsetField::create('TextAlign', _t(__CLASS__.'.TEXTALIGN', 'Text Align'), $textalign) 71 | ); 72 | } 73 | 74 | return $fields; 75 | } 76 | 77 | public function populateDefaults() 78 | { 79 | $textalign = $this->owner->config()->get('textalign'); 80 | $textalign = key($textalign); 81 | 82 | $this->owner->TextAlign = $textalign; 83 | 84 | parent::populateDefaults(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/StylingHorizontalAlign.php: -------------------------------------------------------------------------------- 1 | 'Varchar(255)', 14 | ]; 15 | 16 | /** 17 | * @var string 18 | */ 19 | private static $singular_name = 'Horizontal Align'; 20 | 21 | /** 22 | * @var string 23 | */ 24 | private static $plural_name = 'Horizontal Aligns'; 25 | 26 | /** 27 | * @config 28 | * 29 | * @var array 30 | */ 31 | private static $horalign = []; 32 | 33 | public function getStylingHorizontalAlignNice($key) 34 | { 35 | return (!empty($this->owner->config()->get('horalign')[$key])) ? $this->owner->config()->get('horalign')[$key] : $key; 36 | } 37 | 38 | public function getStylingHorizontalAlignData() 39 | { 40 | return ArrayData::create([ 41 | 'Label' => self::$singular_name, 42 | 'Value' => $this->getStylingHorizontalAlignNice($this->owner->HorAlign), 43 | ]); 44 | } 45 | 46 | /** 47 | * @return string 48 | */ 49 | public function getHorAlignVariant() 50 | { 51 | $horalign = $this->owner->HorAlign; 52 | $horaligns = $this->owner->config()->get('horalign'); 53 | 54 | if (isset($horaligns[$horalign])) { 55 | $horalign = strtolower($horalign); 56 | } else { 57 | $horalign = ''; 58 | } 59 | 60 | return 'horalign-'.$horalign; 61 | } 62 | 63 | public function updateCMSFields(FieldList $fields) 64 | { 65 | $fields->removeByName('HorAlign'); 66 | $horalign = $this->owner->config()->get('horalign'); 67 | if ($horalign && count($horalign) > 1) { 68 | $fields->addFieldsToTab( 69 | 'Root.Styling', 70 | StylingOptionsetField::create('HorAlign', _t(__CLASS__.'.HORIZONTALALIGN', 'Horizontal Align'), $horalign) 71 | ); 72 | } 73 | 74 | return $fields; 75 | } 76 | 77 | public function populateDefaults() 78 | { 79 | $horalign = $this->owner->config()->get('horalign'); 80 | $horalign = key($horalign); 81 | 82 | $this->owner->HorAlign = $horalign; 83 | 84 | parent::populateDefaults(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/StylingVerticalAlign.php: -------------------------------------------------------------------------------- 1 | 'Varchar(255)', 14 | ]; 15 | 16 | /** 17 | * @var string 18 | */ 19 | private static $singular_name = 'Vertical Align'; 20 | 21 | /** 22 | * @var string 23 | */ 24 | private static $plural_name = 'Vertical Aligns'; 25 | 26 | /** 27 | * @config 28 | * 29 | * @var array 30 | */ 31 | private static $veralign = []; 32 | 33 | public function getStylingVerticalAlignNice($key) 34 | { 35 | return (!empty($this->owner->config()->get('veralign')[$key])) ? $this->owner->config()->get('veralign')[$key] : $key; 36 | } 37 | 38 | public function getStylingVerticalAlignData() 39 | { 40 | return ArrayData::create([ 41 | 'Label' => self::$singular_name, 42 | 'Value' => $this->getStylingVerticalAlignNice($this->owner->VerAlign), 43 | ]); 44 | } 45 | 46 | /** 47 | * @return string 48 | */ 49 | public function getVerAlignVariant() 50 | { 51 | $veralign = $this->owner->VerAlign; 52 | $veraligns = $this->owner->config()->get('veralign'); 53 | 54 | if (isset($veraligns[$veralign])) { 55 | $veralign = strtolower($veralign); 56 | } else { 57 | $veralign = ''; 58 | } 59 | 60 | return 'veralign-'.$veralign; 61 | } 62 | 63 | public function updateCMSFields(FieldList $fields) 64 | { 65 | $fields->removeByName('VerAlign'); 66 | $veralign = $this->owner->config()->get('veralign'); 67 | if ($veralign && count($veralign) > 1) { 68 | $fields->addFieldsToTab( 69 | 'Root.Styling', 70 | StylingOptionsetField::create('VerAlign', _t(__CLASS__.'.VERTICALALIGN', 'Vertical Align'), $veralign) 71 | ); 72 | } 73 | 74 | return $fields; 75 | } 76 | 77 | public function populateDefaults() 78 | { 79 | if ($this->owner->config()->get('stop_veralign_inheritance')) { 80 | $veralign = $this->owner->config()->get('veralign', Config::UNINHERITED); 81 | } else { 82 | $veralign = $this->owner->config()->get('veralign'); 83 | } 84 | 85 | $veralign = key($veralign); 86 | $this->owner->VerAlign = $veralign; 87 | 88 | parent::populateDefaults(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SilverStripe Elemental Stylings 2 | [![Latest Stable Version](https://poser.pugx.org/fractas/elemental-stylings/v/stable)](https://packagist.org/packages/fractas/elemental-stylings) 3 | [![Total Downloads](https://poser.pugx.org/fractas/elemental-stylings/downloads)](https://packagist.org/packages/fractas/elemental-stylings) 4 | [![Latest Unstable Version](https://poser.pugx.org/fractas/elemental-stylings/v/unstable)](https://packagist.org/packages/fractas/elemental-stylings) 5 | [![License](https://poser.pugx.org/fractas/elemental-stylings/license)](https://packagist.org/packages/fractas/elemental-stylings) 6 | 7 | 8 | ## Introduction 9 | 10 | This module extends a [SilverStripe Elemental Blocks](https://github.com/dnadesign/silverstripe-elemental) to enhance its functionalities with predefined sets of Classes of Styling elements. 11 | 12 | Predefined Styling classes: 13 | - **StylingHeight** - changes a height of a Block 14 | - **StylingHorizontalAlign** - changes a horizontal alignment of a Block 15 | - **StylingLimit** - changes a limit of a Block 16 | - **StylingSize** - changes a size of a Block 17 | - **StylingStyle** _(extended from Core module)_ - special enhancements for a class extended from Core module 18 | - **StylingTextAlign** - changes a text alignment inside of a Block 19 | - **StylingVerticalAlign** - changes a vertical alignment of a Block 20 | - **StylingWidth** - changes a width of a Block _(example uses Bootstrap Grid syntax)_ 21 | 22 | The module provides basic markup for each of the stylings but you have an option to edit and/or replace those predefined styles. 23 | 24 | 25 | ## Requirements 26 | 27 | * SilverStripe CMS ^4.0 || ^5.0 28 | * SilverStripe Elemental Blocks ^4.0 || ^5.0 29 | 30 | 31 | ## Installation 32 | 33 | - Install a module via Composer 34 | ``` 35 | composer require fractas/elemental-stylings 36 | ``` 37 | - Follow an instructions for installation of [Elemental Blocks module](https://github.com/dnadesign/silverstripe-elemental#installation) 38 | - Apply a desired Styling Class extension on Block class _(ie. ElementContent that ships with Core module)_ 39 | **mysite/\_config/elements.yml** 40 | ```yaml 41 | DNADesign\Elemental\Models\ElementContent: 42 | extensions: 43 | - Fractas\ElementalStylings\StylingHeight 44 | - Fractas\ElementalStylings\StylingHorizontalAlign 45 | - Fractas\ElementalStylings\StylingStyle 46 | - Fractas\ElementalStylings\StylingTextAlign 47 | - Fractas\ElementalStylings\StylingVerticalAlign 48 | - Fractas\ElementalStylings\StylingWidth 49 | ``` 50 | - Add an desired styles based on your preferences, see [Configuration example](#full-configuration-example) 51 | - Optionaly, you can require basic CSS stylings provided with this module to your controller class like: 52 | **mysite/code/PageController.php** 53 | ```php 54 | Requirements::css('fractas/elemental-stylings:client/dist/css/stylings.css'); 55 | ``` 56 | - Build and flush your project ```vendor/bin/sake dev/build flush=1``` 57 | 58 | 59 | ## Full configuration example 60 | 61 | This is a sample configuration for use of Stylings classes in YML configuration. 62 | 63 | **mysite/\_config/elements.yml** 64 | 65 | ```yaml 66 | DNADesign\Elemental\Models\ElementContent: 67 | extensions: 68 | - Fractas\ElementalStylings\StylingHeight 69 | - Fractas\ElementalStylings\StylingHorizontalAlign 70 | - Fractas\ElementalStylings\StylingStyle 71 | - Fractas\ElementalStylings\StylingTextAlign 72 | - Fractas\ElementalStylings\StylingVerticalAlign 73 | - Fractas\ElementalStylings\StylingWidth 74 | styles: 75 | light: 'Light background color with Dark text' 76 | dark: 'Dark background color with White text' 77 | textalign: 78 | left: 'Left' 79 | right: 'Right' 80 | center: 'Center' 81 | horalign: 82 | left: 'Left' 83 | right: 'Right' 84 | center: 'Center' 85 | veralign: 86 | top: 'Top' 87 | middle: 'Middle' 88 | bottom: 'Bottom' 89 | height: 90 | small: 'Small' 91 | medium: 'Medium' 92 | large: 'Large' 93 | width: 94 | col-sm-6: '50%' 95 | col-sm-4: '33.33%' 96 | col-sm-12: '100%' 97 | ``` 98 | 99 | ## Implementation example: 'Text with Image' Element 100 | 101 | * New Element class file: [ElementContentImage.php](https://gist.github.com/jelicanin/20d11104a89fd9ea3a1e69b8bc91824b) 102 | * New Element template file: [ElementContentImage.ss](https://gist.github.com/jelicanin/aec741745d417e9047efbf25bf93245d) 103 | 104 | 105 | ## Screenshots 106 | 107 | Updated GridField with preview of applied stylings: 108 | ![GridFieldStylings](docs/images/overview-gridfield-stylings.png?v=2) 109 | 110 | 111 | Styling tab of a Block with icons for specific styles: 112 | ![BlockStylings](docs/images/overview-block-stylings.png?v=2) 113 | 114 | 115 | ## Reporting Issues 116 | 117 | Please [create an issue](https://github.com/fractaslabs/silverstripe-elemental-stylings/issues) for any bugs you've found, or features you're missing. 118 | 119 | 120 | ## License 121 | 122 | See [License](LICENSE) 123 | 124 | 125 | ## Credits 126 | 127 | Styling icons from IcoMoon - Free by [IcoMoon](https://icomoon.io/app) 128 | -------------------------------------------------------------------------------- /client/dist/css/cms.css: -------------------------------------------------------------------------------- 1 | .styling-block-preview {} 2 | 3 | .styling-block-preview__description { 4 | min-width: 680px; 5 | } 6 | 7 | .styling-block-preview__image { 8 | float: left; 9 | display: block; 10 | margin-right: 10px; 11 | margin-bottom: 10px; 12 | } 13 | 14 | .styling-block-preview__list { 15 | list-style: none; 16 | margin: 0; 17 | padding: 0; 18 | font-size: 12px; 19 | margin-top: 15px; 20 | clear: both; 21 | } 22 | 23 | .styling-block-preview__list-item { 24 | display: inline; 25 | float: left; 26 | margin-right: 20px; 27 | } 28 | 29 | .styling-block-preview__list-item strong { 30 | display: block; 31 | } 32 | 33 | .elemental-editor .col-EditorPreview { 34 | padding-bottom: 10px; 35 | } 36 | 37 | /* Fix for no margin between Gridfield table and subsequent fields */ 38 | .cms-content-view .grid-field, .cms-content-view .grid-field__table { 39 | margin-bottom: 1.2308rem; 40 | } 41 | 42 | .cms-edit-form .stylingoptionset .radio { 43 | position: absolute; 44 | opacity: 0; 45 | left: 0; 46 | width: 60px; 47 | height: 40px; 48 | } 49 | 50 | .cms-edit-form .stylingoptionset ul li { 51 | display: inline-block; 52 | text-align: center; 53 | width: 60px; 54 | position: relative; 55 | } 56 | 57 | .cms-edit-form .stylingoptionset ul { 58 | padding-left: 0; 59 | margin-bottom: 0; 60 | } 61 | 62 | .cms-edit-form .stylingoptionset label { 63 | margin-bottom: 0; 64 | } 65 | 66 | .cms-edit-form .stylingoptionset .icon-wrap { 67 | display: block; 68 | width: 60px; 69 | height: 40px; 70 | margin: 5px auto; 71 | border: 1px solid #e5e8eb; 72 | padding: 7px; 73 | } 74 | 75 | .cms-edit-form .stylingoptionset .ischecked .icon-wrap { 76 | border: 1px solid #29abe2; 77 | background-color: #e6f5fc; 78 | } 79 | 80 | .cms-edit-form .stylingoptionset .icon { 81 | display: inline-block; 82 | background-repeat: no-repeat; 83 | background-image: url(sprite.svg); 84 | width: 24px; 85 | height: 24px; 86 | } 87 | 88 | .cms-edit-form .stylingoptionset .ischecked .icon { 89 | background-image: url(sprite-active.svg); 90 | } 91 | 92 | .cms-edit-form .stylingoptionset .form_itemeditform_horalign_left, 93 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_horalign_left { 94 | background-position: -80px 0; 95 | } 96 | 97 | .cms-edit-form .stylingoptionset .form_itemeditform_horalign_right, 98 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_horalign_right { 99 | background-position: -120px 0; 100 | } 101 | 102 | .cms-edit-form .stylingoptionset .form_itemeditform_horalign_center, 103 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_horalign_center { 104 | background-position: -40px 0; 105 | } 106 | 107 | .cms-edit-form .stylingoptionset .form_itemeditform_veralign_top, 108 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_veralign_top { 109 | background-position: -160px 0; 110 | } 111 | 112 | .cms-edit-form .stylingoptionset .form_itemeditform_veralign_bottom, 113 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_veralign_bottom { 114 | background-position: 0 0; 115 | } 116 | 117 | .cms-edit-form .stylingoptionset .form_itemeditform_veralign_middle, 118 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_veralign_middle { 119 | background-position: -200px 0; 120 | } 121 | 122 | .cms-edit-form .stylingoptionset .form_itemeditform_textalign_left, 123 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_textalign_left { 124 | background-position: -280px 0; 125 | } 126 | 127 | .cms-edit-form .stylingoptionset .form_itemeditform_textalign_right, 128 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_textalign_right { 129 | background-position: -320px 0; 130 | } 131 | 132 | .cms-edit-form .stylingoptionset .form_itemeditform_textalign_center, 133 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_textalign_center { 134 | background-position: -240px 0; 135 | } 136 | 137 | .cms-edit-form .stylingoptionset .form_itemeditform_height_small, 138 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_height_small { 139 | background-position: -364px 0; 140 | } 141 | 142 | .cms-edit-form .stylingoptionset .form_itemeditform_height_medium, 143 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_height_medium { 144 | background-position: -411px 0; 145 | } 146 | 147 | .cms-edit-form .stylingoptionset .form_itemeditform_height_large, 148 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_height_large { 149 | background-position: -456px 0; 150 | } 151 | 152 | .cms-edit-form .stylingoptionset .form_itemeditform_width_col-sm-9, 153 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_width_col-sm-9 { 154 | background-position: -613px 0; 155 | } 156 | 157 | .cms-edit-form .stylingoptionset .form_itemeditform_width_col-sm-6, 158 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_width_col-sm-6 { 159 | background-position: -576px 0; 160 | } 161 | 162 | .cms-edit-form .stylingoptionset .form_itemeditform_width_col-sm-3, 163 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_width_col-sm-3 { 164 | background-position: -542px 0; 165 | } 166 | 167 | .cms-edit-form .stylingoptionset .form_itemeditform_width_col-sm-12, 168 | .cms-edit-form .stylingoptionset .ischecked .form_itemeditform_width_col-sm-12 { 169 | background-position: -650px 0; 170 | } 171 | -------------------------------------------------------------------------------- /client/dist/css/sprite-active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sprite-active 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /client/dist/css/sprite.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sprite-active 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | --------------------------------------------------------------------------------