Commit cca46ba3 authored by colemanw's avatar colemanw

Merge branch 'shoreditch' into 'master'

Upgrade Shoreditch ext

See merge request marketing/civicrm-website!2
parents 011016c5 31d63aa4
......@@ -13,24 +13,40 @@
If you are doing development on this extension, then you may need to build
new CSS files. This requires the toolchain for SCSS=>CSS compilation.
First of all you need [NodeJS](https://nodejs.org/). Please be aware that currently Shoreditch *does not* support NodeJS v6 or higher! It is recommended that you install NodeJS **v5.12.0** (you can use [nvm](https://github.com/creationix/nvm) for managing multiple node versions on the same machine.
First of all you need [NodeJS](https://nodejs.org/). Please be aware that currently Shoreditch *does not* support NodeJS v9 or higher! It is recommended that you install NodeJS LTS version **v8.9.4** (you can use [nvm](https://github.com/creationix/nvm) for managing multiple node versions on the same machine.
Once you have NodeJS installed, run
```
npm install -g gulp
```sh
npm install
```
Once you have the tools, you can run `gulp`. This will monitor the SCSS files and automatically recompile whenever they change.
Once you have the tools, you can run `npx gulp watch`. This will monitor the SCSS files and automatically recompile whenever they are changed.
```sh
# npx command ensures you run a local repository Gulp and not the global one
npx gulp watch
```
gulp
If you would like to just compile files without watching, simply run `npx gulp`.
```sh
npx gulp
```
## Guidelines for `custom-civicrm.css`
Any style changes that are aimed at making the core screens look like they are part of the Bootstrap theme, should go here.
### Disable stylelint rules
Any .scss file under the `civicrm/` folder must have this annotation at the very top
```scss
/* stylelint-disable max-nesting-depth, selector-max-compound-selectors, selector-no-qualifying-type, selector-max-id */
```
in order to tell [stylelint](https://stylelint.io/) to be more a bit more lax when enforcing style conventions
*TBD*
## Guidelines for `bootstrap.css`
......
......@@ -23,7 +23,7 @@ If you'd like to contribute to the project, please make sure to familiarize with
* Reference any issues or pull requests that you think is useful to mention
### Submitting a PR
When your work is complete and you have tested it locally, you can open a PR against the `develop` branch.
When your work is complete and you have tested it locally, you can open a PR against the `master` branch.
In the PR give a description of what you changed (and why!), and attach before & after screenshots to show the effects of your changes.
......
# org.civicrm.shoreditch (developmental)
The "Shoreditch" extension is a theme for CiviCRM based on a contemporary [flat design](https://en.wikipedia.org/wiki/Flat_design) and
[Bootstrap(S)CSS](http://getbootstrap.com/css/). It includes two major components:
the [Bootstrap v3](https://getbootstrap.com/docs/3.3/) framework.
Please note that this extension is currrently in **alpha stage** and under **active development**. Significant elements may change.
## Supported CMSs
At the moment the theme is being developed to work only in Drupal (with default theme set to "Seven"). WordPress and Joomla are not currently supported.
## Components
The theme includes two major components:
* "`bootstrap.css`" is a build of Bootstrap based on the standard Bootstrap style-guide. It can be used with other CiviCRM extensions which satisfy the Bootstrap style-guide.
* "`custom-civicrm.css`" is an optional replacement for "civicrm.css". It uses the same visual conventions and SCSS metadata, but it applies to existing core screens.
> This extension is under **active development**. Significant elements may change.
### Using `bootstrap.css`
This extension provides the CSS for Bootstrap. Other extensions should output compliant HTML, e.g.
......
/**
* Resets css rules that are applied by the CiviCRM style
*
* (`initial` was used at first, but there is no support by IE for it)
* Resets css rules that are applied by the original CiviCRM style
* and the "legacy mode" of Shoreditch
*/
h3 {
@include initial(background-color, transparent);
@include initial(border, 0);
@include initial(border-radius, 0);
@include initial(box-shadow, none);
@include initial(font-family, $font-family-base);
@include initial(padding, 0);
@include initial(margin, 0);
font-size: $font-size-h3;
font-weight: 400;
font-size: $font-size-h3;
}
table {
......@@ -52,6 +54,12 @@ table {
}
.crm-button .crm-i {
left: .6em;
top: .6em;
left: 0.6em;
top: 0.6em;
}
label .crm-error-label {
@include initial(padding, 0);
font-size: $font-size-base;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
var gulp = require('gulp');
var bulk = require('gulp-sass-bulk-import');
var bulk = require('gulp-sass-glob');
var sass = require('gulp-sass');
var postcss = require('gulp-postcss');
var postcssPrefix = require('postcss-prefix-selector');
......@@ -9,8 +9,11 @@ var transformSelectors = require('gulp-transform-selectors');
var civicrmScssRoot = require('civicrm-scssroot')();
var bootstrapNamespace = '#bootstrap-theme';
var outsideNamespaceRegExp = /^\.___outside-namespace/;
gulp.task('sass:bootstrap', ['sass:sync'], function () {
gulp.task('sass:sync', civicrmScssRoot.update);
gulp.task('sass:bootstrap', gulp.series('sass:sync', function buildBootstrapCSS () {
return gulp.src('scss/bootstrap/bootstrap.scss')
.pipe(bulk())
.pipe(sass({
......@@ -21,13 +24,14 @@ gulp.task('sass:bootstrap', ['sass:sync'], function () {
.pipe(stripCssComments({ preserve: false }))
.pipe(postcss([postcssPrefix({
prefix: bootstrapNamespace + ' ',
exclude: [/^html/, /^body/, /\.ta-hidden-input/, /\.mobile/]
exclude: [/^html/, /^body/, /\.ta-hidden-input/, outsideNamespaceRegExp]
})]))
.pipe(transformSelectors(namespaceRootElements, { splitOnCommas: true }))
.pipe(transformSelectors(removeOutsideNamespaceMarker, { splitOnCommas: true }))
.pipe(gulp.dest('css/'));
});
}));
gulp.task('sass:civicrm', ['sass:sync'], function () {
gulp.task('sass:civicrm', gulp.series('sass:sync', function buildCiviCRMCSS () {
return gulp.src('scss/civicrm/custom-civicrm.scss')
.pipe(bulk())
.pipe(sass({
......@@ -39,22 +43,20 @@ gulp.task('sass:civicrm', ['sass:sync'], function () {
.pipe(postcss([postcssPrefix({
prefix: '.crm-container ',
exclude: [/^body/, /tooltip/, /page-civicrm/, /crm-container/,
/civicrm-menu/, /#root-menu-div/]
/ui-datepicker/, /civicrm-menu/, /#root-menu-div/, /jstree-contextmenu/,
outsideNamespaceRegExp]
}), postcssDiscardDuplicates]))
.pipe(transformSelectors(removeOutsideNamespaceMarker, { splitOnCommas: true }))
.pipe(gulp.dest('css/'));
});
gulp.task('sass:sync', function () {
civicrmScssRoot.updateSync();
});
}));
gulp.task('sass', ['sass:bootstrap', 'sass:civicrm']);
gulp.task('sass', gulp.parallel('sass:bootstrap', 'sass:civicrm'));
gulp.task('watch', function () {
gulp.watch(civicrmScssRoot.getWatchList(), ['sass']);
gulp.watch(civicrmScssRoot.getWatchList(), gulp.parallel('sass'));
});
gulp.task('default', ['sass']);
gulp.task('default', gulp.parallel('sass'));
/**
* Apply the namespace on html and body elements
......@@ -73,3 +75,14 @@ function namespaceRootElements (selector) {
return selector;
}
/**
* Deletes the special class that was used as marker for styles that should
* not be nested inside the bootstrap namespace from the given selector
*
* @param {String} selector
* @return {String}
*/
function removeOutsideNamespaceMarker (selector) {
return selector.replace(outsideNamespaceRegExp, '');
}
......@@ -14,8 +14,8 @@
<url desc="Support">http://civicrm.stackexchange.com/</url>
<url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
</urls>
<releaseDate>2017-11-27</releaseDate>
<version>0.1-alpha14</version>
<releaseDate>2018-08-20</releaseDate>
<version>0.1-alpha24</version>
<compatibility>
<ver>4.7</ver>
</compatibility>
......
(function ($) {
$(document).ready(function () {
moveUserPictureNextToContactTitle();
});
/**
* Moves the user image to the left of the contact name
*/
function moveUserPictureNextToContactTitle () {
$('.crm-summary-contactname-block').prepend($('#crm-contact-thumbnail'));
}
}(CRM.$));
......@@ -4,6 +4,19 @@
(function ($, _) {
// [ML] removed menu hack
/**
* Substitutes main menu arrow image with FontAwesome caret icon
*/
function substituteMenuArrows() {
$('#root-menu-div .menu-item-arrow').each(function ($element) {
var $arrow = $(this);
$arrow.before('<i class="fa fa-caret-right menu-item-arrow"></i>');
$arrow.remove();
});
}
$(document).ready(function () {
substituteMenuArrows();
});
}(CRM.$, CRM._));
/* globals MutationObserver, CRM */
CRM.$(function () {
'use strict';
/**
* The purpose of this script is to activate the "select2" dropdowns on standard select elements.
* When the "select2" is enabled, its corresponding select is hidden, so we're
* only targeting the visible ones.
* Because some select elements are dinamically loaded via AJAX,
* we're using the "MutationObserver" to listen to DOM changes
*/
/**
* We're debouncing the callback to avoid calling the plugin multiple times
* during DOM changes
*/
var observer = new MutationObserver(debounce(function () {
CRM.$('select:visible:not(.no-select2):not(.crm-form-multiselect)')
.each(function () {
var select = CRM.$(this);
var hasNoSelect2Parent = select.closest('.no-select2').length;
/**
* The parent selector does not work on the previous query. This query
* `:not(.no-select2) select`
* will still transform the select inputs into select2 components.
* By adding the condition inside a .each we fix this issue.
*/
if (hasNoSelect2Parent) {
return;
}
select.select2({ containerCss: { display: 'inline-block' } })
.on('change', clearSelect2);
});
}, 50));
observer.observe(document.querySelector('body'), {
childList: true,
subtree: true
});
function debounce (fn, delay) {
var timer = null;
return function () {
var me = this;
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(me, args);
}, delay);
};
}
/**
* Walk through all select fields and hide it
* if there isn't any option
*/
function clearSelect2 () {
window.setTimeout(function () {
CRM.$('select').each(function (idx, item) {
var id = '#s2id_' + CRM.$(item).attr('id');
var optionsLength = CRM.$(item).find('option').length;
if (optionsLength === 0) {
CRM.$(id).remove();
}
});
}, 50);
}
});
(function ($, _) {
(function ($, _, ts) {
$(document).ready(function () {
amendMarkupOfMenuItemsWithFontAwesomeIcons();
customizeQuickSearchField();
......@@ -20,7 +20,7 @@
* Changes the placeholder text of the quicksearch field
*/
function changeQuickSearchFieldPlaceholder () {
$('#crm-qsearch .ui-autocomplete-input').attr('placeholder', 'Quick Search');
$('#crm-qsearch .ui-autocomplete-input').attr('placeholder', ts('Quick Search'));
}
/**
......@@ -63,7 +63,9 @@
* @return {boolean}
*/
function isQuickSearchOnGoing () {
return !!$('#sort_name_navigation').val().trim();
var searchValue = $('#sort_name_navigation').val() || '';
return !!searchValue.trim();
}
/**
......@@ -127,13 +129,16 @@
}
/**
* Creates an HTML element out of the text node of the given menu item
* Creates an HTML element out of the text node next to the icon (an element
* with either the .crm-i or the .fa class) of the given menu item
*
* @param {object} $menuItem
*/
function wrapMenuItemLabelInHTML ($menuItem) {
$menuItem.contents().filter(function () {
return this.nodeType === 3 && $(this).parent().is($menuItem);
}).wrap('<span class="menumain-label" />')
var itemLabel = $('.crm-i, .fa', $menuItem)[0].nextSibling;
if (itemLabel.nodeType === Node.TEXT_NODE) {
$(itemLabel).wrap('<span class="menumain-label" />');
}
}
}(CRM.$, CRM._));
}(CRM.$, CRM._, CRM.ts('org.civicrm.shoreditch')));
CRM.$(function() {
'use strict';
/**
* We're debouncing the callback to avoid calling multiple times during DOM changes
*/
var observer = new MutationObserver(debounce(function() {
/**
* The customized radio buttons / checkboxes depend on the existence of the
* "for" attribute in the respective labels.
* This is a workaround to add any missing "for" attributes to the markup.
* @see: org.civicrm.shoreditch/scss/civicrm/common/_radio-checkbox.scss
*/
CRM.$('.crm-container input[type=checkbox], .crm-container input[type=radio]').each(function() {
var $this = CRM.$(this);
var label = $this.next('label');
if (!$this.attr('id')) {
// There's no id. Add a unique random value as the id
$this.attr('id', new Date().valueOf());
}
if (!label.length) {
// There's no sibling label. Let's just show the checkbox / radio button, in order to avoid feature loss
$this.show();
} else if (!label.attr('for')) {
// Add the "for" attribute on the sibling label, matching the input's id
label.attr('for', $this.attr('id'));
}
});
}, 500));
observer.observe(document.querySelector('body'), {
childList: true,
subtree: true
});
function debounce(fn, delay) {
var timer = null;
return function() {
var me = this;
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(me, args);
}, delay);
};
}
});
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "org.civicrm.shoreditch",
"version": "1.0.0",
"description": "A CiviCRM theme based on Bootstrap",
"main": "index.js",
"license": "AGPL-3.0",
"repository": {
"type": "git",
"url": "https://github.com/civicrm/org.civicrm.shoreditch"
},
"bugs": {
"url": "https://github.com/civicrm/org.civicrm.shoreditch/issues"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"precommit": "lint-staged"
},
"lint-staged": {
"*.js": [
"semistandard --fix",
"git add"
],
"*.scss": [
"stylelint --fix",
"git add"
]
},
"semistandard": {
"globals": [
"CRM",
"jQuery"
]
},
"stylelint": {
"extends": "stylelint-config-sass-guidelines",
"plugins": [
"stylelint-order",
"stylelint-scss"
],
"rules": {
"selector-class-pattern": null,
"max-nesting-depth": 3,
"no-extra-semicolons": true,
"no-duplicate-selectors": true,
"scss/dollar-variable-colon-space-after": "at-least-one-space"
}
},
"author": "",
"license": "ISC",
"devDependencies": {
"civicrm-scssroot": "git://github.com/totten/civicrm-scssroot.git#v0.1.1",
"gulp": "^3.9.0",
"gulp-postcss": "~6.1.1",
"node-sass": "3.4.2",
"gulp-sass": "^2.1.0",
"gulp-sass-bulk-import": "^0.3.2",
"gulp-strip-css-comments": "^1.2.0",
"gulp": "^4.0.0",
"gulp-postcss": "^7.0.1",
"gulp-sass": "^4.0.1",
"gulp-sass-glob": "^1.0.9",
"gulp-strip-css-comments": "^2.0.0",
"gulp-transform-selectors": "0.0.2",
"postcss-discard-duplicates": "~2.0.1",
"postcss-prefix-selector": "~1.4.0"
"husky": "^0.14.3",
"lint-staged": "^6.1.1",
"postcss-discard-duplicates": "^2.1.0",
"postcss-prefix-selector": "^1.6.0",
"semistandard": "^12.0.1",
"stylelint": "^8.4.0",
"stylelint-config-sass-guidelines": "^4.2.0",
"stylelint-order": "^0.8.1",
"stylelint-scss": "^2.5.0"
}
}
[text-angular] {
$crm-text-angular-min-height: 120px;
border: 1px solid $gray-light;
padding: 0;
.ta-editor {
border: 0 !important;
}
.form-control {
border: 0;
box-shadow: none !important;
min-height: $crm-text-angular-min-height;
&.ta-scroll-window {
height: auto;
> .ta-bind {
min-height: $crm-text-angular-min-height;
outline: 0;
}
}
}
}
[text-angular-toolbar] {
background-color: #f4f7f8;
border: 0;
margin-left: 0;
padding: 10px;
.btn {
background: transparent !important;
border: 0;
box-shadow: none;
color: $crm-copy;
padding-left: $padding-small-horizontal;
padding-right: $padding-small-horizontal;
&.active {
color: $gray-darker !important;
}
&:hover:not(:disabled) {
color: $gray-dark;
}
.fa {
font-size: $font-size-small;
font-weight: 700;
}
}
}
.ui-select-bootstrap[theme="civihr-ui-select"] {
.ui-select-bootstrap[theme='civihr-ui-select'] {
+ .input-group-btn {
.btn {
@include border-left-radius(0);
margin-left: -1px;
......@@ -10,9 +8,9 @@
&.ui-select-multiple {
min-height: $input-height-base;
padding: 2px 2px 0 2px;
padding: 2px 2px 0;
input.ui-select-search {
.ui-select-search {
height: 1.9em;
text-indent: 10px;
}
......@@ -57,9 +55,8 @@
}
}
.ui-select-container:not([theme="civihr-ui-select"]) {
.ui-select-container:not([theme='civihr-ui-select']) {
&:not(.ui-select-multiple) {
.btn {
&.ui-select-toggle {
border-color: $input-border;
......@@ -69,7 +66,7 @@
}
&:hover {