Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes searchtext bound property #234

Merged
merged 2 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
}