Skip to content
OxyHQPublic

About

Bloom — Oxy's cross-platform UI component library

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

1,098 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bloom is the UI library every Oxy app is built with.
One component set for React Native, Expo and the web, with the same props on every platform.

npm License Breathe 1.0 React Native Expo TypeScript Bun


What it is

Components, hooks and design tokens published as @oxy.so/bloom through component subpath exports, shipped as src for Metro and as compiled CommonJS and ESM for everyone else. Web builds resolve platform forks automatically through export conditions, so a .web.tsx fork never reaches a native bundle.

Styling is NativeWind classes throughout. There are no colour props and no wrapper components to theme a button, because a second way to set a colour is a second thing that can disagree.

How it fits the Oxy platform

Bloom is the presentation layer of oxy. It knows nothing about identity or the network, so it has no dependency on the Oxy SDK and can be used on its own.

Where an app does use the SDK, the two meet at one seam: register imageResolver once at the root, usually oxyServices.getFileDownloadUrl from @oxyhq/core, and every Avatar and image in the tree resolves bare file ids for free.

Install

bun add @oxy.so/bloom
Peer dependencies

Always required:

Package Range
react >=18.0.0
react-dom >=18.0.0
react-native >=0.73.0
react-native-safe-area-context >=5.0.0
react-native-screens >=3.16.0
nativewind >=5.0.0

Required by specific surfaces, and by more of them than you would guess:

Package Range Needed by
react-native-reanimated >=3.13.0 Dialog, BottomSheet, toast, Loading, on the web too
react-native-gesture-handler >=2.16.1 Dialog, BottomSheet, swipe to dismiss on toasts
react-native-svg >=13.0.0 icons, Avatar in any non-circular shape
react-native-keyboard-controller >=1.11.4 keyboard aware surfaces
expo, expo-blur, expo-font, expo-haptics, expo-image, expo-symbols see package.json native effects, fonts, haptics, images and SF Symbols
expo-glass-effect >=0.1.9 glass surfaces
expo-router >=3.0.0 the expo-router variants of tabs, scroll and tab-bar
@react-native-community/netinfo >=11.1.0 connection-status

On native, wrap the app root in GestureHandlerRootView from react-native-gesture-handler, or the bottom sheet pan gestures will not fire.

Upgrading to 2.0

Bloom follows the clean cut rule, so there are no @deprecated aliases and no old name shims. If a symbol you import was removed, nothing re-exports it and the build fails. docs/migrating-to-2.0.mdx is the bridge: the five removed families and what replaces them, the Remix icon set and its codemod, Inter as the UI face, every changed default, and the Breathe License.

The icon codemod ships with the package:

node node_modules/@oxy.so/bloom/scripts/migrate-icons-to-remix.mjs <app-root> --dry-run --diff

Coming from 0.x, read docs/migrating-to-1.0.mdx first. Both guides ship inside the package, so the copy under node_modules/@oxy.so/bloom/docs/ describes the version you installed.

Getting started

Mount BloomProvider once, at the very top of the app. It composes every piece of app wide Bloom state, theme, haptics, image resolution, scroll restoration and tab bar minimise progress, so none of them can end up at the wrong depth.

import { BloomProvider } from '@oxy.so/bloom/provider';

<BloomProvider
  defaultMode="system"
  defaultColorPreset="blue"
  persistKey="app.theme"
  storage={storage}
  imageResolver={(id, variant) => oxyServices.getFileDownloadUrl(id, variant)}
>
  <App />
</BloomProvider>

Everything scrollable must sit under it. useScrollRestoration() throws outside its provider, so a list rendered beside the root, a right rail or an overlay, crashes that screen.

Outlets are deliberately not included, because where they sit in the tree is a real application decision and a second mount duplicates every surface they render. Mount these yourself, under BloomProvider: ToastOutlet, the PortalProvider and PortalOutlet pair from @oxy.so/bloom/portal, and SurfaceHost (which renders alert(), confirm(), prompt() and everything else on the surface stack).

import { Button } from '@oxy.so/bloom/button';
import { toast } from '@oxy.so/bloom/toast';

<Button onPress={() => toast.success('Saved')}>Save</Button>

Theming

Four modes

light, dark, system, and adaptive, which follows the iOS and Android dynamic colours when the platform offers them.

import { useTheme } from '@oxy.so/bloom/theme';

const theme = useTheme();
// theme.colors.primary, theme.colors.text, theme.isDark

useTheme() throws outside a provider, so hoist BloomProvider above the splash and loading branches, not just above the main tree.

Named colour presets

blue, orange, teal, green, yellow and the other names in the public APP_COLOR_NAMES registry. COLOR_PRESET_REGISTRY supplies picker metadata and access gates; FREE_COLOR_NAMES, HANDLE_COLOR_NAMES and PREMIUM_COLOR_NAMES expose availability groups. See Theme for defaults, controlled app identity, persistence and canonical CSS tokens.

Presets use the shared colour engine, with authored accent pairings and token values where specified, for light and dark. Dynamic seed colours use the same role-generation and colour-policy pipeline.

Components

Bloom publishes each component family through a subpath export. Importing from the subpath rather than the root keeps a bundle to what it actually renders.

Icons go one step further: every glyph is its own subpath, @oxy.so/bloom/icons/<RiName>. Metro does not tree-shake, so the flat @oxy.so/bloom/icons barrel ships all 480 glyphs to any app that names one — see icons for the measurement and when to reach for which import. The barrel keeps working unchanged — it stays an exact exports key, and an exact key beats a pattern everywhere.

Group Exports
Providers and theme provider, theme, theme-toggle, color-presets, preset-vars, design-tokens, tailwind-preset, styles, control-surface, hooks
App shell and navigation app-shell, page-header, sidebar, rail, breadcrumb, pagination, tabs, tab-bar, layout, content-panel
Overlays dialog, alert-dialog, bottom-sheet, popover, context-menu, dropdown-menu, menubar, tooltip, overlay, portal, teleport, surfaces, settings-modal
Actions button, button-group, social-button, fab, frosted-icon-button, pressable-scale, subtle-hover
Forms text-field, textarea, phone-input, input-otp, field, input-group, label, select, command, checkbox, radio, switch, slider, segmented-control, search, date-picker, file-upload, auth-card, stepper, rating, wizard
Layout and lists grid, list, scroll, settings-list, card, cover-header, accordion, aspect-ratio, divider, item, carousel
Data and charts table, data-table, chart-cards, stat-cards, calendar, composition-bar, stat-bar, activity-heatmap, recent-hires-card, patient-info-card, important-alerts-card, agent-limits-card, ai-profile-card
Music and media media-card, media-controls, media-header, media-player, media-shelf, track-list, queue-panel, lyrics, music-library, creator-studio, sortable-media
Housing home-search, listing-actions, listing-editor, offering-badge, place-reviews, property-insights, tenancy, eviction
Stays and booking listing-card, listing-details, stay-search, stay-filters, booking, category-bar, map-marker
AI and agents agent-chat, ai-chat, composer-panel, composer-loader, agent-thinking, agent-log, agent-progress, task-list, web-search, questionnaire
Identity and media shapes, avatar, avatar-group, hover-card, user-hover-card, image-resolver, image-aspect-ratio-cache, zoomable-image-gallery, zoomable-media-gallery, media-flight, media-inset-border, progressive-blur, fill
Chat chat-list, chat-screen, chat-composer, chat-people, chat-indicators, message-bubble, message-media, call-ui
Feedback toast, notification, notification-center, announcement, admonition, loading, skeleton, error-boundary, badge, chip, kbd, code, link-preview, connection-status, connection-dots
Motion and assets motion, animated-check, icon-circle, radio-indicator, icons, typography, fonts

tabs, scroll and tab-bar each ship an /expo-router variant for apps on Expo Router.

Documentation

Component guides live in docs/, one .mdx per family, and they ship inside the package at node_modules/@oxy.so/bloom/docs/. The copy you read there always describes the version you installed, which matters most for migrating to 3.0.

Start with getting started, theme and design tokens. Then per surface: app shell, sidebar, data table, chart cards, composer panel, dialog, bottom sheet, toast, alert, dropdown menu, select, context menu, button, avatar, text field, settings list, tab bar and loading.

The theme reference is in README.theme.md.

Development

bun install
bun run build        # react-native-builder-bob, then verify the published shape
bun run typescript   # type check
bun run test         # jest
bun run storybook    # component workshop on port 6006
bun run clean        # remove lib/

build regenerates the platform export map and the theme CSS first, then verifies the package it just produced. If that verification fails, the package is wrong, not the check.

Contributing

Issues and pull requests are welcome. Please run bun run typescript and bun run test first. Org wide contributing notes, the security policy and the code of conduct live in the organisation profile.

License

The Breathe License 1.0, The Oxy Collective, Inc.

About

Bloom — Oxy's cross-platform UI component library

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages