@autobusal/common 1.30.0 → 1.32.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/CHANGELOG.md +16 -0
- package/File/File.tsx +44 -1
- package/File/styles.ts +18 -2
- package/Viewer/styles.ts +30 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## 1.32.0
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- **Drag & drop on `File`**, the shared upload control used everywhere in the app - drop a file directly onto it instead of always going through the native picker. The control's own footprint (a single 38px-tall inline button) is unchanged everywhere it is already used; only a border/background highlight appears while dragging. A dropped file is handed to the same hidden `<input>` react-hook-form already registered, via a real dispatched `change` event, so every existing caller's validation/onChange keeps working with no changes on their end.
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **A checkbox row with a long notice no longer stretches sideways.** `.row-checkbox`'s label+input are laid out `flex-direction: row-reverse`, and the row's own notice/error text (a plain div) was sharing that same row - a short notice fit fine, but a longer one (two sentences, easily) stretched the row's WIDTH to fit on one line, visibly pushing the checkbox by however long the text happened to be. Every div child of a checkbox row now gets `flex-basis: 100%`, dropping straight onto its own full-width line; the label and input are unaffected.
|
|
13
|
+
|
|
14
|
+
## 1.31.0
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **A `row-component` field spans the full row width**, same as `row-textarea-html` already did - what lets a Viewer form's own section headings (`SectionHeading`, admin-label's Content/styles.ts) sit as a full-width divider instead of sharing a row with whatever field lands beside them.
|
|
19
|
+
|
|
4
20
|
## 1.30.0
|
|
5
21
|
|
|
6
22
|
### Changed
|
package/File/File.tsx
CHANGED
|
@@ -19,6 +19,7 @@ interface Props {
|
|
|
19
19
|
const File = ({ name, value, validation, multiple, t, refs }: Props): JSX.Element => {
|
|
20
20
|
const [ uploaded, setUploaded ] = useState<boolean>(false);
|
|
21
21
|
const [ preview, setPreview ] = useState<boolean>(false);
|
|
22
|
+
const [ dragging, setDragging ] = useState<boolean>(false);
|
|
22
23
|
|
|
23
24
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
24
25
|
|
|
@@ -46,11 +47,53 @@ const File = ({ name, value, validation, multiple, t, refs }: Props): JSX.Elemen
|
|
|
46
47
|
}
|
|
47
48
|
};
|
|
48
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Ferjolt Ozuni - Date: 2026-08-08
|
|
52
|
+
*
|
|
53
|
+
* A dropped file has to land on the actual hidden <input> - it is the
|
|
54
|
+
* one react-hook-form registered via refs(name, rules), and that
|
|
55
|
+
* registration is what onSave ultimately reads. The DataTransfer/
|
|
56
|
+
* dispatchEvent pair is the standard way to hand a File to a native
|
|
57
|
+
* file input programmatically: assigning to `.files` directly is
|
|
58
|
+
* read-only on the input itself, but an input accepts a `FileList`
|
|
59
|
+
* built via DataTransfer, and dispatching a real 'change' event (not
|
|
60
|
+
* calling the onChange prop directly) is what makes React's own
|
|
61
|
+
* synthetic-event system - and therefore RHF's registration - see it,
|
|
62
|
+
* exactly as if the browser's own file picker had fired it.
|
|
63
|
+
*/
|
|
64
|
+
const onDrop = (event: React.DragEvent<HTMLDivElement>): void => {
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
setDragging(false);
|
|
67
|
+
|
|
68
|
+
const dropped = event.dataTransfer.files;
|
|
69
|
+
|
|
70
|
+
if (!inputRef.current || dropped.length === 0) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const transfer = new DataTransfer();
|
|
75
|
+
|
|
76
|
+
Array.from(multiple ? dropped : [ dropped[0] ]).forEach(file => transfer.items.add(file));
|
|
77
|
+
|
|
78
|
+
inputRef.current.files = transfer.files;
|
|
79
|
+
inputRef.current.dispatchEvent(new Event('change', { bubbles: true }));
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const onDragOver = (event: React.DragEvent<HTMLDivElement>): void => {
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
setDragging(true);
|
|
85
|
+
};
|
|
86
|
+
|
|
49
87
|
const type = multiple ? 'multiple' : 'single';
|
|
50
88
|
|
|
51
89
|
return (
|
|
52
90
|
<>
|
|
53
|
-
<Container
|
|
91
|
+
<Container
|
|
92
|
+
$dragging={ dragging }
|
|
93
|
+
onDragOver={ onDragOver }
|
|
94
|
+
onDragLeave={ () => setDragging(false) }
|
|
95
|
+
onDrop={ onDrop }
|
|
96
|
+
>
|
|
54
97
|
<input
|
|
55
98
|
{ ...rest }
|
|
56
99
|
type="file"
|
package/File/styles.ts
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
|
-
import styled from 'styled-components';
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Ferjolt Ozuni - Date: 2026-08-08
|
|
5
|
+
* `$dragging` only changes the border/background while a file is being
|
|
6
|
+
* dragged over it - the box itself stays the same 38px-tall inline
|
|
7
|
+
* control everywhere this component is already used (tables, dense
|
|
8
|
+
* forms), rather than growing into a big dropzone that would only fit
|
|
9
|
+
* some of its callers.
|
|
10
|
+
*/
|
|
11
|
+
export const Container = styled.div<{ $dragging?: boolean }>`
|
|
4
12
|
display: flex;
|
|
5
13
|
align-items: center;
|
|
6
14
|
justify-content: space-between;
|
|
7
15
|
gap: 10px;
|
|
8
16
|
height: 38px;
|
|
17
|
+
border-radius: ${ props => props.theme.borderRadius };
|
|
18
|
+
transition: background 0.15s ease;
|
|
19
|
+
|
|
20
|
+
${ props => props.$dragging && css`
|
|
21
|
+
background: ${ props.theme.primary.neutral };
|
|
22
|
+
outline: 2px dashed ${ props.theme.primary.normal };
|
|
23
|
+
outline-offset: 2px;
|
|
24
|
+
` }
|
|
9
25
|
`;
|
|
10
26
|
|
|
11
27
|
export const ImgView = styled.img`
|
package/Viewer/styles.ts
CHANGED
|
@@ -3,8 +3,25 @@ import styled from 'styled-components';
|
|
|
3
3
|
export const Container = styled.div`
|
|
4
4
|
& > div.row-checkbox {
|
|
5
5
|
flex-direction: row-reverse;
|
|
6
|
+
flex-wrap: wrap;
|
|
6
7
|
justify-content: left;
|
|
7
|
-
height: 20px;
|
|
8
|
+
min-height: 20px;
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Edited: Ferjolt Ozuni - Date: 2026-08-08
|
|
12
|
+
* A checkbox row's own notice/error text is a DIV (Notice, Item's
|
|
13
|
+
* error Display) sharing this row's flex layout with the label
|
|
14
|
+
* (a span) and the checkbox input - row-reverse was fine for just
|
|
15
|
+
* those two, but any row with a real notice attached (Construction's
|
|
16
|
+
* "enabled" checkbox is two full sentences) stretched the row's WIDTH
|
|
17
|
+
* to fit the text on one line instead of wrapping it, visibly pushing
|
|
18
|
+
* the checkbox sideways by however long the notice happened to be.
|
|
19
|
+
* Forcing every div child onto its own full-width line - the label
|
|
20
|
+
* and the input stay row-reversed exactly as before.
|
|
21
|
+
*/
|
|
22
|
+
& > div {
|
|
23
|
+
flex-basis: 100%;
|
|
24
|
+
}
|
|
8
25
|
}
|
|
9
26
|
|
|
10
27
|
@media (min-width: 540px) {
|
|
@@ -36,6 +53,18 @@ export const Container = styled.div`
|
|
|
36
53
|
& > div.row-textarea-html {
|
|
37
54
|
flex-basis: 100% !important;
|
|
38
55
|
}
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
* Edited: Ferjolt Ozuni - Date: 2026-08-08
|
|
59
|
+
* A 'component' row gets the full width too, same reasoning as
|
|
60
|
+
* row-textarea-html above - it is how a form's own section headings
|
|
61
|
+
* (SectionHeading, see admin-label's Content/styles.ts) span the row
|
|
62
|
+
* instead of sharing it with whatever field happens to land beside
|
|
63
|
+
* them.
|
|
64
|
+
*/
|
|
65
|
+
& > div.row-component {
|
|
66
|
+
flex-basis: 100% !important;
|
|
67
|
+
}
|
|
39
68
|
}
|
|
40
69
|
|
|
41
70
|
/*
|