@transferwise/components 0.0.0-experimental-38a194b → 0.0.0-experimental-b20133d
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/field/Field.js +60 -32
- package/build/field/Field.js.map +1 -1
- package/build/field/Field.messages.js +14 -0
- package/build/field/Field.messages.js.map +1 -0
- package/build/field/Field.messages.mjs +10 -0
- package/build/field/Field.messages.mjs.map +1 -0
- package/build/field/Field.mjs +62 -34
- package/build/field/Field.mjs.map +1 -1
- package/build/flowNavigation/FlowNavigation.js +4 -2
- package/build/flowNavigation/FlowNavigation.js.map +1 -1
- package/build/flowNavigation/FlowNavigation.mjs +4 -2
- package/build/flowNavigation/FlowNavigation.mjs.map +1 -1
- package/build/i18n/en.json +1 -0
- package/build/i18n/en.json.js +1 -0
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +1 -0
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/inputs/TextArea.js +5 -0
- package/build/inputs/TextArea.js.map +1 -1
- package/build/inputs/TextArea.mjs +6 -1
- package/build/inputs/TextArea.mjs.map +1 -1
- package/build/inputs/contexts.js +16 -0
- package/build/inputs/contexts.js.map +1 -1
- package/build/inputs/contexts.mjs +16 -2
- package/build/inputs/contexts.mjs.map +1 -1
- package/build/main.css +14 -1
- package/build/styles/field/Field.css +13 -1
- package/build/styles/main.css +14 -1
- package/build/types/field/Field.d.ts.map +1 -1
- package/build/types/field/Field.messages.d.ts +8 -0
- package/build/types/field/Field.messages.d.ts.map +1 -0
- package/build/types/flowNavigation/FlowNavigation.d.ts.map +1 -1
- package/build/types/inputs/TextArea.d.ts.map +1 -1
- package/build/types/inputs/contexts.d.ts +6 -0
- package/build/types/inputs/contexts.d.ts.map +1 -1
- package/build/types/test-utils/index.d.ts +2 -0
- package/build/types/test-utils/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/field/Field.css +13 -1
- package/src/field/Field.less +11 -1
- package/src/field/Field.messages.ts +8 -0
- package/src/field/Field.story.tsx +5 -1
- package/src/field/Field.tsx +80 -37
- package/src/flowNavigation/FlowNavigation.test.js +2 -2
- package/src/flowNavigation/FlowNavigation.tsx +5 -2
- package/src/i18n/en.json +1 -0
- package/src/inputs/TextArea.story.tsx +56 -0
- package/src/inputs/TextArea.tsx +7 -2
- package/src/inputs/contexts.tsx +18 -1
- package/src/main.css +14 -1
- package/src/textareaWithDisplayFormat/TextareaWithDisplayFormat.story.tsx +1 -0
- package/src/flowNavigation/FlowNavigation.test.story.tsx +0 -76
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
2
|
import { forwardRef } from 'react';
|
|
3
3
|
import { inputClassNameBase } from './_common.mjs';
|
|
4
|
-
import { useInputAttributes } from './contexts.mjs';
|
|
4
|
+
import { useInputAttributes, useTextareaCharacterCount } from './contexts.mjs';
|
|
5
5
|
import { jsx } from 'react/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
const TextArea = /*#__PURE__*/forwardRef(function TextArea({
|
|
8
8
|
className,
|
|
9
|
+
maxLength,
|
|
9
10
|
...restProps
|
|
10
11
|
}, reference) {
|
|
11
12
|
const inputAttributes = useInputAttributes();
|
|
13
|
+
const value = restProps.value ?? restProps.defaultValue ?? '';
|
|
14
|
+
const currentLength = typeof value === 'string' ? value.length : String(value).length;
|
|
15
|
+
useTextareaCharacterCount(currentLength, maxLength);
|
|
12
16
|
return /*#__PURE__*/jsx("textarea", {
|
|
13
17
|
ref: reference,
|
|
14
18
|
className: clsx(className, inputClassNameBase(), 'np-text-area'),
|
|
19
|
+
maxLength: maxLength,
|
|
15
20
|
...inputAttributes,
|
|
16
21
|
...restProps
|
|
17
22
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextArea.mjs","sources":["../../src/inputs/TextArea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { forwardRef } from 'react';\n\nimport { Merge } from '../utils';\nimport { inputClassNameBase } from './_common';\nimport { useInputAttributes } from './contexts';\n\nexport interface TextAreaProps extends Merge<\n React.ComponentPropsWithRef<'textarea'>,\n {\n 'aria-invalid'?: boolean;\n }\n> {}\n\nexport const TextArea = forwardRef(function TextArea(\n { className, ...restProps }: TextAreaProps,\n reference: React.ForwardedRef<HTMLTextAreaElement | null>,\n) {\n const inputAttributes = useInputAttributes();\n\n return (\n <textarea\n ref={reference}\n className={clsx(className, inputClassNameBase(), 'np-text-area')}\n {...inputAttributes}\n {...restProps}\n />\n );\n});\n"],"names":["TextArea","forwardRef","className","restProps","reference","inputAttributes","useInputAttributes","_jsx","ref","clsx","inputClassNameBase"],"mappings":";;;;;;MAcaA,QAAQ,gBAAGC,UAAU,CAAC,SAASD,QAAQA,CAClD;EAAEE,SAAS;EAAE,GAAGC;AAAS,CAAiB,
|
|
1
|
+
{"version":3,"file":"TextArea.mjs","sources":["../../src/inputs/TextArea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { forwardRef } from 'react';\n\nimport { Merge } from '../utils';\nimport { inputClassNameBase } from './_common';\nimport { useTextareaCharacterCount, useInputAttributes } from './contexts';\n\nexport interface TextAreaProps extends Merge<\n React.ComponentPropsWithRef<'textarea'>,\n {\n 'aria-invalid'?: boolean;\n }\n> {}\n\nexport const TextArea = forwardRef(function TextArea(\n { className, maxLength, ...restProps }: TextAreaProps,\n reference: React.ForwardedRef<HTMLTextAreaElement | null>,\n) {\n const inputAttributes = useInputAttributes();\n const value = restProps.value ?? restProps.defaultValue ?? '';\n const currentLength = typeof value === 'string' ? value.length : String(value).length;\n\n useTextareaCharacterCount(currentLength, maxLength);\n\n return (\n <textarea\n ref={reference}\n className={clsx(className, inputClassNameBase(), 'np-text-area')}\n maxLength={maxLength}\n {...inputAttributes}\n {...restProps}\n />\n );\n});\n"],"names":["TextArea","forwardRef","className","maxLength","restProps","reference","inputAttributes","useInputAttributes","value","defaultValue","currentLength","length","String","useTextareaCharacterCount","_jsx","ref","clsx","inputClassNameBase"],"mappings":";;;;;;MAcaA,QAAQ,gBAAGC,UAAU,CAAC,SAASD,QAAQA,CAClD;EAAEE,SAAS;EAAEC,SAAS;EAAE,GAAGC;AAAS,CAAiB,EACrDC,SAAyD,EAAA;AAEzD,EAAA,MAAMC,eAAe,GAAGC,kBAAkB,EAAE;EAC5C,MAAMC,KAAK,GAAGJ,SAAS,CAACI,KAAK,IAAIJ,SAAS,CAACK,YAAY,IAAI,EAAE;AAC7D,EAAA,MAAMC,aAAa,GAAG,OAAOF,KAAK,KAAK,QAAQ,GAAGA,KAAK,CAACG,MAAM,GAAGC,MAAM,CAACJ,KAAK,CAAC,CAACG,MAAM;AAErFE,EAAAA,yBAAyB,CAACH,aAAa,EAAEP,SAAS,CAAC;AAEnD,EAAA,oBACEW,GAAA,CAAA,UAAA,EAAA;AACEC,IAAAA,GAAG,EAAEV,SAAU;IACfH,SAAS,EAAEc,IAAI,CAACd,SAAS,EAAEe,kBAAkB,EAAE,EAAE,cAAc,CAAE;AACjEd,IAAAA,SAAS,EAAEA,SAAU;AAAA,IAAA,GACjBG,eAAe;IAAA,GACfF;AAAS,GAAC,CACd;AAEN,CAAC;;;;"}
|
package/build/inputs/contexts.js
CHANGED
|
@@ -25,6 +25,20 @@ function useInputAttributes({
|
|
|
25
25
|
function useFieldLabelRef() {
|
|
26
26
|
return React.useContext(FieldLabelContext)?.ref;
|
|
27
27
|
}
|
|
28
|
+
const TextareaCharacterCountContext = /*#__PURE__*/React.createContext(undefined);
|
|
29
|
+
const TextareaCharacterCountProvider = TextareaCharacterCountContext.Provider;
|
|
30
|
+
function useTextareaCharacterCount(current, max) {
|
|
31
|
+
const setCharacterCount = React.useContext(TextareaCharacterCountContext);
|
|
32
|
+
React.useEffect(() => {
|
|
33
|
+
if (setCharacterCount && max != null) {
|
|
34
|
+
setCharacterCount({
|
|
35
|
+
current,
|
|
36
|
+
max
|
|
37
|
+
});
|
|
38
|
+
return () => setCharacterCount(null);
|
|
39
|
+
}
|
|
40
|
+
}, [setCharacterCount, current, max]);
|
|
41
|
+
}
|
|
28
42
|
function withInputAttributes(Component, args) {
|
|
29
43
|
function ComponentWithInputAttributes(props) {
|
|
30
44
|
return /*#__PURE__*/jsxRuntime.jsx(Component, {
|
|
@@ -40,7 +54,9 @@ exports.FieldLabelContextProvider = FieldLabelContextProvider;
|
|
|
40
54
|
exports.InputDescribedByProvider = InputDescribedByProvider;
|
|
41
55
|
exports.InputIdContextProvider = InputIdContextProvider;
|
|
42
56
|
exports.InputInvalidProvider = InputInvalidProvider;
|
|
57
|
+
exports.TextareaCharacterCountProvider = TextareaCharacterCountProvider;
|
|
43
58
|
exports.useFieldLabelRef = useFieldLabelRef;
|
|
44
59
|
exports.useInputAttributes = useInputAttributes;
|
|
60
|
+
exports.useTextareaCharacterCount = useTextareaCharacterCount;
|
|
45
61
|
exports.withInputAttributes = withInputAttributes;
|
|
46
62
|
//# sourceMappingURL=contexts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contexts.js","sources":["../../src/inputs/contexts.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\n\ntype FieldLabelContextType = {\n id?: string;\n ref?: React.RefObject<HTMLLabelElement>;\n};\n\nconst FieldLabelContext = createContext<FieldLabelContextType | undefined>(undefined);\nexport const FieldLabelContextProvider = FieldLabelContext.Provider;\n\nconst InputIdContext = createContext<string | undefined>(undefined);\nexport const InputIdContextProvider = InputIdContext.Provider;\n\nconst InputDescribedByContext = createContext<string | undefined>(undefined);\nexport const InputDescribedByProvider = InputDescribedByContext.Provider;\n\nconst InputInvalidContext = createContext<boolean | undefined>(undefined);\nexport const InputInvalidProvider = InputInvalidContext.Provider;\n\ninterface UseInputAttributesArgs {\n /** Set this to `true` if the underlying element is not directly [labelable as per the HTML specification](https://html.spec.whatwg.org/multipage/forms.html#category-label). */\n nonLabelable?: boolean;\n}\n\nexport function useInputAttributes({ nonLabelable }: UseInputAttributesArgs = {}) {\n const labelId = useContext(FieldLabelContext)?.id;\n return {\n id: useContext(InputIdContext),\n 'aria-labelledby': nonLabelable ? labelId : undefined,\n 'aria-describedby': useContext(InputDescribedByContext),\n 'aria-invalid': useContext(InputInvalidContext),\n } satisfies React.HTMLAttributes<HTMLElement>;\n}\n\nexport function useFieldLabelRef() {\n return useContext(FieldLabelContext)?.ref;\n}\n\nexport interface WithInputAttributesProps {\n inputAttributes: ReturnType<typeof useInputAttributes>;\n}\n\nexport function withInputAttributes<T extends Partial<WithInputAttributesProps>>(\n Component: React.ComponentType<T>,\n args?: UseInputAttributesArgs,\n) {\n function ComponentWithInputAttributes(props: Omit<T, keyof WithInputAttributesProps>) {\n return <Component inputAttributes={useInputAttributes(args)} {...(props as T)} />;\n }\n\n ComponentWithInputAttributes.displayName = `withInputAttributes(${Component.displayName || Component.name || 'Component'})`;\n\n return ComponentWithInputAttributes;\n}\n"],"names":["FieldLabelContext","createContext","undefined","FieldLabelContextProvider","Provider","InputIdContext","InputIdContextProvider","InputDescribedByContext","InputDescribedByProvider","InputInvalidContext","InputInvalidProvider","useInputAttributes","nonLabelable","labelId","useContext","id","useFieldLabelRef","ref","withInputAttributes","Component","args","ComponentWithInputAttributes","props","_jsx","inputAttributes","displayName","name"],"mappings":";;;;;AAOA,MAAMA,iBAAiB,gBAAGC,mBAAa,CAAoCC,SAAS,CAAC;AAC9E,MAAMC,yBAAyB,GAAGH,iBAAiB,CAACI;AAE3D,MAAMC,cAAc,gBAAGJ,mBAAa,CAAqBC,SAAS,CAAC;AAC5D,MAAMI,sBAAsB,GAAGD,cAAc,CAACD;AAErD,MAAMG,uBAAuB,gBAAGN,mBAAa,CAAqBC,SAAS,CAAC;AACrE,MAAMM,wBAAwB,GAAGD,uBAAuB,CAACH;AAEhE,MAAMK,mBAAmB,gBAAGR,mBAAa,CAAsBC,SAAS,CAAC;AAClE,MAAMQ,oBAAoB,GAAGD,mBAAmB,CAACL;SAOxCO,kBAAkBA,CAAC;AAAEC,EAAAA;IAAyC,EAAE,EAAA;AAC9E,EAAA,MAAMC,OAAO,GAAGC,gBAAU,CAACd,iBAAiB,CAAC,EAAEe,EAAE;EACjD,OAAO;AACLA,IAAAA,EAAE,EAAED,gBAAU,CAACT,cAAc,CAAC;AAC9B,IAAA,iBAAiB,EAAEO,YAAY,GAAGC,OAAO,GAAGX,SAAS;AACrD,IAAA,kBAAkB,EAAEY,gBAAU,CAACP,uBAAuB,CAAC;IACvD,cAAc,EAAEO,gBAAU,CAACL,mBAAmB;GACH;AAC/C;SAEgBO,gBAAgBA,GAAA;AAC9B,EAAA,OAAOF,gBAAU,CAACd,iBAAiB,CAAC,EAAEiB,GAAG;AAC3C;AAMM,
|
|
1
|
+
{"version":3,"file":"contexts.js","sources":["../../src/inputs/contexts.tsx"],"sourcesContent":["import { createContext, useContext, useEffect } from 'react';\n\ntype FieldLabelContextType = {\n id?: string;\n ref?: React.RefObject<HTMLLabelElement>;\n};\n\nconst FieldLabelContext = createContext<FieldLabelContextType | undefined>(undefined);\nexport const FieldLabelContextProvider = FieldLabelContext.Provider;\n\nconst InputIdContext = createContext<string | undefined>(undefined);\nexport const InputIdContextProvider = InputIdContext.Provider;\n\nconst InputDescribedByContext = createContext<string | undefined>(undefined);\nexport const InputDescribedByProvider = InputDescribedByContext.Provider;\n\nconst InputInvalidContext = createContext<boolean | undefined>(undefined);\nexport const InputInvalidProvider = InputInvalidContext.Provider;\n\ninterface UseInputAttributesArgs {\n /** Set this to `true` if the underlying element is not directly [labelable as per the HTML specification](https://html.spec.whatwg.org/multipage/forms.html#category-label). */\n nonLabelable?: boolean;\n}\n\nexport function useInputAttributes({ nonLabelable }: UseInputAttributesArgs = {}) {\n const labelId = useContext(FieldLabelContext)?.id;\n return {\n id: useContext(InputIdContext),\n 'aria-labelledby': nonLabelable ? labelId : undefined,\n 'aria-describedby': useContext(InputDescribedByContext),\n 'aria-invalid': useContext(InputInvalidContext),\n } satisfies React.HTMLAttributes<HTMLElement>;\n}\n\nexport function useFieldLabelRef() {\n return useContext(FieldLabelContext)?.ref;\n}\n\nexport type TextareaCharacterCountState = { current: number; max: number } | null;\n\nconst TextareaCharacterCountContext = createContext<\n ((state: TextareaCharacterCountState) => void) | undefined\n>(undefined);\nexport const TextareaCharacterCountProvider = TextareaCharacterCountContext.Provider;\n\nexport function useTextareaCharacterCount(current: number, max: number | undefined) {\n const setCharacterCount = useContext(TextareaCharacterCountContext);\n useEffect(() => {\n if (setCharacterCount && max != null) {\n setCharacterCount({ current, max });\n return () => setCharacterCount(null);\n }\n }, [setCharacterCount, current, max]);\n}\n\nexport interface WithInputAttributesProps {\n inputAttributes: ReturnType<typeof useInputAttributes>;\n}\n\nexport function withInputAttributes<T extends Partial<WithInputAttributesProps>>(\n Component: React.ComponentType<T>,\n args?: UseInputAttributesArgs,\n) {\n function ComponentWithInputAttributes(props: Omit<T, keyof WithInputAttributesProps>) {\n return <Component inputAttributes={useInputAttributes(args)} {...(props as T)} />;\n }\n\n ComponentWithInputAttributes.displayName = `withInputAttributes(${Component.displayName || Component.name || 'Component'})`;\n\n return ComponentWithInputAttributes;\n}\n"],"names":["FieldLabelContext","createContext","undefined","FieldLabelContextProvider","Provider","InputIdContext","InputIdContextProvider","InputDescribedByContext","InputDescribedByProvider","InputInvalidContext","InputInvalidProvider","useInputAttributes","nonLabelable","labelId","useContext","id","useFieldLabelRef","ref","TextareaCharacterCountContext","TextareaCharacterCountProvider","useTextareaCharacterCount","current","max","setCharacterCount","useEffect","withInputAttributes","Component","args","ComponentWithInputAttributes","props","_jsx","inputAttributes","displayName","name"],"mappings":";;;;;AAOA,MAAMA,iBAAiB,gBAAGC,mBAAa,CAAoCC,SAAS,CAAC;AAC9E,MAAMC,yBAAyB,GAAGH,iBAAiB,CAACI;AAE3D,MAAMC,cAAc,gBAAGJ,mBAAa,CAAqBC,SAAS,CAAC;AAC5D,MAAMI,sBAAsB,GAAGD,cAAc,CAACD;AAErD,MAAMG,uBAAuB,gBAAGN,mBAAa,CAAqBC,SAAS,CAAC;AACrE,MAAMM,wBAAwB,GAAGD,uBAAuB,CAACH;AAEhE,MAAMK,mBAAmB,gBAAGR,mBAAa,CAAsBC,SAAS,CAAC;AAClE,MAAMQ,oBAAoB,GAAGD,mBAAmB,CAACL;SAOxCO,kBAAkBA,CAAC;AAAEC,EAAAA;IAAyC,EAAE,EAAA;AAC9E,EAAA,MAAMC,OAAO,GAAGC,gBAAU,CAACd,iBAAiB,CAAC,EAAEe,EAAE;EACjD,OAAO;AACLA,IAAAA,EAAE,EAAED,gBAAU,CAACT,cAAc,CAAC;AAC9B,IAAA,iBAAiB,EAAEO,YAAY,GAAGC,OAAO,GAAGX,SAAS;AACrD,IAAA,kBAAkB,EAAEY,gBAAU,CAACP,uBAAuB,CAAC;IACvD,cAAc,EAAEO,gBAAU,CAACL,mBAAmB;GACH;AAC/C;SAEgBO,gBAAgBA,GAAA;AAC9B,EAAA,OAAOF,gBAAU,CAACd,iBAAiB,CAAC,EAAEiB,GAAG;AAC3C;AAIA,MAAMC,6BAA6B,gBAAGjB,mBAAa,CAEjDC,SAAS,CAAC;AACL,MAAMiB,8BAA8B,GAAGD,6BAA6B,CAACd;AAEtE,SAAUgB,yBAAyBA,CAACC,OAAe,EAAEC,GAAuB,EAAA;AAChF,EAAA,MAAMC,iBAAiB,GAAGT,gBAAU,CAACI,6BAA6B,CAAC;AACnEM,EAAAA,eAAS,CAAC,MAAK;AACb,IAAA,IAAID,iBAAiB,IAAID,GAAG,IAAI,IAAI,EAAE;AACpCC,MAAAA,iBAAiB,CAAC;QAAEF,OAAO;AAAEC,QAAAA;AAAG,OAAE,CAAC;AACnC,MAAA,OAAO,MAAMC,iBAAiB,CAAC,IAAI,CAAC;AACtC,IAAA;EACF,CAAC,EAAE,CAACA,iBAAiB,EAAEF,OAAO,EAAEC,GAAG,CAAC,CAAC;AACvC;AAMM,SAAUG,mBAAmBA,CACjCC,SAAiC,EACjCC,IAA6B,EAAA;EAE7B,SAASC,4BAA4BA,CAACC,KAA8C,EAAA;IAClF,oBAAOC,cAAA,CAACJ,SAAS,EAAA;AAACK,MAAAA,eAAe,EAAEpB,kBAAkB,CAACgB,IAAI,CAAE;MAAA,GAAME;AAAW,MAAI;AACnF,EAAA;AAEAD,EAAAA,4BAA4B,CAACI,WAAW,GAAG,CAAA,oBAAA,EAAuBN,SAAS,CAACM,WAAW,IAAIN,SAAS,CAACO,IAAI,IAAI,WAAW,CAAA,CAAA,CAAG;AAE3H,EAAA,OAAOL,4BAA4B;AACrC;;;;;;;;;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, useContext } from 'react';
|
|
1
|
+
import { createContext, useContext, useEffect } from 'react';
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
const FieldLabelContext = /*#__PURE__*/createContext(undefined);
|
|
@@ -23,6 +23,20 @@ function useInputAttributes({
|
|
|
23
23
|
function useFieldLabelRef() {
|
|
24
24
|
return useContext(FieldLabelContext)?.ref;
|
|
25
25
|
}
|
|
26
|
+
const TextareaCharacterCountContext = /*#__PURE__*/createContext(undefined);
|
|
27
|
+
const TextareaCharacterCountProvider = TextareaCharacterCountContext.Provider;
|
|
28
|
+
function useTextareaCharacterCount(current, max) {
|
|
29
|
+
const setCharacterCount = useContext(TextareaCharacterCountContext);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (setCharacterCount && max != null) {
|
|
32
|
+
setCharacterCount({
|
|
33
|
+
current,
|
|
34
|
+
max
|
|
35
|
+
});
|
|
36
|
+
return () => setCharacterCount(null);
|
|
37
|
+
}
|
|
38
|
+
}, [setCharacterCount, current, max]);
|
|
39
|
+
}
|
|
26
40
|
function withInputAttributes(Component, args) {
|
|
27
41
|
function ComponentWithInputAttributes(props) {
|
|
28
42
|
return /*#__PURE__*/jsx(Component, {
|
|
@@ -34,5 +48,5 @@ function withInputAttributes(Component, args) {
|
|
|
34
48
|
return ComponentWithInputAttributes;
|
|
35
49
|
}
|
|
36
50
|
|
|
37
|
-
export { FieldLabelContextProvider, InputDescribedByProvider, InputIdContextProvider, InputInvalidProvider, useFieldLabelRef, useInputAttributes, withInputAttributes };
|
|
51
|
+
export { FieldLabelContextProvider, InputDescribedByProvider, InputIdContextProvider, InputInvalidProvider, TextareaCharacterCountProvider, useFieldLabelRef, useInputAttributes, useTextareaCharacterCount, withInputAttributes };
|
|
38
52
|
//# sourceMappingURL=contexts.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contexts.mjs","sources":["../../src/inputs/contexts.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\n\ntype FieldLabelContextType = {\n id?: string;\n ref?: React.RefObject<HTMLLabelElement>;\n};\n\nconst FieldLabelContext = createContext<FieldLabelContextType | undefined>(undefined);\nexport const FieldLabelContextProvider = FieldLabelContext.Provider;\n\nconst InputIdContext = createContext<string | undefined>(undefined);\nexport const InputIdContextProvider = InputIdContext.Provider;\n\nconst InputDescribedByContext = createContext<string | undefined>(undefined);\nexport const InputDescribedByProvider = InputDescribedByContext.Provider;\n\nconst InputInvalidContext = createContext<boolean | undefined>(undefined);\nexport const InputInvalidProvider = InputInvalidContext.Provider;\n\ninterface UseInputAttributesArgs {\n /** Set this to `true` if the underlying element is not directly [labelable as per the HTML specification](https://html.spec.whatwg.org/multipage/forms.html#category-label). */\n nonLabelable?: boolean;\n}\n\nexport function useInputAttributes({ nonLabelable }: UseInputAttributesArgs = {}) {\n const labelId = useContext(FieldLabelContext)?.id;\n return {\n id: useContext(InputIdContext),\n 'aria-labelledby': nonLabelable ? labelId : undefined,\n 'aria-describedby': useContext(InputDescribedByContext),\n 'aria-invalid': useContext(InputInvalidContext),\n } satisfies React.HTMLAttributes<HTMLElement>;\n}\n\nexport function useFieldLabelRef() {\n return useContext(FieldLabelContext)?.ref;\n}\n\nexport interface WithInputAttributesProps {\n inputAttributes: ReturnType<typeof useInputAttributes>;\n}\n\nexport function withInputAttributes<T extends Partial<WithInputAttributesProps>>(\n Component: React.ComponentType<T>,\n args?: UseInputAttributesArgs,\n) {\n function ComponentWithInputAttributes(props: Omit<T, keyof WithInputAttributesProps>) {\n return <Component inputAttributes={useInputAttributes(args)} {...(props as T)} />;\n }\n\n ComponentWithInputAttributes.displayName = `withInputAttributes(${Component.displayName || Component.name || 'Component'})`;\n\n return ComponentWithInputAttributes;\n}\n"],"names":["FieldLabelContext","createContext","undefined","FieldLabelContextProvider","Provider","InputIdContext","InputIdContextProvider","InputDescribedByContext","InputDescribedByProvider","InputInvalidContext","InputInvalidProvider","useInputAttributes","nonLabelable","labelId","useContext","id","useFieldLabelRef","ref","withInputAttributes","Component","args","ComponentWithInputAttributes","props","_jsx","inputAttributes","displayName","name"],"mappings":";;;AAOA,MAAMA,iBAAiB,gBAAGC,aAAa,CAAoCC,SAAS,CAAC;AAC9E,MAAMC,yBAAyB,GAAGH,iBAAiB,CAACI;AAE3D,MAAMC,cAAc,gBAAGJ,aAAa,CAAqBC,SAAS,CAAC;AAC5D,MAAMI,sBAAsB,GAAGD,cAAc,CAACD;AAErD,MAAMG,uBAAuB,gBAAGN,aAAa,CAAqBC,SAAS,CAAC;AACrE,MAAMM,wBAAwB,GAAGD,uBAAuB,CAACH;AAEhE,MAAMK,mBAAmB,gBAAGR,aAAa,CAAsBC,SAAS,CAAC;AAClE,MAAMQ,oBAAoB,GAAGD,mBAAmB,CAACL;SAOxCO,kBAAkBA,CAAC;AAAEC,EAAAA;IAAyC,EAAE,EAAA;AAC9E,EAAA,MAAMC,OAAO,GAAGC,UAAU,CAACd,iBAAiB,CAAC,EAAEe,EAAE;EACjD,OAAO;AACLA,IAAAA,EAAE,EAAED,UAAU,CAACT,cAAc,CAAC;AAC9B,IAAA,iBAAiB,EAAEO,YAAY,GAAGC,OAAO,GAAGX,SAAS;AACrD,IAAA,kBAAkB,EAAEY,UAAU,CAACP,uBAAuB,CAAC;IACvD,cAAc,EAAEO,UAAU,CAACL,mBAAmB;GACH;AAC/C;SAEgBO,gBAAgBA,GAAA;AAC9B,EAAA,OAAOF,UAAU,CAACd,iBAAiB,CAAC,EAAEiB,GAAG;AAC3C;AAMM,
|
|
1
|
+
{"version":3,"file":"contexts.mjs","sources":["../../src/inputs/contexts.tsx"],"sourcesContent":["import { createContext, useContext, useEffect } from 'react';\n\ntype FieldLabelContextType = {\n id?: string;\n ref?: React.RefObject<HTMLLabelElement>;\n};\n\nconst FieldLabelContext = createContext<FieldLabelContextType | undefined>(undefined);\nexport const FieldLabelContextProvider = FieldLabelContext.Provider;\n\nconst InputIdContext = createContext<string | undefined>(undefined);\nexport const InputIdContextProvider = InputIdContext.Provider;\n\nconst InputDescribedByContext = createContext<string | undefined>(undefined);\nexport const InputDescribedByProvider = InputDescribedByContext.Provider;\n\nconst InputInvalidContext = createContext<boolean | undefined>(undefined);\nexport const InputInvalidProvider = InputInvalidContext.Provider;\n\ninterface UseInputAttributesArgs {\n /** Set this to `true` if the underlying element is not directly [labelable as per the HTML specification](https://html.spec.whatwg.org/multipage/forms.html#category-label). */\n nonLabelable?: boolean;\n}\n\nexport function useInputAttributes({ nonLabelable }: UseInputAttributesArgs = {}) {\n const labelId = useContext(FieldLabelContext)?.id;\n return {\n id: useContext(InputIdContext),\n 'aria-labelledby': nonLabelable ? labelId : undefined,\n 'aria-describedby': useContext(InputDescribedByContext),\n 'aria-invalid': useContext(InputInvalidContext),\n } satisfies React.HTMLAttributes<HTMLElement>;\n}\n\nexport function useFieldLabelRef() {\n return useContext(FieldLabelContext)?.ref;\n}\n\nexport type TextareaCharacterCountState = { current: number; max: number } | null;\n\nconst TextareaCharacterCountContext = createContext<\n ((state: TextareaCharacterCountState) => void) | undefined\n>(undefined);\nexport const TextareaCharacterCountProvider = TextareaCharacterCountContext.Provider;\n\nexport function useTextareaCharacterCount(current: number, max: number | undefined) {\n const setCharacterCount = useContext(TextareaCharacterCountContext);\n useEffect(() => {\n if (setCharacterCount && max != null) {\n setCharacterCount({ current, max });\n return () => setCharacterCount(null);\n }\n }, [setCharacterCount, current, max]);\n}\n\nexport interface WithInputAttributesProps {\n inputAttributes: ReturnType<typeof useInputAttributes>;\n}\n\nexport function withInputAttributes<T extends Partial<WithInputAttributesProps>>(\n Component: React.ComponentType<T>,\n args?: UseInputAttributesArgs,\n) {\n function ComponentWithInputAttributes(props: Omit<T, keyof WithInputAttributesProps>) {\n return <Component inputAttributes={useInputAttributes(args)} {...(props as T)} />;\n }\n\n ComponentWithInputAttributes.displayName = `withInputAttributes(${Component.displayName || Component.name || 'Component'})`;\n\n return ComponentWithInputAttributes;\n}\n"],"names":["FieldLabelContext","createContext","undefined","FieldLabelContextProvider","Provider","InputIdContext","InputIdContextProvider","InputDescribedByContext","InputDescribedByProvider","InputInvalidContext","InputInvalidProvider","useInputAttributes","nonLabelable","labelId","useContext","id","useFieldLabelRef","ref","TextareaCharacterCountContext","TextareaCharacterCountProvider","useTextareaCharacterCount","current","max","setCharacterCount","useEffect","withInputAttributes","Component","args","ComponentWithInputAttributes","props","_jsx","inputAttributes","displayName","name"],"mappings":";;;AAOA,MAAMA,iBAAiB,gBAAGC,aAAa,CAAoCC,SAAS,CAAC;AAC9E,MAAMC,yBAAyB,GAAGH,iBAAiB,CAACI;AAE3D,MAAMC,cAAc,gBAAGJ,aAAa,CAAqBC,SAAS,CAAC;AAC5D,MAAMI,sBAAsB,GAAGD,cAAc,CAACD;AAErD,MAAMG,uBAAuB,gBAAGN,aAAa,CAAqBC,SAAS,CAAC;AACrE,MAAMM,wBAAwB,GAAGD,uBAAuB,CAACH;AAEhE,MAAMK,mBAAmB,gBAAGR,aAAa,CAAsBC,SAAS,CAAC;AAClE,MAAMQ,oBAAoB,GAAGD,mBAAmB,CAACL;SAOxCO,kBAAkBA,CAAC;AAAEC,EAAAA;IAAyC,EAAE,EAAA;AAC9E,EAAA,MAAMC,OAAO,GAAGC,UAAU,CAACd,iBAAiB,CAAC,EAAEe,EAAE;EACjD,OAAO;AACLA,IAAAA,EAAE,EAAED,UAAU,CAACT,cAAc,CAAC;AAC9B,IAAA,iBAAiB,EAAEO,YAAY,GAAGC,OAAO,GAAGX,SAAS;AACrD,IAAA,kBAAkB,EAAEY,UAAU,CAACP,uBAAuB,CAAC;IACvD,cAAc,EAAEO,UAAU,CAACL,mBAAmB;GACH;AAC/C;SAEgBO,gBAAgBA,GAAA;AAC9B,EAAA,OAAOF,UAAU,CAACd,iBAAiB,CAAC,EAAEiB,GAAG;AAC3C;AAIA,MAAMC,6BAA6B,gBAAGjB,aAAa,CAEjDC,SAAS,CAAC;AACL,MAAMiB,8BAA8B,GAAGD,6BAA6B,CAACd;AAEtE,SAAUgB,yBAAyBA,CAACC,OAAe,EAAEC,GAAuB,EAAA;AAChF,EAAA,MAAMC,iBAAiB,GAAGT,UAAU,CAACI,6BAA6B,CAAC;AACnEM,EAAAA,SAAS,CAAC,MAAK;AACb,IAAA,IAAID,iBAAiB,IAAID,GAAG,IAAI,IAAI,EAAE;AACpCC,MAAAA,iBAAiB,CAAC;QAAEF,OAAO;AAAEC,QAAAA;AAAG,OAAE,CAAC;AACnC,MAAA,OAAO,MAAMC,iBAAiB,CAAC,IAAI,CAAC;AACtC,IAAA;EACF,CAAC,EAAE,CAACA,iBAAiB,EAAEF,OAAO,EAAEC,GAAG,CAAC,CAAC;AACvC;AAMM,SAAUG,mBAAmBA,CACjCC,SAAiC,EACjCC,IAA6B,EAAA;EAE7B,SAASC,4BAA4BA,CAACC,KAA8C,EAAA;IAClF,oBAAOC,GAAA,CAACJ,SAAS,EAAA;AAACK,MAAAA,eAAe,EAAEpB,kBAAkB,CAACgB,IAAI,CAAE;MAAA,GAAME;AAAW,MAAI;AACnF,EAAA;AAEAD,EAAAA,4BAA4B,CAACI,WAAW,GAAG,CAAA,oBAAA,EAAuBN,SAAS,CAACM,WAAW,IAAIN,SAAS,CAACO,IAAI,IAAI,WAAW,CAAA,CAAA,CAAG;AAE3H,EAAA,OAAOL,4BAA4B;AACrC;;;;"}
|
package/build/main.css
CHANGED
|
@@ -30194,9 +30194,22 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
|
|
|
30194
30194
|
}
|
|
30195
30195
|
|
|
30196
30196
|
.np-field-control,
|
|
30197
|
-
.np-
|
|
30197
|
+
.np-field-footer {
|
|
30198
|
+
display: flex;
|
|
30199
|
+
align-items: flex-start;
|
|
30198
30200
|
margin-top: 4px;
|
|
30199
30201
|
margin-top: var(--size-4);
|
|
30202
|
+
gap: 8px;
|
|
30203
|
+
gap: var(--size-8);
|
|
30204
|
+
}
|
|
30205
|
+
|
|
30206
|
+
.np-field-counter {
|
|
30207
|
+
margin-left: auto;
|
|
30208
|
+
white-space: nowrap;
|
|
30209
|
+
padding: 4px 0;
|
|
30210
|
+
padding: var(--size-4) 0;
|
|
30211
|
+
color: #768e9c;
|
|
30212
|
+
color: var(--color-content-tertiary);
|
|
30200
30213
|
}
|
|
30201
30214
|
|
|
30202
30215
|
.np-field .form-group--typeahead[class],
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
.np-field-control,
|
|
2
|
-
.np-
|
|
2
|
+
.np-field-footer {
|
|
3
|
+
display: flex;
|
|
4
|
+
align-items: flex-start;
|
|
3
5
|
margin-top: 4px;
|
|
4
6
|
margin-top: var(--size-4);
|
|
7
|
+
gap: 8px;
|
|
8
|
+
gap: var(--size-8);
|
|
9
|
+
}
|
|
10
|
+
.np-field-counter {
|
|
11
|
+
margin-left: auto;
|
|
12
|
+
white-space: nowrap;
|
|
13
|
+
padding: 4px 0;
|
|
14
|
+
padding: var(--size-4) 0;
|
|
15
|
+
color: #768e9c;
|
|
16
|
+
color: var(--color-content-tertiary);
|
|
5
17
|
}
|
|
6
18
|
.np-field .form-group--typeahead[class],
|
|
7
19
|
.np-field .np-checkbox-label[class] {
|
package/build/styles/main.css
CHANGED
|
@@ -30194,9 +30194,22 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
|
|
|
30194
30194
|
}
|
|
30195
30195
|
|
|
30196
30196
|
.np-field-control,
|
|
30197
|
-
.np-
|
|
30197
|
+
.np-field-footer {
|
|
30198
|
+
display: flex;
|
|
30199
|
+
align-items: flex-start;
|
|
30198
30200
|
margin-top: 4px;
|
|
30199
30201
|
margin-top: var(--size-4);
|
|
30202
|
+
gap: 8px;
|
|
30203
|
+
gap: var(--size-8);
|
|
30204
|
+
}
|
|
30205
|
+
|
|
30206
|
+
.np-field-counter {
|
|
30207
|
+
margin-left: auto;
|
|
30208
|
+
white-space: nowrap;
|
|
30209
|
+
padding: 4px 0;
|
|
30210
|
+
padding: var(--size-4) 0;
|
|
30211
|
+
color: #768e9c;
|
|
30212
|
+
color: var(--color-content-tertiary);
|
|
30200
30213
|
}
|
|
30201
30214
|
|
|
30202
30215
|
.np-field .form-group--typeahead[class],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../../../src/field/Field.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../../../src/field/Field.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAWjE,MAAM,MAAM,UAAU,GAAG;IACvB,6IAA6I;IAC7I,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,sGAAsG;IACtG,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kDAAkD;IAClD,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;SAGK;IACL,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,8EAA8E;IAC9E,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,iCAAiC;IACjC,SAAS,CAAC,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,KAAK,GAAI,wJAanB,UAAU,gCAkHZ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Field.messages.d.ts","sourceRoot":"","sources":["../../../src/field/Field.messages.ts"],"names":[],"mappings":";;;;;;AAEA,wBAKG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlowNavigation.d.ts","sourceRoot":"","sources":["../../../src/flowNavigation/FlowNavigation.tsx"],"names":[],"mappings":"AAOA,OAAgB,EAAE,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAQxD,MAAM,WAAW,mBAAmB;IAClC,iBAAiB;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,wBAAwB;IACxB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,qBAAqB;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,sIAAsI;IACtI,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,wGAAwG;IACxG,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;CACxB;AAED,QAAA,MAAM,cAAc,GAAI,+DAQrB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"FlowNavigation.d.ts","sourceRoot":"","sources":["../../../src/flowNavigation/FlowNavigation.tsx"],"names":[],"mappings":"AAOA,OAAgB,EAAE,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAQxD,MAAM,WAAW,mBAAmB;IAClC,iBAAiB;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,wBAAwB;IACxB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,qBAAqB;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,sIAAsI;IACtI,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,wGAAwG;IACxG,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;CACxB;AAED,QAAA,MAAM,cAAc,GAAI,+DAQrB,mBAAmB,gCAyErB,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextArea.d.ts","sourceRoot":"","sources":["../../../src/inputs/TextArea.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAIjC,MAAM,WAAW,aAAc,SAAQ,KAAK,CAC1C,KAAK,CAAC,qBAAqB,CAAC,UAAU,CAAC,EACvC;IACE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CACF;CAAG;AAEJ,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"TextArea.d.ts","sourceRoot":"","sources":["../../../src/inputs/TextArea.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAIjC,MAAM,WAAW,aAAc,SAAQ,KAAK,CAC1C,KAAK,CAAC,qBAAqB,CAAC,UAAU,CAAC,EACvC;IACE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CACF;CAAG;AAEJ,eAAO,MAAM,QAAQ,mIAmBnB,CAAC"}
|
|
@@ -17,6 +17,12 @@ export declare function useInputAttributes({ nonLabelable }?: UseInputAttributes
|
|
|
17
17
|
'aria-invalid': boolean | undefined;
|
|
18
18
|
};
|
|
19
19
|
export declare function useFieldLabelRef(): import("react").RefObject<HTMLLabelElement> | undefined;
|
|
20
|
+
export type TextareaCharacterCountState = {
|
|
21
|
+
current: number;
|
|
22
|
+
max: number;
|
|
23
|
+
} | null;
|
|
24
|
+
export declare const TextareaCharacterCountProvider: import("react").Provider<((state: TextareaCharacterCountState) => void) | undefined>;
|
|
25
|
+
export declare function useTextareaCharacterCount(current: number, max: number | undefined): void;
|
|
20
26
|
export interface WithInputAttributesProps {
|
|
21
27
|
inputAttributes: ReturnType<typeof useInputAttributes>;
|
|
22
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contexts.d.ts","sourceRoot":"","sources":["../../../src/inputs/contexts.tsx"],"names":[],"mappings":"AAEA,KAAK,qBAAqB,GAAG;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;CACzC,CAAC;AAGF,eAAO,MAAM,yBAAyB,6DAA6B,CAAC;AAGpE,eAAO,MAAM,sBAAsB,8CAA0B,CAAC;AAG9D,eAAO,MAAM,wBAAwB,8CAAmC,CAAC;AAGzE,eAAO,MAAM,oBAAoB,+CAA+B,CAAC;AAEjE,UAAU,sBAAsB;IAC9B,gLAAgL;IAChL,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,GAAE,sBAA2B;;;;;EAQ/E;AAED,wBAAgB,gBAAgB,4DAE/B;AAED,MAAM,WAAW,wBAAwB;IACvC,eAAe,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;CACxD;AAED,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,OAAO,CAAC,wBAAwB,CAAC,EAC7E,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EACjC,IAAI,CAAC,EAAE,sBAAsB;YAEgB,IAAI,CAAC,CAAC,EAAE,MAAM,wBAAwB,CAAC;;EAOrF"}
|
|
1
|
+
{"version":3,"file":"contexts.d.ts","sourceRoot":"","sources":["../../../src/inputs/contexts.tsx"],"names":[],"mappings":"AAEA,KAAK,qBAAqB,GAAG;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;CACzC,CAAC;AAGF,eAAO,MAAM,yBAAyB,6DAA6B,CAAC;AAGpE,eAAO,MAAM,sBAAsB,8CAA0B,CAAC;AAG9D,eAAO,MAAM,wBAAwB,8CAAmC,CAAC;AAGzE,eAAO,MAAM,oBAAoB,+CAA+B,CAAC;AAEjE,UAAU,sBAAsB;IAC9B,gLAAgL;IAChL,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,GAAE,sBAA2B;;;;;EAQ/E;AAED,wBAAgB,gBAAgB,4DAE/B;AAED,MAAM,MAAM,2BAA2B,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC;AAKlF,eAAO,MAAM,8BAA8B,oCAFhC,2BAA2B,KAAK,IAAI,cAEqC,CAAC;AAErF,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,QAQjF;AAED,MAAM,WAAW,wBAAwB;IACvC,eAAe,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;CACxD;AAED,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,OAAO,CAAC,wBAAwB,CAAC,EAC7E,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EACjC,IAAI,CAAC,EAAE,sBAAsB;YAEgB,IAAI,CAAC,CAAC,EAAE,MAAM,wBAAwB,CAAC;;EAOrF"}
|
|
@@ -30,6 +30,7 @@ declare function customRender(ui: ReactElement, { locale, messages, ...renderOpt
|
|
|
30
30
|
"neptune.Expander.expandAriaLabel": string;
|
|
31
31
|
"neptune.ExpressiveMoneyInput.currency.search.placeholder": string;
|
|
32
32
|
"neptune.ExpressiveMoneyInput.currency.select.currency": string;
|
|
33
|
+
"neptune.Field.characterCount": string;
|
|
33
34
|
"neptune.FlowNavigation.back": string;
|
|
34
35
|
"neptune.Info.ariaLabel": string;
|
|
35
36
|
"neptune.Label.optional": string;
|
|
@@ -117,6 +118,7 @@ declare function customRenderHook(callback: () => unknown, { locale, messages }?
|
|
|
117
118
|
"neptune.Expander.expandAriaLabel": string;
|
|
118
119
|
"neptune.ExpressiveMoneyInput.currency.search.placeholder": string;
|
|
119
120
|
"neptune.ExpressiveMoneyInput.currency.select.currency": string;
|
|
121
|
+
"neptune.Field.characterCount": string;
|
|
120
122
|
"neptune.FlowNavigation.back": string;
|
|
121
123
|
"neptune.Info.ariaLabel": string;
|
|
122
124
|
"neptune.Label.optional": string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/test-utils/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAM,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,MAAM,EAAc,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAMxD;;;;GAIG;AACH,iBAAS,YAAY,CACnB,EAAE,EAAE,YAAY,EAChB,EAAE,MAAuB,EAAE,QAAa,EAAE,GAAG,aAAa,EAAE
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/test-utils/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAM,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,MAAM,EAAc,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAMxD;;;;GAIG;AACH,iBAAS,YAAY,CACnB,EAAE,EAAE,YAAY,EAChB,EAAE,MAAuB,EAAE,QAAa,EAAE,GAAG,aAAa,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAK,GAChE,UAAU,CAAC,OAAO,MAAM,CAAC,CAK3B;AAED;;;GAGG;AACH,iBAAS,gBAAgB,CACvB,QAAQ,EAAE,MAAM,OAAO,EACvB,EAAE,MAAuB,EAAE,QAAa,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAK,uEAKhD;AAED,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,YAAY,IAAI,MAAM,EAAE,gBAAgB,IAAI,UAAU,EAAE,SAAS,EAAE,CAAC"}
|
package/package.json
CHANGED
package/src/field/Field.css
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
.np-field-control,
|
|
2
|
-
.np-
|
|
2
|
+
.np-field-footer {
|
|
3
|
+
display: flex;
|
|
4
|
+
align-items: flex-start;
|
|
3
5
|
margin-top: 4px;
|
|
4
6
|
margin-top: var(--size-4);
|
|
7
|
+
gap: 8px;
|
|
8
|
+
gap: var(--size-8);
|
|
9
|
+
}
|
|
10
|
+
.np-field-counter {
|
|
11
|
+
margin-left: auto;
|
|
12
|
+
white-space: nowrap;
|
|
13
|
+
padding: 4px 0;
|
|
14
|
+
padding: var(--size-4) 0;
|
|
15
|
+
color: #768e9c;
|
|
16
|
+
color: var(--color-content-tertiary);
|
|
5
17
|
}
|
|
6
18
|
.np-field .form-group--typeahead[class],
|
|
7
19
|
.np-field .np-checkbox-label[class] {
|
package/src/field/Field.less
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
.np-field {
|
|
2
2
|
&-control,
|
|
3
|
-
|
|
3
|
+
&-footer {
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: flex-start;
|
|
4
6
|
margin-top: var(--size-4);
|
|
7
|
+
gap: var(--size-8);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
&-counter {
|
|
11
|
+
margin-left: auto;
|
|
12
|
+
white-space: nowrap;
|
|
13
|
+
padding: var(--size-4) 0;
|
|
14
|
+
color: var(--color-content-tertiary);
|
|
5
15
|
}
|
|
6
16
|
|
|
7
17
|
// @FIXME space between individual fields should be 24px, while some older inputs
|
|
@@ -84,7 +84,11 @@ export const Basic = (args: FieldProps) => {
|
|
|
84
84
|
messageIconLabel={args.messageIconLabel}
|
|
85
85
|
messageLoading={args.messageLoading}
|
|
86
86
|
>
|
|
87
|
-
<TextArea
|
|
87
|
+
<TextArea
|
|
88
|
+
maxLength={200}
|
|
89
|
+
value={value}
|
|
90
|
+
onChange={({ target }) => setValue(target.value)}
|
|
91
|
+
/>
|
|
88
92
|
</Field>
|
|
89
93
|
|
|
90
94
|
<Field
|
package/src/field/Field.tsx
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
|
-
import { useId, useRef } from 'react';
|
|
2
|
+
import { useCallback, useId, useRef, useState } from 'react';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
3
4
|
|
|
5
|
+
import Body from '../body';
|
|
4
6
|
import { Sentiment } from '../common';
|
|
7
|
+
import messages from './Field.messages';
|
|
5
8
|
import { InlinePrompt, type InlinePromptProps } from '../prompt';
|
|
6
9
|
import {
|
|
10
|
+
TextareaCharacterCountProvider,
|
|
11
|
+
type TextareaCharacterCountState,
|
|
7
12
|
FieldLabelContextProvider,
|
|
8
13
|
InputDescribedByProvider,
|
|
9
14
|
InputIdContextProvider,
|
|
@@ -54,6 +59,7 @@ export const Field = ({
|
|
|
54
59
|
children,
|
|
55
60
|
...props
|
|
56
61
|
}: FieldProps) => {
|
|
62
|
+
const { formatMessage } = useIntl();
|
|
57
63
|
const labelRef = useRef<HTMLLabelElement>(null);
|
|
58
64
|
const sentiment = props.error ? Sentiment.NEGATIVE : propType;
|
|
59
65
|
const message = propMessage || props.error;
|
|
@@ -66,6 +72,14 @@ export const Field = ({
|
|
|
66
72
|
|
|
67
73
|
const messageId = useId();
|
|
68
74
|
const descriptionId = useId();
|
|
75
|
+
const counterId = useId();
|
|
76
|
+
|
|
77
|
+
const [textareaCharacterCount, setTextareaCharacterCount] =
|
|
78
|
+
useState<TextareaCharacterCountState>(null);
|
|
79
|
+
const handleTextareaCharacterCount = useCallback(
|
|
80
|
+
(state: TextareaCharacterCountState) => setTextareaCharacterCount(state),
|
|
81
|
+
[],
|
|
82
|
+
);
|
|
69
83
|
|
|
70
84
|
/**
|
|
71
85
|
* form control can have multiple messages to describe it,
|
|
@@ -79,6 +93,9 @@ export const Field = ({
|
|
|
79
93
|
if (message) {
|
|
80
94
|
messageIds.push(messageId);
|
|
81
95
|
}
|
|
96
|
+
if (textareaCharacterCount) {
|
|
97
|
+
messageIds.push(counterId);
|
|
98
|
+
}
|
|
82
99
|
return messageIds.length > 0 ? messageIds.join(' ') : undefined;
|
|
83
100
|
}
|
|
84
101
|
|
|
@@ -87,43 +104,69 @@ export const Field = ({
|
|
|
87
104
|
<InputIdContextProvider value={inputId}>
|
|
88
105
|
<InputDescribedByProvider value={ariaDescribedbyByIds()}>
|
|
89
106
|
<InputInvalidProvider value={hasError}>
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
{
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
<TextareaCharacterCountProvider value={handleTextareaCharacterCount}>
|
|
108
|
+
<div
|
|
109
|
+
className={clsx(
|
|
110
|
+
'np-field form-group d-block',
|
|
111
|
+
{
|
|
112
|
+
'has-success': sentiment === Sentiment.POSITIVE,
|
|
113
|
+
'has-warning': sentiment === Sentiment.WARNING,
|
|
114
|
+
'has-error': hasError,
|
|
115
|
+
'has-info': sentiment === Sentiment.NEUTRAL,
|
|
116
|
+
},
|
|
117
|
+
className,
|
|
118
|
+
)}
|
|
119
|
+
>
|
|
120
|
+
{label != null ? (
|
|
121
|
+
<>
|
|
122
|
+
<Label ref={labelRef} id={labelId} htmlFor={inputId}>
|
|
123
|
+
{required ? label : <Label.Optional>{label}</Label.Optional>}
|
|
124
|
+
</Label>
|
|
125
|
+
<Label.Description id={descriptionId}>{description}</Label.Description>
|
|
126
|
+
<div className="np-field-control">{children}</div>
|
|
127
|
+
</>
|
|
128
|
+
) : (
|
|
129
|
+
children
|
|
130
|
+
)}
|
|
113
131
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
132
|
+
{(message || textareaCharacterCount) && (
|
|
133
|
+
<div className="np-field-footer">
|
|
134
|
+
{message && (
|
|
135
|
+
<InlinePrompt
|
|
136
|
+
sentiment={sentiment}
|
|
137
|
+
id={messageId}
|
|
138
|
+
mediaLabel={messageIconLabel}
|
|
139
|
+
className="np-field__prompt"
|
|
140
|
+
loading={messageLoading}
|
|
141
|
+
width="full"
|
|
142
|
+
>
|
|
143
|
+
{message}
|
|
144
|
+
</InlinePrompt>
|
|
145
|
+
)}
|
|
146
|
+
{textareaCharacterCount && (
|
|
147
|
+
<Body
|
|
148
|
+
as="span"
|
|
149
|
+
id={counterId}
|
|
150
|
+
role="status"
|
|
151
|
+
aria-live={
|
|
152
|
+
textareaCharacterCount.current >= textareaCharacterCount.max * 0.8
|
|
153
|
+
? 'polite'
|
|
154
|
+
: 'off'
|
|
155
|
+
}
|
|
156
|
+
aria-atomic="true"
|
|
157
|
+
aria-label={formatMessage(messages.characterCount, {
|
|
158
|
+
current: textareaCharacterCount.current,
|
|
159
|
+
max: textareaCharacterCount.max,
|
|
160
|
+
})}
|
|
161
|
+
className="np-field-counter"
|
|
162
|
+
>
|
|
163
|
+
{textareaCharacterCount.current}/{textareaCharacterCount.max}
|
|
164
|
+
</Body>
|
|
165
|
+
)}
|
|
166
|
+
</div>
|
|
167
|
+
)}
|
|
168
|
+
</div>
|
|
169
|
+
</TextareaCharacterCountProvider>
|
|
127
170
|
</InputInvalidProvider>
|
|
128
171
|
</InputDescribedByProvider>
|
|
129
172
|
</InputIdContextProvider>
|
|
@@ -86,10 +86,10 @@ describe('FlowNavigation', () => {
|
|
|
86
86
|
expect(container.querySelector('.np-flow-navigation__stepper')).not.toBeInTheDocument();
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
-
it(`
|
|
89
|
+
it(`renders stepper placeholder when steps is empty`, () => {
|
|
90
90
|
const { container } = render(<FlowNavigation {...props} steps={[]} />);
|
|
91
91
|
|
|
92
|
-
expect(container.querySelector('.np-flow-navigation__stepper')).
|
|
92
|
+
expect(container.querySelector('.np-flow-navigation__stepper')).toBeInTheDocument();
|
|
93
93
|
expect(container.querySelector('.tw-stepper')).not.toBeInTheDocument();
|
|
94
94
|
});
|
|
95
95
|
|
|
@@ -95,13 +95,16 @@ const FlowNavigation = ({
|
|
|
95
95
|
</div>
|
|
96
96
|
}
|
|
97
97
|
bottomContent={
|
|
98
|
-
!done &&
|
|
98
|
+
!done &&
|
|
99
|
+
(steps.length > 0 ? (
|
|
99
100
|
<Stepper
|
|
100
101
|
activeStep={activeStep}
|
|
101
102
|
steps={steps}
|
|
102
103
|
className={clsx('np-flow-navigation__stepper')}
|
|
103
104
|
/>
|
|
104
|
-
) :
|
|
105
|
+
) : (
|
|
106
|
+
<div className="np-flow-navigation__stepper" />
|
|
107
|
+
))
|
|
105
108
|
}
|
|
106
109
|
layout={!screenLg ? Layout.VERTICAL : Layout.HORIZONTAL}
|
|
107
110
|
/>
|
package/src/i18n/en.json
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"neptune.Expander.expandAriaLabel": "Expand",
|
|
21
21
|
"neptune.ExpressiveMoneyInput.currency.search.placeholder": "Type a currency / country",
|
|
22
22
|
"neptune.ExpressiveMoneyInput.currency.select.currency": "Select currency",
|
|
23
|
+
"neptune.Field.characterCount": "{current} of {max} characters used",
|
|
23
24
|
"neptune.FlowNavigation.back": "back to previous step",
|
|
24
25
|
"neptune.Info.ariaLabel": "More information",
|
|
25
26
|
"neptune.Label.optional": "(Optional)",
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
3
|
+
|
|
4
|
+
import { Field } from '../field/Field';
|
|
5
|
+
import { Sentiment } from '../common';
|
|
6
|
+
import { TextArea } from './TextArea';
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof TextArea> = {
|
|
9
|
+
title: 'Forms/TextArea',
|
|
10
|
+
component: TextArea,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
type Story = StoryObj<typeof TextArea>;
|
|
15
|
+
|
|
16
|
+
export const Basic: Story = {
|
|
17
|
+
render: () => {
|
|
18
|
+
const [value, setValue] = useState('');
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Field label="Message" required={false}>
|
|
22
|
+
<TextArea maxLength={200} value={value} onChange={({ target }) => setValue(target.value)} />
|
|
23
|
+
</Field>
|
|
24
|
+
);
|
|
25
|
+
},
|
|
26
|
+
parameters: {
|
|
27
|
+
docs: {
|
|
28
|
+
source: {
|
|
29
|
+
code: `<Field label="Message" required={false}>
|
|
30
|
+
<TextArea
|
|
31
|
+
maxLength={200}
|
|
32
|
+
value={value}
|
|
33
|
+
onChange={({ target }) => setValue(target.value)}
|
|
34
|
+
/>
|
|
35
|
+
</Field>`,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const WithError: Story = {
|
|
42
|
+
render: () => {
|
|
43
|
+
const [value, setValue] = useState('');
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<Field
|
|
47
|
+
label="Message"
|
|
48
|
+
required={false}
|
|
49
|
+
sentiment={Sentiment.NEGATIVE}
|
|
50
|
+
message="You have exceeded the character limit"
|
|
51
|
+
>
|
|
52
|
+
<TextArea maxLength={200} value={value} onChange={({ target }) => setValue(target.value)} />
|
|
53
|
+
</Field>
|
|
54
|
+
);
|
|
55
|
+
},
|
|
56
|
+
};
|