@transferwise/components 46.112.0 → 46.113.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/expressiveMoneyInput/ExpressiveMoneyInput.js +113 -0
- package/build/expressiveMoneyInput/ExpressiveMoneyInput.js.map +1 -0
- package/build/expressiveMoneyInput/ExpressiveMoneyInput.messages.js +17 -0
- package/build/expressiveMoneyInput/ExpressiveMoneyInput.messages.js.map +1 -0
- package/build/expressiveMoneyInput/ExpressiveMoneyInput.messages.mjs +13 -0
- package/build/expressiveMoneyInput/ExpressiveMoneyInput.messages.mjs.map +1 -0
- package/build/expressiveMoneyInput/ExpressiveMoneyInput.mjs +109 -0
- package/build/expressiveMoneyInput/ExpressiveMoneyInput.mjs.map +1 -0
- package/build/expressiveMoneyInput/amountInput/AmountInput.js +281 -0
- package/build/expressiveMoneyInput/amountInput/AmountInput.js.map +1 -0
- package/build/expressiveMoneyInput/amountInput/AmountInput.mjs +279 -0
- package/build/expressiveMoneyInput/amountInput/AmountInput.mjs.map +1 -0
- package/build/expressiveMoneyInput/amountInput/utils.js +87 -0
- package/build/expressiveMoneyInput/amountInput/utils.js.map +1 -0
- package/build/expressiveMoneyInput/amountInput/utils.mjs +78 -0
- package/build/expressiveMoneyInput/amountInput/utils.mjs.map +1 -0
- package/build/expressiveMoneyInput/animatedNumber/AnimatedNumber.js +50 -0
- package/build/expressiveMoneyInput/animatedNumber/AnimatedNumber.js.map +1 -0
- package/build/expressiveMoneyInput/animatedNumber/AnimatedNumber.mjs +48 -0
- package/build/expressiveMoneyInput/animatedNumber/AnimatedNumber.mjs.map +1 -0
- package/build/expressiveMoneyInput/chevron/Chevron.js +31 -0
- package/build/expressiveMoneyInput/chevron/Chevron.js.map +1 -0
- package/build/expressiveMoneyInput/chevron/Chevron.mjs +29 -0
- package/build/expressiveMoneyInput/chevron/Chevron.mjs.map +1 -0
- package/build/expressiveMoneyInput/currencySelector/CurrencySelector.js +160 -0
- package/build/expressiveMoneyInput/currencySelector/CurrencySelector.js.map +1 -0
- package/build/expressiveMoneyInput/currencySelector/CurrencySelector.mjs +157 -0
- package/build/expressiveMoneyInput/currencySelector/CurrencySelector.mjs.map +1 -0
- package/build/expressiveMoneyInput/hooks/useFocus.js +37 -0
- package/build/expressiveMoneyInput/hooks/useFocus.js.map +1 -0
- package/build/expressiveMoneyInput/hooks/useFocus.mjs +35 -0
- package/build/expressiveMoneyInput/hooks/useFocus.mjs.map +1 -0
- package/build/expressiveMoneyInput/hooks/useInputStyle.js +71 -0
- package/build/expressiveMoneyInput/hooks/useInputStyle.js.map +1 -0
- package/build/expressiveMoneyInput/hooks/useInputStyle.mjs +69 -0
- package/build/expressiveMoneyInput/hooks/useInputStyle.mjs.map +1 -0
- package/build/i18n/en.json +2 -0
- package/build/i18n/en.json.js +2 -0
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +2 -0
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/index.js +2 -0
- package/build/index.js.map +1 -1
- package/build/index.mjs +1 -0
- package/build/index.mjs.map +1 -1
- package/build/listItem/useListItemControl.js +1 -1
- package/build/listItem/useListItemControl.js.map +1 -1
- package/build/listItem/useListItemControl.mjs +2 -2
- package/build/listItem/useListItemControl.mjs.map +1 -1
- package/build/listItem/useListItemMedia.js +1 -1
- package/build/listItem/useListItemMedia.js.map +1 -1
- package/build/listItem/useListItemMedia.mjs +2 -2
- package/build/listItem/useListItemMedia.mjs.map +1 -1
- package/build/main.css +73 -7
- package/build/prompt/InlinePrompt/InlinePrompt.js +7 -0
- package/build/prompt/InlinePrompt/InlinePrompt.js.map +1 -1
- package/build/prompt/InlinePrompt/InlinePrompt.mjs +8 -1
- package/build/prompt/InlinePrompt/InlinePrompt.mjs.map +1 -1
- package/build/styles/expressiveMoneyInput/ExpressiveMoneyInput.css +58 -0
- package/build/styles/expressiveMoneyInput/amountInput/AmountInput.css +32 -0
- package/build/styles/expressiveMoneyInput/chevron/Chevron.css +12 -0
- package/build/styles/expressiveMoneyInput/currencySelector/CurrencySelector.css +6 -0
- package/build/styles/main.css +73 -7
- package/build/styles/moneyInput/MoneyInput.css +8 -0
- package/build/styles/prompt/InlinePrompt/InlinePrompt.css +7 -7
- package/build/types/expressiveMoneyInput/ExpressiveMoneyInput.d.ts +59 -0
- package/build/types/expressiveMoneyInput/ExpressiveMoneyInput.d.ts.map +1 -0
- package/build/types/expressiveMoneyInput/ExpressiveMoneyInput.messages.d.ts +12 -0
- package/build/types/expressiveMoneyInput/ExpressiveMoneyInput.messages.d.ts.map +1 -0
- package/build/types/expressiveMoneyInput/amountInput/AmountInput.d.ts +13 -0
- package/build/types/expressiveMoneyInput/amountInput/AmountInput.d.ts.map +1 -0
- package/build/types/expressiveMoneyInput/amountInput/utils.d.ts +22 -0
- package/build/types/expressiveMoneyInput/amountInput/utils.d.ts.map +1 -0
- package/build/types/expressiveMoneyInput/animatedNumber/AnimatedNumber.d.ts +9 -0
- package/build/types/expressiveMoneyInput/animatedNumber/AnimatedNumber.d.ts.map +1 -0
- package/build/types/expressiveMoneyInput/chevron/Chevron.d.ts +6 -0
- package/build/types/expressiveMoneyInput/chevron/Chevron.d.ts.map +1 -0
- package/build/types/expressiveMoneyInput/currencySelector/CurrencySelector.d.ts +30 -0
- package/build/types/expressiveMoneyInput/currencySelector/CurrencySelector.d.ts.map +1 -0
- package/build/types/expressiveMoneyInput/hooks/useFocus.d.ts +7 -0
- package/build/types/expressiveMoneyInput/hooks/useFocus.d.ts.map +1 -0
- package/build/types/expressiveMoneyInput/hooks/useInputStyle.d.ts +10 -0
- package/build/types/expressiveMoneyInput/hooks/useInputStyle.d.ts.map +1 -0
- package/build/types/expressiveMoneyInput/hooks/useSelectionRange.d.ts +10 -0
- package/build/types/expressiveMoneyInput/hooks/useSelectionRange.d.ts.map +1 -0
- package/build/types/expressiveMoneyInput/index.d.ts +3 -0
- package/build/types/expressiveMoneyInput/index.d.ts.map +1 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts +3 -2
- package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts.map +1 -1
- package/build/types/test-utils/index.d.ts +4 -0
- package/build/types/test-utils/index.d.ts.map +1 -1
- package/build/types/withDisplayFormat/WithDisplayFormat.d.ts.map +1 -1
- package/build/withDisplayFormat/WithDisplayFormat.js +0 -1
- package/build/withDisplayFormat/WithDisplayFormat.js.map +1 -1
- package/build/withDisplayFormat/WithDisplayFormat.mjs +0 -1
- package/build/withDisplayFormat/WithDisplayFormat.mjs.map +1 -1
- package/package.json +11 -4
- package/src/expressiveMoneyInput/ExpressiveMoneyInput.autofocus.docs.mdx +12 -0
- package/src/expressiveMoneyInput/ExpressiveMoneyInput.css +58 -0
- package/src/expressiveMoneyInput/ExpressiveMoneyInput.less +13 -0
- package/src/expressiveMoneyInput/ExpressiveMoneyInput.messages.ts +13 -0
- package/src/expressiveMoneyInput/ExpressiveMoneyInput.story.tsx +232 -0
- package/src/expressiveMoneyInput/ExpressiveMoneyInput.tsx +156 -0
- package/src/expressiveMoneyInput/amountInput/AmountInput.css +32 -0
- package/src/expressiveMoneyInput/amountInput/AmountInput.less +43 -0
- package/src/expressiveMoneyInput/amountInput/AmountInput.tsx +353 -0
- package/src/expressiveMoneyInput/amountInput/utils.spec.ts +114 -0
- package/src/expressiveMoneyInput/amountInput/utils.ts +116 -0
- package/src/expressiveMoneyInput/animatedNumber/AnimatedNumber.tsx +40 -0
- package/src/expressiveMoneyInput/chevron/Chevron.css +12 -0
- package/src/expressiveMoneyInput/chevron/Chevron.less +13 -0
- package/src/expressiveMoneyInput/chevron/Chevron.tsx +35 -0
- package/src/expressiveMoneyInput/currencySelector/CurrencySelector.css +6 -0
- package/src/expressiveMoneyInput/currencySelector/CurrencySelector.less +7 -0
- package/src/expressiveMoneyInput/currencySelector/CurrencySelector.tsx +220 -0
- package/src/expressiveMoneyInput/hooks/useFocus.ts +35 -0
- package/src/expressiveMoneyInput/hooks/useInputStyle.ts +85 -0
- package/src/expressiveMoneyInput/hooks/useSelectionRange.ts +23 -0
- package/src/expressiveMoneyInput/index.ts +2 -0
- package/src/i18n/en.json +2 -0
- package/src/index.ts +2 -0
- package/src/listItem/useListItemControl.tsx +2 -2
- package/src/listItem/useListItemMedia.tsx +2 -2
- package/src/main.css +73 -7
- package/src/main.less +1 -0
- package/src/moneyInput/MoneyInput.css +8 -0
- package/src/moneyInput/MoneyInput.less +5 -0
- package/src/prompt/InlinePrompt/InlinePrompt.css +7 -7
- package/src/prompt/InlinePrompt/InlinePrompt.less +7 -7
- package/src/prompt/InlinePrompt/InlinePrompt.spec.tsx +6 -0
- package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +39 -0
- package/src/prompt/InlinePrompt/InlinePrompt.tsx +12 -2
- package/src/ssr.spec.tsx +1 -0
- package/src/withDisplayFormat/WithDisplayFormat.spec.js +28 -1
- package/src/withDisplayFormat/WithDisplayFormat.tsx +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WithDisplayFormat.js","sources":["../../src/withDisplayFormat/WithDisplayFormat.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { HistoryNavigator } from '../common';\nimport {\n formatWithPattern,\n getCountOfSymbolsInSelection,\n getCursorPositionAfterKeystroke,\n unformatWithPattern,\n getDistanceToPreviousSymbol,\n getDistanceToNextSymbol,\n} from '../common/textFormat';\nimport { InputProps } from '../inputs/Input';\nimport { TextAreaProps } from '../inputs/TextArea';\n\ntype HTMLTextElement = HTMLInputElement | HTMLTextAreaElement;\ntype TextElementProps = InputProps | TextAreaProps;\n\nexport type EventType =\n | 'KeyDown'\n | 'Paste'\n | 'Cut'\n | 'Undo'\n | 'Redo'\n | 'Backspace'\n | 'Delete'\n | 'Initial';\n\ninterface WithDisplayFormatState {\n value: string;\n historyNavigator: HistoryNavigator;\n prevDisplayPattern: string;\n triggerType: EventType;\n triggerEvent: React.KeyboardEvent<HTMLTextElement> | null;\n pastedLength: number;\n selectionStart: number;\n selectionEnd: number;\n}\n\nexport interface WithDisplayFormatProps<T extends TextElementProps = TextElementProps>\n extends Pick<\n TextElementProps,\n | 'className'\n | 'disabled'\n | 'id'\n | 'maxLength'\n | 'minLength'\n | 'name'\n | 'placeholder'\n | 'readOnly'\n | 'required'\n | 'inputMode'\n > {\n value?: string;\n displayPattern: string;\n /**\n * autocomplete hides our form help so we need to disable it when help text\n * is present. Chrome ignores autocomplete=off, the only way to disable it is\n * to provide an 'invalid' value, for which 'disabled' serves.\n */\n autoComplete?: TextElementProps['autoComplete'] | 'disabled';\n onChange?: (value: string) => void;\n onBlur?: (value: string) => void;\n onFocus?: (value: string) => void;\n render: (renderProps: T) => React.JSX.Element;\n}\n\nclass WithDisplayFormat<T extends TextElementProps> extends React.Component<\n WithDisplayFormatProps<T>,\n WithDisplayFormatState\n> {\n declare props: WithDisplayFormatProps<T> &\n Required<Pick<WithDisplayFormatProps<T>, keyof typeof WithDisplayFormat.defaultProps>>;\n static defaultProps = {\n autoComplete: 'off',\n displayPattern: '',\n value: '',\n };\n\n constructor(props: WithDisplayFormatProps) {\n super(props);\n const unformattedValue = unformatWithPattern(props.value ?? '', props.displayPattern);\n this.state = {\n value: formatWithPattern(unformattedValue, props.displayPattern),\n historyNavigator: new HistoryNavigator(),\n prevDisplayPattern: props.displayPattern,\n triggerType: 'Initial',\n triggerEvent: null,\n selectionStart: 0,\n selectionEnd: 0,\n pastedLength: 0,\n };\n }\n\n static getDerivedStateFromProps(\n { displayPattern }: WithDisplayFormatProps,\n { prevDisplayPattern = displayPattern, value, historyNavigator }: WithDisplayFormatState,\n ) {\n if (prevDisplayPattern !== displayPattern) {\n const unFormattedValue = unformatWithPattern(value, prevDisplayPattern);\n historyNavigator.reset();\n\n return {\n prevDisplayPattern: displayPattern,\n value: formatWithPattern(unFormattedValue, displayPattern),\n triggerType: null,\n triggerEvent: null,\n pastedLength: 0,\n };\n }\n return null;\n }\n\n getUserAction = (unformattedValue: string): EventType | string => {\n const { triggerEvent, triggerType, value } = this.state;\n const { displayPattern } = this.props;\n\n if (triggerEvent) {\n if (triggerType === 'Paste' || triggerType === 'Cut') {\n return triggerType;\n }\n\n if ((triggerEvent.ctrlKey || triggerEvent.metaKey) && triggerEvent.key === 'z') {\n return triggerEvent.shiftKey ? 'Redo' : 'Undo';\n }\n\n // Detect mouse event redo\n if (triggerEvent.ctrlKey && triggerEvent.key === 'd') {\n return 'Delete';\n }\n\n // Android Fix.\n if (\n typeof triggerEvent.key === 'undefined' &&\n unformattedValue.length <= unformatWithPattern(value, displayPattern).length\n ) {\n return 'Backspace';\n }\n return triggerEvent.key;\n }\n // triggerEvent can be null only in case of \"autofilling\" (via password manager extension or browser build-in one) events\n return 'Paste';\n };\n\n resetEvent = () => {\n this.setState({\n triggerType: 'Initial',\n triggerEvent: null,\n pastedLength: 0,\n });\n };\n\n detectUndoRedo = (event: React.KeyboardEvent<HTMLTextElement>) => {\n if ((event.ctrlKey || event.metaKey) && event.key === 'z') {\n return event.shiftKey ? 'Redo' : 'Undo';\n }\n return null;\n };\n\n handleOnKeyDown: React.KeyboardEventHandler<HTMLTextElement> = (event) => {\n event.persist();\n const { selectionStart, selectionEnd } = event.currentTarget;\n const { historyNavigator } = this.state;\n const { displayPattern } = this.props;\n\n // Unfortunately Undo and Redo don't trigger OnChange event so we need to handle some value logic here.\n let newFormattedValue = '';\n\n if (this.detectUndoRedo(event) === 'Undo') {\n newFormattedValue = formatWithPattern(historyNavigator.undo().toString(), displayPattern);\n this.setState({ value: newFormattedValue, triggerType: 'Undo' });\n } else if (this.detectUndoRedo(event) === 'Redo') {\n newFormattedValue = formatWithPattern(historyNavigator.redo().toString(), displayPattern);\n this.setState({ value: newFormattedValue, triggerType: 'Redo' });\n } else {\n this.setState({\n triggerEvent: event,\n triggerType: 'KeyDown',\n selectionStart: selectionStart ?? 0,\n selectionEnd: selectionEnd ?? 0,\n });\n }\n };\n\n handleOnPaste: React.ClipboardEventHandler<HTMLTextElement> = (event) => {\n const { displayPattern } = this.props;\n const pastedLength = unformatWithPattern(\n event.clipboardData.getData('Text'),\n displayPattern,\n ).length;\n\n this.setState({ triggerType: 'Paste', pastedLength });\n };\n\n handleOnCut: React.ClipboardEventHandler<HTMLTextElement> = () => {\n this.setState({ triggerType: 'Cut' });\n };\n\n isKeyAllowed = (action: EventType | string) => {\n const { displayPattern } = this.props;\n const symbolsInPattern = displayPattern.split('').filter((character) => character !== '*');\n\n return !symbolsInPattern.includes(action);\n };\n\n handleOnChange: React.ChangeEventHandler<HTMLTextElement> = (event) => {\n const { historyNavigator, triggerType } = this.state;\n const { displayPattern, onChange } = this.props;\n const { value } = event.target;\n let unformattedValue = unformatWithPattern(value, displayPattern);\n const action = this.getUserAction(unformattedValue);\n if (!this.isKeyAllowed(action) || triggerType === 'Undo' || triggerType === 'Redo') {\n return;\n }\n\n if (action === 'Backspace' || action === 'Delete') {\n unformattedValue = this.handleDelete(unformattedValue, action);\n }\n\n const newFormattedValue = formatWithPattern(unformattedValue, displayPattern);\n historyNavigator.add(unformattedValue);\n\n this.handleCursorPositioning(action);\n\n this.setState({ value: newFormattedValue }, () => {\n this.resetEvent();\n if (onChange) {\n const broadcastValue = unformatWithPattern(newFormattedValue, displayPattern);\n onChange(broadcastValue);\n }\n });\n };\n\n handleOnBlur: React.FocusEventHandler<HTMLTextElement> = (event) => {\n this.props.onBlur?.(unformatWithPattern(event.target.value, this.props.displayPattern));\n };\n\n handleOnFocus: React.FocusEventHandler<HTMLTextElement> = (event) => {\n const { displayPattern, onFocus } = this.props;\n if (onFocus) {\n this.handleOnChange(event);\n onFocus(unformatWithPattern(event.target.value, displayPattern));\n }\n };\n\n handleDelete = (unformattedValue: string, action: EventType) => {\n const { displayPattern } = this.props;\n const { selectionStart, selectionEnd } = this.state;\n const newStack = [...unformattedValue];\n if (selectionStart === selectionEnd) {\n let startPosition =\n selectionStart - getCountOfSymbolsInSelection(0, selectionStart, displayPattern);\n let toDelete = 0;\n\n let count = getDistanceToNextSymbol(selectionStart, displayPattern);\n if (action === 'Backspace') {\n startPosition -= 1;\n count = getDistanceToPreviousSymbol(selectionStart, displayPattern);\n }\n\n if (startPosition >= 0 && count) {\n toDelete = 1;\n }\n\n newStack.splice(startPosition, toDelete);\n }\n\n return newStack.join('');\n };\n\n handleCursorPositioning = (action: string) => {\n const { displayPattern } = this.props;\n const { triggerEvent, selectionStart, selectionEnd, pastedLength } = this.state;\n\n const cursorPosition = getCursorPositionAfterKeystroke(\n action,\n selectionStart,\n selectionEnd,\n displayPattern,\n pastedLength,\n );\n\n setTimeout(() => {\n if (triggerEvent) {\n (triggerEvent.target as HTMLTextElement).setSelectionRange(cursorPosition, cursorPosition);\n }\n this.setState({ selectionStart: cursorPosition, selectionEnd: cursorPosition });\n }, 0);\n };\n\n render() {\n const {\n inputMode,\n className,\n id,\n name,\n placeholder,\n readOnly,\n required,\n minLength,\n maxLength,\n disabled,\n autoComplete,\n } = this.props;\n const { value } = this.state;\n const renderProps: TextElementProps = {\n inputMode,\n className,\n id,\n name,\n placeholder,\n readOnly,\n required,\n minLength,\n maxLength,\n disabled,\n autoComplete,\n value,\n onFocus: this.handleOnFocus,\n onBlur: this.handleOnBlur,\n onPaste: this.handleOnPaste,\n onKeyDown: this.handleOnKeyDown,\n onChange: this.handleOnChange,\n onCut: this.handleOnCut,\n };\n return this.props.render(renderProps as T);\n }\n}\n\nexport default WithDisplayFormat;\n"],"names":["WithDisplayFormat","React","Component","defaultProps","autoComplete","displayPattern","value","constructor","props","unformattedValue","unformatWithPattern","state","formatWithPattern","historyNavigator","HistoryNavigator","prevDisplayPattern","triggerType","triggerEvent","selectionStart","selectionEnd","pastedLength","getDerivedStateFromProps","unFormattedValue","reset","getUserAction","ctrlKey","metaKey","key","shiftKey","length","resetEvent","setState","detectUndoRedo","event","handleOnKeyDown","persist","currentTarget","newFormattedValue","undo","toString","redo","handleOnPaste","clipboardData","getData","handleOnCut","isKeyAllowed","action","symbolsInPattern","split","filter","character","includes","handleOnChange","onChange","target","handleDelete","add","handleCursorPositioning","broadcastValue","handleOnBlur","onBlur","handleOnFocus","onFocus","newStack","startPosition","getCountOfSymbolsInSelection","toDelete","count","getDistanceToNextSymbol","getDistanceToPreviousSymbol","splice","join","cursorPosition","getCursorPositionAfterKeystroke","setTimeout","setSelectionRange","render","inputMode","className","id","name","placeholder","readOnly","required","minLength","maxLength","disabled","renderProps","onPaste","onKeyDown","onCut"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEA,MAAMA,iBAA8C,SAAQC,gBAAK,CAACC,SAGjE,CAAA;AAGC,EAAA,OAAOC,YAAY,GAAG;AACpBC,IAAAA,YAAY,EAAE,KAAK;AACnBC,IAAAA,cAAc,EAAE,EAAE;AAClBC,IAAAA,KAAK,EAAE;GACR;EAEDC,WAAAA,CAAYC,KAA6B,EAAA;IACvC,KAAK,CAACA,KAAK,CAAC;AACZ,IAAA,MAAMC,gBAAgB,GAAGC,2BAAmB,CAACF,KAAK,CAACF,KAAK,IAAI,EAAE,EAAEE,KAAK,CAACH,cAAc,CAAC;IACrF,IAAI,CAACM,KAAK,GAAG;MACXL,KAAK,EAAEM,yBAAiB,CAACH,gBAAgB,EAAED,KAAK,CAACH,cAAc,CAAC;AAChEQ,MAAAA,gBAAgB,EAAE,IAAIC,wBAAgB,EAAE;MACxCC,kBAAkB,EAAEP,KAAK,CAACH,cAAc;AACxCW,MAAAA,WAAW,EAAE,SAAS;AACtBC,MAAAA,YAAY,EAAE,IAAI;AAClBC,MAAAA,cAAc,EAAE,CAAC;AACjBC,MAAAA,YAAY,EAAE,CAAC;AACfC,MAAAA,YAAY,EAAE;KACf;AACH,EAAA;AAEA,EAAA,OAAOC,wBAAwBA,CAC7B;AAAEhB,IAAAA;AAAc,GAA0B,EAC1C;AAAEU,IAAAA,kBAAkB,GAAGV,cAAc;IAAEC,KAAK;AAAEO,IAAAA;AAAgB,GAA0B,EAAA;IAExF,IAAIE,kBAAkB,KAAKV,cAAc,EAAE;AACzC,MAAA,MAAMiB,gBAAgB,GAAGZ,2BAAmB,CAACJ,KAAK,EAAES,kBAAkB,CAAC;MACvEF,gBAAgB,CAACU,KAAK,EAAE;MAExB,OAAO;AACLR,QAAAA,kBAAkB,EAAEV,cAAc;AAClCC,QAAAA,KAAK,EAAEM,yBAAiB,CAACU,gBAAgB,EAAEjB,cAAc,CAAC;AAC1DW,QAAAA,WAAW,EAAE,IAAI;AACjBC,QAAAA,YAAY,EAAE,IAAI;AAClBG,QAAAA,YAAY,EAAE;OACf;AACH,IAAA;AACA,IAAA,OAAO,IAAI;AACb,EAAA;EAEAI,aAAa,GAAIf,gBAAwB,IAAwB;IAC/D,MAAM;MAAEQ,YAAY;MAAED,WAAW;AAAEV,MAAAA;KAAO,GAAG,IAAI,CAACK,KAAK;IACvD,MAAM;AAAEN,MAAAA;KAAgB,GAAG,IAAI,CAACG,KAAK;AAErC,IAAA,IAAIS,YAAY,EAAE;AAChB,MAAA,IAAID,WAAW,KAAK,OAAO,IAAIA,WAAW,KAAK,KAAK,EAAE;AACpD,QAAA,OAAOA,WAAW;AACpB,MAAA;AAEA,MAAA,IAAI,CAACC,YAAY,CAACQ,OAAO,IAAIR,YAAY,CAACS,OAAO,KAAKT,YAAY,CAACU,GAAG,KAAK,GAAG,EAAE;AAC9E,QAAA,OAAOV,YAAY,CAACW,QAAQ,GAAG,MAAM,GAAG,MAAM;AAChD,MAAA;AAEA;MACA,IAAIX,YAAY,CAACQ,OAAO,IAAIR,YAAY,CAACU,GAAG,KAAK,GAAG,EAAE;AACpD,QAAA,OAAO,QAAQ;AACjB,MAAA;AAEA;AACA,MAAA,IACE,OAAOV,YAAY,CAACU,GAAG,KAAK,WAAW,IACvClB,gBAAgB,CAACoB,MAAM,IAAInB,2BAAmB,CAACJ,KAAK,EAAED,cAAc,CAAC,CAACwB,MAAM,EAC5E;AACA,QAAA,OAAO,WAAW;AACpB,MAAA;MACA,OAAOZ,YAAY,CAACU,GAAG;AACzB,IAAA;AACA;AACA,IAAA,OAAO,OAAO;EAChB,CAAC;EAEDG,UAAU,GAAGA,MAAK;IAChB,IAAI,CAACC,QAAQ,CAAC;AACZf,MAAAA,WAAW,EAAE,SAAS;AACtBC,MAAAA,YAAY,EAAE,IAAI;AAClBG,MAAAA,YAAY,EAAE;AACf,KAAA,CAAC;EACJ,CAAC;EAEDY,cAAc,GAAIC,KAA2C,IAAI;AAC/D,IAAA,IAAI,CAACA,KAAK,CAACR,OAAO,IAAIQ,KAAK,CAACP,OAAO,KAAKO,KAAK,CAACN,GAAG,KAAK,GAAG,EAAE;AACzD,MAAA,OAAOM,KAAK,CAACL,QAAQ,GAAG,MAAM,GAAG,MAAM;AACzC,IAAA;AACA,IAAA,OAAO,IAAI;EACb,CAAC;EAEDM,eAAe,GAAiDD,KAAK,IAAI;IACvEA,KAAK,CAACE,OAAO,EAAE;IACf,MAAM;MAAEjB,cAAc;AAAEC,MAAAA;KAAc,GAAGc,KAAK,CAACG,aAAa;IAC5D,MAAM;AAAEvB,MAAAA;KAAkB,GAAG,IAAI,CAACF,KAAK;IACvC,MAAM;AAAEN,MAAAA;KAAgB,GAAG,IAAI,CAACG,KAAK;AAErC;IACA,IAAI6B,iBAAiB,GAAG,EAAE;IAE1B,IAAI,IAAI,CAACL,cAAc,CAACC,KAAK,CAAC,KAAK,MAAM,EAAE;AACzCI,MAAAA,iBAAiB,GAAGzB,yBAAiB,CAACC,gBAAgB,CAACyB,IAAI,EAAE,CAACC,QAAQ,EAAE,EAAElC,cAAc,CAAC;MACzF,IAAI,CAAC0B,QAAQ,CAAC;AAAEzB,QAAAA,KAAK,EAAE+B,iBAAiB;AAAErB,QAAAA,WAAW,EAAE;AAAM,OAAE,CAAC;IAClE,CAAC,MAAM,IAAI,IAAI,CAACgB,cAAc,CAACC,KAAK,CAAC,KAAK,MAAM,EAAE;AAChDI,MAAAA,iBAAiB,GAAGzB,yBAAiB,CAACC,gBAAgB,CAAC2B,IAAI,EAAE,CAACD,QAAQ,EAAE,EAAElC,cAAc,CAAC;MACzF,IAAI,CAAC0B,QAAQ,CAAC;AAAEzB,QAAAA,KAAK,EAAE+B,iBAAiB;AAAErB,QAAAA,WAAW,EAAE;AAAM,OAAE,CAAC;AAClE,IAAA,CAAC,MAAM;MACL,IAAI,CAACe,QAAQ,CAAC;AACZd,QAAAA,YAAY,EAAEgB,KAAK;AACnBjB,QAAAA,WAAW,EAAE,SAAS;QACtBE,cAAc,EAAEA,cAAc,IAAI,CAAC;QACnCC,YAAY,EAAEA,YAAY,IAAI;AAC/B,OAAA,CAAC;AACJ,IAAA;EACF,CAAC;EAEDsB,aAAa,GAAkDR,KAAK,IAAI;IACtE,MAAM;AAAE5B,MAAAA;KAAgB,GAAG,IAAI,CAACG,KAAK;AACrC,IAAA,MAAMY,YAAY,GAAGV,2BAAmB,CACtCuB,KAAK,CAACS,aAAa,CAACC,OAAO,CAAC,MAAM,CAAC,EACnCtC,cAAc,CACf,CAACwB,MAAM;IAER,IAAI,CAACE,QAAQ,CAAC;AAAEf,MAAAA,WAAW,EAAE,OAAO;AAAEI,MAAAA;AAAY,KAAE,CAAC;EACvD,CAAC;EAEDwB,WAAW,GAAiDA,MAAK;IAC/D,IAAI,CAACb,QAAQ,CAAC;AAAEf,MAAAA,WAAW,EAAE;AAAK,KAAE,CAAC;EACvC,CAAC;EAED6B,YAAY,GAAIC,MAA0B,IAAI;IAC5C,MAAM;AAAEzC,MAAAA;KAAgB,GAAG,IAAI,CAACG,KAAK;AACrC,IAAA,MAAMuC,gBAAgB,GAAG1C,cAAc,CAAC2C,KAAK,CAAC,EAAE,CAAC,CAACC,MAAM,CAAEC,SAAS,IAAKA,SAAS,KAAK,GAAG,CAAC;AAE1F,IAAA,OAAO,CAACH,gBAAgB,CAACI,QAAQ,CAACL,MAAM,CAAC;EAC3C,CAAC;EAEDM,cAAc,GAA+CnB,KAAK,IAAI;IACpE,MAAM;MAAEpB,gBAAgB;AAAEG,MAAAA;KAAa,GAAG,IAAI,CAACL,KAAK;IACpD,MAAM;MAAEN,cAAc;AAAEgD,MAAAA;KAAU,GAAG,IAAI,CAAC7C,KAAK;IAC/C,MAAM;AAAEF,MAAAA;KAAO,GAAG2B,KAAK,CAACqB,MAAM;AAC9B,IAAA,IAAI7C,gBAAgB,GAAGC,2BAAmB,CAACJ,KAAK,EAAED,cAAc,CAAC;AACjE,IAAA,MAAMyC,MAAM,GAAG,IAAI,CAACtB,aAAa,CAACf,gBAAgB,CAAC;AACnD,IAAA,IAAI,CAAC,IAAI,CAACoC,YAAY,CAACC,MAAM,CAAC,IAAI9B,WAAW,KAAK,MAAM,IAAIA,WAAW,KAAK,MAAM,EAAE;AAClF,MAAA;AACF,IAAA;AAEA,IAAA,IAAI8B,MAAM,KAAK,WAAW,IAAIA,MAAM,KAAK,QAAQ,EAAE;MACjDrC,gBAAgB,GAAG,IAAI,CAAC8C,YAAY,CAAC9C,gBAAgB,EAAEqC,MAAM,CAAC;AAChE,IAAA;AAEA,IAAA,MAAMT,iBAAiB,GAAGzB,yBAAiB,CAACH,gBAAgB,EAAEJ,cAAc,CAAC;AAC7EQ,IAAAA,gBAAgB,CAAC2C,GAAG,CAAC/C,gBAAgB,CAAC;AAEtC,IAAA,IAAI,CAACgD,uBAAuB,CAACX,MAAM,CAAC;IAEpC,IAAI,CAACf,QAAQ,CAAC;AAAEzB,MAAAA,KAAK,EAAE+B;AAAiB,KAAE,EAAE,MAAK;MAC/C,IAAI,CAACP,UAAU,EAAE;AACjB,MAAA,IAAIuB,QAAQ,EAAE;AACZ,QAAA,MAAMK,cAAc,GAAGhD,2BAAmB,CAAC2B,iBAAiB,EAAEhC,cAAc,CAAC;QAC7EgD,QAAQ,CAACK,cAAc,CAAC;AAC1B,MAAA;AACF,IAAA,CAAC,CAAC;EACJ,CAAC;EAEDC,YAAY,GAA8C1B,KAAK,IAAI;AACjE,IAAA,IAAI,CAACzB,KAAK,CAACoD,MAAM,GAAGlD,2BAAmB,CAACuB,KAAK,CAACqB,MAAM,CAAChD,KAAK,EAAE,IAAI,CAACE,KAAK,CAACH,cAAc,CAAC,CAAC;EACzF,CAAC;EAEDwD,aAAa,GAA8C5B,KAAK,IAAI;IAClE,MAAM;MAAE5B,cAAc;AAAEyD,MAAAA;KAAS,GAAG,IAAI,CAACtD,KAAK;AAC9C,IAAA,IAAIsD,OAAO,EAAE;AACX,MAAA,IAAI,CAACV,cAAc,CAACnB,KAAK,CAAC;MAC1B6B,OAAO,CAACpD,2BAAmB,CAACuB,KAAK,CAACqB,MAAM,CAAChD,KAAK,EAAED,cAAc,CAAC,CAAC;AAClE,IAAA;EACF,CAAC;AAEDkD,EAAAA,YAAY,GAAGA,CAAC9C,gBAAwB,EAAEqC,MAAiB,KAAI;IAC7D,MAAM;AAAEzC,MAAAA;KAAgB,GAAG,IAAI,CAACG,KAAK;IACrC,MAAM;MAAEU,cAAc;AAAEC,MAAAA;KAAc,GAAG,IAAI,CAACR,KAAK;AACnD,IAAA,MAAMoD,QAAQ,GAAG,CAAC,GAAGtD,gBAAgB,CAAC;IACtC,IAAIS,cAAc,KAAKC,YAAY,EAAE;MACnC,IAAI6C,aAAa,GACf9C,cAAc,GAAG+C,oCAA4B,CAAC,CAAC,EAAE/C,cAAc,EAAEb,cAAc,CAAC;MAClF,IAAI6D,QAAQ,GAAG,CAAC;AAEhB,MAAA,IAAIC,KAAK,GAAGC,2CAAuB,CAAClD,cAAc,EAAEb,cAAc,CAAC;MACnE,IAAIyC,MAAM,KAAK,WAAW,EAAE;AAC1BkB,QAAAA,aAAa,IAAI,CAAC;AAClBG,QAAAA,KAAK,GAAGE,+CAA2B,CAACnD,cAAc,EAAEb,cAAc,CAAC;AACrE,MAAA;AAEA,MAAA,IAAI2D,aAAa,IAAI,CAAC,IAAIG,KAAK,EAAE;AAC/BD,QAAAA,QAAQ,GAAG,CAAC;AACd,MAAA;AAEAH,MAAAA,QAAQ,CAACO,MAAM,CAACN,aAAa,EAAEE,QAAQ,CAAC;AAC1C,IAAA;AAEA,IAAA,OAAOH,QAAQ,CAACQ,IAAI,CAAC,EAAE,CAAC;EAC1B,CAAC;EAEDd,uBAAuB,GAAIX,MAAc,IAAI;IAC3C,MAAM;AAAEzC,MAAAA;KAAgB,GAAG,IAAI,CAACG,KAAK;IACrC,MAAM;MAAES,YAAY;MAAEC,cAAc;MAAEC,YAAY;AAAEC,MAAAA;KAAc,GAAG,IAAI,CAACT,KAAK;AAE/E,IAAA,MAAM6D,cAAc,GAAGC,uCAA+B,CACpD3B,MAAM,EACN5B,cAAc,EACdC,YAAY,EACZd,cAAc,EACde,YAAY,CACb;AAEDsD,IAAAA,UAAU,CAAC,MAAK;AACd,MAAA,IAAIzD,YAAY,EAAE;QACfA,YAAY,CAACqC,MAA0B,CAACqB,iBAAiB,CAACH,cAAc,EAAEA,cAAc,CAAC;AAC5F,MAAA;MACA,IAAI,CAACzC,QAAQ,CAAC;AAAEb,QAAAA,cAAc,EAAEsD,cAAc;AAAErD,QAAAA,YAAY,EAAEqD;AAAc,OAAE,CAAC;IACjF,CAAC,EAAE,CAAC,CAAC;EACP,CAAC;AAEDI,EAAAA,MAAMA,GAAA;IACJ,MAAM;MACJC,SAAS;MACTC,SAAS;MACTC,EAAE;MACFC,IAAI;MACJC,WAAW;MACXC,QAAQ;MACRC,QAAQ;MACRC,SAAS;MACTC,SAAS;MACTC,QAAQ;AACRlF,MAAAA;KACD,GAAG,IAAI,CAACI,KAAK;IACd,MAAM;AAAEF,MAAAA;KAAO,GAAG,IAAI,CAACK,KAAK;AAC5B,IAAA,MAAM4E,WAAW,GAAqB;MACpCV,SAAS;MACTC,SAAS;MACTC,EAAE;MACFC,IAAI;MACJC,WAAW;MACXC,QAAQ;MACRC,QAAQ;MACRC,SAAS;MACTC,SAAS;MACTC,QAAQ;MACRlF,YAAY;MACZE,KAAK;MACLwD,OAAO,EAAE,IAAI,CAACD,aAAa;MAC3BD,MAAM,EAAE,IAAI,CAACD,YAAY;MACzB6B,OAAO,EAAE,IAAI,CAAC/C,aAAa;MAC3BgD,SAAS,EAAE,IAAI,CAACvD,eAAe;MAC/BmB,QAAQ,EAAE,IAAI,CAACD,cAAc;MAC7BsC,KAAK,EAAE,IAAI,CAAC9C;KACb;AACD,IAAA,OAAO,IAAI,CAACpC,KAAK,CAACoE,MAAM,CAACW,WAAgB,CAAC;AAC5C,EAAA;;;;;"}
|
|
1
|
+
{"version":3,"file":"WithDisplayFormat.js","sources":["../../src/withDisplayFormat/WithDisplayFormat.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { HistoryNavigator } from '../common';\nimport {\n formatWithPattern,\n getCountOfSymbolsInSelection,\n getCursorPositionAfterKeystroke,\n unformatWithPattern,\n getDistanceToPreviousSymbol,\n getDistanceToNextSymbol,\n} from '../common/textFormat';\nimport { InputProps } from '../inputs/Input';\nimport { TextAreaProps } from '../inputs/TextArea';\n\ntype HTMLTextElement = HTMLInputElement | HTMLTextAreaElement;\ntype TextElementProps = InputProps | TextAreaProps;\n\nexport type EventType =\n | 'KeyDown'\n | 'Paste'\n | 'Cut'\n | 'Undo'\n | 'Redo'\n | 'Backspace'\n | 'Delete'\n | 'Initial';\n\ninterface WithDisplayFormatState {\n value: string;\n historyNavigator: HistoryNavigator;\n prevDisplayPattern: string;\n triggerType: EventType;\n triggerEvent: React.KeyboardEvent<HTMLTextElement> | null;\n pastedLength: number;\n selectionStart: number;\n selectionEnd: number;\n}\n\nexport interface WithDisplayFormatProps<T extends TextElementProps = TextElementProps>\n extends Pick<\n TextElementProps,\n | 'className'\n | 'disabled'\n | 'id'\n | 'maxLength'\n | 'minLength'\n | 'name'\n | 'placeholder'\n | 'readOnly'\n | 'required'\n | 'inputMode'\n > {\n value?: string;\n displayPattern: string;\n /**\n * autocomplete hides our form help so we need to disable it when help text\n * is present. Chrome ignores autocomplete=off, the only way to disable it is\n * to provide an 'invalid' value, for which 'disabled' serves.\n */\n autoComplete?: TextElementProps['autoComplete'] | 'disabled';\n onChange?: (value: string) => void;\n onBlur?: (value: string) => void;\n onFocus?: (value: string) => void;\n render: (renderProps: T) => React.JSX.Element;\n}\n\nclass WithDisplayFormat<T extends TextElementProps> extends React.Component<\n WithDisplayFormatProps<T>,\n WithDisplayFormatState\n> {\n declare props: WithDisplayFormatProps<T> &\n Required<Pick<WithDisplayFormatProps<T>, keyof typeof WithDisplayFormat.defaultProps>>;\n static defaultProps = {\n autoComplete: 'off',\n displayPattern: '',\n value: '',\n };\n\n constructor(props: WithDisplayFormatProps) {\n super(props);\n const unformattedValue = unformatWithPattern(props.value ?? '', props.displayPattern);\n this.state = {\n value: formatWithPattern(unformattedValue, props.displayPattern),\n historyNavigator: new HistoryNavigator(),\n prevDisplayPattern: props.displayPattern,\n triggerType: 'Initial',\n triggerEvent: null,\n selectionStart: 0,\n selectionEnd: 0,\n pastedLength: 0,\n };\n }\n\n static getDerivedStateFromProps(\n { displayPattern }: WithDisplayFormatProps,\n { prevDisplayPattern = displayPattern, value, historyNavigator }: WithDisplayFormatState,\n ) {\n if (prevDisplayPattern !== displayPattern) {\n const unFormattedValue = unformatWithPattern(value, prevDisplayPattern);\n historyNavigator.reset();\n\n return {\n prevDisplayPattern: displayPattern,\n value: formatWithPattern(unFormattedValue, displayPattern),\n triggerType: null,\n triggerEvent: null,\n pastedLength: 0,\n };\n }\n return null;\n }\n\n getUserAction = (unformattedValue: string): EventType | string => {\n const { triggerEvent, triggerType, value } = this.state;\n const { displayPattern } = this.props;\n\n if (triggerEvent) {\n if (triggerType === 'Paste' || triggerType === 'Cut') {\n return triggerType;\n }\n\n if ((triggerEvent.ctrlKey || triggerEvent.metaKey) && triggerEvent.key === 'z') {\n return triggerEvent.shiftKey ? 'Redo' : 'Undo';\n }\n\n // Detect mouse event redo\n if (triggerEvent.ctrlKey && triggerEvent.key === 'd') {\n return 'Delete';\n }\n\n // Android Fix.\n if (\n typeof triggerEvent.key === 'undefined' &&\n unformattedValue.length <= unformatWithPattern(value, displayPattern).length\n ) {\n return 'Backspace';\n }\n return triggerEvent.key;\n }\n // triggerEvent can be null only in case of \"autofilling\" (via password manager extension or browser build-in one) events\n return 'Paste';\n };\n\n resetEvent = () => {\n this.setState({\n triggerType: 'Initial',\n triggerEvent: null,\n pastedLength: 0,\n });\n };\n\n detectUndoRedo = (event: React.KeyboardEvent<HTMLTextElement>) => {\n if ((event.ctrlKey || event.metaKey) && event.key === 'z') {\n return event.shiftKey ? 'Redo' : 'Undo';\n }\n return null;\n };\n\n handleOnKeyDown: React.KeyboardEventHandler<HTMLTextElement> = (event) => {\n event.persist();\n const { selectionStart, selectionEnd } = event.currentTarget;\n const { historyNavigator } = this.state;\n const { displayPattern } = this.props;\n\n // Unfortunately Undo and Redo don't trigger OnChange event so we need to handle some value logic here.\n let newFormattedValue = '';\n\n if (this.detectUndoRedo(event) === 'Undo') {\n newFormattedValue = formatWithPattern(historyNavigator.undo().toString(), displayPattern);\n this.setState({ value: newFormattedValue, triggerType: 'Undo' });\n } else if (this.detectUndoRedo(event) === 'Redo') {\n newFormattedValue = formatWithPattern(historyNavigator.redo().toString(), displayPattern);\n this.setState({ value: newFormattedValue, triggerType: 'Redo' });\n } else {\n this.setState({\n triggerEvent: event,\n triggerType: 'KeyDown',\n selectionStart: selectionStart ?? 0,\n selectionEnd: selectionEnd ?? 0,\n });\n }\n };\n\n handleOnPaste: React.ClipboardEventHandler<HTMLTextElement> = (event) => {\n const { displayPattern } = this.props;\n const pastedLength = unformatWithPattern(\n event.clipboardData.getData('Text'),\n displayPattern,\n ).length;\n\n this.setState({ triggerType: 'Paste', pastedLength });\n };\n\n handleOnCut: React.ClipboardEventHandler<HTMLTextElement> = () => {\n this.setState({ triggerType: 'Cut' });\n };\n\n isKeyAllowed = (action: EventType | string) => {\n const { displayPattern } = this.props;\n const symbolsInPattern = displayPattern.split('').filter((character) => character !== '*');\n\n return !symbolsInPattern.includes(action);\n };\n\n handleOnChange: React.ChangeEventHandler<HTMLTextElement> = (event) => {\n const { historyNavigator, triggerType } = this.state;\n const { displayPattern, onChange } = this.props;\n const { value } = event.target;\n let unformattedValue = unformatWithPattern(value, displayPattern);\n const action = this.getUserAction(unformattedValue);\n if (!this.isKeyAllowed(action) || triggerType === 'Undo' || triggerType === 'Redo') {\n return;\n }\n\n if (action === 'Backspace' || action === 'Delete') {\n unformattedValue = this.handleDelete(unformattedValue, action);\n }\n\n const newFormattedValue = formatWithPattern(unformattedValue, displayPattern);\n historyNavigator.add(unformattedValue);\n\n this.handleCursorPositioning(action);\n\n this.setState({ value: newFormattedValue }, () => {\n this.resetEvent();\n if (onChange) {\n const broadcastValue = unformatWithPattern(newFormattedValue, displayPattern);\n onChange(broadcastValue);\n }\n });\n };\n\n handleOnBlur: React.FocusEventHandler<HTMLTextElement> = (event) => {\n this.props.onBlur?.(unformatWithPattern(event.target.value, this.props.displayPattern));\n };\n\n handleOnFocus: React.FocusEventHandler<HTMLTextElement> = (event) => {\n const { displayPattern, onFocus } = this.props;\n if (onFocus) {\n onFocus(unformatWithPattern(event.target.value, displayPattern));\n }\n };\n\n handleDelete = (unformattedValue: string, action: EventType) => {\n const { displayPattern } = this.props;\n const { selectionStart, selectionEnd } = this.state;\n const newStack = [...unformattedValue];\n if (selectionStart === selectionEnd) {\n let startPosition =\n selectionStart - getCountOfSymbolsInSelection(0, selectionStart, displayPattern);\n let toDelete = 0;\n\n let count = getDistanceToNextSymbol(selectionStart, displayPattern);\n if (action === 'Backspace') {\n startPosition -= 1;\n count = getDistanceToPreviousSymbol(selectionStart, displayPattern);\n }\n\n if (startPosition >= 0 && count) {\n toDelete = 1;\n }\n\n newStack.splice(startPosition, toDelete);\n }\n\n return newStack.join('');\n };\n\n handleCursorPositioning = (action: string) => {\n const { displayPattern } = this.props;\n const { triggerEvent, selectionStart, selectionEnd, pastedLength } = this.state;\n\n const cursorPosition = getCursorPositionAfterKeystroke(\n action,\n selectionStart,\n selectionEnd,\n displayPattern,\n pastedLength,\n );\n\n setTimeout(() => {\n if (triggerEvent) {\n (triggerEvent.target as HTMLTextElement).setSelectionRange(cursorPosition, cursorPosition);\n }\n this.setState({ selectionStart: cursorPosition, selectionEnd: cursorPosition });\n }, 0);\n };\n\n render() {\n const {\n inputMode,\n className,\n id,\n name,\n placeholder,\n readOnly,\n required,\n minLength,\n maxLength,\n disabled,\n autoComplete,\n } = this.props;\n const { value } = this.state;\n const renderProps: TextElementProps = {\n inputMode,\n className,\n id,\n name,\n placeholder,\n readOnly,\n required,\n minLength,\n maxLength,\n disabled,\n autoComplete,\n value,\n onFocus: this.handleOnFocus,\n onBlur: this.handleOnBlur,\n onPaste: this.handleOnPaste,\n onKeyDown: this.handleOnKeyDown,\n onChange: this.handleOnChange,\n onCut: this.handleOnCut,\n };\n return this.props.render(renderProps as T);\n }\n}\n\nexport default WithDisplayFormat;\n"],"names":["WithDisplayFormat","React","Component","defaultProps","autoComplete","displayPattern","value","constructor","props","unformattedValue","unformatWithPattern","state","formatWithPattern","historyNavigator","HistoryNavigator","prevDisplayPattern","triggerType","triggerEvent","selectionStart","selectionEnd","pastedLength","getDerivedStateFromProps","unFormattedValue","reset","getUserAction","ctrlKey","metaKey","key","shiftKey","length","resetEvent","setState","detectUndoRedo","event","handleOnKeyDown","persist","currentTarget","newFormattedValue","undo","toString","redo","handleOnPaste","clipboardData","getData","handleOnCut","isKeyAllowed","action","symbolsInPattern","split","filter","character","includes","handleOnChange","onChange","target","handleDelete","add","handleCursorPositioning","broadcastValue","handleOnBlur","onBlur","handleOnFocus","onFocus","newStack","startPosition","getCountOfSymbolsInSelection","toDelete","count","getDistanceToNextSymbol","getDistanceToPreviousSymbol","splice","join","cursorPosition","getCursorPositionAfterKeystroke","setTimeout","setSelectionRange","render","inputMode","className","id","name","placeholder","readOnly","required","minLength","maxLength","disabled","renderProps","onPaste","onKeyDown","onCut"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WithDisplayFormat.mjs","sources":["../../src/withDisplayFormat/WithDisplayFormat.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { HistoryNavigator } from '../common';\nimport {\n formatWithPattern,\n getCountOfSymbolsInSelection,\n getCursorPositionAfterKeystroke,\n unformatWithPattern,\n getDistanceToPreviousSymbol,\n getDistanceToNextSymbol,\n} from '../common/textFormat';\nimport { InputProps } from '../inputs/Input';\nimport { TextAreaProps } from '../inputs/TextArea';\n\ntype HTMLTextElement = HTMLInputElement | HTMLTextAreaElement;\ntype TextElementProps = InputProps | TextAreaProps;\n\nexport type EventType =\n | 'KeyDown'\n | 'Paste'\n | 'Cut'\n | 'Undo'\n | 'Redo'\n | 'Backspace'\n | 'Delete'\n | 'Initial';\n\ninterface WithDisplayFormatState {\n value: string;\n historyNavigator: HistoryNavigator;\n prevDisplayPattern: string;\n triggerType: EventType;\n triggerEvent: React.KeyboardEvent<HTMLTextElement> | null;\n pastedLength: number;\n selectionStart: number;\n selectionEnd: number;\n}\n\nexport interface WithDisplayFormatProps<T extends TextElementProps = TextElementProps>\n extends Pick<\n TextElementProps,\n | 'className'\n | 'disabled'\n | 'id'\n | 'maxLength'\n | 'minLength'\n | 'name'\n | 'placeholder'\n | 'readOnly'\n | 'required'\n | 'inputMode'\n > {\n value?: string;\n displayPattern: string;\n /**\n * autocomplete hides our form help so we need to disable it when help text\n * is present. Chrome ignores autocomplete=off, the only way to disable it is\n * to provide an 'invalid' value, for which 'disabled' serves.\n */\n autoComplete?: TextElementProps['autoComplete'] | 'disabled';\n onChange?: (value: string) => void;\n onBlur?: (value: string) => void;\n onFocus?: (value: string) => void;\n render: (renderProps: T) => React.JSX.Element;\n}\n\nclass WithDisplayFormat<T extends TextElementProps> extends React.Component<\n WithDisplayFormatProps<T>,\n WithDisplayFormatState\n> {\n declare props: WithDisplayFormatProps<T> &\n Required<Pick<WithDisplayFormatProps<T>, keyof typeof WithDisplayFormat.defaultProps>>;\n static defaultProps = {\n autoComplete: 'off',\n displayPattern: '',\n value: '',\n };\n\n constructor(props: WithDisplayFormatProps) {\n super(props);\n const unformattedValue = unformatWithPattern(props.value ?? '', props.displayPattern);\n this.state = {\n value: formatWithPattern(unformattedValue, props.displayPattern),\n historyNavigator: new HistoryNavigator(),\n prevDisplayPattern: props.displayPattern,\n triggerType: 'Initial',\n triggerEvent: null,\n selectionStart: 0,\n selectionEnd: 0,\n pastedLength: 0,\n };\n }\n\n static getDerivedStateFromProps(\n { displayPattern }: WithDisplayFormatProps,\n { prevDisplayPattern = displayPattern, value, historyNavigator }: WithDisplayFormatState,\n ) {\n if (prevDisplayPattern !== displayPattern) {\n const unFormattedValue = unformatWithPattern(value, prevDisplayPattern);\n historyNavigator.reset();\n\n return {\n prevDisplayPattern: displayPattern,\n value: formatWithPattern(unFormattedValue, displayPattern),\n triggerType: null,\n triggerEvent: null,\n pastedLength: 0,\n };\n }\n return null;\n }\n\n getUserAction = (unformattedValue: string): EventType | string => {\n const { triggerEvent, triggerType, value } = this.state;\n const { displayPattern } = this.props;\n\n if (triggerEvent) {\n if (triggerType === 'Paste' || triggerType === 'Cut') {\n return triggerType;\n }\n\n if ((triggerEvent.ctrlKey || triggerEvent.metaKey) && triggerEvent.key === 'z') {\n return triggerEvent.shiftKey ? 'Redo' : 'Undo';\n }\n\n // Detect mouse event redo\n if (triggerEvent.ctrlKey && triggerEvent.key === 'd') {\n return 'Delete';\n }\n\n // Android Fix.\n if (\n typeof triggerEvent.key === 'undefined' &&\n unformattedValue.length <= unformatWithPattern(value, displayPattern).length\n ) {\n return 'Backspace';\n }\n return triggerEvent.key;\n }\n // triggerEvent can be null only in case of \"autofilling\" (via password manager extension or browser build-in one) events\n return 'Paste';\n };\n\n resetEvent = () => {\n this.setState({\n triggerType: 'Initial',\n triggerEvent: null,\n pastedLength: 0,\n });\n };\n\n detectUndoRedo = (event: React.KeyboardEvent<HTMLTextElement>) => {\n if ((event.ctrlKey || event.metaKey) && event.key === 'z') {\n return event.shiftKey ? 'Redo' : 'Undo';\n }\n return null;\n };\n\n handleOnKeyDown: React.KeyboardEventHandler<HTMLTextElement> = (event) => {\n event.persist();\n const { selectionStart, selectionEnd } = event.currentTarget;\n const { historyNavigator } = this.state;\n const { displayPattern } = this.props;\n\n // Unfortunately Undo and Redo don't trigger OnChange event so we need to handle some value logic here.\n let newFormattedValue = '';\n\n if (this.detectUndoRedo(event) === 'Undo') {\n newFormattedValue = formatWithPattern(historyNavigator.undo().toString(), displayPattern);\n this.setState({ value: newFormattedValue, triggerType: 'Undo' });\n } else if (this.detectUndoRedo(event) === 'Redo') {\n newFormattedValue = formatWithPattern(historyNavigator.redo().toString(), displayPattern);\n this.setState({ value: newFormattedValue, triggerType: 'Redo' });\n } else {\n this.setState({\n triggerEvent: event,\n triggerType: 'KeyDown',\n selectionStart: selectionStart ?? 0,\n selectionEnd: selectionEnd ?? 0,\n });\n }\n };\n\n handleOnPaste: React.ClipboardEventHandler<HTMLTextElement> = (event) => {\n const { displayPattern } = this.props;\n const pastedLength = unformatWithPattern(\n event.clipboardData.getData('Text'),\n displayPattern,\n ).length;\n\n this.setState({ triggerType: 'Paste', pastedLength });\n };\n\n handleOnCut: React.ClipboardEventHandler<HTMLTextElement> = () => {\n this.setState({ triggerType: 'Cut' });\n };\n\n isKeyAllowed = (action: EventType | string) => {\n const { displayPattern } = this.props;\n const symbolsInPattern = displayPattern.split('').filter((character) => character !== '*');\n\n return !symbolsInPattern.includes(action);\n };\n\n handleOnChange: React.ChangeEventHandler<HTMLTextElement> = (event) => {\n const { historyNavigator, triggerType } = this.state;\n const { displayPattern, onChange } = this.props;\n const { value } = event.target;\n let unformattedValue = unformatWithPattern(value, displayPattern);\n const action = this.getUserAction(unformattedValue);\n if (!this.isKeyAllowed(action) || triggerType === 'Undo' || triggerType === 'Redo') {\n return;\n }\n\n if (action === 'Backspace' || action === 'Delete') {\n unformattedValue = this.handleDelete(unformattedValue, action);\n }\n\n const newFormattedValue = formatWithPattern(unformattedValue, displayPattern);\n historyNavigator.add(unformattedValue);\n\n this.handleCursorPositioning(action);\n\n this.setState({ value: newFormattedValue }, () => {\n this.resetEvent();\n if (onChange) {\n const broadcastValue = unformatWithPattern(newFormattedValue, displayPattern);\n onChange(broadcastValue);\n }\n });\n };\n\n handleOnBlur: React.FocusEventHandler<HTMLTextElement> = (event) => {\n this.props.onBlur?.(unformatWithPattern(event.target.value, this.props.displayPattern));\n };\n\n handleOnFocus: React.FocusEventHandler<HTMLTextElement> = (event) => {\n const { displayPattern, onFocus } = this.props;\n if (onFocus) {\n this.handleOnChange(event);\n onFocus(unformatWithPattern(event.target.value, displayPattern));\n }\n };\n\n handleDelete = (unformattedValue: string, action: EventType) => {\n const { displayPattern } = this.props;\n const { selectionStart, selectionEnd } = this.state;\n const newStack = [...unformattedValue];\n if (selectionStart === selectionEnd) {\n let startPosition =\n selectionStart - getCountOfSymbolsInSelection(0, selectionStart, displayPattern);\n let toDelete = 0;\n\n let count = getDistanceToNextSymbol(selectionStart, displayPattern);\n if (action === 'Backspace') {\n startPosition -= 1;\n count = getDistanceToPreviousSymbol(selectionStart, displayPattern);\n }\n\n if (startPosition >= 0 && count) {\n toDelete = 1;\n }\n\n newStack.splice(startPosition, toDelete);\n }\n\n return newStack.join('');\n };\n\n handleCursorPositioning = (action: string) => {\n const { displayPattern } = this.props;\n const { triggerEvent, selectionStart, selectionEnd, pastedLength } = this.state;\n\n const cursorPosition = getCursorPositionAfterKeystroke(\n action,\n selectionStart,\n selectionEnd,\n displayPattern,\n pastedLength,\n );\n\n setTimeout(() => {\n if (triggerEvent) {\n (triggerEvent.target as HTMLTextElement).setSelectionRange(cursorPosition, cursorPosition);\n }\n this.setState({ selectionStart: cursorPosition, selectionEnd: cursorPosition });\n }, 0);\n };\n\n render() {\n const {\n inputMode,\n className,\n id,\n name,\n placeholder,\n readOnly,\n required,\n minLength,\n maxLength,\n disabled,\n autoComplete,\n } = this.props;\n const { value } = this.state;\n const renderProps: TextElementProps = {\n inputMode,\n className,\n id,\n name,\n placeholder,\n readOnly,\n required,\n minLength,\n maxLength,\n disabled,\n autoComplete,\n value,\n onFocus: this.handleOnFocus,\n onBlur: this.handleOnBlur,\n onPaste: this.handleOnPaste,\n onKeyDown: this.handleOnKeyDown,\n onChange: this.handleOnChange,\n onCut: this.handleOnCut,\n };\n return this.props.render(renderProps as T);\n }\n}\n\nexport default WithDisplayFormat;\n"],"names":["WithDisplayFormat","React","Component","defaultProps","autoComplete","displayPattern","value","constructor","props","unformattedValue","unformatWithPattern","state","formatWithPattern","historyNavigator","HistoryNavigator","prevDisplayPattern","triggerType","triggerEvent","selectionStart","selectionEnd","pastedLength","getDerivedStateFromProps","unFormattedValue","reset","getUserAction","ctrlKey","metaKey","key","shiftKey","length","resetEvent","setState","detectUndoRedo","event","handleOnKeyDown","persist","currentTarget","newFormattedValue","undo","toString","redo","handleOnPaste","clipboardData","getData","handleOnCut","isKeyAllowed","action","symbolsInPattern","split","filter","character","includes","handleOnChange","onChange","target","handleDelete","add","handleCursorPositioning","broadcastValue","handleOnBlur","onBlur","handleOnFocus","onFocus","newStack","startPosition","getCountOfSymbolsInSelection","toDelete","count","getDistanceToNextSymbol","getDistanceToPreviousSymbol","splice","join","cursorPosition","getCursorPositionAfterKeystroke","setTimeout","setSelectionRange","render","inputMode","className","id","name","placeholder","readOnly","required","minLength","maxLength","disabled","renderProps","onPaste","onKeyDown","onCut"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WithDisplayFormat.mjs","sources":["../../src/withDisplayFormat/WithDisplayFormat.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { HistoryNavigator } from '../common';\nimport {\n formatWithPattern,\n getCountOfSymbolsInSelection,\n getCursorPositionAfterKeystroke,\n unformatWithPattern,\n getDistanceToPreviousSymbol,\n getDistanceToNextSymbol,\n} from '../common/textFormat';\nimport { InputProps } from '../inputs/Input';\nimport { TextAreaProps } from '../inputs/TextArea';\n\ntype HTMLTextElement = HTMLInputElement | HTMLTextAreaElement;\ntype TextElementProps = InputProps | TextAreaProps;\n\nexport type EventType =\n | 'KeyDown'\n | 'Paste'\n | 'Cut'\n | 'Undo'\n | 'Redo'\n | 'Backspace'\n | 'Delete'\n | 'Initial';\n\ninterface WithDisplayFormatState {\n value: string;\n historyNavigator: HistoryNavigator;\n prevDisplayPattern: string;\n triggerType: EventType;\n triggerEvent: React.KeyboardEvent<HTMLTextElement> | null;\n pastedLength: number;\n selectionStart: number;\n selectionEnd: number;\n}\n\nexport interface WithDisplayFormatProps<T extends TextElementProps = TextElementProps>\n extends Pick<\n TextElementProps,\n | 'className'\n | 'disabled'\n | 'id'\n | 'maxLength'\n | 'minLength'\n | 'name'\n | 'placeholder'\n | 'readOnly'\n | 'required'\n | 'inputMode'\n > {\n value?: string;\n displayPattern: string;\n /**\n * autocomplete hides our form help so we need to disable it when help text\n * is present. Chrome ignores autocomplete=off, the only way to disable it is\n * to provide an 'invalid' value, for which 'disabled' serves.\n */\n autoComplete?: TextElementProps['autoComplete'] | 'disabled';\n onChange?: (value: string) => void;\n onBlur?: (value: string) => void;\n onFocus?: (value: string) => void;\n render: (renderProps: T) => React.JSX.Element;\n}\n\nclass WithDisplayFormat<T extends TextElementProps> extends React.Component<\n WithDisplayFormatProps<T>,\n WithDisplayFormatState\n> {\n declare props: WithDisplayFormatProps<T> &\n Required<Pick<WithDisplayFormatProps<T>, keyof typeof WithDisplayFormat.defaultProps>>;\n static defaultProps = {\n autoComplete: 'off',\n displayPattern: '',\n value: '',\n };\n\n constructor(props: WithDisplayFormatProps) {\n super(props);\n const unformattedValue = unformatWithPattern(props.value ?? '', props.displayPattern);\n this.state = {\n value: formatWithPattern(unformattedValue, props.displayPattern),\n historyNavigator: new HistoryNavigator(),\n prevDisplayPattern: props.displayPattern,\n triggerType: 'Initial',\n triggerEvent: null,\n selectionStart: 0,\n selectionEnd: 0,\n pastedLength: 0,\n };\n }\n\n static getDerivedStateFromProps(\n { displayPattern }: WithDisplayFormatProps,\n { prevDisplayPattern = displayPattern, value, historyNavigator }: WithDisplayFormatState,\n ) {\n if (prevDisplayPattern !== displayPattern) {\n const unFormattedValue = unformatWithPattern(value, prevDisplayPattern);\n historyNavigator.reset();\n\n return {\n prevDisplayPattern: displayPattern,\n value: formatWithPattern(unFormattedValue, displayPattern),\n triggerType: null,\n triggerEvent: null,\n pastedLength: 0,\n };\n }\n return null;\n }\n\n getUserAction = (unformattedValue: string): EventType | string => {\n const { triggerEvent, triggerType, value } = this.state;\n const { displayPattern } = this.props;\n\n if (triggerEvent) {\n if (triggerType === 'Paste' || triggerType === 'Cut') {\n return triggerType;\n }\n\n if ((triggerEvent.ctrlKey || triggerEvent.metaKey) && triggerEvent.key === 'z') {\n return triggerEvent.shiftKey ? 'Redo' : 'Undo';\n }\n\n // Detect mouse event redo\n if (triggerEvent.ctrlKey && triggerEvent.key === 'd') {\n return 'Delete';\n }\n\n // Android Fix.\n if (\n typeof triggerEvent.key === 'undefined' &&\n unformattedValue.length <= unformatWithPattern(value, displayPattern).length\n ) {\n return 'Backspace';\n }\n return triggerEvent.key;\n }\n // triggerEvent can be null only in case of \"autofilling\" (via password manager extension or browser build-in one) events\n return 'Paste';\n };\n\n resetEvent = () => {\n this.setState({\n triggerType: 'Initial',\n triggerEvent: null,\n pastedLength: 0,\n });\n };\n\n detectUndoRedo = (event: React.KeyboardEvent<HTMLTextElement>) => {\n if ((event.ctrlKey || event.metaKey) && event.key === 'z') {\n return event.shiftKey ? 'Redo' : 'Undo';\n }\n return null;\n };\n\n handleOnKeyDown: React.KeyboardEventHandler<HTMLTextElement> = (event) => {\n event.persist();\n const { selectionStart, selectionEnd } = event.currentTarget;\n const { historyNavigator } = this.state;\n const { displayPattern } = this.props;\n\n // Unfortunately Undo and Redo don't trigger OnChange event so we need to handle some value logic here.\n let newFormattedValue = '';\n\n if (this.detectUndoRedo(event) === 'Undo') {\n newFormattedValue = formatWithPattern(historyNavigator.undo().toString(), displayPattern);\n this.setState({ value: newFormattedValue, triggerType: 'Undo' });\n } else if (this.detectUndoRedo(event) === 'Redo') {\n newFormattedValue = formatWithPattern(historyNavigator.redo().toString(), displayPattern);\n this.setState({ value: newFormattedValue, triggerType: 'Redo' });\n } else {\n this.setState({\n triggerEvent: event,\n triggerType: 'KeyDown',\n selectionStart: selectionStart ?? 0,\n selectionEnd: selectionEnd ?? 0,\n });\n }\n };\n\n handleOnPaste: React.ClipboardEventHandler<HTMLTextElement> = (event) => {\n const { displayPattern } = this.props;\n const pastedLength = unformatWithPattern(\n event.clipboardData.getData('Text'),\n displayPattern,\n ).length;\n\n this.setState({ triggerType: 'Paste', pastedLength });\n };\n\n handleOnCut: React.ClipboardEventHandler<HTMLTextElement> = () => {\n this.setState({ triggerType: 'Cut' });\n };\n\n isKeyAllowed = (action: EventType | string) => {\n const { displayPattern } = this.props;\n const symbolsInPattern = displayPattern.split('').filter((character) => character !== '*');\n\n return !symbolsInPattern.includes(action);\n };\n\n handleOnChange: React.ChangeEventHandler<HTMLTextElement> = (event) => {\n const { historyNavigator, triggerType } = this.state;\n const { displayPattern, onChange } = this.props;\n const { value } = event.target;\n let unformattedValue = unformatWithPattern(value, displayPattern);\n const action = this.getUserAction(unformattedValue);\n if (!this.isKeyAllowed(action) || triggerType === 'Undo' || triggerType === 'Redo') {\n return;\n }\n\n if (action === 'Backspace' || action === 'Delete') {\n unformattedValue = this.handleDelete(unformattedValue, action);\n }\n\n const newFormattedValue = formatWithPattern(unformattedValue, displayPattern);\n historyNavigator.add(unformattedValue);\n\n this.handleCursorPositioning(action);\n\n this.setState({ value: newFormattedValue }, () => {\n this.resetEvent();\n if (onChange) {\n const broadcastValue = unformatWithPattern(newFormattedValue, displayPattern);\n onChange(broadcastValue);\n }\n });\n };\n\n handleOnBlur: React.FocusEventHandler<HTMLTextElement> = (event) => {\n this.props.onBlur?.(unformatWithPattern(event.target.value, this.props.displayPattern));\n };\n\n handleOnFocus: React.FocusEventHandler<HTMLTextElement> = (event) => {\n const { displayPattern, onFocus } = this.props;\n if (onFocus) {\n onFocus(unformatWithPattern(event.target.value, displayPattern));\n }\n };\n\n handleDelete = (unformattedValue: string, action: EventType) => {\n const { displayPattern } = this.props;\n const { selectionStart, selectionEnd } = this.state;\n const newStack = [...unformattedValue];\n if (selectionStart === selectionEnd) {\n let startPosition =\n selectionStart - getCountOfSymbolsInSelection(0, selectionStart, displayPattern);\n let toDelete = 0;\n\n let count = getDistanceToNextSymbol(selectionStart, displayPattern);\n if (action === 'Backspace') {\n startPosition -= 1;\n count = getDistanceToPreviousSymbol(selectionStart, displayPattern);\n }\n\n if (startPosition >= 0 && count) {\n toDelete = 1;\n }\n\n newStack.splice(startPosition, toDelete);\n }\n\n return newStack.join('');\n };\n\n handleCursorPositioning = (action: string) => {\n const { displayPattern } = this.props;\n const { triggerEvent, selectionStart, selectionEnd, pastedLength } = this.state;\n\n const cursorPosition = getCursorPositionAfterKeystroke(\n action,\n selectionStart,\n selectionEnd,\n displayPattern,\n pastedLength,\n );\n\n setTimeout(() => {\n if (triggerEvent) {\n (triggerEvent.target as HTMLTextElement).setSelectionRange(cursorPosition, cursorPosition);\n }\n this.setState({ selectionStart: cursorPosition, selectionEnd: cursorPosition });\n }, 0);\n };\n\n render() {\n const {\n inputMode,\n className,\n id,\n name,\n placeholder,\n readOnly,\n required,\n minLength,\n maxLength,\n disabled,\n autoComplete,\n } = this.props;\n const { value } = this.state;\n const renderProps: TextElementProps = {\n inputMode,\n className,\n id,\n name,\n placeholder,\n readOnly,\n required,\n minLength,\n maxLength,\n disabled,\n autoComplete,\n value,\n onFocus: this.handleOnFocus,\n onBlur: this.handleOnBlur,\n onPaste: this.handleOnPaste,\n onKeyDown: this.handleOnKeyDown,\n onChange: this.handleOnChange,\n onCut: this.handleOnCut,\n };\n return this.props.render(renderProps as T);\n }\n}\n\nexport default WithDisplayFormat;\n"],"names":["WithDisplayFormat","React","Component","defaultProps","autoComplete","displayPattern","value","constructor","props","unformattedValue","unformatWithPattern","state","formatWithPattern","historyNavigator","HistoryNavigator","prevDisplayPattern","triggerType","triggerEvent","selectionStart","selectionEnd","pastedLength","getDerivedStateFromProps","unFormattedValue","reset","getUserAction","ctrlKey","metaKey","key","shiftKey","length","resetEvent","setState","detectUndoRedo","event","handleOnKeyDown","persist","currentTarget","newFormattedValue","undo","toString","redo","handleOnPaste","clipboardData","getData","handleOnCut","isKeyAllowed","action","symbolsInPattern","split","filter","character","includes","handleOnChange","onChange","target","handleDelete","add","handleCursorPositioning","broadcastValue","handleOnBlur","onBlur","handleOnFocus","onFocus","newStack","startPosition","getCountOfSymbolsInSelection","toDelete","count","getDistanceToNextSymbol","getDistanceToPreviousSymbol","splice","join","cursorPosition","getCursorPositionAfterKeystroke","setTimeout","setSelectionRange","render","inputMode","className","id","name","placeholder","readOnly","required","minLength","maxLength","disabled","renderProps","onPaste","onKeyDown","onCut"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transferwise/components",
|
|
3
|
-
"version": "46.
|
|
3
|
+
"version": "46.113.0",
|
|
4
4
|
"description": "Neptune React components",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -83,10 +83,11 @@
|
|
|
83
83
|
"storybook": "^9.1.3",
|
|
84
84
|
"storybook-addon-tag-badges": "^2.0.2",
|
|
85
85
|
"storybook-addon-test-codegen": "^2.0.1",
|
|
86
|
+
"framer-motion": "^12.23.22",
|
|
86
87
|
"@transferwise/less-config": "3.1.2",
|
|
87
|
-
"@transferwise/neptune-css": "14.25.0",
|
|
88
88
|
"@wise/components-theming": "1.7.0",
|
|
89
|
-
"@wise/wds-configs": "0.0.0"
|
|
89
|
+
"@wise/wds-configs": "0.0.0",
|
|
90
|
+
"@transferwise/neptune-css": "14.25.1"
|
|
90
91
|
},
|
|
91
92
|
"peerDependencies": {
|
|
92
93
|
"@transferwise/icons": "^3.22.4",
|
|
@@ -95,7 +96,13 @@
|
|
|
95
96
|
"@wise/components-theming": "^1.6.2",
|
|
96
97
|
"react": ">=18",
|
|
97
98
|
"react-dom": ">=18",
|
|
98
|
-
"react-intl": "^5.10.0 || ^6 || ^7"
|
|
99
|
+
"react-intl": "^5.10.0 || ^6 || ^7",
|
|
100
|
+
"framer-motion": "^12.23.22"
|
|
101
|
+
},
|
|
102
|
+
"peerDependenciesMeta": {
|
|
103
|
+
"framer-motion": {
|
|
104
|
+
"optional": true
|
|
105
|
+
}
|
|
99
106
|
},
|
|
100
107
|
"dependencies": {
|
|
101
108
|
"@babel/runtime": "^7.28.3",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Meta, Canvas, Source } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as stories from './ExpressiveMoneyInput.story';
|
|
3
|
+
|
|
4
|
+
<Meta title="Forms/ExpressiveMoneyInput/Autofocus" />
|
|
5
|
+
|
|
6
|
+
# Autofocus
|
|
7
|
+
|
|
8
|
+
Setting `autofocus` to `true` will automatically focus the amount input field when the component is mounted.
|
|
9
|
+
|
|
10
|
+
> **Please note:** If this is enabled, and someone is navigating through the page via assistive technologies (e.g. keyboard), then they will skip any content beforehand and also may not have the currency selector announced (as it's placed before the money input). This can actually fail [WCAG 2.4.3](https://www.w3.org/WAI/WCAG21/Understanding/focus-order.html) requirements in cases where the focused element isn't the first one. <br />Our recommendation is to only use this functionality sporadically and with careful consideration of the user experience.
|
|
11
|
+
|
|
12
|
+
<Canvas of={stories.WithAutofocus} />
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
.wds-amount-input-container {
|
|
2
|
+
width: 100%;
|
|
3
|
+
}
|
|
4
|
+
.wds-amount-input-input-container {
|
|
5
|
+
display: flex;
|
|
6
|
+
justify-content: right;
|
|
7
|
+
width: 100%;
|
|
8
|
+
transition: font-size 0.4s cubic-bezier(0.3, 0, 0.1, 1), height 0.4s cubic-bezier(0.3, 0, 0.1, 1), margin-top 0.4s cubic-bezier(0.3, 0, 0.1, 1), color 0.4s ease;
|
|
9
|
+
color: var(--color-interactive-primary);
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
margin-bottom: 0 !important;
|
|
12
|
+
}
|
|
13
|
+
@media (prefers-reduced-motion: reduce) {
|
|
14
|
+
.wds-amount-input-input-container {
|
|
15
|
+
transition: none;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
.wds-amount-input-input {
|
|
19
|
+
border: none;
|
|
20
|
+
outline: none;
|
|
21
|
+
flex-grow: 1;
|
|
22
|
+
text-align: right;
|
|
23
|
+
background-color: transparent;
|
|
24
|
+
}
|
|
25
|
+
.wds-amount-input-input:focus-visible {
|
|
26
|
+
outline: none;
|
|
27
|
+
}
|
|
28
|
+
.wds-amount-input-placeholder {
|
|
29
|
+
flex-grow: 0;
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
}
|
|
33
|
+
.wds-currency-selector:disabled {
|
|
34
|
+
opacity: 1 !important;
|
|
35
|
+
cursor: auto !important;
|
|
36
|
+
cursor: initial !important;
|
|
37
|
+
mix-blend-mode: initial !important;
|
|
38
|
+
}
|
|
39
|
+
.wds-chevron-container {
|
|
40
|
+
width: 32px;
|
|
41
|
+
width: var(--size-32);
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
color: var(--color-interactive-primary);
|
|
44
|
+
margin-left: 8px;
|
|
45
|
+
margin-left: var(--size-8);
|
|
46
|
+
transition: width 0.3s ease;
|
|
47
|
+
}
|
|
48
|
+
.wds-chevron-hidden {
|
|
49
|
+
width: 0;
|
|
50
|
+
}
|
|
51
|
+
.wds-expressive-money-input-currency-selector {
|
|
52
|
+
flex-shrink: 0;
|
|
53
|
+
margin-right: 24px;
|
|
54
|
+
margin-right: var(--size-24);
|
|
55
|
+
}
|
|
56
|
+
.wds-expressive-money-input-chevron {
|
|
57
|
+
transform: translateY(-5%);
|
|
58
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@import "./amountInput/AmountInput.less";
|
|
2
|
+
@import "./currencySelector/CurrencySelector.less";
|
|
3
|
+
@import "./chevron/Chevron.less";
|
|
4
|
+
|
|
5
|
+
.wds-expressive-money-input {
|
|
6
|
+
&-currency-selector {
|
|
7
|
+
flex-shrink: 0;
|
|
8
|
+
margin-right: var(--size-24);
|
|
9
|
+
}
|
|
10
|
+
&-chevron {
|
|
11
|
+
transform: translateY(-5%);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl';
|
|
2
|
+
|
|
3
|
+
export default defineMessages({
|
|
4
|
+
currencySelectorSearchPlaceholder: {
|
|
5
|
+
id: 'neptune.ExpressiveMoneyInput.currency.search.placeholder',
|
|
6
|
+
defaultMessage: 'Type a currency / country',
|
|
7
|
+
},
|
|
8
|
+
|
|
9
|
+
currencySelectorSelectCurrency: {
|
|
10
|
+
id: 'neptune.ExpressiveMoneyInput.currency.select.currency',
|
|
11
|
+
defaultMessage: 'Select currency',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/* eslint-disable jsx-a11y/anchor-is-valid, jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */
|
|
2
|
+
import { Meta, StoryObj, Decorator } from '@storybook/react-webpack5';
|
|
3
|
+
import { fn } from 'storybook/test';
|
|
4
|
+
import { Flag } from '@wise/art';
|
|
5
|
+
import { Rewards, Tags } from '@transferwise/icons';
|
|
6
|
+
import { storySourceWithoutNoise } from '../../.storybook/helpers';
|
|
7
|
+
import { lorem10, lorem5 } from '../test-utils';
|
|
8
|
+
import { Sentiment } from '../common';
|
|
9
|
+
import Link from '../link';
|
|
10
|
+
import Money from '../money';
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import Button from '../button';
|
|
13
|
+
import Modal from '../modal';
|
|
14
|
+
import ListItem from '../listItem';
|
|
15
|
+
import List from '../list';
|
|
16
|
+
import ExpressiveMoneyInput, { Props as ExpressiveMoneyInputProps } from './ExpressiveMoneyInput';
|
|
17
|
+
import type { Props as CurrencySelectorProps } from './currencySelector/CurrencySelector';
|
|
18
|
+
|
|
19
|
+
const getCurrencySelectorProps = ({
|
|
20
|
+
logEvents = false,
|
|
21
|
+
secondAvatar = false,
|
|
22
|
+
} = {}): Partial<CurrencySelectorProps> => ({
|
|
23
|
+
addons: secondAvatar ? [{ profileName: 'Mikkael Jordan' }] : undefined,
|
|
24
|
+
options: [
|
|
25
|
+
{
|
|
26
|
+
title: 'Popular',
|
|
27
|
+
currencies: [
|
|
28
|
+
{ code: 'USD', label: 'US Dollar', keywords: ['dollar', 'us'] },
|
|
29
|
+
{ code: 'AUD', label: 'Australia Dollar', keywords: ['dollar', 'us'] },
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
title: 'Others',
|
|
34
|
+
currencies: [
|
|
35
|
+
{ code: 'GBP', label: 'Pound', keywords: ['british'] },
|
|
36
|
+
{ code: 'EUR', label: 'Euro', keywords: ['euro'] },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
onOpen: logEvents ? fn() : () => {},
|
|
41
|
+
onSearchChange: logEvents ? fn() : (payload) => {},
|
|
42
|
+
onChange: logEvents ? fn() : (currency) => {},
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const withScrollbarProtector: Decorator = (Story) => (
|
|
46
|
+
<>
|
|
47
|
+
<style>{`.docs-story > div {overflow-y:hidden;}`}</style>
|
|
48
|
+
<Story />
|
|
49
|
+
</>
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
export default {
|
|
53
|
+
title: 'Forms/ExpressiveMoneyInput',
|
|
54
|
+
component: ExpressiveMoneyInput,
|
|
55
|
+
tags: ['contribution'],
|
|
56
|
+
parameters: {
|
|
57
|
+
docs: {
|
|
58
|
+
toc: true,
|
|
59
|
+
canvas: {
|
|
60
|
+
sourceState: 'hidden',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
args: {
|
|
65
|
+
label: 'You send',
|
|
66
|
+
currency: 'GBP',
|
|
67
|
+
amount: 1234.56,
|
|
68
|
+
currencySelector: getCurrencySelectorProps(),
|
|
69
|
+
loading: false,
|
|
70
|
+
inlinePrompt: { message: lorem10, sentiment: Sentiment.POSITIVE },
|
|
71
|
+
showChevron: false,
|
|
72
|
+
autoFocus: false,
|
|
73
|
+
onAmountChange: fn(),
|
|
74
|
+
onFocusChange: fn(),
|
|
75
|
+
},
|
|
76
|
+
decorators: [withScrollbarProtector],
|
|
77
|
+
} satisfies Meta<ExpressiveMoneyInputProps>;
|
|
78
|
+
|
|
79
|
+
type Story = StoryObj<ExpressiveMoneyInputProps>;
|
|
80
|
+
|
|
81
|
+
export const Playground: Story = {
|
|
82
|
+
tags: ['!autodocs'],
|
|
83
|
+
render: (args: ExpressiveMoneyInputProps) => <ExpressiveMoneyInput {...args} />,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const WithInitialAmount = {
|
|
87
|
+
args: {
|
|
88
|
+
amount: 1500,
|
|
89
|
+
inlinePrompt: undefined,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export const NullAmount = {
|
|
94
|
+
args: {
|
|
95
|
+
amount: null,
|
|
96
|
+
inlinePrompt: undefined,
|
|
97
|
+
currencySelector: getCurrencySelectorProps({ logEvents: true }),
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const WithLoading = {
|
|
102
|
+
args: {
|
|
103
|
+
loading: true,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The chevron should be visible only when the input is inactive
|
|
109
|
+
* and the current value is 0 or null.
|
|
110
|
+
*/
|
|
111
|
+
export const WithChevron = {
|
|
112
|
+
args: {
|
|
113
|
+
showChevron: true,
|
|
114
|
+
amount: 0,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export const WithBalanceText = storySourceWithoutNoise<ExpressiveMoneyInputProps>({
|
|
119
|
+
args: {
|
|
120
|
+
currencySelector: getCurrencySelectorProps({ logEvents: true }),
|
|
121
|
+
},
|
|
122
|
+
render: function Render(args: ExpressiveMoneyInputProps) {
|
|
123
|
+
const availableBalance = 1500;
|
|
124
|
+
const [sourceAmount, setSourceAmount] = React.useState(args.amount);
|
|
125
|
+
return (
|
|
126
|
+
<ExpressiveMoneyInput
|
|
127
|
+
{...args}
|
|
128
|
+
amount={sourceAmount}
|
|
129
|
+
inlinePrompt={{
|
|
130
|
+
message: (
|
|
131
|
+
<>
|
|
132
|
+
{`Available balance `}
|
|
133
|
+
<Link
|
|
134
|
+
onClick={() => {
|
|
135
|
+
setSourceAmount(availableBalance);
|
|
136
|
+
}}
|
|
137
|
+
>
|
|
138
|
+
<Money amount={availableBalance} currency={args.currency} />
|
|
139
|
+
</Link>
|
|
140
|
+
</>
|
|
141
|
+
),
|
|
142
|
+
}}
|
|
143
|
+
/>
|
|
144
|
+
);
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
export const WithInlinePromptSentiment = {
|
|
149
|
+
render: (args: ExpressiveMoneyInputProps) => {
|
|
150
|
+
const inlinePrompts = [
|
|
151
|
+
{ message: lorem5, sentiment: 'negative' },
|
|
152
|
+
{ message: lorem5, sentiment: 'warning' },
|
|
153
|
+
{ message: lorem5, sentiment: 'neutral' },
|
|
154
|
+
{ message: lorem5, sentiment: 'positive' },
|
|
155
|
+
{ message: lorem5, sentiment: 'positive', media: <Tags /> },
|
|
156
|
+
{ message: lorem5, sentiment: 'proposition' },
|
|
157
|
+
{ message: lorem5, sentiment: 'proposition', media: <Rewards /> },
|
|
158
|
+
] as const;
|
|
159
|
+
|
|
160
|
+
return inlinePrompts.map((inlinePrompt, index) => (
|
|
161
|
+
<ExpressiveMoneyInput key={index} {...args} inlinePrompt={inlinePrompt} />
|
|
162
|
+
));
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export const WithSecondaryCurrencySelectorAvatar = {
|
|
167
|
+
args: {
|
|
168
|
+
currencySelector: getCurrencySelectorProps({ logEvents: true, secondAvatar: true }),
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export const WithCustomCurrencySelector = {
|
|
173
|
+
render: (args: ExpressiveMoneyInputProps) => {
|
|
174
|
+
const [open, setOpen] = React.useState(false);
|
|
175
|
+
return (
|
|
176
|
+
<>
|
|
177
|
+
<ExpressiveMoneyInput
|
|
178
|
+
{...args}
|
|
179
|
+
currencySelector={{
|
|
180
|
+
customRender: ({ id, labelId }) => (
|
|
181
|
+
<Button
|
|
182
|
+
v2
|
|
183
|
+
size="sm"
|
|
184
|
+
priority="primary"
|
|
185
|
+
aria-describedby={labelId}
|
|
186
|
+
onClick={() => setOpen(true)}
|
|
187
|
+
>
|
|
188
|
+
Currency Selector
|
|
189
|
+
</Button>
|
|
190
|
+
),
|
|
191
|
+
}}
|
|
192
|
+
/>
|
|
193
|
+
<Modal
|
|
194
|
+
open={open}
|
|
195
|
+
title="Custom UX for currency selectors"
|
|
196
|
+
body={
|
|
197
|
+
<List>
|
|
198
|
+
<ListItem
|
|
199
|
+
media={
|
|
200
|
+
<ListItem.AvatarView>
|
|
201
|
+
<Flag code="gb" />
|
|
202
|
+
</ListItem.AvatarView>
|
|
203
|
+
}
|
|
204
|
+
title="GBP"
|
|
205
|
+
control={<ListItem.Radio name="currency-key" checked={false} />}
|
|
206
|
+
/>
|
|
207
|
+
<ListItem
|
|
208
|
+
media={
|
|
209
|
+
<ListItem.AvatarView>
|
|
210
|
+
<Flag code="au" />
|
|
211
|
+
</ListItem.AvatarView>
|
|
212
|
+
}
|
|
213
|
+
title="AUD"
|
|
214
|
+
control={<ListItem.Radio name="currency-key" checked />}
|
|
215
|
+
/>
|
|
216
|
+
</List>
|
|
217
|
+
}
|
|
218
|
+
onClose={() => setOpen(false)}
|
|
219
|
+
/>
|
|
220
|
+
</>
|
|
221
|
+
);
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
export const WithAutofocus = {
|
|
226
|
+
tags: ['!autodocs', '!dev'],
|
|
227
|
+
args: {
|
|
228
|
+
inlinePrompt: undefined,
|
|
229
|
+
autoFocus: true,
|
|
230
|
+
},
|
|
231
|
+
render: (args: ExpressiveMoneyInputProps) => <ExpressiveMoneyInput {...args} />,
|
|
232
|
+
};
|