@proulr/sdui-components 0.1.16 → 0.1.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proulr/sdui-components",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "main": "./src/renderer/index.ts",
5
5
  "types": "./src/renderer/index.ts",
6
6
  "exports": {
@@ -54,15 +54,46 @@ type InboxCapabilitiesProps = {
54
54
  dataRef?: string;
55
55
  };
56
56
 
57
- function capabilityBlock(type: string, props: InboxCapabilitiesProps): BdcElement {
57
+ function leafBlock(type: string, props: Record<string, unknown>): BdcElement {
58
58
  return { type, props: { ...props }, children: [] };
59
59
  }
60
60
 
61
61
  export const ChatInboxCapabilities: BdcComponent = (props) =>
62
- capabilityBlock('chat_inbox_capabilities', props as InboxCapabilitiesProps);
62
+ leafBlock('chat_inbox_capabilities', props as InboxCapabilitiesProps);
63
63
 
64
64
  export const FlashInboxCapabilities: BdcComponent = (props) =>
65
- capabilityBlock('flash_inbox_capabilities', props as InboxCapabilitiesProps);
65
+ leafBlock('flash_inbox_capabilities', props as InboxCapabilitiesProps);
66
66
 
67
67
  export const ProfileVisitsCapabilities: BdcComponent = (props) =>
68
- capabilityBlock('profile_visits_capabilities', props as InboxCapabilitiesProps);
68
+ leafBlock('profile_visits_capabilities', props as InboxCapabilitiesProps);
69
+
70
+ export type FloatingCreateMenuActionProps = {
71
+ id: string;
72
+ label: string;
73
+ tone?: 'primary' | 'surface';
74
+ icon?: string;
75
+ actionId: string;
76
+ };
77
+
78
+ type FloatingCreateMenuProps = {
79
+ id?: string;
80
+ closedLabel?: string;
81
+ actions: FloatingCreateMenuActionProps[];
82
+ };
83
+
84
+ /** Overlay FAB “+” (sibling do Scroll) — ações via action_id do wire. */
85
+ export const FloatingCreateMenu: BdcComponent = (props) => {
86
+ const menu = props as FloatingCreateMenuProps;
87
+ return leafBlock('floating_create_menu', {
88
+ ...(menu.id ? { id: menu.id } : {}),
89
+ closedLabel: menu.closedLabel,
90
+ // Nested objects não passam por camelToSnake — normaliza action_id aqui.
91
+ actions: (menu.actions ?? []).map((action) => ({
92
+ id: action.id,
93
+ label: action.label,
94
+ tone: action.tone,
95
+ icon: action.icon,
96
+ action_id: action.actionId,
97
+ })),
98
+ });
99
+ };
package/src/bdc/index.ts CHANGED
@@ -20,11 +20,13 @@ export {
20
20
  ChatInboxCapabilities,
21
21
  EmptyState,
22
22
  FlashInboxCapabilities,
23
+ FloatingCreateMenu,
23
24
  InboxPersonRow,
24
25
  InboxSearchField,
25
26
  ProfileVisitsCapabilities,
26
27
  SegmentedTabs,
27
28
  } from './components/inbox';
29
+ export type { FloatingCreateMenuActionProps } from './components/inbox';
28
30
  export { TextField } from './components/forms';
29
31
  export { ProfileCompletionBanner, StoryRail } from './components/social';
30
32
  export {
@@ -10,11 +10,20 @@ type Props = {
10
10
  onAction: (actionId: string, vars?: Record<string, string>) => void;
11
11
  };
12
12
 
13
+ /** Blocos overlay (FAB etc.) — não competem por flex com o Scroll. */
14
+ const OVERLAY_BLOCK_TYPES = new Set(['floating_create_menu']);
15
+
13
16
  export function SduiScreenRenderer({ screen, onAction }: Props) {
14
17
  return (
15
18
  <SduiLayoutDebugFrame layer="renderer" style={styles.screen}>
16
19
  {screen.blocks.map((block) => (
17
- <SduiLayoutDebugFrame key={block.id} layer="block" extra={block.type} style={styles.block}>
20
+ <SduiLayoutDebugFrame
21
+ key={block.id}
22
+ layer="block"
23
+ extra={block.type}
24
+ style={OVERLAY_BLOCK_TYPES.has(block.type) ? styles.overlayBlock : styles.block}
25
+ pointerEvents={OVERLAY_BLOCK_TYPES.has(block.type) ? 'box-none' : undefined}
26
+ >
18
27
  {renderBlockTree(block, screen.data, onAction)}
19
28
  </SduiLayoutDebugFrame>
20
29
  ))}
@@ -25,4 +34,9 @@ export function SduiScreenRenderer({ screen, onAction }: Props) {
25
34
  const styles = StyleSheet.create({
26
35
  screen: { flex: 1, minHeight: 0, backgroundColor: colors.bg },
27
36
  block: { flex: 1, minHeight: 0 },
37
+ overlayBlock: {
38
+ ...StyleSheet.absoluteFill,
39
+ zIndex: 20,
40
+ elevation: 20,
41
+ },
28
42
  });
@@ -295,7 +295,9 @@ export function SduiChipRowBlock({ block, children }: SduiBlockRenderProps) {
295
295
  <ScrollView
296
296
  horizontal
297
297
  showsHorizontalScrollIndicator={false}
298
+ style={styles.chipRowScroll}
298
299
  contentContainerStyle={[styles.chipRow, isHeader && styles.chipRowOnHeader]}
300
+ keyboardShouldPersistTaps="handled"
299
301
  >
300
302
  {children}
301
303
  </ScrollView>
@@ -439,17 +441,27 @@ const styles = StyleSheet.create({
439
441
  fontWeight: '600',
440
442
  fontFamily: fonts.semibold,
441
443
  },
444
+ chipRowScroll: {
445
+ flexGrow: 0,
446
+ flexShrink: 0,
447
+ alignSelf: 'stretch',
448
+ },
442
449
  chipRow: {
443
450
  flexDirection: 'row',
444
- gap: spacing.sm,
451
+ alignItems: 'center',
452
+ gap: spacing.xs,
445
453
  paddingHorizontal: spacing.sm,
454
+ paddingVertical: 0,
446
455
  },
447
456
  chipRowOnHeader: {
448
- paddingHorizontal: 0,
457
+ paddingHorizontal: spacing.sm,
449
458
  },
450
459
  chip: {
451
- paddingHorizontal: spacing.md,
452
- paddingVertical: spacing.sm,
460
+ flexDirection: 'row',
461
+ alignItems: 'center',
462
+ alignSelf: 'center',
463
+ paddingHorizontal: spacing.sm + 2,
464
+ paddingVertical: spacing.xs,
453
465
  borderRadius: m3Shape.cornerFull,
454
466
  backgroundColor: m3Colors.surfaceContainerHigh,
455
467
  borderWidth: 1,
@@ -465,8 +477,8 @@ const styles = StyleSheet.create({
465
477
  },
466
478
  chipLabel: {
467
479
  color: m3Colors.onSurface,
468
- fontSize: 13,
469
- fontFamily: fonts.medium,
480
+ fontSize: 12,
481
+ fontFamily: fonts.semibold,
470
482
  },
471
483
  chipLabelActive: {
472
484
  color: m3Colors.onPrimaryContainer,
@@ -221,9 +221,18 @@ export function SduiProfileVisitsCapabilitiesBlock(props: SduiBlockRenderProps)
221
221
  return <CapabilitiesShell {...props} rendererKey="renderProfileVisitsCapabilities" />;
222
222
  }
223
223
 
224
+ export function SduiFloatingCreateMenuBlock(props: SduiBlockRenderProps) {
225
+ const hybrid = useSduiHybridRenderer();
226
+ if (typeof hybrid.renderFloatingCreateMenu !== 'function') return null;
227
+ return <>{hybrid.renderFloatingCreateMenu(props)}</>;
228
+ }
229
+
224
230
  const styles = StyleSheet.create({
225
231
  segmentTrack: {
226
232
  flexDirection: 'row',
233
+ flexGrow: 0,
234
+ flexShrink: 0,
235
+ alignSelf: 'stretch',
227
236
  gap: spacing.sm,
228
237
  backgroundColor: m3Colors.surfaceContainerHigh,
229
238
  borderRadius: m3Shape.cornerFull,
@@ -36,6 +36,7 @@ import {
36
36
  SduiInboxPersonRowBlock,
37
37
  SduiInboxSearchFieldBlock,
38
38
  SduiProfileVisitsCapabilitiesBlock,
39
+ SduiFloatingCreateMenuBlock,
39
40
  SduiSegmentedTabsBlock,
40
41
  } from './blocks/SduiInboxBlocks';
41
42
  import { SduiNativeAdBlock } from './blocks/SduiNativeAdBlock';
@@ -87,6 +88,7 @@ const REGISTRY: Record<string, SduiBlockComponent> = {
87
88
  chat_inbox_capabilities: SduiChatInboxCapabilitiesBlock,
88
89
  flash_inbox_capabilities: SduiFlashInboxCapabilitiesBlock,
89
90
  profile_visits_capabilities: SduiProfileVisitsCapabilitiesBlock,
91
+ floating_create_menu: SduiFloatingCreateMenuBlock,
90
92
  discover_grid: SduiDiscoverGridBlock,
91
93
  discover_profile_card: SduiDiscoverProfileCardBlock,
92
94
  discover_map: SduiDiscoverMapBlock,
@@ -102,6 +102,7 @@ export type SduiHybridRenderers = {
102
102
  renderChatInboxCapabilities?: (props: SduiNativeBlockRenderProps) => ReactNode;
103
103
  renderFlashInboxCapabilities?: (props: SduiNativeBlockRenderProps) => ReactNode;
104
104
  renderProfileVisitsCapabilities?: (props: SduiNativeBlockRenderProps) => ReactNode;
105
+ renderFloatingCreateMenu?: (props: SduiNativeBlockRenderProps) => ReactNode;
105
106
  };
106
107
 
107
108
  const SduiHybridRendererContext = createContext<SduiHybridRenderers>({});
@@ -73,15 +73,17 @@ export function SduiLayoutDebugFrame({
73
73
  layer,
74
74
  extra,
75
75
  style,
76
+ pointerEvents,
76
77
  children,
77
78
  }: {
78
79
  layer: SduiLayoutDebugLayer;
79
80
  extra?: string;
80
81
  style?: StyleProp<ViewStyle>;
82
+ pointerEvents?: 'auto' | 'none' | 'box-none' | 'box-only';
81
83
  children: ReactNode;
82
84
  }) {
83
85
  return (
84
- <View style={[sduiDebugViewStyle(layer), style]}>
86
+ <View style={[sduiDebugViewStyle(layer), style]} pointerEvents={pointerEvents}>
85
87
  <SduiLayoutDebugLabel layer={layer} extra={extra} />
86
88
  {children}
87
89
  </View>