From 51b5a2381468126fa0e7412a2d7a6d881c631f38 Mon Sep 17 00:00:00 2001 From: Jellygnite Date: Thu, 7 Apr 2022 13:13:14 +1000 Subject: [PATCH] added group and responsive helper --- README.md | 46 ++++++++++--- client/dist/css/bundle.css | 7 ++ src/Extensions/DynamicStyleExtension.php | 85 ++++++++++++++++++++---- src/Model/StyleObject.php | 8 ++- 4 files changed, 123 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 592851d..87a4894 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,14 @@ A good example of where you might want extra styles within your template is when **UPDATES** +- v4.4.2 : Minor updates. Ability to group styles. Responsive helper function to create multiple versions of a single style for different viewports. - v4.4.0 : Extra fields are now available. Multiselect, Optionset and ImageOptionset - v4.3.0 : Includes front end editing for styles. With almost real time results you can see exactly what your elements will look like with various styles applied. You can also use the back end preview area to access this feature. +**TO DO** +- move front end editor into iframe +- improve responsive helper UI + ## Requirements @@ -26,8 +31,6 @@ composer require jellygnite/silverstripe-elemental-style ``` - - ## Example configurations Include the following information in your config: @@ -43,6 +46,8 @@ Include the following information in your config: - 'Suffix' : Suffix for the outputted style - 'Options' : Array of options to create different form fields. Slider and Multiselect (listbox) are the available field types. - 'Default' : Allows a default value when nothing is selected in the dropdown field. Note this does not have to exist as an option in the allowed Styles, i.e. it can be whatever you want. +- 'Group' : Group multiple styles on one line. Use CamelCase for the Group name as this will also be used as the Group title. +- 'Responsive' : This is a helper function to quickly create multiple styles for responsive viewports. ### Method 1 @@ -64,17 +69,27 @@ You can add extra styles to your individual Elements, e.g. 'ElementPaddingVertical' => [ 'Title' => 'Element Padding Vertical', 'Description' => 'Adjust the padding on top and bottom sides of the block element', - 'Tab' => 'Container', 'Location' => 'element.class', + 'Prefix' => 'py-', 'Styles' => [ 'Default' => '', - 'None' => 'py-0', - 'X-Small' => 'py-2', - 'Small' => 'py-4', - 'Medium' => 'py-6', - 'Large' => 'py-8', - 'X-Large' => 'py-9', - ] + 'None' => '0', + 'X-Small' => '2', + 'Small' => '4', + 'Medium' => '6', + 'Large' => '8', + 'X-Large' => '9', + ], + 'Responsive' => [ + 'Mobile' => [ + ], + 'Tablet' => [ + 'Prefix' => 'py-sm-', // You can override any of the original style options + ], + 'Desktop' => [ + 'Prefix' => 'py-lg-', + ], + ], ], 'ElementPaddingTop' => [ 'Title' => 'Element Padding Top', @@ -209,6 +224,17 @@ DNADesign\Elemental\Models\BaseElement: 'Description': 'Set the number of columns for a grid' 'Location': 'grid' 'Tab': 'Layout' + 'Group': 'Grid' + 'Styles': + 'Full': 'uk-child-width-1-1' + 'Two column': 'uk-child-width-1-2' + 'Three column': 'uk-child-width-1-3' + GridTablet: + 'Title': 'Grid Tablet' + 'Description': 'Set the number of columns for a grid' + 'Location': 'grid' + 'Tab': 'Layout' + 'Group': 'Grid' 'Styles': 'Full': 'uk-child-width-1-1' 'Two column': 'uk-child-width-1-2' diff --git a/client/dist/css/bundle.css b/client/dist/css/bundle.css index a3bd7d2..46b92b4 100644 --- a/client/dist/css/bundle.css +++ b/client/dist/css/bundle.css @@ -31,3 +31,10 @@ [data-es-type="checkboxset"] input + span:hover { border-color: #43536d;color: #43536d; } [data-es-type="checkboxset"] input:checked + span { border-color: #0060df; background: #0060df;color: #fff; padding-left: 24px;} [data-es-type="checkboxset"] input:checked + span::before {content:""; display: inline-block; position: absolute; left:4px; width:18px; height:20px; background-size:contain; background: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"%3E%3Cpath fill="none" stroke="%23FFF" stroke-width="12" stroke-miterlimit="10" d="M20,50l20,20l40,-40"/%3E%3C/svg%3E%0A') no-repeat center center;} + + +.form__field-holder.es-fieldgroup { display: flex; align-content: stretch; flex-wrap: wrap;} +.form__field-holder.es-fieldgroup > .form__fieldgroup-item { flex-grow: 1;flex-basis: 166px;flex-shrink: 1;} + + + diff --git a/src/Extensions/DynamicStyleExtension.php b/src/Extensions/DynamicStyleExtension.php index 6a8509f..916b5fb 100644 --- a/src/Extensions/DynamicStyleExtension.php +++ b/src/Extensions/DynamicStyleExtension.php @@ -10,8 +10,11 @@ use SilverStripe\ORM\DataExtension; use SilverStripe\Forms\CheckboxSetField; use SilverStripe\Forms\FormField; +use SilverStripe\Forms\FieldGroup; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\DropdownField; +use SilverStripe\Forms\GroupedDropdownField; + use SilverStripe\Forms\HiddenField; use SilverStripe\Forms\ListboxField; use SilverStripe\Forms\OptionsetField; @@ -73,6 +76,7 @@ public function updateCMSFields(FieldList $fields) { } if (is_array($arr_config_styleobjects) && count($arr_config_styleobjects) > 0) { + $arrFieldGoups = []; foreach($arr_config_styleobjects as $styleobject){ $index = $styleobject->getIndex(); $fieldName = self::getStyleFieldName($index); @@ -81,6 +85,7 @@ public function updateCMSFields(FieldList $fields) { $fieldOptions = $styleobject->getOptions(); $fieldAfter = $styleobject->getAfter(); $fieldType = $styleobject->getType(); + $fieldGroup = $styleobject->getGroup(); if(!empty($fieldStyles) || !empty($fieldOptions)){ // fix this using objects? $fieldValue = (array_key_exists($index, $arr_extrastyle_styleobjects)) ? $arr_extrastyle_styleobjects[$index]->getSelected() : null; @@ -157,13 +162,34 @@ public function updateCMSFields(FieldList $fields) { $fields->insertAfter(Tab::create($tabName), 'Settings'); } } - if($fieldAfter && $fields->dataFieldByName($fieldAfter)){ - $fields->insertAfter($styleFormField,$fieldAfter); + + if($fieldGroup){ + if (!array_key_exists($fieldGroup,$arrFieldGoups)){ + $arrFieldGoups[$fieldGroup] = FieldGroup::create($fieldGroup ) + ->setTitle(ucwords(FormField::name_to_label($fieldGroup))) + ->addExtraClass('es-fieldgroup'); + if($styleobject->getDescription()){ + $arrFieldGoups[$fieldGroup]->setRightTitle($styleobject->getDescription()); + } + if($fieldAfter && $fields->dataFieldByName($fieldAfter)){ + $fields->insertAfter($arrFieldGoups[$fieldGroup],$fieldAfter); + } else { + $fields->addFieldToTab( + 'Root.'. $tabName, + $arrFieldGoups[$fieldGroup] + ); + } + } + $arrFieldGoups[$fieldGroup]->push($styleFormField); } else { - $fields->addFieldToTab( - 'Root.'. $tabName, - $styleFormField - ); + if($fieldAfter && $fields->dataFieldByName($fieldAfter)){ + $fields->insertAfter($styleFormField,$fieldAfter); + } else { + $fields->addFieldToTab( + 'Root.'. $tabName, + $styleFormField + ); + } } } } @@ -172,15 +198,14 @@ public function updateCMSFields(FieldList $fields) { 'Root.' . $default_tab_name, [ HiddenField::create('ExtraStyle','ExtraStyle'), - TextField::create('ExtraStyleOutput','Extra Style', $this->getOwner()->ExtraStyle)->setReadonly(true) + TextField::create('ExtraStyleOutput','Extra Style', $this->getOwner()->ExtraStyle)->setReadonly(true), ] ); } } - - + public function getFrontEndFormFields() { @@ -211,6 +236,7 @@ public function getFrontEndFormFields() { $fieldOptions = $styleobject->getOptions(); $fieldAfter = $styleobject->getAfter(); $fieldType = $styleobject->getType(); + $fieldGroup = $styleobject->getGroup(); if(!empty($fieldStyles) || !empty($fieldOptions)){ // fix this using objects? $fieldValue = (array_key_exists($index, $arr_extrastyle_styleobjects)) ? $arr_extrastyle_styleobjects[$index]->getSelected() : null; @@ -233,7 +259,7 @@ public function getFrontEndFormFields() { if($styleobject->getDescription()){ $styleFormField->setDescription($styleobject->getDescription()); } - } elseif($fieldType=='multiselect'){ + } elseif( ($fieldType=='multiselect') || ($fieldType=='checkboxset') ){ $styleFormField = ListboxField::create($fieldName, $fieldTitle, array_flip($fieldStyles), $fieldValue); $styleFormField->setRightTitle($styleobject->getDescription()); if($disable_chosen){ @@ -294,6 +320,8 @@ public function getFrontEndFormFields() { $fields->push( HiddenField::create($fieldNamePrefix.'ExtraStyleOutput','Extra Style', $this->getOwner()->ExtraStyle)->setReadonly(true) ); + + } return $fields; @@ -356,6 +384,35 @@ public function updateConfigStyles($config_styles) { return $config_styles; } + + protected function updateResponsiveStyles($config_styles){ + if( is_array($config_styles) ) { + foreach($config_styles as $key => $value){ + $orginal_style = $config_styles[$key]; + $original_index = $key; + if( is_array($orginal_style) && array_key_exists('Responsive',$orginal_style) ) { + $responsive_styles = []; + $position = array_search($key, array_keys($config_styles)); + unset($config_styles[$key]['Responsive']); + $style = $config_styles[$key]; +// Debug::show($original_index); + if( is_array($arr_responsive = $orginal_style['Responsive']) ){ + foreach($arr_responsive as $vp_key => $vp_value){ + $vp_index = $original_index . $vp_key; + $responsive_styles[$vp_index] = array_merge($style,$vp_value); + $responsive_styles[$vp_index]['Group'] = $original_index; + $responsive_styles[$vp_index]['Title'] = array_key_exists('Title', $vp_value) ? $vp_value['Title'] : $style['Title'] . ' ' . $vp_key; + } + } + // remove original item and insert new reponsive items + $result = array_slice($config_styles, 0, $position - 1) + $responsive_styles + array_slice($config_styles, $position + 1); + $config_styles = $result; + + } + } + } + return $config_styles; + } /** * Get all styles from config @@ -367,7 +424,9 @@ protected function getConfigStyles() $config_styles = $this->getOwner()->config()->get('extra_styles'); $config_styles = $this->getOwner()->updateConfigStyles($config_styles); - + // loop through styles find responsive auto add extra styles as type group + $config_styles = $this->updateResponsiveStyles($config_styles); + return $config_styles; } @@ -380,11 +439,13 @@ protected function getConfigStyleObjects() { $config_styles = $this->getConfigStyles(); return self::array_to_styleobjects($config_styles); + + } /** - * Get all styles from config as array of StyleObject::class + * Get all styles from ExtraStyle datafield as array of StyleObject::class * * @return array */ diff --git a/src/Model/StyleObject.php b/src/Model/StyleObject.php index 1a76fce..934fc20 100644 --- a/src/Model/StyleObject.php +++ b/src/Model/StyleObject.php @@ -37,6 +37,7 @@ class StyleObject implements \JsonSerializable { protected $prefix; protected $suffix; protected $default; + protected $group; private static $arr_default = [ @@ -51,6 +52,7 @@ class StyleObject implements \JsonSerializable { 'Prefix' => null, 'Suffix' => null, 'Default' => null, // this gets applied when nothing is selected + 'Group' => null, ]; private static $arr_default_options = [ @@ -60,7 +62,7 @@ class StyleObject implements \JsonSerializable { 'Max' => null, 'Unit' => null, 'Step' => null, - 'ImageSize' => null, + 'ImageSize' => null ]; public function __construct(String $index, Array $arr_object = []) @@ -81,6 +83,7 @@ public function __construct(String $index, Array $arr_object = []) $this->prefix = $arr_style['Prefix']; $this->suffix = $arr_style['Suffix']; $this->default = $arr_style['Default']; + $this->group = $arr_style['Group']; } public function jsonSerialize() @@ -160,6 +163,9 @@ public function getType(){ public function getDefault(){ return $this->default; } + public function getGroup(){ + return $this->group; + } // return selected value public function getSelected(){