diff --git a/samples/SkyflowElements/src/components/CardBrandChoice/index.tsx b/samples/SkyflowElements/src/components/CardBrandChoice/index.tsx index 6f50101..4a548cc 100644 --- a/samples/SkyflowElements/src/components/CardBrandChoice/index.tsx +++ b/samples/SkyflowElements/src/components/CardBrandChoice/index.tsx @@ -32,12 +32,6 @@ const CardBrandChoice = () => { invalid: { color: '#f44336', }, - dropdownIcon: { - // Pass styles for the dropdown icon. - }, - dropdown: { - // Pass styles for the card choice dropdown. - }, }, labelStyles: { base: { diff --git a/samples/SkyflowElements/src/components/ComposableElements/index.tsx b/samples/SkyflowElements/src/components/ComposableElements/index.tsx index 5f9b1c4..1b8dadd 100644 --- a/samples/SkyflowElements/src/components/ComposableElements/index.tsx +++ b/samples/SkyflowElements/src/components/ComposableElements/index.tsx @@ -15,7 +15,7 @@ const ComposableElements = () => { base: { fontFamily: 'Inter', fontStyle: 'normal', - fontWeight: 400, + fontWeight: '400', fontSize: '14px', lineHeight: '21px', color: '#1d1d1d', @@ -32,7 +32,7 @@ const ComposableElements = () => { base: { fontFamily: 'Inter', fontStyle: 'normal', - fontWeight: 400, + fontWeight: '400', fontSize: '14px', lineHeight: '21px', }, diff --git a/samples/SkyflowElements/src/components/DynamicComposableElements/index.tsx b/samples/SkyflowElements/src/components/DynamicComposableElements/index.tsx index 2ceabdb..6d0e037 100644 --- a/samples/SkyflowElements/src/components/DynamicComposableElements/index.tsx +++ b/samples/SkyflowElements/src/components/DynamicComposableElements/index.tsx @@ -22,7 +22,7 @@ const DynamicComposableElements = () => { base: { fontFamily: 'Inter', fontStyle: 'normal', - fontWeight: 400, + fontWeight: '400', fontSize: '14px', lineHeight: '21px', color: '#1d1d1d', @@ -30,15 +30,14 @@ const DynamicComposableElements = () => { }, complete: { color: '#4caf50', - } - - }, - empty: { - }, - focus: { - }, - invalid: { - color: '#f44336', + }, + empty: { + }, + focus: { + }, + invalid: { + color: '#f44336', + }, }, }); diff --git a/src/common/index.ts b/src/common/index.ts new file mode 100644 index 0000000..ee95e88 --- /dev/null +++ b/src/common/index.ts @@ -0,0 +1,56 @@ +/* + Copyright (c) 2022 Skyflow, Inc. +*/ +import type { + ContainerOptions, + ErrorTextStyles, + LabelStyles, + InputStyles, +} from 'skyflow-js/types/utils/common'; + +export type { + ContainerOptions, + ErrorTextStyles, + LabelStyles, + InputStyles, +}; + +export interface StylesConfig { + inputStyles?: InputStyles; + labelStyles?: LabelStyles; + errorTextStyles?: ErrorTextStyles; +} + +export interface CollectElementState { + elementType: string; + isEmpty: boolean; + isFocused: boolean; + isValid: boolean; + isComplete: boolean; + value?: string; +} + +export interface ElementClassesConfig { + inputStyles?: InputStyles; + labelStyles?: LabelStyles; + errorTextStyles?: ErrorTextStyles; +} + +export interface EventCallback { + priority: boolean; + callback: EventCallbackFunction; +} + +export type EventCallbackFunction = (...args: any[]) => void; + +export interface ComposableSubmitResponse { + records?: Array<{ + table: string; + fields: Record; + }>; + errors?: Array<{ + code: number; + description: string; + }>; +} + diff --git a/src/elements/ComposableContainer/index.tsx b/src/elements/ComposableContainer/index.tsx index ee81b7d..1e8a97c 100644 --- a/src/elements/ComposableContainer/index.tsx +++ b/src/elements/ComposableContainer/index.tsx @@ -7,11 +7,12 @@ import EventEmitter from '../../utils/event-emitter' import ComposableContainer from 'skyflow-js/types/core/external/collect/compose-collect-container'; import Skyflow from 'skyflow-js' import { v4 as uuid } from 'uuid'; +import { ComposableSubmitResponse } from '../../common'; export interface IComposableContainer { children?: React.ReactNode container: ComposableContainer id?: string - onSubmit?: () => void + onSubmit?: (response?: ComposableSubmitResponse) => void } const ComposableContainerComponent: FC = ({ children, ...props }) => { @@ -24,7 +25,7 @@ const ComposableContainerComponent: FC = ({ children, ...p setCurrentCount((prev) => prev + 1); }); - const iterateOverChildren = (children) => { + const iterateOverChildren = (children: React.ReactNode) => { return React.Children.map(children, (child) => { if (!React.isValidElement(child)) return child; return React.cloneElement(child, { eventEmitter: eventEmitter } as Partial) diff --git a/src/elements/FileRenderElement/index.tsx b/src/elements/FileRenderElement/index.tsx index 6129dfd..a11b873 100644 --- a/src/elements/FileRenderElement/index.tsx +++ b/src/elements/FileRenderElement/index.tsx @@ -4,12 +4,14 @@ import React, { FC } from 'react' import { FileRenderElements, SkyflowRenderElementProps, SkyflowRenderElementRef } from '..' import { v4 as uuid } from 'uuid'; +import RevealElementType from 'skyflow-js/types/core/external/reveal/reveal-element'; import useUpdateFileRenderElement from '../../hooks/UpdateFileRenderElement'; import useErrorOverride from '../../hooks/OverrideError'; +// eslint-disable-next-line react/display-name const FileRenderElement = React.forwardRef(({ ...props }, ref) => { const uniqueDivId = React.useRef(uuid()); - const [element, setElement] = React.useState(null); + const [element, setElement] = React.useState(null); useErrorOverride(element, ref, props); diff --git a/src/elements/RevealElement/index.tsx b/src/elements/RevealElement/index.tsx index a82dcb2..7eee70b 100644 --- a/src/elements/RevealElement/index.tsx +++ b/src/elements/RevealElement/index.tsx @@ -1,16 +1,18 @@ /* Copyright (c) 2022 Skyflow, Inc. */ -import React, { FC } from 'react' -import { SkyflowCollectElementRef, SkyflowRevealElementProps, SkyflowRevealElementRef } from '..' +import React from 'react' +import { SkyflowRevealElementProps, SkyflowRevealElementRef } from '..' import { v4 as uuid } from 'uuid'; import Skyflow from 'skyflow-js'; +import RevealElementType from 'skyflow-js/types/core/external/reveal/reveal-element'; import useUpdateRevealElement from '../../hooks/UpdateRevealElement'; import useErrorOverride from '../../hooks/OverrideError'; +// eslint-disable-next-line react/display-name const RevealElement = React.forwardRef( ({ ...props }, ref) => { const uniqueDivId = React.useRef(uuid()); - const [element,setElement] = React.useState(null); + const [element,setElement] = React.useState(null); useErrorOverride(element, ref, props); diff --git a/src/elements/index.ts b/src/elements/index.ts index 0382e9f..448f714 100644 --- a/src/elements/index.ts +++ b/src/elements/index.ts @@ -8,6 +8,8 @@ import CollectContainer from 'skyflow-js/types/core/external/collect/collect-con import ComposableContainer from 'skyflow-js/types/core/external/collect/compose-collect-container' import RevealContainer from 'skyflow-js/types/core/external/reveal/reveal-container' import { IValidationRule, RedactionType } from 'skyflow-js/types/utils/common' +import { ElementClassesConfig, CollectElementState } from '../common' +import EventEmitter from '../utils/event-emitter' export const FileRenderElements = {}; export const CollectElements = {}; @@ -22,13 +24,13 @@ export interface SkyflowCollectElementProps { placeholder?: string errorText?: string validations?: IValidationRule[] | undefined - classes?: Record + classes?: ElementClassesConfig options?: ICollectElementOptions - onChange?: (state: unknown) => void - onFocus?: (state: unknown) => void - onBlur?: (state: unknown) => void - onReady?: (state: unknown) => void - eventEmitter?:any + onChange?: (state: CollectElementState) => void + onFocus?: (state: CollectElementState) => void + onBlur?: (state: CollectElementState) => void + onReady?: (state: CollectElementState) => void + eventEmitter?: EventEmitter skyflowID?:string ref?: {current: SkyflowCollectElementRef | null}; // TODO ref @@ -44,7 +46,7 @@ export interface SkyflowRevealElementProps { id?: string label?: string altText?: string - classes?: Record + classes?: ElementClassesConfig options?: IRevealOptions redaction?: RedactionType ref?: {current: SkyflowRevealElementRef | null} @@ -58,7 +60,7 @@ export interface SkyflowRenderElementProps { container: RevealContainer id: string altText?: string - classes?: Record + classes?: ElementClassesConfig skyflowID:string table: string column: string diff --git a/src/hooks/CollectContainer/index.ts b/src/hooks/CollectContainer/index.ts index 170d598..4812ad5 100644 --- a/src/hooks/CollectContainer/index.ts +++ b/src/hooks/CollectContainer/index.ts @@ -4,10 +4,10 @@ import React from 'react' import Skyflow from 'skyflow-js' import CollectContainer from 'skyflow-js/types/core/external/collect/collect-container' - +import { ContainerOptions } from '../../common' import { useSkyflowClient } from '../../core/hook' -const useCollectContainer = (options?): CollectContainer => { +const useCollectContainer = (options?: ContainerOptions): CollectContainer => { const { skyflow } = useSkyflowClient() return React.useMemo( diff --git a/src/hooks/ComposableContainer/index.ts b/src/hooks/ComposableContainer/index.ts index 4d05290..cc976f3 100644 --- a/src/hooks/ComposableContainer/index.ts +++ b/src/hooks/ComposableContainer/index.ts @@ -4,10 +4,10 @@ import React from 'react' import Skyflow from 'skyflow-js' import ComposableContainer from 'skyflow-js/types/core/external/collect/compose-collect-container' - +import { ContainerOptions } from '../../common' import { useSkyflowClient } from '../../core/hook' -const useComposableContainer = (options) => { +const useComposableContainer = (options: ContainerOptions) => { const { skyflow } = useSkyflowClient() return React.useMemo( () => skyflow?.container(Skyflow.ContainerType.COMPOSABLE, options) as ComposableContainer, diff --git a/src/hooks/MakeSkyflowStyles/index.ts b/src/hooks/MakeSkyflowStyles/index.ts index fee93eb..40ac675 100644 --- a/src/hooks/MakeSkyflowStyles/index.ts +++ b/src/hooks/MakeSkyflowStyles/index.ts @@ -1,12 +1,13 @@ /* Copyright (c) 2022 Skyflow, Inc. */ +import { StylesConfig } from '../../common' const useMakeSkyflowStyles = ( - styles: Record = {}, -): (() => Record) => { + styles: StylesConfig = {}, +): (() => StylesConfig) => { return function useStyles() { - const classes: Record = styles + const classes: StylesConfig = styles return classes } diff --git a/src/hooks/RevealContainer/index.ts b/src/hooks/RevealContainer/index.ts index 621b9b6..55c44e8 100644 --- a/src/hooks/RevealContainer/index.ts +++ b/src/hooks/RevealContainer/index.ts @@ -4,10 +4,10 @@ import React from 'react' import Skyflow from 'skyflow-js' import RevealContainer from 'skyflow-js/types/core/external/reveal/reveal-container' - +import { ContainerOptions } from '../../common' import { useSkyflowClient } from '../../core/hook' -const useRevealContainer = (options?): RevealContainer => { +const useRevealContainer = (options?: ContainerOptions): RevealContainer => { const { skyflow } = useSkyflowClient() return React.useMemo( () => options ? skyflow?.container(Skyflow.ContainerType.REVEAL, options) as RevealContainer : skyflow?.container(Skyflow.ContainerType.REVEAL) as RevealContainer, diff --git a/src/index.ts b/src/index.ts index 88d9825..5ddc654 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,6 +27,19 @@ import useSkyflow from './hooks/Skyflow' import use3DS from './hooks/ThreeDS' import { SkyflowCollectElementRef, SkyflowRenderElementRef, SkyflowRevealElementRef } from 'elements' +export type { + ContainerOptions, + ErrorTextStyles, + LabelStyles, + InputStyles, + StylesConfig, + ElementClassesConfig, + CollectElementState, + EventCallback, + EventCallbackFunction, + ComposableSubmitResponse, +} from './common' + const LogLevel = Skyflow.LogLevel const Env = Skyflow.Env diff --git a/src/utils/event-emitter/index.ts b/src/utils/event-emitter/index.ts index 2da36c1..2371ece 100644 --- a/src/utils/event-emitter/index.ts +++ b/src/utils/event-emitter/index.ts @@ -1,11 +1,13 @@ +import { EventCallback, EventCallbackFunction } from '../../common' + class EventEmitter { - events: Record + events: Record constructor() { this.events = {} } - on(event: string, callback: any, priority = false): void { + on(event: string, callback: EventCallbackFunction, priority = false): void { if (this.events[event]) { this.events[event].push({ priority, callback }) } else { @@ -13,7 +15,7 @@ class EventEmitter { } } - off(event: string, callback: any): void { + off(event: string, callback: EventCallbackFunction): void { const eventCallbacks = this.events[event] if (!eventCallbacks) { @@ -49,11 +51,11 @@ class EventEmitter { } resetEvents() { - const tempEvents: any = {} + const tempEvents: Record = {} Object.keys(this.events).forEach((eventName) => { const events = this.events[eventName] if (events && events.length > 0) { - const newEvents: any[] = [] + const newEvents: EventCallback[] = [] events.forEach((event) => { if (event.priority) newEvents.push(event) }) diff --git a/tests/elements/collectElements.test.tsx b/tests/elements/collectElements.test.tsx index 32a9439..fb3aa5f 100644 --- a/tests/elements/collectElements.test.tsx +++ b/tests/elements/collectElements.test.tsx @@ -30,7 +30,12 @@ const mountMock = jest.fn(); const eventEmitterMock = jest.fn(); const composableEventEmitter = { + events: {}, + on: jest.fn(), + off: jest.fn(), _emit: eventEmitterMock, + hasListener: jest.fn(), + resetEvents: jest.fn(), }; const collectElementMock = { @@ -94,7 +99,7 @@ describe('test collect elements', () => { jest.clearAllMocks(); jest.resetAllMocks(); }); - let collectContainer; + let collectContainer: any; test('test card number collect Element ', () => { const container = useCollectContainer(); const cardContainer = render(