securingsincity / react-ace

React Ace Component
http://securingsincity.github.io/react-ace/
MIT License
4.08k stars 604 forks source link

How can I set the editor hight auto fit the content ? #415

Open hh54188 opened 6 years ago

hh54188 commented 6 years ago

Problem

I don't want to the editor have height, I want the editor show all content without scrollbar, height as the content's height

How should I set the editor's config or the css ?

Sample code to reproduce your issue

References

Progress on: #

Viijay-Kr commented 6 years ago

@hh54188 U can resize the editor height or pass height as prop to the ace editor to accomplish dynamic heights without scrollbar So if your component looks like this

  1. First approach
<AceEditor
  onLoad={onLoad}
  height={someInitialHeight}
  ...
/>
onLoad(editor){
  // Your editor options comes here
   editor.on('change', (arg, activeEditor) => {
      const aceEditor = activeEditor;
      const newHeight = aceEditor.getSession().getScreenLength() *
        (aceEditor.renderer.lineHeight + aceEditor.renderer.scrollBar.getWidth());
       aceEditor.container.style.height = `${newHeight}px`;
      aceEditor.resize();
    });
}

someInitialHeight could be anything depending upon your requirement

  1. Second approach
    <AceEditor
    onLoad={onLoad}
    height={getInitialHeight(this.editor)}
    ref={(editor)=>this.editor=editor}
    ...
    />
    getIntitialHeight(editor=){
    if(editor){
    let newHeight;
     newHeight = editor.getSession()
        .getScreenLength() *
        (editor.renderer.lineHeight + editor.renderer.scrollBar.getWidth());
      newHeight = newHeight > 70 ? newHeight : 70;
      return `${newHeight}px`;
    }
    return someInitialHeight
    }

    I hope this answers your question!

bmdalex commented 6 years ago

@securingsincity @Vijayk93

tried this and doesn't work for me; editor keeps the same size

Bizarrus commented 6 years ago

You can use the Stylesheet value inherit or the 100% value :)

Sample:

    <AceEditor height="inherit" />
    <AceEditor height="100%" />
nightwing commented 6 years ago

100% will fit the parent, to fit the content use maxLines and minLInes options of ace as shown in https://ace.c9.io/demo/autoresize.html

Viijay-Kr commented 6 years ago

@Bugaa92 Can u create a pen or fiddle so that we can test this?

adesurirey commented 6 years ago

Don't set any height and use maxLines={Infinity} to make the editor height fit to your content and disable vertical scrolling

hiteshsahu commented 5 years ago

maxLines={Infinity}

This actually worked for me

bluepeter commented 5 years ago

Unfortunately, this does not work in the "Split" mode https://github.com/securingsincity/react-ace/blob/master/docs/Split.md ... anyone have ideas on how to achieve the same thing in Split view?

danztran commented 3 years ago

You can achieve auto height in Split view by calculating editor height. Not perfect, but it works. This is an example with disabled wrap, you can achieve with enabled wrap too, but it needs extra handling.

import React, { useEffect, useMemo } from 'react';

type RequestDiffProps = {
  values: string[];
  setValues: (values: string[]) => void;
};

const RequestDiff = ({ values, setValues }: RequestDiffProps) => {
  const fontSize = 13;
  const height = useMemo(() => {
    const aceLine = document.getElementsByClassName('ace_line')?.[1];
    const lineHeight = aceLine?.clientHeight || fontSize + 5;
    const max = Math.max(...values.map(e => e.split(/\r\n|\r|\n/).length));
    const newHeight = max * lineHeight + 5;
    return newHeight;
  }, [values]);

  // force re-mount on browser resize 
  // so Diff component can discards all caching and re-render itself.
  useEffect(() => {
    const onResize = () => {
      setValues([]);
      setValues(values);
    };
    window.addEventListener('resize', onResize);
    return () => {
      window.removeEventListener('resize', onResize);
    };
  }, [values, setValues]);

  if (values.length === 0) {
    return <div />;
  }

  return (
    <Diff
      width="auto"
      mode="yaml"
      theme="tomorrow_night"
      fontSize={fontSize}
      editorProps={{}}
      height={`${height}px`}
      tabSize={2}
      highlightActiveLine={false}
      wrapEnabled={false}
      style={{
        borderRadius: '5px',
      }}
      setOptions={{
        useWorker: false,
        printMargin: false,
      }}
      readOnly
      value={values}
      onChange={v => setValues(v)}
    />
  );
};
eyedean commented 2 years ago

Note that maxLines={Infinity} doesn't work when either of enableSnippets or enableBasicAutocompletion or enableLiveAutocompletion is true.

siddacool commented 1 year ago

@hh54188 U can resize the editor height or pass height as prop to the ace editor to accomplish dynamic heights without scrollbar So if your component looks like this

  1. First approach
<AceEditor
  onLoad={onLoad}
  height={someInitialHeight}
  ...
/>
onLoad(editor){
  // Your editor options comes here
   editor.on('change', (arg, activeEditor) => {
      const aceEditor = activeEditor;
      const newHeight = aceEditor.getSession().getScreenLength() *
        (aceEditor.renderer.lineHeight + aceEditor.renderer.scrollBar.getWidth());
       aceEditor.container.style.height = `${newHeight}px`;
      aceEditor.resize();
    });
}

someInitialHeight could be anything depending upon your requirement

  1. Second approach
    <AceEditor
  onLoad={onLoad}
  height={getInitialHeight(this.editor)}
  ref={(editor)=>this.editor=editor}
  ...
/>
getIntitialHeight(editor=){
  if(editor){
  let newHeight;
     newHeight = editor.getSession()
        .getScreenLength() *
        (editor.renderer.lineHeight + editor.renderer.scrollBar.getWidth());
      newHeight = newHeight > 70 ? newHeight : 70;
      return `${newHeight}px`;
 }
 return someInitialHeight
}

I hope this answers your question!

This worked for me.

Here is a reusable component that i have created

import React from 'react';
import AceEditor from 'react-ace';

import 'ace-builds/src-noconflict/mode-sass';
import 'ace-builds/src-noconflict/theme-github';
import 'ace-builds/src-noconflict/ext-language_tools';

const getInitialHeight = ({ value, minHeight, maxHeight, cellHeight }) => {
  const allLines = value.split(/\r\n|\n/);
  const totalLines = allLines.length;
  let heightRaw = totalLines * cellHeight;

  heightRaw = heightRaw < minHeight ? minHeight : heightRaw;

  heightRaw = heightRaw > maxHeight ? maxHeight : heightRaw;

  return `${heightRaw}px`;
};

const CodeEditor = ({
  value = '',
  fontSize = 14,
  onChange = () => {},
  onLoad = () => {},
  placeholder = '',
  showGutter = true,
  highlightActiveLine = true,
  showLineNumbers = true,
  tabSize = 2,
  name = '',
  disabled = false,
  minHeight = 100,
  maxHeight = 1500,
  cellHeight = 18,
}) => {

  const onAceEditorInit = (editor) => {
    editor.on('change', (_arg, activeEditor) => {
      const aceEditor = activeEditor;
      let newHeight =
        aceEditor.getSession().getScreenLength() *
        (aceEditor.renderer.lineHeight +
          aceEditor.renderer.scrollBar.getWidth());

      newHeight = newHeight < minHeight ? minHeight : newHeight;

      newHeight = newHeight > maxHeight ? maxHeight : newHeight;

      aceEditor.container.style.height = `${newHeight + 20}px`;

      aceEditor.resize();
    });

    onLoad(editor);
  };

  return (
    <div>
      <AceEditor
        height={getInitialHeight({
          value,
          minHeight,
          cellHeight,
          maxHeight,
        })}
        width="100%"
        placeholder={placeholder}
        mode="sass"
        theme="github"
        name={name}
        onLoad={onAceEditorInit}
        onChange={onChange}
        fontSize={fontSize}
        showPrintMargin={true}
        showGutter={showGutter}
        highlightActiveLine={highlightActiveLine}
        value={value}
        setOptions={{
          enableBasicAutocompletion: false,
          enableLiveAutocompletion: false,
          enableSnippets: false,
          showLineNumbers,
          tabSize,
          readOnly: disabled,
        }}
      />
    </div>
  );
};

export default CodeEditor;