@proulr/sdui-components 0.1.33 → 0.1.37

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.33",
3
+ "version": "0.1.37",
4
4
  "type": "module",
5
5
  "main": "./src/renderer/index.ts",
6
6
  "types": "./src/renderer/index.ts",
@@ -37,7 +37,7 @@
37
37
  "access": "public"
38
38
  },
39
39
  "dependencies": {
40
- "@proulr/sdui-contract": "^0.1.5"
40
+ "@proulr/sdui-contract": "^0.1.10"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "expo-blur": ">=15",
@@ -49,6 +49,16 @@ type ButtonProps = LayoutProps & {
49
49
 
50
50
  export const Button: BdcComponent = (props) => layoutBlock('button', props as ButtonProps);
51
51
 
52
+ type IconProps = LayoutProps & {
53
+ /** AppIconName kebab-case (catalog) — ex.: 'gift', 'share'. */
54
+ name: string;
55
+ size?: number;
56
+ /** ColorToken do tema M3 — ex.: 'primary', 'onSurfaceVariant'. */
57
+ color?: string;
58
+ };
59
+
60
+ export const Icon: BdcComponent = (props) => layoutBlock('icon', props as IconProps);
61
+
52
62
  type InfoBannerProps = LayoutProps & {
53
63
  message: string;
54
64
  };
package/src/bdc/index.ts CHANGED
@@ -3,6 +3,7 @@ export {
3
3
  Button,
4
4
  Card,
5
5
  Column,
6
+ Icon,
6
7
  InfoBanner,
7
8
  ListItem,
8
9
  NativeAd,
@@ -75,6 +75,8 @@ export const APP_ICON_NAMES = [
75
75
  'signal',
76
76
  'hourglass',
77
77
  'bell',
78
+ 'share',
79
+ 'gift',
78
80
  ] as const;
79
81
 
80
82
  export type AppIconName = (typeof APP_ICON_NAMES)[number];
@@ -2,7 +2,8 @@ import React from 'react';
2
2
  import { Platform, ScrollView, StyleSheet, Text, View } from 'react-native';
3
3
  import type { SduiBlock } from '@proulr/sdui-contract';
4
4
  import { AppButton } from '../ui/AppButton';
5
- import { colors, m3Type, spacing } from '../theme/proulr-theme';
5
+ import { AppIcon, isAppIconName } from '../ui/app-icon';
6
+ import { colors, m3Colors, m3Type, spacing } from '../theme/proulr-theme';
6
7
  import {
7
8
  resolveGapProp,
8
9
  resolvePaddingProp,
@@ -135,6 +136,27 @@ export function SduiButtonBlock({ block, onAction }: SduiBlockRenderProps) {
135
136
  );
136
137
  }
137
138
 
139
+ /**
140
+ * Bloco genérico de ícone vetorial (AppIcon). Wire: `name` = AppIconName
141
+ * kebab-case, `size` em px, `color` = ColorToken do tema. O container aceita
142
+ * StyleWire (background, borda, padding) para composições tipo hero circle.
143
+ */
144
+ export function SduiIconBlock({ block }: SduiBlockRenderProps) {
145
+ const name = typeof block.props.name === 'string' ? block.props.name : '';
146
+ if (!isAppIconName(name)) return null;
147
+
148
+ const size = typeof block.props.size === 'number' ? block.props.size : spacing.lg;
149
+ const colorToken = typeof block.props.color === 'string' ? block.props.color : undefined;
150
+ const color =
151
+ (colorToken ? m3Colors[colorToken as keyof typeof m3Colors] : undefined) ?? colors.onSurface;
152
+
153
+ return (
154
+ <View style={resolveViewStyleProps(block.props.style as Record<string, unknown>)}>
155
+ <AppIcon name={name} size={size} color={color} />
156
+ </View>
157
+ );
158
+ }
159
+
138
160
  export function SduiSpacerBlock({ block }: SduiBlockRenderProps) {
139
161
  const height = typeof block.props.height === 'number' ? block.props.height : spacing.md;
140
162
  return <View style={{ height }} />;
@@ -3,6 +3,7 @@ import type { SduiBlock } from '@proulr/sdui-contract';
3
3
  import {
4
4
  SduiButtonBlock,
5
5
  SduiColumnBlock,
6
+ SduiIconBlock,
6
7
  SduiInfoBannerBlock,
7
8
  SduiRowBlock,
8
9
  SduiScrollBlock,
@@ -74,6 +75,7 @@ const REGISTRY: Record<string, SduiBlockComponent> = {
74
75
  row: SduiRowBlock,
75
76
  scroll: SduiScrollBlock,
76
77
  button: SduiButtonBlock,
78
+ icon: SduiIconBlock,
77
79
  spacer: SduiSpacerBlock,
78
80
  info_banner: SduiInfoBannerBlock,
79
81
  native_ad: SduiNativeAdBlock,
@@ -69,6 +69,7 @@ export function resolveTextStyleProps(
69
69
  color: resolveColor(style.color),
70
70
  marginTop: resolveSpacing(style.margin_top),
71
71
  opacity: style.opacity,
72
+ textAlign: style.text_align,
72
73
  };
73
74
  }
74
75
 
@@ -1892,6 +1892,99 @@ export function AppChromeBellGlyph({ color = m3Colors.primary, size = 24 }: AppC
1892
1892
  );
1893
1893
  }
1894
1894
 
1895
+ /** Share / export — box with upward arrow. */
1896
+ export function AppChromeShareGlyph({ color = m3Colors.primary, size = 24 }: AppChromeGlyphProps) {
1897
+ const stroke = strokeFor(size);
1898
+ return (
1899
+ <View style={{ width: size, height: size, alignItems: 'center', justifyContent: 'center' }}>
1900
+ <View
1901
+ style={{
1902
+ position: 'absolute',
1903
+ bottom: size * 0.18,
1904
+ width: size * 0.62,
1905
+ height: size * 0.42,
1906
+ borderWidth: stroke,
1907
+ borderTopWidth: 0,
1908
+ borderColor: color,
1909
+ borderBottomLeftRadius: size * 0.1,
1910
+ borderBottomRightRadius: size * 0.1,
1911
+ }}
1912
+ />
1913
+ <View
1914
+ style={{
1915
+ position: 'absolute',
1916
+ top: size * 0.16,
1917
+ width: stroke,
1918
+ height: size * 0.38,
1919
+ backgroundColor: color,
1920
+ borderRadius: 1,
1921
+ }}
1922
+ />
1923
+ <View
1924
+ style={{
1925
+ position: 'absolute',
1926
+ top: size * 0.14,
1927
+ width: size * 0.28,
1928
+ height: size * 0.28,
1929
+ borderLeftWidth: stroke,
1930
+ borderTopWidth: stroke,
1931
+ borderColor: color,
1932
+ transform: [{ rotate: '45deg' }],
1933
+ }}
1934
+ />
1935
+ </View>
1936
+ );
1937
+ }
1938
+
1939
+ /** Gift / referral reward — box with ribbon. */
1940
+ export function AppChromeGiftGlyph({ color = m3Colors.primary, size = 24 }: AppChromeGlyphProps) {
1941
+ const stroke = strokeFor(size);
1942
+ const box = size * 0.55;
1943
+ return (
1944
+ <View style={{ width: size, height: size, alignItems: 'center', justifyContent: 'center' }}>
1945
+ <View
1946
+ style={{
1947
+ width: box,
1948
+ height: box * 0.72,
1949
+ marginTop: size * 0.12,
1950
+ borderWidth: stroke,
1951
+ borderColor: color,
1952
+ borderRadius: size * 0.06,
1953
+ }}
1954
+ />
1955
+ <View
1956
+ style={{
1957
+ position: 'absolute',
1958
+ top: size * 0.22,
1959
+ width: box,
1960
+ height: stroke,
1961
+ backgroundColor: color,
1962
+ }}
1963
+ />
1964
+ <View
1965
+ style={{
1966
+ position: 'absolute',
1967
+ top: size * 0.28,
1968
+ width: stroke,
1969
+ height: box * 0.72,
1970
+ backgroundColor: color,
1971
+ }}
1972
+ />
1973
+ <View
1974
+ style={{
1975
+ position: 'absolute',
1976
+ top: size * 0.1,
1977
+ width: size * 0.22,
1978
+ height: size * 0.16,
1979
+ borderWidth: stroke,
1980
+ borderColor: color,
1981
+ borderRadius: size * 0.11,
1982
+ }}
1983
+ />
1984
+ </View>
1985
+ );
1986
+ }
1987
+
1895
1988
  const styles = StyleSheet.create({
1896
1989
  crosshair: {
1897
1990
  position: 'absolute',
@@ -47,6 +47,8 @@ import {
47
47
  AppChromeRepostGlyph,
48
48
  AppChromeSearchGlyph,
49
49
  AppChromeSendGlyph,
50
+ AppChromeShareGlyph,
51
+ AppChromeGiftGlyph,
50
52
  AppChromeSettingsGlyph,
51
53
  AppChromeShieldGlyph,
52
54
  AppChromeSignalGlyph,
@@ -161,6 +163,8 @@ const ICON_REGISTRY: Record<AppIconName, ComponentType<AppChromeGlyphProps>> = {
161
163
  signal: AppChromeSignalGlyph,
162
164
  hourglass: AppChromeHourglassGlyph,
163
165
  bell: AppChromeBellGlyph,
166
+ share: AppChromeShareGlyph,
167
+ gift: AppChromeGiftGlyph,
164
168
  };
165
169
 
166
170
  export type AppIconProps = {