From 7746038e31f3c89e50961347ac39d3d7ce567c83 Mon Sep 17 00:00:00 2001 From: anserwaseem Date: Thu, 9 Nov 2023 16:21:21 +0500 Subject: [PATCH] add ConfirmationInput widget --- apps/starter/src/ensemble/askEmbrace.yaml | 26 +++ packages/runtime/package.json | 1 + .../src/runtime/hooks/useEnsembleAction.tsx | 2 +- packages/runtime/src/util/types.ts | 4 +- .../runtime/src/widgets/ConfirmationInput.tsx | 174 ++++++++++++++++++ packages/runtime/src/widgets/index.ts | 1 + pnpm-lock.yaml | 11 ++ 7 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 packages/runtime/src/widgets/ConfirmationInput.tsx diff --git a/apps/starter/src/ensemble/askEmbrace.yaml b/apps/starter/src/ensemble/askEmbrace.yaml index de2c499f7..35abd93c1 100644 --- a/apps/starter/src/ensemble/askEmbrace.yaml +++ b/apps/starter/src/ensemble/askEmbrace.yaml @@ -22,6 +22,32 @@ View: # - Text: # id: he # text: hehe + - ConfirmationInput: + id: myConfirmationInput + length: 4 + styles: + inputType: "number" + fieldWidth: 30 + fieldHeight: 30 + defaultFieldBorderColor: "green" + defaultFieldBackgroundColor: "grey" + activeFieldBorderColor: "black" + activeFieldBackgroundColor: "yellow" + filledFieldBorderColor: "blue" + filledFieldBackgroundColor: "aqua" + gap: 30px + backgroundColor: "lightblue" + padding: 20 + textStyle: + fontSize: 15 + onChange: + executeCode: + body: | + console.log(myConfirmationInput.text) + onComplete: + executeCode: + body: | + console.log("completed: "+myConfirmationInput.text) - Form: styles: labelPosition: start diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 4b73d47ba..24e81e56d 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -33,6 +33,7 @@ "@types/react": "^18.2.21", "@types/react-dom": "^18.2.0", "antd": "^5.9.0", + "antd-input-otp": "^2.0.4", "chart.js": "^4.4.0", "eslint-config-custom": "workspace:*", "jest": "27.5.1", diff --git a/packages/runtime/src/runtime/hooks/useEnsembleAction.tsx b/packages/runtime/src/runtime/hooks/useEnsembleAction.tsx index 383e170da..a7a481633 100644 --- a/packages/runtime/src/runtime/hooks/useEnsembleAction.tsx +++ b/packages/runtime/src/runtime/hooks/useEnsembleAction.tsx @@ -339,7 +339,7 @@ export const useEnsembleAction = ( (action.navigateScreen && navigateScreen) || (action.showToast && showToast) || (action.navigateModalScreen && navigateModalScreen) || - ("closeAllDialogs" in action && closeAllDialogs) || + (!isString(action) && "closeAllDialogs" in action && closeAllDialogs) || (action.pickFiles && pickFiles) || (action.uploadFiles && uploadFiles) ); diff --git a/packages/runtime/src/util/types.ts b/packages/runtime/src/util/types.ts index 04d6a29e6..036810c24 100644 --- a/packages/runtime/src/util/types.ts +++ b/packages/runtime/src/util/types.ts @@ -1,9 +1,9 @@ import type { EnsembleWidget, Expression } from "@ensembleui/react-framework"; -export interface EnsembleWidgetProps { +export interface EnsembleWidgetProps> { id?: string; + styles?: T; [key: string]: unknown; - styles?: Record; } export type BaseTextProps = { diff --git a/packages/runtime/src/widgets/ConfirmationInput.tsx b/packages/runtime/src/widgets/ConfirmationInput.tsx new file mode 100644 index 000000000..8a50580e3 --- /dev/null +++ b/packages/runtime/src/widgets/ConfirmationInput.tsx @@ -0,0 +1,174 @@ +import { + type EnsembleAction, + useRegisterBindings, +} from "@ensembleui/react-framework"; +import { InputOTP } from "antd-input-otp"; +import { useState } from "react"; +import { Form } from "antd"; +import { useEnsembleAction } from "../runtime/hooks/useEnsembleAction"; +import { WidgetRegistry } from "../registry"; +import type { EnsembleWidgetProps } from "../util/utils"; +import type { TextStyles } from "./Text"; + +interface ConfirmationInputStyles { + inputType?: "number" | "text"; + fieldWidth?: number | string; + fieldHeight?: number | string; + gap?: number; + spaceEvenly?: boolean; + defaultFieldBorderColor?: string; + activeFieldBorderColor?: string; + filledFieldBorderColor?: string; + defaultFieldBackgroundColor?: string; + activeFieldBackgroundColor?: string; + filledFieldBackgroundColor?: string; + textStyle?: TextStyles; + + backgroundColor?: string; + margin?: number | string; + padding?: number | string; + + [key: string]: unknown; +} + +const defaultStyles: ConfirmationInputStyles = { + inputType: "number", + fieldWidth: 50, + fieldHeight: 50, + gap: 10, + spaceEvenly: true, + defaultFieldBorderColor: "rgba(0, 0, 0, 0.451)", + activeFieldBorderColor: "black", + filledFieldBorderColor: "transparent", + defaultFieldBackgroundColor: "transparent", + activeFieldBackgroundColor: "transparent", + filledFieldBackgroundColor: "transparent", + textStyle: { + color: "black", + fontFamily: "inherit", + fontSize: 25, + fontWeight: "bold", + backgroundColor: "transparent", + }, + + backgroundColor: "transparent", + margin: 0, + padding: 0, +}; + +type ConfirmationInputProps = { + length?: number; + onChange?: EnsembleAction; + onComplete?: EnsembleAction; +} & EnsembleWidgetProps; + +export const ConfirmationInput: React.FC = (props) => { + const { id, length, onChange, onComplete, styles, ...otherProps } = props; + + const [form] = Form.useForm(); + + const [text, setText] = useState(""); + + const onChangeAction = useEnsembleAction(onChange); + const onCompleteAction = useEnsembleAction(onComplete); + + useRegisterBindings({ text }, id, { setText }); + + const handleChange = (value: string[]): void => { + setText(value.join("")); + + onChangeAction?.callback({ + [id as string]: { + text: value.join(""), + setText, + }, + }); + }; + + const handleComplete = (values: Record): unknown => + onCompleteAction?.callback({ + [id as string]: { + text: values["confirmationItem"].join(""), + setText, + }, + }); + + const customStyles = ` + .confirmationInput:focus { + border-color: ${ + styles?.activeFieldBorderColor || defaultStyles.activeFieldBorderColor + } !important; + background-color: ${ + styles?.activeFieldBackgroundColor || + defaultStyles.activeFieldBackgroundColor + } !important; + } + + .confirmationinput[value]:not([value=""]):not(.confirmationinput:where(.ant-input:focus), .confirmationinput:where(.ant-input-focused)) { + border-color: ${ + styles?.filledFieldBorderColor || defaultStyles.filledFieldBorderColor + } !important; + background-color: ${ + styles?.filledFieldBackgroundColor || + defaultStyles.filledFieldBackgroundColor + } !important; + } + `; + + return ( + <> + +
+ + + +
+ + ); +}; + +WidgetRegistry.register("ConfirmationInput", ConfirmationInput); diff --git a/packages/runtime/src/widgets/index.ts b/packages/runtime/src/widgets/index.ts index 2ccd44063..92bcf8cf9 100644 --- a/packages/runtime/src/widgets/index.ts +++ b/packages/runtime/src/widgets/index.ts @@ -23,3 +23,4 @@ export * from "./Tag"; export * from "./Carousel"; export * from "./PopupMenu"; export * from "./Dropdown"; +export * from "./ConfirmationInput"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e583a8a02..e13c98523 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -133,6 +133,7 @@ importers: '@types/react': ^18.2.21 '@types/react-dom': ^18.2.0 antd: ^5.9.0 + antd-input-otp: ^2.0.4 chart.js: ^4.4.0 eslint-config-custom: workspace:* jest: 27.5.1 @@ -156,6 +157,7 @@ importers: '@types/react': 18.2.21 '@types/react-dom': 18.2.7 antd: 5.9.0 + antd-input-otp: 2.0.4_antd@5.9.0 chart.js: 4.4.0 eslint-config-custom: link:../eslint-config-custom jest: 27.5.1 @@ -4462,6 +4464,15 @@ packages: engines: {node: '>=12'} dev: true + /antd-input-otp/2.0.4_antd@5.9.0: + resolution: {integrity: sha512-j0jWH5vi1o/lbt1F9sXxtI/q2hikUjjsjRHlRaspLyxP0fAVdTxsG2Se3K1KQNoEQ94ILJ0c8Hu6ai5Oj7LbEA==} + peerDependencies: + antd: '>=4.19.0' + react: '>=16.8.0' + dependencies: + antd: 5.9.0 + dev: true + /antd/5.9.0: resolution: {integrity: sha512-YgLGtz+GbzrQws+R7siXolUN89ERH2Kbcu8Bz98VY4fwwMSDKKhbCGkIjw9mnIhcrXpHT+FXwrqjAV3j9eakSA==} peerDependencies: