Info¶
The concept of extend very well might be the most difficult concept in ctr to grasp. I have struggled to find words that do extend justice and have ultimately come to the conclusion that extend is the “final boss” of ctr. Without an intimate familiarity with both variable and class, you too will be defeated. Although, put in simple terms, if a variable is defined in a <class> it can be altered through an extend <class> Object. The difficulty comes in practice and understanding the intricacies of extend.
Specific Syntax¶
Description: A specific extend <class> variable is defined as a variable that is set through extend whose property key corresponds to a variable key defined in the <class>.
ctrSetClass('<class>', {
  $$: {
    <variable:one>: <value:default-one>
    <variable:two>: <value:default-two>
  }
  <property:one>: '$<variable:one>$'
  <property:two>: '$<variable:two>$'
})
// <class> property key
ctr('<#selector-one>', {
  extend: {
    // Object key <class> identifier
    myKoolClass: {
      class: <class>
      // variable one altered
      <variable:one>: <value:extend-one>
    }
  }
})
// Object <class> key
ctr('<#selector-two>', {
  extend: {
    // Object key <class> identifier
    <class>: {
      // variable two altered
      <variable:two>: <value:extend-two>
    }
  }
})
ctr:::setClass:<class>:
  $$:
    <variable:one>: <value:default-one>
    <variable:two>: <value:default-two>
  <property:one>: $<variable:one>$
  <property:two>: $<variable:two>$
# <class> property key
<#selector-one>:
  extend:
    # Object key <class> identifier
    myKoolClass:
      class: <class>
      # variable one altered
      <variable:one>: <value:extend-one>
# Object <class> key
<#selector-two>:
  extend:
    # Object key <class> identifier
    <class>:
      # variable two altered
      <variable:two>: <value:extend-two>
<#selector-one> {
  <property:one>: <value:extend-one>;
  <property:two>: <value:default-two>;
}
<#selector-two> {
  <property:one>: <value:default-one>;
  <property:two>: <value:extend-two>;
}
Notes
- A specific 
extend<class>variable will always overwrite aglobal,local,private, or common extend<class>variable 
Specific¶
Description: The specific extend <class> Object alters the corresponding global, local, and/or private <class> variable(s).
// sets global variable
ctrSetVariable({
  primary-bg: #f00
})
// sets class
ctrSetClass('Box', {
  $$: {
    width: 200px
    height: 200px
    border-radius: 4px
  }
  width: '$width$'
  height: '$height$'
  background: '$primary-bg$'
  // private variable
  border-radius: '_$border-radius$_'
})
ctr('.test', {
  font-size: 1em
  extend: {
    Box: {
      height: 400px
      border-radius: 8px
      primary-bg: #00f
    }
  }
})
# sets global variable
ctr:::setVariable:
  primary-bg: '#f00'
# sets class
ctr:::setClass:Box:
  $$:
    width: 200px
    height: 200px
    border-radius: 4px
  width: $width$
  height: $height$
  background: $primary-bg$
  # private variable
  border-radius: _$border-radius$_
.test:
  font-size: 1em
  extend:
    Box:
      height: 400px
      border-radius: 8px
      primary-bg: '#00f'
.test {
  width: 200px;
  height: 400px;
  font-size: 1em;
  background: #00f;
  border-radius: 8px;
}
// sets global variable
ctrSetVariable({
  primary-bg: #f00
})
// sets class
ctrSetClass('Box', {
  $$: {
    width: 200px
    height: 200px
    border-radius: 4px
  }
  width: '$width$'
  height: '$height$'
  background: '$primary-bg$'
  // private variable
  border-radius: '_$border-radius$_'
})
ctr('.test', {
  font-size: 1em
  extend: {
    Box: {
      height: 400px
      border-radius: 8px
      primary-bg: #00f
    }
  }
})
.test {
  width: 200px;
  height: 400px;
  font-size: 1em;
  background: #00f;
  border-radius: 8px;
}
# sets global variable
ctr:::setVariable:
  primary-bg: '#f00'
# sets class
ctr:::setClass:Box:
  $$:
    width: 200px
    height: 200px
    border-radius: 4px
  width: $width$
  height: $height$
  background: $primary-bg$
  # private variable
  border-radius: _$border-radius$_
.test:
  font-size: 1em
  extend:
    Box:
      height: 400px
      border-radius: 8px
      primary-bg: '#00f'
Common Syntax¶
Description: A common extend <class> variable is defined as a variable that is set through extend via the common Object, denoted by the $$ key, and whose property key corresponds to a variable key defined in the <class>.
ctrSetClass('<class-one>', {
  $$: {
    <variable:one-1>: <value:one-default>
    <variable:common>: <value:one-default>
  }
  <property:one-1>: '$<variable:one-1>$'
  <property:one-2>: '$<variable:common>$'
})
ctrSetClass('<class-two>', {
  $$: {
    <variable:two-1>: <value:two-default>
    <variable:common>: <value:two-default>
  }
  <property:two-1>: '$<variable:two-1>$'
  <property:two-2>: '$<variable:common>$'
})
ctr('<#selector>', {
  extend: {
    // common variable Object
    $$: {
      <variable:common>: <value:extend-common>
    }
    class: '<class-one>' '<class-two>'
  }
})
ctr:::setClass:<class-one>:
  $$:
    <variable:one-1>: <value:one-default>
    <variable:common>: <value:one-default>
  <property:one-1>: $<variable:one-1>$
  <property:one-2>: $<variable:common>$
ctr:::setClass:<class-two>:
  $$:
    <variable:two-1>: <value:two-default>
    <variable:common>: <value:two-default>
  <property:two-1>: $<variable:two-1>$
  <property:two-2>: $<variable:common>$
<#selector>:
  extend:
    # common variable Object
    $$:
      <variable:common>: <value:extend-common>
    class: [<class-one>, <class-two>]
<#selector> {
  <property:one-1>: <value:one-default>
  <property:one-2>: <value:extend-common>
  <property:two-1>: <value:two-default>
  <property:two-2>: <value:extend-common>
}
Notes
- A common 
extend<class>variable will always overwrite aglobal,local, orprivatevariable, but not a specific extend<class>variable 
Common¶
Description: The common extend <class> Object ($$) alters the corresponding global, local, and/or private <class> variable(s). In other words, the common extend Object is like a specific global variable that only targets classes defined in the extend Object.
ctrSetClass('BackgroundOnHover', {
  $$: {
    opacity: 1
    background: red
  }
  hover-on: {
    opacity: '$opacity$'
    background: '$background$'
  }
})
ctrSetClass('BackgroundOnFocus', {
  $$: {
    opacity: 1
    background: red
  }
  focus-on: {
    opacity: '$opacity$'
    background: '$background$'
  }
})
ctr('.test', {
  width: 200px
  extend: {
    // common extend <class> Object
    $$: {
      opacity: 0.5
    }
    class: 'BackgroundOnHover' 'BackgroundOnFocus'
  }
})
ctr:::setClass:BackgroundOnHover:
  $$:
    opacity: 1
    background: red
  hover-on:
    opacity: $opacity$
    background: $background$
ctr:::setClass:BackgroundOnFocus:
  $$:
    opacity: 1
    background: red
  focus-on:
    opacity: $opacity$
    background: $background$
.test:
  width: 200px
  extend:
    # common extend <class> Object
    $$:
      opacity: 0.5
    class: [BackgroundOnHover, BackgroundOnFocus]
.test {
  width: 200px;
}
.test:focus {
  opacity: 0.5;
  background: #f00;
  transition-delay: 0s, 0s;
  transition-duration: 0.5s, 0.5s;
  transition-property: opacity, background;
  transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1), cubic-bezier(0.42, 0, 0.58, 1);
}
.test:hover {
  opacity: 0.5;
  background: #f00;
  transition-delay: 0s, 0s;
  transition-duration: 0.5s, 0.5s;
  transition-property: opacity, background;
  transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1), cubic-bezier(0.42, 0, 0.58, 1);
}
ctrSetClass('BackgroundOnHover', {
  $$: {
    opacity: 1
    background: red
  }
  hover-on: {
    opacity: '$opacity$'
    background: '$background$'
  }
})
ctrSetClass('BackgroundOnFocus', {
  $$: {
    opacity: 1
    background: red
  }
  focus-on: {
    opacity: '$opacity$'
    background: '$background$'
  }
})
ctr('.test', {
  width: 200px
  extend: {
    // common extend <class> Object
    $$: {
      opacity: 0.5
    }
    class: 'BackgroundOnHover' 'BackgroundOnFocus'
  }
})
.test {
  width: 200px;
}
.test:focus {
  opacity: 0.5;
  background: #f00;
  transition-delay: 0s, 0s;
  transition-duration: 0.5s, 0.5s;
  transition-property: opacity, background;
  transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1), cubic-bezier(0.42, 0, 0.58, 1);
}
.test:hover {
  opacity: 0.5;
  background: #f00;
  transition-delay: 0s, 0s;
  transition-duration: 0.5s, 0.5s;
  transition-property: opacity, background;
  transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1), cubic-bezier(0.42, 0, 0.58, 1);
}
ctr:::setClass:BackgroundOnHover:
  $$:
    opacity: 1
    background: red
  hover-on:
    opacity: $opacity$
    background: $background$
ctr:::setClass:BackgroundOnFocus:
  $$:
    opacity: 1
    background: red
  focus-on:
    opacity: $opacity$
    background: $background$
.test:
  width: 200px
  extend:
    # common extend <class> Object
    $$:
      opacity: 0.5
    class: [BackgroundOnHover, BackgroundOnFocus]
Notes
- In other-other words, the common 
extendObject is merged into every specific extend<class>unless specified otherwise 
Common Specific¶
Description: A class key can be defined in the common extend <class> Object ($$) to target specific <class(es)>. In other words, it’s like a regular common extend <class> Object, but rather than targeting every <class> in the extend Object it only targets those specified.
ctrSetClass('BackgroundOnHover', {
  $$: {
    opacity: 1
    background: red
  }
  hover-on: {
    opacity: '$opacity$'
    background: '$background$'
  }
})
ctrSetClass('BackgroundOnFocus', {
  $$: {
    opacity: 1
    background: red
  }
  focus-on: {
    opacity: '$opacity$'
    background: '$background$'
  }
})
ctr('.test', {
  width: 200px
  extend: {
    $$: {
      // only targets - BackgroundOnHover
      class: 'BackgroundOnHover'
      opacity: 0.5
    }
    // BackgroundOnHover still needs to be specified
    class: 'BackgroundOnHover'
    // Will not pick up opactiy: 0.5
    BackgroundOnFocus: {
      background: blue
    }
  }
})
ctr:::setClass:BackgroundOnHover:
  $$:
    opacity: 1
    background: red
  hover-on:
    opacity: $opacity$
    background: $background$
ctr:::setClass:BackgroundOnFocus:
  $$:
    opacity: 1
    background: red
  focus-on:
    opacity: $opacity$
    background: $background$
.test:
  width: 200px
  extend:
    $$:
      # only targets - BackgroundOnHover
      class: BackgroundOnHover
      opacity: 0.5
    # BackgroundOnHover still needs to be specified
    class: BackgroundOnHover
    # Will not pick up opactiy: 0.5
    BackgroundOnFocus:
      background: blue
.test {
  width: 200px;
}
.test:hover {
  opacity: 0.5;
  background: #f00;
  transition-delay: 0s, 0s;
  transition-duration: 0.5s, 0.5s;
  transition-property: opacity, background;
  transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1), cubic-bezier(0.42, 0, 0.58, 1);
}
.test:focus {
  opacity: 1;
  background: #00f;
  transition-delay: 0s, 0s;
  transition-duration: 0.5s, 0.5s;
  transition-property: opacity, background;
  transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1), cubic-bezier(0.42, 0, 0.58, 1);
}
ctrSetClass('BackgroundOnHover', {
  $$: {
    opacity: 1
    background: red
  }
  hover-on: {
    opacity: '$opacity$'
    background: '$background$'
  }
})
ctrSetClass('BackgroundOnFocus', {
  $$: {
    opacity: 1
    background: red
  }
  focus-on: {
    opacity: '$opacity$'
    background: '$background$'
  }
})
ctr('.test', {
  width: 200px
  extend: {
    $$: {
      // only targets - BackgroundOnHover
      class: 'BackgroundOnHover'
      opacity: 0.5
    }
    // BackgroundOnHover still needs to be specified
    class: 'BackgroundOnHover'
    // Will not pick up opactiy: 0.5
    BackgroundOnFocus: {
      background: blue
    }
  }
})
.test {
  width: 200px;
}
.test:hover {
  opacity: 0.5;
  background: #f00;
  transition-delay: 0s, 0s;
  transition-duration: 0.5s, 0.5s;
  transition-property: opacity, background;
  transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1), cubic-bezier(0.42, 0, 0.58, 1);
}
.test:focus {
  opacity: 1;
  background: #00f;
  transition-delay: 0s, 0s;
  transition-duration: 0.5s, 0.5s;
  transition-property: opacity, background;
  transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1), cubic-bezier(0.42, 0, 0.58, 1);
}
ctr:::setClass:BackgroundOnHover:
  $$:
    opacity: 1
    background: red
  hover-on:
    opacity: $opacity$
    background: $background$
ctr:::setClass:BackgroundOnFocus:
  $$:
    opacity: 1
    background: red
  focus-on:
    opacity: $opacity$
    background: $background$
.test:
  width: 200px
  extend:
    $$:
      # only targets - BackgroundOnHover
      class: BackgroundOnHover
      opacity: 0.5
    # BackgroundOnHover still needs to be specified
    class: BackgroundOnHover
    # Will not pick up opactiy: 0.5
    BackgroundOnFocus:
      background: blue