@controleonline/ui-common 1.2.93 → 1.2.94

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.
@@ -0,0 +1,6 @@
1
+ # Homepage ADMIN/MANAGER — app-community#1056
2
+
3
+ Soft appearance is opt-in for HomePage only. Existing menu routes/parameters, permissions, stores and translations are preserved. App-provided homepage colors and components are used only in this appearance. Default consumers retain their current behavior.
4
+
5
+ Source: https://github.com/ControleOnline/app-community/issues/1056
6
+ Local evidence: 40 homepage tests and 34 runtime footer/zoom tests passed. No production authorization.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@controleonline/ui-common",
3
- "version": "1.2.93",
3
+ "version": "1.2.94",
4
4
  "author": "ControleOnline",
5
5
  "description": "ControleOnline Common Quasar UI Component",
6
6
  "license": "MIT",
@@ -1,10 +1,13 @@
1
1
  import React, {useLayoutEffect, useMemo} from 'react';
2
2
  import {Pressable, Text, View} from 'react-native';
3
- import Icon from 'react-native-vector-icons/Feather';
3
+ import LegacyIcon from 'react-native-vector-icons/Feather';
4
+ import HomeIcon from '@controleonline/../../src/components/HomeIcon';
4
5
  import {useTheme} from './DefaultProvider';
5
6
  import RuntimeInfoFooter from './RuntimeInfoFooter';
6
7
  import {resolveMenuRouteParams} from '../utils/menuNavigation';
7
8
  import createStyles from './BottomNavigationBar.styles';
9
+ import softenStyles from './BottomNavigationBar.soft.styles';
10
+ import {resolveHomepagePalette} from '@controleonline/../../src/styles/homepagePalette';
8
11
 
9
12
  const BottomNavigationBar = ({
10
13
  navigation,
@@ -14,7 +17,10 @@ const BottomNavigationBar = ({
14
17
  colors = {},
15
18
  testID = 'bottom-navigation',
16
19
  useModernWebChromeProps = false,
20
+ appearance = 'legacy',
17
21
  }) => {
22
+ const Icon = appearance === 'soft' ? HomeIcon : LegacyIcon;
23
+ colors = appearance === 'soft' ? resolveHomepagePalette(colors) : colors;
18
24
  const theme = useTheme?.() || {};
19
25
  const runtimeFooter = theme?.runtimeFooter || null;
20
26
  const registerBottomNavigation =
@@ -31,14 +37,14 @@ const BottomNavigationBar = ({
31
37
 
32
38
  const styles = useMemo(
33
39
  () =>
34
- createStyles({
40
+ softenStyles(createStyles({
35
41
  activeBackground,
36
42
  dockBackground,
37
43
  dockBorder,
38
44
  dockShadow,
39
45
  activeBorder,
40
46
  useModernWebChromeProps,
41
- }),
47
+ }), colors, appearance),
42
48
  [
43
49
  activeBackground,
44
50
  activeBorder,
@@ -46,6 +52,7 @@ const BottomNavigationBar = ({
46
52
  dockBorder,
47
53
  dockShadow,
48
54
  useModernWebChromeProps,
55
+ appearance,
49
56
  ],
50
57
  );
51
58
 
@@ -116,8 +123,11 @@ const BottomNavigationBar = ({
116
123
  ? [styles.host, styles.hostPointerEventsBoxNone]
117
124
  : styles.host;
118
125
  const footerProps = {
126
+ appearance,
119
127
  appVersion: runtimeFooter?.appVersion,
120
- colors: runtimeFooter?.colors || {},
128
+ colors: appearance === 'soft'
129
+ ? {...runtimeFooter?.colors, footerBackground: colors.footerBackground, footerText: colors.footerText}
130
+ : runtimeFooter?.colors || {},
121
131
  mainCompany: runtimeFooter?.mainCompany,
122
132
  device: runtimeFooter?.device,
123
133
  useModernWebChromeProps,
@@ -0,0 +1,28 @@
1
+ import {Platform} from 'react-native';
2
+
3
+ // Only the homepage opts into this chrome; preserve all default navigation styles.
4
+ export default (styles, colors, appearance) => appearance !== 'soft' ? styles : {
5
+ ...styles,
6
+ dock: [styles.dock, {
7
+ paddingHorizontal: 0,
8
+ paddingTop: 0,
9
+ paddingBottom: 0,
10
+ borderWidth: 0,
11
+ borderTopWidth: 1,
12
+ borderColor: colors.navigationBorder,
13
+ borderTopLeftRadius: 0,
14
+ borderTopRightRadius: 0,
15
+ elevation: 0,
16
+ shadowOpacity: 0,
17
+ ...(Platform.OS === 'web' ? {boxShadow: 'none'} : {}),
18
+ }],
19
+ itemsRow: [styles.itemsRow, {minHeight: 64, paddingHorizontal: 12, paddingVertical: 5}],
20
+ item: [styles.item, {minHeight: 54, borderRadius: 12}],
21
+ itemLabel: [styles.itemLabel, {fontSize: 11, fontWeight: '400'}],
22
+ footerSlot: [styles.footerSlot, {
23
+ borderTopWidth: 1,
24
+ borderColor: colors.navigationBorder,
25
+ paddingHorizontal: 0,
26
+ minHeight: 28,
27
+ }],
28
+ };
@@ -19,6 +19,7 @@ const {
19
19
  } = require('@controleonline/ui-common/src/react/utils/bottomNavigationToolbar');
20
20
 
21
21
  const RuntimeBottomNavigationBar = ({
22
+ appearance = 'legacy',
22
23
  activeRouteName: activeRouteNameProp,
23
24
  colors: colorsOverride,
24
25
  disabled: disabledOverride,
@@ -159,6 +160,7 @@ const RuntimeBottomNavigationBar = ({
159
160
 
160
161
  return (
161
162
  <BottomNavigationBar
163
+ appearance={appearance}
162
164
  activeRouteName={effectiveActiveRoute}
163
165
  colors={colors}
164
166
  disabled={isDisabled}
@@ -0,0 +1,5 @@
1
+ // Keep the native safe area outside the centered content row.
2
+ export default (appearance, platform, bottomInset) => appearance === 'soft' ? {
3
+ contentPadding: 4,
4
+ safeAreaBottom: platform === 'web' ? 0 : Math.max(Number(bottomInset) || 0, 0),
5
+ } : null;
@@ -22,6 +22,7 @@ import {
22
22
  } from '@controleonline/ui-common/src/react/utils/runtimeFooter';
23
23
  import styles from './RuntimeInfoFooter.styles';
24
24
  import RuntimeFooterMarqueeText from './RuntimeFooterMarqueeText';
25
+ import resolveHomeFooterSpacing from './RuntimeInfoFooter.home.spacing';
25
26
 
26
27
  const ROTATION_INTERVAL_MS = 4000;
27
28
  const COMPACT_BREAKPOINT = 720;
@@ -66,6 +67,7 @@ const RuntimeInfoFooter = ({
66
67
  device,
67
68
  colors,
68
69
  useModernWebChromeProps = false,
70
+ appearance = 'legacy',
69
71
  }) => {
70
72
  const {width} = useWindowDimensions();
71
73
  const insets = useSafeAreaInsets();
@@ -258,6 +260,7 @@ const RuntimeInfoFooter = ({
258
260
  : inlineText
259
261
  ) || primaryText || device?.id || '';
260
262
  const backgroundColor = colors?.footerBackground;
263
+ const homeSpacing = resolveHomeFooterSpacing(appearance, Platform.OS, insets.bottom);
261
264
  const borderColor = colors?.footerBorder;
262
265
  const textColor = resolveVisibleFooterTextColor(colors);
263
266
  const loadingColor = colors?.footerLink || colors?.primary || textColor;
@@ -267,7 +270,9 @@ const RuntimeInfoFooter = ({
267
270
  : styles.shell;
268
271
 
269
272
  return (
270
- <View {...shellProps} style={shellStyle}>
273
+ <View {...shellProps} style={[shellStyle, homeSpacing && {
274
+ paddingBottom: homeSpacing.safeAreaBottom, backgroundColor,
275
+ }]}>
271
276
  <View
272
277
  testID="runtime-info-footer"
273
278
  style={[
@@ -276,7 +281,8 @@ const RuntimeInfoFooter = ({
276
281
  {
277
282
  backgroundColor,
278
283
  borderTopColor: borderColor,
279
- paddingBottom: bottomInset,
284
+ paddingBottom: homeSpacing ? homeSpacing.contentPadding : bottomInset,
285
+ ...(homeSpacing && !showDebugInfo ? {paddingTop: homeSpacing.contentPadding} : {}),
280
286
  },
281
287
  ]}>
282
288
  <View style={styles.primaryRow}>
@@ -156,6 +156,7 @@ const useDisplayUri = uri => {
156
156
 
157
157
  const UserAvatar = ({
158
158
  imageUrl,
159
+ imageHeaders,
159
160
  email,
160
161
  name,
161
162
  size = 40,
@@ -215,7 +216,8 @@ const UserAvatar = ({
215
216
  <View style={containerStyle}>
216
217
  {displayUri ? (
217
218
  <Image
218
- source={{uri: displayUri}}
219
+ source={imageHeaders && Platform.OS !== 'web' && displayUri === imageUrl
220
+ ? {uri: displayUri, headers: imageHeaders} : {uri: displayUri}}
219
221
  style={styles.image}
220
222
  onError={() => setSourceIndex(index => index + 1)}
221
223
  />