diff --git a/demo/src/screens/MenuStructure.js b/demo/src/screens/MenuStructure.js
index 05014f74ef..4b85987a68 100644
--- a/demo/src/screens/MenuStructure.js
+++ b/demo/src/screens/MenuStructure.js
@@ -194,7 +194,7 @@ export const navigationData = {
tags: 'text field expandable input picker',
screen: 'unicorn.components.IncubatorExpandableOverlayScreen'
},
- {title: 'Pan View', tags: 'pan swipe drag', screen: 'unicorn.incubator.PanViewScreen'}
+ {title: 'PanView', tags: 'pan swipe drag', screen: 'unicorn.incubator.PanViewScreen'}
]
},
Inspirations: {
diff --git a/demo/src/screens/__tests__/__snapshots__/TextFieldScreen.spec.js.snap b/demo/src/screens/__tests__/__snapshots__/TextFieldScreen.spec.js.snap
index b3311c5eb7..b5e809facf 100644
--- a/demo/src/screens/__tests__/__snapshots__/TextFieldScreen.spec.js.snap
+++ b/demo/src/screens/__tests__/__snapshots__/TextFieldScreen.spec.js.snap
@@ -306,7 +306,7 @@ exports[`TextField Screen renders screen 1`] = `
Presets
-
- Preset:
-
-
- Static vs Floating Placeholder
-
-
+ Disabled vs Readonly
+
+
-
-
-
-
-
+
+
+ Disabled
+
+
+
+
+ Readonly
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Static vs Floating Placeholder
+
+
+
+
+
+
+
+
+
+
+ FloatingPlaceholder
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hint vs HelperText
+
+
+
+
+
+
+
+
+
+
- FloatingPlaceholder
+ Enter code
+ >
+
+
+
+
+ Enter code
+
+
+ subtext={true}
+ testID="undefined.helperText"
+ >
+ 1-6 numbers
+
- Email
-
-
-
-
-
-
-
-
-
-
-
-
+ testID="undefined.label"
+ >
+ Email
+
-
-
-
- Name
-
-
-
-
-
-
-
-
-
+ underlineColorAndroid="transparent"
+ validate={
+ [
+ "required",
+ "email",
+ ]
+ }
+ validateOnBlur={true}
+ validateOnChange={true}
+ validationMessage={
+ [
+ "Email is required",
+ "Email is invalid",
+ ]
+ }
+ value="Initial Value"
+ />
+
+
-
-
- Enter first and last name
-
-
-
-
- 0/20
-
-
+ ],
+ ]
+ }
+ testID="undefined.validationMessage"
+ />
-
-
-
- Validate
-
+ />
-
- Hint
-
-
+
-
-
+ Name
+
+
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ ]
+ }
+ >
+
+
+
-
- Enter password
-
-
-
+ ]
+ }
+ underlineColorAndroid="transparent"
+ validate="required"
+ validateOnBlur={true}
+ validateOnChange={true}
+ validationMessage="This field is required. That means you have to enter some value"
+ />
+
-
-
-
+
+ Enter first and last name
+
+
+
+
+ ]
+ }
+ testID="undefined.charCounter"
+ >
+ 0/20
+
+
-
+
+
+ testID="undefined.label"
+ >
+ Validate
+
- Email
+ Color
@@ -5215,7 +6056,7 @@ exports[`TextField Screen renders screen 1`] = `
}
testID="undefined.label"
>
- Email
+ Required
@@ -6004,6 +6845,7 @@ exports[`TextField Screen renders screen 1`] = `
underlineColorAndroid="transparent"
validate="required"
validateOnBlur={true}
+ validateOnChange={true}
validationMessage="This field is required"
/>
@@ -6369,7 +7211,7 @@ exports[`TextField Screen renders screen 1`] = `
({...product}));
-type Item = typeof productsWithIds[0];
+const productsWithIds = products.map(product => ({...product}));
+type Item = (typeof productsWithIds)[0];
class SortableGridListScreen extends Component {
state = {
orientation: Constants.orientation,
selectedItemId: undefined,
items: productsWithIds,
- removedItems: [] as Item[]
+ removedItems: [] as Item[],
+ shouldOrderByIndex: false
};
itemsOrdered = this.state.items;
@@ -44,7 +46,7 @@ class SortableGridListScreen extends Component {
removeSelectedItem = () => {
const {selectedItemId, removedItems} = this.state;
if (!_.isUndefined(selectedItemId)) {
- const newItems = [...this.itemsOrdered];
+ const newItems = [...this.itemsOrdered];
const removed = _.remove(newItems, item => item.id === selectedItemId);
removedItems.push(removed[0]);
this.setState({items: newItems, selectedItemId: undefined, removedItems});
@@ -83,7 +85,7 @@ class SortableGridListScreen extends Component {
};
render() {
- const {items, removedItems, selectedItemId} = this.state;
+ const {items, removedItems, selectedItemId, shouldOrderByIndex} = this.state;
return (
@@ -98,6 +100,9 @@ class SortableGridListScreen extends Component {
/>
+
+ {renderBooleanOption.call(this, 'Order by index', 'shouldOrderByIndex')}
+
diff --git a/demo/src/screens/componentScreens/TextFieldScreen.tsx b/demo/src/screens/componentScreens/TextFieldScreen.tsx
index cc10fb77be..afedaca764 100644
--- a/demo/src/screens/componentScreens/TextFieldScreen.tsx
+++ b/demo/src/screens/componentScreens/TextFieldScreen.tsx
@@ -15,10 +15,13 @@ import {
SegmentedControl,
Icon
} from 'react-native-ui-lib';
-const {loadDemoConfigurations} = require('../../../src/configurations.js');
const {KeyboardAwareInsetsView} = Keyboard;
-const priceFormatter = Intl.NumberFormat('en-US');
+
+const {loadDemoConfigurations} = require('../../../src/configurations.js');
loadDemoConfigurations();
+
+const priceFormatter = Intl.NumberFormat('en-US');
+
export default class TextFieldScreen extends Component {
input = React.createRef();
input2 = React.createRef();
@@ -31,8 +34,9 @@ export default class TextFieldScreen extends Component {
isReadonly: false,
value: 'Initial Value',
isSearching: false,
- preset: TextField.presets.UNDERLINE,
- price: ''
+ preset: undefined,
+ price: '',
+ editable: false
};
componentDidMount() {
@@ -62,8 +66,7 @@ export default class TextFieldScreen extends Component {
Presets
-
- Preset:
+
@@ -73,6 +76,26 @@ export default class TextFieldScreen extends Component {
);
}
+ renderReadonlyExample() {
+ const {editable, preset} = this.state;
+
+ return (
+ <>
+
+
+ Disabled vs Readonly
+
+
+
+
+
+
+
+
+ >
+ );
+ }
+
renderPlaceholdersExample() {
return (
<>
@@ -103,6 +126,35 @@ export default class TextFieldScreen extends Component {
);
}
+ renderHintExample() {
+ return (
+ <>
+
+ Hint vs HelperText
+
+
+
+
+
+
+ >
+ );
+ }
+
renderTrailingAccessory() {
const {isSearching} = this.state;
@@ -237,7 +289,8 @@ export default class TextFieldScreen extends Component {
switch (index) {
case 0:
- // this.input3.current?.clear();
+ this.input3.current?.blur();
+ this.input3.current?.clear();
break;
case 1:
this.input3.current?.focus();
@@ -274,21 +327,28 @@ export default class TextFieldScreen extends Component {
>
);
@@ -298,30 +358,35 @@ export default class TextFieldScreen extends Component {
this.setState({preset: index === 0 ? 'underline' : 'outline'});
};
+ onChangeIndexEditable = (index: number) => {
+ this.setState({editable: index === 1});
+ };
+
getDynamicFieldStyle = (context: FieldContextType, props: TextFieldProps) => {
let color = Colors.$outlineNeutral;
if (context?.isFocused) {
color = Colors.$outlinePrimary;
}
- if (context?.hasValue && context?.isValid === false) {
+ if ((context?.hasValue && context?.isValid === false) ||
+ (context?.failingValidatorIndex !== undefined && context?.isMandatory && !context?.hasValue)) {
color = Colors.$outlineDanger;
}
- if (context?.hasValue && context?.isValid) {
+ if (context?.hasValue && context?.isValid && context?.isFocused) {
color = Colors.$textSuccess;
}
if (context?.disabled) {
- color = Colors.$outlineDefault;
+ color = Colors.$outlineDisabled;
}
if (context?.readonly) {
- color = Colors.$outlineDisabled;
+ color = Colors.$outlineNeutralHeavy;
}
return props?.preset === TextField.presets.UNDERLINE ? {borderBottomColor: color} : {borderColor: color};
};
renderDynamicFieldExample() {
- const {preset, isDisabled, isReadonly} = this.state;
+ const {preset} = this.state;
return (
<>
@@ -330,14 +395,12 @@ export default class TextFieldScreen extends Component {
>
@@ -386,24 +449,6 @@ export default class TextFieldScreen extends Component {
);
}
- renderHintExample() {
- return (
- <>
-
- Hint
-
-
-
- >
- );
- }
-
renderFormatterExample() {
const {price, preset} = this.state;
@@ -446,7 +491,7 @@ export default class TextFieldScreen extends Component {
topTrailingAccessory={}
validate={'required'}
validationMessage={'This field is required'}
- validateOnBlur
+ validateOnChange
validationMessagePosition={errorPosition}
preset={preset}
/>
@@ -475,9 +520,10 @@ export default class TextFieldScreen extends Component {
{this.renderDefaultExample()}
{this.renderPresetExample()}
+ {this.renderReadonlyExample()}
{this.renderPlaceholdersExample()}
- {this.renderValidationExample()}
{this.renderHintExample()}
+ {this.renderValidationExample()}
{this.renderClearButtonExample()}
{this.renderCharCounterExample()}
{this.renderAccessoriesExample()}
diff --git a/lib/android/build.gradle b/lib/android/build.gradle
index 320499e5fd..5f0b7d690d 100644
--- a/lib/android/build.gradle
+++ b/lib/android/build.gradle
@@ -9,6 +9,7 @@ project.ext {
}
android {
+ namespace "com.wix.reactnativeuilib"
compileSdkVersion project.ext.compileSdkVersion
buildToolsVersion project.ext.buildToolsVersion
diff --git a/lib/android/src/main/AndroidManifest.xml b/lib/android/src/main/AndroidManifest.xml
index d7a52b40f8..b2d79a44f7 100644
--- a/lib/android/src/main/AndroidManifest.xml
+++ b/lib/android/src/main/AndroidManifest.xml
@@ -1,5 +1,4 @@
+ xmlns:android="http://schemas.android.com/apk/res/android">
diff --git a/lib/package.json b/lib/package.json
index 1903983f61..2accaaaf3f 100644
--- a/lib/package.json
+++ b/lib/package.json
@@ -1,6 +1,6 @@
{
"name": "uilib-native",
- "version": "4.1.3",
+ "version": "4.2.0",
"homepage": "https://github.com/wix/react-native-ui-lib",
"description": "uilib native components (separated from js components)",
"main": "components/index.js",
diff --git a/src/components/button/Button.driver.ts b/src/components/button/Button.driver.ts
deleted file mode 100644
index eb609483f3..0000000000
--- a/src/components/button/Button.driver.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import {ButtonProps} from './types';
-import {ImageDriver} from '../image/Image.driver';
-import {ComponentDriver, ComponentDriverArgs} from '../../testkit/Component.driver';
-import {TextDriver} from '../text/Text.driver';
-
-/**
- * Please run clear after each test
- */
-export class ButtonDriver extends ComponentDriver {
- private readonly labelDriver: TextDriver;
- private readonly iconDriver: ImageDriver;
-
- constructor(componentDriverArgs: ComponentDriverArgs) {
- super(componentDriverArgs);
-
- this.labelDriver = new TextDriver({...componentDriverArgs, testID: `${this.testID}.label`});
- this.iconDriver = new ImageDriver({...componentDriverArgs, testID: `${this.testID}.icon`});
- }
-
- isPressable = async () => {
- if (await this.exists()) {
- return typeof (await this.getElementProps()).onPress === 'function';
- } else {
- console.warn(`TextDriver: cannot click because testID:${this.testID} were not found`);
- return null;
- }
- };
-
- // label
- getLabelRootElement = () => this.labelDriver.getElement();
- isLabelExists = () => this.labelDriver.exists();
- getLabelContent = () => this.labelDriver.getTextContent();
- // icon
- getIconElement = () => this.iconDriver.getElement();
- isIconExists = () => this.iconDriver.exists();
-}
diff --git a/src/components/carousel/Carousel.driver.ts b/src/components/carousel/Carousel.driver.ts
deleted file mode 100644
index 0b8303a920..0000000000
--- a/src/components/carousel/Carousel.driver.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import {CarouselProps} from './types';
-import {ComponentDriver} from '../../testkit/Component.driver';
-
-export class CarouselDriver extends ComponentDriver {
- getContentOffset = async () => (await this.getElementProps()).contentOffset;
- scroll = async (delta: number) => (await this.uniDriver.selectorByTestId(this.testID)).scrollX(delta);
-}
diff --git a/src/components/picker/Picker.driver.ts b/src/components/picker/Picker.driver.ts
deleted file mode 100644
index 6056991456..0000000000
--- a/src/components/picker/Picker.driver.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import {PickerProps} from './types';
-import {ComponentDriver} from '../../testkit/Component.driver';
-
-export class PickerDriver extends ComponentDriver {
- getPickerOverlay = async () => await this.getByTestId(`${this.testID}.overlay`);
- getPickerOverlayProps = async () => await this.getPropsByTestId(`${this.testID}.overlay`);
-}
diff --git a/src/components/sectionsWheelPicker/SectionsWheelPicker.driver.tsx b/src/components/sectionsWheelPicker/SectionsWheelPicker.driver.tsx
index a823230601..2c8e02b492 100644
--- a/src/components/sectionsWheelPicker/SectionsWheelPicker.driver.tsx
+++ b/src/components/sectionsWheelPicker/SectionsWheelPicker.driver.tsx
@@ -1,16 +1,17 @@
import _ from 'lodash';
+import type {ReactTestInstance} from 'react-test-renderer';
import {useComponentDriver, ComponentProps} from '../../testkit/new/Component.driver';
import {WheelPickerDriver} from '../WheelPicker/WheelPicker.driver';
-import {SectionsWheelPickerProps} from './index';
+import type {SectionsWheelPickerProps} from './index';
export const SectionsWheelPickerDriver = (props: ComponentProps) => {
const driver = useComponentDriver(props);
- const sections = driver.getElement().children as SectionsWheelPickerProps['sections'];
+ const sections = _.map(driver.getElement().children as ReactTestInstance[], (child) => child.props) as SectionsWheelPickerProps['sections'];
const sectionsDrivers = _.map(sections, (section, index) => {
const sectionTestID = `${props.testID}.${index}`;
return WheelPickerDriver({
renderTree: props.renderTree,
- testID: section?.testID || sectionTestID
+ testID: section.testID || sectionTestID
});
});
return {...driver, sections, sectionsDrivers};
diff --git a/src/components/sortableGridList/SortableItem.tsx b/src/components/sortableGridList/SortableItem.tsx
index a42cf9e75d..6f7c4ee023 100644
--- a/src/components/sortableGridList/SortableItem.tsx
+++ b/src/components/sortableGridList/SortableItem.tsx
@@ -26,7 +26,8 @@ function SortableItem(props: PropsWithChildren {
isDragging.value = true;
-
const translation = getTranslationByOrderChange(currIndex.value, initialIndex.value);
translateX.value = translation.x;
translateY.value = translation.y;
@@ -134,8 +134,23 @@ function SortableItem(props: PropsWithChildren oldOrder;
+ if (shouldMoveOthersDown) {
+ for (let i = oldOrder; i < newOrder; i++) {
+ newItemsOrder[i] = itemsOrder.value[i + 1];
+ }
+ } else {
+ for (let i = oldOrder; i > newOrder; i--) {
+ newItemsOrder[i] = itemsOrder.value[i - 1];
+ }
+ }
+ newItemsOrder[newOrder] = id;
+ } else {
+ newItemsOrder[newOrder] = id;
+ newItemsOrder[oldOrder] = itemIdToSwap;
+ }
+
itemsOrder.value = newItemsOrder;
}
}
diff --git a/src/components/sortableGridList/__tests__/index.spec.tsx b/src/components/sortableGridList/__tests__/index.spec.tsx
new file mode 100644
index 0000000000..663fb496e7
--- /dev/null
+++ b/src/components/sortableGridList/__tests__/index.spec.tsx
@@ -0,0 +1,50 @@
+import React from 'react';
+import {render} from '@testing-library/react-native';
+import View from '../../view';
+import Text from '../../text';
+import SortableGridList, {SortableGridListProps} from '../';
+import {useDraggableDriver} from '../../../testkit/new/useDraggable.driver';
+import {useComponentDriver} from '../../../testkit/new/Component.driver';
+
+const testID = 'sortable-grid-list';
+const TEST_DATA = Array(9)
+ .fill(0)
+ .map((_, index) => ({id: `${index}`}));
+const itemsTestId = (id: string) => `${testID}.item.${id}`;
+const testRenderItem: SortableGridListProps<(typeof TEST_DATA)[number]>['renderItem'] = ({item}) => {
+ return (
+
+ {item.id}
+
+ );
+};
+
+const TestCase = (props: Omit) => {
+ return ;
+};
+
+describe('SortableGridlist', () => {
+ it('should render a sortable grid list', () => {
+ render();
+ });
+ it('should reorder by index', () => {
+ const onOrderChange = jest.fn();
+ const renderTree = render();
+ const driverItem = useDraggableDriver(useComponentDriver({renderTree, testID: itemsTestId('0')}));
+ driverItem.drag(150); // Items height is 50 but dragging 100 doesn't work for some reason. 150 works and drags one row down.
+ expect(onOrderChange).toHaveBeenCalledTimes(1);
+ const newOrder = [1, 2, 3, 0, 4, 5, 6, 7, 8];
+ expect(onOrderChange).toHaveBeenCalledWith(newOrder.map(index => TEST_DATA[index]),
+ newOrder.map(index => TEST_DATA[index].id));
+ });
+ it('should reorder by swapping', () => {
+ const onOrderChange = jest.fn();
+ const renderTree = render();
+ const driverItem = useDraggableDriver(useComponentDriver({renderTree, testID: itemsTestId('0')}));
+ driverItem.drag(150);
+ expect(onOrderChange).toHaveBeenCalledTimes(1);
+ const newOrder = [3, 1, 2, 0, 4, 5, 6, 7, 8];
+ expect(onOrderChange).toHaveBeenCalledWith(newOrder.map(index => TEST_DATA[index]),
+ newOrder.map(index => TEST_DATA[index].id));
+ });
+});
diff --git a/src/components/sortableGridList/index.tsx b/src/components/sortableGridList/index.tsx
index 0dbed5eb5a..e231582681 100644
--- a/src/components/sortableGridList/index.tsx
+++ b/src/components/sortableGridList/index.tsx
@@ -17,7 +17,7 @@ function generateItemsOrder(data: SortableGridListProps['data']) {
}
function SortableGridList(props: SortableGridListProps) {
- const {renderItem, onOrderChange, flexMigration, ...others} = props;
+ const {renderItem, onOrderChange, flexMigration, orderByIndex = false, ...others} = props;
const {itemContainerStyle, numberOfColumns, listStyle, listContentStyle, listColumnWrapperStyle} =
useGridLayout(props);
@@ -60,13 +60,14 @@ function SortableGridList(props: SortableGridListProps) {
itemsOrder={itemsOrder}
id={item.id}
onChange={onChange}
+ orderByIndex={orderByIndex}
>
{/* @ts-expect-error */}
{renderItem({item, index})}
);
},
- [data, itemContainerStyle, onChange, renderItem]);
+ [data, itemContainerStyle, onChange, renderItem, orderByIndex]);
return (
diff --git a/src/components/sortableGridList/sortableGridList.api.json b/src/components/sortableGridList/sortableGridList.api.json
index b4b20023a8..d0cab53927 100644
--- a/src/components/sortableGridList/sortableGridList.api.json
+++ b/src/components/sortableGridList/sortableGridList.api.json
@@ -27,6 +27,11 @@
"name": "flexMigration",
"type": "boolean",
"description": "A temporary migration flag for enabling flex on the list's container (like it should be by default)"
+ },
+ {
+ "name": "orderByIndex",
+ "type": "boolean",
+ "description": "Wether to reorder the items by index instead of by swapping locations.\nItems will move to the new index by pushing other items ahead or aback instead of swapping places with the item at the new index."
}
],
"snippet": [
diff --git a/src/components/sortableGridList/types.ts b/src/components/sortableGridList/types.ts
index 44ced27dcf..2e072bba12 100644
--- a/src/components/sortableGridList/types.ts
+++ b/src/components/sortableGridList/types.ts
@@ -16,6 +16,11 @@ export interface SortableGridListProps extends GridListBaseProps, Scrol
* Temporary migration flag for enabling flex on the container of the list (like it should be by default)
*/
flexMigration?: boolean;
+ /**
+ * Wether to reorder the items by index instead of by replacing locations.
+ * Items will move to the new index by pushing other items ahead or aback instead of swapping places with the item at the new index.
+ */
+ orderByIndex?: boolean
}
export interface SortableItemProps {
@@ -24,4 +29,5 @@ export interface SortableItemProps {
itemsOrder: Animated.SharedValue;
onChange: () => void;
style: StyleProp;
+ orderByIndex?: boolean;
}
diff --git a/src/components/sortableList/SortableListItem.driver.ts b/src/components/sortableList/SortableListItem.driver.ts
deleted file mode 100644
index 0e14a50bb4..0000000000
--- a/src/components/sortableList/SortableListItem.driver.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import _ from 'lodash';
-import {SortableListProps, SortableListItemProps} from './types';
-import {ComponentDriver} from '../../testkit/Component.driver';
-
-/**
- * Please run clear after each test
- */
-export class SortableListItemDriver extends ComponentDriver> {
- dragUp = async (indices: number) => {
- this.validateIndices(indices);
- const data = _.times(indices, index => {
- return {
- translationY: -52 * (index + 1)
- };
- });
-
- await this.uniDriver.selectorByTestId(this.testID).then(driver => driver.drag(data));
- };
-
- dragDown = async (indices: number) => {
- this.validateIndices(indices);
- const data = _.times(indices, index => {
- return {
- translationY: 52 * (index + 1)
- };
- });
-
- await this.uniDriver.selectorByTestId(this.testID).then(driver => driver.drag(data));
- };
-
- private validateIndices = (indices: number) => {
- if (indices <= 0 || !Number.isInteger(indices)) {
- throw Error('indices must be a positive integer');
- }
- };
-}
diff --git a/src/components/tabController/TabBar.tsx b/src/components/tabController/TabBar.tsx
index 4c7c50f89f..adda6923bf 100644
--- a/src/components/tabController/TabBar.tsx
+++ b/src/components/tabController/TabBar.tsx
@@ -142,8 +142,8 @@ const TabBar = (props: Props) => {
enableShadow,
shadowStyle: propsShadowStyle,
indicatorStyle,
- labelStyle,
- selectedLabelStyle,
+ labelStyle = DEFAULT_LABEL_STYLE,
+ selectedLabelStyle = DEFAULT_SELECTED_LABEL_STYLE,
labelColor,
selectedLabelColor,
uppercase,
@@ -151,10 +151,10 @@ const TabBar = (props: Props) => {
selectedIconColor,
activeBackgroundColor,
backgroundColor = Colors.$backgroundElevated,
- faderProps,
+ faderProps = DEFAULT_FADER_PROPS,
containerWidth: propsContainerWidth,
centerSelected,
- spreadItems,
+ spreadItems = true,
indicatorInsets = Spacings.s4,
indicatorWidth,
containerStyle,
@@ -319,12 +319,6 @@ const TabBar = (props: Props) => {
};
TabBar.displayName = 'TabController.TabBar';
-TabBar.defaultProps = {
- labelStyle: DEFAULT_LABEL_STYLE,
- selectedLabelStyle: DEFAULT_SELECTED_LABEL_STYLE,
- faderProps: DEFAULT_FADER_PROPS,
- spreadItems: true
-};
const styles = StyleSheet.create({
container: {
diff --git a/src/components/textField/__tests__/index.driver.spec.tsx b/src/components/textField/__tests__/index.driver.spec.tsx
index 15414b1e2b..5151ccf7e1 100644
--- a/src/components/textField/__tests__/index.driver.spec.tsx
+++ b/src/components/textField/__tests__/index.driver.spec.tsx
@@ -169,6 +169,31 @@ describe('TextField', () => {
expect(textFieldDriver.getValidationMessage().exists()).toBe(!!defaultProps?.preset);
});
+ it('should render validationMessage if validationMessage passed and remove it when validationMessage is changed to undefined', () => {
+ const renderTree = render();
+ const textFieldDriver = TextFieldDriver({renderTree, testID: TEXT_FIELD_TEST_ID});
+
+ expect(textFieldDriver.getValidationMessage().exists()).toBe(true);
+ expect(textFieldDriver.getValidationMessage().getText()).toEqual('mock message');
+
+ renderTree.rerender();
+
+ expect(textFieldDriver.getValidationMessage().exists()).toBe(false);
+ });
+
+ it('should not render validationMessage if validationMessage is undefined and add it when validationMessage is passed', () => {
+ const renderTree = render();
+ const textFieldDriver = TextFieldDriver({renderTree, testID: TEXT_FIELD_TEST_ID});
+
+ expect(textFieldDriver.getValidationMessage().exists()).toBe(false);
+
+ renderTree.rerender();
+
+ expect(textFieldDriver.getValidationMessage().exists()).toBe(true);
+ expect(textFieldDriver.getValidationMessage().getText()).toEqual('mock message');
+ });
+
+
it('should render validationMessage on start if input required and validateOnStart passed', () => {
const renderTree = render();
const textFieldDriver = TextFieldDriver({renderTree, testID: TEXT_FIELD_TEST_ID});
diff --git a/src/components/textField/index.tsx b/src/components/textField/index.tsx
index 3fc4e308ab..e2e1ac8a53 100644
--- a/src/components/textField/index.tsx
+++ b/src/components/textField/index.tsx
@@ -209,7 +209,7 @@ const TextField = (props: InternalTextFieldProps) => {
{/* */}
-
+
{validationMessagePosition === ValidationMessagePosition.BOTTOM && (
{};
-
-const defaultProps = {
- testID: 'dialog',
- useSafeArea: true,
- onDismiss,
- bottom: true,
- centerH: true
-};
-
-const TestCase = props => {
- const [visible, setVisible] = useState(props.visible);
-
- useEffect(() => {
- setVisible(props.visible);
- }, [props.visible]);
-
- const openDialog = useCallback(() => {
- setVisible(true);
- }, []);
-
- const closeDialog = useCallback(() => {
- setVisible(false);
- }, []);
-
- return (
-
-
-
- );
-};
-
-describe('Incubator.Dialog', () => {
- it('Incubator.Dialog should exist only if visible', async () => {
- const onDismiss = jest.fn();
- const component = ;
- const dialogDriver = new ComponentDriver({component, testID: 'dialog'});
- expect(await dialogDriver.exists()).toBeFalsy();
- const openButtonDriver = new ButtonDriver({component, testID: 'openButton'});
- await openButtonDriver.press();
- expect(await dialogDriver.exists()).toBeTruthy();
- expect(onDismiss).toHaveBeenCalledTimes(0);
- const closeButtonDriver = new ButtonDriver({component, testID: 'closeButton'});
- await closeButtonDriver.press();
- expect(await dialogDriver.exists()).toBeFalsy();
- // TODO:
- // expect(onDismiss).toHaveBeenCalledTimes(1);
- });
-});
diff --git a/yarn.lock b/yarn.lock
index bcf5d50ea5..38a19e9cb7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4204,9 +4204,9 @@ fast-levenshtein@^2.0.6:
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
fast-xml-parser@^4.0.12:
- version "4.3.6"
- resolved "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.6.tgz#190f9d99097f0c8f2d3a0e681a10404afca052ff"
- integrity sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==
+ version "4.4.1"
+ resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz#86dbf3f18edf8739326447bcaac31b4ae7f6514f"
+ integrity sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==
dependencies:
strnum "^1.0.5"