Implemented direct selection for categories
authorAlexander Ebert <ebert@woltlab.com>
Fri, 23 Jun 2017 11:44:30 +0000 (13:44 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 23 Jun 2017 11:44:30 +0000 (13:44 +0200)
See #2314

wcfsetup/install/files/acp/style/acpStyleEditor.css
wcfsetup/install/files/acp/templates/styleAdd.tpl
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/Editor.js
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 4098a9030477507bb7be04596427038444f03dc6..139016ee815d66e6acbec03ef62040c6a82c59b0 100644 (file)
@@ -5,6 +5,7 @@ html[dir="ltr"] #spWindow { margin-right: 40px; }
 html[dir="rtl"] #spWindow { margin-left: 40px; }
 #spSidebar { flex: 0 0 300px; }
 .spBoundary { margin: 0 40px; }
+.spInlineWrapper { display: inline-block; }
 
 /* ### header ### */
 #spHeader > .spBoundary { display: flex; flex-wrap: wrap; padding: 30px 0; }
@@ -98,10 +99,10 @@ html[dir="rtl"] .spColorBox { margin-left: 10px !important; }
 .spVariable, .spDescription { display: block; font-size: 12px; }
 .spVariable { font-family: Consolas, Courier, monospace; }
 @media (min-width: 769px) {
-       .spSidebarBox.pointer { position: relative; }
-       .spSidebarBox.pointer::before { border: 10px solid transparent;  content: ""; display: block; position: absolute; }
-       html[dir="ltr"] .spSidebarBox.pointer::before { border-right-color: rgb(217, 237, 247); left: -20px; }
-       html[dir="rtl"] .spSidebarBox.pointer::before { border-left-color: rgb(217, 237, 247); right: -20px; }
+       #spVariablesWrapper { position: sticky; top: 60px; }
+        #spSidebar .button { display: block; }
+        #spSidebar .jsButtonSelectCategoryByClick { margin-bottom: 5px; }
+        #spSidebar .jsButtonToggleColorPalette { margin-bottom: 10px; }
 }
 
 /* ### style region marker ### */
@@ -112,3 +113,49 @@ html[dir="rtl"] .spColorBox { margin-left: 10px !important; }
 #stylePreviewRegionMarker::before { border-width: 0 3px 3px 0; left: -20px; top: -20px; }
 #stylePreviewRegionMarkerBottom::after { border-width: 3px 0 0 3px; right: -20px; bottom: -20px; }
 #stylePreviewRegionMarkerBottom::before { border-width: 3px 3px 0 0; left: -20px; bottom: -20px; }
+
+/* ### click on area to select ### */
+#spWindow.spShowRegions { pointer-events: none; z-index: 5; }
+#spWindow.spShowRegions [data-region]:not(#spSubMenu) { position: relative; }
+#spWindow.spShowRegions [data-region]::before {
+       background-color: rgba(242, 222, 222, .9);
+       border: 2px dashed rgb(235, 204, 204);
+       bottom: 0;
+       content: "";
+       cursor: pointer;
+       display: block;
+       left: 0;
+       pointer-events: all;
+       position: absolute;
+       right: 0;
+       top: 0;
+       transition: background-color .12s linear;
+       z-index: 10;
+}
+
+#spWindow.spShowRegions [data-region]:hover::before {
+       background-color: rgba(242, 222, 222, 1);
+}
+
+#spWindow.spShowRegions [data-region]::after {
+       color: rgb(169, 68, 66);
+       content: attr(data-region);
+       font-size: 12px !important;
+       font-weight: 400 !important;
+       left: 50%;
+       position: absolute;
+       top: 50%;
+       transform: translateX(-50%) translateY(-50%);
+       z-index: 40;
+}
+
+#spWindow.spShowRegions [data-region] [data-region] {
+       z-index: 20;
+}
+
+#spWindow.spShowRegions [data-region] [data-region]::before {
+       z-index: 30;
+}
+
+#spWindow.spShowRegions + #spSidebar .jsButtonToggleColorPalette { pointer-events: none; }
+#spWindow.spShowRegions + #spSidebar .spSidebarBox:not(#spSidebarButtons) > ul { opacity: .6; pointer-events: none; }
index bad4b98dfe1f79ba426e2be4e8fc5de8d3b69418..bd99a07b60e3efd10266397a1b22cad48f4be709 100644 (file)
                                                <div id="spHeader" data-region="wcfHeader">
                                                        <div class="spBoundary">
                                                                <div id="spLogo"><img src="{@$__wcf->getPath()}acp/images/woltlabSuite.png"></div>
-                                                               <div id="spSearch"><input type="search" id="spSearchBox" placeholder="{lang}wcf.global.search.enterSearchTerm{/lang}" autocomplete="off" data-region="wcfHeaderSearchBox"></div>
+                                                               <div id="spSearch"><div class="spInlineWrapper" data-region="wcfHeaderSearchBox"><input type="search" id="spSearchBox" placeholder="{lang}wcf.global.search.enterSearchTerm{/lang}" autocomplete="off"></div></div>
                                                        </div>
                                                </div>
                                                
                                                                        
                                                                        <div class="spHeadline">Button</div>
                                                                        
-                                                                       <ol id="spButton" class="inlineList" data-region="wcfButton">
-                                                                               <li><a class="button">Button</a></li>
-                                                                               <li><a class="button active">Button (Active)</a></li>
-                                                                               <li><a class="button disabled" data-region="wcfButtonDisabled">Button (Disabled)</a></li>
-                                                                       </ol>
+                                                                       <div id="spButton">
+                                                                               <div class="spInlineWrapper" data-region="wcfButton">
+                                                                                       <ol class="inlineList">
+                                                                                               <li><a class="button">Button</a></li>
+                                                                                               <li><a class="button active">Button (Active)</a></li>
+                                                                                       </ol>
+                                                                               </div>
+                                                                               <div class="spInlineWrapper" data-region="wcfButtonDisabled">
+                                                                                       <ol class="inlineList">
+                                                                                               <li><a class="button disabled">Button (Disabled)</a></li>
+                                                                                       </ol>
+                                                                               </div>
+                                                                       </div>
                                                                        
-                                                                       <ol id="spButtonPrimary" class="inlineList" data-region="wcfButtonPrimary">
-                                                                               <li><a class="button buttonPrimary">Primary Button</a></li>
-                                                                               <li><a class="button buttonPrimary active">Primary Button (Active)</a></li>
-                                                                               <li><a class="button disabled">Primary Button (Disabled)</a></li>
-                                                                       </ol>
+                                                                       <div id="spButtonPrimary">
+                                                                               <div class="spInlineWrapper" data-region="wcfButtonPrimary">
+                                                                                       <ol class="inlineList">
+                                                                                               <li><a class="button buttonPrimary">Primary Button</a></li>
+                                                                                               <li><a class="button buttonPrimary active">Primary Button (Active)</a></li>
+                                                                                               <li><a class="button disabled">Primary Button (Disabled)</a></li>
+                                                                                       </ol>
+                                                                               </div>
+                                                                       </div>
                                                                        
                                                                        <div class="spHeadline">Dropdown</div>
                                                                        
                                        </div>
                                        <div id="spSidebar">
                                                <div id="spVariablesWrapper">
+                                                       <div id="spSidebarButtons">
+                                                               <ul>
+                                                                       <li><a href="#" class="button jsButtonSelectCategoryByClick">{lang}wcf.acp.style.colors.selectCategoryByClick{/lang}</a></li>
+                                                                       <li><a href="#" class="button jsButtonToggleColorPalette">{lang}wcf.acp.style.colors.toggleColorPalette{/lang}</a></li>
+                                                               </ul>
+                                                       </div>
                                                        <div class="spSidebarBox">
                                                                <select id="spCategories">
                                                                        <option value="none" selected>{lang}wcf.global.noSelection{/lang}</option>
index 1e1a2cdef63cfb917b5add2fbbdfbdcbc8bc4b0f..7b94c217edf2cb068294ee40027f0a2d5957a089 100644 (file)
@@ -46,7 +46,7 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Ui/Screen'],
                        window.addEventListener('resize', callbackRegionMarker);
                        EventHandler.add('com.woltlab.wcf.AcpMenu', 'resize', callbackRegionMarker);
                        EventHandler.add('com.woltlab.wcf.simpleTabMenu_styleTabMenuContainer', 'select', function (data) {
-                               _isVisible = (data.activeName == 'colors');
+                               _isVisible = (data.activeName === 'colors');
                                callbackRegionMarker();
                        });
                },
@@ -146,8 +146,6 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Ui/Screen'],
                                
                                if (lastValue === 'none') {
                                        elHide(_stylePreviewRegionMarker);
-                                       updateWrapperPosition(null);
-                                       scrollToRegion(null);
                                        return;
                                }
                                
@@ -165,54 +163,26 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Ui/Screen'],
                                
                                elShow(_stylePreviewRegionMarker);
                                
-                               updateWrapperPosition(region);
-                               scrollToRegion(top);
-                       };
-                       
-                       var variablesWrapper = elById('spVariablesWrapper');
-                       function updateWrapperPosition(region) {
-                               var fromTop = 0;
-                               if (region !== null) {
-                                       fromTop = (region.offsetTop - variablesWrapper.offsetTop) - 10;
-                                       
-                                       var styles = window.getComputedStyle(region);
-                                       if (styles.getPropertyValue('position') === 'absolute' || styles.getPropertyValue('position') === 'relative') {
-                                               fromTop += region.offsetParent.offsetTop;
-                                       }
-                               }
-                               
-                               if (fromTop <= 0) {
-                                       variablesWrapper.style.removeProperty('transform');
+                               top = DomUtil.offset(region).top;
+                               // `+ 80` = account for sticky header + selection markers (20px)
+                               var firstVisiblePixel = (window.pageYOffset || window.scrollY) + 80;
+                               if (firstVisiblePixel > top) {
+                                       window.scrollTo(0, Math.max(top - 80, 0));
                                }
                                else {
-                                       // ensure that the wrapper does not exceed the bottom boundary
-                                       var maxHeight = variablesWrapper.parentNode.clientHeight;
-                                       var wrapperHeight = variablesWrapper.clientHeight;
-                                       if (wrapperHeight + fromTop > maxHeight) {
-                                               fromTop = maxHeight - wrapperHeight;
+                                       var lastVisiblePixel = window.innerHeight + (window.pageYOffset || window.scrollY);
+                                       if (lastVisiblePixel < top) {
+                                               window.scrollTo(0, top);
+                                       }
+                                       else {
+                                               var bottom = top + region.offsetHeight + 20;
+                                               if (lastVisiblePixel < bottom) {
+                                                       window.scrollBy(0, bottom - top);
+                                               }
                                        }
-                                       
-                                       variablesWrapper.style.setProperty('transform', 'translateY(' + fromTop + 'px)', '');
-                               }
-                       }
-                       
-                       var pageHeader = elById('pageHeader');
-                       function scrollToRegion(top) {
-                               if (top === null) {
-                                       top = variablesWrapper.offsetTop - 60;
-                               }
-                               else {
-                                       // use the region marker as an offset
-                                       top -= 60;
                                }
-                               
-                               // account for sticky header
-                               top -= 60;
-                               
-                               window.scrollTo(0, top);
-                       }
+                       };
                        
-                       var selectContainer = elBySel('.spSidebarBox:first-child');
                        var element;
                        select.addEventListener('change', function() {
                                element = elBySel('.spSidebarBox[data-category="' + lastValue + '"]', container);
@@ -224,11 +194,8 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Ui/Screen'],
                                
                                // set region marker
                                _updateRegionMarker();
-                               
-                               selectContainer.classList[(lastValue === 'none' ? 'remove' : 'add')]('pointer');
                        });
                        
-                       
                        // apply CSS rules
                        var style = elCreate('style');
                        style.appendChild(document.createTextNode(''));
@@ -266,7 +233,7 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Ui/Screen'],
                                }
                        }
                        
-                       var elements = elByClass('styleVariableColor', variablesWrapper);
+                       var elements = elByClass('styleVariableColor', elById('spVariablesWrapper'));
                        [].forEach.call(elements, function(colorField) {
                                var variableName = elData(colorField, 'store').replace(/_value$/, '');
                                
@@ -284,6 +251,38 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Ui/Screen'],
                                
                                updateCSSRule(variableName, colorField.style.getPropertyValue('background-color'));
                        });
+                       
+                       // category selection by clicking on the area
+                       var buttonToggleColorPalette = elBySel('.jsButtonToggleColorPalette');
+                       var buttonSelectCategoryByClick = elBySel('.jsButtonSelectCategoryByClick');
+                       var toggleSelectionMode = function() {
+                               buttonSelectCategoryByClick.classList.toggle('active');
+                               buttonToggleColorPalette.classList.toggle('disabled');
+                               _stylePreviewWindow.classList.toggle('spShowRegions');
+                               select.disabled = !select.disabled;
+                       };
+                       
+                       buttonSelectCategoryByClick.addEventListener(WCF_CLICK_EVENT, function (event) {
+                               event.preventDefault();
+                               
+                               toggleSelectionMode();
+                       });
+                       
+                       elBySelAll('[data-region]', _stylePreviewWindow, function (region) {
+                               region.addEventListener(WCF_CLICK_EVENT, function (event) {
+                                       if (!_stylePreviewWindow.classList.contains('spShowRegions')) {
+                                               return;
+                                       }
+                                       
+                                       event.preventDefault();
+                                       event.stopPropagation();
+                                       
+                                       toggleSelectionMode();
+                                       
+                                       select.value = elData(region, 'region');
+                                       Core.triggerEvent(select, 'change');
+                               });
+                       });
                },
                
                hideVisualEditor: function() {
index e31fc430cdb56e42960b92ffe247d10f5c9f7455..b4c056fd3f7c650bff4aa8dba102fc18f677fd3f 100644 (file)
@@ -1777,7 +1777,9 @@ GmbH=Gesellschaft mit beschränkter Haftung]]></item>
                <item name="wcf.acp.style.colors.primaryBackgroundColor"><![CDATA[Hintergrundfarbe (primär)]]></item>
                <item name="wcf.acp.style.colors.primaryBorderColor"><![CDATA[Rahmenfarbe (primär)]]></item>
                <item name="wcf.acp.style.colors.primaryColor"><![CDATA[Schriftfarbe (primär)]]></item>
+               <item name="wcf.acp.style.colors.selectCategoryByClick"><![CDATA[Kategorie-Direktauswahl]]></item>
                <item name="wcf.acp.style.colors.tabular"><![CDATA[Tabellarische Auflistungen]]></item>
+               <item name="wcf.acp.style.colors.toggleColorPalette"><![CDATA[Ansicht umschalten]]></item>
                <item name="wcf.acp.style.colors.userPanel"><![CDATA[Benutzerleiste]]></item>
                <item name="wcf.acp.style.copyright"><![CDATA[Copyright]]></item>
                <item name="wcf.acp.style.copyStyle"><![CDATA[Stil kopieren]]></item>
index af4250ea7bf8d0e493707de2d5e1e80416010d4d..845a06d6064fa5728ea55522e767dbfeef5ef5cd 100644 (file)
                <item name="wcf.acp.style.colors.primaryBackgroundColor"><![CDATA[Background Color (primary)]]></item>
                <item name="wcf.acp.style.colors.primaryBorderColor"><![CDATA[Border Color (primary)]]></item>
                <item name="wcf.acp.style.colors.primaryColor"><![CDATA[Font Color (primary)]]></item>
+               <item name="wcf.acp.style.colors.selectCategoryByClick"><![CDATA[Category Direct Selection]]></item>
                <item name="wcf.acp.style.colors.tabular"><![CDATA[Tabular Lists]]></item>
+               <item name="wcf.acp.style.colors.toggleColorPalette"><![CDATA[Toggle View]]></item>
                <item name="wcf.acp.style.colors.userPanel"><![CDATA[User Panel]]></item>
                <item name="wcf.acp.style.copyright"><![CDATA[Copyright]]></item>
                <item name="wcf.acp.style.copyStyle"><![CDATA[Duplicate Style]]></item>