@pdfme/ui 2.1.0 → 2.2.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/README.md +7 -3
- package/dist/index.js +1 -1
- package/dist/index.js.LICENSE.txt +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/class.d.ts +1 -0
- package/dist/types/components/Designer/index.d.ts +2 -0
- package/dist/types/components/Schemas/TextSchema.d.ts +1 -0
- package/dist/types/helper.d.ts +1 -0
- package/package.json +1 -1
- package/src/components/Designer/Sidebar/DetailView/TextPropEditor.tsx +15 -1
- package/src/components/Schemas/TextSchema.tsx +84 -26
package/dist/types/class.d.ts
CHANGED
@@ -25,6 +25,7 @@ export declare abstract class BaseUIClass {
|
|
25
25
|
};
|
26
26
|
rotate?: number | undefined;
|
27
27
|
alignment?: "center" | "left" | "right" | undefined;
|
28
|
+
verticalAlignment?: "top" | "bottom" | "middle" | undefined;
|
28
29
|
fontSize?: number | undefined;
|
29
30
|
fontName?: string | undefined;
|
30
31
|
fontColor?: string | undefined;
|
@@ -11,6 +11,7 @@ declare const TemplateEditor: ({ template, size, onSaveTemplate, onChangeTemplat
|
|
11
11
|
};
|
12
12
|
rotate?: number | undefined;
|
13
13
|
alignment?: "center" | "left" | "right" | undefined;
|
14
|
+
verticalAlignment?: "top" | "bottom" | "middle" | undefined;
|
14
15
|
fontSize?: number | undefined;
|
15
16
|
fontName?: string | undefined;
|
16
17
|
fontColor?: string | undefined;
|
@@ -60,6 +61,7 @@ declare const TemplateEditor: ({ template, size, onSaveTemplate, onChangeTemplat
|
|
60
61
|
};
|
61
62
|
rotate?: number | undefined;
|
62
63
|
alignment?: "center" | "left" | "right" | undefined;
|
64
|
+
verticalAlignment?: "top" | "bottom" | "middle" | undefined;
|
63
65
|
fontSize?: number | undefined;
|
64
66
|
fontName?: string | undefined;
|
65
67
|
fontColor?: string | undefined;
|
@@ -11,6 +11,7 @@ declare const _default: React.ForwardRefExoticComponent<SchemaUIProps & {
|
|
11
11
|
};
|
12
12
|
rotate?: number | undefined;
|
13
13
|
alignment?: "center" | "left" | "right" | undefined;
|
14
|
+
verticalAlignment?: "top" | "bottom" | "middle" | undefined;
|
14
15
|
fontSize?: number | undefined;
|
15
16
|
fontName?: string | undefined;
|
16
17
|
fontColor?: string | undefined;
|
package/dist/types/helper.d.ts
CHANGED
@@ -42,6 +42,7 @@ export declare const templateSchemas2SchemasList: (_template: Template) => Promi
|
|
42
42
|
lineHeight?: number | undefined;
|
43
43
|
rotate?: number | undefined;
|
44
44
|
alignment?: "center" | "left" | "right" | undefined;
|
45
|
+
verticalAlignment?: "top" | "bottom" | "middle" | undefined;
|
45
46
|
fontName?: string | undefined;
|
46
47
|
fontColor?: string | undefined;
|
47
48
|
characterSpacing?: number | undefined;
|
package/package.json
CHANGED
@@ -6,6 +6,10 @@ import {
|
|
6
6
|
DEFAULT_LINE_HEIGHT,
|
7
7
|
DEFAULT_CHARACTER_SPACING,
|
8
8
|
DEFAULT_FONT_COLOR,
|
9
|
+
VERTICAL_ALIGN_TOP,
|
10
|
+
VERTICAL_ALIGN_MIDDLE,
|
11
|
+
VERTICAL_ALIGN_BOTTOM,
|
12
|
+
DEFAULT_VERTICAL_ALIGNMENT,
|
9
13
|
DYNAMIC_FIT_VERTICAL,
|
10
14
|
DYNAMIC_FIT_HORIZONTAL,
|
11
15
|
DEFAULT_DYNAMIC_FIT,
|
@@ -154,6 +158,7 @@ const TextPropEditor = (
|
|
154
158
|
) => {
|
155
159
|
const { changeSchemas, activeSchema } = props;
|
156
160
|
const alignments = ['left', 'center', 'right'];
|
161
|
+
const verticalAlignments = [VERTICAL_ALIGN_TOP, VERTICAL_ALIGN_MIDDLE, VERTICAL_ALIGN_BOTTOM];
|
157
162
|
const dynamicFits = [DYNAMIC_FIT_HORIZONTAL, DYNAMIC_FIT_VERTICAL];
|
158
163
|
const font = useContext(FontContext);
|
159
164
|
const fallbackFontName = getFallbackFontName(font);
|
@@ -180,13 +185,22 @@ const TextPropEditor = (
|
|
180
185
|
/>
|
181
186
|
|
182
187
|
<SelectSet
|
183
|
-
label={'
|
188
|
+
label={'Horizontal Align'}
|
184
189
|
value={activeSchema.alignment ?? 'left'}
|
185
190
|
options={alignments}
|
186
191
|
onChange={(e) =>
|
187
192
|
changeSchemas([{ key: 'alignment', value: e.target.value, schemaId: activeSchema.id }])
|
188
193
|
}
|
189
194
|
/>
|
195
|
+
|
196
|
+
<SelectSet
|
197
|
+
label={'Vertical Align'}
|
198
|
+
value={activeSchema.verticalAlignment ?? DEFAULT_VERTICAL_ALIGNMENT}
|
199
|
+
options={verticalAlignments}
|
200
|
+
onChange={(e) => {
|
201
|
+
changeSchemas([{ key: 'verticalAlignment', value: e.target.value, schemaId: activeSchema.id }]);
|
202
|
+
}}
|
203
|
+
/>
|
190
204
|
</div>
|
191
205
|
<div
|
192
206
|
style={{
|
@@ -2,18 +2,34 @@ import React, { useContext, forwardRef, Ref, useState, useEffect } from 'react';
|
|
2
2
|
import {
|
3
3
|
DEFAULT_FONT_SIZE,
|
4
4
|
DEFAULT_ALIGNMENT,
|
5
|
+
VERTICAL_ALIGN_TOP,
|
6
|
+
VERTICAL_ALIGN_MIDDLE,
|
7
|
+
VERTICAL_ALIGN_BOTTOM,
|
8
|
+
DEFAULT_VERTICAL_ALIGNMENT,
|
5
9
|
DEFAULT_LINE_HEIGHT,
|
6
10
|
DEFAULT_CHARACTER_SPACING,
|
7
11
|
DEFAULT_FONT_COLOR,
|
8
12
|
TextSchema,
|
9
13
|
calculateDynamicFontSize,
|
10
14
|
getFontKitFont,
|
11
|
-
|
15
|
+
getBrowserVerticalFontAdjustments,
|
12
16
|
} from '@pdfme/common';
|
13
17
|
import { SchemaUIProps } from './SchemaUI';
|
14
18
|
import { ZOOM } from '../../constants';
|
15
19
|
import { FontContext } from '../../contexts';
|
16
20
|
|
21
|
+
const mapVerticalAlignToFlex = (verticalAlignmentValue: string | undefined) => {
|
22
|
+
switch (verticalAlignmentValue) {
|
23
|
+
case VERTICAL_ALIGN_TOP:
|
24
|
+
return 'flex-start';
|
25
|
+
case VERTICAL_ALIGN_MIDDLE:
|
26
|
+
return 'center';
|
27
|
+
case VERTICAL_ALIGN_BOTTOM:
|
28
|
+
return 'flex-end';
|
29
|
+
}
|
30
|
+
return 'flex-start';
|
31
|
+
};
|
32
|
+
|
17
33
|
type Props = SchemaUIProps & { schema: TextSchema };
|
18
34
|
|
19
35
|
const TextSchemaUI = (
|
@@ -22,8 +38,8 @@ const TextSchemaUI = (
|
|
22
38
|
) => {
|
23
39
|
const font = useContext(FontContext);
|
24
40
|
const [dynamicFontSize, setDynamicFontSize] = useState<number | undefined>(undefined);
|
25
|
-
const [
|
26
|
-
|
41
|
+
const [topAdjustment, setTopAdjustment] = useState<number>(0);
|
42
|
+
const [bottomAdjustment, setBottomAdjustment] = useState<number>(0);
|
27
43
|
|
28
44
|
useEffect(() => {
|
29
45
|
if (schema.dynamicFontSize && schema.data) {
|
@@ -50,10 +66,31 @@ const TextSchemaUI = (
|
|
50
66
|
|
51
67
|
useEffect(() => {
|
52
68
|
getFontKitFont(schema, font).then(fontKitFont => {
|
53
|
-
|
54
|
-
|
69
|
+
// Depending on vertical alignment, we need to move the top or bottom of the font to keep
|
70
|
+
// it within it's defined box and align it with the generated pdf.
|
71
|
+
const { topAdj, bottomAdj } = getBrowserVerticalFontAdjustments(
|
72
|
+
fontKitFont,
|
73
|
+
dynamicFontSize ?? schema.fontSize ?? DEFAULT_FONT_SIZE,
|
74
|
+
schema.lineHeight ?? DEFAULT_LINE_HEIGHT,
|
75
|
+
schema.verticalAlignment ?? DEFAULT_VERTICAL_ALIGNMENT
|
76
|
+
);
|
77
|
+
setTopAdjustment(topAdj);
|
78
|
+
setBottomAdjustment(bottomAdj);
|
55
79
|
});
|
80
|
+
|
81
|
+
if (ref && 'current' in ref) {
|
82
|
+
const textarea = ref.current;
|
83
|
+
|
84
|
+
if (textarea) {
|
85
|
+
// Textareas cannot be vertically aligned, so we need to adjust the height of the textarea
|
86
|
+
// to exactly fit the height of it's content, whilst aligned within it's container.
|
87
|
+
// This gives the appearance of being vertically aligned.
|
88
|
+
textarea.style.height = 'auto'; // Reset the height to auto to ensure we get the correct height.
|
89
|
+
textarea.style.height = `${textarea.scrollHeight}px`;
|
90
|
+
}
|
91
|
+
}
|
56
92
|
}, [
|
93
|
+
schema.data,
|
57
94
|
schema.width,
|
58
95
|
schema.height,
|
59
96
|
schema.fontName,
|
@@ -63,20 +100,36 @@ const TextSchemaUI = (
|
|
63
100
|
schema.dynamicFontSize?.fit,
|
64
101
|
schema.characterSpacing,
|
65
102
|
schema.lineHeight,
|
103
|
+
schema.verticalAlignment,
|
66
104
|
font,
|
67
|
-
dynamicFontSize
|
105
|
+
dynamicFontSize,
|
106
|
+
editable,
|
68
107
|
]);
|
69
108
|
|
70
|
-
|
71
|
-
const style: React.CSSProperties = {
|
109
|
+
const containerStyle: React.CSSProperties = {
|
72
110
|
position: 'absolute',
|
73
111
|
top: 0,
|
74
112
|
padding: 0,
|
75
|
-
height:
|
113
|
+
height: schema.height * ZOOM,
|
76
114
|
width: schema.width * ZOOM,
|
77
115
|
resize: 'none',
|
78
|
-
|
79
|
-
|
116
|
+
backgroundColor: schema.data && schema.backgroundColor ? schema.backgroundColor : 'rgb(242 244 255 / 75%)',
|
117
|
+
border: 'none',
|
118
|
+
display: 'flex',
|
119
|
+
flexDirection: 'column',
|
120
|
+
justifyContent: mapVerticalAlignToFlex(schema.verticalAlignment),
|
121
|
+
};
|
122
|
+
|
123
|
+
const textareaStyle: React.CSSProperties = {
|
124
|
+
padding: 0,
|
125
|
+
resize: 'none',
|
126
|
+
border: 'none',
|
127
|
+
outline: 'none',
|
128
|
+
paddingTop: topAdjustment,
|
129
|
+
background: 'none',
|
130
|
+
};
|
131
|
+
|
132
|
+
const fontStyles: React.CSSProperties = {
|
80
133
|
fontFamily: schema.fontName ? `'${schema.fontName}'` : 'inherit',
|
81
134
|
color: schema.fontColor ? schema.fontColor : DEFAULT_FONT_COLOR,
|
82
135
|
fontSize: `${dynamicFontSize ?? schema.fontSize ?? DEFAULT_FONT_SIZE}pt`,
|
@@ -85,27 +138,32 @@ const TextSchemaUI = (
|
|
85
138
|
textAlign: schema.alignment ?? DEFAULT_ALIGNMENT,
|
86
139
|
whiteSpace: 'pre-wrap',
|
87
140
|
wordBreak: 'break-word',
|
88
|
-
backgroundColor:
|
89
|
-
schema.data && schema.backgroundColor ? schema.backgroundColor : 'rgb(242 244 255 / 75%)',
|
90
|
-
border: 'none',
|
91
141
|
};
|
92
142
|
|
93
143
|
return editable ? (
|
94
|
-
<
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
144
|
+
<div style={containerStyle}>
|
145
|
+
<textarea
|
146
|
+
ref={ref}
|
147
|
+
placeholder={placeholder}
|
148
|
+
tabIndex={tabIndex}
|
149
|
+
style={{ ...textareaStyle, ...fontStyles }}
|
150
|
+
onChange={(e) => onChange(e.target.value)}
|
151
|
+
onBlur={onStopEditing}
|
152
|
+
value={schema.data}
|
153
|
+
></textarea>
|
154
|
+
</div>
|
103
155
|
) : (
|
104
|
-
<div style={
|
105
|
-
<div
|
156
|
+
<div style={containerStyle}>
|
157
|
+
<div
|
158
|
+
style={{
|
159
|
+
...fontStyles,
|
160
|
+
marginBottom: bottomAdjustment,
|
161
|
+
paddingTop: topAdjustment,
|
162
|
+
}}
|
163
|
+
>
|
106
164
|
{/* Set the letterSpacing of the last character to 0. */}
|
107
165
|
{schema.data.split('').map((l, i) => (
|
108
|
-
<span key={i} style={{ letterSpacing: String(schema.data).length === i + 1 ? 0 : 'inherit'
|
166
|
+
<span key={i} style={{ letterSpacing: String(schema.data).length === i + 1 ? 0 : 'inherit' }}>
|
109
167
|
{l}
|
110
168
|
</span>
|
111
169
|
))}
|