From 060704cb1a7396573fc136f1d2998ed749970256 Mon Sep 17 00:00:00 2001 From: Keegan Date: Mon, 29 Feb 2016 14:24:59 +1100 Subject: [PATCH 1/6] Add hide/show method to manipulators. --- dev/custom-fn.js | 4 +- src/scripts/lib/manipulators.js | 40 +++++++++++++++--- src/styles/clay/_base.scss | 31 +++++++------- test/spec/lib/manipulators.js | 73 +++++++++++++++++++++++++++++++-- 4 files changed, 122 insertions(+), 26 deletions(-) diff --git a/dev/custom-fn.js b/dev/custom-fn.js index 4688283..6a52d7e 100644 --- a/dev/custom-fn.js +++ b/dev/custom-fn.js @@ -10,9 +10,9 @@ module.exports = function() { */ function toggleBackground() { if (this.get()) { - Clay.getItemByAppKey('background').enable(); + Clay.getItemByAppKey('colorTest').show(); } else { - Clay.getItemByAppKey('background').disable(); + Clay.getItemByAppKey('colorTest').hide(); } } diff --git a/src/scripts/lib/manipulators.js b/src/scripts/lib/manipulators.js index 5a54cde..9f0000b 100755 --- a/src/scripts/lib/manipulators.js +++ b/src/scripts/lib/manipulators.js @@ -18,6 +18,22 @@ function enable() { return this.trigger('enabled'); } +/** + * @returns {ClayEvents} + */ +function hide() { + this.$element.set('+hide'); + return this.trigger('hide'); +} + +/** + * @returns {ClayEvents} + */ +function show() { + this.$element.set('-hide'); + return this.trigger('show'); +} + module.exports = { html: { get: function() { @@ -26,7 +42,9 @@ module.exports = { set: function(value) { this.$manipulatorTarget.set('innerHTML', value); return this.trigger('change'); - } + }, + hide: hide, + show: show }, val: { get: function() { @@ -37,7 +55,9 @@ module.exports = { return this.trigger('change'); }, disable: disable, - enable: enable + enable: enable, + hide: hide, + show: show }, checked: { get: function() { @@ -48,7 +68,9 @@ module.exports = { return this.trigger('change'); }, disable: disable, - enable: enable + enable: enable, + hide: hide, + show: show }, radiogroup: { get: function() { @@ -61,7 +83,9 @@ module.exports = { return this.trigger('change'); }, disable: disable, - enable: enable + enable: enable, + hide: hide, + show: show }, checkboxgroup: { get: function() { @@ -83,7 +107,9 @@ module.exports = { return self.trigger('change'); }, disable: disable, - enable: enable + enable: enable, + hide: hide, + show: show }, color: { get: function() { @@ -99,6 +125,8 @@ module.exports = { return this.trigger('change'); }, disable: disable, - enable: enable + enable: enable, + hide: hide, + show: show } }; diff --git a/src/styles/clay/_base.scss b/src/styles/clay/_base.scss index 6a468fa..1581160 100644 --- a/src/styles/clay/_base.scss +++ b/src/styles/clay/_base.scss @@ -50,6 +50,19 @@ h6 { @include font-size(0.8); } +strong { + @include font-pfdin(medium); + color: $color-orange; +} + +a { + color: $color-gray-8; + + &:hover { + color: inherit; + } +} + label { display: flex; justify-content: space-between; @@ -83,9 +96,12 @@ label { } } +.hide { + display: none; +} + .component { padding-bottom: $item-spacing-v; - @include tap-highlight(); &.disabled { opacity: 0.25; @@ -134,19 +150,6 @@ label { } -strong { - @include font-pfdin(medium); - color: $color-orange; -} - -a { - color: $color-gray-8; - - &:hover { - color: inherit; - } -} - .inputs { display: block; width:100%; diff --git a/test/spec/lib/manipulators.js b/test/spec/lib/manipulators.js index 550cd12..5dff85a 100644 --- a/test/spec/lib/manipulators.js +++ b/test/spec/lib/manipulators.js @@ -7,7 +7,7 @@ var fixture = require('../../fixture'); describe('manipulators', function() { /** - * @param {string|Clay~ConfigItem} itemType + * @param {string|Object} itemType * @param {*} value * @param {*} [expected] * @return {void} @@ -31,7 +31,7 @@ describe('manipulators', function() { } /** - * @param {string|Clay~ConfigItem} itemType + * @param {string|Object} itemType * @return {void} */ function testDisable(itemType) { @@ -57,7 +57,7 @@ describe('manipulators', function() { } /** - * @param {string} itemType + * @param {string|Object} itemType * @return {void} */ function testEnable(itemType) { @@ -84,14 +84,71 @@ describe('manipulators', function() { }); } + /** + * @param {string|Object} itemType + * @return {void} + */ + function testHide(itemType) { + describe('.hide()', function() { + it('hides the field then triggers a "hide" event', function() { + var handlerSpy = sinon.spy(); + var clayItem = fixture.clayItem(itemType); + clayItem.on('hide', handlerSpy); + + assert.strictEqual( + clayItem.$element[0].classList.contains('hide'), + false + ); + clayItem.hide(); + assert.strictEqual( + clayItem.$element[0].classList.contains('hide'), + true + ); + assert.strictEqual(handlerSpy.callCount, 1, 'handler not called once'); + assert(handlerSpy.calledOn(clayItem), 'handler not called on clayItem'); + }); + }); + } + + /** + * @param {string|Object} itemType + * @return {void} + */ + function testShow(itemType) { + describe('.show()', function() { + it('shows the field then triggers a "show" event', function() { + var handlerSpy = sinon.spy(); + var clayItem = fixture.clayItem(itemType); + clayItem.on('show', handlerSpy); + + clayItem.hide(); + assert.strictEqual( + clayItem.$element[0].classList.contains('hide'), + true + ); + clayItem.show(); + assert.strictEqual( + clayItem.$element[0].classList.contains('hide'), + false + ); + assert.strictEqual(handlerSpy.callCount, 1, 'handler not called once'); + assert(handlerSpy.calledOn(clayItem), 'handler not called on clayItem'); + }); + }); + } + describe('html', function() { - testSetGet('footer', 'test123'); + testSetGet('text', 'test123'); + testShow('text'); + testHide('text'); }); describe('val', function() { testSetGet('input', 'test321'); testDisable('input'); testEnable('input'); + testShow('text'); + testHide('text'); }); describe('checked', function() { @@ -101,6 +158,8 @@ describe('manipulators', function() { testSetGet('toggle', 0); testDisable('toggle'); testEnable('toggle'); + testShow('toggle'); + testHide('toggle'); }); describe('radiogroup', function() { @@ -118,6 +177,8 @@ describe('manipulators', function() { testSetGet(item, 'three "quote'); testDisable(item); testEnable(item); + testShow(item); + testHide(item); }); describe('checkboxgroup', function() { @@ -136,6 +197,8 @@ describe('manipulators', function() { testSetGet(item, false, []); testDisable(item); testEnable(item); + testShow(item); + testHide(item); }); describe('color', function() { @@ -149,5 +212,7 @@ describe('manipulators', function() { testSetGet('color', undefined, 0x000000); testDisable('color'); testEnable('color'); + testShow('color'); + testHide('color'); }); }); From beb623f4fd470a9a320bdd936bbb80d2d1389dca Mon Sep 17 00:00:00 2001 From: Keegan Date: Wed, 2 Mar 2016 14:02:18 +1100 Subject: [PATCH 2/6] fix separator visibility on disabled and hidden items --- src/styles/clay/_base.scss | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/styles/clay/_base.scss b/src/styles/clay/_base.scss index b732a56..ebb8c5f 100644 --- a/src/styles/clay/_base.scss +++ b/src/styles/clay/_base.scss @@ -107,7 +107,7 @@ label { .component { padding-bottom: $item-spacing-v; - &.disabled { + &.disabled > * { opacity: 0.25; pointer-events: none; } @@ -130,7 +130,7 @@ label { padding-bottom: $item-spacing-v; } - &:last-child:after { + &:first-child:after { display: none; } @@ -139,7 +139,7 @@ label { background: $color-gray-6; display: block; position: absolute; - bottom: 0; + top: 0; left: $item-spacing-h / 2; right: $item-spacing-h / 2; height: 1px; @@ -151,7 +151,8 @@ label { background: $color-gray-3; border-radius: $border-radius $border-radius 0 0; - &:after { + &:after, + & + .component:after { display: none; } } From 8e3cd119b8aae3d3c21ea9fbbd293f1173005a3a Mon Sep 17 00:00:00 2001 From: Keegan Date: Wed, 2 Mar 2016 22:11:19 +1100 Subject: [PATCH 3/6] use !important for .hide class --- src/styles/clay/_base.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/clay/_base.scss b/src/styles/clay/_base.scss index ebb8c5f..751137c 100644 --- a/src/styles/clay/_base.scss +++ b/src/styles/clay/_base.scss @@ -97,7 +97,7 @@ label { } .hide { - display: none; + display: none !important; } .tap-highlight { From aa8409912c12949273b1429229188f25c613118b Mon Sep 17 00:00:00 2001 From: Keegan Date: Wed, 2 Mar 2016 23:57:24 +1100 Subject: [PATCH 4/6] fix separator visibility when items are hidden --- src/styles/clay/_base.scss | 26 +++++++++++++++++++++----- src/styles/clay/_vars.scss | 7 ------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/styles/clay/_base.scss b/src/styles/clay/_base.scss index 751137c..53c6c1e 100644 --- a/src/styles/clay/_base.scss +++ b/src/styles/clay/_base.scss @@ -107,9 +107,11 @@ label { .component { padding-bottom: $item-spacing-v; - &.disabled > * { - opacity: 0.25; + &.disabled { pointer-events: none; + > * { + opacity: 0.25; + } } } @@ -119,7 +121,7 @@ label { margin-bottom: 1rem; box-shadow: $color-gray-1 0 0.15rem 0.25rem; - .component { + > .component { padding-top: $item-spacing-v; padding-right: $item-spacing-h; padding-left: $item-spacing-h; @@ -147,14 +149,28 @@ label { } } - .component-heading:first-child { + // don't show the separator for the first non-hidden item + > .component:not(.hide):after { + display: none; + } + + > .component:not(.hide) ~ .component:not(.hide):after { + display: block; + } + + > .component-heading:first-child { background: $color-gray-3; border-radius: $border-radius $border-radius 0 0; + // don't show the separator for the first non-hidden item after the heading &:after, - & + .component:after { + ~ .component:not(.hide):after { display: none; } + + ~ .component:not(.hide) ~ .component:not(.hide):after { + display: block; + } } } diff --git a/src/styles/clay/_vars.scss b/src/styles/clay/_vars.scss index 7982216..391ecbd 100644 --- a/src/styles/clay/_vars.scss +++ b/src/styles/clay/_vars.scss @@ -34,14 +34,7 @@ $color-gray-9: #a4a4a4 ; $color-gray-10: #ececec; $color-gray-11: #f2f2f2; - - - -$global-margin: 55px; -$form-margin: 25px; $button-padding: 0.7rem; $button-padding-ios: 0.6rem; -$button-line-height: 13px; -$footer-height-large: 90px; $box-shadow-small-components: $color-gray-1 0 0.1rem 0.1rem; From 4fb8db32da873eb13ec2ed16b688f861ec494803 Mon Sep 17 00:00:00 2001 From: Keegan Date: Thu, 3 Mar 2016 00:13:51 +1100 Subject: [PATCH 5/6] Fix section spacing when all items in a section are hidden. --- src/styles/clay/_base.scss | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/styles/clay/_base.scss b/src/styles/clay/_base.scss index 53c6c1e..0df4fd0 100644 --- a/src/styles/clay/_base.scss +++ b/src/styles/clay/_base.scss @@ -17,7 +17,7 @@ html, body { body { background-color: $color-gray-2; - padding: $item-spacing-v $item-spacing-h; + padding: 0 $item-spacing-h $item-spacing-v; } h1, h2, h3, h4 { @@ -105,7 +105,7 @@ label { } .component { - padding-bottom: $item-spacing-v; + padding-top: $item-spacing-v; &.disabled { pointer-events: none; @@ -118,14 +118,18 @@ label { .section { background: $color-gray-4; border-radius: 0.25rem; - margin-bottom: 1rem; box-shadow: $color-gray-1 0 0.15rem 0.25rem; > .component { - padding-top: $item-spacing-v; + padding-bottom: $item-spacing-v; padding-right: $item-spacing-h; padding-left: $item-spacing-h; position: relative; + margin-top: 1rem; + + &:not(.hide) ~ .component { + margin-top: 0; + } &:last-child, &:first-child { From 35fc64de99d5048cd11dab333969873f26620530 Mon Sep 17 00:00:00 2001 From: Keegan Date: Thu, 3 Mar 2016 10:06:37 +1100 Subject: [PATCH 6/6] Document hide and show methods --- README.md | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 08a9bd2..1c0ec7a 100755 --- a/README.md +++ b/README.md @@ -443,60 +443,75 @@ The submit button for the page. You **MUST** include this component somewhere in ## Manipulators -Each component has a **manipulator**. This is a set of methods used to talk to the item on the page. At a minimum, manipulators must have a `.get()` and `.set(value)` method. When the config page is closed, the `.get()` method is run on all components registered with an `appKey` to construct the object sent to the C app. Many of these methods fire an event when the method is called. You can listen for these events with `ClayItem.on()`. +Each component has a **manipulator**. This is a set of methods used to talk to the item on the page. +At a minimum, manipulators must have a `.get()` and `.set(value)` method however there are also methods to assist in interactivity such as `.hide()` and `.disable()`. +**NOTE:** There is currently no way to disable or hide an entire section. You must disable/hide each item in the section to achieve this effect. +When the config page is closed, the `.get()` method is run on all components registered with an `appKey` to construct the object sent to the C app. +Many of these methods fire an event when the method is called. You can listen for these events with `ClayItem.on()`. #### html | Method | Returns | Event Fired | Description | |--------|---------|-------------| ------------| | `.set( [string\|HTML] value)` | `ClayItem` | `change` | Sets the content of this item. | -| `.get()` | `string` | Gets the content of this item. | +| `.get()` | `string` | | Gets the content of this item. | +| `.hide()` | `ClayItem` | `hide` | Hides the item | +| `.show()` | `ClayItem` | `show` | Shows the item | #### val | Method | Returns | Event Fired | Description | |--------|---------|-------------| ------------| | `.set( [string] value)` | `ClayItem` | `change` | Sets the value of this item. | -| `.get()` | `string` | Gets the content of this item. | +| `.get()` | `string` | | Gets the content of this item. | | `.disable()` | `ClayItem` | `disabled` | Prevents this item from being edited by the user. | | `.enable()` | `ClayItem` | `enabled` | Allows this item to be edited by the user. | +| `.hide()` | `ClayItem` | `hide` | Hides the item | +| `.show()` | `ClayItem` | `show` | Shows the item | #### checked | Method | Returns | Event Fired | Description | |--------|---------|-------------| ------------| | `.set( [boolean\|int] value)` | `ClayItem` | `change` | Check/uncheck the state of this item. | -| `.get()` | `int` | 1 if checked, 0 if not checked | +| `.get()` | `int` | | 1 if checked, 0 if not checked | | `.disable()` | `ClayItem` | `disabled` | Prevents this item from being edited by the user. | | `.enable()` | `ClayItem` | `enabled` | Allows this item to be edited by the user. | +| `.hide()` | `ClayItem` | `hide` | Hides the item | +| `.show()` | `ClayItem` | `show` | Shows the item | #### color | Method | Returns | Event Fired | Description | |--------|---------|-------------| ------------| | `.set( [string\|int] value)` | `ClayItem` | `change` | Sets the color picker to the provided color. If the value is a string, it must be provided in hex notation eg `'FF0000'`. | -| `.get()` | `int` | Get the chosen color. This is returned as a number in order to make it easy to use on the watch side using `GColorFromHEX()`. | +| `.get()` | `int` | | Get the chosen color. This is returned as a number in order to make it easy to use on the watch side using `GColorFromHEX()`. | | `.disable()` | `ClayItem` | `disabled` | Prevents this item from being edited by the user. | | `.enable()` | `ClayItem` | `enabled` | Allows this item to be edited by the user. | +| `.hide()` | `ClayItem` | `hide` | Hides the item | +| `.show()` | `ClayItem` | `show` | Shows the item | #### radiogroup | Method | Returns | Event Fired | Description | |--------|---------|-------------| ------------| | `.set( [string] value)` | `ClayItem` | `change` | Checks the radio button that corresponds to the provided value. | -| `.get()` | `string` | Gets the value of the checked radio button in the list. | +| `.get()` | `string` | | Gets the value of the checked radio button in the list. | | `.disable()` | `ClayItem` | `disabled` | Prevents this item from being edited by the user. | | `.enable()` | `ClayItem` | `enabled` | Allows this item to be edited by the user. | +| `.hide()` | `ClayItem` | `hide` | Hides the item | +| `.show()` | `ClayItem` | `show` | Shows the item | #### checkboxgroup | Method | Returns | Event Fired | Description | |--------|---------|-------------| ------------| | `.set( [array] value)` | `ClayItem` | `change` | Checks the checkboxes that corresponds to the provided list of values. | -| `.get()` | `Array.` | Gets an array of strings representing the list of the values of the checked items | +| `.get()` | `Array.` | | Gets an array of strings representing the list of the values of the checked items | | `.disable()` | `ClayItem` | `disabled` | Prevents this item from being edited by the user. | | `.enable()` | `ClayItem` | `enabled` | Allows this item to be edited by the user. | - +| `.hide()` | `ClayItem` | `hide` | Hides the item | +| `.show()` | `ClayItem` | `show` | Shows the item | # Extending Clay @@ -591,7 +606,13 @@ module.exports = function(minified) { var coolStuffToggle = Clay.getItemByAppKey('cool_stuff'); toggleBackground.call(coolStuffToggle); coolStuffToggle.on('change', toggleBackground); + + // Hide the color picker for aplite + if (Clay.meta.activeWatchInfo.platform === 'aplite') { + Clay.getItemByAppKey('background').hide(); + } }); + }; ```