Skip to content

Commit 844043d

Browse files
thassiovtassoevand-gubert
authored
feat(fuselage-ui-kit): allow dispatchment of actions from input elements (#747)
Co-authored-by: Tasso Evangelista <tasso.evangelista@rocket.chat> Co-authored-by: Douglas Gubert <douglas.gubert@gmail.com>
1 parent ca9b3e1 commit 844043d

File tree

5 files changed

+48
-1
lines changed

5 files changed

+48
-1
lines changed

packages/fuselage-ui-kit/src/contexts/kitContext.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { InputElementDispatchAction } from '@rocket.chat/ui-kit';
12
import { createContext, useContext } from 'react';
23

34
type ActionParams = {
@@ -6,6 +7,7 @@ type ActionParams = {
67
actionId: string;
78
value: unknown;
89
viewId?: string;
10+
dispatchActionConfig?: InputElementDispatchAction[];
911
};
1012

1113
type UiKitContext = {

packages/fuselage-ui-kit/src/hooks/useUiKitState.ts

+39-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export const useUiKitState: <TElement extends UiKit.ActionableElement>(
3535
| { target: { value: UiKit.ActionOf<TElement> } }
3636
) => void
3737
] = (rest, context) => {
38-
const { blockId, actionId, appId } = rest;
38+
const { blockId, actionId, appId, dispatchActionConfig } = rest;
3939
const {
4040
action,
4141
appId: appIdFromContext,
@@ -72,6 +72,27 @@ export const useUiKitState: <TElement extends UiKit.ActionableElement>(
7272
setLoading(false);
7373
});
7474

75+
// Used for triggering actions on text inputs. Removing the load state
76+
// makes the text input field remain focused after running the action
77+
const noLoadStateActionFunction = useMutableCallback(async (e) => {
78+
const {
79+
target: { value },
80+
} = e;
81+
setValue(value);
82+
state && (await state({ blockId, appId, actionId, value, viewId }, e));
83+
await action(
84+
{
85+
blockId,
86+
appId: appId || appIdFromContext,
87+
actionId,
88+
value,
89+
viewId,
90+
dispatchActionConfig,
91+
},
92+
e
93+
);
94+
});
95+
7596
const stateFunction = useMutableCallback(async (e) => {
7697
const {
7798
target: { value },
@@ -94,6 +115,23 @@ export const useUiKitState: <TElement extends UiKit.ActionableElement>(
94115
[loading, setLoading, error, value]
95116
);
96117

118+
if (context === UiKit.BlockContext.FORM) {
119+
if (
120+
rest.type === 'plain_text_input' &&
121+
Array.isArray(rest?.dispatchActionConfig) &&
122+
rest.dispatchActionConfig.includes('on_character_entered')
123+
) {
124+
return [result, noLoadStateActionFunction];
125+
}
126+
127+
if (
128+
Array.isArray(rest?.dispatchActionConfig) &&
129+
rest.dispatchActionConfig.includes('on_item_selected')
130+
) {
131+
return [result, actionFunction];
132+
}
133+
}
134+
97135
if (
98136
context &&
99137
[UiKit.BlockContext.SECTION, UiKit.BlockContext.ACTION].includes(context)
+2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import type { ConfirmationDialog } from './ConfirmationDialog';
2+
import type { InputElementDispatchAction } from './InputElementDispatchAction';
23

34
export type Actionable<Block> = Block & {
45
appId: string;
56
blockId: string;
67
actionId: string;
78
confirm?: ConfirmationDialog;
9+
dispatchActionConfig?: InputElementDispatchAction[];
810
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export type InputElementDispatchAction =
2+
| 'on_character_entered'
3+
| 'on_item_selected';

packages/ui-kit/src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export { InputBlock } from './blocks/layout/InputBlock';
3434
export { SectionBlock } from './blocks/layout/SectionBlock';
3535
export { LayoutBlock } from './blocks/LayoutBlock';
3636

37+
export { InputElementDispatchAction } from './blocks/InputElementDispatchAction';
38+
3739
export { Block } from './blocks/Block';
3840
export { RenderableBlock } from './blocks/RenderableBlock';
3941

0 commit comments

Comments
 (0)