@proulr/sdui-components 0.1.22 → 0.1.25

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.22",
3
+ "version": "0.1.25",
4
4
  "type": "module",
5
5
  "main": "./src/renderer/index.ts",
6
6
  "types": "./src/renderer/index.ts",
@@ -25,13 +25,14 @@
25
25
  "typecheck": "tsc --noEmit",
26
26
  "prepublishOnly": "npm run typecheck",
27
27
  "lint": "eslint .",
28
- "lint:fix": "eslint . --fix"
28
+ "lint:fix": "eslint . --fix",
29
+ "version:sync": "node ../scripts/proulr-bump-and-sync-deps.mjs"
29
30
  },
30
31
  "publishConfig": {
31
32
  "access": "public"
32
33
  },
33
34
  "dependencies": {
34
- "@proulr/sdui-contract": "^0.1.0"
35
+ "@proulr/sdui-contract": "^0.1.4"
35
36
  },
36
37
  "peerDependencies": {
37
38
  "expo-blur": ">=15",
@@ -25,6 +25,7 @@ export const ProfileView: BdcComponent = (props) => nativeBlock('profile_view',
25
25
  export const ProfileSelf: BdcComponent = (props) => nativeBlock('profile_self', props);
26
26
  export const ProfileSetup: BdcComponent = (props) => nativeBlock('profile_setup', props);
27
27
  export const ProfileOnboarding: BdcComponent = (props) => nativeBlock('profile_onboarding', props);
28
+ export const ProfileReport: BdcComponent = (props) => nativeBlock('profile_report', props);
28
29
  export const AlbumGrid: BdcComponent = (props) => nativeBlock('album_grid', props);
29
30
  export const AlbumDetail: BdcComponent = (props) => nativeBlock('album_detail', props);
30
31
  export const NewPostComposer: BdcComponent = (props) => nativeBlock('new_post_composer', props);
package/src/bdc/index.ts CHANGED
@@ -37,6 +37,7 @@ export {
37
37
  NewStoryComposer,
38
38
  PostComments,
39
39
  ProfileOnboarding,
40
+ ProfileReport,
40
41
  ProfileSelf,
41
42
  ProfileSetup,
42
43
  ProfileView,
@@ -3,7 +3,6 @@ import {
3
3
  FlatList,
4
4
  Image,
5
5
  Pressable,
6
- ScrollView,
7
6
  StyleSheet,
8
7
  Text,
9
8
  View,
@@ -12,6 +11,8 @@ import {
12
11
  import { LinearGradient } from 'expo-linear-gradient';
13
12
  import type { SduiBlock } from '@proulr/sdui-contract';
14
13
  import { TextField as UiTextField } from '../ui/TextField';
14
+ import { Chip } from '../ui/Chip';
15
+ import { ChipRow } from '../ui/ChipRow';
15
16
  import { AppIcon } from '../ui/app-icon';
16
17
  import { colors, fonts, gradients, m3Colors, m3Elevation, m3Shape, spacing } from '../theme/proulr-theme';
17
18
  import { resolveDataRef, resolveDataRefString } from '../lib/resolve-data-ref';
@@ -271,20 +272,16 @@ export function SduiChipBlock({ block, onAction }: SduiBlockRenderProps) {
271
272
  const active = readBooleanProp(block, 'active');
272
273
  const variant = readStringProp(block, 'variant') ?? 'default';
273
274
  const isHeader = variant === 'on_header';
275
+ const displayLabel = glyph ? `${glyph} ${label}` : label;
274
276
 
275
277
  return (
276
- <Pressable
277
- style={[styles.chip, isHeader ? styles.chipOnHeader : null, active && styles.chipActive]}
278
- onPress={() => actionId && onAction(actionId, actionParams)}
278
+ <Chip
279
+ label={displayLabel}
280
+ active={active}
279
281
  disabled={!actionId}
280
- >
281
- {glyph ? (
282
- <Text style={[styles.chipLabel, active && styles.chipLabelActive]} accessibilityElementsHidden>
283
- {glyph}{' '}
284
- </Text>
285
- ) : null}
286
- <Text style={[styles.chipLabel, active && styles.chipLabelActive]}>{label}</Text>
287
- </Pressable>
282
+ variant={isHeader ? 'onHeader' : 'default'}
283
+ onPress={() => actionId && onAction(actionId, actionParams)}
284
+ />
288
285
  );
289
286
  }
290
287
 
@@ -292,21 +289,7 @@ export function SduiChipRowBlock({ block, children }: SduiBlockRenderProps) {
292
289
  const variant = readStringProp(block, 'variant') ?? 'default';
293
290
  const isHeader = variant === 'on_header';
294
291
 
295
- if (children) {
296
- return (
297
- <ScrollView
298
- horizontal
299
- showsHorizontalScrollIndicator={false}
300
- style={styles.chipRowScroll}
301
- contentContainerStyle={[styles.chipRow, isHeader && styles.chipRowOnHeader]}
302
- keyboardShouldPersistTaps="handled"
303
- >
304
- {children}
305
- </ScrollView>
306
- );
307
- }
308
-
309
- return <View style={[styles.chipRow, isHeader && styles.chipRowOnHeader]}>{children}</View>;
292
+ return <ChipRow variant={isHeader ? 'onHeader' : 'default'}>{children}</ChipRow>;
310
293
  }
311
294
 
312
295
  export function SduiTextFieldBlock({ block, data, onAction }: SduiBlockRenderProps) {
@@ -446,49 +429,6 @@ const styles = StyleSheet.create({
446
429
  fontWeight: '600',
447
430
  fontFamily: fonts.semibold,
448
431
  },
449
- chipRowScroll: {
450
- flexGrow: 0,
451
- flexShrink: 0,
452
- alignSelf: 'stretch',
453
- },
454
- chipRow: {
455
- flexDirection: 'row',
456
- alignItems: 'center',
457
- gap: spacing.xs,
458
- paddingHorizontal: spacing.sm,
459
- paddingVertical: 0,
460
- },
461
- chipRowOnHeader: {
462
- paddingHorizontal: spacing.sm,
463
- },
464
- chip: {
465
- flexDirection: 'row',
466
- alignItems: 'center',
467
- alignSelf: 'center',
468
- paddingHorizontal: spacing.sm + 2,
469
- paddingVertical: spacing.xs,
470
- borderRadius: m3Shape.cornerFull,
471
- backgroundColor: m3Colors.surfaceContainerHigh,
472
- borderWidth: 1,
473
- borderColor: m3Colors.outline,
474
- },
475
- chipOnHeader: {
476
- backgroundColor: 'rgba(255,255,255,0.06)',
477
- borderColor: 'rgba(255,255,255,0.08)',
478
- },
479
- chipActive: {
480
- backgroundColor: m3Colors.primaryContainer,
481
- borderColor: m3Colors.primary,
482
- },
483
- chipLabel: {
484
- color: m3Colors.onSurface,
485
- fontSize: 12,
486
- fontFamily: fonts.semibold,
487
- },
488
- chipLabelActive: {
489
- color: m3Colors.onPrimaryContainer,
490
- fontFamily: fonts.semibold,
491
- },
492
432
  textField: {
493
433
  flex: 1,
494
434
  marginBottom: 0,
@@ -25,6 +25,7 @@ function NativeBlockShell({
25
25
  | 'renderProfileSelf'
26
26
  | 'renderProfileSetup'
27
27
  | 'renderProfileOnboarding'
28
+ | 'renderProfileReport'
28
29
  | 'renderAlbumGrid'
29
30
  | 'renderAlbumDetail'
30
31
  | 'renderNewPostComposer'
@@ -97,6 +98,10 @@ export function SduiProfileOnboardingBlock(props: SduiBlockRenderProps) {
97
98
  return <NativeBlockShell {...props} rendererKey="renderProfileOnboarding" fallbackLabel="Onboarding" />;
98
99
  }
99
100
 
101
+ export function SduiProfileReportBlock(props: SduiBlockRenderProps) {
102
+ return <NativeBlockShell {...props} rendererKey="renderProfileReport" fallbackLabel="Denunciar" />;
103
+ }
104
+
100
105
  export function SduiAlbumGridBlock(props: SduiBlockRenderProps) {
101
106
  return <NativeBlockShell {...props} rendererKey="renderAlbumGrid" fallbackLabel="Álbuns" />;
102
107
  }
@@ -50,6 +50,7 @@ import {
50
50
  SduiProfileOnboardingBlock,
51
51
  SduiProfileSelfBlock,
52
52
  SduiProfileSetupBlock,
53
+ SduiProfileReportBlock,
53
54
  SduiProfileViewBlock,
54
55
  SduiSocialPostFeedBlock,
55
56
  SduiSocialProfileBlock,
@@ -103,6 +104,7 @@ const REGISTRY: Record<string, SduiBlockComponent> = {
103
104
  profile_self: SduiProfileSelfBlock,
104
105
  profile_setup: SduiProfileSetupBlock,
105
106
  profile_onboarding: SduiProfileOnboardingBlock,
107
+ profile_report: SduiProfileReportBlock,
106
108
  album_grid: SduiAlbumGridBlock,
107
109
  album_detail: SduiAlbumDetailBlock,
108
110
  new_post_composer: SduiNewPostComposerBlock,
@@ -61,6 +61,7 @@ export type SduiHybridRenderers = {
61
61
  renderProfileSelf?: (props: SduiNativeBlockRenderProps) => ReactNode;
62
62
  renderProfileSetup?: (props: SduiNativeBlockRenderProps) => ReactNode;
63
63
  renderProfileOnboarding?: (props: SduiNativeBlockRenderProps) => ReactNode;
64
+ renderProfileReport?: (props: SduiNativeBlockRenderProps) => ReactNode;
64
65
  renderAlbumGrid?: (props: SduiNativeBlockRenderProps) => ReactNode;
65
66
  renderAlbumDetail?: (props: SduiNativeBlockRenderProps) => ReactNode;
66
67
  renderNewPostComposer?: (props: SduiNativeBlockRenderProps) => ReactNode;
@@ -6,11 +6,13 @@ export function Chip({
6
6
  active,
7
7
  onPress,
8
8
  variant = 'default',
9
+ disabled,
9
10
  }: {
10
11
  label: string;
11
12
  active?: boolean;
12
13
  onPress?: () => void;
13
14
  variant?: 'default' | 'onHeader';
15
+ disabled?: boolean;
14
16
  }) {
15
17
  const isHeader = variant === 'onHeader';
16
18
 
@@ -19,7 +21,7 @@ export function Chip({
19
21
  ? { backgroundColor: m3Colors.onPrimary, borderColor: m3Colors.onPrimary }
20
22
  : { backgroundColor: m3Colors.secondaryContainer, borderColor: m3Colors.outline }
21
23
  : isHeader
22
- ? { backgroundColor: colors.surfaceGlass, borderColor: 'rgba(255,255,255,0.28)' }
24
+ ? { backgroundColor: colors.surfaceGlass, borderColor: colors.chromePillBorder }
23
25
  : { backgroundColor: m3Colors.surfaceContainerHigh, borderColor: m3Colors.outline };
24
26
 
25
27
  const textColor = active
@@ -31,7 +33,11 @@ export function Chip({
31
33
  : m3Colors.onSurfaceVariant;
32
34
 
33
35
  return (
34
- <Pressable onPress={onPress} style={[styles.chip, isHeader && styles.chipOnHeader, containerStyle]}>
36
+ <Pressable
37
+ onPress={onPress}
38
+ disabled={disabled}
39
+ style={[styles.chip, isHeader && styles.chipOnHeader, containerStyle]}
40
+ >
35
41
  <Text
36
42
  style={{
37
43
  color: textColor,
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ import { ScrollView, StyleSheet, View } from 'react-native';
3
+ import { CHROME_HORIZONTAL_INSET } from '../theme/chrome-layout';
4
+ import { spacing } from '../theme/proulr-theme';
5
+
6
+ type ChipRowProps = {
7
+ children: React.ReactNode;
8
+ variant?: 'default' | 'onHeader';
9
+ };
10
+
11
+ /** Horizontal filter chip scroller — single chrome style for Discover, inbox, etc. */
12
+ export function ChipRow({ children, variant = 'default' }: ChipRowProps) {
13
+ const isHeader = variant === 'onHeader';
14
+
15
+ if (!children) {
16
+ return <View style={[styles.content, isHeader && styles.contentOnHeader]} />;
17
+ }
18
+
19
+ return (
20
+ <ScrollView
21
+ horizontal
22
+ showsHorizontalScrollIndicator={false}
23
+ style={styles.scroll}
24
+ contentContainerStyle={[styles.content, isHeader && styles.contentOnHeader]}
25
+ keyboardShouldPersistTaps="handled"
26
+ nestedScrollEnabled
27
+ >
28
+ {children}
29
+ </ScrollView>
30
+ );
31
+ }
32
+
33
+ const styles = StyleSheet.create({
34
+ scroll: {
35
+ flexGrow: 0,
36
+ flexShrink: 0,
37
+ alignSelf: 'stretch',
38
+ },
39
+ content: {
40
+ flexDirection: 'row',
41
+ alignItems: 'center',
42
+ gap: spacing.xs,
43
+ paddingHorizontal: spacing.sm,
44
+ paddingVertical: 0,
45
+ },
46
+ contentOnHeader: {
47
+ paddingLeft: CHROME_HORIZONTAL_INSET,
48
+ paddingRight: CHROME_HORIZONTAL_INSET,
49
+ },
50
+ });
@@ -4,6 +4,7 @@ export { AppLoadingSpinner } from './AppLoadingSpinner';
4
4
  export { AuthStepShell } from './AuthStepShell';
5
5
  export { Card } from './Card';
6
6
  export { Chip } from './Chip';
7
+ export { ChipRow } from './ChipRow';
7
8
  export { ChromeGlassLayer, ChromeGlassShell } from './ChromeGlass';
8
9
  export { ComposeAudiencePill } from './compose-audience-pill';
9
10
  export {
@@ -3,6 +3,7 @@ export { AppButton } from './AppButton';
3
3
  export { AppLoadingSpinner } from './AppLoadingSpinner';
4
4
  export { Card } from './Card';
5
5
  export { Chip } from './Chip';
6
+ export { ChipRow } from './ChipRow';
6
7
  export { DateField } from './DateField';
7
8
  export { HintText } from './HintText';
8
9
  export { InfoBanner } from './InfoBanner';