render() {
    const config = { ...DEFAULT_SETTINGS, ...this.props.config }

    const languageMode = this.handleLanguageChange(
      this.props.children,
      config.language && config.language.toLowerCase()
    )

    const options = {
      screenReaderLabel: 'Code editor',
      lineNumbers: config.lineNumbers,
      firstLineNumber: config.firstLineNumber,
      mode: languageMode || 'plaintext',
      theme: config.theme,
      scrollbarStyle: null,
      viewportMargin: Infinity,
      lineWrapping: true,
      smartIndent: true,
      extraKeys: {
        'Shift-Tab': 'indentLess',
      },
      readOnly: this.props.readOnly,
      showInvisibles: config.hiddenCharacters,
      autoCloseBrackets: true,
    }
    const backgroundImage =
      (this.props.config.backgroundImage && this.props.config.backgroundImageSelection) ||
      this.props.config.backgroundImage

    const themeConfig = this.props.theme || THEMES_HASH[config.theme]

    const light = themeConfig && themeConfig.light

    /* eslint-disable jsx-a11y/no-static-element-interactions */
    const selectionNode =
      !this.props.readOnly &&
      !!this.state.selectionAt &&
      document.getElementById('style-editor-button')

    return (
      <div className="section">
        <div
          ref={this.props.innerRef}
          id="export-container"
          className="export-container"
          onMouseUp={this.onMouseUp}
        >
          {this.props.loading ? (
            // TODO investigate removing these hard-coded values
            <div style={{ width: 876, height: 240 }}>
              <Spinner />
            </div>
          ) : (
            <div className="container">
              {config.windowControls ? (
                <WindowControls
                  titleBar={this.props.titleBar}
                  onTitleBarChange={this.props.onTitleBarChange}
                  theme={config.windowTheme}
                  code={this.props.children}
                  copyable={this.props.copyable}
                  light={light}
                />
              ) : null}
              <CodeMirror
                ref={this.props.editorRef}
                className={`CodeMirror__container window-theme__${config.windowTheme}`}
                value={this.props.children}
                options={options}
                onBeforeChange={this.onBeforeChange}
                onGutterClick={this.props.onGutterClick}
                onSelection={this.onSelection}
              />
              {config.watermark && <Watermark light={light} />}
              <div className="container-bg">
                <div className="white eliminateOnRender" />
                <div className="alpha eliminateOnRender" />
                <div className="bg" />
              </div>

              {/* TODO pass in this child as a prop to Carbon */}
              <WidthHandler
                innerRef={this.props.innerRef}
                onChange={this.props.updateWidth}
                onChangeComplete={this.props.updateWidthConfirm}
                paddingHorizontal={config.paddingHorizontal}
                paddingVertical={config.paddingVertical}
              />
            </div>
          )}
        </div>
        {selectionNode &&
          ReactDOM.createPortal(
            <SelectionEditor onChange={this.onSelectionChange} />,
            // TODO: don't use portal?
            selectionNode
          )}
        <style jsx>
          {`
            .container {
              position: relative;
              min-width: ${config.widthAdjustment ? '90px' : 'auto'};
              max-width: ${config.widthAdjustment ? '1024px' : 'none'};
              ${config.widthAdjustment ? '' : `width: ${config.width}px;`}
              padding: ${config.paddingVertical} ${config.paddingHorizontal};
            }

            .container :global(.watermark) {
              fill-opacity: 0.75;
              position: absolute;
              z-index: 2;
              bottom: calc(${config.paddingVertical} + 16px);
              right: calc(${config.paddingHorizontal} + 16px);
            }

            .container .container-bg {
              position: absolute;
              top: 0px;
              right: 0px;
              bottom: 0px;
              left: 0px;
            }

            .container .white {
              background: #fff;
              position: absolute;
              top: 0px;
              right: 0px;
              bottom: 0px;
              left: 0px;
            }

            .container .bg {
              ${this.props.config.backgroundMode === 'image'
                ? `background: url(${backgroundImage});
                    background-size: cover;
                    background-repeat: no-repeat;`
                : `background: ${this.props.config.backgroundColor || config.backgroundColor};
                    background-size: auto;
                    background-repeat: repeat;`}
              position: absolute;
              top: 0px;
              right: 0px;
              bottom: 0px;
              left: 0px;
            }

            .container .alpha {
              position: absolute;
              top: 0px;
              right: 0px;
              bottom: 0px;
              left: 0px;
              background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg==);
            }

            .container :global(.CodeMirror-gutters) {
              background-color: unset;
              border-right: none;
            }

            .container :global(.CodeMirror__container) {
              min-width: inherit;
              position: relative;
              z-index: 1;
              border-radius: 5px;
              ${config.dropShadow
                ? `box-shadow: 0 ${config.dropShadowOffsetY} ${config.dropShadowBlurRadius} rgba(0, 0, 0, 0.55)`
                : ''};
            }

            .container :global(.CodeMirror__container .CodeMirror) {
              height: auto;
              min-width: inherit;
              padding: 18px 18px;
              padding-left: 12px;
              ${config.lineNumbers ? 'padding-left: 12px;' : ''} border-radius: 5px;
              font-family: ${config.fontFamily}, monospace !important;
              font-size: ${config.fontSize};
              line-height: ${config.lineHeight};
              font-variant-ligatures: contextual;
              font-feature-settings: 'calt' 1;
              user-select: none;
            }

            .container :global(.CodeMirror-scroll),
            .container :global(.CodeMirror-hscrollbar) {
              overflow: hidden !important;
            }

            .container :global(.window-theme__sharp > .CodeMirror) {
              border-radius: 0px;
            }

            .container :global(.window-theme__bw > .CodeMirror) {
              border: 2px solid ${COLORS.SECONDARY};
            }

            .container :global(.window-controls + .CodeMirror__container > .CodeMirror) {
              padding-top: 48px;
            }

            .container :global(.CodeMirror-linenumber) {
              cursor: pointer;
            }

            .container :global(.CodeMirror-cursor) {
              visibility: ${this.props.readOnly ? 'hidden' : ''};
            }

            @media (max-width: 768px) {
              /* show cursor on mobile */
              .container :global([contenteditable='true']) {
                user-select: text;
              }
              .container {
                max-width: 480px;
              }
            }

            .section,
            .export-container {
              height: 100%;
              display: flex;
              flex-direction: column;
              justify-content: center;
              align-items: center;
              overflow: hidden;
              max-width: 100%;
            }
          `}
        </style>
      </div>
    )
  }
Chrome will only round to the nearest wave, causing visual inconsistencies
https://stackoverflow.com/questions/57559588/how-to-make-the-wavy-underline-extend-cover-all-the-characters-in-chrome