@developer_tribe/react-builder 1.0.9 → 1.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/dist/build-components/BIcon/BIconProps.generated.d.ts +2 -2
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +2 -2
- package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +2 -2
- package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +2 -2
- package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +2 -2
- package/dist/build-components/Text/TextProps.generated.d.ts +2 -2
- package/dist/build-components/patterns.generated.d.ts +78 -30
- package/dist/hooks/useProjectFonts.d.ts +13 -0
- package/dist/index.cjs.js +3 -3
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +3 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/index.native.cjs.js +3 -3
- package/dist/index.native.cjs.js.map +1 -1
- package/dist/index.native.esm.js +3 -3
- package/dist/index.native.esm.js.map +1 -1
- package/dist/pages/ProjectPage.d.ts +4 -1
- package/dist/store.d.ts +11 -0
- package/dist/types/Fonts.d.ts +12 -0
- package/dist/utils/fontWeight.d.ts +3 -0
- package/dist/utils/fontsDebug.d.ts +12 -0
- package/dist/utils/loadFontFamily.d.ts +30 -0
- package/package.json +1 -1
- package/scripts/prebuild/utils/createGeneratedProps.js +9 -1
- package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +2 -0
- package/src/AttributesEditor.tsx +237 -1
- package/src/RenderPage.tsx +15 -6
- package/src/attributes-editor/Field.tsx +18 -0
- package/src/build-components/BIcon/BIconProps.generated.ts +2 -13
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +2 -13
- package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +2 -13
- package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +2 -13
- package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +2 -13
- package/src/build-components/Text/TextProps.generated.ts +2 -13
- package/src/build-components/Text/pattern.json +13 -17
- package/src/build-components/patterns.generated.ts +78 -102
- package/src/components/BuilderButton.tsx +13 -11
- package/src/hooks/useProjectFonts.ts +130 -0
- package/src/index.ts +1 -0
- package/src/pages/ProjectPage.tsx +8 -0
- package/src/store.ts +46 -1
- package/src/types/Fonts.ts +16 -0
- package/src/utils/analyseNodeByPatterns.ts +9 -0
- package/src/utils/extractTextStyle.ts +98 -1
- package/src/utils/fontWeight.ts +29 -0
- package/src/utils/fontsDebug.ts +16 -0
- package/src/utils/loadFontFamily.ts +318 -0
- package/src/utils/patterns.ts +2 -0
|
@@ -7,19 +7,8 @@
|
|
|
7
7
|
"attributes": {
|
|
8
8
|
"color": "color",
|
|
9
9
|
"fontSize": "size",
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
"bold",
|
|
13
|
-
"100",
|
|
14
|
-
"200",
|
|
15
|
-
"300",
|
|
16
|
-
"400",
|
|
17
|
-
"500",
|
|
18
|
-
"600",
|
|
19
|
-
"700",
|
|
20
|
-
"800",
|
|
21
|
-
"900"
|
|
22
|
-
],
|
|
10
|
+
"fontFamily": "fontFamily",
|
|
11
|
+
"fontWeight": "fontWeight",
|
|
23
12
|
"textAlign": ["left", "center", "right", "justify"],
|
|
24
13
|
"adjustsFontSizeToFit": "boolean",
|
|
25
14
|
"showEllipsis": "boolean"
|
|
@@ -45,33 +34,40 @@
|
|
|
45
34
|
"sort": 2,
|
|
46
35
|
"preferedScale": "s"
|
|
47
36
|
},
|
|
37
|
+
"fontFamily": {
|
|
38
|
+
"label": "Font Family",
|
|
39
|
+
"description": "Font family used for the text.",
|
|
40
|
+
"category": "style",
|
|
41
|
+
"specialCategory": null,
|
|
42
|
+
"sort": 3
|
|
43
|
+
},
|
|
48
44
|
"fontWeight": {
|
|
49
45
|
"label": "Font Weight",
|
|
50
46
|
"description": "Text weight.",
|
|
51
47
|
"category": "style",
|
|
52
48
|
"specialCategory": null,
|
|
53
|
-
"sort":
|
|
49
|
+
"sort": 4
|
|
54
50
|
},
|
|
55
51
|
"textAlign": {
|
|
56
52
|
"label": "Text Align",
|
|
57
53
|
"description": "Text alignment.",
|
|
58
54
|
"category": "style",
|
|
59
55
|
"specialCategory": null,
|
|
60
|
-
"sort":
|
|
56
|
+
"sort": 5
|
|
61
57
|
},
|
|
62
58
|
"adjustsFontSizeToFit": {
|
|
63
59
|
"label": "Adjust Font Size To Fit",
|
|
64
60
|
"description": "Automatically reduces font size to fit the available space.",
|
|
65
61
|
"category": "style",
|
|
66
62
|
"specialCategory": null,
|
|
67
|
-
"sort":
|
|
63
|
+
"sort": 6
|
|
68
64
|
},
|
|
69
65
|
"showEllipsis": {
|
|
70
66
|
"label": "Show Ellipsis",
|
|
71
67
|
"description": "If text overflows, show ellipsis (…); applied as single-line truncation.",
|
|
72
68
|
"category": "style",
|
|
73
69
|
"specialCategory": null,
|
|
74
|
-
"sort":
|
|
70
|
+
"sort": 7
|
|
75
71
|
}
|
|
76
72
|
}
|
|
77
73
|
}
|
|
@@ -10,19 +10,8 @@ export const patterns = [
|
|
|
10
10
|
attributes: {
|
|
11
11
|
color: 'color',
|
|
12
12
|
fontSize: 'size',
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
'bold',
|
|
16
|
-
'100',
|
|
17
|
-
'200',
|
|
18
|
-
'300',
|
|
19
|
-
'400',
|
|
20
|
-
'500',
|
|
21
|
-
'600',
|
|
22
|
-
'700',
|
|
23
|
-
'800',
|
|
24
|
-
'900',
|
|
25
|
-
],
|
|
13
|
+
fontFamily: 'fontFamily',
|
|
14
|
+
fontWeight: 'fontWeight',
|
|
26
15
|
textAlign: ['left', 'center', 'right', 'justify'],
|
|
27
16
|
adjustsFontSizeToFit: 'boolean',
|
|
28
17
|
showEllipsis: 'boolean',
|
|
@@ -91,19 +80,26 @@ export const patterns = [
|
|
|
91
80
|
sort: 2,
|
|
92
81
|
preferedScale: 's',
|
|
93
82
|
},
|
|
83
|
+
fontFamily: {
|
|
84
|
+
label: 'Font Family',
|
|
85
|
+
description: 'Font family used for the text.',
|
|
86
|
+
category: 'style',
|
|
87
|
+
specialCategory: null,
|
|
88
|
+
sort: 3,
|
|
89
|
+
},
|
|
94
90
|
fontWeight: {
|
|
95
91
|
label: 'Font Weight',
|
|
96
92
|
description: 'Text weight.',
|
|
97
93
|
category: 'style',
|
|
98
94
|
specialCategory: null,
|
|
99
|
-
sort:
|
|
95
|
+
sort: 4,
|
|
100
96
|
},
|
|
101
97
|
textAlign: {
|
|
102
98
|
label: 'Text Align',
|
|
103
99
|
description: 'Text alignment.',
|
|
104
100
|
category: 'style',
|
|
105
101
|
specialCategory: null,
|
|
106
|
-
sort:
|
|
102
|
+
sort: 5,
|
|
107
103
|
},
|
|
108
104
|
adjustsFontSizeToFit: {
|
|
109
105
|
label: 'Adjust Font Size To Fit',
|
|
@@ -111,7 +107,7 @@ export const patterns = [
|
|
|
111
107
|
'Automatically reduces font size to fit the available space.',
|
|
112
108
|
category: 'style',
|
|
113
109
|
specialCategory: null,
|
|
114
|
-
sort:
|
|
110
|
+
sort: 6,
|
|
115
111
|
},
|
|
116
112
|
showEllipsis: {
|
|
117
113
|
label: 'Show Ellipsis',
|
|
@@ -119,7 +115,7 @@ export const patterns = [
|
|
|
119
115
|
'If text overflows, show ellipsis (…); applied as single-line truncation.',
|
|
120
116
|
category: 'style',
|
|
121
117
|
specialCategory: null,
|
|
122
|
-
sort:
|
|
118
|
+
sort: 7,
|
|
123
119
|
},
|
|
124
120
|
scrollable: {
|
|
125
121
|
label: 'Scrollable',
|
|
@@ -5294,19 +5290,8 @@ export const patterns = [
|
|
|
5294
5290
|
attributes: {
|
|
5295
5291
|
color: 'color',
|
|
5296
5292
|
fontSize: 'size',
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
'bold',
|
|
5300
|
-
'100',
|
|
5301
|
-
'200',
|
|
5302
|
-
'300',
|
|
5303
|
-
'400',
|
|
5304
|
-
'500',
|
|
5305
|
-
'600',
|
|
5306
|
-
'700',
|
|
5307
|
-
'800',
|
|
5308
|
-
'900',
|
|
5309
|
-
],
|
|
5293
|
+
fontFamily: 'fontFamily',
|
|
5294
|
+
fontWeight: 'fontWeight',
|
|
5310
5295
|
textAlign: ['left', 'center', 'right', 'justify'],
|
|
5311
5296
|
adjustsFontSizeToFit: 'boolean',
|
|
5312
5297
|
showEllipsis: 'boolean',
|
|
@@ -5379,19 +5364,26 @@ export const patterns = [
|
|
|
5379
5364
|
sort: 2,
|
|
5380
5365
|
preferedScale: 's',
|
|
5381
5366
|
},
|
|
5367
|
+
fontFamily: {
|
|
5368
|
+
label: 'Font Family',
|
|
5369
|
+
description: 'Font family used for the text.',
|
|
5370
|
+
category: 'style',
|
|
5371
|
+
specialCategory: null,
|
|
5372
|
+
sort: 3,
|
|
5373
|
+
},
|
|
5382
5374
|
fontWeight: {
|
|
5383
5375
|
label: 'Font Weight',
|
|
5384
5376
|
description: 'Text weight.',
|
|
5385
5377
|
category: 'style',
|
|
5386
5378
|
specialCategory: null,
|
|
5387
|
-
sort:
|
|
5379
|
+
sort: 4,
|
|
5388
5380
|
},
|
|
5389
5381
|
textAlign: {
|
|
5390
5382
|
label: 'Text Align',
|
|
5391
5383
|
description: 'Text alignment.',
|
|
5392
5384
|
category: 'style',
|
|
5393
5385
|
specialCategory: null,
|
|
5394
|
-
sort:
|
|
5386
|
+
sort: 5,
|
|
5395
5387
|
},
|
|
5396
5388
|
adjustsFontSizeToFit: {
|
|
5397
5389
|
label: 'Adjust Font Size To Fit',
|
|
@@ -5399,7 +5391,7 @@ export const patterns = [
|
|
|
5399
5391
|
'Automatically reduces font size to fit the available space.',
|
|
5400
5392
|
category: 'style',
|
|
5401
5393
|
specialCategory: null,
|
|
5402
|
-
sort:
|
|
5394
|
+
sort: 6,
|
|
5403
5395
|
},
|
|
5404
5396
|
showEllipsis: {
|
|
5405
5397
|
label: 'Show Ellipsis',
|
|
@@ -5407,7 +5399,7 @@ export const patterns = [
|
|
|
5407
5399
|
'If text overflows, show ellipsis (…); applied as single-line truncation.',
|
|
5408
5400
|
category: 'style',
|
|
5409
5401
|
specialCategory: null,
|
|
5410
|
-
sort:
|
|
5402
|
+
sort: 7,
|
|
5411
5403
|
},
|
|
5412
5404
|
scrollable: {
|
|
5413
5405
|
label: 'Scrollable',
|
|
@@ -6874,19 +6866,8 @@ export const patterns = [
|
|
|
6874
6866
|
attributes: {
|
|
6875
6867
|
color: 'color',
|
|
6876
6868
|
fontSize: 'size',
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
'bold',
|
|
6880
|
-
'100',
|
|
6881
|
-
'200',
|
|
6882
|
-
'300',
|
|
6883
|
-
'400',
|
|
6884
|
-
'500',
|
|
6885
|
-
'600',
|
|
6886
|
-
'700',
|
|
6887
|
-
'800',
|
|
6888
|
-
'900',
|
|
6889
|
-
],
|
|
6869
|
+
fontFamily: 'fontFamily',
|
|
6870
|
+
fontWeight: 'fontWeight',
|
|
6890
6871
|
textAlign: ['left', 'center', 'right', 'justify'],
|
|
6891
6872
|
adjustsFontSizeToFit: 'boolean',
|
|
6892
6873
|
showEllipsis: 'boolean',
|
|
@@ -6952,19 +6933,26 @@ export const patterns = [
|
|
|
6952
6933
|
sort: 2,
|
|
6953
6934
|
preferedScale: 's',
|
|
6954
6935
|
},
|
|
6936
|
+
fontFamily: {
|
|
6937
|
+
label: 'Font Family',
|
|
6938
|
+
description: 'Font family used for the text.',
|
|
6939
|
+
category: 'style',
|
|
6940
|
+
specialCategory: null,
|
|
6941
|
+
sort: 3,
|
|
6942
|
+
},
|
|
6955
6943
|
fontWeight: {
|
|
6956
6944
|
label: 'Font Weight',
|
|
6957
6945
|
description: 'Text weight.',
|
|
6958
6946
|
category: 'style',
|
|
6959
6947
|
specialCategory: null,
|
|
6960
|
-
sort:
|
|
6948
|
+
sort: 4,
|
|
6961
6949
|
},
|
|
6962
6950
|
textAlign: {
|
|
6963
6951
|
label: 'Text Align',
|
|
6964
6952
|
description: 'Text alignment.',
|
|
6965
6953
|
category: 'style',
|
|
6966
6954
|
specialCategory: null,
|
|
6967
|
-
sort:
|
|
6955
|
+
sort: 5,
|
|
6968
6956
|
},
|
|
6969
6957
|
adjustsFontSizeToFit: {
|
|
6970
6958
|
label: 'Adjust Font Size To Fit',
|
|
@@ -6972,7 +6960,7 @@ export const patterns = [
|
|
|
6972
6960
|
'Automatically reduces font size to fit the available space.',
|
|
6973
6961
|
category: 'style',
|
|
6974
6962
|
specialCategory: null,
|
|
6975
|
-
sort:
|
|
6963
|
+
sort: 6,
|
|
6976
6964
|
},
|
|
6977
6965
|
showEllipsis: {
|
|
6978
6966
|
label: 'Show Ellipsis',
|
|
@@ -6980,7 +6968,7 @@ export const patterns = [
|
|
|
6980
6968
|
'If text overflows, show ellipsis (…); applied as single-line truncation.',
|
|
6981
6969
|
category: 'style',
|
|
6982
6970
|
specialCategory: null,
|
|
6983
|
-
sort:
|
|
6971
|
+
sort: 7,
|
|
6984
6972
|
},
|
|
6985
6973
|
scrollable: {
|
|
6986
6974
|
label: 'Scrollable',
|
|
@@ -7293,19 +7281,8 @@ export const patterns = [
|
|
|
7293
7281
|
attributes: {
|
|
7294
7282
|
color: 'color',
|
|
7295
7283
|
fontSize: 'size',
|
|
7296
|
-
|
|
7297
|
-
|
|
7298
|
-
'bold',
|
|
7299
|
-
'100',
|
|
7300
|
-
'200',
|
|
7301
|
-
'300',
|
|
7302
|
-
'400',
|
|
7303
|
-
'500',
|
|
7304
|
-
'600',
|
|
7305
|
-
'700',
|
|
7306
|
-
'800',
|
|
7307
|
-
'900',
|
|
7308
|
-
],
|
|
7284
|
+
fontFamily: 'fontFamily',
|
|
7285
|
+
fontWeight: 'fontWeight',
|
|
7309
7286
|
textAlign: ['left', 'center', 'right', 'justify'],
|
|
7310
7287
|
adjustsFontSizeToFit: 'boolean',
|
|
7311
7288
|
showEllipsis: 'boolean',
|
|
@@ -7371,19 +7348,26 @@ export const patterns = [
|
|
|
7371
7348
|
sort: 2,
|
|
7372
7349
|
preferedScale: 's',
|
|
7373
7350
|
},
|
|
7351
|
+
fontFamily: {
|
|
7352
|
+
label: 'Font Family',
|
|
7353
|
+
description: 'Font family used for the text.',
|
|
7354
|
+
category: 'style',
|
|
7355
|
+
specialCategory: null,
|
|
7356
|
+
sort: 3,
|
|
7357
|
+
},
|
|
7374
7358
|
fontWeight: {
|
|
7375
7359
|
label: 'Font Weight',
|
|
7376
7360
|
description: 'Text weight.',
|
|
7377
7361
|
category: 'style',
|
|
7378
7362
|
specialCategory: null,
|
|
7379
|
-
sort:
|
|
7363
|
+
sort: 4,
|
|
7380
7364
|
},
|
|
7381
7365
|
textAlign: {
|
|
7382
7366
|
label: 'Text Align',
|
|
7383
7367
|
description: 'Text alignment.',
|
|
7384
7368
|
category: 'style',
|
|
7385
7369
|
specialCategory: null,
|
|
7386
|
-
sort:
|
|
7370
|
+
sort: 5,
|
|
7387
7371
|
},
|
|
7388
7372
|
adjustsFontSizeToFit: {
|
|
7389
7373
|
label: 'Adjust Font Size To Fit',
|
|
@@ -7391,7 +7375,7 @@ export const patterns = [
|
|
|
7391
7375
|
'Automatically reduces font size to fit the available space.',
|
|
7392
7376
|
category: 'style',
|
|
7393
7377
|
specialCategory: null,
|
|
7394
|
-
sort:
|
|
7378
|
+
sort: 6,
|
|
7395
7379
|
},
|
|
7396
7380
|
showEllipsis: {
|
|
7397
7381
|
label: 'Show Ellipsis',
|
|
@@ -7399,7 +7383,7 @@ export const patterns = [
|
|
|
7399
7383
|
'If text overflows, show ellipsis (…); applied as single-line truncation.',
|
|
7400
7384
|
category: 'style',
|
|
7401
7385
|
specialCategory: null,
|
|
7402
|
-
sort:
|
|
7386
|
+
sort: 7,
|
|
7403
7387
|
},
|
|
7404
7388
|
scrollable: {
|
|
7405
7389
|
label: 'Scrollable',
|
|
@@ -8066,19 +8050,8 @@ export const patterns = [
|
|
|
8066
8050
|
strokeWidth: 'number',
|
|
8067
8051
|
color: 'color',
|
|
8068
8052
|
fontSize: 'size',
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
'bold',
|
|
8072
|
-
'100',
|
|
8073
|
-
'200',
|
|
8074
|
-
'300',
|
|
8075
|
-
'400',
|
|
8076
|
-
'500',
|
|
8077
|
-
'600',
|
|
8078
|
-
'700',
|
|
8079
|
-
'800',
|
|
8080
|
-
'900',
|
|
8081
|
-
],
|
|
8053
|
+
fontFamily: 'fontFamily',
|
|
8054
|
+
fontWeight: 'fontWeight',
|
|
8082
8055
|
textAlign: ['left', 'center', 'right', 'justify'],
|
|
8083
8056
|
adjustsFontSizeToFit: 'boolean',
|
|
8084
8057
|
showEllipsis: 'boolean',
|
|
@@ -8165,19 +8138,26 @@ export const patterns = [
|
|
|
8165
8138
|
sort: 2,
|
|
8166
8139
|
preferedScale: 's',
|
|
8167
8140
|
},
|
|
8141
|
+
fontFamily: {
|
|
8142
|
+
label: 'Font Family',
|
|
8143
|
+
description: 'Font family used for the text.',
|
|
8144
|
+
category: 'style',
|
|
8145
|
+
specialCategory: null,
|
|
8146
|
+
sort: 3,
|
|
8147
|
+
},
|
|
8168
8148
|
fontWeight: {
|
|
8169
8149
|
label: 'Font Weight',
|
|
8170
8150
|
description: 'Text weight.',
|
|
8171
8151
|
category: 'style',
|
|
8172
8152
|
specialCategory: null,
|
|
8173
|
-
sort:
|
|
8153
|
+
sort: 4,
|
|
8174
8154
|
},
|
|
8175
8155
|
textAlign: {
|
|
8176
8156
|
label: 'Text Align',
|
|
8177
8157
|
description: 'Text alignment.',
|
|
8178
8158
|
category: 'style',
|
|
8179
8159
|
specialCategory: null,
|
|
8180
|
-
sort:
|
|
8160
|
+
sort: 5,
|
|
8181
8161
|
},
|
|
8182
8162
|
adjustsFontSizeToFit: {
|
|
8183
8163
|
label: 'Adjust Font Size To Fit',
|
|
@@ -8185,7 +8165,7 @@ export const patterns = [
|
|
|
8185
8165
|
'Automatically reduces font size to fit the available space.',
|
|
8186
8166
|
category: 'style',
|
|
8187
8167
|
specialCategory: null,
|
|
8188
|
-
sort:
|
|
8168
|
+
sort: 6,
|
|
8189
8169
|
},
|
|
8190
8170
|
showEllipsis: {
|
|
8191
8171
|
label: 'Show Ellipsis',
|
|
@@ -8193,7 +8173,7 @@ export const patterns = [
|
|
|
8193
8173
|
'If text overflows, show ellipsis (…); applied as single-line truncation.',
|
|
8194
8174
|
category: 'style',
|
|
8195
8175
|
specialCategory: null,
|
|
8196
|
-
sort:
|
|
8176
|
+
sort: 7,
|
|
8197
8177
|
},
|
|
8198
8178
|
scrollable: {
|
|
8199
8179
|
label: 'Scrollable',
|
|
@@ -10038,19 +10018,8 @@ export const patterns = [
|
|
|
10038
10018
|
zIndex: 'number',
|
|
10039
10019
|
color: 'color',
|
|
10040
10020
|
fontSize: 'size',
|
|
10041
|
-
|
|
10042
|
-
|
|
10043
|
-
'bold',
|
|
10044
|
-
'100',
|
|
10045
|
-
'200',
|
|
10046
|
-
'300',
|
|
10047
|
-
'400',
|
|
10048
|
-
'500',
|
|
10049
|
-
'600',
|
|
10050
|
-
'700',
|
|
10051
|
-
'800',
|
|
10052
|
-
'900',
|
|
10053
|
-
],
|
|
10021
|
+
fontFamily: 'fontFamily',
|
|
10022
|
+
fontWeight: 'fontWeight',
|
|
10054
10023
|
textAlign: ['left', 'center', 'right', 'justify'],
|
|
10055
10024
|
adjustsFontSizeToFit: 'boolean',
|
|
10056
10025
|
showEllipsis: 'boolean',
|
|
@@ -10366,19 +10335,26 @@ export const patterns = [
|
|
|
10366
10335
|
sort: 2,
|
|
10367
10336
|
preferedScale: 's',
|
|
10368
10337
|
},
|
|
10338
|
+
fontFamily: {
|
|
10339
|
+
label: 'Font Family',
|
|
10340
|
+
description: 'Font family used for the text.',
|
|
10341
|
+
category: 'style',
|
|
10342
|
+
specialCategory: null,
|
|
10343
|
+
sort: 3,
|
|
10344
|
+
},
|
|
10369
10345
|
fontWeight: {
|
|
10370
10346
|
label: 'Font Weight',
|
|
10371
10347
|
description: 'Text weight.',
|
|
10372
10348
|
category: 'style',
|
|
10373
10349
|
specialCategory: null,
|
|
10374
|
-
sort:
|
|
10350
|
+
sort: 4,
|
|
10375
10351
|
},
|
|
10376
10352
|
textAlign: {
|
|
10377
10353
|
label: 'Text Align',
|
|
10378
10354
|
description: 'Text alignment.',
|
|
10379
10355
|
category: 'style',
|
|
10380
10356
|
specialCategory: null,
|
|
10381
|
-
sort:
|
|
10357
|
+
sort: 5,
|
|
10382
10358
|
},
|
|
10383
10359
|
adjustsFontSizeToFit: {
|
|
10384
10360
|
label: 'Adjust Font Size To Fit',
|
|
@@ -10386,7 +10362,7 @@ export const patterns = [
|
|
|
10386
10362
|
'Automatically reduces font size to fit the available space.',
|
|
10387
10363
|
category: 'style',
|
|
10388
10364
|
specialCategory: null,
|
|
10389
|
-
sort:
|
|
10365
|
+
sort: 6,
|
|
10390
10366
|
},
|
|
10391
10367
|
showEllipsis: {
|
|
10392
10368
|
label: 'Show Ellipsis',
|
|
@@ -10394,7 +10370,7 @@ export const patterns = [
|
|
|
10394
10370
|
'If text overflows, show ellipsis (…); applied as single-line truncation.',
|
|
10395
10371
|
category: 'style',
|
|
10396
10372
|
specialCategory: null,
|
|
10397
|
-
sort:
|
|
10373
|
+
sort: 7,
|
|
10398
10374
|
},
|
|
10399
10375
|
},
|
|
10400
10376
|
},
|
|
@@ -19,14 +19,8 @@ export function BuilderButton({
|
|
|
19
19
|
onMoveUp,
|
|
20
20
|
onMoveDown,
|
|
21
21
|
}: BuilderButtonProps) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
if (isNodeString(node)) {
|
|
26
|
-
return <div className="builder__text">{node as string}</div>;
|
|
27
|
-
}
|
|
28
|
-
const nodeData = node as NodeData<NodeDefaultAttribute>;
|
|
29
|
-
|
|
22
|
+
// IMPORTANT: Hooks must be called unconditionally on every render.
|
|
23
|
+
// (Early returns before hooks can trigger React internal invariants.)
|
|
30
24
|
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
31
25
|
const actionsRef = useRef<HTMLDivElement | null>(null);
|
|
32
26
|
const menuId = useMemo(
|
|
@@ -35,9 +29,9 @@ export function BuilderButton({
|
|
|
35
29
|
);
|
|
36
30
|
|
|
37
31
|
const handleDelete = () => {
|
|
38
|
-
if (onDelete)
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
if (!onDelete) return;
|
|
33
|
+
if (isNodeNullOrUndefined(node) || isNodeString(node)) return;
|
|
34
|
+
onDelete(node);
|
|
41
35
|
};
|
|
42
36
|
|
|
43
37
|
// Copy/Paste intentionally removed for now.
|
|
@@ -66,6 +60,14 @@ export function BuilderButton({
|
|
|
66
60
|
};
|
|
67
61
|
}, [isMenuOpen]);
|
|
68
62
|
|
|
63
|
+
if (isNodeNullOrUndefined(node)) {
|
|
64
|
+
return <div className="builder__placeholder">Null or undefined</div>;
|
|
65
|
+
}
|
|
66
|
+
if (isNodeString(node)) {
|
|
67
|
+
return <div className="builder__text">{node as string}</div>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const nodeData = node as NodeData<NodeDefaultAttribute>;
|
|
69
71
|
let extra = '';
|
|
70
72
|
if (nodeData.attributes?.condition) {
|
|
71
73
|
extra = ` (${nodeData.attributes.condition} ${nodeData.attributes.conditionVariable})`;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import type { Fonts } from '../types/Fonts';
|
|
3
|
+
import { useRenderStore } from '../store';
|
|
4
|
+
import { loadFontFamily } from '../utils/loadFontFamily';
|
|
5
|
+
import { fontsDebug } from '../utils/fontsDebug';
|
|
6
|
+
|
|
7
|
+
function sleep(ms: number): Promise<void> {
|
|
8
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async function loadWithDeadline<T>(
|
|
12
|
+
task: Promise<T>,
|
|
13
|
+
deadlineMs: number,
|
|
14
|
+
): Promise<T> {
|
|
15
|
+
if (!Number.isFinite(deadlineMs) || deadlineMs <= 0) {
|
|
16
|
+
return await task;
|
|
17
|
+
}
|
|
18
|
+
return (await Promise.race([
|
|
19
|
+
task,
|
|
20
|
+
sleep(deadlineMs).then(() => {
|
|
21
|
+
throw new Error('timeout');
|
|
22
|
+
}),
|
|
23
|
+
])) as T;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type UseProjectFontsParams = {
|
|
27
|
+
fonts: Fonts;
|
|
28
|
+
appFont: string | undefined;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Syncs project-provided fonts into the library store and ensures appFont is loaded (web).
|
|
33
|
+
* Loading behavior:
|
|
34
|
+
* - keep waiting while the load is in-flight
|
|
35
|
+
* - stop only when it loads, an error is thrown, or 10s deadline passes
|
|
36
|
+
*/
|
|
37
|
+
export function useProjectFonts({ fonts, appFont }: UseProjectFontsParams) {
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
fontsDebug.info('useProjectFonts: effect start', {
|
|
40
|
+
appFont,
|
|
41
|
+
fontsCount: Array.isArray(fonts) ? fonts.length : 'not-array',
|
|
42
|
+
});
|
|
43
|
+
const {
|
|
44
|
+
setFonts,
|
|
45
|
+
setAppFont,
|
|
46
|
+
setErrors,
|
|
47
|
+
addError,
|
|
48
|
+
loadedFonts,
|
|
49
|
+
markFontLoaded,
|
|
50
|
+
} = useRenderStore.getState();
|
|
51
|
+
|
|
52
|
+
fontsDebug.info('useProjectFonts: storing fonts/appFont in store', {
|
|
53
|
+
appFont,
|
|
54
|
+
fontsCount: Array.isArray(fonts) ? fonts.length : 'not-array',
|
|
55
|
+
});
|
|
56
|
+
setFonts(fonts);
|
|
57
|
+
setAppFont(appFont);
|
|
58
|
+
setErrors([]);
|
|
59
|
+
|
|
60
|
+
let cancelled = false;
|
|
61
|
+
|
|
62
|
+
const run = async () => {
|
|
63
|
+
const normalizedAppFont =
|
|
64
|
+
typeof appFont === 'string' ? appFont.trim() : '';
|
|
65
|
+
if (!normalizedAppFont) {
|
|
66
|
+
fontsDebug.warn('useProjectFonts: appFont missing/empty');
|
|
67
|
+
setErrors(['appFont is undefined']);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (cancelled) return;
|
|
72
|
+
|
|
73
|
+
const exists =
|
|
74
|
+
Array.isArray(fonts) &&
|
|
75
|
+
fonts.some(
|
|
76
|
+
(f) =>
|
|
77
|
+
f?.name === normalizedAppFont &&
|
|
78
|
+
f?.family &&
|
|
79
|
+
typeof f.family === 'object' &&
|
|
80
|
+
Object.keys(f.family).length > 0,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (!exists) {
|
|
84
|
+
fontsDebug.warn('useProjectFonts: appFont not found in fonts', {
|
|
85
|
+
normalizedAppFont,
|
|
86
|
+
});
|
|
87
|
+
setErrors([`appFont "${normalizedAppFont}" not found in fonts`]);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (
|
|
92
|
+
Array.isArray(loadedFonts) &&
|
|
93
|
+
loadedFonts.includes(normalizedAppFont)
|
|
94
|
+
) {
|
|
95
|
+
fontsDebug.info(
|
|
96
|
+
'useProjectFonts: appFont already loaded (store cache)',
|
|
97
|
+
{
|
|
98
|
+
normalizedAppFont,
|
|
99
|
+
},
|
|
100
|
+
);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
fontsDebug.info('useProjectFonts: loading appFont', {
|
|
105
|
+
normalizedAppFont,
|
|
106
|
+
deadlineMs: 10_000,
|
|
107
|
+
});
|
|
108
|
+
await loadWithDeadline(
|
|
109
|
+
loadFontFamily(fonts, normalizedAppFont, { forceFetch: true }),
|
|
110
|
+
10_000,
|
|
111
|
+
);
|
|
112
|
+
if (cancelled) return;
|
|
113
|
+
markFontLoaded(normalizedAppFont);
|
|
114
|
+
fontsDebug.info('useProjectFonts: appFont loaded', { normalizedAppFont });
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
void run().catch((e) => {
|
|
118
|
+
if (cancelled) return;
|
|
119
|
+
fontsDebug.compactError('useProjectFonts: failed', e, { appFont });
|
|
120
|
+
addError(
|
|
121
|
+
`Failed to initialize fonts: ${e instanceof Error ? e.message : String(e)}`,
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return () => {
|
|
126
|
+
fontsDebug.info('useProjectFonts: cleanup');
|
|
127
|
+
cancelled = true;
|
|
128
|
+
};
|
|
129
|
+
}, [fonts, appFont]);
|
|
130
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -16,6 +16,7 @@ export { useLocalize } from './hooks/useLocalize';
|
|
|
16
16
|
export type { TargetedScreenSize } from './types/TargetedScreenSize';
|
|
17
17
|
export type { Node, NodeData, NodeDefaultAttribute } from './types/Node';
|
|
18
18
|
export type { Project, ProjectColors } from './types/Project';
|
|
19
|
+
export type { Fonts, FontDefinition } from './types/Fonts';
|
|
19
20
|
export {
|
|
20
21
|
isNodeNullOrUndefined,
|
|
21
22
|
isNodeString,
|
|
@@ -34,6 +34,8 @@ import {
|
|
|
34
34
|
isNodeRecord,
|
|
35
35
|
nodeHasChild,
|
|
36
36
|
} from '../utils/nodeTree';
|
|
37
|
+
import type { Fonts } from '../types/Fonts';
|
|
38
|
+
import { useProjectFonts } from '../hooks/useProjectFonts';
|
|
37
39
|
export type ProjectPageProps = {
|
|
38
40
|
project: Project;
|
|
39
41
|
onSaveProject: (project: Project) => void;
|
|
@@ -42,6 +44,9 @@ export type ProjectPageProps = {
|
|
|
42
44
|
projectColors?: ProjectColors;
|
|
43
45
|
onSaveProjectColors?: (colors: ProjectColors) => void;
|
|
44
46
|
name?: string;
|
|
47
|
+
fonts: Fonts;
|
|
48
|
+
// NOTE: appFont is required as a prop to force the host to think about it.
|
|
49
|
+
appFont: string | undefined;
|
|
45
50
|
};
|
|
46
51
|
|
|
47
52
|
const MOBILE_BREAKPOINT = 1000;
|
|
@@ -54,9 +59,12 @@ export function ProjectPage({
|
|
|
54
59
|
projectColors,
|
|
55
60
|
onSaveProjectColors,
|
|
56
61
|
name,
|
|
62
|
+
fonts,
|
|
63
|
+
appFont,
|
|
57
64
|
}: ProjectPageProps) {
|
|
58
65
|
useLogRender('ProjectPage');
|
|
59
66
|
useSyncHtmlThemeClass();
|
|
67
|
+
useProjectFonts({ fonts, appFont });
|
|
60
68
|
const resolvedName = name ?? project.name;
|
|
61
69
|
const resolvedProjectColors = projectColors ?? project.projectColors;
|
|
62
70
|
const isEmptyProjectData =
|