PromucFlow_constructor/app/client/src/utils/UseComposeRef.ts

53 lines
1.1 KiB
TypeScript
Raw Normal View History

feat: multi-line input and auto-resize textarea (#19141) ## Description Features:- 1. Created a new AutoResizeTextArea component in the editorComponents. Textarea does not increase its height on adding text, but it increases its scroll height. To accommodate Auto Height with the textarea/Multi-line InputWidget, I have created a new TextArea component which changes its height when its content changes based on its scrollHeight. This is done by creating another hidden similar proxy Textarea with contents equal to the widget's value, and whenever this value changes we run a layout effect that sets the main text area height equal to the scrollHeight of the proxy textarea. 2. Added a new configuration `Multi-line` for InputWidget in the Data-Type which will decide whether to replace the `input` element with `textarea`. Currently, the way to decide whether we should display a textarea or not is based on whether widget's height is greater than 8 rows or not. To fix it, I added a proper configuration which will user to select whether he/she wants a Single-line input or Multi-line textarea. 3. Replaced the label of `Text` configuration to `Single-line` which remains a simple `input` element as before. Changed the label of the Text configuration to Single-line in contrast with Multi-line. 4. Migration Added migration number 75 for the InputWidgetsV2. Used the same previous logic to detect whether the input type should be multiple-line or not and set the `inputType` to `MULTI_LINE_TEXT` if it's true. 5. Changed a lot of CSS styling in Input components (Currency and Phone too) so that they look similar to other components like DatePicker and Select. Currently the input component take containers height which is different from other components. 6. The onSubmit behaviour of the Multi-line input has also changed. Now the line-break will happen on Enter and submit will be triggered on Cmd + Enter. 7. Added an updateHook in the Input widget which when selected the Multi-line input will set its dynamic height property to AutoHeight. Fixes #19655 Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video ## Type of change - New feature (non-breaking change which adds functionality) ## How Has This Been Tested? - Manual - Jest ### Test Plan https://github.com/appsmithorg/TestSmith/issues/2151 ### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) ## Checklist: ### Dev activity - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag ### QA activity: - [x] Test plan has been approved by relevant developers - [x] Test plan has been peer reviewed by QA - [ ] Cypress test cases have been added and approved by either SDET or manual QA - [ ] Organized project review call with relevant stakeholders after Round 1/2 of QA - [ ] Added Test Plan Approved label after reveiwing all Cypress test Co-authored-by: Apple <nandan@thinkify.io> Co-authored-by: Parthvi Goswami <parthvigoswami@Parthvis-MacBook-Pro.local>
2023-01-17 13:16:35 +00:00
import * as React from "react";
// basically Exclude<React.ClassAttributes<T>["ref"], string>
type UserRef<T> =
| ((instance: T | null) => void)
| React.RefObject<T>
| null
| undefined;
type Writable<T> = { -readonly [P in keyof T]: T[P] };
const updateRef = <T>(ref: NonNullable<UserRef<T>>, value: T | null) => {
if (typeof ref === "function") {
ref(value);
chore: add blank line eslint rule (#36369) ## Description Added ESLint rule to force blank lines between statements. Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.All" ### :mag: Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!CAUTION] > 🔴 🔴 🔴 Some tests have failed. > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/10924926728> > Commit: 34f57714a1575ee04e94e03cbcaf95e57a96c86c > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10924926728&attempt=1&selectiontype=test&testsstatus=failed&specsstatus=fail" target="_blank">Cypress dashboard</a>. > Tags: @tag.All > Spec: > The following are new failures, please fix them before merging the PR: <ol> > <li>cypress/e2e/Regression/ClientSide/Anvil/AnvilModal_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts</ol> > <a href="https://internal.appsmith.com/app/cypress-dashboard/identified-flaky-tests-65890b3c81d7400d08fa9ee3?branch=master" target="_blank">List of identified flaky tests</a>. > <hr>Wed, 18 Sep 2024 16:33:36 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No --------- Co-authored-by: Valera Melnikov <valera@appsmith.com>
2024-09-18 16:35:28 +00:00
feat: multi-line input and auto-resize textarea (#19141) ## Description Features:- 1. Created a new AutoResizeTextArea component in the editorComponents. Textarea does not increase its height on adding text, but it increases its scroll height. To accommodate Auto Height with the textarea/Multi-line InputWidget, I have created a new TextArea component which changes its height when its content changes based on its scrollHeight. This is done by creating another hidden similar proxy Textarea with contents equal to the widget's value, and whenever this value changes we run a layout effect that sets the main text area height equal to the scrollHeight of the proxy textarea. 2. Added a new configuration `Multi-line` for InputWidget in the Data-Type which will decide whether to replace the `input` element with `textarea`. Currently, the way to decide whether we should display a textarea or not is based on whether widget's height is greater than 8 rows or not. To fix it, I added a proper configuration which will user to select whether he/she wants a Single-line input or Multi-line textarea. 3. Replaced the label of `Text` configuration to `Single-line` which remains a simple `input` element as before. Changed the label of the Text configuration to Single-line in contrast with Multi-line. 4. Migration Added migration number 75 for the InputWidgetsV2. Used the same previous logic to detect whether the input type should be multiple-line or not and set the `inputType` to `MULTI_LINE_TEXT` if it's true. 5. Changed a lot of CSS styling in Input components (Currency and Phone too) so that they look similar to other components like DatePicker and Select. Currently the input component take containers height which is different from other components. 6. The onSubmit behaviour of the Multi-line input has also changed. Now the line-break will happen on Enter and submit will be triggered on Cmd + Enter. 7. Added an updateHook in the Input widget which when selected the Multi-line input will set its dynamic height property to AutoHeight. Fixes #19655 Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video ## Type of change - New feature (non-breaking change which adds functionality) ## How Has This Been Tested? - Manual - Jest ### Test Plan https://github.com/appsmithorg/TestSmith/issues/2151 ### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) ## Checklist: ### Dev activity - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag ### QA activity: - [x] Test plan has been approved by relevant developers - [x] Test plan has been peer reviewed by QA - [ ] Cypress test cases have been added and approved by either SDET or manual QA - [ ] Organized project review call with relevant stakeholders after Round 1/2 of QA - [ ] Added Test Plan Approved label after reveiwing all Cypress test Co-authored-by: Apple <nandan@thinkify.io> Co-authored-by: Parthvi Goswami <parthvigoswami@Parthvis-MacBook-Pro.local>
2023-01-17 13:16:35 +00:00
return;
}
(ref as Writable<typeof ref>).current = value;
};
// Compose 2 refs and give a single entry ref to
// attach to dom node
// Very useful when you want to forward ref and
// at the same time use a ref internally
const useComposedRef = <T extends HTMLElement>(
libRef: React.MutableRefObject<T | null>,
userRef: UserRef<T>,
) => {
const prevUserRef = React.useRef<UserRef<T>>();
return React.useCallback(
(instance: T | null) => {
libRef.current = instance;
if (prevUserRef.current) {
updateRef(prevUserRef.current, null);
}
prevUserRef.current = userRef;
if (!userRef) {
return;
}
updateRef(userRef, instance);
},
[userRef],
);
};
export default useComposedRef;