Skip to content

Commit

Permalink
fixes searchtext bound property (#234)
Browse files Browse the repository at this point in the history
* fixes searchtext bound property

* updated testsnap
  • Loading branch information
Ramakrishnan24689 authored Apr 17, 2023
1 parent 90cea63 commit 4cb967f
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 30 deletions.
6 changes: 6 additions & 0 deletions SearchBox/SearchBox/ControlManifest.Input.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<control namespace="PowerCAT" constructor="SearchBox" version="0.0.1" display-name-key="SearchBox" description-key="SearchBox_desc" control-type="virtual">
<!--<property name="DefaultValue" display-name-key="SearchBox_DefaultValue" description-key="SearchBox_DefaultValue_Desc" of-type="SingleLine.Text" usage="input"/>-->
<property name="SearchText" display-name-key="SearchBox_SearchText" description-key="SearchBox_SearchText_Desc" of-type="SingleLine.Text" usage="bound"/>
<property name="Theme" display-name-key="Theme" of-type="Multiple" usage="input" required="false" />
<property name="AccessibilityLabel" display-name-key="AccessibilityLabel" of-type="SingleLine.Text" usage="input" required="false" />
Expand All @@ -10,6 +11,11 @@
<property name="PlaceHolderText" display-name-key="PlaceHolderText" of-type="SingleLine.Text" usage="input" required="false" default-value="Search" />
<property name="InputEvent" display-name-key="InputEvent" of-type="SingleLine.Text" usage="input" required="false"/>
<property name="DelayOutput" display-name-key="DelayOutput" of-type="TwoOptions" usage="input" required="false" />
<common-event name="OnChange" />
<feature-usage>
<!-- No common events (OnChange, OnSelect, etc.) are shown unless explicitly declared in the manifest -->
<uses-feature name="ExplicitCommonEvents" required="true" />
</feature-usage>
<resources>
<code path="index.ts" order="1" />
<resx path="strings/SearchBox.1033.resx" version="1.0.0" />
Expand Down
2 changes: 1 addition & 1 deletion SearchBox/SearchBox/ManifestConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export const enum InputEvents {

export const enum InputProperties {
InputEvent = 'InputEvent',
SelectedKey = 'SelectedKey',
SearchText = 'SearchText',
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ exports[`SearchBox renders 1`] = `
disabled={false}
height={-1}
iconName=""
onChanged={[Function]}
onChange={[Function]}
placeholderText=""
setFocus=""
themeJSON=""
Expand Down Expand Up @@ -156,7 +156,7 @@ exports[`SearchBox theme 1`] = `
display: none;
}
disabled={false}
id="SearchBox3"
id="SearchBox6"
onBlur={[Function]}
onChange={[Function]}
onInput={[Function]}
Expand Down
2 changes: 1 addition & 1 deletion SearchBox/SearchBox/components/Component.types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export interface ISearchBoxComponentProps {
width?: number;
height?: number;
onChanged: (newValue: string | undefined) => void;
onChange: (event?: React.ChangeEvent<HTMLInputElement>, newValue?: string) => void;
themeJSON?: string;
ariaLabel?: string;
underLined?: boolean;
Expand Down
30 changes: 14 additions & 16 deletions SearchBox/SearchBox/components/SearchBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,10 @@ import { SearchBox, createTheme, IPartialTheme, ThemeProvider, IIconProps, merge
import { ISearchBoxComponentProps } from './Component.types';

export const SearchBoxComponent = React.memo((props: ISearchBoxComponentProps) => {
const {
onChanged,
themeJSON,
ariaLabel,
placeholderText,
underLined,
disabled,
disableAnimation,
setFocus,
value,
} = props;
const { onChange, themeJSON, ariaLabel, placeholderText, underLined, disabled, disableAnimation, setFocus, value } =
props;
const filterIcon: IIconProps = { iconName: props.iconName };
const [searchText, setSearchText] = React.useState(value);
const rootRef = React.useRef<HTMLDivElement>(null);
const theme = React.useMemo(() => {
try {
Expand All @@ -25,9 +17,15 @@ export const SearchBoxComponent = React.memo((props: ISearchBoxComponentProps) =
}
}, [themeJSON]);

const onChange = (event?: React.ChangeEvent<HTMLInputElement>, newValue?: string): void => {
onChanged(newValue);
};
React.useEffect(() => {
value !== searchText && setSearchText(value);
}, [value, searchText]);

function onChangeEvent(ev?: React.ChangeEvent<HTMLInputElement>, newValue?: string) {
setSearchText(newValue);
onChange(ev, newValue);
}

const wrapperClass = mergeStyles({
width: props.width,
});
Expand All @@ -45,15 +43,15 @@ export const SearchBoxComponent = React.memo((props: ISearchBoxComponentProps) =
<ThemeProvider theme={theme}>
<SearchBox
placeholder={placeholderText}
onChange={onChange}
onChange={onChangeEvent}
ariaLabel={ariaLabel}
underlined={underLined}
iconProps={filterIcon}
disabled={disabled}
disableAnimation={disableAnimation}
className={wrapperClass}
ref={rootRef}
value={value}
value={searchText}
/>
</ThemeProvider>
);
Expand Down
32 changes: 22 additions & 10 deletions SearchBox/SearchBox/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@ import * as React from 'react';
import { IInputs, IOutputs } from './generated/ManifestTypes';
import { SearchBoxComponent } from './components/SearchBox';
import { ISearchBoxComponentProps } from './components/Component.types';
import { InputEvents } from './ManifestConstants';
import { InputEvents, InputProperties } from './ManifestConstants';
import { Async } from '@fluentui/react';

export class SearchBox implements ComponentFramework.ReactControl<IInputs, IOutputs> {
private static readonly DELAY_TIMEOUT: number = 500;
context: ComponentFramework.Context<IInputs>;
notifyOutputChanged: ((debounce?: boolean) => void) | null;
searchTextValue: string;
defaultValue: string;
setFocus = '';
asyncFluent: Async;
debouncedOutputChanged: (debounce?: boolean) => void;
delayOutput: boolean;

constructor() {
this.onChange = this.onChange.bind(this);
this.onChanged = this.onChanged.bind(this);
this.asyncFluent = new Async();
}

Expand Down Expand Up @@ -46,12 +47,20 @@ export class SearchBox implements ComponentFramework.ReactControl<IInputs, IOutp
this.delayOutput = context.parameters.DelayOutput.raw;
const inputEvent = this.context.parameters.InputEvent.raw;
const eventChanged = inputEvent && this.setFocus !== inputEvent;
this.searchTextValue = context.parameters.SearchText.raw ?? '';
const valueChanged = context.updatedProperties.indexOf(InputProperties.SearchText) > -1;
if (valueChanged) {
const value = context.parameters.SearchText.raw;
// If the default value is different from searchText value
if (value && this.searchTextValue !== value) {
this.searchTextValue = value;
this.notifyOutputChanged;
}
}
if (eventChanged && inputEvent.startsWith(InputEvents.SetFocus)) {
this.setFocus = inputEvent;
}
const props: ISearchBoxComponentProps = {
onChanged: this.onChange,
onChange: this.onChanged,
themeJSON: context.parameters.Theme.raw ?? '',
ariaLabel: context.parameters?.AccessibilityLabel.raw ?? '',
underLined: context.parameters.Underlined.raw ?? false,
Expand All @@ -62,7 +71,7 @@ export class SearchBox implements ComponentFramework.ReactControl<IInputs, IOutp
width: allocatedWidth,
height: allocatedHeight,
setFocus: this.setFocus,
value: this.searchTextValue,
value: this.searchTextValue ?? '',
};

return React.createElement(SearchBoxComponent, props);
Expand All @@ -72,11 +81,14 @@ export class SearchBox implements ComponentFramework.ReactControl<IInputs, IOutp
* Called when a change is detected from the control. Updates the searchTextValue variable that is assigned to the output SearchText.
* @param newValue a string returned as the input search text
*/
private onChange = (newValue?: string): void => {
this.searchTextValue = newValue || '';
this.delayOutput
? this.debouncedOutputChanged && this.debouncedOutputChanged()
: this.notifyOutputChanged && this.notifyOutputChanged();
private onChanged = (event?: React.ChangeEvent<HTMLInputElement>, newValue?: string): void => {
// If the new Value is different from searchTextValue
if (this.searchTextValue !== newValue) {
this.searchTextValue = newValue ?? '';
this.delayOutput
? this.debouncedOutputChanged && this.debouncedOutputChanged()
: this.notifyOutputChanged && this.notifyOutputChanged();
}
};

/**
Expand Down
6 changes: 6 additions & 0 deletions SearchBox/SearchBox/strings/SearchBox.1033.resx
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,10 @@
<data name="SearchBox_SearchText_Desc" xml:space="preserve">
<value>Represents the default as well as the current value of search box</value>
</data>
<data name="SearchBox_DefaultValue" xml:space="preserve">
<value>Default value</value>
</data>
<data name="SearchBox_DefaultValue_Desc" xml:space="preserve">
<value>Default value to set for the search box. This can be used only once</value>
</data>
</root>
3 changes: 3 additions & 0 deletions SearchBox/featureconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"pcfAllowEvents": "on"
}

0 comments on commit 4cb967f

Please sign in to comment.