@transferwise/components 46.46.0 → 46.47.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/inputs/InputGroup.js +42 -46
- package/build/inputs/InputGroup.js.map +1 -1
- package/build/inputs/InputGroup.mjs +43 -47
- package/build/inputs/InputGroup.mjs.map +1 -1
- package/build/types/inputs/InputGroup.d.ts.map +1 -1
- package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
- package/build/uploadInput/UploadInput.js +6 -0
- package/build/uploadInput/UploadInput.js.map +1 -1
- package/build/uploadInput/UploadInput.mjs +6 -0
- package/build/uploadInput/UploadInput.mjs.map +1 -1
- package/package.json +1 -1
- package/src/inputs/InputGroup.spec.tsx +6 -1
- package/src/inputs/InputGroup.tsx +39 -45
- package/src/inputs/SearchInput.spec.tsx +1 -1
- package/src/inputs/SelectInput.spec.tsx +1 -1
- package/src/uploadInput/UploadInput.spec.tsx +14 -1
- package/src/uploadInput/UploadInput.story.tsx +11 -0
- package/src/uploadInput/UploadInput.tsx +8 -1
|
@@ -34,45 +34,25 @@ function InputGroup({
|
|
|
34
34
|
className,
|
|
35
35
|
children
|
|
36
36
|
}) {
|
|
37
|
-
const inputAttributes = contexts.useInputAttributes({
|
|
38
|
-
nonLabelable: true
|
|
39
|
-
});
|
|
40
37
|
const [paddingStart, setPaddingStart] = React.useState(inputPaddingInitialState(addonStart));
|
|
41
38
|
const [paddingEnd, setPaddingEnd] = React.useState(inputPaddingInitialState(addonEnd));
|
|
42
|
-
return (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
children: /*#__PURE__*/jsxRuntime.jsx(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
value: React.useMemo(() => [paddingEnd, setPaddingEnd], [paddingEnd]),
|
|
57
|
-
children: /*#__PURE__*/jsxRuntime.jsxs("fieldset", {
|
|
58
|
-
...inputAttributes,
|
|
59
|
-
disabled: disabled,
|
|
60
|
-
className: classNames__default.default(className, 'np-input-group'),
|
|
61
|
-
children: [addonStart != null ? /*#__PURE__*/jsxRuntime.jsx(InputAddon, {
|
|
62
|
-
placement: "start",
|
|
63
|
-
...addonStart
|
|
64
|
-
}) : null, children, addonEnd != null ? /*#__PURE__*/jsxRuntime.jsx(InputAddon, {
|
|
65
|
-
placement: "end",
|
|
66
|
-
...addonEnd
|
|
67
|
-
}) : null]
|
|
68
|
-
})
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
})
|
|
72
|
-
})
|
|
39
|
+
return /*#__PURE__*/jsxRuntime.jsx(InputPaddingStartContext.Provider, {
|
|
40
|
+
value: React.useMemo(() => [paddingStart, setPaddingStart], [paddingStart]),
|
|
41
|
+
children: /*#__PURE__*/jsxRuntime.jsx(InputPaddingEndContext.Provider, {
|
|
42
|
+
value: React.useMemo(() => [paddingEnd, setPaddingEnd], [paddingEnd]),
|
|
43
|
+
children: /*#__PURE__*/jsxRuntime.jsxs("fieldset", {
|
|
44
|
+
disabled: disabled,
|
|
45
|
+
className: classNames__default.default(className, 'np-input-group'),
|
|
46
|
+
children: [addonStart != null ? /*#__PURE__*/jsxRuntime.jsx(InputAddon, {
|
|
47
|
+
placement: "start",
|
|
48
|
+
...addonStart
|
|
49
|
+
}) : null, children, addonEnd != null ? /*#__PURE__*/jsxRuntime.jsx(InputAddon, {
|
|
50
|
+
placement: "end",
|
|
51
|
+
...addonEnd
|
|
52
|
+
}) : null]
|
|
73
53
|
})
|
|
74
54
|
})
|
|
75
|
-
);
|
|
55
|
+
});
|
|
76
56
|
}
|
|
77
57
|
const inputAddonContentWidthAddendByPadding = {
|
|
78
58
|
none: 0,
|
|
@@ -98,17 +78,33 @@ function InputAddon({
|
|
|
98
78
|
setInputPadding(entry.contentRect.width + Number.parseFloat(targetStyle.paddingInlineStart) + Number.parseFloat(targetStyle.paddingInlineEnd));
|
|
99
79
|
}
|
|
100
80
|
});
|
|
101
|
-
return
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
81
|
+
return (
|
|
82
|
+
/*#__PURE__*/
|
|
83
|
+
/* Prevent nested controls from being labeled redundantly */
|
|
84
|
+
jsxRuntime.jsx(contexts.FieldLabelIdContextProvider, {
|
|
85
|
+
value: undefined,
|
|
86
|
+
children: /*#__PURE__*/jsxRuntime.jsx(contexts.InputIdContextProvider, {
|
|
87
|
+
value: undefined,
|
|
88
|
+
children: /*#__PURE__*/jsxRuntime.jsx(contexts.InputDescribedByProvider, {
|
|
89
|
+
value: undefined,
|
|
90
|
+
children: /*#__PURE__*/jsxRuntime.jsx(contexts.InputInvalidProvider, {
|
|
91
|
+
value: undefined,
|
|
92
|
+
children: /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
93
|
+
ref: ref,
|
|
94
|
+
className: classNames__default.default('np-input-addon', {
|
|
95
|
+
'np-input-addon--placement-start': placement === 'start',
|
|
96
|
+
'np-input-addon--placement-end': placement === 'end'
|
|
97
|
+
}, interactive && 'np-input-addon--interactive', {
|
|
98
|
+
'np-input-addon--padding-sm': padding === 'sm',
|
|
99
|
+
'np-input-addon--padding-md': padding === 'md'
|
|
100
|
+
}),
|
|
101
|
+
children: content
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
);
|
|
112
108
|
}
|
|
113
109
|
|
|
114
110
|
exports.InputGroup = InputGroup;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputGroup.js","sources":["../../src/inputs/InputGroup.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { createContext, useContext, useMemo, useRef, useState } from 'react';\n\nimport { useResizeObserver } from '../common/hooks/useResizeObserver';\nimport { cssValueWithUnit } from '../utilities/cssValueWithUnit';\nimport {\n FieldLabelIdContextProvider,\n InputDescribedByProvider,\n InputIdContextProvider,\n InputInvalidProvider,\n useInputAttributes,\n} from './contexts';\n\ntype InputPaddingContextType = [\n number | string | undefined,\n React.Dispatch<React.SetStateAction<number | string | undefined>>,\n];\n\nconst InputPaddingStartContext = createContext<InputPaddingContextType>([undefined, () => {}]);\n\nconst InputPaddingEndContext = createContext<InputPaddingContextType>([undefined, () => {}]);\n\nexport function useInputPaddings() {\n const [paddingStart] = useContext(InputPaddingStartContext);\n const [paddingEnd] = useContext(InputPaddingEndContext);\n\n return {\n paddingInlineStart: paddingStart,\n paddingInlineEnd: paddingEnd,\n } satisfies React.CSSProperties;\n}\n\ninterface InputGroupAddon {\n content: React.ReactNode;\n initialContentWidth?: number | string;\n interactive?: boolean;\n padding?: 'none' | 'sm' | 'md';\n}\n\nexport interface InputGroupProps {\n addonStart?: InputGroupAddon;\n addonEnd?: InputGroupAddon;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nfunction inputPaddingInitialState({\n initialContentWidth,\n padding = inputAddonDefaultPadding,\n}: Pick<\n InputGroupAddon,\n 'initialContentWidth' | 'padding'\n> = {}): () => InputPaddingContextType[0] {\n return () =>\n initialContentWidth != null\n ? `calc(${cssValueWithUnit(initialContentWidth)} + ${cssValueWithUnit(\n inputAddonContentWidthAddendByPadding[padding],\n )})`\n : undefined;\n}\n\nexport function InputGroup({\n addonStart,\n addonEnd,\n disabled,\n className,\n children,\n}: InputGroupProps) {\n const
|
|
1
|
+
{"version":3,"file":"InputGroup.js","sources":["../../src/inputs/InputGroup.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { createContext, useContext, useMemo, useRef, useState } from 'react';\n\nimport { useResizeObserver } from '../common/hooks/useResizeObserver';\nimport { cssValueWithUnit } from '../utilities/cssValueWithUnit';\nimport {\n FieldLabelIdContextProvider,\n InputDescribedByProvider,\n InputIdContextProvider,\n InputInvalidProvider,\n useInputAttributes,\n} from './contexts';\n\ntype InputPaddingContextType = [\n number | string | undefined,\n React.Dispatch<React.SetStateAction<number | string | undefined>>,\n];\n\nconst InputPaddingStartContext = createContext<InputPaddingContextType>([undefined, () => {}]);\n\nconst InputPaddingEndContext = createContext<InputPaddingContextType>([undefined, () => {}]);\n\nexport function useInputPaddings() {\n const [paddingStart] = useContext(InputPaddingStartContext);\n const [paddingEnd] = useContext(InputPaddingEndContext);\n\n return {\n paddingInlineStart: paddingStart,\n paddingInlineEnd: paddingEnd,\n } satisfies React.CSSProperties;\n}\n\ninterface InputGroupAddon {\n content: React.ReactNode;\n initialContentWidth?: number | string;\n interactive?: boolean;\n padding?: 'none' | 'sm' | 'md';\n}\n\nexport interface InputGroupProps {\n addonStart?: InputGroupAddon;\n addonEnd?: InputGroupAddon;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nfunction inputPaddingInitialState({\n initialContentWidth,\n padding = inputAddonDefaultPadding,\n}: Pick<\n InputGroupAddon,\n 'initialContentWidth' | 'padding'\n> = {}): () => InputPaddingContextType[0] {\n return () =>\n initialContentWidth != null\n ? `calc(${cssValueWithUnit(initialContentWidth)} + ${cssValueWithUnit(\n inputAddonContentWidthAddendByPadding[padding],\n )})`\n : undefined;\n}\n\nexport function InputGroup({\n addonStart,\n addonEnd,\n disabled,\n className,\n children,\n}: InputGroupProps) {\n const [paddingStart, setPaddingStart] = useState(inputPaddingInitialState(addonStart));\n const [paddingEnd, setPaddingEnd] = useState(inputPaddingInitialState(addonEnd));\n\n return (\n <InputPaddingStartContext.Provider\n value={useMemo(() => [paddingStart, setPaddingStart], [paddingStart])}\n >\n <InputPaddingEndContext.Provider\n value={useMemo(() => [paddingEnd, setPaddingEnd], [paddingEnd])}\n >\n <fieldset disabled={disabled} className={classNames(className, 'np-input-group')}>\n {addonStart != null ? <InputAddon placement=\"start\" {...addonStart} /> : null}\n {children}\n {addonEnd != null ? <InputAddon placement=\"end\" {...addonEnd} /> : null}\n </fieldset>\n </InputPaddingEndContext.Provider>\n </InputPaddingStartContext.Provider>\n );\n}\n\ninterface InputAddonProps extends Omit<InputGroupAddon, 'initialContentWidth'> {\n placement: 'start' | 'end';\n}\n\nconst inputAddonContentWidthAddendByPadding = {\n none: 0,\n sm: '1rem',\n md: '1.5rem',\n} satisfies {\n [key in NonNullable<InputAddonProps['padding']>]: InputPaddingContextType[0];\n};\n\nconst inputAddonDefaultPadding = 'md' satisfies InputAddonProps['padding'];\n\nfunction InputAddon({\n placement,\n content,\n interactive,\n padding = inputAddonDefaultPadding,\n}: InputAddonProps) {\n const [, setInputPadding] = useContext(\n placement === 'start' ? InputPaddingStartContext : InputPaddingEndContext,\n );\n\n const ref = useRef<HTMLSpanElement>(null);\n useResizeObserver(ref, (entry) => {\n // TODO: Remove fallback once most browsers support `borderBoxSize`\n const inlineSize = entry.borderBoxSize?.[0]?.inlineSize;\n if (inlineSize != null) {\n setInputPadding(inlineSize);\n } else {\n const targetStyle = getComputedStyle(entry.target);\n setInputPadding(\n entry.contentRect.width +\n Number.parseFloat(targetStyle.paddingInlineStart) +\n Number.parseFloat(targetStyle.paddingInlineEnd),\n );\n }\n });\n\n return (\n /* Prevent nested controls from being labeled redundantly */\n <FieldLabelIdContextProvider value={undefined}>\n <InputIdContextProvider value={undefined}>\n <InputDescribedByProvider value={undefined}>\n <InputInvalidProvider value={undefined}>\n <span\n ref={ref}\n className={classNames(\n 'np-input-addon',\n {\n 'np-input-addon--placement-start': placement === 'start',\n 'np-input-addon--placement-end': placement === 'end',\n },\n interactive && 'np-input-addon--interactive',\n {\n 'np-input-addon--padding-sm': padding === 'sm',\n 'np-input-addon--padding-md': padding === 'md',\n },\n )}\n >\n {content}\n </span>\n </InputInvalidProvider>\n </InputDescribedByProvider>\n </InputIdContextProvider>\n </FieldLabelIdContextProvider>\n );\n}\n"],"names":["InputPaddingStartContext","createContext","undefined","InputPaddingEndContext","useInputPaddings","paddingStart","useContext","paddingEnd","paddingInlineStart","paddingInlineEnd","inputPaddingInitialState","initialContentWidth","padding","inputAddonDefaultPadding","cssValueWithUnit","inputAddonContentWidthAddendByPadding","InputGroup","addonStart","addonEnd","disabled","className","children","setPaddingStart","useState","setPaddingEnd","_jsx","Provider","value","useMemo","_jsxs","classNames","InputAddon","placement","none","sm","md","content","interactive","setInputPadding","ref","useRef","useResizeObserver","entry","inlineSize","borderBoxSize","targetStyle","getComputedStyle","target","contentRect","width","Number","parseFloat","FieldLabelIdContextProvider","InputIdContextProvider","InputDescribedByProvider","InputInvalidProvider"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import classNames from 'classnames';
|
|
|
2
2
|
import { useState, useMemo, useContext, useRef, createContext } from 'react';
|
|
3
3
|
import { useResizeObserver } from '../common/hooks/useResizeObserver.mjs';
|
|
4
4
|
import { cssValueWithUnit } from '../utilities/cssValueWithUnit.mjs';
|
|
5
|
-
import {
|
|
5
|
+
import { FieldLabelIdContextProvider, InputIdContextProvider, InputDescribedByProvider, InputInvalidProvider } from './contexts.mjs';
|
|
6
6
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
7
|
|
|
8
8
|
const InputPaddingStartContext = /*#__PURE__*/createContext([undefined, () => {}]);
|
|
@@ -28,45 +28,25 @@ function InputGroup({
|
|
|
28
28
|
className,
|
|
29
29
|
children
|
|
30
30
|
}) {
|
|
31
|
-
const inputAttributes = useInputAttributes({
|
|
32
|
-
nonLabelable: true
|
|
33
|
-
});
|
|
34
31
|
const [paddingStart, setPaddingStart] = useState(inputPaddingInitialState(addonStart));
|
|
35
32
|
const [paddingEnd, setPaddingEnd] = useState(inputPaddingInitialState(addonEnd));
|
|
36
|
-
return (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
children: /*#__PURE__*/jsx(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
value: useMemo(() => [paddingEnd, setPaddingEnd], [paddingEnd]),
|
|
51
|
-
children: /*#__PURE__*/jsxs("fieldset", {
|
|
52
|
-
...inputAttributes,
|
|
53
|
-
disabled: disabled,
|
|
54
|
-
className: classNames(className, 'np-input-group'),
|
|
55
|
-
children: [addonStart != null ? /*#__PURE__*/jsx(InputAddon, {
|
|
56
|
-
placement: "start",
|
|
57
|
-
...addonStart
|
|
58
|
-
}) : null, children, addonEnd != null ? /*#__PURE__*/jsx(InputAddon, {
|
|
59
|
-
placement: "end",
|
|
60
|
-
...addonEnd
|
|
61
|
-
}) : null]
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
})
|
|
65
|
-
})
|
|
66
|
-
})
|
|
33
|
+
return /*#__PURE__*/jsx(InputPaddingStartContext.Provider, {
|
|
34
|
+
value: useMemo(() => [paddingStart, setPaddingStart], [paddingStart]),
|
|
35
|
+
children: /*#__PURE__*/jsx(InputPaddingEndContext.Provider, {
|
|
36
|
+
value: useMemo(() => [paddingEnd, setPaddingEnd], [paddingEnd]),
|
|
37
|
+
children: /*#__PURE__*/jsxs("fieldset", {
|
|
38
|
+
disabled: disabled,
|
|
39
|
+
className: classNames(className, 'np-input-group'),
|
|
40
|
+
children: [addonStart != null ? /*#__PURE__*/jsx(InputAddon, {
|
|
41
|
+
placement: "start",
|
|
42
|
+
...addonStart
|
|
43
|
+
}) : null, children, addonEnd != null ? /*#__PURE__*/jsx(InputAddon, {
|
|
44
|
+
placement: "end",
|
|
45
|
+
...addonEnd
|
|
46
|
+
}) : null]
|
|
67
47
|
})
|
|
68
48
|
})
|
|
69
|
-
);
|
|
49
|
+
});
|
|
70
50
|
}
|
|
71
51
|
const inputAddonContentWidthAddendByPadding = {
|
|
72
52
|
none: 0,
|
|
@@ -92,17 +72,33 @@ function InputAddon({
|
|
|
92
72
|
setInputPadding(entry.contentRect.width + Number.parseFloat(targetStyle.paddingInlineStart) + Number.parseFloat(targetStyle.paddingInlineEnd));
|
|
93
73
|
}
|
|
94
74
|
});
|
|
95
|
-
return
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
75
|
+
return (
|
|
76
|
+
/*#__PURE__*/
|
|
77
|
+
/* Prevent nested controls from being labeled redundantly */
|
|
78
|
+
jsx(FieldLabelIdContextProvider, {
|
|
79
|
+
value: undefined,
|
|
80
|
+
children: /*#__PURE__*/jsx(InputIdContextProvider, {
|
|
81
|
+
value: undefined,
|
|
82
|
+
children: /*#__PURE__*/jsx(InputDescribedByProvider, {
|
|
83
|
+
value: undefined,
|
|
84
|
+
children: /*#__PURE__*/jsx(InputInvalidProvider, {
|
|
85
|
+
value: undefined,
|
|
86
|
+
children: /*#__PURE__*/jsx("span", {
|
|
87
|
+
ref: ref,
|
|
88
|
+
className: classNames('np-input-addon', {
|
|
89
|
+
'np-input-addon--placement-start': placement === 'start',
|
|
90
|
+
'np-input-addon--placement-end': placement === 'end'
|
|
91
|
+
}, interactive && 'np-input-addon--interactive', {
|
|
92
|
+
'np-input-addon--padding-sm': padding === 'sm',
|
|
93
|
+
'np-input-addon--padding-md': padding === 'md'
|
|
94
|
+
}),
|
|
95
|
+
children: content
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
})
|
|
101
|
+
);
|
|
106
102
|
}
|
|
107
103
|
|
|
108
104
|
export { InputGroup, useInputPaddings };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputGroup.mjs","sources":["../../src/inputs/InputGroup.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { createContext, useContext, useMemo, useRef, useState } from 'react';\n\nimport { useResizeObserver } from '../common/hooks/useResizeObserver';\nimport { cssValueWithUnit } from '../utilities/cssValueWithUnit';\nimport {\n FieldLabelIdContextProvider,\n InputDescribedByProvider,\n InputIdContextProvider,\n InputInvalidProvider,\n useInputAttributes,\n} from './contexts';\n\ntype InputPaddingContextType = [\n number | string | undefined,\n React.Dispatch<React.SetStateAction<number | string | undefined>>,\n];\n\nconst InputPaddingStartContext = createContext<InputPaddingContextType>([undefined, () => {}]);\n\nconst InputPaddingEndContext = createContext<InputPaddingContextType>([undefined, () => {}]);\n\nexport function useInputPaddings() {\n const [paddingStart] = useContext(InputPaddingStartContext);\n const [paddingEnd] = useContext(InputPaddingEndContext);\n\n return {\n paddingInlineStart: paddingStart,\n paddingInlineEnd: paddingEnd,\n } satisfies React.CSSProperties;\n}\n\ninterface InputGroupAddon {\n content: React.ReactNode;\n initialContentWidth?: number | string;\n interactive?: boolean;\n padding?: 'none' | 'sm' | 'md';\n}\n\nexport interface InputGroupProps {\n addonStart?: InputGroupAddon;\n addonEnd?: InputGroupAddon;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nfunction inputPaddingInitialState({\n initialContentWidth,\n padding = inputAddonDefaultPadding,\n}: Pick<\n InputGroupAddon,\n 'initialContentWidth' | 'padding'\n> = {}): () => InputPaddingContextType[0] {\n return () =>\n initialContentWidth != null\n ? `calc(${cssValueWithUnit(initialContentWidth)} + ${cssValueWithUnit(\n inputAddonContentWidthAddendByPadding[padding],\n )})`\n : undefined;\n}\n\nexport function InputGroup({\n addonStart,\n addonEnd,\n disabled,\n className,\n children,\n}: InputGroupProps) {\n const
|
|
1
|
+
{"version":3,"file":"InputGroup.mjs","sources":["../../src/inputs/InputGroup.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { createContext, useContext, useMemo, useRef, useState } from 'react';\n\nimport { useResizeObserver } from '../common/hooks/useResizeObserver';\nimport { cssValueWithUnit } from '../utilities/cssValueWithUnit';\nimport {\n FieldLabelIdContextProvider,\n InputDescribedByProvider,\n InputIdContextProvider,\n InputInvalidProvider,\n useInputAttributes,\n} from './contexts';\n\ntype InputPaddingContextType = [\n number | string | undefined,\n React.Dispatch<React.SetStateAction<number | string | undefined>>,\n];\n\nconst InputPaddingStartContext = createContext<InputPaddingContextType>([undefined, () => {}]);\n\nconst InputPaddingEndContext = createContext<InputPaddingContextType>([undefined, () => {}]);\n\nexport function useInputPaddings() {\n const [paddingStart] = useContext(InputPaddingStartContext);\n const [paddingEnd] = useContext(InputPaddingEndContext);\n\n return {\n paddingInlineStart: paddingStart,\n paddingInlineEnd: paddingEnd,\n } satisfies React.CSSProperties;\n}\n\ninterface InputGroupAddon {\n content: React.ReactNode;\n initialContentWidth?: number | string;\n interactive?: boolean;\n padding?: 'none' | 'sm' | 'md';\n}\n\nexport interface InputGroupProps {\n addonStart?: InputGroupAddon;\n addonEnd?: InputGroupAddon;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nfunction inputPaddingInitialState({\n initialContentWidth,\n padding = inputAddonDefaultPadding,\n}: Pick<\n InputGroupAddon,\n 'initialContentWidth' | 'padding'\n> = {}): () => InputPaddingContextType[0] {\n return () =>\n initialContentWidth != null\n ? `calc(${cssValueWithUnit(initialContentWidth)} + ${cssValueWithUnit(\n inputAddonContentWidthAddendByPadding[padding],\n )})`\n : undefined;\n}\n\nexport function InputGroup({\n addonStart,\n addonEnd,\n disabled,\n className,\n children,\n}: InputGroupProps) {\n const [paddingStart, setPaddingStart] = useState(inputPaddingInitialState(addonStart));\n const [paddingEnd, setPaddingEnd] = useState(inputPaddingInitialState(addonEnd));\n\n return (\n <InputPaddingStartContext.Provider\n value={useMemo(() => [paddingStart, setPaddingStart], [paddingStart])}\n >\n <InputPaddingEndContext.Provider\n value={useMemo(() => [paddingEnd, setPaddingEnd], [paddingEnd])}\n >\n <fieldset disabled={disabled} className={classNames(className, 'np-input-group')}>\n {addonStart != null ? <InputAddon placement=\"start\" {...addonStart} /> : null}\n {children}\n {addonEnd != null ? <InputAddon placement=\"end\" {...addonEnd} /> : null}\n </fieldset>\n </InputPaddingEndContext.Provider>\n </InputPaddingStartContext.Provider>\n );\n}\n\ninterface InputAddonProps extends Omit<InputGroupAddon, 'initialContentWidth'> {\n placement: 'start' | 'end';\n}\n\nconst inputAddonContentWidthAddendByPadding = {\n none: 0,\n sm: '1rem',\n md: '1.5rem',\n} satisfies {\n [key in NonNullable<InputAddonProps['padding']>]: InputPaddingContextType[0];\n};\n\nconst inputAddonDefaultPadding = 'md' satisfies InputAddonProps['padding'];\n\nfunction InputAddon({\n placement,\n content,\n interactive,\n padding = inputAddonDefaultPadding,\n}: InputAddonProps) {\n const [, setInputPadding] = useContext(\n placement === 'start' ? InputPaddingStartContext : InputPaddingEndContext,\n );\n\n const ref = useRef<HTMLSpanElement>(null);\n useResizeObserver(ref, (entry) => {\n // TODO: Remove fallback once most browsers support `borderBoxSize`\n const inlineSize = entry.borderBoxSize?.[0]?.inlineSize;\n if (inlineSize != null) {\n setInputPadding(inlineSize);\n } else {\n const targetStyle = getComputedStyle(entry.target);\n setInputPadding(\n entry.contentRect.width +\n Number.parseFloat(targetStyle.paddingInlineStart) +\n Number.parseFloat(targetStyle.paddingInlineEnd),\n );\n }\n });\n\n return (\n /* Prevent nested controls from being labeled redundantly */\n <FieldLabelIdContextProvider value={undefined}>\n <InputIdContextProvider value={undefined}>\n <InputDescribedByProvider value={undefined}>\n <InputInvalidProvider value={undefined}>\n <span\n ref={ref}\n className={classNames(\n 'np-input-addon',\n {\n 'np-input-addon--placement-start': placement === 'start',\n 'np-input-addon--placement-end': placement === 'end',\n },\n interactive && 'np-input-addon--interactive',\n {\n 'np-input-addon--padding-sm': padding === 'sm',\n 'np-input-addon--padding-md': padding === 'md',\n },\n )}\n >\n {content}\n </span>\n </InputInvalidProvider>\n </InputDescribedByProvider>\n </InputIdContextProvider>\n </FieldLabelIdContextProvider>\n );\n}\n"],"names":["InputPaddingStartContext","createContext","undefined","InputPaddingEndContext","useInputPaddings","paddingStart","useContext","paddingEnd","paddingInlineStart","paddingInlineEnd","inputPaddingInitialState","initialContentWidth","padding","inputAddonDefaultPadding","cssValueWithUnit","inputAddonContentWidthAddendByPadding","InputGroup","addonStart","addonEnd","disabled","className","children","setPaddingStart","useState","setPaddingEnd","_jsx","Provider","value","useMemo","_jsxs","classNames","InputAddon","placement","none","sm","md","content","interactive","setInputPadding","ref","useRef","useResizeObserver","entry","inlineSize","borderBoxSize","targetStyle","getComputedStyle","target","contentRect","width","Number","parseFloat","FieldLabelIdContextProvider","InputIdContextProvider","InputDescribedByProvider","InputInvalidProvider"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputGroup.d.ts","sourceRoot":"","sources":["../../../src/inputs/InputGroup.tsx"],"names":[],"mappings":"AAsBA,wBAAgB,gBAAgB;;;EAQ/B;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAiBD,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE,eAAe,+
|
|
1
|
+
{"version":3,"file":"InputGroup.d.ts","sourceRoot":"","sources":["../../../src/inputs/InputGroup.tsx"],"names":[],"mappings":"AAsBA,wBAAgB,gBAAgB;;;EAQ/B;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAiBD,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE,eAAe,+BAmBjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadInput.d.ts","sourceRoot":"","sources":["../../../src/uploadInput/UploadInput.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAiC,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"UploadInput.d.ts","sourceRoot":"","sources":["../../../src/uploadInput/UploadInput.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAiC,MAAM,WAAW,CAAC;AAOvE,OAAO,EAAE,YAAY,EAAe,cAAc,EAAE,MAAM,SAAS,CAAC;AACpE,OAAqB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAE9E,OAAmB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEtE,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAEhC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,YAAY,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAE9D;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAErD;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAEjD;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAEhD;;OAEG;IACH,aAAa,CAAC,EAAE;QACd;;WAEG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QAEf;;WAEG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;QAEvB;;WAEG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC;QAErB;;WAEG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,GAAG,IAAI,CACN,iBAAiB,EACjB,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,IAAI,GAAG,mBAAmB,CACjG,GACC,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,GACnC,WAAW,CAAC;AAQd,QAAA,MAAM,WAAW,uQAoBd,gBAAgB,gCA8PlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -4,6 +4,7 @@ var classNames = require('classnames');
|
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var reactIntl = require('react-intl');
|
|
6
6
|
var Button = require('../button/Button.js');
|
|
7
|
+
var contexts = require('../inputs/contexts.js');
|
|
7
8
|
var Modal = require('../modal/Modal.js');
|
|
8
9
|
var isSizeValid = require('../upload/utils/isSizeValid/isSizeValid.js');
|
|
9
10
|
var isTypeValid = require('../upload/utils/isTypeValid/isTypeValid.js');
|
|
@@ -48,6 +49,9 @@ const UploadInput = ({
|
|
|
48
49
|
sizeLimitErrorMessage,
|
|
49
50
|
uploadButtonTitle
|
|
50
51
|
}) => {
|
|
52
|
+
const inputAttributes = contexts.useInputAttributes({
|
|
53
|
+
nonLabelable: true
|
|
54
|
+
});
|
|
51
55
|
const [markedFileForDelete, setMarkedFileForDelete] = React.useState(null);
|
|
52
56
|
const [mounted, setMounted] = React.useState(false);
|
|
53
57
|
const {
|
|
@@ -204,9 +208,11 @@ const UploadInput = ({
|
|
|
204
208
|
}, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
205
209
|
return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
206
210
|
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
211
|
+
role: "group",
|
|
207
212
|
className: classNames__default.default('np-upload-input', className, {
|
|
208
213
|
disabled
|
|
209
214
|
}),
|
|
215
|
+
...inputAttributes,
|
|
210
216
|
children: [uploadedFiles.map(file => /*#__PURE__*/jsxRuntime.jsx(UploadItem.default, {
|
|
211
217
|
file: file,
|
|
212
218
|
singleFileUpload: !multiple,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadInput.js","sources":["../../src/uploadInput/UploadInput.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { useEffect, useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Button from '../button';\nimport { CommonProps, ControlType, Priority, Status } from '../common';\nimport Modal from '../modal';\nimport { isSizeValid } from '../upload/utils/isSizeValid';\nimport { isTypeValid } from '../upload/utils/isTypeValid';\n\nimport MESSAGES from './UploadInput.messages';\nimport { UploadedFile, UploadError, UploadResponse } from './types';\nimport UploadButton, { UploadButtonProps } from './uploadButton/UploadButton';\nimport { DEFAULT_SIZE_LIMIT, imageFileTypes } from './uploadButton/defaults';\nimport UploadItem, { UploadItemProps } from './uploadItem/UploadItem';\n\nexport type UploadInputProps = {\n /**\n * List of already existing, failed or in progress files\n */\n files?: readonly UploadedFile[];\n\n /**\n * The key of the file in the returned FormData object (default: file)\n */\n fileInputName?: string;\n\n /**\n * Callback that handles form submission\n *\n * @param formData\n */\n onUploadFile: (formData: FormData) => Promise<UploadResponse>;\n\n /**\n * Provide a callback if the file can be removed/deleted from the server\n * Your app is responsible for reloading the uploaded files list and updating the component to ensure that the file has in fact been deleted successfully\n *\n * @param id\n */\n onDeleteFile?: (id: string | number) => Promise<any>;\n\n /**\n * Provide a callback to trigger on validation error\n *\n * @param file\n */\n onValidationError?: (file: UploadedFile) => void;\n\n /**\n * Provide a callback to trigger on change whenever the files are updated\n *\n * @param files\n */\n onFilesChange?: (files: UploadedFile[]) => void;\n\n /**\n * Confirmation modal displayed on delete\n */\n deleteConfirm?: {\n /**\n * The title of the confirmation modal on delete\n */\n title?: string;\n\n /**\n * The body of the confirmation modal on delete\n */\n body?: React.ReactNode;\n\n /**\n * The confirm button text of the confirmation modal on delete\n */\n confirmText?: string;\n\n /**\n * The cancel button text of the confirmation modal on delete\n */\n cancelText?: string;\n };\n\n /**\n * Maximum number of files allowed, if provided, shows error below file item\n */\n maxFiles?: number;\n\n /**\n * Error message to show when the maximum number of files are uploaded already\n */\n maxFilesErrorMessage?: string;\n\n /**\n * Error message to show when files over a allowed size limit are uploaded\n */\n sizeLimitErrorMessage?: string;\n} & Pick<\n UploadButtonProps,\n 'disabled' | 'multiple' | 'fileTypes' | 'sizeLimit' | 'description' | 'id' | 'uploadButtonTitle'\n> &\n Pick<UploadItemProps, 'onDownload'> &\n CommonProps;\n\nfunction generateFileId(file: File) {\n const { name, size } = file;\n const uploadTimeStamp = new Date().getTime();\n return `${name}_${size}_${uploadTimeStamp}`;\n}\n\nconst UploadInput = ({\n files = [],\n fileInputName = 'file',\n className,\n deleteConfirm,\n disabled,\n multiple = false,\n fileTypes = imageFileTypes,\n sizeLimit = DEFAULT_SIZE_LIMIT,\n description,\n onUploadFile,\n onDeleteFile,\n onValidationError,\n onFilesChange,\n onDownload,\n maxFiles,\n maxFilesErrorMessage,\n id,\n sizeLimitErrorMessage,\n uploadButtonTitle,\n}: UploadInputProps) => {\n const [markedFileForDelete, setMarkedFileForDelete] = useState<UploadedFile | null>(null);\n const [mounted, setMounted] = useState(false);\n const { formatMessage } = useIntl();\n\n const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);\n\n const [uploadedFiles, setUploadedFiles] = useState<readonly UploadedFile[]>(\n multiple || files.length === 0 ? files : [files[0]],\n );\n\n const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);\n\n function addFileToList(recentUploadedFile: UploadedFile) {\n function addToList(listToAddTo: readonly UploadedFile[]) {\n return [...listToAddTo, recentUploadedFile];\n }\n\n setUploadedFiles(addToList);\n uploadedFilesListReference.current = addToList(uploadedFilesListReference.current);\n }\n\n const removeFileFromList = (file: UploadedFile) => {\n function filterOutFrom(listToFilterFrom: readonly UploadedFile[]) {\n return listToFilterFrom.filter(\n (fileInList) => file !== fileInList && file.id !== fileInList.id,\n );\n }\n\n setUploadedFiles(filterOutFrom);\n uploadedFilesListReference.current = filterOutFrom(uploadedFilesListReference.current);\n };\n\n const modifyFileInList = (file: UploadedFile, updates: Partial<UploadedFile>) => {\n const updateListItem = (listToUpdate: readonly UploadedFile[]) =>\n listToUpdate.map((fileInList) => {\n return fileInList === file || fileInList.id === file.id\n ? { ...file, ...updates }\n : fileInList;\n });\n\n setUploadedFiles(updateListItem);\n uploadedFilesListReference.current = updateListItem(uploadedFilesListReference.current);\n };\n\n const removeFile = (file: UploadedFile) => {\n const { id, status } = file;\n\n if (status === Status.FAILED) {\n // If removing a failed upload, we're just updating the view\n removeFileFromList(file);\n } else if (onDeleteFile && id) {\n // Set status to PROCESSING\n modifyFileInList(file, { status: Status.PROCESSING, error: undefined });\n\n // Notify host app about deletion\n onDeleteFile(id)\n .then(() => removeFileFromList(file))\n .catch((error) => {\n modifyFileInList(file, { error: error as UploadError });\n });\n }\n };\n\n function handleFileUploadFailure(file: File, failureMessage: string) {\n const { name } = file;\n const id = generateFileId(file);\n const failedUpload = {\n id,\n filename: name,\n status: Status.FAILED,\n error: failureMessage,\n };\n\n addFileToList(failedUpload);\n\n if (onValidationError) {\n onValidationError(failedUpload);\n }\n }\n\n function getNumberOfFilesUploaded() {\n const uploadInitiatedStatus = new Set([Status.SUCCEEDED, Status.PENDING]);\n const validFiles = uploadedFilesListReference.current.filter(\n (file) => file.status && uploadInitiatedStatus.has(file.status),\n );\n return validFiles.length;\n }\n\n function areMaximumFilesUploadedAlready() {\n if (!maxFiles) {\n return false;\n }\n\n const numberOfValidFiles = getNumberOfFilesUploaded();\n return numberOfValidFiles >= maxFiles;\n }\n\n // One or more files selected, create entries for them\n const addFiles = (selectedFiles: FileList) => {\n for (let i = 0; i < selectedFiles.length; i += 1) {\n const file = selectedFiles.item(i);\n\n // Returning a FormData[] array instead of FileList so we can filter out incorrect files\n const formData = new FormData();\n\n if (file) {\n const { name } = file;\n const id = generateFileId(file);\n\n const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');\n\n // Check if file type is valid\n if (!isTypeValid(file, allowedFileTypes)) {\n handleFileUploadFailure(file, formatMessage(MESSAGES.fileTypeNotSupported));\n continue;\n }\n\n // Check if the filesize is valid\n // Convert to rough bytes\n if (!isSizeValid(file, sizeLimit * 1000)) {\n const failureMessage = sizeLimitErrorMessage || formatMessage(MESSAGES.fileIsTooLarge);\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n if (areMaximumFilesUploadedAlready()) {\n const failureMessage =\n maxFilesErrorMessage ||\n formatMessage(MESSAGES.maximumFilesAlreadyUploaded, { maxFilesAllowed: maxFiles });\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n formData.append(fileInputName, file);\n const pendingFile = {\n id,\n filename: name,\n status: Status.PENDING,\n };\n\n addFileToList(pendingFile);\n\n // Start uploading the file\n onUploadFile(formData)\n .then(({ id, url, error }: UploadResponse) => {\n // Replace the temporary id with the final one received from the API, and also set any errors\n modifyFileInList(pendingFile, { id, url, error, status: Status.SUCCEEDED });\n })\n .catch((error) => {\n modifyFileInList(pendingFile, { error: error as UploadError, status: Status.FAILED });\n });\n\n if (!multiple) {\n // Only upload a single file\n break;\n }\n }\n }\n };\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n if (onFilesChange && mounted) {\n onFilesChange([...uploadedFiles]);\n }\n }, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <>\n <div className={classNames('np-upload-input', className, { disabled })}>\n {uploadedFiles.map((file) => (\n <UploadItem\n key={file.id}\n file={file}\n singleFileUpload={!multiple}\n canDelete={\n (!!onDeleteFile || file.status === Status.FAILED) &&\n (!file.status || !PROGRESS_STATUSES.has(file.status))\n }\n onDelete={\n file.status === Status.FAILED\n ? () => removeFile(file)\n : () => setMarkedFileForDelete(file)\n }\n onDownload={onDownload}\n />\n ))}\n {(multiple || (!multiple && !uploadedFiles.length)) && (\n <UploadButton\n id={id}\n uploadButtonTitle={uploadButtonTitle}\n disabled={areMaximumFilesUploadedAlready() || disabled}\n multiple={multiple}\n fileTypes={fileTypes}\n sizeLimit={sizeLimit}\n description={description}\n maxFiles={maxFiles}\n onChange={addFiles}\n />\n )}\n </div>\n <Modal\n title={\n deleteConfirm?.title !== undefined\n ? deleteConfirm.title\n : formatMessage(MESSAGES.deleteModalTitle)\n }\n body={\n deleteConfirm?.body !== undefined\n ? deleteConfirm.body\n : formatMessage(MESSAGES.deleteModalBody)\n }\n open={!!markedFileForDelete}\n footer={\n <>\n <Button\n block\n onClick={() => {\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.cancelText || formatMessage(MESSAGES.deleteModalCancelButtonText)}\n </Button>\n <Button\n block\n priority={Priority.SECONDARY}\n type={ControlType.NEGATIVE}\n onClick={() => {\n if (markedFileForDelete) {\n removeFile(markedFileForDelete);\n }\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.confirmText || formatMessage(MESSAGES.deleteModalConfirmButtonText)}\n </Button>\n </>\n }\n onClose={() => {\n setMarkedFileForDelete(null);\n }}\n />\n </>\n );\n};\n\nexport default UploadInput;\n"],"names":["generateFileId","file","name","size","uploadTimeStamp","Date","getTime","UploadInput","files","fileInputName","className","deleteConfirm","disabled","multiple","fileTypes","imageFileTypes","sizeLimit","DEFAULT_SIZE_LIMIT","description","onUploadFile","onDeleteFile","onValidationError","onFilesChange","onDownload","maxFiles","maxFilesErrorMessage","id","sizeLimitErrorMessage","uploadButtonTitle","markedFileForDelete","setMarkedFileForDelete","useState","mounted","setMounted","formatMessage","useIntl","PROGRESS_STATUSES","Set","Status","PENDING","PROCESSING","uploadedFiles","setUploadedFiles","length","uploadedFilesListReference","useRef","addFileToList","recentUploadedFile","addToList","listToAddTo","current","removeFileFromList","filterOutFrom","listToFilterFrom","filter","fileInList","modifyFileInList","updates","updateListItem","listToUpdate","map","removeFile","status","FAILED","error","undefined","then","catch","handleFileUploadFailure","failureMessage","failedUpload","filename","getNumberOfFilesUploaded","uploadInitiatedStatus","SUCCEEDED","validFiles","has","areMaximumFilesUploadedAlready","numberOfValidFiles","addFiles","selectedFiles","i","item","formData","FormData","allowedFileTypes","join","isTypeValid","MESSAGES","fileTypeNotSupported","isSizeValid","fileIsTooLarge","maximumFilesAlreadyUploaded","maxFilesAllowed","append","pendingFile","url","useEffect","_jsxs","_Fragment","children","classNames","_jsx","UploadItem","singleFileUpload","canDelete","onDelete","UploadButton","onChange","Modal","title","deleteModalTitle","body","deleteModalBody","open","footer","Button","block","onClick","cancelText","deleteModalCancelButtonText","priority","Priority","SECONDARY","type","ControlType","NEGATIVE","confirmText","deleteModalConfirmButtonText","onClose"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UploadInput.js","sources":["../../src/uploadInput/UploadInput.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { useEffect, useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Button from '../button';\nimport { CommonProps, ControlType, Priority, Status } from '../common';\nimport { useInputAttributes } from '../inputs/contexts';\nimport Modal from '../modal';\nimport { isSizeValid } from '../upload/utils/isSizeValid';\nimport { isTypeValid } from '../upload/utils/isTypeValid';\n\nimport MESSAGES from './UploadInput.messages';\nimport { UploadedFile, UploadError, UploadResponse } from './types';\nimport UploadButton, { UploadButtonProps } from './uploadButton/UploadButton';\nimport { DEFAULT_SIZE_LIMIT, imageFileTypes } from './uploadButton/defaults';\nimport UploadItem, { UploadItemProps } from './uploadItem/UploadItem';\n\nexport type UploadInputProps = {\n /**\n * List of already existing, failed or in progress files\n */\n files?: readonly UploadedFile[];\n\n /**\n * The key of the file in the returned FormData object (default: file)\n */\n fileInputName?: string;\n\n /**\n * Callback that handles form submission\n *\n * @param formData\n */\n onUploadFile: (formData: FormData) => Promise<UploadResponse>;\n\n /**\n * Provide a callback if the file can be removed/deleted from the server\n * Your app is responsible for reloading the uploaded files list and updating the component to ensure that the file has in fact been deleted successfully\n *\n * @param id\n */\n onDeleteFile?: (id: string | number) => Promise<any>;\n\n /**\n * Provide a callback to trigger on validation error\n *\n * @param file\n */\n onValidationError?: (file: UploadedFile) => void;\n\n /**\n * Provide a callback to trigger on change whenever the files are updated\n *\n * @param files\n */\n onFilesChange?: (files: UploadedFile[]) => void;\n\n /**\n * Confirmation modal displayed on delete\n */\n deleteConfirm?: {\n /**\n * The title of the confirmation modal on delete\n */\n title?: string;\n\n /**\n * The body of the confirmation modal on delete\n */\n body?: React.ReactNode;\n\n /**\n * The confirm button text of the confirmation modal on delete\n */\n confirmText?: string;\n\n /**\n * The cancel button text of the confirmation modal on delete\n */\n cancelText?: string;\n };\n\n /**\n * Maximum number of files allowed, if provided, shows error below file item\n */\n maxFiles?: number;\n\n /**\n * Error message to show when the maximum number of files are uploaded already\n */\n maxFilesErrorMessage?: string;\n\n /**\n * Error message to show when files over a allowed size limit are uploaded\n */\n sizeLimitErrorMessage?: string;\n} & Pick<\n UploadButtonProps,\n 'disabled' | 'multiple' | 'fileTypes' | 'sizeLimit' | 'description' | 'id' | 'uploadButtonTitle'\n> &\n Pick<UploadItemProps, 'onDownload'> &\n CommonProps;\n\nfunction generateFileId(file: File) {\n const { name, size } = file;\n const uploadTimeStamp = new Date().getTime();\n return `${name}_${size}_${uploadTimeStamp}`;\n}\n\nconst UploadInput = ({\n files = [],\n fileInputName = 'file',\n className,\n deleteConfirm,\n disabled,\n multiple = false,\n fileTypes = imageFileTypes,\n sizeLimit = DEFAULT_SIZE_LIMIT,\n description,\n onUploadFile,\n onDeleteFile,\n onValidationError,\n onFilesChange,\n onDownload,\n maxFiles,\n maxFilesErrorMessage,\n id,\n sizeLimitErrorMessage,\n uploadButtonTitle,\n}: UploadInputProps) => {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n\n const [markedFileForDelete, setMarkedFileForDelete] = useState<UploadedFile | null>(null);\n const [mounted, setMounted] = useState(false);\n const { formatMessage } = useIntl();\n\n const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);\n\n const [uploadedFiles, setUploadedFiles] = useState<readonly UploadedFile[]>(\n multiple || files.length === 0 ? files : [files[0]],\n );\n\n const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);\n\n function addFileToList(recentUploadedFile: UploadedFile) {\n function addToList(listToAddTo: readonly UploadedFile[]) {\n return [...listToAddTo, recentUploadedFile];\n }\n\n setUploadedFiles(addToList);\n uploadedFilesListReference.current = addToList(uploadedFilesListReference.current);\n }\n\n const removeFileFromList = (file: UploadedFile) => {\n function filterOutFrom(listToFilterFrom: readonly UploadedFile[]) {\n return listToFilterFrom.filter(\n (fileInList) => file !== fileInList && file.id !== fileInList.id,\n );\n }\n\n setUploadedFiles(filterOutFrom);\n uploadedFilesListReference.current = filterOutFrom(uploadedFilesListReference.current);\n };\n\n const modifyFileInList = (file: UploadedFile, updates: Partial<UploadedFile>) => {\n const updateListItem = (listToUpdate: readonly UploadedFile[]) =>\n listToUpdate.map((fileInList) => {\n return fileInList === file || fileInList.id === file.id\n ? { ...file, ...updates }\n : fileInList;\n });\n\n setUploadedFiles(updateListItem);\n uploadedFilesListReference.current = updateListItem(uploadedFilesListReference.current);\n };\n\n const removeFile = (file: UploadedFile) => {\n const { id, status } = file;\n\n if (status === Status.FAILED) {\n // If removing a failed upload, we're just updating the view\n removeFileFromList(file);\n } else if (onDeleteFile && id) {\n // Set status to PROCESSING\n modifyFileInList(file, { status: Status.PROCESSING, error: undefined });\n\n // Notify host app about deletion\n onDeleteFile(id)\n .then(() => removeFileFromList(file))\n .catch((error) => {\n modifyFileInList(file, { error: error as UploadError });\n });\n }\n };\n\n function handleFileUploadFailure(file: File, failureMessage: string) {\n const { name } = file;\n const id = generateFileId(file);\n const failedUpload = {\n id,\n filename: name,\n status: Status.FAILED,\n error: failureMessage,\n };\n\n addFileToList(failedUpload);\n\n if (onValidationError) {\n onValidationError(failedUpload);\n }\n }\n\n function getNumberOfFilesUploaded() {\n const uploadInitiatedStatus = new Set([Status.SUCCEEDED, Status.PENDING]);\n const validFiles = uploadedFilesListReference.current.filter(\n (file) => file.status && uploadInitiatedStatus.has(file.status),\n );\n return validFiles.length;\n }\n\n function areMaximumFilesUploadedAlready() {\n if (!maxFiles) {\n return false;\n }\n\n const numberOfValidFiles = getNumberOfFilesUploaded();\n return numberOfValidFiles >= maxFiles;\n }\n\n // One or more files selected, create entries for them\n const addFiles = (selectedFiles: FileList) => {\n for (let i = 0; i < selectedFiles.length; i += 1) {\n const file = selectedFiles.item(i);\n\n // Returning a FormData[] array instead of FileList so we can filter out incorrect files\n const formData = new FormData();\n\n if (file) {\n const { name } = file;\n const id = generateFileId(file);\n\n const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');\n\n // Check if file type is valid\n if (!isTypeValid(file, allowedFileTypes)) {\n handleFileUploadFailure(file, formatMessage(MESSAGES.fileTypeNotSupported));\n continue;\n }\n\n // Check if the filesize is valid\n // Convert to rough bytes\n if (!isSizeValid(file, sizeLimit * 1000)) {\n const failureMessage = sizeLimitErrorMessage || formatMessage(MESSAGES.fileIsTooLarge);\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n if (areMaximumFilesUploadedAlready()) {\n const failureMessage =\n maxFilesErrorMessage ||\n formatMessage(MESSAGES.maximumFilesAlreadyUploaded, { maxFilesAllowed: maxFiles });\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n formData.append(fileInputName, file);\n const pendingFile = {\n id,\n filename: name,\n status: Status.PENDING,\n };\n\n addFileToList(pendingFile);\n\n // Start uploading the file\n onUploadFile(formData)\n .then(({ id, url, error }: UploadResponse) => {\n // Replace the temporary id with the final one received from the API, and also set any errors\n modifyFileInList(pendingFile, { id, url, error, status: Status.SUCCEEDED });\n })\n .catch((error) => {\n modifyFileInList(pendingFile, { error: error as UploadError, status: Status.FAILED });\n });\n\n if (!multiple) {\n // Only upload a single file\n break;\n }\n }\n }\n };\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n if (onFilesChange && mounted) {\n onFilesChange([...uploadedFiles]);\n }\n }, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <>\n <div\n role=\"group\"\n className={classNames('np-upload-input', className, { disabled })}\n {...inputAttributes}\n >\n {uploadedFiles.map((file) => (\n <UploadItem\n key={file.id}\n file={file}\n singleFileUpload={!multiple}\n canDelete={\n (!!onDeleteFile || file.status === Status.FAILED) &&\n (!file.status || !PROGRESS_STATUSES.has(file.status))\n }\n onDelete={\n file.status === Status.FAILED\n ? () => removeFile(file)\n : () => setMarkedFileForDelete(file)\n }\n onDownload={onDownload}\n />\n ))}\n {(multiple || (!multiple && !uploadedFiles.length)) && (\n <UploadButton\n id={id}\n uploadButtonTitle={uploadButtonTitle}\n disabled={areMaximumFilesUploadedAlready() || disabled}\n multiple={multiple}\n fileTypes={fileTypes}\n sizeLimit={sizeLimit}\n description={description}\n maxFiles={maxFiles}\n onChange={addFiles}\n />\n )}\n </div>\n <Modal\n title={\n deleteConfirm?.title !== undefined\n ? deleteConfirm.title\n : formatMessage(MESSAGES.deleteModalTitle)\n }\n body={\n deleteConfirm?.body !== undefined\n ? deleteConfirm.body\n : formatMessage(MESSAGES.deleteModalBody)\n }\n open={!!markedFileForDelete}\n footer={\n <>\n <Button\n block\n onClick={() => {\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.cancelText || formatMessage(MESSAGES.deleteModalCancelButtonText)}\n </Button>\n <Button\n block\n priority={Priority.SECONDARY}\n type={ControlType.NEGATIVE}\n onClick={() => {\n if (markedFileForDelete) {\n removeFile(markedFileForDelete);\n }\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.confirmText || formatMessage(MESSAGES.deleteModalConfirmButtonText)}\n </Button>\n </>\n }\n onClose={() => {\n setMarkedFileForDelete(null);\n }}\n />\n </>\n );\n};\n\nexport default UploadInput;\n"],"names":["generateFileId","file","name","size","uploadTimeStamp","Date","getTime","UploadInput","files","fileInputName","className","deleteConfirm","disabled","multiple","fileTypes","imageFileTypes","sizeLimit","DEFAULT_SIZE_LIMIT","description","onUploadFile","onDeleteFile","onValidationError","onFilesChange","onDownload","maxFiles","maxFilesErrorMessage","id","sizeLimitErrorMessage","uploadButtonTitle","inputAttributes","useInputAttributes","nonLabelable","markedFileForDelete","setMarkedFileForDelete","useState","mounted","setMounted","formatMessage","useIntl","PROGRESS_STATUSES","Set","Status","PENDING","PROCESSING","uploadedFiles","setUploadedFiles","length","uploadedFilesListReference","useRef","addFileToList","recentUploadedFile","addToList","listToAddTo","current","removeFileFromList","filterOutFrom","listToFilterFrom","filter","fileInList","modifyFileInList","updates","updateListItem","listToUpdate","map","removeFile","status","FAILED","error","undefined","then","catch","handleFileUploadFailure","failureMessage","failedUpload","filename","getNumberOfFilesUploaded","uploadInitiatedStatus","SUCCEEDED","validFiles","has","areMaximumFilesUploadedAlready","numberOfValidFiles","addFiles","selectedFiles","i","item","formData","FormData","allowedFileTypes","join","isTypeValid","MESSAGES","fileTypeNotSupported","isSizeValid","fileIsTooLarge","maximumFilesAlreadyUploaded","maxFilesAllowed","append","pendingFile","url","useEffect","_jsxs","_Fragment","children","role","classNames","_jsx","UploadItem","singleFileUpload","canDelete","onDelete","UploadButton","onChange","Modal","title","deleteModalTitle","body","deleteModalBody","open","footer","Button","block","onClick","cancelText","deleteModalCancelButtonText","priority","Priority","SECONDARY","type","ControlType","NEGATIVE","confirmText","deleteModalConfirmButtonText","onClose"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import classNames from 'classnames';
|
|
|
2
2
|
import { useState, useRef, useEffect } from 'react';
|
|
3
3
|
import { useIntl } from 'react-intl';
|
|
4
4
|
import Button from '../button/Button.mjs';
|
|
5
|
+
import { useInputAttributes } from '../inputs/contexts.mjs';
|
|
5
6
|
import Modal from '../modal/Modal.mjs';
|
|
6
7
|
import { isSizeValid } from '../upload/utils/isSizeValid/isSizeValid.mjs';
|
|
7
8
|
import { isTypeValid } from '../upload/utils/isTypeValid/isTypeValid.mjs';
|
|
@@ -42,6 +43,9 @@ const UploadInput = ({
|
|
|
42
43
|
sizeLimitErrorMessage,
|
|
43
44
|
uploadButtonTitle
|
|
44
45
|
}) => {
|
|
46
|
+
const inputAttributes = useInputAttributes({
|
|
47
|
+
nonLabelable: true
|
|
48
|
+
});
|
|
45
49
|
const [markedFileForDelete, setMarkedFileForDelete] = useState(null);
|
|
46
50
|
const [mounted, setMounted] = useState(false);
|
|
47
51
|
const {
|
|
@@ -198,9 +202,11 @@ const UploadInput = ({
|
|
|
198
202
|
}, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
199
203
|
return /*#__PURE__*/jsxs(Fragment, {
|
|
200
204
|
children: [/*#__PURE__*/jsxs("div", {
|
|
205
|
+
role: "group",
|
|
201
206
|
className: classNames('np-upload-input', className, {
|
|
202
207
|
disabled
|
|
203
208
|
}),
|
|
209
|
+
...inputAttributes,
|
|
204
210
|
children: [uploadedFiles.map(file => /*#__PURE__*/jsx(UploadItem, {
|
|
205
211
|
file: file,
|
|
206
212
|
singleFileUpload: !multiple,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadInput.mjs","sources":["../../src/uploadInput/UploadInput.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { useEffect, useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Button from '../button';\nimport { CommonProps, ControlType, Priority, Status } from '../common';\nimport Modal from '../modal';\nimport { isSizeValid } from '../upload/utils/isSizeValid';\nimport { isTypeValid } from '../upload/utils/isTypeValid';\n\nimport MESSAGES from './UploadInput.messages';\nimport { UploadedFile, UploadError, UploadResponse } from './types';\nimport UploadButton, { UploadButtonProps } from './uploadButton/UploadButton';\nimport { DEFAULT_SIZE_LIMIT, imageFileTypes } from './uploadButton/defaults';\nimport UploadItem, { UploadItemProps } from './uploadItem/UploadItem';\n\nexport type UploadInputProps = {\n /**\n * List of already existing, failed or in progress files\n */\n files?: readonly UploadedFile[];\n\n /**\n * The key of the file in the returned FormData object (default: file)\n */\n fileInputName?: string;\n\n /**\n * Callback that handles form submission\n *\n * @param formData\n */\n onUploadFile: (formData: FormData) => Promise<UploadResponse>;\n\n /**\n * Provide a callback if the file can be removed/deleted from the server\n * Your app is responsible for reloading the uploaded files list and updating the component to ensure that the file has in fact been deleted successfully\n *\n * @param id\n */\n onDeleteFile?: (id: string | number) => Promise<any>;\n\n /**\n * Provide a callback to trigger on validation error\n *\n * @param file\n */\n onValidationError?: (file: UploadedFile) => void;\n\n /**\n * Provide a callback to trigger on change whenever the files are updated\n *\n * @param files\n */\n onFilesChange?: (files: UploadedFile[]) => void;\n\n /**\n * Confirmation modal displayed on delete\n */\n deleteConfirm?: {\n /**\n * The title of the confirmation modal on delete\n */\n title?: string;\n\n /**\n * The body of the confirmation modal on delete\n */\n body?: React.ReactNode;\n\n /**\n * The confirm button text of the confirmation modal on delete\n */\n confirmText?: string;\n\n /**\n * The cancel button text of the confirmation modal on delete\n */\n cancelText?: string;\n };\n\n /**\n * Maximum number of files allowed, if provided, shows error below file item\n */\n maxFiles?: number;\n\n /**\n * Error message to show when the maximum number of files are uploaded already\n */\n maxFilesErrorMessage?: string;\n\n /**\n * Error message to show when files over a allowed size limit are uploaded\n */\n sizeLimitErrorMessage?: string;\n} & Pick<\n UploadButtonProps,\n 'disabled' | 'multiple' | 'fileTypes' | 'sizeLimit' | 'description' | 'id' | 'uploadButtonTitle'\n> &\n Pick<UploadItemProps, 'onDownload'> &\n CommonProps;\n\nfunction generateFileId(file: File) {\n const { name, size } = file;\n const uploadTimeStamp = new Date().getTime();\n return `${name}_${size}_${uploadTimeStamp}`;\n}\n\nconst UploadInput = ({\n files = [],\n fileInputName = 'file',\n className,\n deleteConfirm,\n disabled,\n multiple = false,\n fileTypes = imageFileTypes,\n sizeLimit = DEFAULT_SIZE_LIMIT,\n description,\n onUploadFile,\n onDeleteFile,\n onValidationError,\n onFilesChange,\n onDownload,\n maxFiles,\n maxFilesErrorMessage,\n id,\n sizeLimitErrorMessage,\n uploadButtonTitle,\n}: UploadInputProps) => {\n const [markedFileForDelete, setMarkedFileForDelete] = useState<UploadedFile | null>(null);\n const [mounted, setMounted] = useState(false);\n const { formatMessage } = useIntl();\n\n const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);\n\n const [uploadedFiles, setUploadedFiles] = useState<readonly UploadedFile[]>(\n multiple || files.length === 0 ? files : [files[0]],\n );\n\n const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);\n\n function addFileToList(recentUploadedFile: UploadedFile) {\n function addToList(listToAddTo: readonly UploadedFile[]) {\n return [...listToAddTo, recentUploadedFile];\n }\n\n setUploadedFiles(addToList);\n uploadedFilesListReference.current = addToList(uploadedFilesListReference.current);\n }\n\n const removeFileFromList = (file: UploadedFile) => {\n function filterOutFrom(listToFilterFrom: readonly UploadedFile[]) {\n return listToFilterFrom.filter(\n (fileInList) => file !== fileInList && file.id !== fileInList.id,\n );\n }\n\n setUploadedFiles(filterOutFrom);\n uploadedFilesListReference.current = filterOutFrom(uploadedFilesListReference.current);\n };\n\n const modifyFileInList = (file: UploadedFile, updates: Partial<UploadedFile>) => {\n const updateListItem = (listToUpdate: readonly UploadedFile[]) =>\n listToUpdate.map((fileInList) => {\n return fileInList === file || fileInList.id === file.id\n ? { ...file, ...updates }\n : fileInList;\n });\n\n setUploadedFiles(updateListItem);\n uploadedFilesListReference.current = updateListItem(uploadedFilesListReference.current);\n };\n\n const removeFile = (file: UploadedFile) => {\n const { id, status } = file;\n\n if (status === Status.FAILED) {\n // If removing a failed upload, we're just updating the view\n removeFileFromList(file);\n } else if (onDeleteFile && id) {\n // Set status to PROCESSING\n modifyFileInList(file, { status: Status.PROCESSING, error: undefined });\n\n // Notify host app about deletion\n onDeleteFile(id)\n .then(() => removeFileFromList(file))\n .catch((error) => {\n modifyFileInList(file, { error: error as UploadError });\n });\n }\n };\n\n function handleFileUploadFailure(file: File, failureMessage: string) {\n const { name } = file;\n const id = generateFileId(file);\n const failedUpload = {\n id,\n filename: name,\n status: Status.FAILED,\n error: failureMessage,\n };\n\n addFileToList(failedUpload);\n\n if (onValidationError) {\n onValidationError(failedUpload);\n }\n }\n\n function getNumberOfFilesUploaded() {\n const uploadInitiatedStatus = new Set([Status.SUCCEEDED, Status.PENDING]);\n const validFiles = uploadedFilesListReference.current.filter(\n (file) => file.status && uploadInitiatedStatus.has(file.status),\n );\n return validFiles.length;\n }\n\n function areMaximumFilesUploadedAlready() {\n if (!maxFiles) {\n return false;\n }\n\n const numberOfValidFiles = getNumberOfFilesUploaded();\n return numberOfValidFiles >= maxFiles;\n }\n\n // One or more files selected, create entries for them\n const addFiles = (selectedFiles: FileList) => {\n for (let i = 0; i < selectedFiles.length; i += 1) {\n const file = selectedFiles.item(i);\n\n // Returning a FormData[] array instead of FileList so we can filter out incorrect files\n const formData = new FormData();\n\n if (file) {\n const { name } = file;\n const id = generateFileId(file);\n\n const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');\n\n // Check if file type is valid\n if (!isTypeValid(file, allowedFileTypes)) {\n handleFileUploadFailure(file, formatMessage(MESSAGES.fileTypeNotSupported));\n continue;\n }\n\n // Check if the filesize is valid\n // Convert to rough bytes\n if (!isSizeValid(file, sizeLimit * 1000)) {\n const failureMessage = sizeLimitErrorMessage || formatMessage(MESSAGES.fileIsTooLarge);\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n if (areMaximumFilesUploadedAlready()) {\n const failureMessage =\n maxFilesErrorMessage ||\n formatMessage(MESSAGES.maximumFilesAlreadyUploaded, { maxFilesAllowed: maxFiles });\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n formData.append(fileInputName, file);\n const pendingFile = {\n id,\n filename: name,\n status: Status.PENDING,\n };\n\n addFileToList(pendingFile);\n\n // Start uploading the file\n onUploadFile(formData)\n .then(({ id, url, error }: UploadResponse) => {\n // Replace the temporary id with the final one received from the API, and also set any errors\n modifyFileInList(pendingFile, { id, url, error, status: Status.SUCCEEDED });\n })\n .catch((error) => {\n modifyFileInList(pendingFile, { error: error as UploadError, status: Status.FAILED });\n });\n\n if (!multiple) {\n // Only upload a single file\n break;\n }\n }\n }\n };\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n if (onFilesChange && mounted) {\n onFilesChange([...uploadedFiles]);\n }\n }, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <>\n <div className={classNames('np-upload-input', className, { disabled })}>\n {uploadedFiles.map((file) => (\n <UploadItem\n key={file.id}\n file={file}\n singleFileUpload={!multiple}\n canDelete={\n (!!onDeleteFile || file.status === Status.FAILED) &&\n (!file.status || !PROGRESS_STATUSES.has(file.status))\n }\n onDelete={\n file.status === Status.FAILED\n ? () => removeFile(file)\n : () => setMarkedFileForDelete(file)\n }\n onDownload={onDownload}\n />\n ))}\n {(multiple || (!multiple && !uploadedFiles.length)) && (\n <UploadButton\n id={id}\n uploadButtonTitle={uploadButtonTitle}\n disabled={areMaximumFilesUploadedAlready() || disabled}\n multiple={multiple}\n fileTypes={fileTypes}\n sizeLimit={sizeLimit}\n description={description}\n maxFiles={maxFiles}\n onChange={addFiles}\n />\n )}\n </div>\n <Modal\n title={\n deleteConfirm?.title !== undefined\n ? deleteConfirm.title\n : formatMessage(MESSAGES.deleteModalTitle)\n }\n body={\n deleteConfirm?.body !== undefined\n ? deleteConfirm.body\n : formatMessage(MESSAGES.deleteModalBody)\n }\n open={!!markedFileForDelete}\n footer={\n <>\n <Button\n block\n onClick={() => {\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.cancelText || formatMessage(MESSAGES.deleteModalCancelButtonText)}\n </Button>\n <Button\n block\n priority={Priority.SECONDARY}\n type={ControlType.NEGATIVE}\n onClick={() => {\n if (markedFileForDelete) {\n removeFile(markedFileForDelete);\n }\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.confirmText || formatMessage(MESSAGES.deleteModalConfirmButtonText)}\n </Button>\n </>\n }\n onClose={() => {\n setMarkedFileForDelete(null);\n }}\n />\n </>\n );\n};\n\nexport default UploadInput;\n"],"names":["generateFileId","file","name","size","uploadTimeStamp","Date","getTime","UploadInput","files","fileInputName","className","deleteConfirm","disabled","multiple","fileTypes","imageFileTypes","sizeLimit","DEFAULT_SIZE_LIMIT","description","onUploadFile","onDeleteFile","onValidationError","onFilesChange","onDownload","maxFiles","maxFilesErrorMessage","id","sizeLimitErrorMessage","uploadButtonTitle","markedFileForDelete","setMarkedFileForDelete","useState","mounted","setMounted","formatMessage","useIntl","PROGRESS_STATUSES","Set","Status","PENDING","PROCESSING","uploadedFiles","setUploadedFiles","length","uploadedFilesListReference","useRef","addFileToList","recentUploadedFile","addToList","listToAddTo","current","removeFileFromList","filterOutFrom","listToFilterFrom","filter","fileInList","modifyFileInList","updates","updateListItem","listToUpdate","map","removeFile","status","FAILED","error","undefined","then","catch","handleFileUploadFailure","failureMessage","failedUpload","filename","getNumberOfFilesUploaded","uploadInitiatedStatus","SUCCEEDED","validFiles","has","areMaximumFilesUploadedAlready","numberOfValidFiles","addFiles","selectedFiles","i","item","formData","FormData","allowedFileTypes","join","isTypeValid","MESSAGES","fileTypeNotSupported","isSizeValid","fileIsTooLarge","maximumFilesAlreadyUploaded","maxFilesAllowed","append","pendingFile","url","useEffect","_jsxs","_Fragment","children","classNames","_jsx","UploadItem","singleFileUpload","canDelete","onDelete","UploadButton","onChange","Modal","title","deleteModalTitle","body","deleteModalBody","open","footer","Button","block","onClick","cancelText","deleteModalCancelButtonText","priority","Priority","SECONDARY","type","ControlType","NEGATIVE","confirmText","deleteModalConfirmButtonText","onClose"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UploadInput.mjs","sources":["../../src/uploadInput/UploadInput.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { useEffect, useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Button from '../button';\nimport { CommonProps, ControlType, Priority, Status } from '../common';\nimport { useInputAttributes } from '../inputs/contexts';\nimport Modal from '../modal';\nimport { isSizeValid } from '../upload/utils/isSizeValid';\nimport { isTypeValid } from '../upload/utils/isTypeValid';\n\nimport MESSAGES from './UploadInput.messages';\nimport { UploadedFile, UploadError, UploadResponse } from './types';\nimport UploadButton, { UploadButtonProps } from './uploadButton/UploadButton';\nimport { DEFAULT_SIZE_LIMIT, imageFileTypes } from './uploadButton/defaults';\nimport UploadItem, { UploadItemProps } from './uploadItem/UploadItem';\n\nexport type UploadInputProps = {\n /**\n * List of already existing, failed or in progress files\n */\n files?: readonly UploadedFile[];\n\n /**\n * The key of the file in the returned FormData object (default: file)\n */\n fileInputName?: string;\n\n /**\n * Callback that handles form submission\n *\n * @param formData\n */\n onUploadFile: (formData: FormData) => Promise<UploadResponse>;\n\n /**\n * Provide a callback if the file can be removed/deleted from the server\n * Your app is responsible for reloading the uploaded files list and updating the component to ensure that the file has in fact been deleted successfully\n *\n * @param id\n */\n onDeleteFile?: (id: string | number) => Promise<any>;\n\n /**\n * Provide a callback to trigger on validation error\n *\n * @param file\n */\n onValidationError?: (file: UploadedFile) => void;\n\n /**\n * Provide a callback to trigger on change whenever the files are updated\n *\n * @param files\n */\n onFilesChange?: (files: UploadedFile[]) => void;\n\n /**\n * Confirmation modal displayed on delete\n */\n deleteConfirm?: {\n /**\n * The title of the confirmation modal on delete\n */\n title?: string;\n\n /**\n * The body of the confirmation modal on delete\n */\n body?: React.ReactNode;\n\n /**\n * The confirm button text of the confirmation modal on delete\n */\n confirmText?: string;\n\n /**\n * The cancel button text of the confirmation modal on delete\n */\n cancelText?: string;\n };\n\n /**\n * Maximum number of files allowed, if provided, shows error below file item\n */\n maxFiles?: number;\n\n /**\n * Error message to show when the maximum number of files are uploaded already\n */\n maxFilesErrorMessage?: string;\n\n /**\n * Error message to show when files over a allowed size limit are uploaded\n */\n sizeLimitErrorMessage?: string;\n} & Pick<\n UploadButtonProps,\n 'disabled' | 'multiple' | 'fileTypes' | 'sizeLimit' | 'description' | 'id' | 'uploadButtonTitle'\n> &\n Pick<UploadItemProps, 'onDownload'> &\n CommonProps;\n\nfunction generateFileId(file: File) {\n const { name, size } = file;\n const uploadTimeStamp = new Date().getTime();\n return `${name}_${size}_${uploadTimeStamp}`;\n}\n\nconst UploadInput = ({\n files = [],\n fileInputName = 'file',\n className,\n deleteConfirm,\n disabled,\n multiple = false,\n fileTypes = imageFileTypes,\n sizeLimit = DEFAULT_SIZE_LIMIT,\n description,\n onUploadFile,\n onDeleteFile,\n onValidationError,\n onFilesChange,\n onDownload,\n maxFiles,\n maxFilesErrorMessage,\n id,\n sizeLimitErrorMessage,\n uploadButtonTitle,\n}: UploadInputProps) => {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n\n const [markedFileForDelete, setMarkedFileForDelete] = useState<UploadedFile | null>(null);\n const [mounted, setMounted] = useState(false);\n const { formatMessage } = useIntl();\n\n const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);\n\n const [uploadedFiles, setUploadedFiles] = useState<readonly UploadedFile[]>(\n multiple || files.length === 0 ? files : [files[0]],\n );\n\n const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);\n\n function addFileToList(recentUploadedFile: UploadedFile) {\n function addToList(listToAddTo: readonly UploadedFile[]) {\n return [...listToAddTo, recentUploadedFile];\n }\n\n setUploadedFiles(addToList);\n uploadedFilesListReference.current = addToList(uploadedFilesListReference.current);\n }\n\n const removeFileFromList = (file: UploadedFile) => {\n function filterOutFrom(listToFilterFrom: readonly UploadedFile[]) {\n return listToFilterFrom.filter(\n (fileInList) => file !== fileInList && file.id !== fileInList.id,\n );\n }\n\n setUploadedFiles(filterOutFrom);\n uploadedFilesListReference.current = filterOutFrom(uploadedFilesListReference.current);\n };\n\n const modifyFileInList = (file: UploadedFile, updates: Partial<UploadedFile>) => {\n const updateListItem = (listToUpdate: readonly UploadedFile[]) =>\n listToUpdate.map((fileInList) => {\n return fileInList === file || fileInList.id === file.id\n ? { ...file, ...updates }\n : fileInList;\n });\n\n setUploadedFiles(updateListItem);\n uploadedFilesListReference.current = updateListItem(uploadedFilesListReference.current);\n };\n\n const removeFile = (file: UploadedFile) => {\n const { id, status } = file;\n\n if (status === Status.FAILED) {\n // If removing a failed upload, we're just updating the view\n removeFileFromList(file);\n } else if (onDeleteFile && id) {\n // Set status to PROCESSING\n modifyFileInList(file, { status: Status.PROCESSING, error: undefined });\n\n // Notify host app about deletion\n onDeleteFile(id)\n .then(() => removeFileFromList(file))\n .catch((error) => {\n modifyFileInList(file, { error: error as UploadError });\n });\n }\n };\n\n function handleFileUploadFailure(file: File, failureMessage: string) {\n const { name } = file;\n const id = generateFileId(file);\n const failedUpload = {\n id,\n filename: name,\n status: Status.FAILED,\n error: failureMessage,\n };\n\n addFileToList(failedUpload);\n\n if (onValidationError) {\n onValidationError(failedUpload);\n }\n }\n\n function getNumberOfFilesUploaded() {\n const uploadInitiatedStatus = new Set([Status.SUCCEEDED, Status.PENDING]);\n const validFiles = uploadedFilesListReference.current.filter(\n (file) => file.status && uploadInitiatedStatus.has(file.status),\n );\n return validFiles.length;\n }\n\n function areMaximumFilesUploadedAlready() {\n if (!maxFiles) {\n return false;\n }\n\n const numberOfValidFiles = getNumberOfFilesUploaded();\n return numberOfValidFiles >= maxFiles;\n }\n\n // One or more files selected, create entries for them\n const addFiles = (selectedFiles: FileList) => {\n for (let i = 0; i < selectedFiles.length; i += 1) {\n const file = selectedFiles.item(i);\n\n // Returning a FormData[] array instead of FileList so we can filter out incorrect files\n const formData = new FormData();\n\n if (file) {\n const { name } = file;\n const id = generateFileId(file);\n\n const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');\n\n // Check if file type is valid\n if (!isTypeValid(file, allowedFileTypes)) {\n handleFileUploadFailure(file, formatMessage(MESSAGES.fileTypeNotSupported));\n continue;\n }\n\n // Check if the filesize is valid\n // Convert to rough bytes\n if (!isSizeValid(file, sizeLimit * 1000)) {\n const failureMessage = sizeLimitErrorMessage || formatMessage(MESSAGES.fileIsTooLarge);\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n if (areMaximumFilesUploadedAlready()) {\n const failureMessage =\n maxFilesErrorMessage ||\n formatMessage(MESSAGES.maximumFilesAlreadyUploaded, { maxFilesAllowed: maxFiles });\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n formData.append(fileInputName, file);\n const pendingFile = {\n id,\n filename: name,\n status: Status.PENDING,\n };\n\n addFileToList(pendingFile);\n\n // Start uploading the file\n onUploadFile(formData)\n .then(({ id, url, error }: UploadResponse) => {\n // Replace the temporary id with the final one received from the API, and also set any errors\n modifyFileInList(pendingFile, { id, url, error, status: Status.SUCCEEDED });\n })\n .catch((error) => {\n modifyFileInList(pendingFile, { error: error as UploadError, status: Status.FAILED });\n });\n\n if (!multiple) {\n // Only upload a single file\n break;\n }\n }\n }\n };\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n if (onFilesChange && mounted) {\n onFilesChange([...uploadedFiles]);\n }\n }, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <>\n <div\n role=\"group\"\n className={classNames('np-upload-input', className, { disabled })}\n {...inputAttributes}\n >\n {uploadedFiles.map((file) => (\n <UploadItem\n key={file.id}\n file={file}\n singleFileUpload={!multiple}\n canDelete={\n (!!onDeleteFile || file.status === Status.FAILED) &&\n (!file.status || !PROGRESS_STATUSES.has(file.status))\n }\n onDelete={\n file.status === Status.FAILED\n ? () => removeFile(file)\n : () => setMarkedFileForDelete(file)\n }\n onDownload={onDownload}\n />\n ))}\n {(multiple || (!multiple && !uploadedFiles.length)) && (\n <UploadButton\n id={id}\n uploadButtonTitle={uploadButtonTitle}\n disabled={areMaximumFilesUploadedAlready() || disabled}\n multiple={multiple}\n fileTypes={fileTypes}\n sizeLimit={sizeLimit}\n description={description}\n maxFiles={maxFiles}\n onChange={addFiles}\n />\n )}\n </div>\n <Modal\n title={\n deleteConfirm?.title !== undefined\n ? deleteConfirm.title\n : formatMessage(MESSAGES.deleteModalTitle)\n }\n body={\n deleteConfirm?.body !== undefined\n ? deleteConfirm.body\n : formatMessage(MESSAGES.deleteModalBody)\n }\n open={!!markedFileForDelete}\n footer={\n <>\n <Button\n block\n onClick={() => {\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.cancelText || formatMessage(MESSAGES.deleteModalCancelButtonText)}\n </Button>\n <Button\n block\n priority={Priority.SECONDARY}\n type={ControlType.NEGATIVE}\n onClick={() => {\n if (markedFileForDelete) {\n removeFile(markedFileForDelete);\n }\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.confirmText || formatMessage(MESSAGES.deleteModalConfirmButtonText)}\n </Button>\n </>\n }\n onClose={() => {\n setMarkedFileForDelete(null);\n }}\n />\n </>\n );\n};\n\nexport default UploadInput;\n"],"names":["generateFileId","file","name","size","uploadTimeStamp","Date","getTime","UploadInput","files","fileInputName","className","deleteConfirm","disabled","multiple","fileTypes","imageFileTypes","sizeLimit","DEFAULT_SIZE_LIMIT","description","onUploadFile","onDeleteFile","onValidationError","onFilesChange","onDownload","maxFiles","maxFilesErrorMessage","id","sizeLimitErrorMessage","uploadButtonTitle","inputAttributes","useInputAttributes","nonLabelable","markedFileForDelete","setMarkedFileForDelete","useState","mounted","setMounted","formatMessage","useIntl","PROGRESS_STATUSES","Set","Status","PENDING","PROCESSING","uploadedFiles","setUploadedFiles","length","uploadedFilesListReference","useRef","addFileToList","recentUploadedFile","addToList","listToAddTo","current","removeFileFromList","filterOutFrom","listToFilterFrom","filter","fileInList","modifyFileInList","updates","updateListItem","listToUpdate","map","removeFile","status","FAILED","error","undefined","then","catch","handleFileUploadFailure","failureMessage","failedUpload","filename","getNumberOfFilesUploaded","uploadInitiatedStatus","SUCCEEDED","validFiles","has","areMaximumFilesUploadedAlready","numberOfValidFiles","addFiles","selectedFiles","i","item","formData","FormData","allowedFileTypes","join","isTypeValid","MESSAGES","fileTypeNotSupported","isSizeValid","fileIsTooLarge","maximumFilesAlreadyUploaded","maxFilesAllowed","append","pendingFile","url","useEffect","_jsxs","_Fragment","children","role","classNames","_jsx","UploadItem","singleFileUpload","canDelete","onDelete","UploadButton","onChange","Modal","title","deleteModalTitle","body","deleteModalBody","open","footer","Button","block","onClick","cancelText","deleteModalCancelButtonText","priority","Priority","SECONDARY","type","ControlType","NEGATIVE","confirmText","deleteModalConfirmButtonText","onClose"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@ import { Field } from '../field/Field';
|
|
|
4
4
|
import { mockResizeObserver, render, screen } from '../test-utils';
|
|
5
5
|
import { Input } from './Input';
|
|
6
6
|
import { InputGroup } from './InputGroup';
|
|
7
|
+
import Button from '../button';
|
|
7
8
|
|
|
8
9
|
mockResizeObserver();
|
|
9
10
|
|
|
@@ -16,11 +17,15 @@ describe('InputGroup', () => {
|
|
|
16
17
|
content: <Search size={24} />,
|
|
17
18
|
initialContentWidth: 24,
|
|
18
19
|
}}
|
|
20
|
+
addonEnd={{
|
|
21
|
+
content: <Button>Go</Button>,
|
|
22
|
+
interactive: true,
|
|
23
|
+
}}
|
|
19
24
|
>
|
|
20
25
|
<Input />
|
|
21
26
|
</InputGroup>
|
|
22
27
|
</Field>,
|
|
23
28
|
);
|
|
24
|
-
expect(screen.
|
|
29
|
+
expect(screen.getByLabelText('Search…')).toHaveRole('textbox');
|
|
25
30
|
});
|
|
26
31
|
});
|
|
@@ -67,38 +67,23 @@ export function InputGroup({
|
|
|
67
67
|
className,
|
|
68
68
|
children,
|
|
69
69
|
}: InputGroupProps) {
|
|
70
|
-
const inputAttributes = useInputAttributes({ nonLabelable: true });
|
|
71
|
-
|
|
72
70
|
const [paddingStart, setPaddingStart] = useState(inputPaddingInitialState(addonStart));
|
|
73
71
|
const [paddingEnd, setPaddingEnd] = useState(inputPaddingInitialState(addonEnd));
|
|
74
72
|
|
|
75
73
|
return (
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
disabled={disabled}
|
|
90
|
-
className={classNames(className, 'np-input-group')}
|
|
91
|
-
>
|
|
92
|
-
{addonStart != null ? <InputAddon placement="start" {...addonStart} /> : null}
|
|
93
|
-
{children}
|
|
94
|
-
{addonEnd != null ? <InputAddon placement="end" {...addonEnd} /> : null}
|
|
95
|
-
</fieldset>
|
|
96
|
-
</InputPaddingEndContext.Provider>
|
|
97
|
-
</InputPaddingStartContext.Provider>
|
|
98
|
-
</InputInvalidProvider>
|
|
99
|
-
</InputDescribedByProvider>
|
|
100
|
-
</InputIdContextProvider>
|
|
101
|
-
</FieldLabelIdContextProvider>
|
|
74
|
+
<InputPaddingStartContext.Provider
|
|
75
|
+
value={useMemo(() => [paddingStart, setPaddingStart], [paddingStart])}
|
|
76
|
+
>
|
|
77
|
+
<InputPaddingEndContext.Provider
|
|
78
|
+
value={useMemo(() => [paddingEnd, setPaddingEnd], [paddingEnd])}
|
|
79
|
+
>
|
|
80
|
+
<fieldset disabled={disabled} className={classNames(className, 'np-input-group')}>
|
|
81
|
+
{addonStart != null ? <InputAddon placement="start" {...addonStart} /> : null}
|
|
82
|
+
{children}
|
|
83
|
+
{addonEnd != null ? <InputAddon placement="end" {...addonEnd} /> : null}
|
|
84
|
+
</fieldset>
|
|
85
|
+
</InputPaddingEndContext.Provider>
|
|
86
|
+
</InputPaddingStartContext.Provider>
|
|
102
87
|
);
|
|
103
88
|
}
|
|
104
89
|
|
|
@@ -143,22 +128,31 @@ function InputAddon({
|
|
|
143
128
|
});
|
|
144
129
|
|
|
145
130
|
return (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
131
|
+
/* Prevent nested controls from being labeled redundantly */
|
|
132
|
+
<FieldLabelIdContextProvider value={undefined}>
|
|
133
|
+
<InputIdContextProvider value={undefined}>
|
|
134
|
+
<InputDescribedByProvider value={undefined}>
|
|
135
|
+
<InputInvalidProvider value={undefined}>
|
|
136
|
+
<span
|
|
137
|
+
ref={ref}
|
|
138
|
+
className={classNames(
|
|
139
|
+
'np-input-addon',
|
|
140
|
+
{
|
|
141
|
+
'np-input-addon--placement-start': placement === 'start',
|
|
142
|
+
'np-input-addon--placement-end': placement === 'end',
|
|
143
|
+
},
|
|
144
|
+
interactive && 'np-input-addon--interactive',
|
|
145
|
+
{
|
|
146
|
+
'np-input-addon--padding-sm': padding === 'sm',
|
|
147
|
+
'np-input-addon--padding-md': padding === 'md',
|
|
148
|
+
},
|
|
149
|
+
)}
|
|
150
|
+
>
|
|
151
|
+
{content}
|
|
152
|
+
</span>
|
|
153
|
+
</InputInvalidProvider>
|
|
154
|
+
</InputDescribedByProvider>
|
|
155
|
+
</InputIdContextProvider>
|
|
156
|
+
</FieldLabelIdContextProvider>
|
|
163
157
|
);
|
|
164
158
|
}
|
|
@@ -214,6 +214,6 @@ describe('SelectInput', () => {
|
|
|
214
214
|
<SelectInput items={[{ type: 'option', value: 'USD' }]} value="USD" />
|
|
215
215
|
</Field>,
|
|
216
216
|
);
|
|
217
|
-
expect(screen.
|
|
217
|
+
expect(screen.getByLabelText('Currency')).toHaveAttribute('aria-haspopup');
|
|
218
218
|
});
|
|
219
219
|
});
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { within } from '@testing-library/react';
|
|
2
2
|
import { userEvent } from '@testing-library/user-event';
|
|
3
|
+
import { act } from 'react';
|
|
3
4
|
|
|
4
5
|
import { Status } from '../common';
|
|
6
|
+
import { Field } from '../field/Field';
|
|
5
7
|
import { mockMatchMedia, render, screen, waitFor, waitForElementToBeRemoved } from '../test-utils';
|
|
6
8
|
|
|
7
9
|
import UploadInput, { UploadInputProps } from './UploadInput';
|
|
8
10
|
import { TEST_IDS as UPLOAD_BUTTON_TEST_IDS } from './uploadButton/UploadButton';
|
|
9
11
|
import { TEST_IDS as UPLOAD_ITEM_TEST_IDS } from './uploadItem/UploadItem';
|
|
10
|
-
import { act } from 'react';
|
|
11
12
|
|
|
12
13
|
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTimeAsync });
|
|
13
14
|
|
|
@@ -310,4 +311,16 @@ describe('UploadInput', () => {
|
|
|
310
311
|
});
|
|
311
312
|
});
|
|
312
313
|
});
|
|
314
|
+
|
|
315
|
+
it('supports `Field` for error messages', () => {
|
|
316
|
+
render(
|
|
317
|
+
<Field message="Something went wrong" sentiment="negative">
|
|
318
|
+
<UploadInput {...props} />
|
|
319
|
+
</Field>,
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
const container = screen.getAllByRole('group')[0];
|
|
323
|
+
expect(container).toBeInvalid();
|
|
324
|
+
expect(container).toHaveAccessibleDescription('Something went wrong');
|
|
325
|
+
});
|
|
313
326
|
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { StoryFn, Meta } from '@storybook/react';
|
|
2
2
|
|
|
3
|
+
import { Field } from '../field/Field';
|
|
4
|
+
|
|
3
5
|
import UploadInput, { UploadInputProps } from './UploadInput';
|
|
4
6
|
import { UploadResponse } from './types';
|
|
5
7
|
|
|
@@ -44,3 +46,12 @@ SingleFile.args = { ...props };
|
|
|
44
46
|
|
|
45
47
|
export const MultipleFiles: Story = Template.bind({});
|
|
46
48
|
MultipleFiles.args = { ...props, multiple: true };
|
|
49
|
+
|
|
50
|
+
export const WithinField: Story = Template.bind({});
|
|
51
|
+
WithinField.decorators = [
|
|
52
|
+
(Story) => (
|
|
53
|
+
<Field message="Something went wrong" sentiment="negative">
|
|
54
|
+
<Story />
|
|
55
|
+
</Field>
|
|
56
|
+
),
|
|
57
|
+
];
|
|
@@ -4,6 +4,7 @@ import { useIntl } from 'react-intl';
|
|
|
4
4
|
|
|
5
5
|
import Button from '../button';
|
|
6
6
|
import { CommonProps, ControlType, Priority, Status } from '../common';
|
|
7
|
+
import { useInputAttributes } from '../inputs/contexts';
|
|
7
8
|
import Modal from '../modal';
|
|
8
9
|
import { isSizeValid } from '../upload/utils/isSizeValid';
|
|
9
10
|
import { isTypeValid } from '../upload/utils/isTypeValid';
|
|
@@ -127,6 +128,8 @@ const UploadInput = ({
|
|
|
127
128
|
sizeLimitErrorMessage,
|
|
128
129
|
uploadButtonTitle,
|
|
129
130
|
}: UploadInputProps) => {
|
|
131
|
+
const inputAttributes = useInputAttributes({ nonLabelable: true });
|
|
132
|
+
|
|
130
133
|
const [markedFileForDelete, setMarkedFileForDelete] = useState<UploadedFile | null>(null);
|
|
131
134
|
const [mounted, setMounted] = useState(false);
|
|
132
135
|
const { formatMessage } = useIntl();
|
|
@@ -299,7 +302,11 @@ const UploadInput = ({
|
|
|
299
302
|
|
|
300
303
|
return (
|
|
301
304
|
<>
|
|
302
|
-
<div
|
|
305
|
+
<div
|
|
306
|
+
role="group"
|
|
307
|
+
className={classNames('np-upload-input', className, { disabled })}
|
|
308
|
+
{...inputAttributes}
|
|
309
|
+
>
|
|
303
310
|
{uploadedFiles.map((file) => (
|
|
304
311
|
<UploadItem
|
|
305
312
|
key={file.id}
|