From 942a99a52ec40df6e4d3ad31eac86f9125e0e4ca Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Thu, 24 Aug 2023 12:19:47 +0530 Subject: [PATCH 1/8] Adding useDebounce to the react utils --- .../framework/esm-react-utils/src/index.ts | 1 + .../esm-react-utils/src/useDebounce.ts | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 packages/framework/esm-react-utils/src/useDebounce.ts diff --git a/packages/framework/esm-react-utils/src/index.ts b/packages/framework/esm-react-utils/src/index.ts index 7644f5a91..84f5fe325 100644 --- a/packages/framework/esm-react-utils/src/index.ts +++ b/packages/framework/esm-react-utils/src/index.ts @@ -26,3 +26,4 @@ export * from "./useStore"; export * from "./useVisit"; export * from "./useVisitTypes"; export * from "./usePagination"; +export * from "./useDebounce"; diff --git a/packages/framework/esm-react-utils/src/useDebounce.ts b/packages/framework/esm-react-utils/src/useDebounce.ts new file mode 100644 index 000000000..426dd7a0e --- /dev/null +++ b/packages/framework/esm-react-utils/src/useDebounce.ts @@ -0,0 +1,43 @@ +import { useEffect, useState } from "react"; + +/** + * This hook will help us out in getting the debounced value of a state variable, + * which then makes a request to the backend. + * + * For example, + * + * ```tsx + * import { useDebounceValue } from "@openmrs/esm-react-utils"; + * + * function MyComponent() { + * const [searchTerm, setSearchTerm] = useState(''); + * const debouncedSearchTerm = useDebounce(searchTerm); + * const swrResult = useSWR(`/api/search?q=${debouncedSearchTerm}`) + * + * return ( + * setSearchTerm(e.target.value)} + value={searchTerm} + /> + * ) + * } + * + * ``` + * + * @param value + * @param delay number = 300 + * @returns debounceValue + */ +export function useDebounceValue(value: T, delay: number = 300) { + const [debounceValue, setDebounceValue] = useState(value); + useEffect(() => { + const timer = setTimeout(() => { + setDebounceValue(value); + }, delay); + return () => { + clearTimeout(timer); + }; + }, [value, delay]); + return debounceValue; +} From fd6484db63f37d912aa8910440989dbf5e126d50 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Tue, 5 Sep 2023 23:12:04 +0530 Subject: [PATCH 2/8] Review changes --- packages/framework/esm-framework/mock.tsx | 1 + packages/framework/esm-react-utils/src/public.ts | 1 + .../framework/esm-react-utils/src/useDebounce.ts | 15 ++++++++------- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/framework/esm-framework/mock.tsx b/packages/framework/esm-framework/mock.tsx index 1b422e067..49031d98d 100644 --- a/packages/framework/esm-framework/mock.tsx +++ b/packages/framework/esm-framework/mock.tsx @@ -304,3 +304,4 @@ export const showModal = jest.fn(); export const LeftNavMenu = jest.fn(); export const setLeftNav = jest.fn(); export const unsetLeftNav = jest.fn(); +export const useDebounce = jest.fn().mockImplementation((value) => value); diff --git a/packages/framework/esm-react-utils/src/public.ts b/packages/framework/esm-react-utils/src/public.ts index efd29149d..a837e5466 100644 --- a/packages/framework/esm-react-utils/src/public.ts +++ b/packages/framework/esm-react-utils/src/public.ts @@ -22,3 +22,4 @@ export * from "./useStore"; export * from "./useVisit"; export * from "./useVisitTypes"; export * from "./usePagination"; +export * from "./useDebounce"; diff --git a/packages/framework/esm-react-utils/src/useDebounce.ts b/packages/framework/esm-react-utils/src/useDebounce.ts index 426dd7a0e..bf3791d99 100644 --- a/packages/framework/esm-react-utils/src/useDebounce.ts +++ b/packages/framework/esm-react-utils/src/useDebounce.ts @@ -1,13 +1,14 @@ import { useEffect, useState } from "react"; /** - * This hook will help us out in getting the debounced value of a state variable, - * which then makes a request to the backend. + * This hook debounces a state variable. That state variable can then be used as the + * value of a controlled input, while the return value of this hook is used for making + * a request. * * For example, * * ```tsx - * import { useDebounceValue } from "@openmrs/esm-react-utils"; + * import { useDebounce } from "@openmrs/esm-react-utils"; * * function MyComponent() { * const [searchTerm, setSearchTerm] = useState(''); @@ -25,11 +26,11 @@ import { useEffect, useState } from "react"; * * ``` * - * @param value - * @param delay number = 300 - * @returns debounceValue + * @param value: The value that will be used to set `debounceValue` + * @param delay number = 300: The number of milliseconds to wait before updating `debounceValue` + * @returns debounceValue: The debounced value */ -export function useDebounceValue(value: T, delay: number = 300) { +export function useDebounce(value: T, delay: number = 300) { const [debounceValue, setDebounceValue] = useState(value); useEffect(() => { const timer = setTimeout(() => { From 50d0407295ceedd798e7fe3075af8504f5ed3c82 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Tue, 5 Sep 2023 23:12:36 +0530 Subject: [PATCH 3/8] Updated docs --- packages/framework/esm-framework/docs/API.md | 55 ++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index 2ac065b0d..b66ee4e4a 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -154,6 +154,7 @@ ### Other Functions - [ExtensionSlot](API.md#extensionslot) +- [useDebounce](API.md#usedebounce) ### Store Functions @@ -3751,6 +3752,60 @@ Passing a function as children ___ +### useDebounce + +▸ **useDebounce**<`T`\>(`value`, `delay?`): `T` + +This hook debounces a state variable. That state variable can then be used as the +value of a controlled input, while the return value of this hook is used for making +a request. + +For example, + +```tsx +import { useDebounce } from "@openmrs/esm-react-utils"; + +function MyComponent() { + const [searchTerm, setSearchTerm] = useState(''); + const debouncedSearchTerm = useDebounce(searchTerm); + const swrResult = useSWR(`/api/search?q=${debouncedSearchTerm}`) + + return ( + setSearchTerm(e.target.value)} +value={searchTerm} +/> + ) +} + +``` + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Parameters + +| Name | Type | Default value | Description | +| :------ | :------ | :------ | :------ | +| `value` | `T` | `undefined` | - | +| `delay` | `number` | `300` | number = 300: The number of milliseconds to wait before updating `debounceValue` | + +#### Returns + +`T` + +debounceValue: The debounced value + +#### Defined in + +[packages/framework/esm-react-utils/src/useDebounce.ts:33](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useDebounce.ts#L33) + +___ + ## Store Functions ### createGlobalStore From 92049aeb3f4a169d5495093bef883d8561d1dea8 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Tue, 5 Sep 2023 23:13:46 +0530 Subject: [PATCH 4/8] Fix the jsx doc --- packages/framework/esm-react-utils/src/useDebounce.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/framework/esm-react-utils/src/useDebounce.ts b/packages/framework/esm-react-utils/src/useDebounce.ts index bf3791d99..622259264 100644 --- a/packages/framework/esm-react-utils/src/useDebounce.ts +++ b/packages/framework/esm-react-utils/src/useDebounce.ts @@ -5,7 +5,7 @@ import { useEffect, useState } from "react"; * value of a controlled input, while the return value of this hook is used for making * a request. * - * For example, + * @example * * ```tsx * import { useDebounce } from "@openmrs/esm-react-utils"; From e662838ce6764f433db4ff998795f648927e5d40 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Tue, 5 Sep 2023 23:14:11 +0530 Subject: [PATCH 5/8] Updated docs --- packages/framework/esm-framework/docs/API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index b66ee4e4a..b48bca9fb 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -3760,7 +3760,7 @@ This hook debounces a state variable. That state variable can then be used as th value of a controlled input, while the return value of this hook is used for making a request. -For example, +**`example`** ```tsx import { useDebounce } from "@openmrs/esm-react-utils"; From d14575d0d64c759f5169f6ce360bb7774874287f Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Wed, 6 Sep 2023 12:18:09 +0200 Subject: [PATCH 6/8] Apply suggestions from code review --- .../esm-react-utils/src/useDebounce.ts | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/framework/esm-react-utils/src/useDebounce.ts b/packages/framework/esm-react-utils/src/useDebounce.ts index 426dd7a0e..25a0f0d1e 100644 --- a/packages/framework/esm-react-utils/src/useDebounce.ts +++ b/packages/framework/esm-react-utils/src/useDebounce.ts @@ -1,13 +1,13 @@ import { useEffect, useState } from "react"; /** - * This hook will help us out in getting the debounced value of a state variable, - * which then makes a request to the backend. - * - * For example, + * This hook debounces a state variable. That state variable can then be used as the + * value of a controlled input, while the return value of this hook is used for making + * a request. * + * @example * ```tsx - * import { useDebounceValue } from "@openmrs/esm-react-utils"; + * import { useDebounce } from "@openmrs/esm-react-utils"; * * function MyComponent() { * const [searchTerm, setSearchTerm] = useState(''); @@ -16,20 +16,19 @@ import { useEffect, useState } from "react"; * * return ( * setSearchTerm(e.target.value)} - value={searchTerm} - /> + * labelText={t('search', 'Search')} + * onChange={(e) => setSearchTerm(e.target.value)} + * value={searchTerm} + * /> * ) * } - * * ``` * - * @param value - * @param delay number = 300 - * @returns debounceValue + * @param value: The value that will be used to set `debounceValue` + * @param delay number = 300: The number of milliseconds to wait before updating `debounceValue` + * @returns debounceValue: The debounced value */ -export function useDebounceValue(value: T, delay: number = 300) { +export function useDebounce(value: T, delay: number = 300) { const [debounceValue, setDebounceValue] = useState(value); useEffect(() => { const timer = setTimeout(() => { From ddf51356cd4e3ad0cda433fbce59690b7a171f69 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Thu, 14 Sep 2023 22:46:33 -0400 Subject: [PATCH 7/8] Review feedback --- packages/framework/esm-framework/docs/API.md | 133 ++++++++++-------- .../esm-react-utils/src/useDebounce.ts | 3 +- 2 files changed, 80 insertions(+), 56 deletions(-) diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index b48bca9fb..4d6384a2d 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -26,6 +26,7 @@ - [toLocationObject](API.md#tolocationobject) - [toVisitTypeObject](API.md#tovisittypeobject) - [updateVisit](API.md#updatevisit) +- [useDebounce](API.md#usedebounce) - [useLocations](API.md#uselocations) - [usePatient](API.md#usepatient) - [useSession](API.md#usesession) @@ -62,6 +63,7 @@ - [formatDate](API.md#formatdate) - [formatDatetime](API.md#formatdatetime) - [formatTime](API.md#formattime) +- [getLocale](API.md#getlocale) - [isOmrsDateStrict](API.md#isomrsdatestrict) - [isOmrsDateToday](API.md#isomrsdatetoday) - [parseDate](API.md#parsedate) @@ -154,7 +156,6 @@ ### Other Functions - [ExtensionSlot](API.md#extensionslot) -- [useDebounce](API.md#usedebounce) ### Store Functions @@ -819,6 +820,16 @@ and *must* only be used once within that ``. ___ +### OpenmrsDatePicker + +• `Const` **OpenmrsDatePicker**: `React.FC`<`OpenmrsDatePickerProps`\> + +#### Defined in + +[packages/framework/esm-styleguide/src/datepicker/openmrs/openmrs-date-picker.component.tsx:41](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/datepicker/openmrs/openmrs-date-picker.component.tsx#L41) + +___ + ### backendDependencies • `Const` **backendDependencies**: `Object` @@ -1367,6 +1378,58 @@ ___ ___ +### useDebounce + +▸ **useDebounce**<`T`\>(`value`, `delay?`): `T` + +This hook debounces a state variable. That state variable can then be used as the +value of a controlled input, while the return value of this hook is used for making +a request. + +**`example`** +```tsx +import { useDebounce } from "@openmrs/esm-react-utils"; + +function MyComponent() { + const [searchTerm, setSearchTerm] = useState(''); + const debouncedSearchTerm = useDebounce(searchTerm); + const swrResult = useSWR(`/api/search?q=${debouncedSearchTerm}`) + + return ( + setSearchTerm(e.target.value)} + value={searchTerm} + /> + ) +} +``` + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Parameters + +| Name | Type | Default value | Description | +| :------ | :------ | :------ | :------ | +| `value` | `T` | `undefined` | T: The value that will be used to set `debounceValue` | +| `delay` | `number` | `300` | number = 300: The number of milliseconds to wait before updating `debounceValue` | + +#### Returns + +`T` + +debounceValue: The debounced value + +#### Defined in + +[packages/framework/esm-react-utils/src/useDebounce.ts:32](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useDebounce.ts#L32) + +___ + ### useLocations ▸ **useLocations**(): [`Location`](interfaces/Location.md)[] @@ -1970,6 +2033,20 @@ Formats the input as a time, according to the current locale. ___ +### getLocale + +▸ **getLocale**(): `string` + +#### Returns + +`string` + +#### Defined in + +[packages/framework/esm-utils/src/omrs-dates.ts:269](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-utils/src/omrs-dates.ts#L269) + +___ + ### isOmrsDateStrict ▸ **isOmrsDateStrict**(`omrsPayloadString`): `boolean` @@ -3752,60 +3829,6 @@ Passing a function as children ___ -### useDebounce - -▸ **useDebounce**<`T`\>(`value`, `delay?`): `T` - -This hook debounces a state variable. That state variable can then be used as the -value of a controlled input, while the return value of this hook is used for making -a request. - -**`example`** - -```tsx -import { useDebounce } from "@openmrs/esm-react-utils"; - -function MyComponent() { - const [searchTerm, setSearchTerm] = useState(''); - const debouncedSearchTerm = useDebounce(searchTerm); - const swrResult = useSWR(`/api/search?q=${debouncedSearchTerm}`) - - return ( - setSearchTerm(e.target.value)} -value={searchTerm} -/> - ) -} - -``` - -#### Type parameters - -| Name | -| :------ | -| `T` | - -#### Parameters - -| Name | Type | Default value | Description | -| :------ | :------ | :------ | :------ | -| `value` | `T` | `undefined` | - | -| `delay` | `number` | `300` | number = 300: The number of milliseconds to wait before updating `debounceValue` | - -#### Returns - -`T` - -debounceValue: The debounced value - -#### Defined in - -[packages/framework/esm-react-utils/src/useDebounce.ts:33](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useDebounce.ts#L33) - -___ - ## Store Functions ### createGlobalStore diff --git a/packages/framework/esm-react-utils/src/useDebounce.ts b/packages/framework/esm-react-utils/src/useDebounce.ts index b82db3428..0415ee19d 100644 --- a/packages/framework/esm-react-utils/src/useDebounce.ts +++ b/packages/framework/esm-react-utils/src/useDebounce.ts @@ -1,3 +1,4 @@ +/** @module @category API */ import { useEffect, useState } from "react"; /** @@ -24,7 +25,7 @@ import { useEffect, useState } from "react"; * } * ``` * - * @param value: The value that will be used to set `debounceValue` + * @param value T: The value that will be used to set `debounceValue` * @param delay number = 300: The number of milliseconds to wait before updating `debounceValue` * @returns debounceValue: The debounced value */ From 08501315ed26e817bace37afe3665b2c57aaaa48 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Thu, 14 Sep 2023 22:49:01 -0400 Subject: [PATCH 8/8] Revise docstring --- packages/framework/esm-framework/docs/API.md | 6 +++--- packages/framework/esm-react-utils/src/useDebounce.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index 4d6384a2d..0baa26354 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -1415,14 +1415,14 @@ function MyComponent() { | Name | Type | Default value | Description | | :------ | :------ | :------ | :------ | -| `value` | `T` | `undefined` | T: The value that will be used to set `debounceValue` | -| `delay` | `number` | `300` | number = 300: The number of milliseconds to wait before updating `debounceValue` | +| `value` | `T` | `undefined` | The value that will be used to set `debounceValue` | +| `delay` | `number` | `300` | The number of milliseconds to wait before updating `debounceValue` | #### Returns `T` -debounceValue: The debounced value +The debounced value #### Defined in diff --git a/packages/framework/esm-react-utils/src/useDebounce.ts b/packages/framework/esm-react-utils/src/useDebounce.ts index 0415ee19d..d1266f6a5 100644 --- a/packages/framework/esm-react-utils/src/useDebounce.ts +++ b/packages/framework/esm-react-utils/src/useDebounce.ts @@ -25,9 +25,9 @@ import { useEffect, useState } from "react"; * } * ``` * - * @param value T: The value that will be used to set `debounceValue` - * @param delay number = 300: The number of milliseconds to wait before updating `debounceValue` - * @returns debounceValue: The debounced value + * @param value The value that will be used to set `debounceValue` + * @param delay The number of milliseconds to wait before updating `debounceValue` + * @returns The debounced value */ export function useDebounce(value: T, delay: number = 300) { const [debounceValue, setDebounceValue] = useState(value);