<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ryan Munil Lee</title>
    <description>The latest articles on DEV Community by Ryan Munil Lee (@thewatchmaker).</description>
    <link>https://dev.to/thewatchmaker</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F579343%2F7a009702-9ebf-486c-90a8-119a658755d2.png</url>
      <title>DEV Community: Ryan Munil Lee</title>
      <link>https://dev.to/thewatchmaker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thewatchmaker"/>
    <language>en</language>
    <item>
      <title>How to limit input length or lines in React-codemirror</title>
      <dc:creator>Ryan Munil Lee</dc:creator>
      <pubDate>Fri, 03 Mar 2023 17:47:28 +0000</pubDate>
      <link>https://dev.to/thewatchmaker/how-to-limit-input-length-or-lines-in-react-codemirror-5bcg</link>
      <guid>https://dev.to/thewatchmaker/how-to-limit-input-length-or-lines-in-react-codemirror-5bcg</guid>
      <description>&lt;p&gt;Codemirror is a powerful library that allows users to integrate a production-ready code editor into their projects. It’s a huge library with great thorough documentation, but it’s not something you can read in one sitting. &lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR;
&lt;/h2&gt;

&lt;p&gt;How to limit the length of doc:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lengthLimit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// NOTE: limiting the length to 100 characters.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;newDoc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CodeMirror&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;EditorState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;changeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lengthLimit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source &lt;a href="https://codesandbox.io/s/react-codemirror-example-codemirror-6-forked-kylrmk?file=/src/App.tsx" rel="noopener noreferrer"&gt;[1]&lt;/a&gt;, &lt;a href="https://github.com/uiwjs/react-codemirror/issues/371" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, this is how you limit line numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleLengthLimit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// doc will only update with the newDoc’s line number &amp;lt;= 10&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;newDoc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CodeMirror&lt;/span&gt;
      &lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;                  
          &lt;span class="nx"&gt;EditorState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;changeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handleLengthLimit&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;                      
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  In-depth
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/uiwjs/react-codemirro" rel="noopener noreferrer"&gt;React-codemirror&lt;/a&gt; is the most widely used React component for Codemirror. It uses Codemirror 6 behind the scene. However, it has lots of known limitations because Codemirror does not behave in a React way. (It was there before React.)&lt;/p&gt;

&lt;p&gt;As of Mar, 2023, React-codemirror editor is currently a &lt;a href="https://reactjs.org/docs/uncontrolled-components.html" rel="noopener noreferrer"&gt;uncontrolled component&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;So when most of React Developer would want to achieve something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;User input -&amp;gt; update input state -&amp;gt; mutate input state using useMemo or useEffect -&amp;gt; update input state -&amp;gt; rerender with thew new input&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The above wouldn’t work since the component is uncontrolled. So the work around is going to be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;User input -&amp;gt; intercept input and do your stuff with EditorState.changeFilter or EditorState.transactionFilter -&amp;gt; update state -&amp;gt; rerender&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re using it for a production feature at your work. I highly recommend you to do a DIY React component by following &lt;a href="https://www.codiga.io/blog/revisiting-codemirror-6-react-implementation/" rel="noopener noreferrer"&gt;this article.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About
&lt;/h2&gt;

&lt;p&gt;If you run into the same problem and this article helped you a bit please:&lt;br&gt;
 follow my &lt;a href="https://github.com/the-watchmaker" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt; &lt;br&gt;
And check out my silly project &lt;a href="https://github.com/the-watchmaker/typingbrain" rel="noopener noreferrer"&gt;Typing Brain&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What do you call a person who does full-stack dev, DevOps, UX design, product design and everything else?</title>
      <dc:creator>Ryan Munil Lee</dc:creator>
      <pubDate>Sat, 27 Mar 2021 21:41:27 +0000</pubDate>
      <link>https://dev.to/thewatchmaker/how-do-you-call-a-person-who-does-full-stack-dev-devops-ux-design-product-design-and-everything-else-40dg</link>
      <guid>https://dev.to/thewatchmaker/how-do-you-call-a-person-who-does-full-stack-dev-devops-ux-design-product-design-and-everything-else-40dg</guid>
      <description>&lt;h3&gt;
  
  
  "A Single Parent?"
&lt;/h3&gt;

&lt;p&gt;To the software you're building, you are basically a single mom or dad.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I came up with the product and designed the logo, branding, the landinage page, and UI. Then I designed the UX and did some user testings. Then I coded the frontend, backend, then some scripts to deploy them. I made Youtube videos and Instagram posts to promote it. Tomorrow morning, I have a sales Zoom call. I hope they buy it. I'm like a single mom, here."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But it sounds fun but not enough. We need something else that sounds more professional.&lt;/p&gt;

&lt;h3&gt;
  
  
  "A solopreneur?"
&lt;/h3&gt;

&lt;p&gt;But anybody can be a soloprenuer and don't have to work on a load balancer.&lt;/p&gt;

&lt;h3&gt;
  
  
  "A person who is not good at anything."
&lt;/h3&gt;

&lt;p&gt;Haha. Yes, I'm guilty. But come on.&lt;/p&gt;

&lt;h3&gt;
  
  
  "A generic small startup dev?"
&lt;/h3&gt;

&lt;p&gt;GSSD? I don't know. That's too long.&lt;/p&gt;

&lt;h3&gt;
  
  
  "I propose Watchmaker."
&lt;/h3&gt;

&lt;p&gt;I still like to call myself a craftsman. Watchmakers were the heroes of craftsmanship back in the days. &lt;/p&gt;

&lt;p&gt;Watchmakers designed, made and sold watches from their workshop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1dxKLXEG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6gj42sgsptelffdfm1q1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1dxKLXEG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6gj42sgsptelffdfm1q1.jpg" alt="Alt Text" width="435" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you put a computer in front of that guy in the picture, I won't be able to distinguish myself from him.&lt;/p&gt;

&lt;p&gt;We are essentially the digital watchmakers.&lt;/p&gt;

&lt;p&gt;Yeah, let's call us watchmakers.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
