                 </div>
             </div>
 
+DimensionWidget = React.createClass
+    # props:
+    #   width
+    #   height
+    #   onSet(width, height)
+    getInitialState: () ->
+        isEditing: false
+
+    mixins: [React.addons.PureRenderMixin]
+
+    render: () ->
+        if @state.isEditing
+            <div className="dimension-panel">
+                <span className="dimension-panel-edit-1">Width:</span>
+                <span className="dimension-panel-edit-2"><input type="text" defaultValue={@props.width} onKeyDown={@onKeyDown} ref={@widthInputFun} className="dont-bubble-keydown" /></span>
+                <span className="dimension-panel-edit-3">Height:</span>
+                <span className="dimension-panel-edit-4"><input type="text" defaultValue={@props.height} onKeyDown={@onKeyDown} ref={@heightInputFun} className="dont-bubble-keydown" /></span>
+                <span className="dimension-panel-static-4"><input type="button" className="lt-button" value="Submit" onClick={@onSubmit} /></span>
+            </div>
+        else
+            <div className="dimension-panel">
+                <span className="dimension-panel-static-1">Width:</span>
+                <span className="dimension-panel-static-2">{@props.width}</span>
+                <span className="dimension-panel-static-3">Height:</span>
+                <span className="dimension-panel-static-4">{@props.height}</span>
+                <span className="dimension-panel-static-4"><input type="button" className="lt-button" value="Edit" onClick={@onClickEdit} /></span>
+            </div>
+
+    widthInputFun: (elem) ->
+        if elem? and (not @widthInput?)
+            # when creating this field, focus on it
+            node = React.findDOMNode(elem)
+
+            # code to focus on the input element 'node' at the END
+            # from http://stackoverflow.com/questions/1056359/set-mouse-focus-and-move-cursor-to-end-of-input-using-jquery
+            node.focus()
+            if node.setSelectionRange
+                len = $(node).val().length * 2
+                node.setSelectionRange(len, len)
+            else
+                $(node).val($(node).val())
+
+        @widthInput = elem
+
+
+    heightInputFun: (elem) ->
+        @heightInput = elem
+
+    onClickEdit: () ->
+        @setState
+            isEditing: true
+
+    onSubmit: () ->
+        widthStr = React.findDOMNode(@widthInput).value
+        heightStr = React.findDOMNode(@heightInput).value
+        if (not Utils.isValidInteger(widthStr)) or (not Utils.isValidInteger(heightStr))
+            return
+        width = parseInt(widthStr, 10)
+        height = parseInt(heightStr, 10)
+        if width <= 0 or height <= 0 or width >= 200 or height >= 200
+            return
+        @props.onSet(width, height)
+        @setState
+            isEditing: false
+
+    onCancelEdit: () ->
+        @setState
+            isEditing: false
+
+    onKeyDown: (event) ->
+        if event.which == 13 # enter
+            @onSubmit()
+            event.preventDefault()
+        else if event.which == 27 # escape
+            @onCancelEdit()
+            event.preventDefault()
+
 PuzzleGrid = React.createClass
     shouldComponentUpdate: (nextProps, nextState) -> not Utils.deepEquals(@props, nextProps)
 


        @closeMatchFinder()

    # Copy/cut/paste stuff

    doCopy: (event) ->

                op = Ot.compose(@state.puzzle, op, Ot.opEditCellValue row, col, "contents", "")
                op = Ot.compose(@state.puzzle, op, Ot.opEditCellValue row, col, "number", null)
                op = Ot.compose(@state.puzzle, op, Ot.opEditCellValue row, col, "open", true)
        @props.requestOp op

    # Perform an automatic renumbering.
