@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 +1 -1
- package/src/bdc/components/inbox.tsx +35 -4
- package/src/bdc/index.ts +2 -0
- package/src/renderer/SduiScreenRenderer.tsx +15 -1
- package/src/renderer/blocks/SduiDiscoverBlocks.tsx +18 -6
- package/src/renderer/blocks/SduiInboxBlocks.tsx +9 -0
- package/src/renderer/sdui-component-registry.tsx +2 -0
- package/src/renderer/sdui-hybrid-renderer-context.tsx +1 -0
- package/src/renderer/sdui-layout-debug.tsx +3 -1
package/package.json
CHANGED
|
@@ -54,15 +54,46 @@ type InboxCapabilitiesProps = {
|
|
|
54
54
|
dataRef?: string;
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
-
function
|
|
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
|
-
|
|
62
|
+
leafBlock('chat_inbox_capabilities', props as InboxCapabilitiesProps);
|
|
63
63
|
|
|
64
64
|
export const FlashInboxCapabilities: BdcComponent = (props) =>
|
|
65
|
-
|
|
65
|
+
leafBlock('flash_inbox_capabilities', props as InboxCapabilitiesProps);
|
|
66
66
|
|
|
67
67
|
export const ProfileVisitsCapabilities: BdcComponent = (props) =>
|
|
68
|
-
|
|
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
|
|
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
|
-
|
|
451
|
+
alignItems: 'center',
|
|
452
|
+
gap: spacing.xs,
|
|
445
453
|
paddingHorizontal: spacing.sm,
|
|
454
|
+
paddingVertical: 0,
|
|
446
455
|
},
|
|
447
456
|
chipRowOnHeader: {
|
|
448
|
-
paddingHorizontal:
|
|
457
|
+
paddingHorizontal: spacing.sm,
|
|
449
458
|
},
|
|
450
459
|
chip: {
|
|
451
|
-
|
|
452
|
-
|
|
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:
|
|
469
|
-
fontFamily: fonts.
|
|
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>
|