acore-mobile-ui
v0.1.0
Published
ACore Mobile UI components for React Native CLI and Expo.
Readme
acore-mobile-ui
ACore Mobile UI es una libreria de componentes React Native para construir apps SaaS, CRM, dashboards operativos, formularios, listas, navegacion, feedback, overlays y patrones de pantalla.
El paquete es dark-first, no depende de una UI kit externa y funciona tanto en Expo como en React Native CLI. La app consumidora mantiene su logica de negocio; la libreria entrega tokens, tema, componentes y composiciones visuales reutilizables.
Resumen
- Componentes React Native para apps mobile de producto.
- Compatible con Expo y React Native CLI.
- Dark-first con provider de tema.
- Zero external UI kit dependencies.
- Componentes tactiles con estados disabled, loading, error, empty y feedback.
- Patterns de pantalla para acelerar dashboards, formularios, listas y detalle.
- Sin dependencia obligatoria de Expo.
Requisitos
| Dependency | Version |
| --- | --- |
| react | >=18 |
| react-native | >=0.74 |
| expo | Opcional, recomendado SDK 51+ |
Instalacion
npm install acore-mobile-ui react react-nativepnpm add acore-mobile-ui react react-nativeyarn add acore-mobile-ui react react-nativeexpo no es peer dependency. Puedes usar este paquete en Expo managed workflow o en React Native CLI.
Quick start
1. Envuelve tu app con AcoreThemeProvider
import { AcoreThemeProvider } from 'acore-mobile-ui';
export default function App() {
return (
<AcoreThemeProvider>
<YourApp />
</AcoreThemeProvider>
);
}2. Usa componentes
import {
AcoreButton,
AcoreCard,
AcoreInput,
AcoreStack,
AcoreText,
} from 'acore-mobile-ui';
export function LeadForm() {
return (
<AcoreCard>
<AcoreStack gap={3}>
<AcoreText variant="title">New lead</AcoreText>
<AcoreInput
label="Lead name"
placeholder="John Smith"
value={name}
onChangeText={setName}
/>
<AcoreButton fullWidth onPress={saveLead}>
Save lead
</AcoreButton>
</AcoreStack>
</AcoreCard>
);
}3. Accede al tema desde cualquier componente
import { View } from 'react-native';
import { useAcoreTheme } from 'acore-mobile-ui';
export function ScreenShell({ children }) {
const theme = useAcoreTheme();
return (
<View
style={{
flex: 1,
backgroundColor: theme.colors.bgPage,
padding: theme.spacing[4],
}}
>
{children}
</View>
);
}4. Personaliza colores
import { AcoreThemeProvider } from 'acore-mobile-ui';
export function Root() {
return (
<AcoreThemeProvider
theme={{
colors: {
primary: '#5dd6ff',
danger: '#ff7b72',
},
}}
>
<App />
</AcoreThemeProvider>
);
}Metro en monorepo
Si consumes el paquete desde un monorepo, configura Metro para resolver workspaces.
Expo
const { getDefaultConfig } = require('expo/metro-config');
const path = require('path');
const config = getDefaultConfig(__dirname);
const workspaceRoot = path.resolve(__dirname, '../..');
config.watchFolders = [workspaceRoot];
config.resolver.nodeModulesPaths = [
path.resolve(__dirname, 'node_modules'),
path.resolve(workspaceRoot, 'node_modules'),
];
module.exports = config;React Native CLI
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const path = require('path');
const workspaceRoot = path.resolve(__dirname, '../..');
const defaultConfig = getDefaultConfig(__dirname);
module.exports = mergeConfig(defaultConfig, {
watchFolders: [workspaceRoot],
resolver: {
nodeModulesPaths: [
path.resolve(__dirname, 'node_modules'),
path.resolve(workspaceRoot, 'node_modules'),
],
},
});Theme y tokens
El tema mobile centraliza colores, spacing, radius, typography y sombras.
| Export | Tipo | Uso |
| --- | --- | --- |
| AcoreThemeProvider | Component | Provider raiz del tema. |
| useAcoreTheme | Hook | Acceso a colors, spacing, radius, typography e isDark. |
| createAcoreTheme | Function | Crea un tema desde overrides parciales. |
| acoreDefaultTheme | Object | Tema dark por defecto. |
| acoreDarkColors | Object | Tokens de color dark-first. |
| acoreSpacing | Object | Escala de spacing. |
| acoreRadius | Object | Escala de radios. |
| acoreTypography | Object | Tamanos y pesos tipograficos. |
| acoreShadows | Object | Sombras para iOS y Android. |
Ejemplo con useAcoreTheme:
import { StyleSheet, View } from 'react-native';
import { AcoreText, useAcoreTheme } from 'acore-mobile-ui';
export function CustomSurface() {
const theme = useAcoreTheme();
return (
<View
style={[
styles.surface,
{
backgroundColor: theme.colors.bgCard,
borderColor: theme.colors.border,
borderRadius: theme.radius.lg,
padding: theme.spacing[4],
},
]}
>
<AcoreText variant="label">Custom surface</AcoreText>
</View>
);
}
const styles = StyleSheet.create({
surface: {
borderWidth: 1,
},
});Componentes
Foundation
| Component | Descripcion | Props principales |
| --- | --- | --- |
| AcoreText | Tipografia base para titulos, body, labels y captions. | variant, color, weight, align, children |
| AcoreBadge | Badge compacto para estados y categorias. | label, variant |
| AcoreIconSlot | Slot visual para iconos, iniciales o elementos custom. | size, variant, label, children |
Layout
| Component | Descripcion | Props principales |
| --- | --- | --- |
| AcoreCard | Superficie con variantes default, muted, elevated e interactive. | variant, padding, radius, children, style |
| AcoreStack | Layout primitivo para row/column con gap tokenizado. | direction, gap, align, justify, wrap |
| AcoreDivider | Separador horizontal o vertical. | orientation, spacing, style |
| AcoreSectionHeader | Encabezado de seccion con label, titulo, descripcion y accion. | title, label, description, action |
| AcoreContainer | Contenedor con padding, maxWidth y centrado opcional. | paddingHorizontal, paddingVertical, maxWidth, centered |
Forms
| Component | Descripcion | Props principales |
| --- | --- | --- |
| AcoreButton | Boton primary, secondary, ghost o danger. | variant, size, loading, disabled, fullWidth, leftSlot, rightSlot, onPress |
| AcoreInput | TextInput con label, helper, error y slots. | label, helperText, errorText, leftSlot, rightSlot, TextInputProps |
| AcoreTextarea | Campo multilinea para notas y descripciones. | label, helperText, errorText, numberOfLines, TextInputProps |
| AcoreCheckbox | Boolean control con label, helper e indeterminate. | checked, onChange, label, helperText, indeterminate, disabled |
| AcoreRadio | Opcion individual dentro de un grupo. | value, label, checked, onPress, disabled |
| AcoreRadioGroup | Contexto controlado para radios relacionados. | value, onValueChange, disabled, children |
| AcoreSwitch | Toggle con label, helper, error y disabled. | value, onValueChange, label, helperText, errorText, disabled |
| AcoreSelect | Selector custom sin dependencia de Picker. | options, value, onValueChange, label, placeholder, helperText, errorText |
Feedback
| Component | Descripcion | Props principales |
| --- | --- | --- |
| AcoreAlert | Mensaje contextual info, success, warning, danger o neutral. | variant, title, description, action |
| AcoreEmptyState | Estado vacio con titulo, descripcion, icon slot y accion. | title, description, iconSlot, action |
| AcoreLoadingState | Indicador de carga con mensaje. | message, size |
| AcoreSkeleton | Placeholder rect, text o circle con animacion opcional. | width, height, variant, animated |
Navigation
| Component | Descripcion | Props principales |
| --- | --- | --- |
| AcoreHeader | Header mobile con titulo, subtitulo, acciones y status slot. | title, subtitle, leftAction, rightActions, statusSlot |
| AcoreTabs | Tabs mobile en modo pills o underline. | items, value, onValueChange, variant, scrollable |
| AcoreBottomBar | Barra inferior para navegacion principal. | items, activeKey, onChange |
| AcoreActionSheet | Lista contextual de acciones en presentacion bottom. | visible, onClose, title, actions, cancelLabel |
Data Display
| Component | Descripcion | Props principales |
| --- | --- | --- |
| AcoreDataRow | Fila con label, value, caption y slots. | label, value, caption, leftSlot, rightSlot, onPress |
| AcoreDataList | Lista con loading, empty, header, footer y pagination hook. | items, headerComponent, footerComponent, emptyComponent, loading, onEndReached |
| AcoreProgressBar | Barra de progreso 0-100. | value, variant, showLabel, height |
| AcoreMiniBarChart | Mini chart basado en Views, sin SVG externo. | data, maxValue, height, barColor |
| AcoreMetricCard | Card de metrica con value, trend y mini chart. | label, value, unit, trend, trendVariant, miniChart |
Overlays
| Component | Descripcion | Props principales |
| --- | --- | --- |
| AcoreModal | Modal center o bottom con titulo, descripcion, children y acciones. | visible, onClose, title, description, children, actions, presentation, dismissible |
| AcoreDrawer | Panel left, right o bottom para filtros y detalle. | visible, onClose, side, title, children, width, dismissible |
Patterns
Los patterns son composiciones visuales puras. No incluyen logica de negocio, requests, navegacion ni estado global.
| Pattern | Uso | Slots |
| --- | --- | --- |
| AcoreDashboardScreenPattern | Dashboard con header, metricas, acciones y contenido. | header, metricsSlot, actionsSlot, contentSlot |
| AcoreFormScreenPattern | Pantalla de formulario con acciones sticky. | header, children, stickyActions |
| AcoreListScreenPattern | Pantalla de lista con busqueda, tabs y lista. | header, searchSlot, tabsSlot, listSlot |
| AcoreDetailScreenPattern | Detalle de entidad con estado, acciones y timeline. | header, statusSlot, contentSlot, actionsSlot, timelineSlot |
Ejemplos
Botones
import { AcoreButton, AcoreStack } from 'acore-mobile-ui';
export function ButtonExamples() {
return (
<AcoreStack gap={2}>
<AcoreButton onPress={saveLead}>Save lead</AcoreButton>
<AcoreButton variant="secondary" onPress={cancel}>Cancel</AcoreButton>
<AcoreButton variant="ghost" onPress={openHelp}>Help</AcoreButton>
<AcoreButton variant="danger" loading={isDeleting} onPress={deleteLead}>
Delete lead
</AcoreButton>
</AcoreStack>
);
}Formulario
import {
AcoreButton,
AcoreCard,
AcoreInput,
AcoreSelect,
AcoreStack,
AcoreTextarea,
} from 'acore-mobile-ui';
const stageOptions = [
{ label: 'Hot', value: 'hot' },
{ label: 'Warm', value: 'warm' },
{ label: 'Cold', value: 'cold' },
];
export function LeadForm() {
return (
<AcoreCard>
<AcoreStack gap={3}>
<AcoreInput
label="Lead name"
placeholder="John Smith"
value={name}
onChangeText={setName}
/>
<AcoreSelect
label="Pipeline stage"
value={stage}
options={stageOptions}
onValueChange={setStage}
/>
<AcoreTextarea
label="Notes"
placeholder="Add context for the sales team"
value={notes}
onChangeText={setNotes}
/>
<AcoreButton fullWidth onPress={saveLead}>
Save lead
</AcoreButton>
</AcoreStack>
</AcoreCard>
);
}Dashboard
import {
AcoreDataList,
AcoreHeader,
AcoreMetricCard,
AcoreProgressBar,
AcoreSectionHeader,
AcoreStack,
} from 'acore-mobile-ui';
export function DashboardScreen() {
return (
<AcoreStack gap={4}>
<AcoreHeader title="Dashboard" subtitle="CRM Overview" />
<AcoreMetricCard
label="Calls Today"
value={142}
trend="+12%"
trendVariant="success"
miniChart={callsByDay}
/>
<AcoreStack gap={2}>
<AcoreSectionHeader label="SALES" title="Pipeline Progress" />
<AcoreProgressBar value={78} variant="success" showLabel />
</AcoreStack>
<AcoreDataList items={recentLeads} />
</AcoreStack>
);
}Dashboard pattern
import {
AcoreDashboardScreenPattern,
AcoreDataList,
AcoreHeader,
AcoreMetricCard,
} from 'acore-mobile-ui';
export function SalesDashboard() {
return (
<AcoreDashboardScreenPattern
header={<AcoreHeader title="Dashboard" subtitle="CRM Overview" />}
metricsSlot={
<AcoreMetricCard
label="Calls Today"
value={142}
trend="+12%"
trendVariant="success"
/>
}
contentSlot={<AcoreDataList items={leads} />}
/>
);
}Modal de confirmacion
import {
AcoreButton,
AcoreModal,
AcoreStack,
} from 'acore-mobile-ui';
export function ArchiveLeadModal() {
return (
<AcoreModal
visible={isOpen}
onClose={() => setIsOpen(false)}
title="Archive lead?"
description="This action can be reversed later."
presentation="bottom"
actions={
<AcoreStack gap={2}>
<AcoreButton fullWidth onPress={archiveLead}>
Confirm
</AcoreButton>
<AcoreButton
fullWidth
variant="ghost"
onPress={() => setIsOpen(false)}
>
Cancel
</AcoreButton>
</AcoreStack>
}
/>
);
}Buenas practicas
- Envuelve la app una sola vez con
AcoreThemeProvider. - Usa
AcoreContainer,AcoreStackyAcoreCardantes de crear layouts manuales. - Mantiene acciones primarias claras y usa
fullWidthen formularios mobile. - Usa
AcoreDataListpara listas de producto; deja la carga remota en la app consumidora. - Usa
AcoreSelectcuando necesites consistencia entre iOS, Android, Expo y RN CLI. - Pasa iconos como
ReactNode; la libreria no impone una libreria de iconos. - Mantiene la logica de negocio fuera de patterns.
Accesibilidad
- Usa labels descriptivos en inputs, selects, radios, checkboxes y switches.
- Evita depender solo del color para comunicar errores o estados.
- Usa
disabledcuando una accion no este disponible. - Usa textos cortos en botones y acciones de
AcoreActionSheet. - En overlays, usa titulos claros y provee
onClose. - Valida screen readers en la app final, especialmente si pasas iconos custom.
Limitaciones actuales
| Area | Limitacion |
| --- | --- |
| AcoreSelect | Usa modal custom, no Picker nativo. Esto evita diferencias fuertes entre plataformas. |
| AcoreDrawer | Los lados left/right usan transicion simple. Gestos avanzados pueden requerir react-native-reanimated en una capa futura. |
| AcoreMiniBarChart | Esta basado en View, no SVG. Mejor para hasta 12 barras. |
| AcoreSkeleton | Usa pulso de opacidad. Shimmer requiere una dependencia opcional como LinearGradient. |
| Iconos | No incluye icon set. Pasa ReactNode en iconSlot, leftSlot, rightSlot o children. |
| Fuentes | Usa system font. La app consumidora decide carga de fuentes custom. |
| Tema | Dark-first. Light mode puede agregarse como layer de tema. |
Exports
import {
AcoreActionSheet,
AcoreAlert,
AcoreBadge,
AcoreBottomBar,
AcoreButton,
AcoreCard,
AcoreCheckbox,
AcoreContainer,
AcoreDashboardScreenPattern,
AcoreDataList,
AcoreDataRow,
AcoreDetailScreenPattern,
AcoreDivider,
AcoreDrawer,
AcoreEmptyState,
AcoreFormScreenPattern,
AcoreHeader,
AcoreIconSlot,
AcoreInput,
AcoreListScreenPattern,
AcoreLoadingState,
AcoreMetricCard,
AcoreMiniBarChart,
AcoreModal,
AcoreProgressBar,
AcoreRadio,
AcoreRadioGroup,
AcoreSectionHeader,
AcoreSelect,
AcoreSkeleton,
AcoreStack,
AcoreSwitch,
AcoreTabs,
AcoreText,
AcoreTextarea,
AcoreThemeProvider,
createAcoreTheme,
useAcoreTheme,
} from 'acore-mobile-ui';Desarrollo local
Desde la raiz del monorepo:
pnpm install
pnpm --filter acore-mobile-ui build
pnpm --filter acore-mobile-ui typecheck
pnpm --filter example-expo startValidacion antes de publicar
pnpm --filter acore-mobile-ui build
pnpm --filter acore-mobile-ui typecheck
pnpm --filter docs buildRoadmap sugerido
| Version | Objetivo |
| --- | --- |
| 0.1.x | Foundation, Layout, Forms, Feedback, Overlays y documentacion npm. |
| 0.2.x | Navigation, Data Display y Patterns estabilizados. |
| 0.3.x | Mejoras de accesibilidad, reduce motion y tablet breakpoints. |
| 0.4.x | Adaptadores opcionales para gestures, reanimated y light theme. |
| 1.0.0 | API estable validada en apps reales. |
Licencia
ACore Mobile UI is publicly installable, but it is not open source software. See LICENSE.md for permitted usage and restrictions.
Estado
Version actual: 0.1.0
