flet-box 1.0.6 → 1.0.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.
Files changed (162) hide show
  1. package/README.md +28 -1
  2. package/bin/cli.js +90 -11
  3. package/bin/commands/auditFix.js +682 -0
  4. package/bin/commands/checkApi.js +20 -6
  5. package/bin/commands/checkUi.js +1369 -0
  6. package/bin/commands/create.js +86 -12
  7. package/bin/commands/createBundle.js +75 -1
  8. package/bin/commands/images.js +349 -0
  9. package/bin/commands/pruneAssets.js +170 -0
  10. package/bin/commands/release.js +34 -1
  11. package/bin/commands/runCloudflare.js +47 -9
  12. package/bin/commands/runServer.js +91 -25
  13. package/bin/commands/toPng.js +346 -0
  14. package/bin/commands/unpack.js +1173 -0
  15. package/bin/ota/loader.js +90 -0
  16. package/bin/utils/appSources.js +101 -0
  17. package/bin/utils/bundleConfig.js +166 -0
  18. package/bin/utils/dtsProps.js +147 -0
  19. package/bin/utils/imageTools.js +271 -0
  20. package/bin/utils/images/bmp.js +99 -0
  21. package/bin/utils/images/gif.js +244 -0
  22. package/bin/utils/images/index.js +163 -0
  23. package/bin/utils/images/jpeg.js +643 -0
  24. package/bin/utils/images/png.js +486 -0
  25. package/bin/utils/images/unsupported.js +29 -0
  26. package/bin/utils/neutralise.js +109 -6
  27. package/bin/utils/pwaShell.js +137 -0
  28. package/bin/utils/templates.js +1653 -471
  29. package/docs/README.md +2 -0
  30. package/docs/cli/README.md +144 -1
  31. package/docs/guides/README.md +2 -0
  32. package/docs/guides/clean-ui.md +211 -0
  33. package/docs/guides/minification-and-protection.md +1 -1
  34. package/docs/guides/online-updates.md +105 -9
  35. package/docs/tools/README.md +1 -1
  36. package/docs/tools/animation.md +1 -1
  37. package/docs/tools/markdown.md +3 -3
  38. package/docs/tools/theme.md +41 -1
  39. package/docs/widget/Accordion.md +4 -0
  40. package/docs/widget/AdMob.md +5 -1
  41. package/docs/widget/AdSense.md +4 -0
  42. package/docs/widget/AnimatedBox.md +7 -3
  43. package/docs/widget/AnimatedText.md +4 -0
  44. package/docs/widget/Audio.md +5 -1
  45. package/docs/widget/Avatar.md +15 -3
  46. package/docs/widget/Badge.md +4 -0
  47. package/docs/widget/Button.md +4 -0
  48. package/docs/widget/COMMON_PROPS.md +52 -0
  49. package/docs/widget/Card.md +4 -0
  50. package/docs/widget/Carousel.md +4 -0
  51. package/docs/widget/Chart.md +4 -0
  52. package/docs/widget/Checkbox.md +4 -0
  53. package/docs/widget/Chip.md +4 -0
  54. package/docs/widget/CircularBar.md +4 -0
  55. package/docs/widget/CircularChart.md +4 -0
  56. package/docs/widget/CodeViewer.md +4 -0
  57. package/docs/widget/Column.md +4 -0
  58. package/docs/widget/Container.md +4 -0
  59. package/docs/widget/DataTable.md +4 -0
  60. package/docs/widget/Divider.md +4 -0
  61. package/docs/widget/DraggBox.md +6 -2
  62. package/docs/widget/Dropdown.md +6 -0
  63. package/docs/widget/DroppBox.md +5 -1
  64. package/docs/widget/FloatingActionButton.md +4 -0
  65. package/docs/widget/GridView.md +4 -0
  66. package/docs/widget/Icon.md +4 -0
  67. package/docs/widget/Image.md +14 -3
  68. package/docs/widget/Input.md +4 -0
  69. package/docs/widget/Inspector.md +2 -2
  70. package/docs/widget/InstallButton.md +4 -0
  71. package/docs/widget/ListTile.md +4 -0
  72. package/docs/widget/ListView.md +4 -0
  73. package/docs/widget/Maps.md +191 -0
  74. package/docs/widget/Markdown.md +4 -0
  75. package/docs/widget/MatrixRain.md +4 -0
  76. package/docs/widget/Pagination.md +4 -0
  77. package/docs/widget/ParallaxBox.md +4 -0
  78. package/docs/widget/ProgressBar.md +4 -0
  79. package/docs/widget/QRCode.md +4 -0
  80. package/docs/widget/README.md +12 -10
  81. package/docs/widget/Radio.md +5 -1
  82. package/docs/widget/Rating.md +4 -0
  83. package/docs/widget/Row.md +4 -0
  84. package/docs/widget/Skeleton.md +4 -0
  85. package/docs/widget/Slider.md +4 -0
  86. package/docs/widget/Stack.md +4 -0
  87. package/docs/widget/Stepper.md +4 -0
  88. package/docs/widget/Switch.md +4 -0
  89. package/docs/widget/Tabs.md +5 -5
  90. package/docs/widget/Text.md +4 -0
  91. package/docs/widget/Tooltip.md +14 -13
  92. package/docs/widget/TreeView.md +4 -0
  93. package/docs/widget/Video.md +6 -2
  94. package/package.json +2 -2
  95. package/src/animations/AnimatedBox.js +4 -1
  96. package/src/animations/MatrixRain.js +3 -3
  97. package/src/core/hmr-client.js +129 -34
  98. package/src/index.d.ts +195 -7
  99. package/src/index.js +2 -0
  100. package/src/navigations/AppBar.js +22 -16
  101. package/src/navigations/BottomNavigation.js +8 -13
  102. package/src/navigations/CollapsibleSideBar.js +30 -8
  103. package/src/navigations/Drawer.js +25 -15
  104. package/src/navigations/DrawerItem.js +3 -1
  105. package/src/navigations/Scaffold.js +26 -12
  106. package/src/navigations/Tabs.js +104 -59
  107. package/src/tools/color.js +54 -0
  108. package/src/tools/index.js +9 -1
  109. package/src/tools/scale.js +41 -0
  110. package/src/tools/shadow.js +20 -0
  111. package/src/utils/index.js +1 -0
  112. package/src/utils/readableInk.js +19 -0
  113. package/src/utils/syntaxHighlight.js +78 -10
  114. package/src/utils/themes.js +217 -54
  115. package/src/utils/units.js +33 -11
  116. package/src/widget-factory/effects.js +56 -5
  117. package/src/widget-factory/processProps.js +10 -1
  118. package/src/widget-factory/remTool.js +15 -29
  119. package/src/widget-factory/stackPosition.js +18 -3
  120. package/src/widget-factory/translateProps.js +60 -1
  121. package/src/widgets/Accordion.js +20 -23
  122. package/src/widgets/AdMob.js +7 -2
  123. package/src/widgets/Avatar.js +236 -133
  124. package/src/widgets/Badge.js +3 -2
  125. package/src/widgets/BottomSheet.js +14 -13
  126. package/src/widgets/Button.js +69 -30
  127. package/src/widgets/Card.js +6 -2
  128. package/src/widgets/Carousel.js +12 -10
  129. package/src/widgets/Chart.js +28 -5
  130. package/src/widgets/Checkbox.js +76 -18
  131. package/src/widgets/Chip.js +31 -10
  132. package/src/widgets/CircularBar.js +7 -7
  133. package/src/widgets/CircularChart.js +26 -8
  134. package/src/widgets/CodeViewer.js +93 -20
  135. package/src/widgets/Container.js +13 -0
  136. package/src/widgets/DataTable.js +17 -11
  137. package/src/widgets/DraggBox.js +2 -1
  138. package/src/widgets/Dropdown.js +59 -14
  139. package/src/widgets/DroppBox.js +4 -2
  140. package/src/widgets/FloatingActionButton.js +13 -7
  141. package/src/widgets/Icon.js +3 -1
  142. package/src/widgets/Image.js +102 -3
  143. package/src/widgets/Input.js +30 -23
  144. package/src/widgets/Inspector.js +54 -1
  145. package/src/widgets/InstallButton.js +6 -4
  146. package/src/widgets/ListTile.js +4 -3
  147. package/src/widgets/ListView.js +30 -12
  148. package/src/widgets/Maps.js +1495 -0
  149. package/src/widgets/Markdown.js +37 -26
  150. package/src/widgets/Modal.js +14 -11
  151. package/src/widgets/Pagination.js +16 -11
  152. package/src/widgets/ProgressBar.js +6 -4
  153. package/src/widgets/Radio.js +73 -15
  154. package/src/widgets/Rating.js +24 -6
  155. package/src/widgets/Skeleton.js +31 -31
  156. package/src/widgets/Slider.js +29 -18
  157. package/src/widgets/SnackBar.js +35 -39
  158. package/src/widgets/Stepper.js +13 -9
  159. package/src/widgets/Switch.js +59 -18
  160. package/src/widgets/Tooltip.js +24 -12
  161. package/src/widgets/TreeView.js +27 -15
  162. package/src/widgets/index.js +1 -0
@@ -123,8 +123,17 @@ function applyUnit(def, value) {
123
123
  }
124
124
  if (value === true) return 1;
125
125
  if (value === false) return 0;
126
- if (typeof value !== "number") return value;
127
126
  const unit = def.unit || "px";
127
+ // A rem prop written as a pixel *string* ("8px 12px") is the same framework
128
+ // number written a different way, so it converts like the number does. `toREM`
129
+ // only rewrites strings made entirely of pixel lengths, which leaves "100%",
130
+ // "auto", "calc(100% - 16px)" and "2px solid red" exactly as they were.
131
+ if (unit === "rem" && typeof value === "string") return toREM(value);
132
+ // A rem prop written as a *list* (`padding: [8, 16]`) is the same pair of
133
+ // framework units again; the generic formatter would suffix each item with px.
134
+ if (unit === "rem" && Array.isArray(value))
135
+ return value.map((item) => toREM(item)).join(" ");
136
+ if (typeof value !== "number") return value;
128
137
  if (unit === "none") return value;
129
138
 
130
139
  // Use the dynamic REM converter instead of a hard-coded division.
@@ -1,34 +1,20 @@
1
1
  /**
2
- * REM TOOL - Only converts numbers to REM
2
+ * @file remTool.js
3
+ * @description The engine's entry point to the framework's one unit converter.
4
+ *
5
+ * This file used to keep its own copy of the rule — `value / 16` for numbers,
6
+ * strings passed through untouched. Two converters in one framework means two
7
+ * meanings for one number: a widget that called `src/utils/units.js` honoured
8
+ * `setBaseFontSize()` and an engine-routed prop did not, so the same `40` painted
9
+ * 40px in one place and 50px in another. Both halves now call the same function,
10
+ * and a length written as pixels ("8px", "4px 12px") converts like the number
11
+ * that produced it instead of freezing at that size.
3
12
  */
13
+ import { toREM as convert } from "../utils/units.js";
4
14
 
5
15
  /**
6
- * Converts a number to REM
7
- * @param {number} value - Number to convert
8
- * @param {number} baseFontSize - Base root font size (default: 16)
9
- * @returns {string} - Value in REM
16
+ * @param {number|string} value - A framework number, or a CSS length/value.
17
+ * @returns {string|*} `40` → `"2.5rem"`; `"8px 12px"` → `"0.5rem 0.75rem"`;
18
+ * anything that is not a pixel length (`"50%"`, `"auto"`) is returned as given.
10
19
  */
11
- export const toREM = (value, baseFontSize = 16) => {
12
- if (typeof value !== "number") return value;
13
- return `${value / baseFontSize}rem`;
14
- };
15
-
16
- /**
17
- * Applies REM to a styles object
18
- * @param {Object} styles - Styles with numbers
19
- * @param {number} baseFontSize - Base root font size (default: 16)
20
- * @returns {Object} - Styles with REM
21
- */
22
- export const applyREM = (styles, baseFontSize = 16) => {
23
- const result = {};
24
-
25
- for (const [key, value] of Object.entries(styles)) {
26
- if (typeof value === "number") {
27
- result[key] = toREM(value, baseFontSize);
28
- } else {
29
- result[key] = value;
30
- }
31
- }
32
-
33
- return result;
34
- };
20
+ export const toREM = (value) => convert(value);
@@ -26,9 +26,16 @@ export const stackPosition = (widget, props) => {
26
26
  // Absolute positioning
27
27
  widget.style.position = "absolute";
28
28
 
29
+ // `centerX` + `centerY` must compose: writing each transform as it is found
30
+ // would let the second one erase the first.
31
+ const transforms = [];
32
+
29
33
  // Process each position prop
30
34
  for (const [key, value] of Object.entries(props)) {
31
35
  if (key === "position") continue;
36
+ // The placement shorthands are booleans: a present `false` means "do not
37
+ // apply", not "the key exists".
38
+ if (value === false) continue;
32
39
 
33
40
  switch (key) {
34
41
  case "top":
@@ -51,16 +58,16 @@ export const stackPosition = (widget, props) => {
51
58
  break;
52
59
  case "centerX":
53
60
  widget.style.left = "50%";
54
- widget.style.transform = "translateX(-50%)";
61
+ transforms.push("translateX(-50%)");
55
62
  break;
56
63
  case "centerY":
57
64
  widget.style.top = "50%";
58
- widget.style.transform = "translateY(-50%)";
65
+ transforms.push("translateY(-50%)");
59
66
  break;
60
67
  case "center":
61
68
  widget.style.top = "50%";
62
69
  widget.style.left = "50%";
63
- widget.style.transform = "translate(-50%, -50%)";
70
+ transforms.push("translate(-50%, -50%)");
64
71
  break;
65
72
  case "fullWidth":
66
73
  widget.style.width = "100%";
@@ -81,6 +88,14 @@ export const stackPosition = (widget, props) => {
81
88
  }
82
89
  }
83
90
 
91
+ if (transforms.length) {
92
+ // `center` already covers both axes; mixing it with a single-axis shorthand
93
+ // must not shift the widget twice.
94
+ widget.style.transform = transforms.includes("translate(-50%, -50%)")
95
+ ? "translate(-50%, -50%)"
96
+ : transforms.join(" ");
97
+ }
98
+
84
99
  return widget;
85
100
  };
86
101
 
@@ -183,6 +183,34 @@ export const ALL_PROPS = [
183
183
  { prop: "boxShadow", domProp: "boxShadow", type: "style", unit: "none", reactive: true },
184
184
  { prop: "elevation", domProp: "boxShadow", type: "style", unit: "none", reactive: true },
185
185
 
186
+ // ============================================================
187
+ // GLASS & FILTERS
188
+ // ============================================================
189
+ // A translucent card is only glass when what sits behind it blurs, and there
190
+ // is no `style` object in this API — so if `backdrop-filter` were not routed,
191
+ // the effect would be unreachable rather than merely undocumented.
192
+ //
193
+ // Both names are written because WebKit only lifted the `-webkit-` requirement
194
+ // for `backdrop-filter` in Safari 18, and this framework ships iOS apps.
195
+ {
196
+ prop: "backdropFilter",
197
+ domProp: "backdropFilter",
198
+ type: "style",
199
+ unit: "none",
200
+ reactive: true,
201
+ targets: ["backdropFilter", "WebkitBackdropFilter"],
202
+ },
203
+ // Composes with the object builder in `src/tools/filter.js`.
204
+ { prop: "filter", domProp: "filter", type: "style", unit: "none", reactive: true },
205
+ {
206
+ prop: "maskImage",
207
+ domProp: "maskImage",
208
+ type: "style",
209
+ unit: "none",
210
+ reactive: true,
211
+ targets: ["maskImage", "WebkitMaskImage"],
212
+ },
213
+
186
214
  // ============================================================
187
215
  // DISPLAY & LAYOUT
188
216
  // ============================================================
@@ -480,6 +508,7 @@ export const ALL_PROPS = [
480
508
  { prop: "widthExpanded", domProp: "widthExpanded", type: "special" },
481
509
  { prop: "widthCollapsed", domProp: "widthCollapsed", type: "special" },
482
510
  { prop: "showTooltip", domProp: "showTooltip", type: "special" },
511
+ // Legacy alias of `delay`, still honoured by Tooltip.
483
512
  { prop: "tooltipDelay", domProp: "tooltipDelay", type: "special" },
484
513
 
485
514
  // ---- ListView / GridView ----
@@ -702,6 +731,7 @@ export const ALL_PROPS = [
702
731
  // ---- Avatar / Badge / Icon / Chip ----
703
732
  { prop: "icon", domProp: "icon", type: "special" },
704
733
  { prop: "shape", domProp: "shape", type: "special" },
734
+ // Presence dot: `online` shows it on Avatar, `badgeColor` paints it.
705
735
  { prop: "online", domProp: "online", type: "special" },
706
736
  { prop: "badge", domProp: "badge", type: "special" },
707
737
  { prop: "badgeColor", domProp: "badgeColor", type: "special" },
@@ -732,9 +762,12 @@ export const ALL_PROPS = [
732
762
  { prop: "headingColor", domProp: "headingColor", type: "special" },
733
763
  { prop: "allowDangerousHtml", domProp: "allowDangerousHtml", type: "special" },
734
764
 
735
- // ---- InstallButton ----
765
+ // ---- Image ----
766
+ // `downloadable` turns a click into a save, `downloadFileName` names the file.
736
767
  { prop: "downloadable", domProp: "downloadable", type: "special" },
737
768
  { prop: "downloadFileName", domProp: "downloadFileName", type: "special" },
769
+
770
+ // ---- InstallButton ----
738
771
  { prop: "onInstalled", domProp: "onInstalled", type: "special" },
739
772
 
740
773
  // ---- MatrixRain ----
@@ -748,6 +781,32 @@ export const ALL_PROPS = [
748
781
  { prop: "fgColor", domProp: "fgColor", type: "special" },
749
782
  { prop: "errorCorrection", domProp: "errorCorrection", type: "special" },
750
783
 
784
+ // ---- Maps ----
785
+ // `center` and `markers` are already registered above; the rest are Maps-only.
786
+ // All are inert here: Maps destructures them before the factory sees them and
787
+ // re-applies them through `composeUpdate`, so the registry entry only has to
788
+ // keep them out of the unknown-prop fallback (an invalid inline style for a
789
+ // `{lat, lng}` object, a bogus `mapclick` listener for `onMapClick`).
790
+ { prop: "zoom", domProp: "zoom", type: "special" },
791
+ { prop: "minZoom", domProp: "minZoom", type: "special" },
792
+ { prop: "maxZoom", domProp: "maxZoom", type: "special" },
793
+ { prop: "markerColor", domProp: "markerColor", type: "special" },
794
+ { prop: "polylines", domProp: "polylines", type: "special" },
795
+ { prop: "polylineColor", domProp: "polylineColor", type: "special" },
796
+ { prop: "tileUrl", domProp: "tileUrl", type: "special" },
797
+ { prop: "attribution", domProp: "attribution", type: "special" },
798
+ { prop: "showAttribution", domProp: "showAttribution", type: "special" },
799
+ { prop: "showZoomControl", domProp: "showZoomControl", type: "special" },
800
+ { prop: "interactive", domProp: "interactive", type: "special" },
801
+ { prop: "scrollZoom", domProp: "scrollZoom", type: "special" },
802
+ { prop: "doubleClickZoom", domProp: "doubleClickZoom", type: "special" },
803
+ { prop: "showUserLocation", domProp: "showUserLocation", type: "special" },
804
+ { prop: "followUser", domProp: "followUser", type: "special" },
805
+ { prop: "onMapClick", domProp: "onMapClick", type: "special" },
806
+ { prop: "onMarkerClick", domProp: "onMarkerClick", type: "special" },
807
+ { prop: "onMoveEnd", domProp: "onMoveEnd", type: "special" },
808
+ { prop: "onUserUpdate", domProp: "onUserUpdate", type: "special" },
809
+
751
810
  // ---- Image fit ----
752
811
  { prop: "fit", domProp: "objectFit", type: "style", unit: "none", reactive: true },
753
812
  { prop: "objectFit", domProp: "objectFit", type: "style", unit: "none", reactive: true },
@@ -8,11 +8,13 @@
8
8
 
9
9
  import { WidgetFactory } from "../widget-factory/index.js";
10
10
  import { colors } from "../utils/themes.js";
11
+ import { toREM } from "../utils/units.js";
11
12
  import { composeUpdate } from "../utils/composeUpdate.js";
12
13
  import { Container } from "./Container.js";
13
14
  import { Row } from "./Row.js";
14
15
  import { Text } from "./Text.js";
15
16
  import { Icon } from "./Icon.js";
17
+ import { SHADOW_LEVELS } from "../tools/shadow.js";
16
18
 
17
19
  /**
18
20
  * Props owned by the Accordion's own closure state. They are routed to the
@@ -41,14 +43,14 @@ const ACCORDION_PROP_KEYS = [
41
43
  * @param {number} [props.borderRadius=8] - Corner radius in pixels.
42
44
  * @param {string} [props.bgColor=colors.surface] - Background color of the container (used in 'contained' variant).
43
45
  * @param {string} [props.titleColor=colors.text] - Text color of the title when collapsed.
44
- * @param {string} [props.expandedColor=colors.primary] - Accent color applied to the title and background when expanded.
46
+ * @param {string} [props.expandedColor=colors.primary] - Accent color applied to the title-bar background when expanded.
45
47
  * @param {string|null} [props.border=null] - Explicit CSS border shorthand. Overrides variant-based border logic.
46
48
  * @param {string} [props.borderColor=colors.border] - Border color used in 'outlined' variant.
47
49
  * @param {number} [props.borderWidth=1] - Border width in pixels (outlined variant).
48
50
  * @param {number} [props.titleSize=14] - Font size of the title text in pixels.
49
51
  * @param {string} [props.titleWeight='500'] - Font weight of the title text.
50
- * @param {string} [props.titlePadding='12px 16px'] - CSS padding for the title bar.
51
- * @param {string} [props.contentPadding='16px'] - CSS padding applied to the inner content area.
52
+ * @param {string} [props.titlePadding='0.75rem 1rem'] - CSS padding for the title bar.
53
+ * @param {string} [props.contentPadding='1rem'] - CSS padding applied to the inner content area.
52
54
  * @param {string} [props.iconCollapsed='chevron_right'] - Material icon name shown when collapsed.
53
55
  * @param {string} [props.iconExpanded='expand_more'] - Material icon name shown when expanded.
54
56
  * @param {string} [props.iconColor=colors.textSecondary] - Color of the expand/collapse icon.
@@ -83,7 +85,7 @@ export const Accordion = (props) => {
83
85
  titleWeight = "500",
84
86
  titlePadding = "12px 16px",
85
87
  // Content
86
- contentPadding = "16px",
88
+ contentPadding = 16,
87
89
  // Icon
88
90
  iconCollapsed = "chevron_right",
89
91
  iconExpanded = "expand_more",
@@ -149,11 +151,11 @@ export const Accordion = (props) => {
149
151
  titleElement.textContent = currentTitle;
150
152
  }
151
153
 
152
- // Title color shifts to the accent color when expanded
153
- titleElement.style.color = isExpanded
154
- ? currentExpandedColor
155
- : currentTitleColor;
156
- titleElement.style.fontSize = `${currentTitleSize}px`;
154
+ // The accent marks the open state through the title-bar tint; the title
155
+ // itself keeps `titleColor`. Painting it with `primary` put #00A5FF words
156
+ // on a 6% primary wash (2.4:1) in the light theme.
157
+ titleElement.style.color = currentTitleColor;
158
+ titleElement.style.fontSize = toREM(currentTitleSize);
157
159
  titleElement.style.fontWeight = currentTitleWeight;
158
160
 
159
161
  // Swap icon based on current expanded state. `Icon` renders its glyph as
@@ -163,12 +165,12 @@ export const Accordion = (props) => {
163
165
  ? currentIconExpanded
164
166
  : currentIconCollapsed;
165
167
  iconElement.style.color = currentIconColor;
166
- iconElement.style.fontSize = `${currentIconSize}px`;
168
+ iconElement.style.fontSize = toREM(currentIconSize);
167
169
 
168
170
  // Title bar cursor and opacity reflect the disabled state
169
171
  titleBar.style.cursor = currentDisabled ? "not-allowed" : "pointer";
170
172
  titleBar.style.opacity = currentDisabled ? "0.5" : "1";
171
- titleBar.style.padding = currentTitlePadding;
173
+ titleBar.style.padding = toREM(currentTitlePadding);
172
174
 
173
175
  // Tint the title bar background slightly when expanded (contained only)
174
176
  if (currentVariant === "contained") {
@@ -202,23 +204,18 @@ export const Accordion = (props) => {
202
204
  container.style.backgroundColor = "transparent";
203
205
  }
204
206
 
205
- container.style.borderRadius = `${currentBorderRadius}px`;
207
+ container.style.borderRadius = toREM(currentBorderRadius);
206
208
  container.style.overflow = "hidden";
207
209
 
208
- // Predefined shadow presets keyed by elevation level
210
+ // The framework's depth scale, not a local copy of it (src/tools/shadow.js).
209
211
  if (currentElevation > 0) {
210
- const shadows = {
211
- 1: "0 1px 3px rgba(0,0,0,0.12)",
212
- 2: "0 3px 6px rgba(0,0,0,0.16)",
213
- 3: "0 6px 12px rgba(0,0,0,0.2)",
214
- 4: "0 10px 20px rgba(0,0,0,0.25)",
215
- };
216
- container.style.boxShadow = shadows[currentElevation] || shadows[2];
212
+ container.style.boxShadow =
213
+ SHADOW_LEVELS[currentElevation] || SHADOW_LEVELS[2];
217
214
  } else {
218
215
  container.style.boxShadow = "none";
219
216
  }
220
217
 
221
- contentInner.style.padding = currentContentPadding;
218
+ contentInner.style.padding = toREM(currentContentPadding);
222
219
  };
223
220
 
224
221
  // ========== HEIGHT ANIMATION ==========
@@ -238,7 +235,7 @@ export const Accordion = (props) => {
238
235
  clone.style.visibility = "hidden";
239
236
  clone.style.display = "block";
240
237
  clone.style.height = "auto";
241
- clone.style.padding = currentContentPadding;
238
+ clone.style.padding = toREM(currentContentPadding);
242
239
  document.body.appendChild(clone);
243
240
  const height = clone.offsetHeight;
244
241
  document.body.removeChild(clone);
@@ -508,7 +505,7 @@ export const Accordion = (props) => {
508
505
  currentTitlePadding = newProps.titlePadding;
509
506
  if (newProps.contentPadding !== undefined) {
510
507
  currentContentPadding = newProps.contentPadding;
511
- contentInner.style.padding = currentContentPadding;
508
+ contentInner.style.padding = toREM(currentContentPadding);
512
509
  }
513
510
  if (newProps.iconCollapsed !== undefined)
514
511
  currentIconCollapsed = newProps.iconCollapsed;
@@ -205,7 +205,7 @@ export const AdMob = (props) => {
205
205
  }
206
206
 
207
207
  const showBanner = () => {
208
- if (disposed || !autoShow || bannerVisible) return Promise.resolve(null);
208
+ if (disposed || bannerVisible) return Promise.resolve(null);
209
209
  return withPlugin((plugin) =>
210
210
  Promise.resolve(
211
211
  plugin.showBanner({
@@ -305,7 +305,12 @@ export const AdMob = (props) => {
305
305
  };
306
306
  container.onUnmount(dispose);
307
307
 
308
- container.onMount(showBanner);
308
+ // `autoShow` is the mount switch, nothing more. An app that holds the banner
309
+ // back for a paywall moment still has to be able to ask for it later with
310
+ // `container.show()`, so the flag must not gate that method.
311
+ container.onMount(() => {
312
+ if (autoShow) showBanner();
313
+ });
309
314
 
310
315
  refreshPlaceholder();
311
316