   ###
   @CSS:
     BUTTON_TAG: 'li'
+
+  ###
+    @enum {string}
+  ###
+  @CLS:
     BUTTON_CLASS: 'dropup-button'
-    TARGET_ATTRIBUTE: 'target'
     CARET: 'caret-marker' # do not set to 'caret', as it is would add another arrow
     ARROW_UP: 'fa-angle-up'
     ARROW_LEFT: 'fa-angle-left'
     COLLAPSE: 'collapse'
+    OPENED: 'opened'
+    CLOSED: 'closed'
 
   ###
     @enum {number}
   ###
   @ANIMATION:
     DEFAULT_DURATION: 500
+
+  ###
+    @enum {string}
+  ###
+  @DATA:
+    TARGET: 'target'
 
   ###*
     @param {wzk.dom.Dom} dom

  ###
  toggle: (event) =>
    event.preventDefault()
    if (goog.style.isElementShown @dropupElement) and (not @animationLock)
      @close()
    else
      @open()

  ###
  decorate: (@dropupButton) ->
    # arrow span, allowing change of icon according to state
    @caretElement = @dom.cls(wzk.ui.dropup.Dropup.CLS.CARET, @dropupButton)

    # id of tag to dropup
    dropupSelector = goog.dom.dataset.get(@dropupButton, wzk.ui.dropup.Dropup.DATA.TARGET)
    unless dropupSelector?
      throw new Error "Dropup button element has no '#{wzk.ui.dropup.Dropup.DATA.TARGET}' attribute!"

    # find element with id or class
    @dropupElement = @dom.one "##{dropupSelector}, .#{dropupSelector}", @dom.getDocument()
    unless @dropupElement?
      console.warn("Dropup element with specified id or class  '#{dropupSelector}', does not exist!")
      return

    # hide dropupElement right after registering
    goog.style.setElementShown(@dropupElement, false)

    # set overflow property
    goog.style.setStyle(@dropupElement, 'overflow', 'hidden')

    # when animation is running, lock is set to true
    @animationLock = false

    # register handler for button
    goog.events.listen(@dropupButton, goog.events.EventType.CLICK, @toggle)

  ###*
    @protected
