@drakkar.software/octospaces-ui 0.2.0 → 0.2.1
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/dist/index.d.ts +13 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -334,7 +334,19 @@ interface DiscoverScreenProps {
|
|
|
334
334
|
* @default true
|
|
335
335
|
*/
|
|
336
336
|
searchEnabled?: boolean;
|
|
337
|
+
/**
|
|
338
|
+
* Optional ref whose `.current` is set to a `reload()` function once mounted.
|
|
339
|
+
* Lets a host (e.g. a tab screen) trigger a soft-refresh on focus without
|
|
340
|
+
* blanking the existing list — identical to pull-to-refresh behaviour.
|
|
341
|
+
*
|
|
342
|
+
* ```tsx
|
|
343
|
+
* const reloadRef = useRef<() => void>(null);
|
|
344
|
+
* useFocusEffect(useCallback(() => { reloadRef.current?.(); }, []));
|
|
345
|
+
* <DiscoverScreen reloadRef={reloadRef} ... />
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
reloadRef?: React.RefObject<(() => void) | null>;
|
|
337
349
|
}
|
|
338
|
-
declare function DiscoverScreen({ loadEntries, renderIcon, onOpen, title, emptyMessage, emptySearchMessage, searchEnabled, }: DiscoverScreenProps): React.JSX.Element;
|
|
350
|
+
declare function DiscoverScreen({ loadEntries, renderIcon, onOpen, title, emptyMessage, emptySearchMessage, searchEnabled, reloadRef, }: DiscoverScreenProps): React.JSX.Element;
|
|
339
351
|
|
|
340
352
|
export { type ColorScheme, type DiscoverEntry, DiscoverList, type DiscoverListProps, DiscoverRow, type DiscoverRowProps, DiscoverScreen, type DiscoverScreenProps, type Easing, type Fonts, type LabelTracking, type Layers, type Layout, type Motion, type MotionToken, OctoSpacesThemeProvider, type OctoSpacesThemeProviderProps, type Opacity, type Palette, type Radii, type ShadowToken, type Shadows, type Spacing, type Swatches, type Theme, type TypeScale, type Typography, avatarTint, filterDiscoverEntries, focusRingStyle, glowShadow, paperBorder, presenceColor, sortDiscoverEntries, statusColor, swatch, useOctoSpacesTheme, verificationColor };
|
package/dist/index.js
CHANGED
|
@@ -237,7 +237,7 @@ function DiscoverList({
|
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
// src/discover/DiscoverScreen.tsx
|
|
240
|
-
import React4, { useCallback as useCallback3, useEffect, useRef, useState } from "react";
|
|
240
|
+
import React4, { useCallback as useCallback3, useEffect, useImperativeHandle, useRef, useState } from "react";
|
|
241
241
|
import { ActivityIndicator, Pressable as Pressable2, Text as Text3, TextInput, View as View3 } from "react-native";
|
|
242
242
|
function DiscoverScreen({
|
|
243
243
|
loadEntries,
|
|
@@ -246,7 +246,8 @@ function DiscoverScreen({
|
|
|
246
246
|
title = "Discover",
|
|
247
247
|
emptyMessage = "No public objects yet",
|
|
248
248
|
emptySearchMessage,
|
|
249
|
-
searchEnabled = true
|
|
249
|
+
searchEnabled = true,
|
|
250
|
+
reloadRef
|
|
250
251
|
}) {
|
|
251
252
|
const theme = useOctoSpacesTheme();
|
|
252
253
|
const [state, setState] = useState({ status: "idle" });
|
|
@@ -278,6 +279,7 @@ function DiscoverScreen({
|
|
|
278
279
|
if (!cancelledRef.current) setRefreshing(false);
|
|
279
280
|
}
|
|
280
281
|
}, [loadEntries]);
|
|
282
|
+
useImperativeHandle(reloadRef, () => handleRefresh, [handleRefresh]);
|
|
281
283
|
useEffect(() => {
|
|
282
284
|
cancelledRef.current = false;
|
|
283
285
|
void load();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/theme/provider.tsx","../src/theme/helpers.ts","../src/discover/filter.ts","../src/discover/DiscoverRow.tsx","../src/discover/DiscoverList.tsx","../src/discover/DiscoverScreen.tsx"],"sourcesContent":["/**\n * Theme injection plumbing — provider + hook.\n *\n * The package carries ZERO theme values. The host app builds a concrete {@link Theme}\n * and wraps its tree in `<OctoSpacesThemeProvider theme={resolvedTheme}>`.\n * All primitives then call `useOctoSpacesTheme()` to read the active theme.\n */\nimport React, { createContext, useContext } from 'react';\nimport type { Theme } from './types.js';\n\nconst ThemeContext = createContext<Theme | null>(null);\n\nexport interface OctoSpacesThemeProviderProps {\n theme: Theme;\n children: React.ReactNode;\n}\n\n/**\n * Wrap your root component with this provider to inject the resolved Theme into\n * every primitive from `@drakkar.software/octospaces-ui`.\n *\n * @example\n * ```tsx\n * import { OctoSpacesThemeProvider } from '@drakkar.software/octospaces-ui';\n * import { resolvedTheme } from '@/theme'; // your app's theme\n *\n * export default function App() {\n * return (\n * <OctoSpacesThemeProvider theme={resolvedTheme}>\n * <RootNavigator />\n * </OctoSpacesThemeProvider>\n * );\n * }\n * ```\n */\nexport function OctoSpacesThemeProvider({ theme, children }: OctoSpacesThemeProviderProps) {\n return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>;\n}\n\n/**\n * Read the active theme. Throws if called outside an `<OctoSpacesThemeProvider>` —\n * this is intentional: a missing provider means primitives have no colors/spacing,\n * so a hard failure with a clear message is better than a silent rendering bug.\n */\nexport function useOctoSpacesTheme(): Theme {\n const theme = useContext(ThemeContext);\n if (!theme) {\n throw new Error(\n '[octospaces-ui] useOctoSpacesTheme() called outside of <OctoSpacesThemeProvider>. ' +\n 'Wrap your root component with <OctoSpacesThemeProvider theme={…}>.',\n );\n }\n return theme;\n}\n","/**\n * Pure palette-helper functions over a {@link Palette}. No theme values live here —\n * only functions that DERIVE from the injected palette (or from passed-in colors).\n *\n * Import these from `@drakkar.software/octospaces-ui` (re-exported by `src/index.ts`).\n */\nimport type { Palette, ShadowToken, Theme } from './types.js';\n\n// ── Presence ──────────────────────────────────────────────────────────────────\n\n/** Map a presence status string to the corresponding palette color. */\nexport function presenceColor(\n palette: Palette,\n status: 'online' | 'away' | 'busy' | 'offline' | string,\n): string {\n switch (status) {\n case 'online': return palette.presenceOnline;\n case 'away': return palette.presenceAway;\n case 'busy': return palette.presenceBusy;\n default: return palette.presenceOffline;\n }\n}\n\n// ── Verification ──────────────────────────────────────────────────────────────\n\n/** Map a verification level to the corresponding palette color. */\nexport function verificationColor(\n palette: Palette,\n level: 'verified' | 'partial' | 'none' | string,\n): string {\n switch (level) {\n case 'verified': return palette.verificationVerified;\n case 'partial': return palette.verificationPartial;\n default: return palette.verificationNone;\n }\n}\n\n// ── Avatar ────────────────────────────────────────────────────────────────────\n\nconst AVATAR_TINT_KEYS = [\n 'primary', 'success', 'warning', 'danger', 'info',\n] as const;\n\n/** Stable avatar background tint derived from a userId string. */\nexport function avatarTint(palette: Palette, userId: string): string {\n let hash = 0;\n for (let i = 0; i < userId.length; i++) hash = (hash * 31 + userId.charCodeAt(i)) | 0;\n const key = AVATAR_TINT_KEYS[Math.abs(hash) % AVATAR_TINT_KEYS.length];\n return (palette as unknown as Record<string, string>)[key] ?? palette.primary;\n}\n\n// ── Swatch ────────────────────────────────────────────────────────────────────\n\n/** Look up a named swatch; falls back to `palette.primary` if absent. */\nexport function swatch(theme: Theme, name: string): string {\n return theme.swatches[name] ?? theme.colors.primary;\n}\n\n// ── Borders ───────────────────────────────────────────────────────────────────\n\n/** Derive a `borderColor` value for a \"paper\" (elevated surface) border. */\nexport function paperBorder(palette: Palette): string {\n return palette.borderSubtle;\n}\n\n// ── Shadows ───────────────────────────────────────────────────────────────────\n\n/** Build a glow shadow token from a base color (used for focus rings, highlights). */\nexport function glowShadow(color: string, radius = 8, opacity = 0.4): ShadowToken {\n return {\n shadowColor: color,\n shadowOffset: { width: 0, height: 0 },\n shadowOpacity: opacity,\n shadowRadius: radius,\n elevation: 4,\n };\n}\n\n// ── Focus ring ────────────────────────────────────────────────────────────────\n\n/** Style object for a keyboard-focus indicator (web + React Native). */\nexport function focusRingStyle(\n palette: Palette,\n width = 2,\n): {\n borderWidth: number;\n borderColor: string;\n borderStyle: 'solid';\n} {\n return { borderWidth: width, borderColor: palette.focus, borderStyle: 'solid' };\n}\n\n// ── Status color ──────────────────────────────────────────────────────────────\n\n/** Map a semantic status name to its palette color. */\nexport function statusColor(\n palette: Palette,\n status: 'success' | 'warning' | 'danger' | 'info' | string,\n muted = false,\n): string {\n if (muted) {\n switch (status) {\n case 'success': return palette.successMuted;\n case 'warning': return palette.warningMuted;\n case 'danger': return palette.dangerMuted;\n default: return palette.infoMuted;\n }\n }\n switch (status) {\n case 'success': return palette.success;\n case 'warning': return palette.warning;\n case 'danger': return palette.danger;\n default: return palette.info;\n }\n}\n","import type { DiscoverEntry } from './types.js';\n\n/**\n * Case-insensitive substring filter over a `DiscoverEntry[]`.\n *\n * Returns the original array reference unchanged when `query` is blank so the\n * caller can skip a re-render. Pure function — no side effects.\n */\nexport function filterDiscoverEntries(\n entries: DiscoverEntry[],\n query: string,\n): DiscoverEntry[] {\n const q = query.trim().toLowerCase();\n if (!q) return entries;\n return entries.filter((e) => e.title.toLowerCase().includes(q));\n}\n\n/**\n * Sort discover entries by updatedAt descending (most recent first).\n * Entries without an `updatedAt` field sort last. Pure function.\n */\nexport function sortDiscoverEntries(entries: DiscoverEntry[]): DiscoverEntry[] {\n return [...entries].sort((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0));\n}\n","/**\n * A single row in the Discover list — shows the object's emoji/icon, title,\n * and type. All app-specific behaviour is injected via props:\n * - `renderIcon` — render a type/emoji icon; receives the entry and must\n * return a ReactNode (null for no icon).\n * - `onOpen` — called when the row is pressed.\n *\n * Styled entirely from the injected {@link Theme} via `useOctoSpacesTheme()`.\n */\nimport React, { useCallback } from 'react';\nimport { Pressable, Text, View } from 'react-native';\n\nimport { useOctoSpacesTheme } from '../theme/provider.js';\nimport type { DiscoverEntry } from './types.js';\n\nexport interface DiscoverRowProps {\n entry: DiscoverEntry;\n /** Render a leading icon for the entry. Return `null` to show nothing. */\n renderIcon?: (entry: DiscoverEntry) => React.ReactNode;\n /** Called when the user taps the row. */\n onOpen: (entry: DiscoverEntry) => void;\n}\n\nexport function DiscoverRow({ entry, renderIcon, onOpen }: DiscoverRowProps) {\n const theme = useOctoSpacesTheme();\n\n const handlePress = useCallback(() => {\n onOpen(entry);\n }, [entry, onOpen]);\n\n const icon = renderIcon ? renderIcon(entry) : null;\n const displayEmoji = !icon && entry.emoji ? entry.emoji : null;\n\n return (\n <Pressable\n onPress={handlePress}\n style={({ pressed }) => ({\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: (theme.spacing['3'] as number) ?? 12,\n paddingHorizontal: (theme.spacing['4'] as number) ?? 16,\n backgroundColor: pressed\n ? (theme.colors.surface ?? '#f5f5f5')\n : 'transparent',\n borderRadius: (theme.radii['sm'] as number) ?? 6,\n })}\n accessibilityRole=\"button\"\n accessibilityLabel={entry.title || 'Untitled'}\n >\n {/* Leading icon / emoji */}\n {(icon || displayEmoji) && (\n <View\n style={{\n width: 28,\n height: 28,\n marginRight: (theme.spacing['2'] as number) ?? 8,\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n >\n {icon ?? (\n <Text style={{ fontSize: 18, lineHeight: 24 }}>{displayEmoji}</Text>\n )}\n </View>\n )}\n\n {/* Title + type subtitle */}\n <View style={{ flex: 1, minWidth: 0 }}>\n <Text\n numberOfLines={1}\n style={{\n fontSize: (theme.type['body']?.size ?? 15),\n lineHeight: (theme.type['body']?.lineHeight ?? 22),\n color: entry.title ? theme.colors.text : theme.colors.textTertiary,\n fontFamily: theme.fonts['body'] ?? undefined,\n }}\n >\n {entry.title || 'Untitled'}\n </Text>\n <Text\n numberOfLines={1}\n style={{\n fontSize: (theme.type['caption']?.size ?? 12),\n lineHeight: (theme.type['caption']?.lineHeight ?? 18),\n color: theme.colors.textSecondary,\n marginTop: 1,\n textTransform: 'capitalize',\n }}\n >\n {entry.type}\n </Text>\n </View>\n </Pressable>\n );\n}\n","/**\n * A themed FlatList wrapper that renders a list of {@link DiscoverEntry} rows.\n *\n * All app-specific behaviour is injected via props so this component has zero\n * imports from any specific OctoSpaces app.\n */\nimport React, { useCallback } from 'react';\nimport { FlatList, RefreshControl, Text, View } from 'react-native';\n\nimport { useOctoSpacesTheme } from '../theme/provider.js';\nimport { DiscoverRow } from './DiscoverRow.js';\nimport type { DiscoverEntry } from './types.js';\n\nexport interface DiscoverListProps {\n entries: DiscoverEntry[];\n /** Render a leading icon for each row — see {@link DiscoverRowProps.renderIcon}. */\n renderIcon?: (entry: DiscoverEntry) => React.ReactNode;\n /** Called when a row is tapped. */\n onOpen: (entry: DiscoverEntry) => void;\n /** Text shown when `entries` is empty (default: \"No public objects found\"). */\n emptyMessage?: string;\n /** Whether a pull-to-refresh is currently in progress. */\n refreshing?: boolean;\n /** Called when the user pulls to refresh. */\n onRefresh?: () => void;\n}\n\nexport function DiscoverList({\n entries,\n renderIcon,\n onOpen,\n emptyMessage = 'No public objects found',\n refreshing,\n onRefresh,\n}: DiscoverListProps) {\n const theme = useOctoSpacesTheme();\n\n const renderItem = useCallback(\n ({ item }: { item: DiscoverEntry }) => (\n <DiscoverRow entry={item} renderIcon={renderIcon} onOpen={onOpen} />\n ),\n [renderIcon, onOpen],\n );\n\n const keyExtractor = useCallback(\n (item: DiscoverEntry) => `${item.spaceId}:${item.id}`,\n [],\n );\n\n if (entries.length === 0) {\n return (\n <View\n style={{\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: (theme.spacing['6'] as number) ?? 24,\n }}\n >\n <Text\n style={{\n fontSize: theme.type['body']?.size ?? 15,\n color: theme.colors.textSecondary,\n textAlign: 'center',\n }}\n >\n {emptyMessage}\n </Text>\n </View>\n );\n }\n\n return (\n <FlatList\n data={entries}\n renderItem={renderItem}\n keyExtractor={keyExtractor}\n contentContainerStyle={{ paddingVertical: (theme.spacing['1'] as number) ?? 4 }}\n showsVerticalScrollIndicator={false}\n removeClippedSubviews\n refreshControl={\n onRefresh ? (\n <RefreshControl\n refreshing={refreshing ?? false}\n onRefresh={onRefresh}\n tintColor={theme.colors.primary}\n />\n ) : undefined\n }\n />\n );\n}\n","/**\n * Generic public-object discovery screen.\n *\n * Loads the world-readable public-object directory via `loadEntries`, renders a\n * search bar, and delegates row rendering + tap behaviour to the injected props.\n * No app-specific logic lives here — all customisation is via props:\n *\n * ```tsx\n * <DiscoverScreen\n * loadEntries={readObjectDirectory}\n * renderIcon={(e) => <TypeIcon entry={e} />}\n * onOpen={(e) => router.push({ pathname: routeForNode(e), params: { id: e.id, spaceId: e.spaceId } })}\n * />\n * ```\n *\n * State machine:\n * idle → loading → (ready | error)\n * Any pull of `loadEntries` updates the entries; errors show a retry button.\n */\nimport React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { ActivityIndicator, Pressable, Text, TextInput, View, type TextStyle } from 'react-native';\n\nimport { useOctoSpacesTheme } from '../theme/provider.js';\nimport { DiscoverList } from './DiscoverList.js';\nimport { filterDiscoverEntries, sortDiscoverEntries } from './filter.js';\nimport type { DiscoverEntry } from './types.js';\n\nexport interface DiscoverScreenProps {\n /**\n * Async function that resolves to the current public-object directory.\n * Typically `readObjectDirectory` from `@drakkar.software/octospaces-sdk`.\n * Called on mount and when `refresh()` is triggered.\n */\n loadEntries: () => Promise<DiscoverEntry[]>;\n /** Render a leading icon for each row. */\n renderIcon?: (entry: DiscoverEntry) => React.ReactNode;\n /** Called when the user taps a row — navigate to the object. */\n onOpen: (entry: DiscoverEntry) => void;\n /**\n * Optional heading text shown above the search bar.\n * @default \"Discover\"\n */\n title?: string;\n /**\n * Text shown when the directory is empty after loading.\n * @default \"No public objects yet\"\n */\n emptyMessage?: string;\n /**\n * Text shown when the directory is empty due to an active search query.\n * @default \"No results for «query»\"\n */\n emptySearchMessage?: string;\n /**\n * Whether to show the inline search bar.\n * @default true\n */\n searchEnabled?: boolean;\n}\n\ntype State =\n | { status: 'idle' }\n | { status: 'loading' }\n | { status: 'ready'; entries: DiscoverEntry[] }\n | { status: 'error'; message: string };\n\nexport function DiscoverScreen({\n loadEntries,\n renderIcon,\n onOpen,\n title = 'Discover',\n emptyMessage = 'No public objects yet',\n emptySearchMessage,\n searchEnabled = true,\n}: DiscoverScreenProps) {\n const theme = useOctoSpacesTheme();\n const [state, setState] = useState<State>({ status: 'idle' });\n const [query, setQuery] = useState('');\n const [refreshing, setRefreshing] = useState(false);\n const cancelledRef = useRef(false);\n\n const load = useCallback(async () => {\n setState({ status: 'loading' });\n try {\n const raw = await loadEntries();\n if (cancelledRef.current) return;\n setState({ status: 'ready', entries: sortDiscoverEntries(raw) });\n } catch (err) {\n if (cancelledRef.current) return;\n setState({\n status: 'error',\n message: err instanceof Error ? err.message : 'Failed to load directory',\n });\n }\n }, [loadEntries]);\n\n /** Pull-to-refresh: re-fetches without blanking the existing list. */\n const handleRefresh = useCallback(async () => {\n setRefreshing(true);\n try {\n const raw = await loadEntries();\n if (cancelledRef.current) return;\n setState({ status: 'ready', entries: sortDiscoverEntries(raw) });\n } catch {\n // keep the existing list on refresh failure; the retry button remains for error state\n } finally {\n if (!cancelledRef.current) setRefreshing(false);\n }\n }, [loadEntries]);\n\n useEffect(() => {\n cancelledRef.current = false;\n void load();\n return () => {\n cancelledRef.current = true;\n };\n }, [load]);\n\n // ── Derived list ─────────────────────────────────────────────────────────\n const allEntries = state.status === 'ready' ? state.entries : [];\n const visibleEntries = filterDiscoverEntries(allEntries, query);\n const noSearchResults = !!query.trim() && visibleEntries.length === 0 && allEntries.length > 0;\n const resolvedEmptyMessage = noSearchResults\n ? (emptySearchMessage ?? `No results for \"${query.trim()}\"`)\n : emptyMessage;\n\n // ── Palette shortcuts ─────────────────────────────────────────────────────\n const sp2 = (theme.spacing['2'] as number) ?? 8;\n const sp3 = (theme.spacing['3'] as number) ?? 12;\n const sp4 = (theme.spacing['4'] as number) ?? 16;\n const radMd = (theme.radii['md'] as number) ?? 8;\n\n return (\n <View style={{ flex: 1, backgroundColor: theme.colors.background }}>\n {/* Header */}\n <View\n style={{\n paddingHorizontal: sp4,\n paddingTop: sp4,\n paddingBottom: sp2,\n }}\n >\n <Text\n style={{\n fontSize: theme.type['title2']?.size ?? 22,\n fontWeight: (theme.type['title2']?.weight as TextStyle['fontWeight']) ?? '700',\n lineHeight: theme.type['title2']?.lineHeight ?? 28,\n color: theme.colors.text,\n fontFamily: theme.fonts['heading'] ?? undefined,\n marginBottom: sp3,\n }}\n >\n {title}\n </Text>\n\n {/* Search bar */}\n {searchEnabled && (\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n backgroundColor: theme.colors.surfaceInput ?? theme.colors.surface,\n borderRadius: radMd,\n borderWidth: 1,\n borderColor: theme.colors.borderSubtle,\n paddingHorizontal: sp3,\n height: 40,\n }}\n >\n <TextInput\n placeholder=\"Search…\"\n placeholderTextColor={theme.colors.textTertiary}\n value={query}\n onChangeText={setQuery}\n style={{\n flex: 1,\n fontSize: theme.type['body']?.size ?? 15,\n color: theme.colors.text,\n fontFamily: theme.fonts['body'] ?? undefined,\n }}\n returnKeyType=\"search\"\n clearButtonMode=\"while-editing\"\n accessibilityLabel=\"Search discover\"\n />\n </View>\n )}\n </View>\n\n {/* Body */}\n {state.status === 'loading' ? (\n <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>\n <ActivityIndicator color={theme.colors.primary} />\n </View>\n ) : state.status === 'error' ? (\n <View\n style={{\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: sp4,\n }}\n >\n <Text\n style={{\n color: theme.colors.textSecondary,\n fontSize: theme.type['body']?.size ?? 15,\n textAlign: 'center',\n marginBottom: sp3,\n }}\n >\n {state.message}\n </Text>\n <Pressable\n onPress={load}\n style={{\n paddingHorizontal: sp4,\n paddingVertical: sp2,\n backgroundColor: theme.colors.primary,\n borderRadius: radMd,\n }}\n >\n <Text style={{ color: theme.colors.textOnPrimary, fontWeight: '600' }}>\n Retry\n </Text>\n </Pressable>\n </View>\n ) : (\n <DiscoverList\n entries={visibleEntries}\n renderIcon={renderIcon}\n onOpen={onOpen}\n emptyMessage={resolvedEmptyMessage}\n refreshing={refreshing}\n onRefresh={handleRefresh}\n />\n )}\n </View>\n );\n}\n"],"mappings":"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","names":["React","React","React","useCallback","Text","View","useCallback","React","View","Text","React","useCallback","Pressable","Text","View","useCallback","React","View","Text","Pressable"]}
|
|
1
|
+
{"version":3,"sources":["../src/theme/provider.tsx","../src/theme/helpers.ts","../src/discover/filter.ts","../src/discover/DiscoverRow.tsx","../src/discover/DiscoverList.tsx","../src/discover/DiscoverScreen.tsx"],"sourcesContent":["/**\n * Theme injection plumbing — provider + hook.\n *\n * The package carries ZERO theme values. The host app builds a concrete {@link Theme}\n * and wraps its tree in `<OctoSpacesThemeProvider theme={resolvedTheme}>`.\n * All primitives then call `useOctoSpacesTheme()` to read the active theme.\n */\nimport React, { createContext, useContext } from 'react';\nimport type { Theme } from './types.js';\n\nconst ThemeContext = createContext<Theme | null>(null);\n\nexport interface OctoSpacesThemeProviderProps {\n theme: Theme;\n children: React.ReactNode;\n}\n\n/**\n * Wrap your root component with this provider to inject the resolved Theme into\n * every primitive from `@drakkar.software/octospaces-ui`.\n *\n * @example\n * ```tsx\n * import { OctoSpacesThemeProvider } from '@drakkar.software/octospaces-ui';\n * import { resolvedTheme } from '@/theme'; // your app's theme\n *\n * export default function App() {\n * return (\n * <OctoSpacesThemeProvider theme={resolvedTheme}>\n * <RootNavigator />\n * </OctoSpacesThemeProvider>\n * );\n * }\n * ```\n */\nexport function OctoSpacesThemeProvider({ theme, children }: OctoSpacesThemeProviderProps) {\n return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>;\n}\n\n/**\n * Read the active theme. Throws if called outside an `<OctoSpacesThemeProvider>` —\n * this is intentional: a missing provider means primitives have no colors/spacing,\n * so a hard failure with a clear message is better than a silent rendering bug.\n */\nexport function useOctoSpacesTheme(): Theme {\n const theme = useContext(ThemeContext);\n if (!theme) {\n throw new Error(\n '[octospaces-ui] useOctoSpacesTheme() called outside of <OctoSpacesThemeProvider>. ' +\n 'Wrap your root component with <OctoSpacesThemeProvider theme={…}>.',\n );\n }\n return theme;\n}\n","/**\n * Pure palette-helper functions over a {@link Palette}. No theme values live here —\n * only functions that DERIVE from the injected palette (or from passed-in colors).\n *\n * Import these from `@drakkar.software/octospaces-ui` (re-exported by `src/index.ts`).\n */\nimport type { Palette, ShadowToken, Theme } from './types.js';\n\n// ── Presence ──────────────────────────────────────────────────────────────────\n\n/** Map a presence status string to the corresponding palette color. */\nexport function presenceColor(\n palette: Palette,\n status: 'online' | 'away' | 'busy' | 'offline' | string,\n): string {\n switch (status) {\n case 'online': return palette.presenceOnline;\n case 'away': return palette.presenceAway;\n case 'busy': return palette.presenceBusy;\n default: return palette.presenceOffline;\n }\n}\n\n// ── Verification ──────────────────────────────────────────────────────────────\n\n/** Map a verification level to the corresponding palette color. */\nexport function verificationColor(\n palette: Palette,\n level: 'verified' | 'partial' | 'none' | string,\n): string {\n switch (level) {\n case 'verified': return palette.verificationVerified;\n case 'partial': return palette.verificationPartial;\n default: return palette.verificationNone;\n }\n}\n\n// ── Avatar ────────────────────────────────────────────────────────────────────\n\nconst AVATAR_TINT_KEYS = [\n 'primary', 'success', 'warning', 'danger', 'info',\n] as const;\n\n/** Stable avatar background tint derived from a userId string. */\nexport function avatarTint(palette: Palette, userId: string): string {\n let hash = 0;\n for (let i = 0; i < userId.length; i++) hash = (hash * 31 + userId.charCodeAt(i)) | 0;\n const key = AVATAR_TINT_KEYS[Math.abs(hash) % AVATAR_TINT_KEYS.length];\n return (palette as unknown as Record<string, string>)[key] ?? palette.primary;\n}\n\n// ── Swatch ────────────────────────────────────────────────────────────────────\n\n/** Look up a named swatch; falls back to `palette.primary` if absent. */\nexport function swatch(theme: Theme, name: string): string {\n return theme.swatches[name] ?? theme.colors.primary;\n}\n\n// ── Borders ───────────────────────────────────────────────────────────────────\n\n/** Derive a `borderColor` value for a \"paper\" (elevated surface) border. */\nexport function paperBorder(palette: Palette): string {\n return palette.borderSubtle;\n}\n\n// ── Shadows ───────────────────────────────────────────────────────────────────\n\n/** Build a glow shadow token from a base color (used for focus rings, highlights). */\nexport function glowShadow(color: string, radius = 8, opacity = 0.4): ShadowToken {\n return {\n shadowColor: color,\n shadowOffset: { width: 0, height: 0 },\n shadowOpacity: opacity,\n shadowRadius: radius,\n elevation: 4,\n };\n}\n\n// ── Focus ring ────────────────────────────────────────────────────────────────\n\n/** Style object for a keyboard-focus indicator (web + React Native). */\nexport function focusRingStyle(\n palette: Palette,\n width = 2,\n): {\n borderWidth: number;\n borderColor: string;\n borderStyle: 'solid';\n} {\n return { borderWidth: width, borderColor: palette.focus, borderStyle: 'solid' };\n}\n\n// ── Status color ──────────────────────────────────────────────────────────────\n\n/** Map a semantic status name to its palette color. */\nexport function statusColor(\n palette: Palette,\n status: 'success' | 'warning' | 'danger' | 'info' | string,\n muted = false,\n): string {\n if (muted) {\n switch (status) {\n case 'success': return palette.successMuted;\n case 'warning': return palette.warningMuted;\n case 'danger': return palette.dangerMuted;\n default: return palette.infoMuted;\n }\n }\n switch (status) {\n case 'success': return palette.success;\n case 'warning': return palette.warning;\n case 'danger': return palette.danger;\n default: return palette.info;\n }\n}\n","import type { DiscoverEntry } from './types.js';\n\n/**\n * Case-insensitive substring filter over a `DiscoverEntry[]`.\n *\n * Returns the original array reference unchanged when `query` is blank so the\n * caller can skip a re-render. Pure function — no side effects.\n */\nexport function filterDiscoverEntries(\n entries: DiscoverEntry[],\n query: string,\n): DiscoverEntry[] {\n const q = query.trim().toLowerCase();\n if (!q) return entries;\n return entries.filter((e) => e.title.toLowerCase().includes(q));\n}\n\n/**\n * Sort discover entries by updatedAt descending (most recent first).\n * Entries without an `updatedAt` field sort last. Pure function.\n */\nexport function sortDiscoverEntries(entries: DiscoverEntry[]): DiscoverEntry[] {\n return [...entries].sort((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0));\n}\n","/**\n * A single row in the Discover list — shows the object's emoji/icon, title,\n * and type. All app-specific behaviour is injected via props:\n * - `renderIcon` — render a type/emoji icon; receives the entry and must\n * return a ReactNode (null for no icon).\n * - `onOpen` — called when the row is pressed.\n *\n * Styled entirely from the injected {@link Theme} via `useOctoSpacesTheme()`.\n */\nimport React, { useCallback } from 'react';\nimport { Pressable, Text, View } from 'react-native';\n\nimport { useOctoSpacesTheme } from '../theme/provider.js';\nimport type { DiscoverEntry } from './types.js';\n\nexport interface DiscoverRowProps {\n entry: DiscoverEntry;\n /** Render a leading icon for the entry. Return `null` to show nothing. */\n renderIcon?: (entry: DiscoverEntry) => React.ReactNode;\n /** Called when the user taps the row. */\n onOpen: (entry: DiscoverEntry) => void;\n}\n\nexport function DiscoverRow({ entry, renderIcon, onOpen }: DiscoverRowProps) {\n const theme = useOctoSpacesTheme();\n\n const handlePress = useCallback(() => {\n onOpen(entry);\n }, [entry, onOpen]);\n\n const icon = renderIcon ? renderIcon(entry) : null;\n const displayEmoji = !icon && entry.emoji ? entry.emoji : null;\n\n return (\n <Pressable\n onPress={handlePress}\n style={({ pressed }) => ({\n flexDirection: 'row',\n alignItems: 'center',\n paddingVertical: (theme.spacing['3'] as number) ?? 12,\n paddingHorizontal: (theme.spacing['4'] as number) ?? 16,\n backgroundColor: pressed\n ? (theme.colors.surface ?? '#f5f5f5')\n : 'transparent',\n borderRadius: (theme.radii['sm'] as number) ?? 6,\n })}\n accessibilityRole=\"button\"\n accessibilityLabel={entry.title || 'Untitled'}\n >\n {/* Leading icon / emoji */}\n {(icon || displayEmoji) && (\n <View\n style={{\n width: 28,\n height: 28,\n marginRight: (theme.spacing['2'] as number) ?? 8,\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n >\n {icon ?? (\n <Text style={{ fontSize: 18, lineHeight: 24 }}>{displayEmoji}</Text>\n )}\n </View>\n )}\n\n {/* Title + type subtitle */}\n <View style={{ flex: 1, minWidth: 0 }}>\n <Text\n numberOfLines={1}\n style={{\n fontSize: (theme.type['body']?.size ?? 15),\n lineHeight: (theme.type['body']?.lineHeight ?? 22),\n color: entry.title ? theme.colors.text : theme.colors.textTertiary,\n fontFamily: theme.fonts['body'] ?? undefined,\n }}\n >\n {entry.title || 'Untitled'}\n </Text>\n <Text\n numberOfLines={1}\n style={{\n fontSize: (theme.type['caption']?.size ?? 12),\n lineHeight: (theme.type['caption']?.lineHeight ?? 18),\n color: theme.colors.textSecondary,\n marginTop: 1,\n textTransform: 'capitalize',\n }}\n >\n {entry.type}\n </Text>\n </View>\n </Pressable>\n );\n}\n","/**\n * A themed FlatList wrapper that renders a list of {@link DiscoverEntry} rows.\n *\n * All app-specific behaviour is injected via props so this component has zero\n * imports from any specific OctoSpaces app.\n */\nimport React, { useCallback } from 'react';\nimport { FlatList, RefreshControl, Text, View } from 'react-native';\n\nimport { useOctoSpacesTheme } from '../theme/provider.js';\nimport { DiscoverRow } from './DiscoverRow.js';\nimport type { DiscoverEntry } from './types.js';\n\nexport interface DiscoverListProps {\n entries: DiscoverEntry[];\n /** Render a leading icon for each row — see {@link DiscoverRowProps.renderIcon}. */\n renderIcon?: (entry: DiscoverEntry) => React.ReactNode;\n /** Called when a row is tapped. */\n onOpen: (entry: DiscoverEntry) => void;\n /** Text shown when `entries` is empty (default: \"No public objects found\"). */\n emptyMessage?: string;\n /** Whether a pull-to-refresh is currently in progress. */\n refreshing?: boolean;\n /** Called when the user pulls to refresh. */\n onRefresh?: () => void;\n}\n\nexport function DiscoverList({\n entries,\n renderIcon,\n onOpen,\n emptyMessage = 'No public objects found',\n refreshing,\n onRefresh,\n}: DiscoverListProps) {\n const theme = useOctoSpacesTheme();\n\n const renderItem = useCallback(\n ({ item }: { item: DiscoverEntry }) => (\n <DiscoverRow entry={item} renderIcon={renderIcon} onOpen={onOpen} />\n ),\n [renderIcon, onOpen],\n );\n\n const keyExtractor = useCallback(\n (item: DiscoverEntry) => `${item.spaceId}:${item.id}`,\n [],\n );\n\n if (entries.length === 0) {\n return (\n <View\n style={{\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: (theme.spacing['6'] as number) ?? 24,\n }}\n >\n <Text\n style={{\n fontSize: theme.type['body']?.size ?? 15,\n color: theme.colors.textSecondary,\n textAlign: 'center',\n }}\n >\n {emptyMessage}\n </Text>\n </View>\n );\n }\n\n return (\n <FlatList\n data={entries}\n renderItem={renderItem}\n keyExtractor={keyExtractor}\n contentContainerStyle={{ paddingVertical: (theme.spacing['1'] as number) ?? 4 }}\n showsVerticalScrollIndicator={false}\n removeClippedSubviews\n refreshControl={\n onRefresh ? (\n <RefreshControl\n refreshing={refreshing ?? false}\n onRefresh={onRefresh}\n tintColor={theme.colors.primary}\n />\n ) : undefined\n }\n />\n );\n}\n","/**\n * Generic public-object discovery screen.\n *\n * Loads the world-readable public-object directory via `loadEntries`, renders a\n * search bar, and delegates row rendering + tap behaviour to the injected props.\n * No app-specific logic lives here — all customisation is via props:\n *\n * ```tsx\n * <DiscoverScreen\n * loadEntries={readObjectDirectory}\n * renderIcon={(e) => <TypeIcon entry={e} />}\n * onOpen={(e) => router.push({ pathname: routeForNode(e), params: { id: e.id, spaceId: e.spaceId } })}\n * />\n * ```\n *\n * State machine:\n * idle → loading → (ready | error)\n * Any pull of `loadEntries` updates the entries; errors show a retry button.\n */\nimport React, { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { ActivityIndicator, Pressable, Text, TextInput, View, type TextStyle } from 'react-native';\n\nimport { useOctoSpacesTheme } from '../theme/provider.js';\nimport { DiscoverList } from './DiscoverList.js';\nimport { filterDiscoverEntries, sortDiscoverEntries } from './filter.js';\nimport type { DiscoverEntry } from './types.js';\n\nexport interface DiscoverScreenProps {\n /**\n * Async function that resolves to the current public-object directory.\n * Typically `readObjectDirectory` from `@drakkar.software/octospaces-sdk`.\n * Called on mount and when `refresh()` is triggered.\n */\n loadEntries: () => Promise<DiscoverEntry[]>;\n /** Render a leading icon for each row. */\n renderIcon?: (entry: DiscoverEntry) => React.ReactNode;\n /** Called when the user taps a row — navigate to the object. */\n onOpen: (entry: DiscoverEntry) => void;\n /**\n * Optional heading text shown above the search bar.\n * @default \"Discover\"\n */\n title?: string;\n /**\n * Text shown when the directory is empty after loading.\n * @default \"No public objects yet\"\n */\n emptyMessage?: string;\n /**\n * Text shown when the directory is empty due to an active search query.\n * @default \"No results for «query»\"\n */\n emptySearchMessage?: string;\n /**\n * Whether to show the inline search bar.\n * @default true\n */\n searchEnabled?: boolean;\n /**\n * Optional ref whose `.current` is set to a `reload()` function once mounted.\n * Lets a host (e.g. a tab screen) trigger a soft-refresh on focus without\n * blanking the existing list — identical to pull-to-refresh behaviour.\n *\n * ```tsx\n * const reloadRef = useRef<() => void>(null);\n * useFocusEffect(useCallback(() => { reloadRef.current?.(); }, []));\n * <DiscoverScreen reloadRef={reloadRef} ... />\n * ```\n */\n reloadRef?: React.RefObject<(() => void) | null>;\n}\n\ntype State =\n | { status: 'idle' }\n | { status: 'loading' }\n | { status: 'ready'; entries: DiscoverEntry[] }\n | { status: 'error'; message: string };\n\nexport function DiscoverScreen({\n loadEntries,\n renderIcon,\n onOpen,\n title = 'Discover',\n emptyMessage = 'No public objects yet',\n emptySearchMessage,\n searchEnabled = true,\n reloadRef,\n}: DiscoverScreenProps) {\n const theme = useOctoSpacesTheme();\n const [state, setState] = useState<State>({ status: 'idle' });\n const [query, setQuery] = useState('');\n const [refreshing, setRefreshing] = useState(false);\n const cancelledRef = useRef(false);\n\n const load = useCallback(async () => {\n setState({ status: 'loading' });\n try {\n const raw = await loadEntries();\n if (cancelledRef.current) return;\n setState({ status: 'ready', entries: sortDiscoverEntries(raw) });\n } catch (err) {\n if (cancelledRef.current) return;\n setState({\n status: 'error',\n message: err instanceof Error ? err.message : 'Failed to load directory',\n });\n }\n }, [loadEntries]);\n\n /** Pull-to-refresh: re-fetches without blanking the existing list. */\n const handleRefresh = useCallback(async () => {\n setRefreshing(true);\n try {\n const raw = await loadEntries();\n if (cancelledRef.current) return;\n setState({ status: 'ready', entries: sortDiscoverEntries(raw) });\n } catch {\n // keep the existing list on refresh failure; the retry button remains for error state\n } finally {\n if (!cancelledRef.current) setRefreshing(false);\n }\n }, [loadEntries]);\n\n // Expose handleRefresh via reloadRef so a host can trigger a soft reload on focus.\n useImperativeHandle(reloadRef, () => handleRefresh, [handleRefresh]);\n\n useEffect(() => {\n cancelledRef.current = false;\n void load();\n return () => {\n cancelledRef.current = true;\n };\n }, [load]);\n\n // ── Derived list ─────────────────────────────────────────────────────────\n const allEntries = state.status === 'ready' ? state.entries : [];\n const visibleEntries = filterDiscoverEntries(allEntries, query);\n const noSearchResults = !!query.trim() && visibleEntries.length === 0 && allEntries.length > 0;\n const resolvedEmptyMessage = noSearchResults\n ? (emptySearchMessage ?? `No results for \"${query.trim()}\"`)\n : emptyMessage;\n\n // ── Palette shortcuts ─────────────────────────────────────────────────────\n const sp2 = (theme.spacing['2'] as number) ?? 8;\n const sp3 = (theme.spacing['3'] as number) ?? 12;\n const sp4 = (theme.spacing['4'] as number) ?? 16;\n const radMd = (theme.radii['md'] as number) ?? 8;\n\n return (\n <View style={{ flex: 1, backgroundColor: theme.colors.background }}>\n {/* Header */}\n <View\n style={{\n paddingHorizontal: sp4,\n paddingTop: sp4,\n paddingBottom: sp2,\n }}\n >\n <Text\n style={{\n fontSize: theme.type['title2']?.size ?? 22,\n fontWeight: (theme.type['title2']?.weight as TextStyle['fontWeight']) ?? '700',\n lineHeight: theme.type['title2']?.lineHeight ?? 28,\n color: theme.colors.text,\n fontFamily: theme.fonts['heading'] ?? undefined,\n marginBottom: sp3,\n }}\n >\n {title}\n </Text>\n\n {/* Search bar */}\n {searchEnabled && (\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n backgroundColor: theme.colors.surfaceInput ?? theme.colors.surface,\n borderRadius: radMd,\n borderWidth: 1,\n borderColor: theme.colors.borderSubtle,\n paddingHorizontal: sp3,\n height: 40,\n }}\n >\n <TextInput\n placeholder=\"Search…\"\n placeholderTextColor={theme.colors.textTertiary}\n value={query}\n onChangeText={setQuery}\n style={{\n flex: 1,\n fontSize: theme.type['body']?.size ?? 15,\n color: theme.colors.text,\n fontFamily: theme.fonts['body'] ?? undefined,\n }}\n returnKeyType=\"search\"\n clearButtonMode=\"while-editing\"\n accessibilityLabel=\"Search discover\"\n />\n </View>\n )}\n </View>\n\n {/* Body */}\n {state.status === 'loading' ? (\n <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>\n <ActivityIndicator color={theme.colors.primary} />\n </View>\n ) : state.status === 'error' ? (\n <View\n style={{\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: sp4,\n }}\n >\n <Text\n style={{\n color: theme.colors.textSecondary,\n fontSize: theme.type['body']?.size ?? 15,\n textAlign: 'center',\n marginBottom: sp3,\n }}\n >\n {state.message}\n </Text>\n <Pressable\n onPress={load}\n style={{\n paddingHorizontal: sp4,\n paddingVertical: sp2,\n backgroundColor: theme.colors.primary,\n borderRadius: radMd,\n }}\n >\n <Text style={{ color: theme.colors.textOnPrimary, fontWeight: '600' }}>\n Retry\n </Text>\n </Pressable>\n </View>\n ) : (\n <DiscoverList\n entries={visibleEntries}\n renderIcon={renderIcon}\n onOpen={onOpen}\n emptyMessage={resolvedEmptyMessage}\n refreshing={refreshing}\n onRefresh={handleRefresh}\n />\n )}\n </View>\n );\n}\n"],"mappings":";AAOA,OAAO,SAAS,eAAe,kBAAkB;AAGjD,IAAM,eAAe,cAA4B,IAAI;AAyB9C,SAAS,wBAAwB,EAAE,OAAO,SAAS,GAAiC;AACzF,SAAO,oCAAC,aAAa,UAAb,EAAsB,OAAO,SAAQ,QAAS;AACxD;AAOO,SAAS,qBAA4B;AAC1C,QAAM,QAAQ,WAAW,YAAY;AACrC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACA,SAAO;AACT;;;AC1CO,SAAS,cACd,SACA,QACQ;AACR,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAU,aAAO,QAAQ;AAAA,IAC9B,KAAK;AAAU,aAAO,QAAQ;AAAA,IAC9B,KAAK;AAAU,aAAO,QAAQ;AAAA,IAC9B;AAAe,aAAO,QAAQ;AAAA,EAChC;AACF;AAKO,SAAS,kBACd,SACA,OACQ;AACR,UAAQ,OAAO;AAAA,IACb,KAAK;AAAY,aAAO,QAAQ;AAAA,IAChC,KAAK;AAAY,aAAO,QAAQ;AAAA,IAChC;AAAiB,aAAO,QAAQ;AAAA,EAClC;AACF;AAIA,IAAM,mBAAmB;AAAA,EACvB;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EAAU;AAC7C;AAGO,SAAS,WAAW,SAAkB,QAAwB;AACnE,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,QAAQ,OAAO,KAAK,OAAO,WAAW,CAAC,IAAK;AACpF,QAAM,MAAM,iBAAiB,KAAK,IAAI,IAAI,IAAI,iBAAiB,MAAM;AACrE,SAAQ,QAA8C,GAAG,KAAK,QAAQ;AACxE;AAKO,SAAS,OAAO,OAAc,MAAsB;AACzD,SAAO,MAAM,SAAS,IAAI,KAAK,MAAM,OAAO;AAC9C;AAKO,SAAS,YAAY,SAA0B;AACpD,SAAO,QAAQ;AACjB;AAKO,SAAS,WAAW,OAAe,SAAS,GAAG,UAAU,KAAkB;AAChF,SAAO;AAAA,IACL,aAAa;AAAA,IACb,cAAc,EAAE,OAAO,GAAG,QAAQ,EAAE;AAAA,IACpC,eAAe;AAAA,IACf,cAAc;AAAA,IACd,WAAW;AAAA,EACb;AACF;AAKO,SAAS,eACd,SACA,QAAQ,GAKR;AACA,SAAO,EAAE,aAAa,OAAO,aAAa,QAAQ,OAAO,aAAa,QAAQ;AAChF;AAKO,SAAS,YACd,SACA,QACA,QAAQ,OACA;AACR,MAAI,OAAO;AACT,YAAQ,QAAQ;AAAA,MACd,KAAK;AAAW,eAAO,QAAQ;AAAA,MAC/B,KAAK;AAAW,eAAO,QAAQ;AAAA,MAC/B,KAAK;AAAW,eAAO,QAAQ;AAAA,MAC/B;AAAgB,eAAO,QAAQ;AAAA,IACjC;AAAA,EACF;AACA,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAW,aAAO,QAAQ;AAAA,IAC/B,KAAK;AAAW,aAAO,QAAQ;AAAA,IAC/B,KAAK;AAAW,aAAO,QAAQ;AAAA,IAC/B;AAAgB,aAAO,QAAQ;AAAA,EACjC;AACF;;;AC1GO,SAAS,sBACd,SACA,OACiB;AACjB,QAAM,IAAI,MAAM,KAAK,EAAE,YAAY;AACnC,MAAI,CAAC,EAAG,QAAO;AACf,SAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,MAAM,YAAY,EAAE,SAAS,CAAC,CAAC;AAChE;AAMO,SAAS,oBAAoB,SAA2C;AAC7E,SAAO,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,OAAO,EAAE,aAAa,MAAM,EAAE,aAAa,EAAE;AAC5E;;;ACdA,OAAOA,UAAS,mBAAmB;AACnC,SAAS,WAAW,MAAM,YAAY;AAa/B,SAAS,YAAY,EAAE,OAAO,YAAY,OAAO,GAAqB;AAC3E,QAAM,QAAQ,mBAAmB;AAEjC,QAAM,cAAc,YAAY,MAAM;AACpC,WAAO,KAAK;AAAA,EACd,GAAG,CAAC,OAAO,MAAM,CAAC;AAElB,QAAM,OAAO,aAAa,WAAW,KAAK,IAAI;AAC9C,QAAM,eAAe,CAAC,QAAQ,MAAM,QAAQ,MAAM,QAAQ;AAE1D,SACE,gBAAAC,OAAA;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,OAAO,CAAC,EAAE,QAAQ,OAAO;AAAA,QACvB,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,iBAAkB,MAAM,QAAQ,GAAG,KAAgB;AAAA,QACnD,mBAAoB,MAAM,QAAQ,GAAG,KAAgB;AAAA,QACrD,iBAAiB,UACZ,MAAM,OAAO,WAAW,YACzB;AAAA,QACJ,cAAe,MAAM,MAAM,IAAI,KAAgB;AAAA,MACjD;AAAA,MACA,mBAAkB;AAAA,MAClB,oBAAoB,MAAM,SAAS;AAAA;AAAA,KAGjC,QAAQ,iBACR,gBAAAA,OAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aAAc,MAAM,QAAQ,GAAG,KAAgB;AAAA,UAC/C,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,YAAY;AAAA,QACd;AAAA;AAAA,MAEC,QACC,gBAAAA,OAAA,cAAC,QAAK,OAAO,EAAE,UAAU,IAAI,YAAY,GAAG,KAAI,YAAa;AAAA,IAEjE;AAAA,IAIF,gBAAAA,OAAA,cAAC,QAAK,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,KAClC,gBAAAA,OAAA;AAAA,MAAC;AAAA;AAAA,QACC,eAAe;AAAA,QACf,OAAO;AAAA,UACL,UAAW,MAAM,KAAK,MAAM,GAAG,QAAQ;AAAA,UACvC,YAAa,MAAM,KAAK,MAAM,GAAG,cAAc;AAAA,UAC/C,OAAO,MAAM,QAAQ,MAAM,OAAO,OAAO,MAAM,OAAO;AAAA,UACtD,YAAY,MAAM,MAAM,MAAM,KAAK;AAAA,QACrC;AAAA;AAAA,MAEC,MAAM,SAAS;AAAA,IAClB,GACA,gBAAAA,OAAA;AAAA,MAAC;AAAA;AAAA,QACC,eAAe;AAAA,QACf,OAAO;AAAA,UACL,UAAW,MAAM,KAAK,SAAS,GAAG,QAAQ;AAAA,UAC1C,YAAa,MAAM,KAAK,SAAS,GAAG,cAAc;AAAA,UAClD,OAAO,MAAM,OAAO;AAAA,UACpB,WAAW;AAAA,UACX,eAAe;AAAA,QACjB;AAAA;AAAA,MAEC,MAAM;AAAA,IACT,CACF;AAAA,EACF;AAEJ;;;ACzFA,OAAOC,UAAS,eAAAC,oBAAmB;AACnC,SAAS,UAAU,gBAAgB,QAAAC,OAAM,QAAAC,aAAY;AAoB9C,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,QAAQ,mBAAmB;AAEjC,QAAM,aAAaC;AAAA,IACjB,CAAC,EAAE,KAAK,MACN,gBAAAC,OAAA,cAAC,eAAY,OAAO,MAAM,YAAwB,QAAgB;AAAA,IAEpE,CAAC,YAAY,MAAM;AAAA,EACrB;AAEA,QAAM,eAAeD;AAAA,IACnB,CAAC,SAAwB,GAAG,KAAK,OAAO,IAAI,KAAK,EAAE;AAAA,IACnD,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,WACE,gBAAAC,OAAA;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,mBAAoB,MAAM,QAAQ,GAAG,KAAgB;AAAA,QACvD;AAAA;AAAA,MAEA,gBAAAD,OAAA;AAAA,QAACE;AAAA,QAAA;AAAA,UACC,OAAO;AAAA,YACL,UAAU,MAAM,KAAK,MAAM,GAAG,QAAQ;AAAA,YACtC,OAAO,MAAM,OAAO;AAAA,YACpB,WAAW;AAAA,UACb;AAAA;AAAA,QAEC;AAAA,MACH;AAAA,IACF;AAAA,EAEJ;AAEA,SACE,gBAAAF,OAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,uBAAuB,EAAE,iBAAkB,MAAM,QAAQ,GAAG,KAAgB,EAAE;AAAA,MAC9E,8BAA8B;AAAA,MAC9B,uBAAqB;AAAA,MACrB,gBACE,YACE,gBAAAA,OAAA;AAAA,QAAC;AAAA;AAAA,UACC,YAAY,cAAc;AAAA,UAC1B;AAAA,UACA,WAAW,MAAM,OAAO;AAAA;AAAA,MAC1B,IACE;AAAA;AAAA,EAER;AAEJ;;;ACxEA,OAAOG,UAAS,eAAAC,cAAa,WAAW,qBAAqB,QAAQ,gBAAgB;AACrF,SAAS,mBAAmB,aAAAC,YAAW,QAAAC,OAAM,WAAW,QAAAC,aAA4B;AA0D7E,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,eAAe;AAAA,EACf;AAAA,EACA,gBAAgB;AAAA,EAChB;AACF,GAAwB;AACtB,QAAM,QAAQ,mBAAmB;AACjC,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAgB,EAAE,QAAQ,OAAO,CAAC;AAC5D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,EAAE;AACrC,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,eAAe,OAAO,KAAK;AAEjC,QAAM,OAAOC,aAAY,YAAY;AACnC,aAAS,EAAE,QAAQ,UAAU,CAAC;AAC9B,QAAI;AACF,YAAM,MAAM,MAAM,YAAY;AAC9B,UAAI,aAAa,QAAS;AAC1B,eAAS,EAAE,QAAQ,SAAS,SAAS,oBAAoB,GAAG,EAAE,CAAC;AAAA,IACjE,SAAS,KAAK;AACZ,UAAI,aAAa,QAAS;AAC1B,eAAS;AAAA,QACP,QAAQ;AAAA,QACR,SAAS,eAAe,QAAQ,IAAI,UAAU;AAAA,MAChD,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAGhB,QAAM,gBAAgBA,aAAY,YAAY;AAC5C,kBAAc,IAAI;AAClB,QAAI;AACF,YAAM,MAAM,MAAM,YAAY;AAC9B,UAAI,aAAa,QAAS;AAC1B,eAAS,EAAE,QAAQ,SAAS,SAAS,oBAAoB,GAAG,EAAE,CAAC;AAAA,IACjE,QAAQ;AAAA,IAER,UAAE;AACA,UAAI,CAAC,aAAa,QAAS,eAAc,KAAK;AAAA,IAChD;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAGhB,sBAAoB,WAAW,MAAM,eAAe,CAAC,aAAa,CAAC;AAEnE,YAAU,MAAM;AACd,iBAAa,UAAU;AACvB,SAAK,KAAK;AACV,WAAO,MAAM;AACX,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAGT,QAAM,aAAa,MAAM,WAAW,UAAU,MAAM,UAAU,CAAC;AAC/D,QAAM,iBAAiB,sBAAsB,YAAY,KAAK;AAC9D,QAAM,kBAAkB,CAAC,CAAC,MAAM,KAAK,KAAK,eAAe,WAAW,KAAK,WAAW,SAAS;AAC7F,QAAM,uBAAuB,kBACxB,sBAAsB,mBAAmB,MAAM,KAAK,CAAC,MACtD;AAGJ,QAAM,MAAO,MAAM,QAAQ,GAAG,KAAgB;AAC9C,QAAM,MAAO,MAAM,QAAQ,GAAG,KAAgB;AAC9C,QAAM,MAAO,MAAM,QAAQ,GAAG,KAAgB;AAC9C,QAAM,QAAS,MAAM,MAAM,IAAI,KAAgB;AAE/C,SACE,gBAAAC,OAAA,cAACC,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,iBAAiB,MAAM,OAAO,WAAW,KAE/D,gBAAAD,OAAA;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,mBAAmB;AAAA,QACnB,YAAY;AAAA,QACZ,eAAe;AAAA,MACjB;AAAA;AAAA,IAEA,gBAAAD,OAAA;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU,MAAM,KAAK,QAAQ,GAAG,QAAQ;AAAA,UACxC,YAAa,MAAM,KAAK,QAAQ,GAAG,UAAsC;AAAA,UACzE,YAAY,MAAM,KAAK,QAAQ,GAAG,cAAc;AAAA,UAChD,OAAO,MAAM,OAAO;AAAA,UACpB,YAAY,MAAM,MAAM,SAAS,KAAK;AAAA,UACtC,cAAc;AAAA,QAChB;AAAA;AAAA,MAEC;AAAA,IACH;AAAA,IAGC,iBACC,gBAAAF,OAAA;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,eAAe;AAAA,UACf,YAAY;AAAA,UACZ,iBAAiB,MAAM,OAAO,gBAAgB,MAAM,OAAO;AAAA,UAC3D,cAAc;AAAA,UACd,aAAa;AAAA,UACb,aAAa,MAAM,OAAO;AAAA,UAC1B,mBAAmB;AAAA,UACnB,QAAQ;AAAA,QACV;AAAA;AAAA,MAEA,gBAAAD,OAAA;AAAA,QAAC;AAAA;AAAA,UACC,aAAY;AAAA,UACZ,sBAAsB,MAAM,OAAO;AAAA,UACnC,OAAO;AAAA,UACP,cAAc;AAAA,UACd,OAAO;AAAA,YACL,MAAM;AAAA,YACN,UAAU,MAAM,KAAK,MAAM,GAAG,QAAQ;AAAA,YACtC,OAAO,MAAM,OAAO;AAAA,YACpB,YAAY,MAAM,MAAM,MAAM,KAAK;AAAA,UACrC;AAAA,UACA,eAAc;AAAA,UACd,iBAAgB;AAAA,UAChB,oBAAmB;AAAA;AAAA,MACrB;AAAA,IACF;AAAA,EAEJ,GAGC,MAAM,WAAW,YAChB,gBAAAA,OAAA,cAACC,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,YAAY,UAAU,gBAAgB,SAAS,KACrE,gBAAAD,OAAA,cAAC,qBAAkB,OAAO,MAAM,OAAO,SAAS,CAClD,IACE,MAAM,WAAW,UACnB,gBAAAA,OAAA;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,mBAAmB;AAAA,MACrB;AAAA;AAAA,IAEA,gBAAAD,OAAA;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,OAAO,MAAM,OAAO;AAAA,UACpB,UAAU,MAAM,KAAK,MAAM,GAAG,QAAQ;AAAA,UACtC,WAAW;AAAA,UACX,cAAc;AAAA,QAChB;AAAA;AAAA,MAEC,MAAM;AAAA,IACT;AAAA,IACA,gBAAAF,OAAA;AAAA,MAACG;AAAA,MAAA;AAAA,QACC,SAAS;AAAA,QACT,OAAO;AAAA,UACL,mBAAmB;AAAA,UACnB,iBAAiB;AAAA,UACjB,iBAAiB,MAAM,OAAO;AAAA,UAC9B,cAAc;AAAA,QAChB;AAAA;AAAA,MAEA,gBAAAH,OAAA,cAACE,OAAA,EAAK,OAAO,EAAE,OAAO,MAAM,OAAO,eAAe,YAAY,MAAM,KAAG,OAEvE;AAAA,IACF;AAAA,EACF,IAEA,gBAAAF,OAAA;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd;AAAA,MACA,WAAW;AAAA;AAAA,EACb,CAEJ;AAEJ;","names":["React","React","React","useCallback","Text","View","useCallback","React","View","Text","React","useCallback","Pressable","Text","View","useCallback","React","View","Text","Pressable"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drakkar.software/octospaces-ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Shared headless-themed UI primitives for OctoSpaces apps. Theme values are injected by the host app; this package ships only types + plumbing + primitives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|