@faststore/components 3.98.0-dev.1 → 3.98.0-dev.8
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/dist/cjs/atoms/Link/Link.d.ts +1 -1
- package/dist/cjs/atoms/Link/Link.d.ts.map +1 -1
- package/dist/cjs/atoms/Link/Link.js.map +1 -1
- package/dist/cjs/atoms/List/List.d.ts.map +1 -1
- package/dist/cjs/atoms/List/List.js.map +1 -1
- package/dist/cjs/hooks/index.d.ts +7 -3
- package/dist/cjs/hooks/index.d.ts.map +1 -1
- package/dist/cjs/hooks/index.js +12 -6
- package/dist/cjs/hooks/index.js.map +1 -1
- package/dist/cjs/hooks/useCSVParser.d.ts +43 -0
- package/dist/cjs/hooks/useCSVParser.d.ts.map +1 -0
- package/dist/cjs/hooks/useCSVParser.js +264 -0
- package/dist/cjs/hooks/useCSVParser.js.map +1 -0
- package/dist/cjs/hooks/useFileUpload.d.ts +26 -0
- package/dist/cjs/hooks/useFileUpload.d.ts.map +1 -0
- package/dist/cjs/hooks/useFileUpload.js +68 -0
- package/dist/cjs/hooks/useFileUpload.js.map +1 -0
- package/dist/cjs/index.d.ts +58 -50
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +47 -32
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/molecules/Accordion/AccordionItem.d.ts.map +1 -1
- package/dist/cjs/molecules/Accordion/AccordionItem.js.map +1 -1
- package/dist/cjs/molecules/Dropzone/Dropzone.d.ts +87 -0
- package/dist/cjs/molecules/Dropzone/Dropzone.d.ts.map +1 -0
- package/dist/cjs/molecules/Dropzone/Dropzone.js +85 -0
- package/dist/cjs/molecules/Dropzone/Dropzone.js.map +1 -0
- package/dist/cjs/molecules/Dropzone/index.d.ts +3 -0
- package/dist/cjs/molecules/Dropzone/index.d.ts.map +1 -0
- package/dist/cjs/molecules/Dropzone/index.js +9 -0
- package/dist/cjs/molecules/Dropzone/index.js.map +1 -0
- package/dist/cjs/molecules/FileUploadCard/FileUploadCard.d.ts +113 -0
- package/dist/cjs/molecules/FileUploadCard/FileUploadCard.d.ts.map +1 -0
- package/dist/cjs/molecules/FileUploadCard/FileUploadCard.js +169 -0
- package/dist/cjs/molecules/FileUploadCard/FileUploadCard.js.map +1 -0
- package/dist/cjs/molecules/FileUploadCard/index.d.ts +3 -0
- package/dist/cjs/molecules/FileUploadCard/index.d.ts.map +1 -0
- package/dist/cjs/molecules/FileUploadCard/index.js +9 -0
- package/dist/cjs/molecules/FileUploadCard/index.js.map +1 -0
- package/dist/cjs/molecules/FileUploadStatus/FileUploadStatus.d.ts +93 -0
- package/dist/cjs/molecules/FileUploadStatus/FileUploadStatus.d.ts.map +1 -0
- package/dist/cjs/molecules/FileUploadStatus/FileUploadStatus.js +77 -0
- package/dist/cjs/molecules/FileUploadStatus/FileUploadStatus.js.map +1 -0
- package/dist/cjs/molecules/FileUploadStatus/index.d.ts +3 -0
- package/dist/cjs/molecules/FileUploadStatus/index.d.ts.map +1 -0
- package/dist/cjs/molecules/FileUploadStatus/index.js +11 -0
- package/dist/cjs/molecules/FileUploadStatus/index.js.map +1 -0
- package/dist/cjs/molecules/SearchInputField/SearchInputField.d.ts +23 -1
- package/dist/cjs/molecules/SearchInputField/SearchInputField.d.ts.map +1 -1
- package/dist/cjs/molecules/SearchInputField/SearchInputField.js +9 -4
- package/dist/cjs/molecules/SearchInputField/SearchInputField.js.map +1 -1
- package/dist/cjs/molecules/SearchProducts/SearchProductItem.d.ts +1 -1
- package/dist/cjs/molecules/SearchProducts/SearchProductItem.d.ts.map +1 -1
- package/dist/cjs/molecules/SearchProducts/SearchProductItem.js +2 -2
- package/dist/cjs/molecules/SearchProducts/SearchProductItem.js.map +1 -1
- package/dist/cjs/molecules/SearchProvider/SearchProvider.d.ts +5 -1
- package/dist/cjs/molecules/SearchProvider/SearchProvider.d.ts.map +1 -1
- package/dist/cjs/molecules/SearchProvider/SearchProvider.js +2 -2
- package/dist/cjs/molecules/SearchProvider/SearchProvider.js.map +1 -1
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawer.d.ts +24 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawer.d.ts.map +1 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawer.js +14 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawer.js.map +1 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.d.ts +16 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.d.ts.map +1 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.js +37 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.js.map +1 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.d.ts +9 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.d.ts.map +1 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.js +24 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.js.map +1 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.d.ts +35 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.d.ts.map +1 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.js +91 -0
- package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.js.map +1 -0
- package/dist/cjs/organisms/QuickOrderDrawer/index.d.ts +11 -0
- package/dist/cjs/organisms/QuickOrderDrawer/index.d.ts.map +1 -0
- package/dist/cjs/organisms/QuickOrderDrawer/index.js +18 -0
- package/dist/cjs/organisms/QuickOrderDrawer/index.js.map +1 -0
- package/dist/cjs/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.d.ts +61 -0
- package/dist/cjs/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.d.ts.map +1 -0
- package/dist/cjs/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.js +86 -0
- package/dist/cjs/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.js.map +1 -0
- package/dist/cjs/organisms/SearchInput/SearchInput.d.ts +8 -0
- package/dist/cjs/organisms/SearchInput/SearchInput.d.ts.map +1 -1
- package/dist/cjs/organisms/SearchInput/SearchInput.js +2 -2
- package/dist/cjs/organisms/SearchInput/SearchInput.js.map +1 -1
- package/dist/esm/atoms/Link/Link.d.ts +1 -1
- package/dist/esm/atoms/Link/Link.d.ts.map +1 -1
- package/dist/esm/atoms/Link/Link.js.map +1 -1
- package/dist/esm/atoms/List/List.d.ts.map +1 -1
- package/dist/esm/atoms/List/List.js.map +1 -1
- package/dist/esm/hooks/index.d.ts +7 -3
- package/dist/esm/hooks/index.d.ts.map +1 -1
- package/dist/esm/hooks/index.js +6 -3
- package/dist/esm/hooks/index.js.map +1 -1
- package/dist/esm/hooks/useCSVParser.d.ts +43 -0
- package/dist/esm/hooks/useCSVParser.d.ts.map +1 -0
- package/dist/esm/hooks/useCSVParser.js +259 -0
- package/dist/esm/hooks/useCSVParser.js.map +1 -0
- package/dist/esm/hooks/useFileUpload.d.ts +26 -0
- package/dist/esm/hooks/useFileUpload.d.ts.map +1 -0
- package/dist/esm/hooks/useFileUpload.js +64 -0
- package/dist/esm/hooks/useFileUpload.js.map +1 -0
- package/dist/esm/index.d.ts +58 -50
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +24 -20
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/molecules/Accordion/AccordionItem.d.ts.map +1 -1
- package/dist/esm/molecules/Accordion/AccordionItem.js.map +1 -1
- package/dist/esm/molecules/Dropzone/Dropzone.d.ts +87 -0
- package/dist/esm/molecules/Dropzone/Dropzone.d.ts.map +1 -0
- package/dist/esm/molecules/Dropzone/Dropzone.js +82 -0
- package/dist/esm/molecules/Dropzone/Dropzone.js.map +1 -0
- package/dist/esm/molecules/Dropzone/index.d.ts +3 -0
- package/dist/esm/molecules/Dropzone/index.d.ts.map +1 -0
- package/dist/esm/molecules/Dropzone/index.js +2 -0
- package/dist/esm/molecules/Dropzone/index.js.map +1 -0
- package/dist/esm/molecules/FileUploadCard/FileUploadCard.d.ts +113 -0
- package/dist/esm/molecules/FileUploadCard/FileUploadCard.d.ts.map +1 -0
- package/dist/esm/molecules/FileUploadCard/FileUploadCard.js +166 -0
- package/dist/esm/molecules/FileUploadCard/FileUploadCard.js.map +1 -0
- package/dist/esm/molecules/FileUploadCard/index.d.ts +3 -0
- package/dist/esm/molecules/FileUploadCard/index.d.ts.map +1 -0
- package/dist/esm/molecules/FileUploadCard/index.js +2 -0
- package/dist/esm/molecules/FileUploadCard/index.js.map +1 -0
- package/dist/esm/molecules/FileUploadStatus/FileUploadStatus.d.ts +93 -0
- package/dist/esm/molecules/FileUploadStatus/FileUploadStatus.d.ts.map +1 -0
- package/dist/esm/molecules/FileUploadStatus/FileUploadStatus.js +73 -0
- package/dist/esm/molecules/FileUploadStatus/FileUploadStatus.js.map +1 -0
- package/dist/esm/molecules/FileUploadStatus/index.d.ts +3 -0
- package/dist/esm/molecules/FileUploadStatus/index.d.ts.map +1 -0
- package/dist/esm/molecules/FileUploadStatus/index.js +2 -0
- package/dist/esm/molecules/FileUploadStatus/index.js.map +1 -0
- package/dist/esm/molecules/SearchInputField/SearchInputField.d.ts +23 -1
- package/dist/esm/molecules/SearchInputField/SearchInputField.d.ts.map +1 -1
- package/dist/esm/molecules/SearchInputField/SearchInputField.js +9 -4
- package/dist/esm/molecules/SearchInputField/SearchInputField.js.map +1 -1
- package/dist/esm/molecules/SearchProducts/SearchProductItem.d.ts +1 -1
- package/dist/esm/molecules/SearchProducts/SearchProductItem.d.ts.map +1 -1
- package/dist/esm/molecules/SearchProducts/SearchProductItem.js +2 -2
- package/dist/esm/molecules/SearchProducts/SearchProductItem.js.map +1 -1
- package/dist/esm/molecules/SearchProvider/SearchProvider.d.ts +5 -1
- package/dist/esm/molecules/SearchProvider/SearchProvider.d.ts.map +1 -1
- package/dist/esm/molecules/SearchProvider/SearchProvider.js +2 -2
- package/dist/esm/molecules/SearchProvider/SearchProvider.js.map +1 -1
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawer.d.ts +24 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawer.d.ts.map +1 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawer.js +11 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawer.js.map +1 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.d.ts +16 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.d.ts.map +1 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.js +34 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.js.map +1 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.d.ts +9 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.d.ts.map +1 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.js +21 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.js.map +1 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.d.ts +35 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.d.ts.map +1 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.js +88 -0
- package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.js.map +1 -0
- package/dist/esm/organisms/QuickOrderDrawer/index.d.ts +11 -0
- package/dist/esm/organisms/QuickOrderDrawer/index.d.ts.map +1 -0
- package/dist/esm/organisms/QuickOrderDrawer/index.js +6 -0
- package/dist/esm/organisms/QuickOrderDrawer/index.js.map +1 -0
- package/dist/esm/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.d.ts +61 -0
- package/dist/esm/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.d.ts.map +1 -0
- package/dist/esm/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.js +80 -0
- package/dist/esm/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.js.map +1 -0
- package/dist/esm/organisms/SearchInput/SearchInput.d.ts +8 -0
- package/dist/esm/organisms/SearchInput/SearchInput.d.ts.map +1 -1
- package/dist/esm/organisms/SearchInput/SearchInput.js +2 -2
- package/dist/esm/organisms/SearchInput/SearchInput.js.map +1 -1
- package/package.json +5 -2
- package/src/atoms/Link/Link.tsx +4 -1
- package/src/atoms/List/List.tsx +18 -16
- package/src/hooks/index.ts +11 -3
- package/src/hooks/useCSVParser.ts +367 -0
- package/src/hooks/useFileUpload.ts +88 -0
- package/src/index.ts +97 -66
- package/src/molecules/Accordion/AccordionItem.tsx +4 -3
- package/src/molecules/Dropzone/Dropzone.tsx +248 -0
- package/src/molecules/Dropzone/index.ts +2 -0
- package/src/molecules/FileUploadCard/FileUploadCard.tsx +406 -0
- package/src/molecules/FileUploadCard/index.tsx +2 -0
- package/src/molecules/FileUploadStatus/FileUploadStatus.tsx +258 -0
- package/src/molecules/FileUploadStatus/index.tsx +6 -0
- package/src/molecules/SearchInputField/SearchInputField.tsx +72 -23
- package/src/molecules/SearchProducts/SearchProductItem.tsx +8 -3
- package/src/molecules/SearchProvider/SearchProvider.tsx +6 -1
- package/src/organisms/QuickOrderDrawer/QuickOrderDrawer.tsx +58 -0
- package/src/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.tsx +72 -0
- package/src/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.tsx +43 -0
- package/src/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.tsx +323 -0
- package/src/organisms/QuickOrderDrawer/index.ts +19 -0
- package/src/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.tsx +205 -0
- package/src/organisms/SearchInput/SearchInput.tsx +6 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import { Button, Icon } from '../..'
|
|
5
|
+
|
|
6
|
+
export enum FileUploadState {
|
|
7
|
+
Uploading = 'uploading',
|
|
8
|
+
Completed = 'completed',
|
|
9
|
+
Error = 'error',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export enum FileUploadErrorType {
|
|
13
|
+
Unexpected = 'unexpected',
|
|
14
|
+
Unsupported = 'unsupported',
|
|
15
|
+
Unreadable = 'unreadable',
|
|
16
|
+
InvalidStructure = 'invalid-structure',
|
|
17
|
+
Empty = 'empty',
|
|
18
|
+
TooLarge = 'too-large',
|
|
19
|
+
NoProductsFound = 'no-products-found',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface FileUploadStatusProps extends HTMLAttributes<HTMLDivElement> {
|
|
23
|
+
/**
|
|
24
|
+
* ID to find this component in testing tools (e.g.: cypress, testing library, and jest).
|
|
25
|
+
*/
|
|
26
|
+
testId?: string
|
|
27
|
+
/**
|
|
28
|
+
* The file being uploaded.
|
|
29
|
+
*/
|
|
30
|
+
file: File
|
|
31
|
+
/**
|
|
32
|
+
* Current upload state.
|
|
33
|
+
* @default 'uploading'
|
|
34
|
+
*/
|
|
35
|
+
state?: FileUploadState
|
|
36
|
+
/**
|
|
37
|
+
* Type of error when state is 'error'.
|
|
38
|
+
*/
|
|
39
|
+
errorType?: FileUploadErrorType
|
|
40
|
+
/**
|
|
41
|
+
* Custom error message. If provided, overrides the default error message for the errorType.
|
|
42
|
+
*/
|
|
43
|
+
errorMessage?: string
|
|
44
|
+
/**
|
|
45
|
+
* Callback when the remove/cancel button is clicked.
|
|
46
|
+
*/
|
|
47
|
+
onRemove?: () => void
|
|
48
|
+
/**
|
|
49
|
+
* Callback when the search button is clicked (only shown when state is 'completed').
|
|
50
|
+
*/
|
|
51
|
+
onSearch?: () => void
|
|
52
|
+
/**
|
|
53
|
+
* Callback when download template is clicked (only shown when state is 'error').
|
|
54
|
+
*/
|
|
55
|
+
onDownloadTemplate?: () => void
|
|
56
|
+
/**
|
|
57
|
+
* Callback when select file is clicked (only shown when state is 'error').
|
|
58
|
+
*/
|
|
59
|
+
onSelectFile?: () => void
|
|
60
|
+
/**
|
|
61
|
+
* Aria-label for the remove button (e.g. from CMS).
|
|
62
|
+
*/
|
|
63
|
+
removeButtonAriaLabel: string
|
|
64
|
+
/**
|
|
65
|
+
* Label for the search button when state is 'completed' (e.g. from CMS).
|
|
66
|
+
*/
|
|
67
|
+
searchButtonLabel: string
|
|
68
|
+
/**
|
|
69
|
+
* Label for the download template button (e.g. from CMS).
|
|
70
|
+
*/
|
|
71
|
+
downloadTemplateButtonLabel: string
|
|
72
|
+
/**
|
|
73
|
+
* Label for the select file button (e.g. from CMS).
|
|
74
|
+
*/
|
|
75
|
+
selectFileButtonLabel: string
|
|
76
|
+
/**
|
|
77
|
+
* Error messages per error type (e.g. from CMS). Required when state is Error to show messages.
|
|
78
|
+
*/
|
|
79
|
+
errorMessages: Partial<
|
|
80
|
+
Record<FileUploadErrorType, { title: string; description: string }>
|
|
81
|
+
>
|
|
82
|
+
/**
|
|
83
|
+
* Status text when state is Uploading (e.g. from CMS).
|
|
84
|
+
*/
|
|
85
|
+
uploadingStatusText: string
|
|
86
|
+
/**
|
|
87
|
+
* Status text when state is Completed (e.g. from CMS). May include file size.
|
|
88
|
+
*/
|
|
89
|
+
completedStatusText: string
|
|
90
|
+
/**
|
|
91
|
+
* Custom file name display (optional).
|
|
92
|
+
*/
|
|
93
|
+
fileName?: string
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const FileUploadStatus = ({
|
|
97
|
+
testId = 'fs-file-upload-status',
|
|
98
|
+
file,
|
|
99
|
+
state = FileUploadState.Uploading,
|
|
100
|
+
errorType,
|
|
101
|
+
errorMessage,
|
|
102
|
+
onRemove,
|
|
103
|
+
onSearch,
|
|
104
|
+
onDownloadTemplate,
|
|
105
|
+
onSelectFile,
|
|
106
|
+
removeButtonAriaLabel,
|
|
107
|
+
searchButtonLabel,
|
|
108
|
+
downloadTemplateButtonLabel,
|
|
109
|
+
selectFileButtonLabel,
|
|
110
|
+
errorMessages,
|
|
111
|
+
uploadingStatusText,
|
|
112
|
+
completedStatusText,
|
|
113
|
+
fileName,
|
|
114
|
+
...otherProps
|
|
115
|
+
}: FileUploadStatusProps) => {
|
|
116
|
+
const getErrorMessage = (): { title: string; description: string } => {
|
|
117
|
+
if (errorMessage) {
|
|
118
|
+
return { title: errorMessage, description: '' }
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (errorType && errorMessages?.[errorType]) {
|
|
122
|
+
return errorMessages[errorType]!
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
errorMessages?.[FileUploadErrorType.Unexpected] ?? {
|
|
127
|
+
title: '',
|
|
128
|
+
description: '',
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const getStatusText = (): string => {
|
|
134
|
+
switch (state) {
|
|
135
|
+
case FileUploadState.Uploading:
|
|
136
|
+
return uploadingStatusText
|
|
137
|
+
case FileUploadState.Completed:
|
|
138
|
+
return completedStatusText
|
|
139
|
+
default:
|
|
140
|
+
return ''
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const getIcon = () => {
|
|
145
|
+
switch (state) {
|
|
146
|
+
case FileUploadState.Uploading:
|
|
147
|
+
return (
|
|
148
|
+
<div data-fs-file-upload-status-icon-loading>
|
|
149
|
+
<Icon name="CircleNotch" width={24} height={24} strokeWidth={5} />
|
|
150
|
+
</div>
|
|
151
|
+
)
|
|
152
|
+
case FileUploadState.Completed:
|
|
153
|
+
return (
|
|
154
|
+
<div data-fs-file-upload-status-icon-completed>
|
|
155
|
+
<Icon name="Table" width={24} height={24} strokeWidth={5} />
|
|
156
|
+
</div>
|
|
157
|
+
)
|
|
158
|
+
case FileUploadState.Error:
|
|
159
|
+
return (
|
|
160
|
+
<div data-fs-file-upload-status-icon-error>
|
|
161
|
+
<Icon
|
|
162
|
+
name="WarningOctagon"
|
|
163
|
+
width={24}
|
|
164
|
+
height={24}
|
|
165
|
+
strokeWidth={5}
|
|
166
|
+
/>
|
|
167
|
+
</div>
|
|
168
|
+
)
|
|
169
|
+
default:
|
|
170
|
+
return null
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return (
|
|
175
|
+
<div
|
|
176
|
+
data-fs-file-upload-status
|
|
177
|
+
data-fs-file-upload-status-state={state}
|
|
178
|
+
data-testid={testId}
|
|
179
|
+
{...otherProps}
|
|
180
|
+
>
|
|
181
|
+
<div
|
|
182
|
+
data-fs-file-upload-status-file-info
|
|
183
|
+
data-fs-file-upload-state={state}
|
|
184
|
+
>
|
|
185
|
+
<div data-fs-file-upload-status-icon>{getIcon()}</div>
|
|
186
|
+
|
|
187
|
+
<div data-fs-file-upload-status-details>
|
|
188
|
+
{state === FileUploadState.Error ? (
|
|
189
|
+
<>
|
|
190
|
+
<p data-fs-file-upload-status-text-error>
|
|
191
|
+
{getErrorMessage().title}
|
|
192
|
+
</p>
|
|
193
|
+
<p data-fs-file-upload-status-text-error>
|
|
194
|
+
{getErrorMessage().description}
|
|
195
|
+
</p>
|
|
196
|
+
</>
|
|
197
|
+
) : (
|
|
198
|
+
<>
|
|
199
|
+
<p data-fs-file-upload-status-filename>{fileName ?? file.name}</p>
|
|
200
|
+
<p data-fs-file-upload-status-text>{getStatusText()}</p>
|
|
201
|
+
</>
|
|
202
|
+
)}
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
{onRemove && (
|
|
206
|
+
<Button
|
|
207
|
+
type="button"
|
|
208
|
+
onClick={onRemove}
|
|
209
|
+
data-fs-file-upload-status-remove
|
|
210
|
+
aria-label={removeButtonAriaLabel}
|
|
211
|
+
>
|
|
212
|
+
<Icon name="X" width={16} height={16} />
|
|
213
|
+
</Button>
|
|
214
|
+
)}
|
|
215
|
+
</div>
|
|
216
|
+
{state === FileUploadState.Completed && onSearch && (
|
|
217
|
+
<Button
|
|
218
|
+
type="button"
|
|
219
|
+
variant="primary"
|
|
220
|
+
size="regular"
|
|
221
|
+
onClick={onSearch}
|
|
222
|
+
data-fs-file-upload-status-search-button
|
|
223
|
+
>
|
|
224
|
+
{searchButtonLabel}
|
|
225
|
+
</Button>
|
|
226
|
+
)}
|
|
227
|
+
|
|
228
|
+
{state === FileUploadState.Error && (
|
|
229
|
+
<div data-fs-file-upload-status-error-actions>
|
|
230
|
+
{onDownloadTemplate && (
|
|
231
|
+
<Button
|
|
232
|
+
type="button"
|
|
233
|
+
variant="secondary"
|
|
234
|
+
size="regular"
|
|
235
|
+
onClick={onDownloadTemplate}
|
|
236
|
+
data-fs-file-upload-status-download-button
|
|
237
|
+
>
|
|
238
|
+
{downloadTemplateButtonLabel}
|
|
239
|
+
</Button>
|
|
240
|
+
)}
|
|
241
|
+
{onSelectFile && (
|
|
242
|
+
<Button
|
|
243
|
+
type="button"
|
|
244
|
+
variant="primary"
|
|
245
|
+
size="regular"
|
|
246
|
+
onClick={onSelectFile}
|
|
247
|
+
data-fs-file-upload-status-select-button
|
|
248
|
+
>
|
|
249
|
+
{selectFileButtonLabel}
|
|
250
|
+
</Button>
|
|
251
|
+
)}
|
|
252
|
+
</div>
|
|
253
|
+
)}
|
|
254
|
+
</div>
|
|
255
|
+
)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export default FileUploadStatus
|
|
@@ -14,6 +14,7 @@ type ButtonProps = {
|
|
|
14
14
|
onClick?: () => void
|
|
15
15
|
testId?: string
|
|
16
16
|
}
|
|
17
|
+
|
|
17
18
|
export interface SearchInputFieldProps extends InputProps {
|
|
18
19
|
/**
|
|
19
20
|
* ID to find this component in testing tools (e.g.: cypress, testing library, and jest).
|
|
@@ -29,7 +30,29 @@ export interface SearchInputFieldProps extends InputProps {
|
|
|
29
30
|
*/
|
|
30
31
|
buttonIcon?: ReactNode
|
|
31
32
|
/**
|
|
32
|
-
*
|
|
33
|
+
* Whether to show the attachment button.
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
showAttachmentButton?: boolean
|
|
37
|
+
/**
|
|
38
|
+
* Props for the paperclip button inside the input.
|
|
39
|
+
*/
|
|
40
|
+
attachmentButtonProps?: ButtonProps
|
|
41
|
+
/**
|
|
42
|
+
* Aria-label for the attachment button (e.g. from CMS).
|
|
43
|
+
*/
|
|
44
|
+
attachmentButtonAriaLabel?: string
|
|
45
|
+
/**
|
|
46
|
+
* Aria-label for the submit button (e.g. from CMS).
|
|
47
|
+
*/
|
|
48
|
+
submitButtonAriaLabel?: string
|
|
49
|
+
/**
|
|
50
|
+
* A React component that will be rendered as an icon (attachment button).
|
|
51
|
+
* @default <Icon name="Paperclip" />
|
|
52
|
+
*/
|
|
53
|
+
attachmentButtonIcon?: ReactNode
|
|
54
|
+
/**
|
|
55
|
+
* Aria-label for the search input (e.g. from CMS).
|
|
33
56
|
*/
|
|
34
57
|
'aria-label'?: AriaAttributes['aria-label']
|
|
35
58
|
/**
|
|
@@ -50,7 +73,12 @@ const SearchInputField = forwardRef<
|
|
|
50
73
|
{
|
|
51
74
|
onSubmit,
|
|
52
75
|
buttonIcon,
|
|
53
|
-
|
|
76
|
+
showAttachmentButton = false,
|
|
77
|
+
attachmentButtonAriaLabel,
|
|
78
|
+
attachmentButtonIcon,
|
|
79
|
+
attachmentButtonProps,
|
|
80
|
+
submitButtonAriaLabel,
|
|
81
|
+
'aria-label': ariaLabel,
|
|
54
82
|
testId = 'fs-search-input',
|
|
55
83
|
buttonProps,
|
|
56
84
|
...otherProps
|
|
@@ -74,27 +102,48 @@ const SearchInputField = forwardRef<
|
|
|
74
102
|
}))
|
|
75
103
|
|
|
76
104
|
return (
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
105
|
+
<div data-fs-search-input-field-wrapper>
|
|
106
|
+
<form
|
|
107
|
+
ref={formRef}
|
|
108
|
+
data-fs-search-input-field
|
|
109
|
+
data-testid={testId}
|
|
110
|
+
onSubmit={handleSubmit}
|
|
111
|
+
role="search"
|
|
112
|
+
>
|
|
113
|
+
<Input
|
|
114
|
+
ref={inputRef}
|
|
115
|
+
aria-label={ariaLabel}
|
|
116
|
+
data-fs-search-input-field-input
|
|
117
|
+
{...otherProps}
|
|
118
|
+
/>
|
|
119
|
+
|
|
120
|
+
<div data-fs-search-input-field-actions>
|
|
121
|
+
{showAttachmentButton && (
|
|
122
|
+
<>
|
|
123
|
+
<IconButton
|
|
124
|
+
type="button"
|
|
125
|
+
aria-label={attachmentButtonAriaLabel}
|
|
126
|
+
icon={attachmentButtonIcon ?? <Icon name="Paperclip" />}
|
|
127
|
+
size="small"
|
|
128
|
+
data-fs-search-input-field-attachment-button
|
|
129
|
+
{...attachmentButtonProps}
|
|
130
|
+
/>
|
|
131
|
+
|
|
132
|
+
<span data-fs-search-input-field-separator />
|
|
133
|
+
</>
|
|
134
|
+
)}
|
|
135
|
+
|
|
136
|
+
<IconButton
|
|
137
|
+
type="submit"
|
|
138
|
+
aria-label={submitButtonAriaLabel}
|
|
139
|
+
icon={buttonIcon ?? <Icon name="MagnifyingGlass" />}
|
|
140
|
+
size="small"
|
|
141
|
+
data-fs-search-input-field-submit-button
|
|
142
|
+
{...buttonProps}
|
|
143
|
+
/>
|
|
144
|
+
</div>
|
|
145
|
+
</form>
|
|
146
|
+
</div>
|
|
98
147
|
)
|
|
99
148
|
})
|
|
100
149
|
|
|
@@ -3,7 +3,7 @@ import React, { forwardRef } from 'react'
|
|
|
3
3
|
|
|
4
4
|
import { Link, type LinkElementType, type LinkProps } from '../..'
|
|
5
5
|
|
|
6
|
-
export interface SearchProductItemProps extends HTMLAttributes<
|
|
6
|
+
export interface SearchProductItemProps extends HTMLAttributes<HTMLLIElement> {
|
|
7
7
|
/**
|
|
8
8
|
* ID to find this component in testing tools (e.g.: cypress,
|
|
9
9
|
* testing-library, and jest).
|
|
@@ -17,11 +17,16 @@ export interface SearchProductItemProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
17
17
|
|
|
18
18
|
const SearchProductItem = forwardRef<HTMLLIElement, SearchProductItemProps>(
|
|
19
19
|
function ProductItem(
|
|
20
|
-
{ testId = 'fs-search-product-item', linkProps, children },
|
|
20
|
+
{ testId = 'fs-search-product-item', linkProps, children, ...otherProps },
|
|
21
21
|
ref
|
|
22
22
|
) {
|
|
23
23
|
return (
|
|
24
|
-
<li
|
|
24
|
+
<li
|
|
25
|
+
ref={ref}
|
|
26
|
+
data-fs-search-product-item
|
|
27
|
+
data-testid={testId}
|
|
28
|
+
{...otherProps}
|
|
29
|
+
>
|
|
25
30
|
<Link {...linkProps} data-fs-search-product-item-link variant="display">
|
|
26
31
|
{children}
|
|
27
32
|
</Link>
|
|
@@ -23,6 +23,10 @@ export interface SearchProviderContextValue {
|
|
|
23
23
|
* Callback function when a search term is selected.
|
|
24
24
|
*/
|
|
25
25
|
onSearchSelection?: (term: string, path: string) => void
|
|
26
|
+
/**
|
|
27
|
+
* Search result searchId.
|
|
28
|
+
*/
|
|
29
|
+
searchId?: string
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
export const SearchContext = createContext<SearchProviderContextValue | null>(
|
|
@@ -36,10 +40,11 @@ function SearchProvider({
|
|
|
36
40
|
terms,
|
|
37
41
|
products,
|
|
38
42
|
isLoading,
|
|
43
|
+
searchId,
|
|
39
44
|
}: PropsWithChildren<SearchProviderContextValue>) {
|
|
40
45
|
return (
|
|
41
46
|
<SearchContext.Provider
|
|
42
|
-
value={{ onSearchSelection, term, terms, products, isLoading }}
|
|
47
|
+
value={{ onSearchSelection, term, terms, products, isLoading, searchId }}
|
|
43
48
|
>
|
|
44
49
|
{children}
|
|
45
50
|
</SearchContext.Provider>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React, { type PropsWithChildren } from 'react'
|
|
2
|
+
import type { OverlayProps } from '../../atoms/Overlay'
|
|
3
|
+
import { useFadeEffect } from '../../hooks'
|
|
4
|
+
import SlideOver from '../SlideOver/SlideOver'
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
QuickOrderDrawerProvider,
|
|
8
|
+
type QuickOrderDrawerProviderProps,
|
|
9
|
+
} from './provider/QuickOrderDrawerProvider'
|
|
10
|
+
|
|
11
|
+
export type QuickOrderDrawerProps = {
|
|
12
|
+
/**
|
|
13
|
+
* ID to find this component in testing tools (e.g.: cypress, testing library, and jest).
|
|
14
|
+
*/
|
|
15
|
+
testId?: string
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Controls the state
|
|
19
|
+
*/
|
|
20
|
+
isOpen: boolean
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Props forwarded to the `Overlay` component.
|
|
24
|
+
*/
|
|
25
|
+
overlayProps?: OverlayProps
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Props forwarded to the `QuickOrderDrawerProvider` component.
|
|
29
|
+
*/
|
|
30
|
+
providerProps?: Omit<QuickOrderDrawerProviderProps, 'children'>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const QuickOrderDrawer = ({
|
|
34
|
+
testId = 'fs-quick-order-drawer',
|
|
35
|
+
isOpen,
|
|
36
|
+
overlayProps,
|
|
37
|
+
providerProps,
|
|
38
|
+
children,
|
|
39
|
+
}: PropsWithChildren<QuickOrderDrawerProps>) => {
|
|
40
|
+
const { fade } = useFadeEffect()
|
|
41
|
+
return (
|
|
42
|
+
<QuickOrderDrawerProvider {...providerProps}>
|
|
43
|
+
<SlideOver
|
|
44
|
+
testId={testId}
|
|
45
|
+
fade={fade}
|
|
46
|
+
isOpen={isOpen}
|
|
47
|
+
size="partial"
|
|
48
|
+
direction="rightSide"
|
|
49
|
+
overlayProps={overlayProps}
|
|
50
|
+
data-fs-quick-order-drawer
|
|
51
|
+
>
|
|
52
|
+
{children}
|
|
53
|
+
</SlideOver>
|
|
54
|
+
</QuickOrderDrawerProvider>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default QuickOrderDrawer
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import Button from '../../atoms/Button'
|
|
3
|
+
import Icon from '../../atoms/Icon'
|
|
4
|
+
import Price, { type PriceFormatter } from '../../atoms/Price'
|
|
5
|
+
import { useQuickOrderDrawer } from './provider/QuickOrderDrawerProvider'
|
|
6
|
+
|
|
7
|
+
export type QuickOrderDrawerFooterProps = {
|
|
8
|
+
formatter?: PriceFormatter
|
|
9
|
+
/**
|
|
10
|
+
* Text labels for CMS configuration
|
|
11
|
+
*/
|
|
12
|
+
labels?: {
|
|
13
|
+
itemsLabel?: string
|
|
14
|
+
addToCartLabel?: string
|
|
15
|
+
addToCartAriaLabel?: string
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const QuickOrderDrawerFooter = ({
|
|
20
|
+
formatter,
|
|
21
|
+
labels,
|
|
22
|
+
}: QuickOrderDrawerFooterProps) => {
|
|
23
|
+
const [loading, setLoading] = useState(false)
|
|
24
|
+
const {
|
|
25
|
+
itemsCount,
|
|
26
|
+
totalPrice,
|
|
27
|
+
onAddToCart,
|
|
28
|
+
formatter: contextFormatter,
|
|
29
|
+
} = useQuickOrderDrawer()
|
|
30
|
+
const priceFormatter = formatter || contextFormatter
|
|
31
|
+
const { itemsLabel, addToCartLabel, addToCartAriaLabel } = labels || {}
|
|
32
|
+
|
|
33
|
+
const handleAddToCart = async () => {
|
|
34
|
+
if (itemsCount === 0) return
|
|
35
|
+
setLoading(true)
|
|
36
|
+
try {
|
|
37
|
+
onAddToCart()
|
|
38
|
+
} finally {
|
|
39
|
+
setLoading(false)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<div data-fs-quick-order-drawer-footer>
|
|
45
|
+
<div data-fs-quick-order-drawer-footer-items>
|
|
46
|
+
<Icon name="Inventory" width={24} height={24} />
|
|
47
|
+
<span>
|
|
48
|
+
{itemsCount} {itemsLabel || ''}
|
|
49
|
+
</span>
|
|
50
|
+
</div>
|
|
51
|
+
<div data-fs-quick-order-drawer-footer-actions>
|
|
52
|
+
<Price
|
|
53
|
+
value={totalPrice}
|
|
54
|
+
variant="selling"
|
|
55
|
+
formatter={priceFormatter}
|
|
56
|
+
/>
|
|
57
|
+
<Button
|
|
58
|
+
data-fs-quick-order-drawer-add-to-cart-btn
|
|
59
|
+
variant="primary"
|
|
60
|
+
disabled={itemsCount === 0}
|
|
61
|
+
loading={loading}
|
|
62
|
+
onClick={handleAddToCart}
|
|
63
|
+
aria-label={addToCartAriaLabel}
|
|
64
|
+
>
|
|
65
|
+
{addToCartLabel}
|
|
66
|
+
</Button>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default QuickOrderDrawerFooter
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import Icon from '../../atoms/Icon'
|
|
3
|
+
import { SlideOverHeader } from '../SlideOver'
|
|
4
|
+
|
|
5
|
+
export type QuickOrderDrawerHeaderProps = {
|
|
6
|
+
title: string
|
|
7
|
+
titleCharLimit?: number
|
|
8
|
+
onCloseDrawer?: () => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const QuickOrderDrawerHeader = ({
|
|
12
|
+
onCloseDrawer,
|
|
13
|
+
title,
|
|
14
|
+
titleCharLimit = 30,
|
|
15
|
+
}: QuickOrderDrawerHeaderProps) => {
|
|
16
|
+
const leftOffset = Math.floor(titleCharLimit / 2) - 3
|
|
17
|
+
const rightOffset = Math.floor(titleCharLimit / 2)
|
|
18
|
+
const titleFormatted =
|
|
19
|
+
title.length > titleCharLimit
|
|
20
|
+
? `${title.slice(0, leftOffset)}...${title.slice(-rightOffset)}`
|
|
21
|
+
: title
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<SlideOverHeader
|
|
25
|
+
data-fs-quick-order-drawer-header
|
|
26
|
+
closeBtnProps={{
|
|
27
|
+
variant: 'tertiary',
|
|
28
|
+
color: 'black',
|
|
29
|
+
'aria-label': 'Close quick order drawer',
|
|
30
|
+
}}
|
|
31
|
+
onClose={() => onCloseDrawer?.()}
|
|
32
|
+
>
|
|
33
|
+
<div data-fs-quick-order-drawer-title-container>
|
|
34
|
+
<div data-fs-quick-order-drawer-icon>
|
|
35
|
+
<Icon name="Table" weight="bold" width={32} height={32} />
|
|
36
|
+
</div>
|
|
37
|
+
<div data-fs-quick-order-drawer-title>{titleFormatted}</div>
|
|
38
|
+
</div>
|
|
39
|
+
</SlideOverHeader>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default QuickOrderDrawerHeader
|