playbook_ui 14.11.0.pre.rc.10 → 14.11.0.pre.rc.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_card/_card.scss +21 -3
- data/app/pb_kits/playbook/pb_card/docs/_card_header.html.erb +18 -0
- data/app/pb_kits/playbook/pb_card/docs/_card_header.jsx +40 -0
- data/app/pb_kits/playbook/pb_file_upload/_file_upload.tsx +24 -15
- data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_accept.jsx +3 -1
- data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_custom_description.jsx +4 -1
- data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_max_size.jsx +1 -1
- data/dist/chunks/_typeahead-DhQHv7TA.js +36 -0
- data/dist/chunks/_weekday_stacked-BImEPKQq.js +45 -0
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-doc.js +1 -1
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +4 -4
- data/dist/chunks/_typeahead-gJLWiR0r.js +0 -22
- data/dist/chunks/_weekday_stacked-7XLAG_Yz.js +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a40cb7946b47dc89652e34a40d2b6bebf0da7f07a0943b9bb69fc50c931be1c3
|
4
|
+
data.tar.gz: b2600a754bfbc2dcf00b84f6b82310a09470f935fb207a5b59636fe05a4354ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de7cc821c3dbeb94089076acf60bd695ad2052dc722489f9f1f1f5b24dde7f9278ea7e43199b7f9ad4d6337c846e9f9a0e813e7abd09950c239befa532123ed7
|
7
|
+
data.tar.gz: 94af3455871098939f89e548515cb289287841e0cd140723b77ddd2d3f3130a6adc818be8ae2765293bf2dde579235f49f66850bee7b8b34a6efe7d9b5247036
|
@@ -21,6 +21,14 @@
|
|
21
21
|
border-width: 0px;
|
22
22
|
}
|
23
23
|
|
24
|
+
@function ends-with($string, $suffix) {
|
25
|
+
$suffix-length: str-length($suffix);
|
26
|
+
@if $suffix-length == 0 {
|
27
|
+
@return true;
|
28
|
+
}
|
29
|
+
@return str-slice($string, -$suffix-length) == $suffix;
|
30
|
+
}
|
31
|
+
|
24
32
|
[class^=pb_card_header_kit] {
|
25
33
|
flex-grow: 0;
|
26
34
|
flex-shrink: 0;
|
@@ -30,9 +38,19 @@
|
|
30
38
|
border: 0;
|
31
39
|
border-radius: $pb_card_header_border_radius $pb_card_header_border_radius 0px 0px;
|
32
40
|
@each $color_name, $color_value in $pb_card_header_colors {
|
33
|
-
|
34
|
-
|
35
|
-
|
41
|
+
@if not ends-with($color_name, '_subtle') {
|
42
|
+
&[class*="_#{$color_name}"] {
|
43
|
+
@include pb_card_header_color($color_value);
|
44
|
+
color: lightenText($color_value);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
@each $color_name, $color_value in $pb_card_header_colors {
|
49
|
+
@if ends-with($color_name, '_subtle') {
|
50
|
+
&[class*="_#{$color_name}"] {
|
51
|
+
@include pb_card_header_color($color_value);
|
52
|
+
color: lightenText($color_value);
|
53
|
+
}
|
36
54
|
}
|
37
55
|
}
|
38
56
|
@each $color_name, $color_value in $pb_card_header_colors {
|
@@ -88,3 +88,21 @@
|
|
88
88
|
Body
|
89
89
|
<% end %>
|
90
90
|
<% end %>
|
91
|
+
|
92
|
+
<%= pb_rails("card", props: { padding: "none", header: true, margin_bottom: "sm"}) do %>
|
93
|
+
<%= pb_rails("card/card_header", props: { padding: "sm", header_color: "success_subtle" }) do %>
|
94
|
+
<%= pb_rails("body", props: { text: "Success Subtle" }) %>
|
95
|
+
<% end %>
|
96
|
+
<%= pb_rails("card/card_body", props: { padding: "md" }) do %>
|
97
|
+
Body
|
98
|
+
<% end %>
|
99
|
+
<% end %>
|
100
|
+
|
101
|
+
<%= pb_rails("card", props: { padding: "none", header: true, margin_bottom: "sm"}) do %>
|
102
|
+
<%= pb_rails("card/card_header", props: { padding: "sm", header_color: "error_subtle" }) do %>
|
103
|
+
<%= pb_rails("body", props: { text: "Error Subtle"}) %>
|
104
|
+
<% end %>
|
105
|
+
<%= pb_rails("card/card_body", props: { padding: "md" }) do %>
|
106
|
+
Body
|
107
|
+
<% end %>
|
108
|
+
<% end %>
|
@@ -231,6 +231,46 @@ const CardHeader = (props) => {
|
|
231
231
|
/>
|
232
232
|
</Card.Body>
|
233
233
|
</Card>
|
234
|
+
|
235
|
+
<Card
|
236
|
+
{...props}
|
237
|
+
marginBottom='sm'
|
238
|
+
padding="none"
|
239
|
+
>
|
240
|
+
<Card.Header
|
241
|
+
headerColor="success_subtle"
|
242
|
+
>
|
243
|
+
<Body
|
244
|
+
text="Success Subtle"
|
245
|
+
/>
|
246
|
+
</Card.Header>
|
247
|
+
<Card.Body>
|
248
|
+
<Body
|
249
|
+
{...props}
|
250
|
+
text="Body"
|
251
|
+
/>
|
252
|
+
</Card.Body>
|
253
|
+
</Card>
|
254
|
+
|
255
|
+
<Card
|
256
|
+
{...props}
|
257
|
+
marginBottom='sm'
|
258
|
+
padding="none"
|
259
|
+
>
|
260
|
+
<Card.Header
|
261
|
+
headerColor="error_subtle"
|
262
|
+
>
|
263
|
+
<Body
|
264
|
+
text="Error Subtle"
|
265
|
+
/>
|
266
|
+
</Card.Header>
|
267
|
+
<Card.Body>
|
268
|
+
<Body
|
269
|
+
{...props}
|
270
|
+
text="Body"
|
271
|
+
/>
|
272
|
+
</Card.Body>
|
273
|
+
</Card>
|
234
274
|
</>
|
235
275
|
)
|
236
276
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import React, { useEffect, useCallback, useRef } from 'react'
|
2
|
-
import { useDropzone, DropzoneInputProps, DropzoneRootProps } from 'react-dropzone'
|
2
|
+
import { useDropzone, DropzoneInputProps, DropzoneRootProps, FileRejection } from 'react-dropzone'
|
3
3
|
import classnames from 'classnames'
|
4
4
|
|
5
5
|
import { buildCss, buildDataProps, noop, buildHtmlProps } from '../utilities/props'
|
@@ -9,8 +9,10 @@ import type { Callback } from '../types'
|
|
9
9
|
import Body from '../pb_body/_body'
|
10
10
|
import Card from '../pb_card/_card'
|
11
11
|
|
12
|
+
import { isEmpty } from '../utilities/object'
|
13
|
+
|
12
14
|
type FileUploadProps = {
|
13
|
-
accept?: string[]
|
15
|
+
accept?: Record<string, string[]>,
|
14
16
|
className?: string,
|
15
17
|
customMessage?: string,
|
16
18
|
dark?: boolean,
|
@@ -19,7 +21,7 @@ type FileUploadProps = {
|
|
19
21
|
acceptedFilesDescription?: string,
|
20
22
|
maxSize?: number,
|
21
23
|
onFilesAccepted: Callback<File, File>,
|
22
|
-
onFilesRejected: (error: string, files:
|
24
|
+
onFilesRejected: (error: string, files: readonly FileRejection[]) => void,
|
23
25
|
}
|
24
26
|
|
25
27
|
const getFormattedFileSize = (fileSize: number): string => {
|
@@ -28,7 +30,7 @@ const getFormattedFileSize = (fileSize: number): string => {
|
|
28
30
|
|
29
31
|
const FileUpload = (props: FileUploadProps): React.ReactElement => {
|
30
32
|
const {
|
31
|
-
accept =
|
33
|
+
accept = {},
|
32
34
|
acceptedFilesDescription = '',
|
33
35
|
className,
|
34
36
|
customMessage,
|
@@ -48,30 +50,37 @@ const FileUpload = (props: FileUploadProps): React.ReactElement => {
|
|
48
50
|
getRootProps: () => DropzoneRootProps & any;
|
49
51
|
getInputProps: () => DropzoneInputProps & any;
|
50
52
|
isDragActive: boolean;
|
51
|
-
|
53
|
+
fileRejections: readonly FileRejection[];
|
52
54
|
}
|
53
55
|
|
54
|
-
const { getRootProps, getInputProps, isDragActive,
|
56
|
+
const { getRootProps, getInputProps, isDragActive, fileRejections }: DropZoneProps = useDropzone({
|
55
57
|
accept,
|
56
58
|
maxSize,
|
57
59
|
onDrop,
|
58
60
|
})
|
59
61
|
|
60
|
-
const prevRejected = useRef<
|
62
|
+
const prevRejected = useRef<readonly FileRejection[] | null>(null);
|
61
63
|
|
62
|
-
|
64
|
+
let maxFileSizeText = ''
|
65
|
+
if (maxSize !== undefined) {
|
66
|
+
maxFileSizeText = `Max file size is ${getFormattedFileSize(maxSize)}.`
|
67
|
+
}
|
63
68
|
|
64
69
|
useEffect(() => {
|
65
|
-
if (
|
66
|
-
const isFileTooLarge = maxSize &&
|
70
|
+
if (fileRejections === prevRejected.current) return
|
71
|
+
const isFileTooLarge = maxSize && fileRejections.length > 0 && fileRejections[0].file.size > maxSize;
|
67
72
|
if (isFileTooLarge) {
|
68
|
-
onFilesRejected(`File size is too large! ${maxFileSizeText}`,
|
73
|
+
onFilesRejected(`File size is too large! ${maxFileSizeText}`, fileRejections)
|
69
74
|
}
|
70
|
-
prevRejected.current =
|
71
|
-
}, [maxFileSizeText, maxSize, onFilesRejected,
|
75
|
+
prevRejected.current = fileRejections
|
76
|
+
}, [maxFileSizeText, maxSize, onFilesRejected, fileRejections])
|
72
77
|
|
73
78
|
const acceptedFileTypes = () => {
|
74
|
-
|
79
|
+
if (!accept) {
|
80
|
+
return []
|
81
|
+
}
|
82
|
+
|
83
|
+
return Object.keys(accept).map((fileType) => {
|
75
84
|
if (fileType.startsWith('image/')) {
|
76
85
|
return fileType.replace('image/', ' ')
|
77
86
|
} else {
|
@@ -86,7 +95,7 @@ const FileUpload = (props: FileUploadProps): React.ReactElement => {
|
|
86
95
|
const getDescription = () => {
|
87
96
|
return customMessage
|
88
97
|
? customMessage
|
89
|
-
: `Choose a file or drag it here.${accept
|
98
|
+
: `Choose a file or drag it here.${isEmpty(accept) ? '' : ` The accepted file types are: ${acceptedFilesDescription || acceptedFileTypes()}.`}${maxSize ? ` ${maxFileSizeText}` : ''}`;
|
90
99
|
}
|
91
100
|
|
92
101
|
return (
|
@@ -25,7 +25,10 @@ const FileUploadCustomDescription = (props) => {
|
|
25
25
|
{...props}
|
26
26
|
/>
|
27
27
|
<FileUpload
|
28
|
-
accept={
|
28
|
+
accept={{
|
29
|
+
"application/pdf": [".pdf"],
|
30
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [".xlsx"],
|
31
|
+
}}
|
29
32
|
acceptedFilesDescription="Adobe (.pdf) and Microsoft (.xslx)"
|
30
33
|
onFilesAccepted={handleOnFilesAccepted}
|
31
34
|
{...props}
|
@@ -18,7 +18,7 @@ const AcceptedFilesList = ({ files }) => (
|
|
18
18
|
const RejectedFilesList = ({ files }) => (
|
19
19
|
<List>
|
20
20
|
{files.map((file) => (
|
21
|
-
<ListItem key={file.name}><Body color="error">{`${file.name} (file too large)`}</Body></ListItem>
|
21
|
+
<ListItem key={file.file.name}><Body color="error">{`${file.file.name} (file too large)`}</Body></ListItem>
|
22
22
|
))}
|
23
23
|
</List>
|
24
24
|
)
|