11import PropTypes from 'prop-types' ;
22import React from 'react' ;
3+ import debounce from 'lodash.debounce' ;
34import PropForm from './PropForm' ;
45import Types from './types' ;
56
7+ const getTimestamp = ( ) => + new Date ( ) ;
8+
69const styles = {
710 panelWrapper : {
811 width : '100%' ,
@@ -44,35 +47,50 @@ export default class Panel extends React.Component {
4447 this . handleChange = this . handleChange . bind ( this ) ;
4548 this . setKnobs = this . setKnobs . bind ( this ) ;
4649 this . reset = this . reset . bind ( this ) ;
50+ this . setOptions = this . setOptions . bind ( this ) ;
4751
4852 this . state = { knobs : { } } ;
53+ this . options = { } ;
54+
55+ this . lastEdit = getTimestamp ( ) ;
4956 this . loadedFromUrl = false ;
5057 this . props . channel . on ( 'addon:knobs:setKnobs' , this . setKnobs ) ;
58+ this . props . channel . on ( 'addon:knobs:setOptions' , this . setOptions ) ;
5159 }
5260
5361 componentWillUnmount ( ) {
5462 this . props . channel . removeListener ( 'addon:knobs:setKnobs' , this . setKnobs ) ;
5563 }
5664
57- setKnobs ( knobs ) {
65+ setOptions ( options = { debounce : false , timestamps : false } ) {
66+ this . options = options ;
67+
68+ if ( options . debounce ) {
69+ this . emitChange = debounce ( this . emitChange , options . debounce . wait , { leading : options . debounce . leading } ) ;
70+ }
71+ }
72+
73+ setKnobs ( { knobs, timestamp } ) {
5874 const queryParams = { } ;
5975 const { api, channel } = this . props ;
6076
61- Object . keys ( knobs ) . forEach ( name => {
62- const knob = knobs [ name ] ;
63- // For the first time, get values from the URL and set them.
64- if ( ! this . loadedFromUrl ) {
65- const urlValue = api . getQueryParam ( `knob-${ name } ` ) ;
66-
67- if ( urlValue !== undefined ) {
68- // If the knob value present in url
69- knob . value = Types [ knob . type ] . deserialize ( urlValue ) ;
70- channel . emit ( 'addon:knobs:knobChange' , knob ) ;
77+ if ( ! this . options . timestamps || ! timestamp || this . lastEdit <= timestamp ) {
78+ Object . keys ( knobs ) . forEach ( name => {
79+ const knob = knobs [ name ] ;
80+ // For the first time, get values from the URL and set them.
81+ if ( ! this . loadedFromUrl ) {
82+ const urlValue = api . getQueryParam ( `knob-${ name } ` ) ;
83+
84+ if ( urlValue !== undefined ) {
85+ // If the knob value present in url
86+ knob . value = Types [ knob . type ] . deserialize ( urlValue ) ;
87+ channel . emit ( 'addon:knobs:knobChange' , knob ) ;
88+ }
7189 }
72- }
7390
74- queryParams [ `knob-${ name } ` ] = Types [ knob . type ] . serialize ( knob . value ) ;
75- } ) ;
91+ queryParams [ `knob-${ name } ` ] = Types [ knob . type ] . serialize ( knob . value ) ;
92+ } ) ;
93+ }
7694
7795 this . loadedFromUrl = true ;
7896 api . setQueryParams ( queryParams ) ;
@@ -83,8 +101,13 @@ export default class Panel extends React.Component {
83101 this . props . channel . emit ( 'addon:knobs:reset' ) ;
84102 }
85103
104+ emitChange ( changedKnob ) {
105+ this . props . channel . emit ( 'addon:knobs:knobChange' , changedKnob ) ;
106+ }
107+
86108 handleChange ( changedKnob ) {
87- const { api, channel } = this . props ;
109+ this . lastEdit = getTimestamp ( ) ;
110+ const { api } = this . props ;
88111 const { knobs } = this . state ;
89112 const { name, type, value } = changedKnob ;
90113 const newKnobs = { ...knobs } ;
@@ -99,7 +122,7 @@ export default class Panel extends React.Component {
99122 queryParams [ `knob-${ name } ` ] = Types [ type ] . serialize ( value ) ;
100123
101124 api . setQueryParams ( queryParams ) ;
102- channel . emit ( 'addon: knobs:knobChange' , changedKnob ) ;
125+ this . setState ( { knobs : newKnobs } , this . emitChange ( changedKnob ) ) ;
103126 }
104127
105128 render ( ) {
0 commit comments