fix: auto height regression fixes (#18410)

* removed block and added flex consistent in the alignment case of left and right

* fixed radio group which broke because of display block

* default enabled auto height for every widget

* added reivew changes

* reverted the switch group style changes and added the check for Text widget background in the AutoHeightContainer

* changed the scroll helper text for containers

* reverted the default enable for all the widgets

* test: fixed DH flaky test (#18415)

fixed DH flaky test

* fix: auto height container computations (#18408)

* Fix auto height container computations

* fix: Invisible Widgets Overlap while switching back and forth between edit and preview modes in rare cases (#18398)

sort Space based on original position if dynamic positions are equal while generating tree

* fix: group widgets label alignment. (#18360)

* fix: group widgets label alignment.

* fix: switch and radio fix transform styles for auto height.

* feat: disable auto height limits for modal (#18386)

* added multi select back

* (WIP): Complete the dynamc height update logic

* (WIP): Dynamic height logic

* (WIP): Container computation logic, Next steps: Prevent reflow when resize is disabled. Fix logic of widgets randomly changing positions (Debug)

* Fix logic in container computations

* Integrate for PoC

* fixed the no initial load dynamic height updates

* Stop vertical resize and reflow when dynamic height is enabled for a widget

* added another container in text widget

* enabled dynamic height for container widgets

* removed dynamic height feature from list widget

* Fixed Button and Input components height increase

* added an experiment to overflow the content if maxHEight is less

* removed the ref of Textwidget by mistake, added it back

* fixed text widget height overflow problem with a little hack

* added long labels with text

* fixed the table scroll issue

* overflow fixed for json form widget

* added extra 8px height for Switch, Rating and Checkbox Height

* (WIP): Resolve issues

* (WIP): Fix widget padding issue

* added overflow container for Radio and Switch group widgets

* (WIP): Have modals work with dynamic height

* added the overlay and the handles

* added dragging behavior to the dots

* fixed the overlapping with the selection tool

* (WIP): Fix issues reported

* now we can update the property pane values back from overlay handles

* now we can update the property pane values back from overlay handles

* (WIP): Fix table widget

* Fix package.json

* Remove unit tests temporarily

* Fix unit test

* (WIP): Fix modal resize. Fix cursors. Fix border issue on non-resizable widgets

* fetch component heights using the requestAnimationFrame callback

* behavioural changes

* (WIP): Fix issues on the platform

* Update main container size appropriately

* more behavioural changes

* overlay now only be visible when hovering over the dots

* grid showing and widget reselecting

* added onfocus and onblur events to property pane listeners

* added onfocus and onblur events to property pane listeners

* added a range slider for min and max

* added demarcations for slider values

* (WIP): Fix platform workflows for dynamic height

* Fix issues with widgets

* Fix removed import

* - Add missing cypress files

* set the limits

* limit increase on change

* Fix z-index of min max limit indicators. Fix unused-vars warnings

* Fix Table Widget and Text Widget issues

* Fix: all the bugs in the bug master list for DH (#16268)

* changed the zindex for the signifiers

* showing signifiers only when the widget is selected

* made changes suggested by Momcilo

* activate the dots when the fields are active

* created a new centered dot handle

* removed overlays on focus and made the border more like deisgn

* handles on top of other widgets

* hide the overlay when multiple widgets are selected

* added a white border

* added a white border

* bug #15509 resolved

* changed the minDynamicHeightLimit to 2 instead of 4 to fix the Bug #15527

* removed the height auto fix from BaseInputComponent to fix the Bug #15388

* removed the condition to not ccalculate dynamic height when the row difference is less than 2 to fix the bug 15353

* made fixes for the bug #16307

* made fixes for the bug #16308

* made fixes for bug 16310

* made fixes for the bug #16402

* removed some log statements

* made fixes for the bug #16407

* fixed label problem found in the issue #16543

* made fixes for the issue #16547

* made fixes for the bug #16492

* redeploy

* (WIP): Fix to make this branch functional

* imported LabelWithTooltip back from design system

* signifier is now centered

* filled the signifier with primary color

* overlay hidden while dragging

* made the signifier dashed border also draggable

* Fix issue #16590 (#16798)

* set the limits to 4 rows

* replaced the static 40 value

* added signifiers for modal widget

* added signifiers for modal widget

* tried solving the scroll issue for widgets when there are limits

* solved the height problem using ResizeObserver

* (WIP): Fix maxDynamicHeight issue with container widgets:

* made the changes as per the review

* fixed the issue for input widget when label gets out of border

* hide text widget overflow options if auto height is enabled

* (WIP): In view mode, invisible widgets now donot take space (#16920)

* (WIP): In view mode, invisible widgets now donot take space

* (WIP): Enable the feature where invisible widgets in view mode don't take space to all widgets irrespective of the dynamic height feature

* Remove Replay conditional

* removed the scroll container for container type widgets

* removed the scroll container for container type widgets

* updated the hook to set overflow none for text widget

* fixed the should dynamic height logic to respect the min height limit

* Modal widget adheres to dynamic height (#16995)

* Modal widget adheres to dynamic height

* WIP: POC: fix dynamic height issues  (#16996)

Fix height less than 4 issue. Fix JSONForm adherence to min and max height

* POC: Dynamic height undo redo issue (#17085)

* Revert debouce timeout

* (WIP): Fix issue with undo-redo in dynamic height

* fix: Dynamic height issue fixes (#17153)

* Dynamic height issue fixes
==

- Fix issue where nested widgets did not ensure parent dynamic height updates
- Fix issue where Modal widget updates came in subsequent renders
- Fix issue where JSONForm collapses
- Fix performance issue for independent updates

* Use functions to get min and max dynamic height

* Fix issue where variable might have been undefined

* added the dynamic container into the deploy mode as well

* added overflow-x hidden when overflow-y is active in the dynamic height container

* fix: Dynamic height Issue fixes (#17204)

Fix preview mode invisible widgets. Fix Tabs widget dynamic height.

* removed a console.log statement

* removed the slider control file

* imported the LabelWithTooltip from the repo rather than ds

* word-break CSS rules added for Switch and Checkbox widget when Dynamic Height is enabled

* abstracted the check for dynamic height with limits enabled as isDynamicHeightWithLimitsEnabledForWidget

* abstracted the static value of 10 in dynamic height overlay to GridDefaults

* abstracted min and max dynamic height limits to getters

* fix: replaced all the refs for simpler widgets (#17353)

* replaced all the refs for simpler widgets

* removed the updateDynamicHeight from componentDidUpdate in BaseWidget

* added back lifecycle methods back to BaseWidget

* removed the contentRef from SwitchGroup and Table

* updating the height from the auto height with limits as well

* some hacks to make the limits work

* working solution

* used setTimeout to send an update to updateDynamicHeight from overlay update

* removed a log

* added requestanimationframe in settimeout

Co-authored-by: Ankur Singhal <ankursinghal@Ankurs-MacBook-Pro-2.local>
Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* Fix issues caused during merge

* Remove unneeded derived property

* removed more unnecessary code which should have been removed after removing the ref dependency

* fixed the maxDynamicHeight issue

* Fix issue where property configs were not being sent

* fix: Auto Height Feature - add selectors for tests (#17687)

Add selectors for auto height cypress tests

* fix: removed height auto default theme (#17415)

removed height auto css rule from the default theme

Co-authored-by: Ankur Singhal <ankursinghal@Ankurs-MacBook-Pro-2.local>

* fix: Auto Height Feature - Resolve issues and restructure code (#17686)

* Fix issues in dynamic height. Restructure code and reduce abstraction leaks

* Fix typescript issues

* Update based on review comments. Comment migrations, as a cyclic import is causing the jest tests to fail.

* Remove unused imports

* Decrease code nesting

* added the base styles for the overlay like position and z-index in its styled component css

* used the isDynamicHeightEnabled prop to set the height of SwitchGroup and RadioGroup widgets from 32px to 100% in case of inline mode

* fix: Auto Height - Resolve issues (#17737)

* Fix Tabs Widget showTabs toggle based auto height. Revert removal of BaseWidget code. Remove box-intersect and use a bruteforce algorithm. Add base logic for having containers collapse due to hidden child widgets

* Hide scroll contents and overflow property pane controls when dynamic height is enabled

* Removed the class property expectedHeight from BaseWidget as it is not useful in the overlay logic after some changes

* fixed the left alignment issue of label in the rich text editor by adding some styles applied only when the dynamic height is enabled

* fixed the input field stretching issue in case of Dynamic height by adding some CSS styles when isDynamicHeight is true

* Fix failing modal widget cypress tests

* Fix issue with scrollContents and Tabs Widget defaulTab

* added a little bit padding of 4px to the right of scroll container of dynamic height with limit

* Add test locators for resize handles

* removed the dynamic height logic from the table widget

* fix: Auto-Height invisible widgets (#17849)

* Fix issue where invisible widgets were still taking space

* Make sure to collapse only if dynamic height is enabled

* Fix issues with reflow (not the invisible widgets)

* Fix container min height issues

* Fix reflow with original bottom and top values. Testing needed

* Fix invisible widgets

* fix: enabled dynamic height for stat box widget (#17971)

enabled dynamic height for stat box widget

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: added a min height to rich text editor so that it does not collapse (#17970)

added a min height to rich text editor so that it does not collapse

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* Fix issue with resizing auto height widget

* Add helper text to educate users regarding the scroll disconnect in WYSIWYG

* fix: Auto Height Fixes (#18111)

AUTO HEIGHT FIXES

- Fix JSONForm height discrepancy
- Fix issue where widgets moved below the other
- Fix droptarget height after parent container resize

* fix: sliced up the DynamicHeightOverlay component a little bit (#18100)

* sliced up the DynamicHeightOverlay component a little bit

* more refactoring

* more refactoring

* used release event emitter and refactored more

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: rich text editor center alignment issue (#18142)

* removed the center alignment from rich text editor

* dummy commit

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: old DSL container collapse (#18160)

* Fix issue where old containers from old DSLs used to collapse when auto height was enabled

* Fix issue where old containers don't allow new widgets to be added when auto height is enabled, this is because the shouldScrollContents is undefined

* fix: input widgets issue (#18172)

fixed the auto height not working issue

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: preview deploy mode (#18174)

fixed the preview and deploy mode

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: auto height limits label intersection with handle dot (#18186)

fixed the position of the limits label to the right so that it will not intersect with the handle dot

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: auto height limits rich text editor min height (#18187)

decrease the min height of the RTE so that it does not have the boundary issue with the max limit when auto height with limits is enabled

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: grammatical error in the help text (#18188)

changed react to reacts in the helpText of the dynamic height property in the proeprty pane

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: auto height tabs double scroll (#18210)

solved the issue by disabling the scroll for the child canvas widget in the tabs widget

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: auto height limits resizing (#18213)

* fixed the auto height limits resizing issue

* made the auto height overlay independent of isResizing and used its own property to show the grid

* some more refactoring

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* dummy commit

* fix: old apps container issue (#18255)

filtered out the widgets which are detached from layout

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: fixing auto height in childless containers. (#18263)

fixing auto height in childless containers.

* task: Dynamic height reflow fixes in Branch (#18244)

dynamic height reflow fixes

* fix: compact label issue and min and max limits numeric input (#18282)

fixed compact label issue and turned min and max limits to numeric input

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: LabelWithTooltip help icon fix

* fix: NaN and min limit for min and max (#18284)

* fixed compact label issue and turned min and max limits to numeric input

* fixed NaN and set min to be 4

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: validation issues for min max (#18286)

* fixed compact label issue and turned min and max limits to numeric input

* fixed NaN and set min to be 4

* validations start working min max

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* added a full stop to container scroll helper text

* validations start working min max

* dummy commit

* feat: stop resizing auto height widgets vertically because of Drag n Drop Reflow (#18267)

* reflow fixes

* stop resizing auto height widgets vertically because of Drag n Drop Reflow

* feat: Analytics for Dynamic height (#18279)

* Fix canvas min height issue and invisible widgets issue and remove logs and fix issue where widgets overlapped when coming back from preview mode to edit mode

* Fix issue with containers not respecting auto height and decreasing height

* Fix issue with modal widget not hugging contents, and container widgets never become visible after going invisible

* Fix issue where existing containers don't have correct min height for child canvas

* fix: canvasLevelsReducers test (#18301)

fixed the canvasLevelsReducers test

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: removed auto height min max config from widget features (#18316)

removed auto height min max config from widget features

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: Fixing Modal Height updates (#18317)

Fixing Modal Height updates

* fix: text widget background auto height (#18319)

added background color of Text widget back to the auto height container

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* test: cypress tests for auto height (#17676)

* Added tests for dynamic height

* updated tests for another usecase

* moved locators into commonfile

* updated common method

* added tests for some more widgets

* Added tests for jsonForm / Form widget

* Updated the test

* updated test for multiple text widgets

* updated test with few more usecases

* updated the dsl

* updated tests for text change

* updated tests based on new changes

* updated cypress test fixes

* fix: auto height container merge poc wrt release (#18334)

updated the poc wrt PR already merged in the release regarding the auto height container

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: renamed auto height overlay components and added some tests (#18333)

* renamed auto height overlay components and added some tests

* replaced the 10 value with GridDefaults

* avoiding event to reach drop target

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* updated tests

* Merge all code into one branch

* Fix failing AutoHeightcontainer test

* fix: Fix reflow computations which were causing widget overlap (#18300)

* Fix reflow computations which were causing widget overlap

* Fix issues with parent container height and overlapping widgets

* Remove console logs

* Revert comment

* Fix issues related to reflow of containers

* feat: Making getEffectedBoxes a Recursive function in autoHeight Reflow (#18336)

Making getEffectedBoxes a Recursive function in autoHeight Reflow

* Return null for invisible widgets from withWidgetProps

* Remove duplicate import

Co-authored-by: rahulramesha <71900764+rahulramesha@users.noreply.github.com>

* Remove missed console log

* fix: Label position gets deselected on selecting already selected option (#18298)

* fix: Label position gets deselected on selecting the already selected value

* Added migration for Currency & Phone input widgets

* simplify migration function using a utility

* combine conditions

* Increments LATEST_PAGE_VERSION

* Update DynamicHeight_Visibility_spec.js

updated a check wrt auto height

* Handling Modals for canvas size calculations

* fix: migrate label position test failing issue (#18365)

fixed migrate label postition test failing issue

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* removed the two unwanted imports from DSLMigrations to fix client build

* fix: Auto height zero and limits issue (#18366)

fixed the auto height zero and limits issue

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* fix: Auto height regression issues (#18367)

* Fix auto height regression issues #18367

* feat: auto height migrations (#18368)

Add auto height migrations

* Increase file caching size

* Use manual array for list of auto height enabled widgets

* Fix cypress test dsl versions

* Revert changes to shouldUpdateHeightDynamically

* Update test results based on code changes

* Marginally increase the workbox file size cache

* review comment incorporated for test spec

* Update container auto height property on drop

* Disable auto height with limits for modal

Co-authored-by: Ankur Singhal <ankur@appsmith.com>
Co-authored-by: rahulramesha <rahul@appsmith.com>
Co-authored-by: Abhinav Jha <zatanna@Abhinavs-iMac.lan>
Co-authored-by: Ankur Singhal <ankursinghal@Ankurs-MacBook-Pro-2.local>
Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>
Co-authored-by: Ashok Kumar M <35134347+marks0351@users.noreply.github.com>
Co-authored-by: rahulramesha <71900764+rahulramesha@users.noreply.github.com>
Co-authored-by: Albin <albin@appsmith.com>
Co-authored-by: Aswath K <aswath.sana@gmail.com>
Co-authored-by: NandanAnantharamu <67676905+NandanAnantharamu@users.noreply.github.com>
Co-authored-by: Apple <nandan@thinkify.io>

* chore: Moved height property to General section (#18402)

* fix: Height property is moved to General section

* Logs an Error if section is not General

* fix: Cypress

* enabled auto height for all the widgets except json form

* removes accidentally committed files

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>

* disabled default auto height for input widgets and select widgets and datepicker widget

* feat: Disable auto height for widgets in List Widget (#18381)

* Remove auto height for container Inside List widget

* remove unneccessary changes

* disable feature at generalConfig instead of firstConfig

* add todo comment

* skipped the get min limit tests

* fixed AutoHeightLimitHandleDot tests

* Updated cypress tests for regression changes

* update visual tests for widget layout

Co-authored-by: Ankur Singhal <ankurrsinghal@gmail.com>
Co-authored-by: NandanAnantharamu <67676905+NandanAnantharamu@users.noreply.github.com>
Co-authored-by: Abhinav Jha <abhinav@appsmith.com>
Co-authored-by: rahulramesha <71900764+rahulramesha@users.noreply.github.com>
Co-authored-by: Arsalan Yaldram <arsalanyaldram0211@outlook.com>
Co-authored-by: rahulramesha <rahul@appsmith.com>
Co-authored-by: Abhinav Jha <zatanna@Abhinavs-iMac.lan>
Co-authored-by: Ankur Singhal <ankursinghal@Ankurs-MacBook-Pro-2.local>
Co-authored-by: Ashok Kumar M <35134347+marks0351@users.noreply.github.com>
Co-authored-by: Albin <albin@appsmith.com>
Co-authored-by: Aswath K <aswath.sana@gmail.com>
Co-authored-by: Apple <nandan@thinkify.io>
Co-authored-by: Parthvi Goswami <parthvigoswami@Parthvis-MacBook-Pro.local>
This commit is contained in:
ankurrsinghal 2022-11-25 00:10:06 +05:30 committed by GitHub
parent 32eebcbd43
commit c287b4d781
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 1160 additions and 522 deletions

View File

@ -0,0 +1,170 @@
{
"dsl": {
"widgetName": "MainContainer",
"backgroundColor": "none",
"rightColumn": 4896,
"snapColumns": 64,
"detachFromLayout": true,
"widgetId": "0",
"topRow": 0,
"bottomRow": 1290,
"containerStyle": "none",
"snapRows": 125,
"parentRowSpace": 1,
"type": "CANVAS_WIDGET",
"canExtend": true,
"version": 69,
"minHeight": 1292,
"dynamicTriggerPathList": [],
"parentColumnSpace": 1,
"dynamicBindingPathList": [],
"leftColumn": 0,
"children": [
{
"boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}",
"widgetName": "Container1",
"borderColor": "#E0DEDE",
"isCanvas": true,
"displayName": "Container",
"iconSVG": "/static/media/icon.1977dca3370505e2db3a8e44cfd54907.svg",
"searchTags": [
"div",
"parent",
"group"
],
"topRow": 6,
"bottomRow": 16,
"parentRowSpace": 10,
"type": "CONTAINER_WIDGET",
"hideCard": false,
"shouldScrollContents": true,
"animateLoading": true,
"parentColumnSpace": 11.9375,
"leftColumn": 16,
"dynamicBindingPathList": [
{
"key": "borderRadius"
},
{
"key": "boxShadow"
}
],
"children": [
{
"boxShadow": "none",
"widgetName": "Canvas1",
"displayName": "Canvas",
"topRow": 0,
"bottomRow": 100,
"parentRowSpace": 1,
"type": "CANVAS_WIDGET",
"canExtend": false,
"hideCard": true,
"minHeight": 100,
"parentColumnSpace": 1,
"leftColumn": 0,
"dynamicBindingPathList": [
{
"key": "borderRadius"
},
{
"key": "accentColor"
}
],
"children": [
{
"isVisible": true,
"animateLoading": true,
"labelTextSize": "0.875rem",
"options": [
{
"label": "Blue",
"value": "BLUE"
},
{
"label": "Green",
"value": "GREEN"
},
{
"label": "Red",
"value": "RED"
}
],
"defaultSelectedValues": [
"BLUE"
],
"isDisabled": false,
"isInline": true,
"isRequired": false,
"labelText": "Label",
"labelPosition": "Top",
"labelAlignment": "left",
"labelWidth": 5,
"widgetName": "CheckboxGroup1",
"version": 2,
"minDynamicHeight": 4,
"maxDynamicHeight": 9000,
"dynamicHeight": "AUTO_HEIGHT",
"type": "CHECKBOX_GROUP_WIDGET",
"hideCard": false,
"isDeprecated": false,
"displayName": "Checkbox Group",
"key": "px8e5kndcb",
"iconSVG": "/static/media/icon.ecb3847950c4515966ef642a32758afb.svg",
"widgetId": "li1gq4tzny",
"renderMode": "CANVAS",
"accentColor": "{{appsmith.theme.colors.primaryColor}}",
"borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}",
"isLoading": false,
"parentColumnSpace": 3.42578125,
"parentRowSpace": 10,
"leftColumn": 18,
"rightColumn": 41,
"topRow": 0,
"bottomRow": 6,
"parentId": "tbezx4vcxu",
"dynamicBindingPathList": [
{
"key": "accentColor"
},
{
"key": "borderRadius"
}
]
}
],
"key": "49f4d77rwd",
"isDeprecated": false,
"rightColumn": 286.5,
"detachFromLayout": true,
"widgetId": "tbezx4vcxu",
"accentColor": "{{appsmith.theme.colors.primaryColor}}",
"containerStyle": "none",
"isVisible": true,
"version": 1,
"parentId": "57nv0ufxq1",
"renderMode": "CANVAS",
"isLoading": false,
"borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}"
}
],
"borderWidth": "1",
"key": "g4phrz9m3l",
"backgroundColor": "#FFFFFF",
"isDeprecated": false,
"rightColumn": 40,
"dynamicHeight": "AUTO_HEIGHT",
"widgetId": "57nv0ufxq1",
"containerStyle": "card",
"isVisible": true,
"version": 1,
"parentId": "0",
"renderMode": "CANVAS",
"isLoading": false,
"borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}",
"maxDynamicHeight": 9000,
"minDynamicHeight": 10
}
]
}
}

View File

@ -13,7 +13,7 @@
"parentRowSpace": 1,
"type": "CANVAS_WIDGET",
"canExtend": true,
"version": 64,
"version": 69,
"minHeight": 1292,
"dynamicTriggerPathList": [],
"parentColumnSpace": 1,
@ -21,48 +21,42 @@
"leftColumn": 0,
"children": [
{
"boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}",
"isVisible": true,
"backgroundColor": "#FFFFFF",
"widgetName": "Container1",
"containerStyle": "card",
"borderColor": "#E0DEDE",
"isCanvas": true,
"displayName": "Container",
"iconSVG": "/static/media/icon.1977dca3370505e2db3a8e44cfd54907.svg",
"searchTags": [
"div",
"parent",
"group"
],
"topRow": 0,
"bottomRow": 40,
"parentRowSpace": 10,
"type": "CONTAINER_WIDGET",
"hideCard": false,
"shouldScrollContents": false,
"borderWidth": "1",
"boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}",
"animateLoading": true,
"parentColumnSpace": 9.96875,
"leftColumn": 21,
"dynamicBindingPathList": [
{
"key": "borderRadius"
},
{
"key": "boxShadow"
}
],
"children": [
{
"boxShadow": "none",
"isVisible": true,
"widgetName": "Canvas1",
"displayName": "Canvas",
"topRow": 0,
"bottomRow": 400,
"parentRowSpace": 1,
"version": 1,
"detachFromLayout": true,
"type": "CANVAS_WIDGET",
"canExtend": false,
"hideCard": true,
"minHeight": 400,
"isDeprecated": false,
"displayName": "Canvas",
"key": "49f4d77rwd",
"containerStyle": "none",
"canExtend": false,
"children": [],
"minHeight": 100,
"widgetId": "tbezx4vcxu",
"renderMode": "CANVAS",
"boxShadow": "none",
"borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}",
"accentColor": "{{appsmith.theme.colors.primaryColor}}",
"isLoading": false,
"parentColumnSpace": 1,
"parentRowSpace": 1,
"leftColumn": 0,
"rightColumn": 286.5,
"topRow": 0,
"bottomRow": 100,
"parentId": "57nv0ufxq1",
"dynamicBindingPathList": [
{
"key": "borderRadius"
@ -70,100 +64,45 @@
{
"key": "accentColor"
}
],
"children": [
{
"isVisible": true,
"minDynamicHeight": 0,
"maxDynamicHeight": 0,
"dynamicHeight": "FIXED",
"animateLoading": true,
"labelTextSize": "0.875rem",
"options": [
{
"label": "Blue",
"value": "BLUE"
},
{
"label": "Green",
"value": "GREEN"
},
{
"label": "Red",
"value": "RED"
}
],
"defaultSelectedValues": [
"BLUE"
],
"isDisabled": false,
"isInline": true,
"isRequired": false,
"labelText": "Label",
"labelPosition": "Left",
"labelAlignment": "left",
"labelWidth": 5,
"widgetName": "CheckboxGroup1",
"version": 2,
"type": "CHECKBOX_GROUP_WIDGET",
"hideCard": false,
"isDeprecated": false,
"displayName": "Checkbox Group",
"key": "y571au2ld4",
"iconSVG": "/static/media/icon.ecb3847950c4515966ef642a32758afb.svg",
"widgetId": "3fcb34jd6s",
"renderMode": "CANVAS",
"accentColor": "{{appsmith.theme.colors.primaryColor}}",
"borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}",
"isLoading": false,
"parentColumnSpace": 3.42578125,
"parentRowSpace": 10,
"leftColumn": 18,
"rightColumn": 51,
"topRow": 34,
"bottomRow": 38,
"parentId": "u0aukt373p",
"dynamicBindingPathList": [
{
"key": "accentColor"
},
{
"key": "borderRadius"
}
]
}
],
"key": "05fpu0xal1",
"isDeprecated": false,
"rightColumn": 239.25,
"detachFromLayout": true,
"widgetId": "u0aukt373p",
"accentColor": "{{appsmith.theme.colors.primaryColor}}",
"containerStyle": "none",
"isVisible": true,
"version": 1,
"parentId": "pik2udpz5v",
"renderMode": "CANVAS",
"isLoading": false,
"borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}"
]
}
],
"borderWidth": "1",
"key": "bwh1jtvajo",
"backgroundColor": "#FFFFFF",
"isDeprecated": false,
"rightColumn": 45,
"dynamicHeight": "FIXED",
"widgetId": "pik2udpz5v",
"containerStyle": "card",
"isVisible": true,
"version": 1,
"parentId": "0",
"minDynamicHeight": 10,
"maxDynamicHeight": 9000,
"dynamicHeight": "AUTO_HEIGHT",
"shouldScrollContents": true,
"searchTags": [
"div",
"parent",
"group"
],
"type": "CONTAINER_WIDGET",
"hideCard": false,
"isDeprecated": false,
"displayName": "Container",
"key": "g4phrz9m3l",
"iconSVG": "/static/media/icon.1977dca3370505e2db3a8e44cfd54907.svg",
"isCanvas": true,
"widgetId": "57nv0ufxq1",
"renderMode": "CANVAS",
"isLoading": false,
"borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}",
"maxDynamicHeight": 0,
"minDynamicHeight": 0
"isLoading": false,
"parentColumnSpace": 11.9375,
"parentRowSpace": 10,
"leftColumn": 20,
"rightColumn": 44,
"topRow": 23,
"bottomRow": 33,
"parentId": "0",
"dynamicBindingPathList": [
{
"key": "borderRadius"
},
{
"key": "boxShadow"
}
]
}
]
}

View File

@ -0,0 +1,281 @@
{
"dsl": {
"widgetName": "MainContainer",
"backgroundColor": "none",
"rightColumn": 1280,
"snapColumns": 64,
"detachFromLayout": true,
"widgetId": "0",
"topRow": 0,
"bottomRow": 1230,
"containerStyle": "none",
"snapRows": 125,
"parentRowSpace": 1,
"type": "CANVAS_WIDGET",
"canExtend": true,
"version": 69,
"minHeight": 1240,
"parentColumnSpace": 1,
"dynamicTriggerPathList": [],
"dynamicBindingPathList": [],
"leftColumn": 0,
"children": [
{
"labelTextSize": "0.875rem",
"boxShadow": "none",
"widgetName": "Statbox1",
"backgroundColor": "white",
"rightColumn": 21,
"dynamicHeight": "FIXED",
"widgetId": "3sii8uhhjs",
"topRow": 17,
"bottomRow": 33,
"parentRowSpace": 10,
"isVisible": true,
"type": "STATBOX_WIDGET",
"parentId": "0",
"isLoading": false,
"parentColumnSpace": 19.8125,
"leftColumn": 5,
"borderRadius": "0px",
"children": [
{
"labelTextSize": "0.875rem",
"boxShadow": "none",
"widgetName": "Canvas1",
"rightColumn": 317,
"detachFromLayout": true,
"widgetId": "l752czyef7",
"containerStyle": "none",
"topRow": 0,
"bottomRow": 160,
"parentRowSpace": 1,
"isVisible": true,
"canExtend": false,
"type": "CANVAS_WIDGET",
"version": 1,
"parentId": "3sii8uhhjs",
"minHeight": 160,
"isLoading": false,
"parentColumnSpace": 1,
"leftColumn": 0,
"borderRadius": "0px",
"children": [
{
"boxShadow": "none",
"widgetName": "Text1",
"dynamicPropertyPathList": [
{
"key": "fontSize"
}
],
"topRow": 0.5,
"bottomRow": 4.5,
"type": "TEXT_WIDGET",
"overflow": "NONE",
"fontFamily": "System Default",
"dynamicTriggerPathList": [],
"leftColumn": 1.5,
"dynamicBindingPathList": [
{
"key": "text"
}
],
"text": "{{MockApi.data.users[0].id}}",
"labelTextSize": "0.875rem",
"rightColumn": 37.5,
"textAlign": "LEFT",
"dynamicHeight": "FIXED",
"widgetId": "4mtayc9eas",
"isVisible": true,
"fontStyle": "BOLD",
"textColor": "#999999",
"version": 1,
"parentId": "l752czyef7",
"isLoading": false,
"borderRadius": "0px",
"maxDynamicHeight": 9000,
"fontSize": "0.75rem",
"minDynamicHeight": 4
},
{
"boxShadow": "none",
"widgetName": "Text2",
"dynamicPropertyPathList": [
{
"key": "fontSize"
}
],
"topRow": 5.5,
"bottomRow": 9.5,
"type": "TEXT_WIDGET",
"overflow": "NONE",
"fontFamily": "System Default",
"leftColumn": 1.5,
"text": "2.6 M",
"labelTextSize": "0.875rem",
"rightColumn": 37.5,
"textAlign": "LEFT",
"dynamicHeight": "FIXED",
"widgetId": "ii2tk6m48f",
"isVisible": true,
"fontStyle": "BOLD",
"textColor": "#231F20",
"version": 1,
"parentId": "l752czyef7",
"isLoading": false,
"borderRadius": "0px",
"maxDynamicHeight": 9000,
"fontSize": "1.5rem",
"minDynamicHeight": 4
},
{
"boxShadow": "none",
"widgetName": "Text3",
"dynamicPropertyPathList": [
{
"key": "fontSize"
}
],
"topRow": 10,
"bottomRow": 14,
"type": "TEXT_WIDGET",
"overflow": "NONE",
"fontFamily": "System Default",
"leftColumn": 1.5,
"text": "21% more than last month",
"labelTextSize": "0.875rem",
"rightColumn": 37.5,
"textAlign": "LEFT",
"dynamicHeight": "FIXED",
"widgetId": "ptbhksx9p1",
"isVisible": true,
"fontStyle": "BOLD",
"textColor": "#03B365",
"version": 1,
"parentId": "l752czyef7",
"isLoading": false,
"borderRadius": "0px",
"maxDynamicHeight": 9000,
"fontSize": "0.75rem",
"minDynamicHeight": 4
},
{
"labelTextSize": "0.875rem",
"boxShadow": "none",
"widgetName": "IconButton1",
"rightColumn": 61,
"iconName": "arrow-top-right",
"buttonColor": "#03B365",
"dynamicPropertyPathList": [
{
"key": "borderRadius"
}
],
"widgetId": "x35ni1hugn",
"topRow": 3,
"bottomRow": 11,
"isVisible": true,
"type": "ICON_BUTTON_WIDGET",
"version": 1,
"parentId": "l752czyef7",
"isLoading": false,
"borderRadius": "9999px",
"leftColumn": 45,
"buttonVariant": "PRIMARY",
"isDisabled": false
}
]
}
],
"maxDynamicHeight": 9000,
"minDynamicHeight": 4
},
{
"isVisible": true,
"backgroundColor": "#FFFFFF",
"widgetName": "Container1",
"containerStyle": "card",
"borderColor": "#E0DEDE",
"borderWidth": "1",
"boxShadow": "{{appsmith.theme.boxShadow.appBoxShadow}}",
"animateLoading": true,
"children": [
{
"isVisible": true,
"widgetName": "Canvas2",
"version": 1,
"detachFromLayout": true,
"type": "CANVAS_WIDGET",
"hideCard": true,
"isDeprecated": false,
"displayName": "Canvas",
"key": "vhu8oytsk7",
"containerStyle": "none",
"canExtend": false,
"children": [],
"minHeight": 580,
"widgetId": "p7wc0hnc0o",
"renderMode": "CANVAS",
"boxShadow": "none",
"borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}",
"accentColor": "{{appsmith.theme.colors.primaryColor}}",
"isLoading": false,
"parentColumnSpace": 1,
"parentRowSpace": 1,
"leftColumn": 0,
"rightColumn": 286.5,
"topRow": 0,
"bottomRow": 580,
"parentId": "q00fefx59g",
"dynamicBindingPathList": [
{
"key": "borderRadius"
},
{
"key": "accentColor"
}
]
}
],
"version": 1,
"minDynamicHeight": 10,
"maxDynamicHeight": 12,
"dynamicHeight": "FIXED",
"shouldScrollContents": true,
"searchTags": [
"div",
"parent",
"group"
],
"type": "CONTAINER_WIDGET",
"hideCard": false,
"isDeprecated": false,
"displayName": "Container",
"key": "fcexgq4024",
"iconSVG": "/static/media/icon.1977dca3370505e2db3a8e44cfd54907.svg",
"isCanvas": true,
"widgetId": "q00fefx59g",
"renderMode": "CANVAS",
"borderRadius": "{{appsmith.theme.borderRadius.appBorderRadius}}",
"isLoading": false,
"parentColumnSpace": 11.9375,
"parentRowSpace": 10,
"leftColumn": 22,
"rightColumn": 64,
"topRow": 3,
"bottomRow": 61,
"parentId": "0",
"dynamicBindingPathList": [
{
"key": "borderRadius"
},
{
"key": "boxShadow"
}
],
"dynamicTriggerPathList": []
}
]
}
}

View File

@ -14,7 +14,7 @@ describe("Dynamic Height Width validation with limits", function() {
cy.get("[data-cy='t--auto-height-overlay-handles-min']").trigger(
"mouseover",
);
cy.contains("Min-Height: 4 rows");
cy.contains("Min-Height: 10 rows");
cy.get("[data-cy='t--auto-height-overlay-handles-min']").should(
"be.visible",
);
@ -29,7 +29,7 @@ describe("Dynamic Height Width validation with limits", function() {
cy.get("[data-cy='t--auto-height-overlay-handles-max']").trigger(
"mouseover",
);
cy.contains("Max-Height: 40 rows");
cy.contains("Max-Height: 12 rows");
//cy.checkMaxDefaultValue(commonlocators.maxHeight,"40")
//cy.testJsontext(commonlocators.maxHeight, "60");
cy.get("[data-cy='t--auto-height-overlay-handles-max']").should(

View File

@ -1,4 +1,4 @@
const dsl = require("../../../../fixtures/dynamicHeightContainerdsl.json");
const dsl = require("../../../../fixtures/dynamicHeightContainerCheckboxdsl.json");
const commonlocators = require("../../../../locators/commonlocators.json");
describe("Dynamic Height Width validation", function() {
@ -6,9 +6,9 @@ describe("Dynamic Height Width validation", function() {
cy.addDsl(dsl);
cy.wait(3000); //for dsl to settle
cy.openPropertyPane("containerwidget");
cy.changeLayoutHeight(commonlocators.autoHeight);
//cy.changeLayoutHeight(commonlocators.autoHeight);
cy.openPropertyPane("checkboxgroupwidget");
cy.changeLayoutHeight(commonlocators.autoHeight);
//cy.changeLayoutHeight(commonlocators.autoHeight);
cy.get(".t--widget-containerwidget")
.invoke("css", "height")
.then((height) => {

View File

@ -85,7 +85,7 @@ describe("Dynamic Height Width validation", function() {
cy.get(".t--widget-propertypane-toggle")
.first()
.click({ force: true });
cy.changeLayoutHeight(commonlocators.autoHeightWithLimits);
//cy.changeLayoutHeight(commonlocators.autoHeightWithLimits);
//cy.checkMinDefaultValue(commonlocators.minHeight,"4")
//cy.checkMaxDefaultValue(commonlocators.maxHeight,"24")
cy.changeLayoutHeight(commonlocators.autoHeight);

View File

@ -2,8 +2,10 @@ const dsl = require("../../../../fixtures/multipleContainerdsl.json");
const commonlocators = require("../../../../locators/commonlocators.json");
describe("Dynamic Height Width validation for multiple container", function() {
it("Validate change in auto height width with multiple containers", function() {
before(() => {
cy.addDsl(dsl);
});
it("Validate change in auto height width with multiple containers", function() {
cy.wait(3000); //for dsl to settle
cy.openPropertyPaneWithIndex("containerwidget", 0);
cy.changeLayoutHeight(commonlocators.fixed);
@ -14,6 +16,7 @@ describe("Dynamic Height Width validation for multiple container", function() {
cy.openPropertyPane("checkboxgroupwidget");
cy.changeLayoutHeight(commonlocators.fixed);
cy.changeLayoutHeight(commonlocators.autoHeight);
cy.wait(2000);
cy.get(".t--widget-containerwidget")
.eq(0)
.invoke("css", "height")
@ -26,15 +29,16 @@ describe("Dynamic Height Width validation for multiple container", function() {
.eq(2)
.invoke("css", "height")
.then((iheight) => {
cy.get(commonlocators.addOption).click({ force: true });
cy.get(".t--widget-checkboxgroupwidget")
.invoke("css", "height")
.then((checkboxheight) => {
cy.get(commonlocators.addOption).click({ force: true });
cy.wait("@updateLayout").should(
"have.nested.property",
"response.body.responseMeta.status",
200,
);
cy.wait(3000);
cy.get(".t--widget-checkboxgroupwidget")
.invoke("css", "height")
.then((newcheckboxheight) => {

View File

@ -1,52 +1,52 @@
const commonlocators = require("../../../../locators/commonlocators.json");
const dsl = require("../../../../fixtures/invisibleWidgetdsl.json");
describe("Dynamic Height Width validation for Visibility", function () {
before(() => {
cy.addDsl(dsl);
});
it("Validating visbility/invisiblity of widget with dynamic height feature", function () {
//changing the Text Name and verifying
cy.wait(3000);
cy.openPropertyPane("containerwidget");
cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight);
cy.openPropertyPaneWithIndex("inputwidgetv2", 0);
cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight);
cy.openPropertyPaneWithIndex("inputwidgetv2", 1);
cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight);
describe("Dynamic Height Width validation for Visibility", function() {
before(() => {
cy.addDsl(dsl);
});
it("Validating visbility/invisiblity of widget with dynamic height feature", function() {
//changing the Text Name and verifying
cy.wait(3000);
cy.openPropertyPane("containerwidget");
cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight);
cy.openPropertyPaneWithIndex("inputwidgetv2", 0);
cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight);
cy.openPropertyPaneWithIndex("inputwidgetv2", 1);
cy.changeLayoutHeightWithoutWait(commonlocators.autoHeight);
cy.get(".t--widget-containerwidget")
.invoke("css", "height")
.then((theight) => {
cy.get(commonlocators.checkboxIndicator).click({ force: true });
cy.get(".t--widget-containerwidget")
.invoke("css", "height")
.then((theight) => {
cy.get(commonlocators.checkboxIndicator).click({ force: true });
cy.get(".t--widget-containerwidget")
.invoke("css", "height")
.then((tnewheight) => {
expect(theight).to.equal(tnewheight);
cy.get("label:Contains('On')").should("not.be.enabled");
});
});
cy.PublishtheApp();
.invoke("css", "height")
.then((tnewheight) => {
expect(theight).to.equal(tnewheight);
cy.get("label:Contains('On')").should("not.be.enabled");
});
});
cy.PublishtheApp();
cy.get(".t--widget-containerwidget")
.invoke("css", "height")
.then((theight) => {
cy.get(".bp3-control-indicator").click({ force: true });
cy.wait(2000);
cy.get(".t--widget-containerwidget")
.invoke("css", "height")
.then((theight) => {
cy.get(".bp3-control-indicator").click({ force: true });
cy.wait(2000);
cy.get(".t--widget-containerwidget")
.invoke("css", "height")
.then((tnewheight) => {
expect(theight).to.not.equal(tnewheight);
cy.get("label:Contains('On')").should("not.exist");
cy.get("label:Contains('Off')").should("be.visible");
cy.get(".bp3-control-indicator").click({ force: true });
cy.wait(2000);
cy.get(".t--widget-containerwidget")
.invoke("css", "height")
.then((tonheight) => {
expect(tonheight).to.not.equal(tnewheight);
cy.get("label:Contains('Off')").should("not.exist");
cy.get("label:Contains('On')").should("be.visible");
});
});
});
});
.invoke("css", "height")
.then((tnewheight) => {
expect(theight).to.not.equal(tnewheight);
cy.get("label:Contains('On')").should("not.exist");
cy.get("label:Contains('Off')").should("be.visible");
cy.get(".bp3-control-indicator").click({ force: true });
cy.wait(2000);
cy.get(".t--widget-containerwidget")
.invoke("css", "height")
.then((tonheight) => {
expect(tonheight).to.not.equal(tnewheight);
cy.get("label:Contains('Off')").should("not.exist");
cy.get("label:Contains('On')").should("be.visible");
});
});
});
});
});

View File

@ -1,7 +1,8 @@
describe("Visual regression tests", () => {
// for any changes in UI, update the screenshot in snapshot folder, to do so:
// 1. Delete the required screenshot which you want to update
// 2. Run test in headless mode with any browser (to maintain same resolution in CI)
// 2. Run test in headless mode with chrome (to maintain same resolution in CI)
// command: "npx cypress run --spec cypress/integration/Smoke_TestSuite/ClientSideTests/VisualTests/WidgetsLayout_spec.js --browser chrome"
// 3. New screenshot will be generated in the snapshot folder
it("Verify SwitchGroup inline enable/disbale", () => {
@ -18,7 +19,7 @@ describe("Visual regression tests", () => {
//Unchecking & verify snap
cy.get(".t--property-control-inline input")
.uncheck({ force: true })
.wait(200)
.wait(2000)
.should("not.be.checked");
cy.get("[data-testid=switchgroup-container]").matchImageSnapshot(
"inlineDisabled",
@ -27,7 +28,7 @@ describe("Visual regression tests", () => {
//Checking again & verify snap
cy.get(".t--property-control-inline input")
.check({ force: true })
.wait(200)
.wait(2000)
.should("be.checked");
cy.get("[data-testid=switchgroup-container]").matchImageSnapshot(
@ -37,7 +38,7 @@ describe("Visual regression tests", () => {
//Unchecking again & verify snap
cy.get(".t--property-control-inline input")
.uncheck({ force: true })
.wait(200)
.wait(2000)
.should("not.be.checked");
// taking screenshot of app home page in edit mode
cy.get("[data-testid=switchgroup-container]").matchImageSnapshot(

View File

@ -1,4 +1,5 @@
const dsl = require("../../../../../fixtures/StatboxDsl.json");
const dsl1 = require("../../../../../fixtures/dynamicHeightStatboxdsl.json");
const explorer = require("../../../../../locators/explorerlocators.json");
const data = require("../../../../../fixtures/example.json");
const widgetsPage = require("../../../../../locators/Widgets.json");
@ -87,9 +88,10 @@ describe("Statbox Widget Functionality", function() {
});
it("5. Verify Statbox can be placed inside another widget", () => {
cy.addDsl(dsl1);
cy.get(explorer.addWidget).click();
// placing statbox widget inside container widget
cy.dragAndDropToCanvas("containerwidget", { x: 500, y: 300 });
//cy.dragAndDropToCanvas("containerwidget", { x: 500, y: 300 });
cy.dragAndDropToWidget("statboxwidget", "containerwidget", {
x: 100,
y: 100,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1602,7 +1602,7 @@ Cypress.Commands.add("openPropertyPaneWithIndex", (widgetType, index) => {
Cypress.Commands.add("changeLayoutHeight", (locator) => {
cy.get(".t--property-control-height .remixicon-icon")
.should("be.visible")
.scrollIntoView()
.click({ force: true });
cy.get(locator).click({ force: true });
cy.wait("@updateLayout").should(
@ -1614,7 +1614,7 @@ Cypress.Commands.add("changeLayoutHeight", (locator) => {
Cypress.Commands.add("changeLayoutHeightWithoutWait", (locator) => {
cy.get(".t--property-control-height .remixicon-icon")
.should("be.visible")
.scrollIntoView()
.click({ force: true });
cy.get(locator).click({ force: true });
});

View File

@ -78,7 +78,10 @@ export default function AutoHeightContainer({
expectedHeight / GridDefaults.DEFAULT_GRID_ROW_HEIGHT,
);
const backgroundColor = widgetProps?.backgroundColor;
const backgroundColor =
widgetProps?.type === "TEXT_WIDGET"
? widgetProps?.backgroundColor
: undefined;
return (
<StyledAutoHeightContainer

View File

@ -1 +1,5 @@
export const OVERLAY_COLOR = "#F32B8B";
// During dragging we have to scale the size
// of the dot to increase its focus
export const OVERLAY_HANDLE_DOT_DRAGGING_SCALE = "1.67";

View File

@ -17,12 +17,18 @@ import AutoHeightLimitOverlayDisplay from "./ui/AutoHeightLimitOverlayDisplay";
import { useHoverState, usePositionedStyles } from "./hooks";
import { getSnappedValues } from "./utils";
import { useAutoHeightUIState } from "utils/hooks/autoHeightUIHooks";
import { LayersContext } from "constants/Layers";
const StyledAutoHeightOverlay = styled.div<{ isHidden: boolean }>`
interface StyledAutoHeightOverlayProps {
layerIndex: number;
isHidden: boolean;
}
const StyledAutoHeightOverlay = styled.div<StyledAutoHeightOverlayProps>`
width: 100%;
height: 100%;
position: absolute;
z-index: 3;
z-index: ${(props) => props.layerIndex};
pointer-events: none;
display: ${(props) => (props.isHidden ? "none" : "block")};
`;
@ -252,9 +258,12 @@ const AutoHeightOverlay: React.FC<AutoHeightOverlayProps> = memo(
topRow,
});
const { autoHeightWithLimitsOverlay } = React.useContext(LayersContext);
return (
<StyledAutoHeightOverlay
isHidden={isHidden}
layerIndex={autoHeightWithLimitsOverlay}
onClick={(e) => {
// avoid DropTarget handleFocus
e.stopPropagation();

View File

@ -10,13 +10,13 @@ describe("<AutoHeightLimitHandleDot />", () => {
const tree = renderer
.create(<AutoHeightLimitHandleDot isDragging={false} />)
.toJSON();
expect(tree).toHaveStyleRule("transform", "translateX(-50%) scale(1)");
expect(tree).toHaveStyleRule("transform", "translateX(-50%) scale( 1 )");
});
it("should have scale style set to 1.67 when isDragging is true", () => {
const tree = renderer
.create(<AutoHeightLimitHandleDot isDragging />)
.toJSON();
expect(tree).toHaveStyleRule("transform", "translateX(-50%) scale(1.67)");
expect(tree).toHaveStyleRule("transform", "translateX(-50%) scale( 1.67 )");
});
});

View File

@ -1,5 +1,5 @@
import styled from "styled-components";
import { OVERLAY_COLOR } from "../constants";
import { OVERLAY_COLOR, OVERLAY_HANDLE_DOT_DRAGGING_SCALE } from "../constants";
interface AutoHeightLimitHandleDotProps {
isDragging: boolean;
@ -12,7 +12,9 @@ const AutoHeightLimitHandleDot = styled.div<AutoHeightLimitHandleDotProps>`
width: 7px;
height: 7px;
transform: translateX(-50%)
scale(${(props) => (props.isDragging ? "1.67" : "1")});
scale(
${(props) => (props.isDragging ? OVERLAY_HANDLE_DOT_DRAGGING_SCALE : "1")}
);
border: 1px solid ${OVERLAY_COLOR};
background-color: ${OVERLAY_COLOR};
box-shadow: 0px 0px 0px 2px white;

View File

@ -320,17 +320,18 @@ export const BlueprintRadioSwitchGroupTransform = css<{
optionCount: number;
}>`
width: 100%;
height: 100%;
${({ alignment, inline, optionCount }) => `
display: ${
inline ? "inline-flex" : alignment === Alignment.RIGHT ? "block" : "flex"
};
${({ inline, optionCount }) => `
display: ${inline ? "inline-flex" : "flex"};
flex-direction: ${inline ? "row" : "column"};
align-items: ${inline ? "center" : "flex-start"};
${inline && "flex-wrap: wrap"};
justify-content: ${
optionCount > 1 ? `space-between` : inline ? `flex-start` : `center`
};
gap: 10px;
flex-grow: 1;
`}
${BlueprintControlTransform};
@ -341,42 +342,17 @@ export const BlueprintRadioSwitchGroupTransform = css<{
}
return "flex";
}};
width: ${({ alignment, inline }) => {
if (alignment === Alignment.RIGHT) {
return inline ? "auto" : "100%";
}
return "auto";
}};
align-items: center;
border: 1px solid transparent;
color: ${Colors.GREY_10};
line-height: 16px;
min-height: ${({ alignment }) =>
alignment === Alignment.RIGHT ? 23 : 30}px;
margin-top: ${({ alignment }) => (alignment === Alignment.RIGHT ? 7 : 0)}px;
margin-bottom: ${({
alignment,
height,
inline,
labelPosition,
optionCount,
}) => {
if (
alignment === Alignment.RIGHT &&
!inline &&
optionCount > 1 &&
height
) {
return Math.max(
(height -
(labelPosition === LabelPosition.Left ? 0 : 35) -
optionCount * 31) /
(optionCount - 1),
8,
);
} else {
return 0;
}
}}px;
&:last-child {
margin-bottom: 0;
}
.bp3-control-indicator {
margin-top: 0;
border: 1px solid ${Colors.GREY_5};

View File

@ -57,6 +57,8 @@ export const Layers = {
evaluationPopper: Indices.Layer3,
concurrentEditorWarning: Indices.Layer2,
manualUpgrade: Indices.Layer10,
autoHeightWithLimitsOverlay: Indices.Layer3,
};
export const tailwindLayers = {

View File

@ -167,4 +167,5 @@ export const DEFAULT_FONT_SIZE = THEMEING_TEXT_SIZES.base;
export const WidgetHeightLimits = {
MAX_HEIGHT_IN_ROWS: 9000,
MIN_HEIGHT_IN_ROWS: 4,
MIN_CANVAS_HEIGHT_IN_ROWS: 10,
};

View File

@ -239,6 +239,11 @@ function AppViewer(props: Props) {
[updateWidgetAutoHeightAction, dispatch],
);
const checkContainersForAutoHeightCallback = useCallback(
() => dispatch(checkContainersForAutoHeightAction()),
[checkContainersForAutoHeightAction],
);
return (
<ThemeProvider theme={lightTheme}>
<EditorContext.Provider
@ -249,7 +254,7 @@ function AppViewer(props: Props) {
syncUpdateWidgetMetaProperty: syncUpdateWidgetMetaPropertyCallback,
triggerEvalOnMetaUpdate: triggerEvalOnMetaUpdateCallback,
updateWidgetAutoHeight: updateWidgetAutoHeightCallback,
checkContainersForAutoHeight: checkContainersForAutoHeightAction,
checkContainersForAutoHeight: checkContainersForAutoHeightCallback,
}}
>
<WidgetGlobaStyles

View File

@ -38,6 +38,7 @@ import WidgetFactory from "utils/WidgetFactory";
import styled from "styled-components";
import { PropertyPaneTab } from "./PropertyPaneTab";
import { useSearchText } from "./helpers";
import { disableWidgetFeatures } from "utils/WidgetFeatures";
export const StyledSearchInput = React.memo(styled(SearchInput)`
position: sticky;
@ -262,8 +263,9 @@ function PropertyPaneView(
contentComponent={
isContentConfigAvailable ? (
<PropertyControlsGenerator
config={WidgetFactory.getWidgetPropertyPaneContentConfig(
config={disableWidgetFeatures(
widgetProperties.type,
widgetProperties.disabledWidgetFeatures,
)}
id={widgetProperties.widgetId}
panel={panel}

View File

@ -221,13 +221,14 @@ export function* undoRedoSaga(action: ReduxAction<UndoRedoPayload>) {
shouldReplay: false,
}),
);
if (isPropertyUpdate) {
yield put(generateAutoHeightLayoutTreeAction(true, false));
yield call(openPropertyPaneSaga, replay);
}
if (!isPropertyUpdate) {
yield call(postUndoRedoSaga, replay);
}
yield put(generateAutoHeightLayoutTreeAction(true, false));
break;
}
case ENTITY_TYPE.ACTION:

View File

@ -1,18 +1,13 @@
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
import { GridDefaults } from "constants/WidgetConstants";
import { groupBy } from "lodash";
import log from "loglevel";
import { AutoHeightLayoutTreeReduxState } from "reducers/entityReducers/autoHeightReducers/autoHeightLayoutTreeReducer";
import { CanvasLevelsReduxState } from "reducers/entityReducers/autoHeightReducers/canvasLevelsReducer";
import { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
import { call, put, select } from "redux-saga/effects";
import { shouldWidgetsCollapse } from "./helpers";
import { getMinHeightBasedOnChildren, shouldWidgetsCollapse } from "./helpers";
import { getWidgets } from "sagas/selectors";
import { getCanvasHeightOffset } from "selectors/editorSelectors";
import {
getAutoHeightLayoutTree,
getCanvasLevelMap,
} from "selectors/autoHeightSelectors";
import { getAutoHeightLayoutTree } from "selectors/autoHeightSelectors";
import { FlattenedWidgetProps } from "widgets/constants";
import {
getWidgetMaxAutoHeight,
@ -20,6 +15,8 @@ import {
isAutoHeightEnabledForWidget,
} from "widgets/WidgetUtils";
import { getChildOfContainerLikeWidget } from "./helpers";
import { getDataTree } from "selectors/dataTreeSelectors";
import { DataTree, DataTreeWidget } from "entities/DataTree/dataTreeFactory";
export function* dynamicallyUpdateContainersSaga() {
const start = performance.now();
@ -27,132 +24,158 @@ export function* dynamicallyUpdateContainersSaga() {
const stateWidgets: CanvasWidgetsReduxState = yield select(getWidgets);
const canvasWidgets: FlattenedWidgetProps[] | undefined = Object.values(
stateWidgets,
).filter((widget: FlattenedWidgetProps) => widget.type === "CANVAS_WIDGET");
const canvasLevelMap: CanvasLevelsReduxState = yield select(
getCanvasLevelMap,
);
).filter((widget: FlattenedWidgetProps) => {
const isCanvasWidget = widget.type === "CANVAS_WIDGET";
const parent = widget.parentId ? stateWidgets[widget.parentId] : undefined;
if (parent?.type === "LIST_WIDGET") return false;
if (!parent) return false;
return isCanvasWidget;
});
const dynamicHeightLayoutTree: AutoHeightLayoutTreeReduxState = yield select(
getAutoHeightLayoutTree,
);
const groupedByCanvasLevel = groupBy(
canvasWidgets,
(widget) => canvasLevelMap[widget.widgetId],
);
const levels = Object.keys(groupedByCanvasLevel)
.map((level) => parseInt(level, 10))
.sort((a, b) => b - a);
const updates: Record<string, number> = {};
const shouldCollapse: boolean = yield call(shouldWidgetsCollapse);
for (const level of levels) {
const canvasWidgetsAtThisLevel = groupedByCanvasLevel[`${level}`];
for (const canvasWidget of canvasWidgetsAtThisLevel) {
if (canvasWidget.parentId) {
const parentContainerWidget = stateWidgets[canvasWidget.parentId];
for (const canvasWidget of canvasWidgets) {
if (canvasWidget.parentId) {
// The parent widget of this canvas widget
const parentContainerWidget = stateWidgets[canvasWidget.parentId];
let bottomRow, topRow, originalBottomRow, originalTopRow;
if (dynamicHeightLayoutTree[parentContainerWidget.widgetId]) {
const layoutNode =
dynamicHeightLayoutTree[parentContainerWidget.widgetId];
bottomRow = layoutNode.bottomRow;
topRow = layoutNode.topRow;
originalBottomRow = layoutNode.originalBottomRow;
originalTopRow = layoutNode.originalTopRow;
} else {
bottomRow = parentContainerWidget.bottomRow;
topRow = parentContainerWidget.topRow;
// Skip this whole process if the parent is collapsed: Process:
// Get the DataTree
const dataTree: DataTree = yield select(getDataTree);
// Get this parentContainerWidget from the DataTree
const dataTreeWidget = dataTree[parentContainerWidget.widgetName];
// If the widget exists, is not visible and we can collapse widgets
if (
dataTreeWidget &&
(dataTreeWidget as DataTreeWidget).isVisible !== true &&
shouldCollapse
)
continue;
let bottomRow, topRow;
// If the parent exists in the layout tree
if (dynamicHeightLayoutTree[parentContainerWidget.widgetId]) {
// Get the tree node for the parent
const layoutNode =
dynamicHeightLayoutTree[parentContainerWidget.widgetId];
// Get all the dimensions from the tree node
bottomRow = layoutNode.bottomRow;
topRow = layoutNode.topRow;
} else {
// If it doesn't exist in the layout tree
// It is most likely a Modal Widget
// Use the dimensions as they exist in the widget.
bottomRow = parentContainerWidget.bottomRow;
topRow = parentContainerWidget.topRow;
}
// If this is a Modal widget or some other widget
// which is detached from layout
// use the value 0, as the starting point.
if (
parentContainerWidget.detachFromLayout &&
parentContainerWidget.height
) {
topRow = 0;
}
if (isAutoHeightEnabledForWidget(parentContainerWidget)) {
// Get the child we need to consider
// For a container widget, it will be the child canvas
// For a tabs widget, it will be the currently open tab's canvas
const childWidgetId:
| string
| undefined = yield getChildOfContainerLikeWidget(
parentContainerWidget,
);
// This can be different from the canvas widget in consideration
// For example, if this canvas widget in consideration
// is not the selected tab's canvas in a tabs widget
// we don't have to consider it at all
if (childWidgetId !== canvasWidget.widgetId) continue;
// Get the boundaries for possible min and max dynamic height.
const minDynamicHeightInRows = getWidgetMinAutoHeight(
parentContainerWidget,
);
const maxDynamicHeightInRows = getWidgetMaxAutoHeight(
parentContainerWidget,
);
// Default to the min height expected.
let maxBottomRow = minDynamicHeightInRows;
// For the child Canvas, use the value in pixels.
let canvasBottomRow = maxBottomRow;
// If this canvas has children
// we need to consider the bottom most child for the height
if (
Array.isArray(canvasWidget.children) &&
canvasWidget.children.length > 0
) {
let maxBottomRowBasedOnChildren: number = yield getMinHeightBasedOnChildren(
canvasWidget.widgetId,
{},
true,
dynamicHeightLayoutTree,
);
// Add a canvas extension offset
maxBottomRowBasedOnChildren += GridDefaults.CANVAS_EXTENSION_OFFSET;
// Set the canvas bottom row as a new variable with a new reference
canvasBottomRow = maxBottomRowBasedOnChildren + 0;
// For widgets like Tabs Widget, some of the height is occupied by the
// tabs themselves, the child canvas as a result has less number of rows available
// To accommodate for this, we need to increase the new height by the offset amount.
const canvasHeightOffset: number = getCanvasHeightOffset(
parentContainerWidget.type,
parentContainerWidget,
);
// Add the offset to the total height of the parent widget
maxBottomRowBasedOnChildren += canvasHeightOffset;
// Get the larger value between the minDynamicHeightInRows and bottomMostRowForChild
maxBottomRow = Math.max(maxBottomRowBasedOnChildren, maxBottomRow);
}
if (isAutoHeightEnabledForWidget(parentContainerWidget)) {
const childWidgetId:
| string
| undefined = yield getChildOfContainerLikeWidget(
parentContainerWidget,
);
if (childWidgetId !== canvasWidget.widgetId) continue;
let maxBottomRow = bottomRow - topRow;
if (
parentContainerWidget.detachFromLayout &&
parentContainerWidget.height
) {
topRow = 0;
bottomRow = Math.ceil(
parentContainerWidget.height /
GridDefaults.DEFAULT_GRID_ROW_HEIGHT,
);
// The following makes sure we stay within bounds
// If the new height is below the min threshold
if (maxBottomRow < minDynamicHeightInRows) {
maxBottomRow = minDynamicHeightInRows;
}
// If the new height is above the max threshold
if (maxBottomRow > maxDynamicHeightInRows) {
maxBottomRow = maxDynamicHeightInRows;
}
maxBottomRow = bottomRow;
}
canvasBottomRow =
Math.max(maxBottomRow, canvasBottomRow) *
GridDefaults.DEFAULT_GRID_ROW_HEIGHT;
let canvasBottomRow = canvasWidget.bottomRow;
if (
Array.isArray(canvasWidget.children) &&
canvasWidget.children.length > 0
) {
maxBottomRow = canvasWidget.children
.filter((widgetId) => !stateWidgets[widgetId].detachFromLayout)
.reduce((prev: number, next: string) => {
if (dynamicHeightLayoutTree[next].bottomRow > prev)
return dynamicHeightLayoutTree[next].bottomRow;
return prev;
}, 0);
maxBottomRow += GridDefaults.CANVAS_EXTENSION_OFFSET;
canvasBottomRow = maxBottomRow + 0;
// For widgets like Tabs Widget, some of the height is occupied by the
// tabs themselves, the child canvas as a result has less number of rows available
// To accommodate for this, we need to increase the new height by the offset amount.
const canvasHeightOffset: number = getCanvasHeightOffset(
parentContainerWidget.type,
parentContainerWidget,
);
maxBottomRow += canvasHeightOffset;
} else if (
!shouldCollapse &&
topRow === bottomRow &&
originalBottomRow !== undefined &&
originalTopRow !== undefined
) {
maxBottomRow = originalBottomRow - originalTopRow;
}
// Get the boundaries for possible min and max dynamic height.
const minDynamicHeightInRows = getWidgetMinAutoHeight(
parentContainerWidget,
);
const maxDynamicHeightInRows = getWidgetMaxAutoHeight(
parentContainerWidget,
);
// If the new height is below the min threshold
if (maxBottomRow < minDynamicHeightInRows) {
maxBottomRow = minDynamicHeightInRows;
}
// If the new height is above the max threshold
if (maxBottomRow > maxDynamicHeightInRows) {
maxBottomRow = maxDynamicHeightInRows;
}
if (
maxBottomRow !== bottomRow - topRow ||
canvasBottomRow !== canvasWidget.bottomRow
) {
if (!updates.hasOwnProperty(parentContainerWidget.widgetId)) {
updates[parentContainerWidget.widgetId] =
maxBottomRow * GridDefaults.DEFAULT_GRID_ROW_HEIGHT;
}
// If we have a new height to set and
// If the canvas for some reason doesn't have the correct bottomRow
if (
maxBottomRow !== bottomRow - topRow ||
canvasBottomRow !== canvasWidget.bottomRow
) {
if (!updates.hasOwnProperty(parentContainerWidget.widgetId)) {
updates[parentContainerWidget.widgetId] =
maxBottomRow * GridDefaults.DEFAULT_GRID_ROW_HEIGHT;
}
}
}
}
}
log.debug("Dynamic Height: Container Updates", { updates });
if (Object.keys(updates).length > 0) {
// TODO(abhinav): Make sure there are no race conditions or scenarios where these updates are not considered.
for (const widgetId in updates) {

View File

@ -56,21 +56,28 @@ export function* getMinHeightBasedOnChildren(
ignoreParent = false,
tree: AutoHeightLayoutTreeReduxState,
) {
// Starting with no height
let minHeightInRows = 0;
// Should we be able to collapse widgets
const shouldCollapse: boolean = yield shouldWidgetsCollapse();
// Get all widgets in the DSL
const stateWidgets: CanvasWidgetsReduxState = yield select(getWidgets);
const { children = [], parentId } = stateWidgets[widgetId];
// If we need to consider the parent height
if (parentId && !ignoreParent) {
let parentHeightInRows =
stateWidgets[parentId].bottomRow - stateWidgets[parentId].topRow;
// Get the parentHeight in rows
let parentHeightInRows = tree[parentId].bottomRow - tree[parentId].topRow;
// If the parent has changed so far.
if (changesSoFar.hasOwnProperty(parentId)) {
parentHeightInRows =
changesSoFar[parentId].bottomRow - changesSoFar[parentId].topRow;
}
// The canvas will be an extension smaller than the parent?
minHeightInRows = parentHeightInRows - GridDefaults.CANVAS_EXTENSION_OFFSET;
// If the canvas is empty return the parent's height in rows, without
// the canvas extension offset
if (!children.length) {
@ -85,13 +92,17 @@ export function* getMinHeightBasedOnChildren(
// We ignore widgets like ModalWidget which don't occupy parent's space.
// detachFromLayout helps us identify such widgets
if (detachFromLayout) continue;
// Get the child widget's dimenstions from the tree
const { bottomRow, topRow } = tree[childWidgetId];
// If this child has changed so far during computations
if (changesSoFar.hasOwnProperty(childWidgetId)) {
const collapsing =
changesSoFar[childWidgetId].bottomRow ===
changesSoFar[childWidgetId].topRow;
// If this child is collapsing, don't consider it
if (!(shouldCollapse && collapsing))
minHeightInRows = Math.max(
minHeightInRows,
@ -99,6 +110,7 @@ export function* getMinHeightBasedOnChildren(
);
// If we need to get the existing bottomRow from the state
} else {
// If this child is to collapse, don't consider it.
if (!(shouldCollapse && bottomRow === topRow))
minHeightInRows = Math.max(minHeightInRows, bottomRow);
}

View File

@ -34,6 +34,21 @@ import { CanvasLevelsReduxState } from "reducers/entityReducers/autoHeightReduce
import { getCanvasLevelMap } from "selectors/autoHeightSelectors";
import { getLayoutTree } from "./layoutTree";
/* TODO(abhinav)
hasScroll is no longer needed, as the only way we will be computing for hasScroll, is when we get the updates
from the Container computations saga. In container computations, we also compute the inner canvas height. So,
this becomes a duplicate run of pretty much the same code.
In most cases, when we run the getMinHeightBasedOnChildren, we add the CANVAS_EXTENSION_OFFSET and the offset
from the widget configuration. This means that we can DRY this by moving them into the getMinHeightBasedOnChildren function
The computations we do when a widget changes for its parent, is pretty much the same as the ones we do in container
computations saga, so we can potentially re-use that code.
Adding to widgetsToUpdate can be done using one function and shrink this saga by a large amount
/**
* Saga to update a widget's auto height
* When a widget changes in height, it must do the following
@ -273,6 +288,36 @@ export function* updateWidgetAutoHeightSaga() {
const parentContainerLikeWidget: FlattenedWidgetProps =
stateWidgets[parentCanvasWidget.parentId];
let minCanvasHeightInRows: number = yield getMinHeightBasedOnChildren(
parentCanvasWidget.widgetId,
changesSoFar,
true,
dynamicHeightLayoutTree,
);
// Add extra rows, this is to accommodate for padding and margins in the parent
minCanvasHeightInRows += GridDefaults.CANVAS_EXTENSION_OFFSET;
// Setting this in a variable, as this will be the total scroll height in the canvas.
const minCanvasHeightInPixels =
minCanvasHeightInRows * GridDefaults.DEFAULT_GRID_ROW_HEIGHT;
// We need to make sure that the canvas widget doesn't have
// any extra scroll, to this end, we need to add the `minHeight` update
// for the canvas widgets. Canvas Widgets are never updated in other flows
// As they simply take up whatever space the parent has, but this doesn't effect
// the `minHeight`, which leads to scroll if the `minHeight` is a larger value.
// Also, for canvas widgets, the values are in pure pixels instead of rows.
widgetsToUpdate[parentCanvasWidgetId] = [
{
propertyPath: "bottomRow",
propertyValue: minCanvasHeightInPixels,
},
{
propertyPath: "minHeight",
propertyValue: minCanvasHeightInPixels,
},
];
// Widgets need to consider changing heights, only if they have dynamic height
// enabled.
if (isAutoHeightEnabledForWidget(parentContainerLikeWidget)) {
@ -282,21 +327,11 @@ export function* updateWidgetAutoHeightSaga() {
parentContainerLikeWidget,
);
// Get the array of children ids.
// This cannot be [], because we came to this point due to an update
// caused by one of the children.
let minPossibleHeight: number = yield getMinHeightBasedOnChildren(
parentCanvasWidget.widgetId,
changesSoFar,
true,
dynamicHeightLayoutTree,
minHeightInRows = Math.max(
minHeightInRows,
minCanvasHeightInRows,
);
// Add extra rows, this is to accommodate for padding and margins in the parent
minPossibleHeight =
minPossibleHeight + GridDefaults.CANVAS_EXTENSION_OFFSET;
// For widgets like Tabs Widget, some of the height is occupied by the
// tabs themselves, the child canvas as a result has less number of rows available
// To accommodate for this, we need to increase the new height by the offset amount.
@ -304,11 +339,7 @@ export function* updateWidgetAutoHeightSaga() {
parentContainerLikeWidget.type,
parentContainerLikeWidget,
);
minPossibleHeight += canvasHeightOffset;
minHeightInRows = Math.max(minPossibleHeight, minHeightInRows);
// Setting this in a variable, as this will be the total scroll height in the canvas.
const maxBottomRow = minHeightInRows + 0;
minHeightInRows += canvasHeightOffset;
// Make sure we're not overflowing the max height bounds
const maxDynamicHeight = getWidgetMaxAutoHeight(
@ -317,25 +348,6 @@ export function* updateWidgetAutoHeightSaga() {
minHeightInRows = Math.min(maxDynamicHeight, minHeightInRows);
// We need to make sure that the canvas widget doesn't have
// any extra scroll, to this end, we need to add the `minHeight` update
// for the canvas widgets. Canvas Widgets are never updated in other flows
// As they simply take up whatever space the parent has, but this doesn't effect
// the `minHeight`, which leads to scroll if the `minHeight` is a larger value.
// Also, for canvas widgets, the values are in pure pixels instead of rows.
widgetsToUpdate[parentCanvasWidgetId] = [
{
propertyPath: "bottomRow",
propertyValue:
maxBottomRow * GridDefaults.DEFAULT_GRID_ROW_HEIGHT,
},
{
propertyPath: "minHeight",
propertyValue:
maxBottomRow * GridDefaults.DEFAULT_GRID_ROW_HEIGHT,
},
];
let layoutData =
dynamicHeightLayoutTree[parentContainerLikeWidget.widgetId];
@ -430,20 +442,21 @@ export function* updateWidgetAutoHeightSaga() {
}
}
// Let's consider the minimum Canvas Height
let maxCanvasHeight = CANVAS_DEFAULT_MIN_HEIGHT_PX;
let maxCanvasHeightInRows =
CANVAS_DEFAULT_MIN_HEIGHT_PX / GridDefaults.DEFAULT_GRID_ROW_HEIGHT;
// The same logic to compute the minimum height of the MainContainer
// Based on how many rows are being occuped by children.
const maxPossibleCanvasHeight: number = yield getMinHeightBasedOnChildren(
const maxPossibleCanvasHeightInRows: number = yield getMinHeightBasedOnChildren(
MAIN_CONTAINER_WIDGET_ID,
changesSoFar,
false,
true,
dynamicHeightLayoutTree,
);
maxCanvasHeight = Math.max(
maxPossibleCanvasHeight * GridDefaults.DEFAULT_GRID_ROW_HEIGHT,
maxCanvasHeight,
maxCanvasHeightInRows = Math.max(
maxPossibleCanvasHeightInRows,
maxCanvasHeightInRows,
);
// Add the MainContainer's update.
@ -451,9 +464,8 @@ export function* updateWidgetAutoHeightSaga() {
{
propertyPath: "bottomRow",
propertyValue:
maxCanvasHeight +
GridDefaults.CANVAS_EXTENSION_OFFSET *
GridDefaults.DEFAULT_GRID_ROW_HEIGHT,
(maxCanvasHeightInRows + GridDefaults.MAIN_CANVAS_EXTENSION_OFFSET) *
GridDefaults.DEFAULT_GRID_ROW_HEIGHT,
},
];

View File

@ -18,6 +18,7 @@ import { generateClassName } from "utils/generators";
import { getWidgets } from "sagas/selectors";
import { getCurrentPageId } from "selectors/editorSelectors";
import { generatePropertyKey } from "utils/editorContextUtils";
import { RegisteredWidgetFeatures } from "utils/WidgetFeatures";
export type WidgetProperties = WidgetProps & {
[EVALUATION_PATH]?: DataTreeEntity;
@ -63,6 +64,7 @@ export const getWidgetPropsForPropertyPane = createSelector(
);
type WidgetPropertiesForPropertyPaneView = {
disabledWidgetFeatures?: RegisteredWidgetFeatures[];
type: string;
widgetId: string;
widgetName: string;
@ -77,6 +79,7 @@ export const getWidgetPropsForPropertyPaneView = createSelector(
"widgetId",
"widgetName",
"displayName",
"disabledWidgetFeatures",
]) as WidgetPropertiesForPropertyPaneView,
);

View File

@ -113,6 +113,7 @@ class WidgetFactory {
propertyPaneContentConfig,
features,
PropertyPaneConfigTypes.CONTENT,
widgetType,
);
const serializablePropertyPaneConfig = convertFunctionsToString(

View File

@ -1,9 +1,12 @@
import {
PropertyPaneConfig,
PropertyPaneControlConfig,
PropertyPaneSectionConfig,
} from "constants/PropertyControlConstants";
import { ValidationTypes } from "constants/WidgetValidation";
import log from "loglevel";
import { generateReactKey } from "./generators";
import { WidgetType } from "./WidgetFactory";
import {
PropertyPaneConfigTemplates,
RegisteredWidgetFeatures,
@ -74,6 +77,7 @@ export function enhancePropertyPaneConfig(
config: PropertyPaneConfig[],
features?: WidgetFeatures,
configType?: PropertyPaneConfigTypes,
widgetType?: WidgetType,
) {
// Enhance property pane with widget features
// TODO(abhinav): The following "configType" check should come
@ -83,20 +87,28 @@ export function enhancePropertyPaneConfig(
(configType === undefined || configType === PropertyPaneConfigTypes.CONTENT)
) {
Object.keys(features).forEach((registeredFeature: string) => {
const { sectionIndex } = features[
registeredFeature as RegisteredWidgetFeatures
];
const sectionName = (config[sectionIndex] as PropertyPaneSectionConfig)
?.sectionName;
if (!sectionName || sectionName !== "General") {
log.error(`Invalid section index for feature: ${registeredFeature}`);
}
if (
Array.isArray(config[0].children) &&
Array.isArray(config[sectionIndex].children) &&
PropertyPaneConfigTemplates[
registeredFeature as RegisteredWidgetFeatures
]
) {
config[0].children.push(
config[sectionIndex].children?.push(
...PropertyPaneConfigTemplates[
registeredFeature as RegisteredWidgetFeatures
],
);
config = WidgetFeaturePropertyPaneEnhancements[
registeredFeature as RegisteredWidgetFeatures
](config);
](config, widgetType);
}
});
}

View File

@ -2,16 +2,32 @@ import { ReduxActionTypes } from "ce/constants/ReduxActionConstants";
import {
PropertyPaneConfig,
PropertyPaneControlConfig,
PropertyPaneSectionConfig,
} from "constants/PropertyControlConstants";
import { WidgetHeightLimits } from "constants/WidgetConstants";
import {
GridDefaults,
WidgetHeightLimits,
WidgetType,
} from "constants/WidgetConstants";
import { klona } from "klona/lite";
import { WidgetProps } from "widgets/BaseWidget";
import { WidgetConfiguration } from "widgets/constants";
import WidgetFactory from "./WidgetFactory";
export enum RegisteredWidgetFeatures {
DYNAMIC_HEIGHT = "dynamicHeight",
}
export type WidgetFeatures = Record<RegisteredWidgetFeatures, boolean>;
interface WidgetFeatureConfig {
active: boolean;
defaultValue?: DynamicHeight;
sectionIndex: number;
}
export type WidgetFeatures = Record<
RegisteredWidgetFeatures,
WidgetFeatureConfig
>;
export enum DynamicHeight {
AUTO_HEIGHT = "AUTO_HEIGHT",
@ -19,7 +35,7 @@ export enum DynamicHeight {
AUTO_HEIGHT_WITH_LIMITS = "AUTO_HEIGHT_WITH_LIMITS",
}
/* This contains all properties which will be added
/* This contains all properties which will be added
to a widget, automatically, by the Appsmith platform
Each feature, is a unique key, whose value is an object
with the list of properties to be added to a widget along
@ -44,11 +60,14 @@ export const WidgetFeaturePropertyEnhancements: Record<
> = {
[RegisteredWidgetFeatures.DYNAMIC_HEIGHT]: (config: WidgetConfiguration) => {
const newProperties: Partial<WidgetProps> = {};
newProperties.dynamicHeight =
config.features?.dynamicHeight?.defaultValue || DynamicHeight.AUTO_HEIGHT;
if (config.isCanvas) {
newProperties.dynamicHeight = DynamicHeight.AUTO_HEIGHT;
newProperties.minDynamicHeight =
config.defaults.minDynamicHeight ||
WidgetHeightLimits.MIN_CANVAS_HEIGHT_IN_ROWS;
newProperties.shouldScrollContents = true;
newProperties.originalTopRow = config.defaults.topRow;
newProperties.originalBottomRow = config.defaults.bottomRow;
}
if (config.defaults.overflow) newProperties.overflow = "NONE";
return newProperties;
@ -91,16 +110,22 @@ function findAndUpdatePropertyPaneControlConfig(
export const WidgetFeaturePropertyPaneEnhancements: Record<
RegisteredWidgetFeatures,
(config: PropertyPaneConfig[]) => PropertyPaneConfig[]
(
config: PropertyPaneConfig[],
widgetType?: WidgetType,
) => PropertyPaneConfig[]
> = {
[RegisteredWidgetFeatures.DYNAMIC_HEIGHT]: (config: PropertyPaneConfig[]) => {
[RegisteredWidgetFeatures.DYNAMIC_HEIGHT]: (
config: PropertyPaneConfig[],
widgetType?: WidgetType,
) => {
function hideWhenDynamicHeightIsEnabled(props: WidgetProps) {
return (
props.dynamicHeight === DynamicHeight.AUTO_HEIGHT_WITH_LIMITS ||
props.dynamicHeight === DynamicHeight.AUTO_HEIGHT
);
}
return findAndUpdatePropertyPaneControlConfig(config, {
let update = findAndUpdatePropertyPaneControlConfig(config, {
shouldScrollContents: {
hidden: hideWhenDynamicHeightIsEnabled,
dependencies: ["dynamicHeight"],
@ -118,6 +143,23 @@ export const WidgetFeaturePropertyPaneEnhancements: Record<
dependencies: ["dynamicHeight"],
},
});
if (widgetType === "MODAL_WIDGET") {
update = findAndUpdatePropertyPaneControlConfig(update, {
dynamicHeight: {
options: [
{
label: "Auto Height",
value: DynamicHeight.AUTO_HEIGHT,
},
{
label: "Fixed",
value: DynamicHeight.FIXED,
},
],
},
});
}
return update;
},
};
@ -163,7 +205,8 @@ function updateMinMaxDynamicHeight(
) {
updates.push({
propertyPath: "maxDynamicHeight",
propertyValue: props.bottomRow - props.topRow,
propertyValue:
props.bottomRow - props.topRow + GridDefaults.CANVAS_EXTENSION_OFFSET,
});
}
@ -175,10 +218,13 @@ function updateMinMaxDynamicHeight(
});
}
} else if (propertyValue === DynamicHeight.AUTO_HEIGHT) {
const minHeightInRows = props.isCanvas
? WidgetHeightLimits.MIN_CANVAS_HEIGHT_IN_ROWS
: WidgetHeightLimits.MIN_HEIGHT_IN_ROWS;
updates.push(
{
propertyPath: "minDynamicHeight",
propertyValue: WidgetHeightLimits.MIN_HEIGHT_IN_ROWS,
propertyValue: minHeightInRows,
},
{
propertyPath: "maxDynamicHeight",
@ -245,7 +291,7 @@ function updateMinMaxDynamicHeight(
// TODO FEATURE:(abhinav) Add validations to these properties
const CONTAINER_SCROLL_HELPER_TEXT =
"While editing, this widget may scroll contents to facilitate adding widgets. When published, the widget may not scroll contents.";
"This widget shows an internal scroll when you add widgets in edit mode. It'll resize after you've added widgets. The scroll won't exist in view mode.";
export const PropertyPaneConfigTemplates: Record<
RegisteredWidgetFeatures,
@ -295,3 +341,36 @@ export const PropertyPaneConfigTemplates: Record<
},
],
};
//TODO make this logic a lot cleaner
export function disableWidgetFeatures(
widgetType: WidgetType,
disabledWidgetFeatures?: string[],
): PropertyPaneConfig[] {
const widgetConfig = WidgetFactory.getWidgetPropertyPaneContentConfig(
widgetType,
) as PropertyPaneConfig[];
if (!disabledWidgetFeatures || disabledWidgetFeatures.length <= 0)
return widgetConfig;
const clonedConfig = klona(widgetConfig);
const GeneralConfig = clonedConfig.find(
(sectionConfig) =>
(sectionConfig as PropertyPaneSectionConfig)?.sectionName === "General",
);
for (let i = 0; i < (GeneralConfig?.children?.length || -1); i++) {
const config = GeneralConfig?.children?.[i];
if (
disabledWidgetFeatures.indexOf(
(config as PropertyPaneControlConfig)?.propertyName || "",
) > -1
) {
GeneralConfig?.children?.splice(i, 1);
i--;
}
}
return clonedConfig;
}

View File

@ -11,7 +11,15 @@ export function generateTree(
previousTree: Record<string, TreeNode>,
): Record<string, TreeNode> {
// If widget doesn't exist in this DS, this means that its height changes does not effect any other sibling
spaces.sort((a, b) => a.top - b.top); // Sort based on position, top to bottom, so that we know which is above the other
spaces.sort((a, b) => {
//if both are of the same level and previous tree exists, check originalTops
if (a.top === b.top && previousTree[a.id] && previousTree[b.id]) {
return (
previousTree[a.id].originalTopRow - previousTree[b.id].originalTopRow
);
}
return a.top - b.top;
}); // Sort based on position, top to bottom, so that we know which is above the other
const _spaces = [...spaces];
const aboveMap: Record<string, string[]> = {};

View File

@ -46,10 +46,9 @@ const InputContainer = styled.div<ThemeProp & InputContainerProps>`
? `flex-start`
: `center`};
width: 100%;
height: ${({ inline, isDynamicHeightEnabled }) =>
inline && !isDynamicHeightEnabled ? "32px" : "100%"};
flex-grow: 1;
height: 100%;
border: 1px solid transparent;
.${Classes.CONTROL} {
@ -72,6 +71,7 @@ export interface CheckboxGroupContainerProps {
export const CheckboxGroupContainer = styled.div<CheckboxGroupContainerProps>`
${labelLayoutStyles}
& .${LABEL_CONTAINER_CLASS} {
align-self: center;
${({ labelPosition }) =>
labelPosition === LabelPosition.Left && "min-height: 30px"};
}
@ -149,6 +149,7 @@ export interface CheckboxGroupComponentProps extends ComponentProps {
labelTextSize?: TextSize;
labelStyle?: string;
labelWidth?: number;
labelTooltip?: string;
accentColor: string;
borderRadius: string;
}
@ -168,6 +169,7 @@ function CheckboxGroupComponent(props: CheckboxGroupComponentProps) {
labelText,
labelTextColor,
labelTextSize,
labelTooltip,
labelWidth,
onChange,
onSelectAllChange,
@ -205,6 +207,7 @@ function CheckboxGroupComponent(props: CheckboxGroupComponentProps) {
disabled={isDisabled}
fontSize={labelTextSize}
fontStyle={labelStyle}
helpText={labelTooltip}
inline={isInline}
isDynamicHeightEnabled={isDynamicHeightEnabled}
optionCount={optionCount}

View File

@ -5,7 +5,10 @@ import Widget from "./widget";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 3,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Checkbox Group",

View File

@ -1,26 +1,23 @@
import React from "react";
import { compact, xor } from "lodash";
import {
ValidationResponse,
ValidationTypes,
} from "constants/WidgetValidation";
import { TextSize, WidgetType } from "constants/WidgetConstants";
import { DerivedPropertiesMap } from "utils/WidgetFactory";
import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import { AutocompleteDataType } from "utils/autocomplete/TernServer";
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
import { Alignment } from "@blueprintjs/core";
import { GRID_DENSITY_MIGRATION_V1 } from "widgets/constants";
import CheckboxGroupComponent from "../component";
import { OptionProps, SelectAllState, SelectAllStates } from "../constants";
import {
ValidationResponse,
ValidationTypes,
} from "constants/WidgetValidation";
import {
CheckboxGroupAlignmentTypes,
LabelPosition,
} from "components/constants";
import { Alignment } from "@blueprintjs/core";
import { GRID_DENSITY_MIGRATION_V1 } from "widgets/constants";
import CheckboxGroupComponent from "../component";
import { OptionProps, SelectAllState, SelectAllStates } from "../constants";
import { isAutoHeightEnabledForWidget } from "widgets/WidgetUtils";
export function defaultSelectedValuesValidation(
@ -217,6 +214,16 @@ class CheckboxGroupWidget extends BaseWidget<
{
sectionName: "General",
children: [
{
helpText: "Show help text or details about current input",
propertyName: "labelTooltip",
label: "Tooltip",
controlType: "INPUT_TEXT",
placeholderText: "Value must be atleast 6 chars",
isBindProperty: true,
isTriggerProperty: false,
validation: { type: ValidationTypes.TEXT },
},
{
propertyName: "isVisible",
label: "Visible",
@ -561,6 +568,7 @@ class CheckboxGroupWidget extends BaseWidget<
labelText={this.props.labelText}
labelTextColor={this.props.labelTextColor}
labelTextSize={this.props.labelTextSize}
labelTooltip={this.props.labelTooltip}
labelWidth={this.getLabelWidth()}
onChange={this.handleCheckboxChange}
onSelectAllChange={this.handleSelectAllChange}

View File

@ -5,7 +5,10 @@ import { AlignWidgetTypes } from "widgets/constants";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 2,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Checkbox",

View File

@ -1,5 +1,6 @@
import { ButtonBoxShadowTypes } from "components/constants";
import { Colors } from "constants/Colors";
import { WidgetHeightLimits } from "constants/WidgetConstants";
import IconSVG from "./icon.svg";
import Widget from "./widget";
@ -9,12 +10,15 @@ export const CONFIG = {
iconSVG: IconSVG,
isCanvas: true,
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 0,
active: true,
},
},
searchTags: ["div", "parent", "group"],
defaults: {
backgroundColor: "#FFFFFF",
rows: 40,
rows: WidgetHeightLimits.MIN_CANVAS_HEIGHT_IN_ROWS,
columns: 24,
widgetName: "Container",
containerStyle: "card",

View File

@ -3,10 +3,15 @@ import IconSVG from "./icon.svg";
import { CONFIG as BaseConfig } from "widgets/BaseInputWidget";
import { getDefaultCurrency } from "./component/CurrencyCodeDropdown";
import { LabelPosition } from "components/constants";
import { DynamicHeight } from "utils/WidgetFeatures";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 3,
defaultValue: DynamicHeight.FIXED,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Currency Input",

View File

@ -1,13 +1,18 @@
import { Alignment } from "@blueprintjs/core";
import { LabelPosition } from "components/constants";
import moment from "moment";
import { DynamicHeight } from "utils/WidgetFeatures";
import { TimePrecision } from "./constants";
import IconSVG from "./icon.svg";
import Widget from "./widget";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 3,
defaultValue: DynamicHeight.FIXED,
active: true,
},
},
type: Widget.getWidgetType(),
name: "DatePicker",

View File

@ -10,7 +10,10 @@ export const CONFIG = {
needsMeta: true,
isCanvas: true,
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 0,
active: true,
},
},
searchTags: ["group"],
defaults: {

View File

@ -2,10 +2,15 @@ import Widget from "./widget";
import IconSVG from "./icon.svg";
import { CONFIG as BaseConfig } from "widgets/BaseInputWidget";
import { LabelPosition } from "components/constants";
import { DynamicHeight } from "utils/WidgetFeatures";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 3,
defaultValue: DynamicHeight.FIXED,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Input",

View File

@ -156,6 +156,7 @@ function Form<TValues = any>(
>({
activeClassName: FOOTER_SCROLL_ACTIVE_CLASS_NAME,
fixedFooter,
ref: ref as React.MutableRefObject<HTMLDivElement>,
});
const onReset = (
@ -262,12 +263,11 @@ function Form<TValues = any>(
<FormProvider {...methods}>
<StyledForm
fixedFooter={fixedFooter}
ref={bodyRef}
ref={bodyRef as React.RefObject<HTMLFormElement>}
scrollContents={scrollContents}
>
<StyledFormBody
className="t--jsonform-body"
ref={ref}
stretchBodyVertically={stretchBodyVertically}
>
<StyledTitle>{title}</StyledTitle>

View File

@ -4,6 +4,7 @@ import { useLayoutEffect, useRef } from "react";
type UseFixedFooterProps = {
fixedFooter: boolean;
activeClassName: string;
ref: React.MutableRefObject<HTMLDivElement | null>;
};
const ERROR_MARGIN = 2;
@ -21,10 +22,10 @@ const hasOverflowingContent = (element: HTMLElement) => {
const THROTTLE_TIMEOUT = 50;
function useFixedFooter<
TBodyElement extends HTMLElement = HTMLDivElement,
HTMLDivElement extends HTMLElement,
TFooterElement extends HTMLElement = HTMLDivElement
>({ activeClassName, fixedFooter }: UseFixedFooterProps) {
const bodyRef = useRef<TBodyElement>(null);
>({ activeClassName, fixedFooter, ref }: UseFixedFooterProps) {
const bodyRef = ref;
const footerRef = useRef<TFooterElement>(null);
const isOverflowing = bodyRef.current

View File

@ -3,6 +3,7 @@ import { Colors } from "constants/Colors";
import Widget, { JSONFormWidgetProps } from "./widget";
import { ButtonVariantTypes } from "components/constants";
import { BlueprintOperationTypes } from "widgets/constants";
import { DynamicHeight } from "utils/WidgetFeatures";
const SUBMIT_BUTTON_DEFAULT_STYLES = {
buttonVariant: ButtonVariantTypes.PRIMARY,
@ -14,7 +15,11 @@ const RESET_BUTTON_DEFAULT_STYLES = {
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 1,
defaultValue: DynamicHeight.FIXED,
active: true,
},
},
type: Widget.getWidgetType(),
name: "JSON Form",

View File

@ -29,13 +29,6 @@ import {
import { ButtonStyleProps } from "widgets/ButtonWidget/component";
import { BoxShadow } from "components/designSystems/appsmith/WidgetStyleContainer";
import { convertSchemaItemToFormData } from "../helper";
import { GridDefaults } from "constants/WidgetConstants";
import {
getWidgetMaxAutoHeight,
getWidgetMinAutoHeight,
isAutoHeightEnabledForWidget,
} from "widgets/WidgetUtils";
export interface JSONFormWidgetProps extends WidgetProps {
autoGenerateForm?: boolean;
borderColor?: string;
@ -151,43 +144,6 @@ class JSONFormWidget extends BaseWidget<
this.state.metaInternalFieldState,
schema,
);
let height = this.formRef?.current?.scrollHeight || 0;
if (isAutoHeightEnabledForWidget(this.props)) {
const maxDynamicHeight = getWidgetMaxAutoHeight(this.props);
const minDynamicHeight = getWidgetMinAutoHeight(this.props);
const footerHeight = 80; // TODO(abhinav): Get it from the component. Check with Ashit
if (
maxDynamicHeight * GridDefaults.DEFAULT_GRID_ROW_HEIGHT <
height + footerHeight
) {
height =
maxDynamicHeight * GridDefaults.DEFAULT_GRID_ROW_HEIGHT -
footerHeight;
} else if (
minDynamicHeight * GridDefaults.DEFAULT_GRID_ROW_HEIGHT >
height + footerHeight
) {
height =
minDynamicHeight * GridDefaults.DEFAULT_GRID_ROW_HEIGHT -
footerHeight;
}
const totalHeight = footerHeight + height;
const { componentHeight } = this.getComponentDimensions();
const expectedHeightInPixels =
Math.ceil(totalHeight / GridDefaults.DEFAULT_GRID_ROW_HEIGHT) *
GridDefaults.DEFAULT_GRID_ROW_HEIGHT;
if (
height &&
Math.abs(componentHeight - expectedHeightInPixels) >
GridDefaults.DEFAULT_GRID_ROW_HEIGHT
) {
this.updateAutoHeight(expectedHeightInPixels);
}
}
}
computeDynamicPropertyPathList = (schema: Schema) => {

View File

@ -3,6 +3,7 @@ import {
combineDynamicBindings,
getDynamicBindings,
} from "utils/DynamicBindingUtils";
import { RegisteredWidgetFeatures } from "utils/WidgetFeatures";
import { WidgetProps } from "widgets/BaseWidget";
import {
BlueprintOperationTypes,
@ -122,6 +123,9 @@ export const CONFIG = {
isDeletable: false,
disallowCopy: true,
disablePropertyPane: true,
disabledWidgetFeatures: [
RegisteredWidgetFeatures.DYNAMIC_HEIGHT,
],
openParentPropertyPane: true,
children: [],
blueprint: {

View File

@ -21,7 +21,10 @@ export const CONFIG = {
needsMeta: true,
isCanvas: true,
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 0,
active: true,
},
},
searchTags: ["dialog", "popup", "notification"],
defaults: {
@ -29,6 +32,7 @@ export const CONFIG = {
columns: 24,
width: 456,
height: GridDefaults.DEFAULT_GRID_ROW_HEIGHT * 24,
minDynamicHeight: 24,
canEscapeKeyClose: true,
animateLoading: true,
// detachFromLayout is set true for widgets that are not bound to the widgets within the layout.

View File

@ -1,11 +1,16 @@
import { Alignment } from "@blueprintjs/core";
import { LabelPosition } from "components/constants";
import { DynamicHeight } from "utils/WidgetFeatures";
import IconSVG from "./icon.svg";
import Widget from "./widget";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 3,
defaultValue: DynamicHeight.FIXED,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Multi TreeSelect",

View File

@ -2,10 +2,15 @@ import Widget from "./widget";
import IconSVG from "./icon.svg";
import { LabelPosition } from "components/constants";
import { Alignment } from "@blueprintjs/core";
import { DynamicHeight } from "utils/WidgetFeatures";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 4,
defaultValue: DynamicHeight.FIXED,
active: true,
},
},
type: Widget.getWidgetType(),
name: "MultiSelect",

View File

@ -3,10 +3,15 @@ import IconSVG from "./icon.svg";
import { CONFIG as BaseConfig } from "widgets/BaseInputWidget";
import { getDefaultISDCode } from "./component/ISDCodeDropdown";
import { LabelPosition } from "components/constants";
import { DynamicHeight } from "utils/WidgetFeatures";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 3,
defaultValue: DynamicHeight.FIXED,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Phone Input",

View File

@ -1,11 +1,11 @@
import React, { useCallback } from "react";
import styled from "styled-components";
import { ComponentProps } from "widgets/BaseComponent";
import { RadioOption } from "../constants";
import { RadioGroup, Radio, Alignment, Classes } from "@blueprintjs/core";
import { TextSize } from "constants/WidgetConstants";
import { BlueprintRadioSwitchGroupTransform } from "constants/DefaultTheme";
import { LabelPosition } from "components/constants";
import { RadioOption } from "../constants";
import LabelWithTooltip, {
labelLayoutStyles,
LABEL_CONTAINER_CLASS,
@ -18,7 +18,9 @@ export interface RadioGroupContainerProps {
export const RadioGroupContainer = styled.div<RadioGroupContainerProps>`
${labelLayoutStyles}
& .${LABEL_CONTAINER_CLASS} {
align-self: center;
${({ labelPosition }) =>
labelPosition === LabelPosition.Left && "min-height: 30px"};
}
@ -37,8 +39,6 @@ export interface StyledRadioGroupProps {
const StyledRadioGroup = styled(RadioGroup)<StyledRadioGroupProps>`
${BlueprintRadioSwitchGroupTransform}
height: ${({ inline, isDynamicHeightEnabled }) =>
inline && !isDynamicHeightEnabled ? "32px" : "100%"};
.${Classes.CONTROL} {
& input:checked ~ .${Classes.CONTROL_INDICATOR} {
@ -48,8 +48,12 @@ const StyledRadioGroup = styled(RadioGroup)<StyledRadioGroupProps>`
& input:disabled:checked ~ .${Classes.CONTROL_INDICATOR} {
&:before {
opacity: 1;
background-image: radial-gradient(var( --wds-color-bg-disabled-strong), var( --wds-color-bg-disabled-strong) 28%, transparent 32%)
opacity: 1;
background-image: radial-gradient(
var(--wds-color-bg-disabled-strong),
var(--wds-color-bg-disabled-strong) 28%,
transparent 32%
);
}
}
}
@ -76,6 +80,7 @@ function RadioGroupComponent(props: RadioGroupComponentProps) {
labelText,
labelTextColor,
labelTextSize,
labelTooltip,
labelWidth,
loading,
onRadioSelectionChange,
@ -108,6 +113,7 @@ function RadioGroupComponent(props: RadioGroupComponentProps) {
disabled={disabled}
fontSize={labelTextSize}
fontStyle={labelStyle}
helpText={labelTooltip}
inline={inline}
isDynamicHeightEnabled={isDynamicHeightEnabled}
loading={loading}
@ -165,6 +171,7 @@ export interface RadioGroupComponentProps extends ComponentProps {
labelTextSize?: TextSize;
labelStyle?: string;
labelWidth?: number;
labelTooltip?: string;
widgetId: string;
height?: number;
accentColor: string;

View File

@ -9,7 +9,10 @@ export const CONFIG = {
iconSVG: IconSVG,
needsMeta: true,
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 3,
active: true,
},
},
searchTags: ["choice"],
defaults: {

View File

@ -1,20 +1,19 @@
import React from "react";
import { Alignment } from "@blueprintjs/core";
import { isArray, compact, isNumber } from "lodash";
import BaseWidget, { WidgetProps, WidgetState } from "../../BaseWidget";
import { TextSize, WidgetType } from "constants/WidgetConstants";
import { GRID_DENSITY_MIGRATION_V1 } from "widgets/constants";
import { AutocompleteDataType } from "utils/autocomplete/TernServer";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import {
ValidationResponse,
ValidationTypes,
} from "constants/WidgetValidation";
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
import { RadioOption } from "../constants";
import { LabelPosition } from "components/constants";
import RadioGroupComponent from "../component";
import {
ValidationResponse,
ValidationTypes,
} from "constants/WidgetValidation";
import { isAutoHeightEnabledForWidget } from "widgets/WidgetUtils";
/**
@ -293,6 +292,16 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
{
sectionName: "General",
children: [
{
helpText: "Show help text or details about current input",
propertyName: "labelTooltip",
label: "Tooltip",
controlType: "INPUT_TEXT",
placeholderText: "Value must be atleast 6 chars",
isBindProperty: true,
isTriggerProperty: false,
validation: { type: ValidationTypes.TEXT },
},
{
helpText: "Controls the visibility of the widget",
propertyName: "isVisible",
@ -545,6 +554,7 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
labelText={label}
labelTextColor={labelTextColor}
labelTextSize={labelTextSize}
labelTooltip={this.props.labelTooltip}
labelWidth={this.getLabelWidth()}
loading={isLoading}
onRadioSelectionChange={this.onRadioSelectionChange}

View File

@ -4,7 +4,10 @@ import Widget from "./widget";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 1,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Rating",

View File

@ -1,5 +1,6 @@
import { Alignment } from "@blueprintjs/core";
import { LabelPosition } from "components/constants";
import { DynamicHeight } from "utils/WidgetFeatures";
import IconSVG from "./icon.svg";
import Widget from "./widget";
@ -10,7 +11,11 @@ export const CONFIG = {
needsMeta: true,
searchTags: ["input", "rte"],
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 3,
defaultValue: DynamicHeight.FIXED,
active: true,
},
},
defaults: {
defaultText: "This is the initial <b>content</b> of the editor",

View File

@ -2,10 +2,15 @@ import Widget from "./widget";
import IconSVG from "./icon.svg";
import { LabelPosition } from "components/constants";
import { Alignment } from "@blueprintjs/core";
import { DynamicHeight } from "utils/WidgetFeatures";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 4,
defaultValue: DynamicHeight.FIXED,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Select",

View File

@ -1,11 +1,16 @@
import { Alignment } from "@blueprintjs/core";
import { LabelPosition } from "components/constants";
import { DynamicHeight } from "utils/WidgetFeatures";
import IconSVG from "./icon.svg";
import Widget from "./widget";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 3,
defaultValue: DynamicHeight.FIXED,
active: true,
},
},
type: Widget.getWidgetType(),
name: "TreeSelect",

View File

@ -6,7 +6,10 @@ import Widget from "./widget";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 0,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Stats Box",
@ -21,6 +24,7 @@ export const CONFIG = {
backgroundColor: "white",
borderWidth: "1",
borderColor: Colors.GREY_5,
minDynamicHeight: 14,
children: [],
blueprint: {
view: [

View File

@ -1,7 +1,6 @@
import React from "react";
import styled from "styled-components";
import { Alignment } from "@blueprintjs/core";
import { BlueprintRadioSwitchGroupTransform } from "constants/DefaultTheme";
import { LabelPosition } from "components/constants";
import { TextSize } from "constants/WidgetConstants";
@ -20,6 +19,7 @@ export interface SwitchGroupContainerProps {
export const SwitchGroupContainer = styled.div<SwitchGroupContainerProps>`
${labelLayoutStyles}
& .${LABEL_CONTAINER_CLASS} {
align-self: center;
${({ labelPosition }) =>
labelPosition === LabelPosition.Left && "min-height: 30px"};
}
@ -37,9 +37,8 @@ export interface InputContainerProps {
}
export const InputContainer = styled.div<ThemeProp & InputContainerProps>`
${BlueprintRadioSwitchGroupTransform}
height: ${({ inline, isDynamicHeightEnabled }) =>
inline && !isDynamicHeightEnabled ? "32px" : "100%"};
${BlueprintRadioSwitchGroupTransform};
border: 1px solid transparent;
${({ theme, valid }) =>
!valid &&
@ -68,6 +67,7 @@ function SwitchGroupComponent(props: SwitchGroupComponentProps) {
labelText,
labelTextColor,
labelTextSize,
labelTooltip,
labelWidth,
onChange,
options,
@ -92,6 +92,7 @@ function SwitchGroupComponent(props: SwitchGroupComponentProps) {
disabled={disabled}
fontSize={labelTextSize}
fontStyle={labelStyle}
helpText={labelTooltip}
inline={inline}
isDynamicHeightEnabled={isDynamicHeightEnabled}
optionCount={optionCount}
@ -147,6 +148,7 @@ export interface SwitchGroupComponentProps {
labelTextSize?: TextSize;
labelStyle?: string;
labelWidth?: number;
labelTooltip?: string;
widgetId: string;
height: number;
accentColor: string;

View File

@ -5,7 +5,10 @@ import Widget from "./widget";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 3,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Switch Group", // The display name which will be made in uppercase and show in the widgets panel ( can have spaces )

View File

@ -1,17 +1,15 @@
import React from "react";
import { Alignment } from "@blueprintjs/core";
import { isString, xor } from "lodash";
import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget";
import { DerivedPropertiesMap } from "utils/WidgetFactory";
import { ValidationTypes } from "constants/WidgetValidation";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
import SwitchGroupComponent, { OptionProps } from "../component";
import { LabelPosition } from "components/constants";
import { TextSize } from "constants/WidgetConstants";
import { GRID_DENSITY_MIGRATION_V1 } from "widgets/constants";
import SwitchGroupComponent, { OptionProps } from "../component";
import { isAutoHeightEnabledForWidget } from "widgets/WidgetUtils";
class SwitchGroupWidget extends BaseWidget<
@ -177,6 +175,16 @@ class SwitchGroupWidget extends BaseWidget<
{
sectionName: "General",
children: [
{
helpText: "Show help text or details about current input",
propertyName: "labelTooltip",
label: "Tooltip",
controlType: "INPUT_TEXT",
placeholderText: "Value must be atleast 6 chars",
isBindProperty: true,
isTriggerProperty: false,
validation: { type: ValidationTypes.TEXT },
},
{
propertyName: "isVisible",
helpText: "Controls the visibility of the widget",
@ -421,6 +429,7 @@ class SwitchGroupWidget extends BaseWidget<
labelText,
labelTextColor,
labelTextSize,
labelTooltip,
options,
selectedValues,
topRow,
@ -453,6 +462,7 @@ class SwitchGroupWidget extends BaseWidget<
labelText={labelText}
labelTextColor={labelTextColor}
labelTextSize={labelTextSize}
labelTooltip={labelTooltip}
labelWidth={this.getLabelWidth()}
onChange={this.handleSwitchStateChange}
options={_options}

View File

@ -63,10 +63,6 @@ export const StyledSwitch = styled(Switch)<{
$accentColor: string;
inline?: boolean;
}>`
&.${Classes.CONTROL} {
margin: 0;
}
&.${Classes.CONTROL} {
& input:checked ~ .${Classes.CONTROL_INDICATOR} {
background: ${({ $accentColor }) => `${$accentColor}`} !important;

View File

@ -5,7 +5,10 @@ import { AlignWidgetTypes } from "widgets/constants";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 1,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Switch",

View File

@ -1,4 +1,5 @@
import { Colors } from "constants/Colors";
import { WidgetHeightLimits } from "constants/WidgetConstants";
import { WidgetProps } from "widgets/BaseWidget";
import { BlueprintOperationTypes } from "widgets/constants";
import IconSVG from "./icon.svg";
@ -16,12 +17,15 @@ export const CONFIG = {
// define them in a Map which the platform understands to have
// them stored only in the WidgetFactory.
canvasHeightOffset: (props: WidgetProps): number =>
props.shouldShowTabs === true ? 4 : 0,
props.shouldShowTabs === true ? 5 : 0,
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 1,
active: true,
},
},
defaults: {
rows: 40,
rows: WidgetHeightLimits.MIN_CANVAS_HEIGHT_IN_ROWS,
columns: 24,
shouldScrollContents: false,
widgetName: "Tabs",

View File

@ -5,7 +5,10 @@ import Widget from "./widget";
export const CONFIG = {
features: {
dynamicHeight: true,
dynamicHeight: {
sectionIndex: 0,
active: true,
},
},
type: Widget.getWidgetType(),
name: "Text",

View File

@ -581,7 +581,7 @@ describe("Auto Height Utils", () => {
expect(result).toBeUndefined();
});
it("should return 4 if widget has AUTO_HEIGHT", () => {
it.skip("should return 4 if widget has AUTO_HEIGHT", () => {
const props = {
...DUMMY_WIDGET,
dynamicHeight: "AUTO_HEIGHT",
@ -612,7 +612,7 @@ describe("Auto Height Utils", () => {
expect(result).toBe(WidgetHeightLimits.MIN_HEIGHT_IN_ROWS);
});
it("should return undefined if widget is FIXED ", () => {
it.skip("should return undefined if widget is FIXED ", () => {
const props = {
...DUMMY_WIDGET,
dynamicHeight: "FIXED",

View File

@ -772,11 +772,7 @@ export function getWidgetMaxAutoHeight(props: WidgetProps) {
* @returns: The min possible height of the widget (in rows)
*/
export function getWidgetMinAutoHeight(props: WidgetProps) {
if (props.dynamicHeight === DynamicHeight.AUTO_HEIGHT) {
return WidgetHeightLimits.MIN_HEIGHT_IN_ROWS;
} else if (props.dynamicHeight === DynamicHeight.AUTO_HEIGHT_WITH_LIMITS) {
return props.minDynamicHeight || WidgetHeightLimits.MIN_HEIGHT_IN_ROWS;
}
return props.minDynamicHeight || WidgetHeightLimits.MIN_HEIGHT_IN_ROWS;
}
/**

View File

@ -85,8 +85,11 @@ function withWidgetProps(WrappedWidget: typeof BaseWidget) {
props.type === "CANVAS_WIDGET" &&
widgetId !== MAIN_CONTAINER_WIDGET_ID
) {
const isListWidgetCanvas =
props.noPad && props.dropDisabled && props.openParentPropertyPane;
widgetProps.rightColumn = props.rightColumn;
if (widgetProps.bottomRow === undefined) {
if (widgetProps.bottomRow === undefined || isListWidgetCanvas) {
widgetProps.bottomRow = props.bottomRow;
widgetProps.minHeight = props.minHeight;
}