diff --git a/README.md b/README.md index fddf60b..e3e9c43 100644 --- a/README.md +++ b/README.md @@ -329,6 +329,31 @@ Using Synergy, you can create themes and control your entire project's UI from a ## Changelog +### Version 3.10.3 + +Released: 1st July 2018 + +###### Release Notes + +* Updating to node-sass `4.9.0` +* Fixing regression bugs as a result of node-sass update + +### Version 3.10.2 + +Released: 25th June 2018 + +###### Release Notes + +* Bug fixes + +### Version 3.10.1 + +Released: 25th June 2018 + +###### Release Notes + +* Bug fixes + ### Version 3.10.0 Released: 20th June 2018 @@ -354,20 +379,4 @@ Released: 20th June 2018 * Allow passing of data-attributes to module * Append content before/after module through `before` and `after` props * Removing Bower -* General refactoring, syntax improvements and bug fixes - -### Version 3.9.2 - -Released: 13th January 2018 - -###### Release Notes - -* Fixing bug where only first modifier in module.jsx was parsed - -### Version 3.9.1 - -Released: 11th January 2018 - -###### Release Notes - -* Exporting transpiled module instead of ES6 \ No newline at end of file +* General refactoring, syntax improvements and bug fixes \ No newline at end of file diff --git a/dist/_synergy.scss b/dist/_synergy.scss index 8680242..7c2d444 100644 --- a/dist/_synergy.scss +++ b/dist/_synergy.scss @@ -403,7 +403,7 @@ $module: null !default; // Evaluate configuration values @if ($parser) { - $map-merged: call($parser, $map-merged); + $map-merged: call(get-function($parser), $map-merged); } // Store config in global variable @@ -1828,7 +1828,7 @@ $css-properties: ( $debug: true; @if (variable-exists('sass-config-parser') and $sass-config-parser) { - $value: call($sass-config-parser, $value); + $value: call(get-function($sass-config-parser), $value); } $this: &; @@ -2011,21 +2011,16 @@ $css-properties: ( /// @param {string|list} $components - The component or components to be used /// /// @example -/// /// @include module('header') { /// @include component('wrapper') { /// ... /// } /// } -/// -///
...
@mixin component($components: null, $content: (), $sub-component: false, $glue: $component-glue) { - $parents : (); $this : &; $selectors : '[class*="#{$module}#{$glue}"]'; - $tree : module-tree(&); - $namespace : nth($tree, length($tree)); + $namespace : nth(module-tree(&), length(module-tree(&))); @if not $sub-component { $namespace: $module; @@ -2040,6 +2035,8 @@ $css-properties: ( } } + $parents: (); + @each $selector in & { // spoof the selector into a list $selector: selector-parse(str-replace(inspect($selector), ' ', ', ')); @@ -2064,23 +2061,59 @@ $css-properties: ( @if length($parents) == 1 { $parents: nth($parents, 1); - $parents: clean-selector($parents); // https://github.com/sass/libsass/issues/2520 } - @at-root #{if($parents == '()', $selectors, $parents)} { - #{if($parents == '()', &, $selectors)} { - @content; - - @if selector-is-root-module($this) { - @each $component in $components { - $component: if(map-get($config, $component), map-get($config, $component), ()); - $content: merge-css-maps($content, $component); + @if ($parents == '()') { + @at-root #{$selectors} { + @include render-component($this, $components, $content) { + @content; + } + } + } + @else { + @at-root #{$parents} { + #{$selectors} { + @include render-component($this, $components, $content) { + @content; } } + } + } + + // @TODO - this works with node-sass 4.7.2 but not 4.9.0 + // + // @at-root #{if($parents == '()', $selectors, $parents)} { + // #{if($parents == '()', &, $selectors)} { + // @content; - @include get-css-from-map($content); + // @if selector-is-root-module($this) { + // @each $component in $components { + // $component: if(map-get($config, $component), map-get($config, $component), ()); + // $content: merge-css-maps($content, $component); + // } + // } + + // @include get-css-from-map($content); + // } + // } +} + +/// Render a component's content +/// +/// @param {selector} $target +/// @param {list} $components +/// @param {map} $content +@mixin render-component($target, $components, $content, $config: if(variable-exists('config'), $config, ())) { + @content; + + @if selector-is-root-module($target) { + @each $component in $components { + $component: if(map-get($config, $component), map-get($config, $component), ()); + $content: merge-css-maps($content, $component); } } + + @include get-css-from-map($content); } /// Alis for `component` mixin with $sub-component: true @@ -2120,47 +2153,34 @@ $css-properties: ( /// ... /// } /// } -/// -///
...
@mixin modifier($modifiers, $special: null, $glue: $modifier-glue) { - // BEGIN TOMFOOLERY https://github.com/sass/libsass/issues/2520 - $this: (); - - @each $selector in & { - $selector: clean-selector($selector); - $this: append($this, $selector, comma); - } - - $selectors: $this; - // END TOMFOOLERY - //$selectors: &; + $selectors: &; $is-local-flex-type: variable-exists('config') and map-get($config, 'selector-type') == 'flex'; $is-global-flex-type: not variable-exists('config') and $selector-type == 'flex'; - @if str-index(inspect($this), '.#{$module}') { + @if str-index(inspect(&), '.#{$module}') { @if $is-local-flex-type or $is-global-flex-type { $selectors: (); - @for $i from 1 through length($this) { + @for $i from 1 through length(&) { @if $i % 2 == 0 { - $selectors: append($selectors, nth($this, $i), comma); + $selectors: append($selectors, nth(&, $i), comma); } } } } @at-root #{$selectors} { - $this: &; $modifier-selectors: (); @each $modifier in $modifiers { @if $special == 'not' { - $modifier-selectors: join($modifier-selectors, '#{$this}:not([class*="#{$glue}#{$modifier}"])', comma); + $modifier-selectors: join($modifier-selectors, '&:not([class*="#{$glue}#{$modifier}"])', comma); } @else { - $modifier-selectors: join($modifier-selectors, '#{$this}[class*="#{$glue}#{$modifier}"]', comma); + $modifier-selectors: join($modifier-selectors, '&[class*="#{$glue}#{$modifier}"]', comma); } } diff --git a/dist/synergy.js b/dist/synergy.js index ee2ff05..2a81c57 100644 --- a/dist/synergy.js +++ b/dist/synergy.js @@ -946,7 +946,9 @@ exports.default = getModifiersFromProps; * @param {*} props * @param {*} blacklist */ -function getModifiersFromProps(props, blacklist) { +function getModifiersFromProps(props) { + var blacklist = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + var modifiers = []; for (var prop in props) { @@ -1979,7 +1981,7 @@ var Module = function (_React$Component) { }, { key: 'componentDidMount', value: function componentDidMount() { - var _module = Synergy.modules[this.props.name]; + var _module = Synergy.modules ? Synergy.modules[this.props.name] : null; if (_module && _module.methods) { if (_module.methods.init) { @@ -5694,8 +5696,6 @@ var _renderModifiers2 = _interopRequireDefault(_renderModifiers); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } @@ -5723,6 +5723,8 @@ var Component = function (_React$Component) { _this.selector = _this.module + '_' + (_this.props.name + _this.modifiers) + _this.classes; _this.getEventHandlers([_this.props, _this.config[_this.props.name] ? _this.config[_this.props.name] : {}]); + + if (_this.props.href) _this.tag = 'a'; return _this; } @@ -5781,6 +5783,8 @@ var Component = function (_React$Component) { continue; } else if (prop === 'modifiers') { continue; + } else if (prop === 'tag') { + continue; } else if (prop === 'elementname') { HtmlProps.name = props[prop]; } else { @@ -5796,19 +5800,15 @@ var Component = function (_React$Component) { var _this3 = this; var renderTag = function renderTag() { - if (_this3.props.from) { - return _react2.default.cloneElement(_this3.props.from, Object.assign.apply(Object, _toConsumableArray(_this3.getHtmlProps(_this3.props)).concat(_toConsumableArray(_this3.eventHandlers), [{ className: _this3.selector }])), _this3.props.from.props.children); - } else { - return _react2.default.createElement( - _this3.tag, - _extends({}, _this3.getHtmlProps(_this3.props), _this3.eventHandlers, { - - className: _this3.selector, - 'data-component': _this3.props.name - }), - _this3.props.children - ); - } + return _react2.default.createElement( + _this3.tag, + _extends({}, _this3.getHtmlProps(_this3.props), _this3.eventHandlers, { + + className: _this3.selector, + 'data-component': _this3.props.name + }), + _this3.props.children + ); }; if (this.isNested()) { diff --git a/package.json b/package.json index d4b0ee4..8f57041 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Synergy", - "version": "3.10.0", + "version": "3.10.3", "description": "A front-end framework for building modular, configurable and scalable UI components", "main": "dist/synergy.js", "author": "(Edmund Reed)[http://twitter.com/esr360] ", @@ -47,7 +47,7 @@ "jsdom": "^11.0.0", "jsdom-global": "^3.0.2", "mocha": "^3.4.2", - "node-sass": "^4.7.2", + "node-sass": "^4.9.0", "sass-true": "^3.0.0-beta.1", "sassdoc": "^2.5.0", "stylelint": "^8.4.0", diff --git a/src/js/component.jsx b/src/js/component.jsx index 6bedb94..34ab55d 100644 --- a/src/js/component.jsx +++ b/src/js/component.jsx @@ -27,6 +27,8 @@ export default class Component extends React.Component { this.getEventHandlers([ this.props, this.config[this.props.name] ? this.config[this.props.name] : {} ]); + + if (this.props.href) this.tag = 'a'; } getEventHandlers(properties) { @@ -78,7 +80,10 @@ export default class Component extends React.Component { } else if (prop === 'modifiers') { continue; - } + } + else if (prop === 'tag') { + continue; + } else if (prop === 'elementname') { HtmlProps.name = props[prop]; } @@ -91,26 +96,18 @@ export default class Component extends React.Component { } render() { - const renderTag = () => { - if (this.props.from) { - return React.cloneElement(this.props.from, Object.assign( - ...this.getHtmlProps(this.props), ...this.eventHandlers, { className: this.selector } - ), this.props.from.props.children) - } else { - return ( - - - {this.props.children} - - ) - } - } + const renderTag = () => ( + + + {this.props.children} + + ); if (this.isNested()) { const parentKeys = Object.keys(this.props).sort(); diff --git a/src/js/module.jsx b/src/js/module.jsx index 571c2c6..8f60e28 100644 --- a/src/js/module.jsx +++ b/src/js/module.jsx @@ -82,7 +82,7 @@ export default class Module extends React.Component { } componentDidMount() { - const _module = Synergy.modules[this.props.name]; + const _module = Synergy.modules ? Synergy.modules[this.props.name] : null; if (_module && _module.methods) { if (_module.methods.init) { diff --git a/src/js/utilities/getModifiersFromProps.js b/src/js/utilities/getModifiersFromProps.js index 69cea17..8f42b94 100644 --- a/src/js/utilities/getModifiersFromProps.js +++ b/src/js/utilities/getModifiersFromProps.js @@ -2,7 +2,7 @@ * @param {*} props * @param {*} blacklist */ -export default function getModifiersFromProps(props, blacklist) { +export default function getModifiersFromProps(props, blacklist = []) { const modifiers = []; for (var prop in props) { diff --git a/src/scss/mixins/_component.scss b/src/scss/mixins/_component.scss index 359a1e7..dc83150 100644 --- a/src/scss/mixins/_component.scss +++ b/src/scss/mixins/_component.scss @@ -6,21 +6,16 @@ /// @param {string|list} $components - The component or components to be used /// /// @example -/// /// @include module('header') { /// @include component('wrapper') { /// ... /// } /// } -/// -///
...
@mixin component($components: null, $content: (), $sub-component: false, $glue: $component-glue) { - $parents : (); $this : &; $selectors : '[class*="#{$module}#{$glue}"]'; - $tree : module-tree(&); - $namespace : nth($tree, length($tree)); + $namespace : nth(module-tree(&), length(module-tree(&))); @if not $sub-component { $namespace: $module; @@ -35,6 +30,8 @@ } } + $parents: (); + @each $selector in & { // spoof the selector into a list $selector: selector-parse(str-replace(inspect($selector), ' ', ', ')); @@ -59,23 +56,59 @@ @if length($parents) == 1 { $parents: nth($parents, 1); - $parents: clean-selector($parents); // https://github.com/sass/libsass/issues/2520 } - @at-root #{if($parents == '()', $selectors, $parents)} { - #{if($parents == '()', &, $selectors)} { - @content; - - @if selector-is-root-module($this) { - @each $component in $components { - $component: if(map-get($config, $component), map-get($config, $component), ()); - $content: merge-css-maps($content, $component); + @if ($parents == '()') { + @at-root #{$selectors} { + @include render-component($this, $components, $content) { + @content; + } + } + } + @else { + @at-root #{$parents} { + #{$selectors} { + @include render-component($this, $components, $content) { + @content; } } + } + } + + // @TODO - this works with node-sass 4.7.2 but not 4.9.0 + // + // @at-root #{if($parents == '()', $selectors, $parents)} { + // #{if($parents == '()', &, $selectors)} { + // @content; + + // @if selector-is-root-module($this) { + // @each $component in $components { + // $component: if(map-get($config, $component), map-get($config, $component), ()); + // $content: merge-css-maps($content, $component); + // } + // } + + // @include get-css-from-map($content); + // } + // } +} + +/// Render a component's content +/// +/// @param {selector} $target +/// @param {list} $components +/// @param {map} $content +@mixin render-component($target, $components, $content, $config: if(variable-exists('config'), $config, ())) { + @content; - @include get-css-from-map($content); + @if selector-is-root-module($target) { + @each $component in $components { + $component: if(map-get($config, $component), map-get($config, $component), ()); + $content: merge-css-maps($content, $component); } } + + @include get-css-from-map($content); } /// Alis for `component` mixin with $sub-component: true diff --git a/src/scss/mixins/_modifier.scss b/src/scss/mixins/_modifier.scss index 0fd750d..0b563da 100644 --- a/src/scss/mixins/_modifier.scss +++ b/src/scss/mixins/_modifier.scss @@ -13,47 +13,34 @@ /// ... /// } /// } -/// -///
...
@mixin modifier($modifiers, $special: null, $glue: $modifier-glue) { - // BEGIN TOMFOOLERY https://github.com/sass/libsass/issues/2520 - $this: (); - - @each $selector in & { - $selector: clean-selector($selector); - $this: append($this, $selector, comma); - } - - $selectors: $this; - // END TOMFOOLERY - //$selectors: &; + $selectors: &; $is-local-flex-type: variable-exists('config') and map-get($config, 'selector-type') == 'flex'; $is-global-flex-type: not variable-exists('config') and $selector-type == 'flex'; - @if str-index(inspect($this), '.#{$module}') { + @if str-index(inspect(&), '.#{$module}') { @if $is-local-flex-type or $is-global-flex-type { $selectors: (); - @for $i from 1 through length($this) { + @for $i from 1 through length(&) { @if $i % 2 == 0 { - $selectors: append($selectors, nth($this, $i), comma); + $selectors: append($selectors, nth(&, $i), comma); } } } } @at-root #{$selectors} { - $this: &; $modifier-selectors: (); @each $modifier in $modifiers { @if $special == 'not' { - $modifier-selectors: join($modifier-selectors, '#{$this}:not([class*="#{$glue}#{$modifier}"])', comma); + $modifier-selectors: join($modifier-selectors, '&:not([class*="#{$glue}#{$modifier}"])', comma); } @else { - $modifier-selectors: join($modifier-selectors, '#{$this}[class*="#{$glue}#{$modifier}"]', comma); + $modifier-selectors: join($modifier-selectors, '&[class*="#{$glue}#{$modifier}"]', comma); } } diff --git a/src/scss/utilities/_config.scss b/src/scss/utilities/_config.scss index caad39f..e6cecdc 100644 --- a/src/scss/utilities/_config.scss +++ b/src/scss/utilities/_config.scss @@ -19,7 +19,7 @@ // Evaluate configuration values @if ($parser) { - $map-merged: call($parser, $map-merged); + $map-merged: call(get-function($parser), $map-merged); } // Store config in global variable diff --git a/src/scss/utilities/_this.scss b/src/scss/utilities/_this.scss index 194d287..e047bc9 100644 --- a/src/scss/utilities/_this.scss +++ b/src/scss/utilities/_this.scss @@ -9,7 +9,7 @@ $debug: true; @if (variable-exists('sass-config-parser') and $sass-config-parser) { - $value: call($sass-config-parser, $value); + $value: call(get-function($sass-config-parser), $value); } $this: &;