mondaycom / vibe

🎨 Official monday.com UI resources for application development in React.js
https://vibe.monday.com
434 stars 316 forks source link

[Bug]: MondayEditableHeader => How to change value prop programmatically #2461

Open ohabash opened 2 weeks ago

ohabash commented 2 weeks ago

Vibe version

"monday-ui-react-core": "^2.134.1",

Describe the bug

I dont know if this is a React question or a Monday UI question. Look at this reproduction 1

I am using EditableHeading

When you edit the field - a discard button appears. how can i change the value of the editableHeader in this example?

Expected behavior

This discard function in this example (also seen in reproduction) should setValue(val); which would change the value in the frontend.

import { EditableHeading, Label } from 'monday-ui-react-core';
import { useState, useEffect } from 'react';

export declare enum HeadingTypes {
  h1 = 'h1',
  h2 = 'h2',
  h3 = 'h3',
  h4 = 'h4',
  h5 = 'h5',
  h6 = 'h6',
}
type HeadingTypeValues = `${HeadingTypes}`;

export interface Props {
  val: string;
  type: HeadingTypeValues;
  save: (val: string) => void;
}

export const Field = ({ val, type, save }: Props) => {
  const [edits, setEdits] = useState('');
  const [value, setValue] = useState(val);

  useEffect(() => {
    setValue(val);
  }, [val]);

  function editVal(name: string) {
    console.log(`🚀 => Field => editVal => name:`, name);
    setEdits(name);
  }

  function discard() {
    setEdits('');
    setValue(val);
  }

  return (
    <div className='block relative'>
      <EditableHeading
        type={(EditableHeading as any).types[type]}
        value={value}
        onChange={editVal}
      />
      {edits.length > 0 && (
        <div className='actions absolute right-3 top-3 flex text-xs'>
          <Label
            className='cursor-pointer opacity-90 hover:opacity-100'
            text='Discard'
            color={Label.colors.DARK}
            onClick={discard}
          />
        </div>
      )}
    </div>
  );
};

Steps to reproduce

  1. go to link https://playcode.io/2018514
  2. type something in field
  3. try to discard edits
  4. note that the discard function does not return the value to default

Reproduction example link

https://playcode.io/2018514

System Info

System:
    OS: macOS 14.1.2
    CPU: (8) arm64 Apple M1 Pro
    Memory: 71.81 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.9.0 - ~/.nvm/versions/node/v20.9.0/bin/node
    npm: 10.1.0 - ~/.nvm/versions/node/v20.9.0/bin/npm
  Browsers:
    Brave Browser: 121.1.62.153
    Chrome: 129.0.6668.90
    Safari: 17.1.2
  npmPackages:
    monday-ui-react-core: ^2.134.1 => 2.134.1 
    react: 18.3.1 => 18.3.1 


### Additional context, Screenshots

_No response_
sahilpatel2712 commented 2 weeks ago

When an edit occurs, only the edits value changes, while the value variable remains unchanged. As a result, when the discard function is called, the setValue function tries to set the same string, which is why React doesn't update the state or re-render the component. This causes the value on the front end to remain unchanged.

you can update your code as belove

import { useState, useEffect } from 'react';

export declare enum HeadingTypes {
  h1 = 'h1',
  h2 = 'h2',
  h3 = 'h3',
  h4 = 'h4',
  h5 = 'h5',
  h6 = 'h6',
}
type HeadingTypeValues = `${HeadingTypes}`;

export interface Props {
  val: string;
  type: HeadingTypeValues;
  save: (val: string) => void;
}

export const Field = ({ val, type, save }: Props) => {
  const [edits, setEdits] = useState('');
  const [value, setValue] = useState(val);

  useEffect(() => {
    setValue(val); 
  }, [val]);

  function editVal(name: string) {
    console.log(`🚀 => Field => editVal => name:`, name);
    setEdits(name);
    setValue(name); // Update the value state when the field is being edited
  }

  function discard() {
    setEdits('');
    setValue(val);
  }

  return (
    <div className='block relative'>
      <EditableHeading
        type={(EditableHeading as any).types[type]}
        value={value} 
        onChange={editVal}
      />
      {edits.length > 0 && (
        <div className='actions absolute right-3 top-3 flex text-xs'>
          <Label
            className='cursor-pointer opacity-90 hover:opacity-100'
            text='Discard'
            color={Label.colors.DARK}
            onClick={discard}
          />
        </div>
      )}
    </div>
  );
};