react-native-gtkx 0.1.0-alpha.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/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/animated/composite.d.ts +5 -0
- package/dist/animated/composite.js +132 -0
- package/dist/animated/composite.js.map +1 -0
- package/dist/animated/create-animated.d.ts +12 -0
- package/dist/animated/create-animated.js +17 -0
- package/dist/animated/create-animated.js.map +1 -0
- package/dist/animated/easing.d.ts +11 -0
- package/dist/animated/easing.js +91 -0
- package/dist/animated/easing.js.map +1 -0
- package/dist/animated/frame-loop.d.ts +6 -0
- package/dist/animated/frame-loop.js +25 -0
- package/dist/animated/frame-loop.js.map +1 -0
- package/dist/animated/index.d.ts +6 -0
- package/dist/animated/index.js +7 -0
- package/dist/animated/index.js.map +1 -0
- package/dist/animated/interpolate.d.ts +2 -0
- package/dist/animated/interpolate.js +90 -0
- package/dist/animated/interpolate.js.map +1 -0
- package/dist/animated/native-driver.d.ts +1 -0
- package/dist/animated/native-driver.js +17 -0
- package/dist/animated/native-driver.js.map +1 -0
- package/dist/animated/spring.d.ts +3 -0
- package/dist/animated/spring.js +67 -0
- package/dist/animated/spring.js.map +1 -0
- package/dist/animated/timing.d.ts +3 -0
- package/dist/animated/timing.js +30 -0
- package/dist/animated/timing.js.map +1 -0
- package/dist/animated/types.d.ts +51 -0
- package/dist/animated/types.js +6 -0
- package/dist/animated/types.js.map +1 -0
- package/dist/animated/value-animation.d.ts +9 -0
- package/dist/animated/value-animation.js +65 -0
- package/dist/animated/value-animation.js.map +1 -0
- package/dist/animated/value.d.ts +46 -0
- package/dist/animated/value.js +130 -0
- package/dist/animated/value.js.map +1 -0
- package/dist/apis/alert.d.ts +16 -0
- package/dist/apis/alert.js +33 -0
- package/dist/apis/alert.js.map +1 -0
- package/dist/apis/app-state.d.ts +11 -0
- package/dist/apis/app-state.js +54 -0
- package/dist/apis/app-state.js.map +1 -0
- package/dist/apis/appearance.d.ts +12 -0
- package/dist/apis/appearance.js +33 -0
- package/dist/apis/appearance.js.map +1 -0
- package/dist/apis/dev-settings.d.ts +9 -0
- package/dist/apis/dev-settings.js +25 -0
- package/dist/apis/dev-settings.js.map +1 -0
- package/dist/apis/dimensions.d.ts +14 -0
- package/dist/apis/dimensions.js +80 -0
- package/dist/apis/dimensions.js.map +1 -0
- package/dist/apis/emitter.d.ts +8 -0
- package/dist/apis/emitter.js +35 -0
- package/dist/apis/emitter.js.map +1 -0
- package/dist/apis/hooks.d.ts +11 -0
- package/dist/apis/hooks.js +29 -0
- package/dist/apis/hooks.js.map +1 -0
- package/dist/apis/host.d.ts +45 -0
- package/dist/apis/host.gtkx.d.ts +2 -0
- package/dist/apis/host.gtkx.js +301 -0
- package/dist/apis/host.gtkx.js.map +1 -0
- package/dist/apis/host.js +6 -0
- package/dist/apis/host.js.map +1 -0
- package/dist/apis/index.d.ts +39 -0
- package/dist/apis/index.js +21 -0
- package/dist/apis/index.js.map +1 -0
- package/dist/apis/linking.d.ts +7 -0
- package/dist/apis/linking.js +28 -0
- package/dist/apis/linking.js.map +1 -0
- package/dist/apis/platform.d.ts +14 -0
- package/dist/apis/platform.js +23 -0
- package/dist/apis/platform.js.map +1 -0
- package/dist/components/activity-indicator.d.ts +10 -0
- package/dist/components/activity-indicator.js +21 -0
- package/dist/components/activity-indicator.js.map +1 -0
- package/dist/components/animated.d.ts +34 -0
- package/dist/components/animated.js +152 -0
- package/dist/components/animated.js.map +1 -0
- package/dist/components/app-registry.d.ts +14 -0
- package/dist/components/app-registry.js +61 -0
- package/dist/components/app-registry.js.map +1 -0
- package/dist/components/flat-list.d.ts +48 -0
- package/dist/components/flat-list.js +23 -0
- package/dist/components/flat-list.js.map +1 -0
- package/dist/components/host-node.d.ts +10 -0
- package/dist/components/host-node.js +10 -0
- package/dist/components/host-node.js.map +1 -0
- package/dist/components/image-loader.d.ts +17 -0
- package/dist/components/image-loader.js +54 -0
- package/dist/components/image-loader.js.map +1 -0
- package/dist/components/image.d.ts +19 -0
- package/dist/components/image.js +73 -0
- package/dist/components/image.js.map +1 -0
- package/dist/components/index.d.ts +14 -0
- package/dist/components/index.js +14 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/modal.d.ts +12 -0
- package/dist/components/modal.js +18 -0
- package/dist/components/modal.js.map +1 -0
- package/dist/components/pressable.d.ts +33 -0
- package/dist/components/pressable.js +116 -0
- package/dist/components/pressable.js.map +1 -0
- package/dist/components/rect-store.d.ts +17 -0
- package/dist/components/rect-store.js +40 -0
- package/dist/components/rect-store.js.map +1 -0
- package/dist/components/root.d.ts +8 -0
- package/dist/components/root.js +59 -0
- package/dist/components/root.js.map +1 -0
- package/dist/components/scroll-view.d.ts +56 -0
- package/dist/components/scroll-view.js +324 -0
- package/dist/components/scroll-view.js.map +1 -0
- package/dist/components/switch.d.ts +11 -0
- package/dist/components/switch.js +20 -0
- package/dist/components/switch.js.map +1 -0
- package/dist/components/text-input.d.ts +23 -0
- package/dist/components/text-input.js +151 -0
- package/dist/components/text-input.js.map +1 -0
- package/dist/components/text.d.ts +11 -0
- package/dist/components/text.js +100 -0
- package/dist/components/text.js.map +1 -0
- package/dist/components/use-layout-child.d.ts +36 -0
- package/dist/components/use-layout-child.js +177 -0
- package/dist/components/use-layout-child.js.map +1 -0
- package/dist/components/view.d.ts +13 -0
- package/dist/components/view.js +60 -0
- package/dist/components/view.js.map +1 -0
- package/dist/components/virtualized-list.d.ts +67 -0
- package/dist/components/virtualized-list.js +519 -0
- package/dist/components/virtualized-list.js.map +1 -0
- package/dist/contracts.d.ts +119 -0
- package/dist/contracts.js +5 -0
- package/dist/contracts.js.map +1 -0
- package/dist/gtkx/bridge/index.d.ts +16 -0
- package/dist/gtkx/bridge/index.js +25 -0
- package/dist/gtkx/bridge/index.js.map +1 -0
- package/dist/gtkx/bridge/layout-manager.d.ts +11 -0
- package/dist/gtkx/bridge/layout-manager.js +87 -0
- package/dist/gtkx/bridge/layout-manager.js.map +1 -0
- package/dist/gtkx/bridge/measure.d.ts +9 -0
- package/dist/gtkx/bridge/measure.js +20 -0
- package/dist/gtkx/bridge/measure.js.map +1 -0
- package/dist/gtkx/bridge/theme.d.ts +4 -0
- package/dist/gtkx/bridge/theme.js +5 -0
- package/dist/gtkx/bridge/theme.js.map +1 -0
- package/dist/gtkx/bridge/view-box.d.ts +7 -0
- package/dist/gtkx/bridge/view-box.js +40 -0
- package/dist/gtkx/bridge/view-box.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/apply-style.d.ts +4 -0
- package/dist/layout/apply-style.js +148 -0
- package/dist/layout/apply-style.js.map +1 -0
- package/dist/layout/engine.d.ts +22 -0
- package/dist/layout/engine.js +90 -0
- package/dist/layout/engine.js.map +1 -0
- package/dist/layout/index.d.ts +3 -0
- package/dist/layout/index.js +4 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/layout/node.d.ts +33 -0
- package/dist/layout/node.js +151 -0
- package/dist/layout/node.js.map +1 -0
- package/dist/layout/yoga.d.ts +13 -0
- package/dist/layout/yoga.js +52 -0
- package/dist/layout/yoga.js.map +1 -0
- package/dist/metro/index.d.ts +42 -0
- package/dist/metro/index.js +119 -0
- package/dist/metro/index.js.map +1 -0
- package/dist/runner/host-dev.d.ts +1 -0
- package/dist/runner/host-dev.js +208 -0
- package/dist/runner/host-dev.js.map +1 -0
- package/dist/runner/host.d.ts +1 -0
- package/dist/runner/host.js +101 -0
- package/dist/runner/host.js.map +1 -0
- package/dist/runner/index.d.ts +26 -0
- package/dist/runner/index.js +179 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/style/colors.d.ts +17 -0
- package/dist/style/colors.js +375 -0
- package/dist/style/colors.js.map +1 -0
- package/dist/style/dev-warning.d.ts +2 -0
- package/dist/style/dev-warning.js +18 -0
- package/dist/style/dev-warning.js.map +1 -0
- package/dist/style/index.d.ts +7 -0
- package/dist/style/index.js +14 -0
- package/dist/style/index.js.map +1 -0
- package/dist/style/registry.d.ts +12 -0
- package/dist/style/registry.gtkx.d.ts +2 -0
- package/dist/style/registry.gtkx.js +9 -0
- package/dist/style/registry.gtkx.js.map +1 -0
- package/dist/style/registry.js +23 -0
- package/dist/style/registry.js.map +1 -0
- package/dist/style/split-style.d.ts +6 -0
- package/dist/style/split-style.js +107 -0
- package/dist/style/split-style.js.map +1 -0
- package/dist/style/style-sheet.d.ts +43 -0
- package/dist/style/style-sheet.js +57 -0
- package/dist/style/style-sheet.js.map +1 -0
- package/dist/style/text-align.d.ts +7 -0
- package/dist/style/text-align.js +22 -0
- package/dist/style/text-align.js.map +1 -0
- package/dist/style/visual-css.d.ts +6 -0
- package/dist/style/visual-css.js +133 -0
- package/dist/style/visual-css.js.map +1 -0
- package/dist/vite/index.d.ts +53 -0
- package/dist/vite/index.js +127 -0
- package/dist/vite/index.js.map +1 -0
- package/package.json +88 -0
- package/react-native.config.js +21 -0
- package/types.d.ts +43 -0
- package/types.js +4 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.gtkx.js","sourceRoot":"","sources":["../../src/apis/host.gtkx.ts"],"names":[],"mappings":"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","sourcesContent":["// Production host adapter: the ONLY module under src/apis/ allowed to import\n// the gtkx bridge. Everything GTK-specific lives here; the API modules stay\n// pure and receive this object (or a mock in unit tests) via injection.\n\nimport type { SubscriptionHandle } from \"../contracts\"\nimport {\n Adw,\n colorScheme,\n Gdk,\n Gio,\n Gtk,\n styleManager,\n toNumber,\n} from \"../gtkx/bridge/index\"\nimport type {\n ColorSchemeName,\n Host,\n HostAlertRequest,\n ScaledSize,\n} from \"./host\"\n\nconst FALLBACK_METRICS: ScaledSize = {\n width: 0,\n height: 0,\n scale: 1,\n fontScale: 1,\n}\n\nconst getApplication = (): Gtk.Application | null =>\n Gio.Application.getDefault() as unknown as Gtk.Application | null\n\nconst getActiveAppWindow = (): Gtk.Window | null => {\n const app = getApplication()\n if (!app || typeof app.getActiveWindow !== \"function\") {\n return null\n }\n return app.getActiveWindow() ?? null\n}\n\nconst windowAt = (model: Gio.ListModel, index: number): Gtk.Window | null =>\n model.getItem(index) as unknown as Gtk.Window | null\n\n// The application's active window if any, otherwise the first toplevel. The\n// toplevel fallback covers the test harness, where windows exist without a\n// GtkApplication (`Gio.Application.getDefault()` is null there).\n// RN's Dimensions(\"window\") means the MAIN window: transient toplevels\n// (Modal → modal GtkWindow, dialogs) must never be resolved as \"the window\" —\n// an open modal becomes the active window and would shrink the app viewport\n// to the modal size.\nconst isMainWindow = (window: Gtk.Window): boolean =>\n window.getTransientFor() === null\n\nconst resolveWindow = (): Gtk.Window | null => {\n const active = getActiveAppWindow()\n if (active && isMainWindow(active)) {\n return active\n }\n const toplevels = Gtk.Window.getToplevels()\n const count = toNumber(toplevels.getNItems())\n let first: Gtk.Window | null = null\n for (let index = 0; index < count; index += 1) {\n const window = windowAt(toplevels, index)\n if (!window || !isMainWindow(window)) {\n continue\n }\n if (window.isActive()) {\n return window\n }\n first = first ?? window\n }\n return first\n}\n\nconst isAnyWindowActive = (): boolean => {\n const toplevels = Gtk.Window.getToplevels()\n const count = toNumber(toplevels.getNItems())\n for (let index = 0; index < count; index += 1) {\n if (windowAt(toplevels, index)?.isActive()) {\n return true\n }\n }\n return false\n}\n\nconst windowMetrics = (): ScaledSize => {\n const window = resolveWindow()\n if (!window) {\n return FALLBACK_METRICS\n }\n // RN's Dimensions(\"window\") is the app viewport: the window CHILD's\n // allocation (the content area under the headerbar), not the window widget\n // size. Falls back to the window size before the first allocation.\n const child = window.getChild()\n const childAllocation = child?.getAllocation()\n const allocatedWidth =\n childAllocation && childAllocation.width > 0\n ? toNumber(childAllocation.width)\n : toNumber(window.getWidth())\n const allocatedHeight =\n childAllocation && childAllocation.height > 0\n ? toNumber(childAllocation.height)\n : toNumber(window.getHeight())\n // Before the first allocation everything reports 0 — fall back to\n // the requested default size (which GTK4 also keeps updated on resize).\n const width =\n allocatedWidth > 0\n ? allocatedWidth\n : Math.max(toNumber(window.defaultWidth ?? 0), 0)\n const height =\n allocatedHeight > 0\n ? allocatedHeight\n : Math.max(toNumber(window.defaultHeight ?? 0), 0)\n return {\n width,\n height,\n scale: toNumber(window.getScaleFactor()),\n fontScale: 1,\n }\n}\n\nconst screenMetrics = (): ScaledSize => {\n const display = Gdk.Display.getDefault()\n if (!display) {\n return windowMetrics()\n }\n const monitors = display.getMonitors()\n if (toNumber(monitors.getNItems()) === 0) {\n return windowMetrics()\n }\n const monitor = monitors.getItem(0) as unknown as Gdk.Monitor | null\n if (!monitor) {\n return windowMetrics()\n }\n const geometry = monitor.getGeometry()\n return {\n width: toNumber(geometry.width),\n height: toNumber(geometry.height),\n scale: toNumber(monitor.getScaleFactor()),\n fontScale: 1,\n }\n}\n\n// GtkNative.getSurface is an interface method merged onto Gtk.Window at\n// runtime via mixins; accessed defensively to stay typecheckable either way.\nconst surfaceOf = (window: Gtk.Window): Gdk.Surface | null => {\n const native = window as unknown as { getSurface?: () => Gdk.Surface | null }\n return typeof native.getSurface === \"function\"\n ? (native.getSurface() ?? null)\n : null\n}\n\n// Tracks the \"current\" window across creation/destruction/focus moves:\n// listens on the given signals of the resolved window (and, when requested,\n// its GdkSurface) plus the toplevel list model, re-resolving and re-attaching\n// whenever the tracked window may have changed. Modules dedupe, so\n// over-notifying is fine.\n//\n// Why the surface: notify::default-width fires when setDefaultSize() is\n// called, i.e. before the compositor actually resizes the surface — the\n// allocated size (what Dimensions reports) only changes when the surface\n// does. And GdkSurface notify::width/height fires at configure time, still\n// before the widget allocation pass, so the \"layout\" signal is also needed:\n// it is emitted during the frame's layout phase and — because GTK's own\n// relayout handler is connected first — our handler observes the updated\n// allocation. The module dedupes, so early/no-op emissions cost nothing.\nconst watchWindow = (\n windowSignals: readonly string[],\n surfaceSignals: readonly string[],\n notify: () => void,\n): SubscriptionHandle => {\n let window: Gtk.Window | null = null\n let surface: Gdk.Surface | null = null\n\n const attachWindow = (): void => {\n if (!window) {\n return\n }\n for (const signal of windowSignals) {\n window.on(signal, onSignal)\n }\n }\n\n const detachWindow = (): void => {\n if (!window) {\n return\n }\n for (const signal of windowSignals) {\n window.off(signal, onSignal)\n }\n }\n\n const attachSurface = (): void => {\n if (!surface) {\n return\n }\n for (const signal of surfaceSignals) {\n surface.on(signal, onSignal)\n }\n }\n\n const detachSurface = (): void => {\n if (!surface) {\n return\n }\n for (const signal of surfaceSignals) {\n surface.off(signal, onSignal)\n }\n }\n\n const syncTargets = (): void => {\n const nextWindow = resolveWindow()\n if (nextWindow !== window) {\n detachWindow()\n window = nextWindow\n attachWindow()\n }\n const nextSurface =\n window && surfaceSignals.length > 0 ? surfaceOf(window) : null\n if (nextSurface !== surface) {\n detachSurface()\n surface = nextSurface\n attachSurface()\n }\n }\n\n const onSignal = (): void => {\n syncTargets()\n notify()\n }\n\n const toplevels = Gtk.Window.getToplevels()\n const onToplevelsChanged = (): void => {\n syncTargets()\n notify()\n }\n toplevels.on(\"items-changed\", onToplevelsChanged)\n syncTargets()\n\n return {\n remove: () => {\n detachWindow()\n detachSurface()\n window = null\n surface = null\n toplevels.off(\"items-changed\", onToplevelsChanged)\n },\n }\n}\n\n// realize/map re-run target resolution so the surface listeners attach as\n// soon as the surface exists.\nconst WINDOW_SIZE_SIGNALS = [\n \"notify::default-width\",\n \"notify::default-height\",\n \"realize\",\n \"map\",\n] as const\n\nconst SURFACE_SIZE_SIGNALS = [\n \"notify::width\",\n \"notify::height\",\n \"layout\",\n] as const\n\nconst WINDOW_ACTIVE_SIGNALS = [\"notify::is-active\"] as const\n\nconst gtkVersion = (): string =>\n `${toNumber(Gtk.getMajorVersion())}.${toNumber(Gtk.getMinorVersion())}.${toNumber(Gtk.getMicroVersion())}`\n\nconst setColorScheme = (scheme: ColorSchemeName | null): void => {\n const manager = styleManager()\n if (scheme === \"dark\") {\n manager.setColorScheme(Adw.ColorScheme.FORCE_DARK)\n } else if (scheme === \"light\") {\n manager.setColorScheme(Adw.ColorScheme.FORCE_LIGHT)\n } else {\n manager.setColorScheme(Adw.ColorScheme.DEFAULT)\n }\n // Our apps are GtkApplication (not AdwApplication), so Adwaita may not\n // restyle widgets: duplicate the request through the classic GTK setting,\n // which the theme always honors.\n const settings = Gtk.Settings.getDefault()\n if (settings) {\n if (scheme === null) {\n settings.resetProperty(\"gtk-application-prefer-dark-theme\")\n } else {\n settings.gtkApplicationPreferDarkTheme = scheme === \"dark\"\n }\n }\n}\n\nconst onColorSchemeChange = (notify: () => void): SubscriptionHandle => {\n const manager = styleManager()\n const listener = (): void => notify()\n manager.on(\"notify::dark\", listener)\n return { remove: () => manager.off(\"notify::dark\", listener) }\n}\n\nconst showAlert = async (request: HostAlertRequest): Promise<string | null> => {\n const dialog = new Adw.AlertDialog()\n dialog.setHeading(request.title)\n if (request.message !== undefined && request.message.length > 0) {\n dialog.setBody(request.message)\n }\n let closeResponse: string | null = null\n for (const button of request.buttons) {\n dialog.addResponse(button.id, button.label)\n if (button.style === \"destructive\") {\n dialog.setResponseAppearance(\n button.id,\n Adw.ResponseAppearance.DESTRUCTIVE,\n )\n }\n if (button.isPreferred) {\n dialog.setResponseAppearance(button.id, Adw.ResponseAppearance.SUGGESTED)\n dialog.setDefaultResponse(button.id)\n }\n if (button.style === \"cancel\") {\n closeResponse = button.id\n }\n }\n if (closeResponse !== null) {\n // Esc / close maps onto the cancel button, like RN's cancel semantics.\n dialog.setCloseResponse(closeResponse)\n } else if (!request.cancelable) {\n // No cancel button and not cancelable: block Esc-dismissal. Responses\n // still close the dialog (they bypass the can-close guard).\n dialog.setCanClose(false)\n }\n const response = await dialog.choose(resolveWindow())\n // Anything that is not one of our buttons (e.g. the built-in \"close\"\n // response) is a dismissal.\n return request.buttons.some((button) => button.id === response)\n ? response\n : null\n}\n\nconst launchUri = async (uri: string): Promise<void> => {\n const launcher = new Gtk.UriLauncher({ uri })\n // Promisified by the gi codegen; rejects with the GError on failure.\n await launcher.launch(resolveWindow())\n}\n\nexport const gtkxHost: Host = {\n gtkVersion,\n getWindowMetrics: windowMetrics,\n getScreenMetrics: screenMetrics,\n onMetricsChange: (notify) =>\n watchWindow(WINDOW_SIZE_SIGNALS, SURFACE_SIZE_SIGNALS, notify),\n getColorScheme: () => colorScheme(),\n setColorScheme,\n onColorSchemeChange,\n isActive: isAnyWindowActive,\n onActiveChange: (notify) => watchWindow(WINDOW_ACTIVE_SIGNALS, [], notify),\n showAlert,\n launchUri,\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Narrow host interfaces backing the react-native compatible API modules.
|
|
2
|
+
// The pure modules in this directory receive these capabilities via injection:
|
|
3
|
+
// production wiring passes the gtkx adapter (host.gtkx.ts), unit tests pass
|
|
4
|
+
// in-memory mocks, so all module logic runs without GTK.
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/apis/host.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,+EAA+E;AAC/E,4EAA4E;AAC5E,yDAAyD","sourcesContent":["// Narrow host interfaces backing the react-native compatible API modules.\n// The pure modules in this directory receive these capabilities via injection:\n// production wiring passes the gtkx adapter (host.gtkx.ts), unit tests pass\n// in-memory mocks, so all module logic runs without GTK.\n\nimport type { SubscriptionHandle } from \"../contracts\"\n\nexport type ColorSchemeName = \"light\" | \"dark\"\n\n// Matches react-native's ScaledSize (Dimensions.get / useWindowDimensions).\nexport type ScaledSize = {\n width: number\n height: number\n scale: number\n fontScale: number\n}\n\nexport type AlertButtonStyle = \"default\" | \"cancel\" | \"destructive\"\n\nexport type HostAlertButton = {\n id: string\n label: string\n style: AlertButtonStyle\n isPreferred: boolean\n}\n\nexport type HostAlertRequest = {\n title: string\n message?: string\n buttons: HostAlertButton[]\n cancelable: boolean\n}\n\nexport interface PlatformHost {\n // Runtime GTK version, e.g. \"4.22.4\".\n gtkVersion(): string\n}\n\nexport interface DimensionsHost {\n getWindowMetrics(): ScaledSize\n getScreenMetrics(): ScaledSize\n // Fires whenever the window geometry (or the tracked window itself) may\n // have changed; the module re-reads metrics and dedupes.\n onMetricsChange(notify: () => void): SubscriptionHandle\n}\n\nexport interface AppearanceHost {\n getColorScheme(): ColorSchemeName\n // null resets to the system preference.\n setColorScheme(scheme: ColorSchemeName | null): void\n onColorSchemeChange(notify: () => void): SubscriptionHandle\n}\n\nexport interface AppStateHost {\n isActive(): boolean\n onActiveChange(notify: () => void): SubscriptionHandle\n}\n\nexport interface AlertHost {\n // Resolves with the id of the pressed button, or null when the dialog was\n // dismissed without pressing any of the requested buttons.\n showAlert(request: HostAlertRequest): Promise<string | null>\n}\n\nexport interface LinkingHost {\n launchUri(uri: string): Promise<void>\n}\n\nexport type Host = PlatformHost &\n DimensionsHost &\n AppearanceHost &\n AppStateHost &\n AlertHost &\n LinkingHost\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const Platform: {
|
|
2
|
+
OS: "linux";
|
|
3
|
+
isTV: false;
|
|
4
|
+
isTesting: boolean;
|
|
5
|
+
readonly Version: string;
|
|
6
|
+
select<T>(spec: import("./platform").PlatformSelectSpec<T>): T | undefined;
|
|
7
|
+
};
|
|
8
|
+
export declare const Dimensions: {
|
|
9
|
+
get: (key: import("./dimensions").DimensionKey) => import("./host").ScaledSize;
|
|
10
|
+
set: (dimensions: Partial<Record<import("./dimensions").DimensionKey, Partial<import("./host").ScaledSize>>>) => void;
|
|
11
|
+
addEventListener: (type: "change", handler: import("./dimensions").DimensionsChangeHandler) => import("../contracts").SubscriptionHandle;
|
|
12
|
+
};
|
|
13
|
+
export declare const Appearance: {
|
|
14
|
+
getColorScheme: () => import("./host").ColorSchemeName;
|
|
15
|
+
setColorScheme: (scheme: import("./host").ColorSchemeName | null | undefined) => void;
|
|
16
|
+
addChangeListener: (handler: import("./appearance").AppearanceChangeHandler) => import("../contracts").SubscriptionHandle;
|
|
17
|
+
};
|
|
18
|
+
export declare const AppState: {
|
|
19
|
+
isAvailable: true;
|
|
20
|
+
readonly currentState: import("./app-state").AppStateStatus;
|
|
21
|
+
addEventListener: (type: import("./app-state").AppStateEvent, handler: import("./app-state").AppStateHandler) => import("../contracts").SubscriptionHandle;
|
|
22
|
+
};
|
|
23
|
+
export declare const Alert: {
|
|
24
|
+
alert: (title: string, message?: string, buttons?: import("./alert").AlertButton[], options?: import("./alert").AlertOptions) => void;
|
|
25
|
+
};
|
|
26
|
+
export declare const Linking: {
|
|
27
|
+
openURL: (url: string) => Promise<void>;
|
|
28
|
+
canOpenURL: (url: string) => Promise<boolean>;
|
|
29
|
+
getInitialURL: () => Promise<string | null>;
|
|
30
|
+
};
|
|
31
|
+
export { DevSettings } from "./dev-settings";
|
|
32
|
+
export declare const useWindowDimensions: () => import("./host").ScaledSize;
|
|
33
|
+
export declare const useColorScheme: () => import("./host").ColorSchemeName;
|
|
34
|
+
export type { AlertButton, AlertOptions } from "./alert";
|
|
35
|
+
export type { AppStateEvent, AppStateStatus } from "./app-state";
|
|
36
|
+
export type { AppearancePreferences } from "./appearance";
|
|
37
|
+
export type { DimensionKey, DimensionsPayload } from "./dimensions";
|
|
38
|
+
export type { AlertButtonStyle, ColorSchemeName, ScaledSize } from "./host";
|
|
39
|
+
export type { PlatformSelectSpec } from "./platform";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Production wiring: singleton API modules bound to the gtkx host, exported
|
|
2
|
+
// under their react-native names. Unit tests use the create* factories with a
|
|
3
|
+
// mock host instead of importing this file (it pulls in the gtkx bridge).
|
|
4
|
+
import { createAlert } from "./alert";
|
|
5
|
+
import { createAppState } from "./app-state";
|
|
6
|
+
import { createAppearance } from "./appearance";
|
|
7
|
+
import { createDimensions } from "./dimensions";
|
|
8
|
+
import { createUseColorScheme, createUseWindowDimensions } from "./hooks";
|
|
9
|
+
import { gtkxHost } from "./host.gtkx";
|
|
10
|
+
import { createLinking } from "./linking";
|
|
11
|
+
import { createPlatform } from "./platform";
|
|
12
|
+
export const Platform = createPlatform(gtkxHost);
|
|
13
|
+
export const Dimensions = createDimensions(gtkxHost);
|
|
14
|
+
export const Appearance = createAppearance(gtkxHost);
|
|
15
|
+
export const AppState = createAppState(gtkxHost);
|
|
16
|
+
export const Alert = createAlert(gtkxHost);
|
|
17
|
+
export const Linking = createLinking(gtkxHost);
|
|
18
|
+
export { DevSettings } from "./dev-settings";
|
|
19
|
+
export const useWindowDimensions = createUseWindowDimensions(Dimensions);
|
|
20
|
+
export const useColorScheme = createUseColorScheme(Appearance);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/apis/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,8EAA8E;AAC9E,0EAA0E;AAE1E,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE3C,MAAM,CAAC,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;AAChD,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAA;AACpD,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAA;AACpD,MAAM,CAAC,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;AAChD,MAAM,CAAC,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;AAC1C,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE5C,MAAM,CAAC,MAAM,mBAAmB,GAAG,yBAAyB,CAAC,UAAU,CAAC,CAAA;AACxE,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAA","sourcesContent":["// Production wiring: singleton API modules bound to the gtkx host, exported\n// under their react-native names. Unit tests use the create* factories with a\n// mock host instead of importing this file (it pulls in the gtkx bridge).\n\nimport { createAlert } from \"./alert\"\nimport { createAppState } from \"./app-state\"\nimport { createAppearance } from \"./appearance\"\nimport { createDimensions } from \"./dimensions\"\nimport { createUseColorScheme, createUseWindowDimensions } from \"./hooks\"\nimport { gtkxHost } from \"./host.gtkx\"\nimport { createLinking } from \"./linking\"\nimport { createPlatform } from \"./platform\"\n\nexport const Platform = createPlatform(gtkxHost)\nexport const Dimensions = createDimensions(gtkxHost)\nexport const Appearance = createAppearance(gtkxHost)\nexport const AppState = createAppState(gtkxHost)\nexport const Alert = createAlert(gtkxHost)\nexport const Linking = createLinking(gtkxHost)\nexport { DevSettings } from \"./dev-settings\"\n\nexport const useWindowDimensions = createUseWindowDimensions(Dimensions)\nexport const useColorScheme = createUseColorScheme(Appearance)\n\nexport type { AlertButton, AlertOptions } from \"./alert\"\nexport type { AppStateEvent, AppStateStatus } from \"./app-state\"\nexport type { AppearancePreferences } from \"./appearance\"\nexport type { DimensionKey, DimensionsPayload } from \"./dimensions\"\nexport type { AlertButtonStyle, ColorSchemeName, ScaledSize } from \"./host\"\nexport type { PlatformSelectSpec } from \"./platform\"\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LinkingHost } from "./host";
|
|
2
|
+
export declare const createLinking: (host: LinkingHost) => {
|
|
3
|
+
openURL: (url: string) => Promise<void>;
|
|
4
|
+
canOpenURL: (url: string) => Promise<boolean>;
|
|
5
|
+
getInitialURL: () => Promise<string | null>;
|
|
6
|
+
};
|
|
7
|
+
export type LinkingModule = ReturnType<typeof createLinking>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Schemes every Linux desktop resolves through the portal / default handlers.
|
|
2
|
+
// There is no per-handler introspection API comparable to canOpenURL on
|
|
3
|
+
// mobile, so the answer is static per scheme.
|
|
4
|
+
const SUPPORTED_SCHEMES = new Set(["http", "https", "mailto", "file"]);
|
|
5
|
+
const schemeOf = (url) => {
|
|
6
|
+
const match = /^([a-z][a-z0-9+.-]*):/i.exec(url);
|
|
7
|
+
const scheme = match?.[1];
|
|
8
|
+
return scheme === undefined ? null : scheme.toLowerCase();
|
|
9
|
+
};
|
|
10
|
+
export const createLinking = (host) => ({
|
|
11
|
+
// Opens the URL in the user's default handler (Gtk.UriLauncher → portal).
|
|
12
|
+
openURL: (url) => {
|
|
13
|
+
if (typeof url !== "string" || url.length === 0) {
|
|
14
|
+
return Promise.reject(new Error("Linking.openURL: url must be a non-empty string"));
|
|
15
|
+
}
|
|
16
|
+
return host.launchUri(url);
|
|
17
|
+
},
|
|
18
|
+
canOpenURL: (url) => {
|
|
19
|
+
if (typeof url !== "string") {
|
|
20
|
+
return Promise.reject(new Error("Linking.canOpenURL: url must be a string"));
|
|
21
|
+
}
|
|
22
|
+
const scheme = schemeOf(url);
|
|
23
|
+
return Promise.resolve(scheme !== null && SUPPORTED_SCHEMES.has(scheme));
|
|
24
|
+
},
|
|
25
|
+
// Desktop apps are not launched through deep links: always null.
|
|
26
|
+
getInitialURL: () => Promise.resolve(null),
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=linking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linking.js","sourceRoot":"","sources":["../../src/apis/linking.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,wEAAwE;AACxE,8CAA8C;AAC9C,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;AAEtE,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAiB,EAAE;IAC9C,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAChD,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAA;IACzB,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAA;AAC3D,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAiB,EAAE,EAAE,CAAC,CAAC;IACnD,0EAA0E;IAC1E,OAAO,EAAE,CAAC,GAAW,EAAiB,EAAE;QACtC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAC7D,CAAA;QACH,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IACD,UAAU,EAAE,CAAC,GAAW,EAAoB,EAAE;QAC5C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CAAC,0CAA0C,CAAC,CACtD,CAAA;QACH,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAA;QAC5B,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI,IAAI,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IAC1E,CAAC;IACD,iEAAiE;IACjE,aAAa,EAAE,GAA2B,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;CACnE,CAAC,CAAA","sourcesContent":["import type { LinkingHost } from \"./host\"\n\n// Schemes every Linux desktop resolves through the portal / default handlers.\n// There is no per-handler introspection API comparable to canOpenURL on\n// mobile, so the answer is static per scheme.\nconst SUPPORTED_SCHEMES = new Set([\"http\", \"https\", \"mailto\", \"file\"])\n\nconst schemeOf = (url: string): string | null => {\n const match = /^([a-z][a-z0-9+.-]*):/i.exec(url)\n const scheme = match?.[1]\n return scheme === undefined ? null : scheme.toLowerCase()\n}\n\nexport const createLinking = (host: LinkingHost) => ({\n // Opens the URL in the user's default handler (Gtk.UriLauncher → portal).\n openURL: (url: string): Promise<void> => {\n if (typeof url !== \"string\" || url.length === 0) {\n return Promise.reject(\n new Error(\"Linking.openURL: url must be a non-empty string\"),\n )\n }\n return host.launchUri(url)\n },\n canOpenURL: (url: string): Promise<boolean> => {\n if (typeof url !== \"string\") {\n return Promise.reject(\n new Error(\"Linking.canOpenURL: url must be a string\"),\n )\n }\n const scheme = schemeOf(url)\n return Promise.resolve(scheme !== null && SUPPORTED_SCHEMES.has(scheme))\n },\n // Desktop apps are not launched through deep links: always null.\n getInitialURL: (): Promise<string | null> => Promise.resolve(null),\n})\n\nexport type LinkingModule = ReturnType<typeof createLinking>\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PlatformHost } from "./host";
|
|
2
|
+
export type PlatformSelectSpec<T> = {
|
|
3
|
+
linux?: T;
|
|
4
|
+
native?: T;
|
|
5
|
+
default?: T;
|
|
6
|
+
} & Record<string, T | undefined>;
|
|
7
|
+
export declare const createPlatform: (host: PlatformHost) => {
|
|
8
|
+
OS: "linux";
|
|
9
|
+
isTV: false;
|
|
10
|
+
isTesting: boolean;
|
|
11
|
+
readonly Version: string;
|
|
12
|
+
select<T>(spec: PlatformSelectSpec<T>): T | undefined;
|
|
13
|
+
};
|
|
14
|
+
export type PlatformModule = ReturnType<typeof createPlatform>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const detectTesting = () => process.env.NODE_ENV === "test" || process.env.VITEST !== undefined;
|
|
2
|
+
export const createPlatform = (host) => ({
|
|
3
|
+
OS: "linux",
|
|
4
|
+
isTV: false,
|
|
5
|
+
isTesting: detectTesting(),
|
|
6
|
+
// GTK runtime version, e.g. "4.22.4". Lazy getter: GTK may not be
|
|
7
|
+
// initialized yet when the module graph is imported.
|
|
8
|
+
get Version() {
|
|
9
|
+
return host.gtkVersion();
|
|
10
|
+
},
|
|
11
|
+
// Same key-presence semantics as react-native: an explicit `linux:
|
|
12
|
+
// undefined` wins over `default` (checked with `in`, not truthiness).
|
|
13
|
+
select(spec) {
|
|
14
|
+
if ("linux" in spec) {
|
|
15
|
+
return spec.linux;
|
|
16
|
+
}
|
|
17
|
+
if ("native" in spec) {
|
|
18
|
+
return spec.native;
|
|
19
|
+
}
|
|
20
|
+
return spec.default;
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=platform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/apis/platform.ts"],"names":[],"mappings":"AAUA,MAAM,aAAa,GAAG,GAAY,EAAE,CAClC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAA;AAErE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAkB,EAAE,EAAE,CAAC,CAAC;IACrD,EAAE,EAAE,OAAgB;IACpB,IAAI,EAAE,KAAc;IACpB,SAAS,EAAE,aAAa,EAAE;IAC1B,kEAAkE;IAClE,qDAAqD;IACrD,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,UAAU,EAAE,CAAA;IAC1B,CAAC;IACD,mEAAmE;IACnE,sEAAsE;IACtE,MAAM,CAAI,IAA2B;QACnC,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,KAAK,CAAA;QACnB,CAAC;QACD,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC,MAAM,CAAA;QACpB,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;CACF,CAAC,CAAA","sourcesContent":["import type { PlatformHost } from \"./host\"\n\n// Cross-platform code may pass ios/android/... keys too; they are ignored on\n// linux, mirroring react-native's Platform.select fallback contract.\nexport type PlatformSelectSpec<T> = {\n linux?: T\n native?: T\n default?: T\n} & Record<string, T | undefined>\n\nconst detectTesting = (): boolean =>\n process.env.NODE_ENV === \"test\" || process.env.VITEST !== undefined\n\nexport const createPlatform = (host: PlatformHost) => ({\n OS: \"linux\" as const,\n isTV: false as const,\n isTesting: detectTesting(),\n // GTK runtime version, e.g. \"4.22.4\". Lazy getter: GTK may not be\n // initialized yet when the module graph is imported.\n get Version(): string {\n return host.gtkVersion()\n },\n // Same key-presence semantics as react-native: an explicit `linux:\n // undefined` wins over `default` (checked with `in`, not truthiness).\n select<T>(spec: PlatformSelectSpec<T>): T | undefined {\n if (\"linux\" in spec) {\n return spec.linux\n }\n if (\"native\" in spec) {\n return spec.native\n }\n return spec.default\n },\n})\n\nexport type PlatformModule = ReturnType<typeof createPlatform>\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { StyleProp } from "../contracts";
|
|
2
|
+
import { type LayoutEvent } from "./use-layout-child";
|
|
3
|
+
export type ActivityIndicatorProps = {
|
|
4
|
+
animating?: boolean;
|
|
5
|
+
size?: "small" | "large" | number;
|
|
6
|
+
style?: StyleProp;
|
|
7
|
+
onLayout?: (event: LayoutEvent) => void;
|
|
8
|
+
testID?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const ActivityIndicator: ({ animating, size, style, onLayout, testID, }: ActivityIndicatorProps) => React.JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
import { GtkSpinner } from "../gtkx/bridge/index";
|
|
4
|
+
import { useLayoutChild } from "./use-layout-child";
|
|
5
|
+
const sizeToPixels = (size) => {
|
|
6
|
+
if (typeof size === "number") {
|
|
7
|
+
return size;
|
|
8
|
+
}
|
|
9
|
+
return size === "large" ? 36 : 20;
|
|
10
|
+
};
|
|
11
|
+
export const ActivityIndicator = ({ animating = true, size = "small", style, onLayout, testID, }) => {
|
|
12
|
+
const widgetRef = useRef(null);
|
|
13
|
+
const pixels = sizeToPixels(size);
|
|
14
|
+
useLayoutChild(widgetRef, {
|
|
15
|
+
style,
|
|
16
|
+
onLayout,
|
|
17
|
+
extraLayout: { width: pixels, height: pixels },
|
|
18
|
+
});
|
|
19
|
+
return (_jsx(GtkSpinner, { ref: widgetRef, name: testID, spinning: animating }));
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=activity-indicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity-indicator.js","sourceRoot":"","sources":["../../src/components/activity-indicator.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,UAAU,EAAY,MAAM,sBAAsB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAoB,MAAM,oBAAoB,CAAA;AAUrE,MAAM,YAAY,GAAG,CAAC,IAAoC,EAAU,EAAE;IACpE,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;AACnC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAChC,SAAS,GAAG,IAAI,EAChB,IAAI,GAAG,OAAO,EACd,KAAK,EACL,QAAQ,EACR,MAAM,GACiB,EAAE,EAAE;IAC3B,MAAM,SAAS,GAAG,MAAM,CAAqB,IAAI,CAAC,CAAA;IAClD,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IAEjC,cAAc,CAAC,SAAS,EAAE;QACxB,KAAK;QACL,QAAQ;QACR,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;KAC/C,CAAC,CAAA;IAEF,OAAO,CACL,KAAC,UAAU,IACT,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,SAAS,GACnB,CACH,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { useRef } from \"react\"\nimport type { StyleProp } from \"../contracts\"\nimport { GtkSpinner, type Gtk } from \"../gtkx/bridge/index\"\nimport { useLayoutChild, type LayoutEvent } from \"./use-layout-child\"\n\nexport type ActivityIndicatorProps = {\n animating?: boolean\n size?: \"small\" | \"large\" | number\n style?: StyleProp\n onLayout?: (event: LayoutEvent) => void\n testID?: string\n}\n\nconst sizeToPixels = (size: ActivityIndicatorProps[\"size\"]): number => {\n if (typeof size === \"number\") {\n return size\n }\n return size === \"large\" ? 36 : 20\n}\n\nexport const ActivityIndicator = ({\n animating = true,\n size = \"small\",\n style,\n onLayout,\n testID,\n}: ActivityIndicatorProps) => {\n const widgetRef = useRef<Gtk.Spinner | null>(null)\n const pixels = sizeToPixels(size)\n\n useLayoutChild(widgetRef, {\n style,\n onLayout,\n extraLayout: { width: pixels, height: pixels },\n })\n\n return (\n <GtkSpinner\n ref={widgetRef}\n name={testID}\n spinning={animating}\n />\n )\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { FlatStyle, TransformPart } from "../contracts";
|
|
3
|
+
import { type LayoutEvent } from "./use-layout-child";
|
|
4
|
+
type AnimatedNode = {
|
|
5
|
+
addListener(callback: (state: {
|
|
6
|
+
value: number;
|
|
7
|
+
}) => void): string;
|
|
8
|
+
removeListener(id: string): void;
|
|
9
|
+
__getValue(): number;
|
|
10
|
+
};
|
|
11
|
+
type AnimatedTransformPart = {
|
|
12
|
+
[key: string]: number | string | AnimatedNode;
|
|
13
|
+
};
|
|
14
|
+
export type AnimatedViewStyle = Omit<FlatStyle, "opacity" | "transform"> & {
|
|
15
|
+
opacity?: number | AnimatedNode;
|
|
16
|
+
transform?: (TransformPart | AnimatedTransformPart)[];
|
|
17
|
+
};
|
|
18
|
+
export type AnimatedViewProps = {
|
|
19
|
+
style?: AnimatedViewStyle | AnimatedViewStyle[];
|
|
20
|
+
children?: ReactNode;
|
|
21
|
+
onLayout?: (event: LayoutEvent) => void;
|
|
22
|
+
testID?: string;
|
|
23
|
+
};
|
|
24
|
+
export declare const Animated: {
|
|
25
|
+
View: ({ style, children, onLayout, testID, }: AnimatedViewProps) => React.JSX.Element;
|
|
26
|
+
Value: typeof import("../animated/value").AnimatedValue;
|
|
27
|
+
timing(value: import("../animated/value").AnimatedValue, config: import("../animated/types").TimingConfig): import("../animated/types").CompositeAnimation;
|
|
28
|
+
spring(value: import("../animated/value").AnimatedValue, config: import("../animated/types").SpringConfig): import("../animated/types").CompositeAnimation;
|
|
29
|
+
sequence(animations: import("../animated/types").CompositeAnimation[]): import("../animated/types").CompositeAnimation;
|
|
30
|
+
parallel(animations: import("../animated/types").CompositeAnimation[], config?: import("../animated/types").ParallelConfig): import("../animated/types").CompositeAnimation;
|
|
31
|
+
delay(ms: number): import("../animated/types").CompositeAnimation;
|
|
32
|
+
loop(animation: import("../animated/types").CompositeAnimation, config?: import("../animated/types").LoopConfig): import("../animated/types").CompositeAnimation;
|
|
33
|
+
};
|
|
34
|
+
export { Easing } from "../animated/index";
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useLayoutEffect, useRef } from "react";
|
|
3
|
+
import { createAnimated } from "../animated/index";
|
|
4
|
+
import { GLib, GtkBox, queueAllocate } from "../gtkx/bridge/index";
|
|
5
|
+
import { HostNodeContext } from "./host-node";
|
|
6
|
+
import { setStoredOffset } from "./rect-store";
|
|
7
|
+
import { useLayoutChild, useRnContainer, } from "./use-layout-child";
|
|
8
|
+
// ~60fps one-shot ticks off the GLib main loop. A frame-clock driver (per
|
|
9
|
+
// window) is a later optimization; timeouts keep the driver widget-free.
|
|
10
|
+
const glibScheduler = {
|
|
11
|
+
schedule(callback) {
|
|
12
|
+
let cancelled = false;
|
|
13
|
+
const id = GLib.timeoutAdd(GLib.PRIORITY_DEFAULT, 16, () => {
|
|
14
|
+
if (!cancelled) {
|
|
15
|
+
callback(Number(GLib.getMonotonicTime()) / 1000);
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
});
|
|
19
|
+
return () => {
|
|
20
|
+
if (!cancelled) {
|
|
21
|
+
cancelled = true;
|
|
22
|
+
GLib.Source.remove(id);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
const api = createAnimated(glibScheduler);
|
|
28
|
+
const isAnimatedNode = (value) => typeof value === "object" &&
|
|
29
|
+
value !== null &&
|
|
30
|
+
typeof value.addListener === "function" &&
|
|
31
|
+
typeof value.__getValue === "function";
|
|
32
|
+
const splitAnimated = (style) => {
|
|
33
|
+
const flat = {};
|
|
34
|
+
const collect = (entry) => {
|
|
35
|
+
if (!entry) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (Array.isArray(entry)) {
|
|
39
|
+
entry.forEach(collect);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
Object.assign(flat, entry);
|
|
43
|
+
};
|
|
44
|
+
collect(style);
|
|
45
|
+
let opacity = null;
|
|
46
|
+
let translateX = null;
|
|
47
|
+
let translateY = null;
|
|
48
|
+
if (isAnimatedNode(flat.opacity)) {
|
|
49
|
+
opacity = flat.opacity;
|
|
50
|
+
delete flat.opacity;
|
|
51
|
+
}
|
|
52
|
+
if (Array.isArray(flat.transform)) {
|
|
53
|
+
const staticParts = [];
|
|
54
|
+
for (const part of flat.transform) {
|
|
55
|
+
const key = Object.keys(part)[0];
|
|
56
|
+
const value = part[key];
|
|
57
|
+
if (key === "translateX" && isAnimatedNode(value)) {
|
|
58
|
+
translateX = value;
|
|
59
|
+
}
|
|
60
|
+
else if (key === "translateY" && isAnimatedNode(value)) {
|
|
61
|
+
translateY = value;
|
|
62
|
+
}
|
|
63
|
+
else if (!isAnimatedNode(value)) {
|
|
64
|
+
staticParts.push(part);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (staticParts.length > 0) {
|
|
68
|
+
flat.transform = staticParts;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
delete flat.transform;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return { staticStyle: flat, opacity, translateX, translateY };
|
|
75
|
+
};
|
|
76
|
+
// Animated values bypass React entirely: listeners write straight to the
|
|
77
|
+
// widget (opacity) and to the rect store (translate offsets applied by the
|
|
78
|
+
// parent's allocate), on top of the engine-committed base rect — the fast
|
|
79
|
+
// path measured in the spike. Animation frames never touch Yoga.
|
|
80
|
+
const AnimatedView = ({ style, children, onLayout, testID, }) => {
|
|
81
|
+
const widgetRef = useRef(null);
|
|
82
|
+
const { staticStyle, opacity, translateX, translateY } = splitAnimated(style);
|
|
83
|
+
const { host, node, cssClass } = useLayoutChild(widgetRef, {
|
|
84
|
+
style: staticStyle,
|
|
85
|
+
onLayout,
|
|
86
|
+
});
|
|
87
|
+
useRnContainer(widgetRef, node);
|
|
88
|
+
const offsets = useRef({ x: 0, y: 0 });
|
|
89
|
+
useLayoutEffect(() => {
|
|
90
|
+
// RN transform semantics: translate is paint-only. The offset goes to
|
|
91
|
+
// the rect store unclamped — the parent's measure ignores children, so an
|
|
92
|
+
// out-of-bounds child draws past the boundary over its neighbors without
|
|
93
|
+
// moving a single ancestor.
|
|
94
|
+
const applyTranslate = () => {
|
|
95
|
+
const widget = widgetRef.current;
|
|
96
|
+
const parentWidget = host.widgetRef.current;
|
|
97
|
+
if (!widget || !parentWidget) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
setStoredOffset(widget, offsets.current.x, offsets.current.y);
|
|
101
|
+
queueAllocate(parentWidget);
|
|
102
|
+
};
|
|
103
|
+
const bindings = [];
|
|
104
|
+
if (opacity) {
|
|
105
|
+
bindings.push({
|
|
106
|
+
node: opacity,
|
|
107
|
+
apply: (value) => {
|
|
108
|
+
widgetRef.current?.setOpacity(Math.min(1, Math.max(0, value)));
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (translateX) {
|
|
113
|
+
bindings.push({
|
|
114
|
+
node: translateX,
|
|
115
|
+
apply: (value) => {
|
|
116
|
+
offsets.current.x = value;
|
|
117
|
+
applyTranslate();
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (translateY) {
|
|
122
|
+
bindings.push({
|
|
123
|
+
node: translateY,
|
|
124
|
+
apply: (value) => {
|
|
125
|
+
offsets.current.y = value;
|
|
126
|
+
applyTranslate();
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
const subscriptions = bindings.map((binding) => ({
|
|
131
|
+
binding,
|
|
132
|
+
id: binding.node.addListener(({ value }) => binding.apply(value)),
|
|
133
|
+
}));
|
|
134
|
+
for (const { binding } of subscriptions) {
|
|
135
|
+
binding.apply(binding.node.__getValue());
|
|
136
|
+
}
|
|
137
|
+
return () => {
|
|
138
|
+
for (const { binding, id } of subscriptions) {
|
|
139
|
+
binding.node.removeListener(id);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
// Re-bind when the animated node identities change.
|
|
143
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
144
|
+
}, [opacity, translateX, translateY, node]);
|
|
145
|
+
return (_jsx(GtkBox, { ref: widgetRef, name: testID, cssClasses: cssClass ? [cssClass] : [], children: _jsx(HostNodeContext.Provider, { value: { engine: host.engine, node, widgetRef }, children: children }) }));
|
|
146
|
+
};
|
|
147
|
+
export const Animated = {
|
|
148
|
+
...api,
|
|
149
|
+
View: AnimatedView,
|
|
150
|
+
};
|
|
151
|
+
export { Easing } from "../animated/index";
|
|
152
|
+
//# sourceMappingURL=animated.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animated.js","sourceRoot":"","sources":["../../src/components/animated.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useLayoutEffect, useRef, type ReactNode } from \"react\"\nimport { createAnimated, type FrameScheduler } from \"../animated/index\"\nimport type { FlatStyle, StyleProp, TransformPart } from \"../contracts\"\nimport { GLib, GtkBox, queueAllocate, type Gtk } from \"../gtkx/bridge/index\"\nimport { HostNodeContext } from \"./host-node\"\nimport { setStoredOffset } from \"./rect-store\"\nimport {\n useLayoutChild,\n useRnContainer,\n type LayoutEvent,\n} from \"./use-layout-child\"\n\n// ~60fps one-shot ticks off the GLib main loop. A frame-clock driver (per\n// window) is a later optimization; timeouts keep the driver widget-free.\nconst glibScheduler: FrameScheduler = {\n schedule(callback) {\n let cancelled = false\n const id = GLib.timeoutAdd(GLib.PRIORITY_DEFAULT, 16, () => {\n if (!cancelled) {\n callback(Number(GLib.getMonotonicTime()) / 1000)\n }\n return false\n })\n return () => {\n if (!cancelled) {\n cancelled = true\n GLib.Source.remove(id)\n }\n }\n },\n}\n\nconst api = createAnimated(glibScheduler)\n\ntype AnimatedNode = {\n addListener(callback: (state: { value: number }) => void): string\n removeListener(id: string): void\n __getValue(): number\n}\n\nconst isAnimatedNode = (value: unknown): value is AnimatedNode =>\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as AnimatedNode).addListener === \"function\" &&\n typeof (value as AnimatedNode).__getValue === \"function\"\n\ntype AnimatedTransformPart = { [key: string]: number | string | AnimatedNode }\n\n// Omit, not plain intersection: intersecting would AND the animated transform\n// with FlatStyle's numeric one, rejecting Animated.Value entries.\nexport type AnimatedViewStyle = Omit<FlatStyle, \"opacity\" | \"transform\"> & {\n opacity?: number | AnimatedNode\n transform?: (TransformPart | AnimatedTransformPart)[]\n}\n\ntype Binding = {\n node: AnimatedNode\n apply: (value: number) => void\n}\n\nexport type AnimatedViewProps = {\n style?: AnimatedViewStyle | AnimatedViewStyle[]\n children?: ReactNode\n onLayout?: (event: LayoutEvent) => void\n testID?: string\n}\n\nconst splitAnimated = (\n style: AnimatedViewProps[\"style\"],\n): {\n staticStyle: StyleProp\n opacity: AnimatedNode | null\n translateX: AnimatedNode | null\n translateY: AnimatedNode | null\n} => {\n const flat: Record<string, unknown> = {}\n const collect = (entry: AnimatedViewProps[\"style\"]): void => {\n if (!entry) {\n return\n }\n if (Array.isArray(entry)) {\n entry.forEach(collect)\n return\n }\n Object.assign(flat, entry)\n }\n collect(style)\n\n let opacity: AnimatedNode | null = null\n let translateX: AnimatedNode | null = null\n let translateY: AnimatedNode | null = null\n\n if (isAnimatedNode(flat.opacity)) {\n opacity = flat.opacity\n delete flat.opacity\n }\n if (Array.isArray(flat.transform)) {\n const staticParts: TransformPart[] = []\n for (const part of flat.transform as AnimatedTransformPart[]) {\n const key = Object.keys(part)[0]\n const value = part[key!]\n if (key === \"translateX\" && isAnimatedNode(value)) {\n translateX = value\n } else if (key === \"translateY\" && isAnimatedNode(value)) {\n translateY = value\n } else if (!isAnimatedNode(value)) {\n staticParts.push(part as TransformPart)\n }\n }\n if (staticParts.length > 0) {\n flat.transform = staticParts\n } else {\n delete flat.transform\n }\n }\n\n return { staticStyle: flat as StyleProp, opacity, translateX, translateY }\n}\n\n// Animated values bypass React entirely: listeners write straight to the\n// widget (opacity) and to the rect store (translate offsets applied by the\n// parent's allocate), on top of the engine-committed base rect — the fast\n// path measured in the spike. Animation frames never touch Yoga.\nconst AnimatedView = ({\n style,\n children,\n onLayout,\n testID,\n}: AnimatedViewProps) => {\n const widgetRef = useRef<Gtk.Box | null>(null)\n const { staticStyle, opacity, translateX, translateY } = splitAnimated(style)\n\n const { host, node, cssClass } = useLayoutChild(widgetRef, {\n style: staticStyle,\n onLayout,\n })\n useRnContainer(widgetRef, node)\n\n const offsets = useRef({ x: 0, y: 0 })\n\n useLayoutEffect(() => {\n // RN transform semantics: translate is paint-only. The offset goes to\n // the rect store unclamped — the parent's measure ignores children, so an\n // out-of-bounds child draws past the boundary over its neighbors without\n // moving a single ancestor.\n const applyTranslate = (): void => {\n const widget = widgetRef.current\n const parentWidget = host.widgetRef.current\n if (!widget || !parentWidget) {\n return\n }\n setStoredOffset(widget, offsets.current.x, offsets.current.y)\n queueAllocate(parentWidget)\n }\n\n const bindings: Binding[] = []\n if (opacity) {\n bindings.push({\n node: opacity,\n apply: (value) => {\n widgetRef.current?.setOpacity(Math.min(1, Math.max(0, value)))\n },\n })\n }\n if (translateX) {\n bindings.push({\n node: translateX,\n apply: (value) => {\n offsets.current.x = value\n applyTranslate()\n },\n })\n }\n if (translateY) {\n bindings.push({\n node: translateY,\n apply: (value) => {\n offsets.current.y = value\n applyTranslate()\n },\n })\n }\n\n const subscriptions = bindings.map((binding) => ({\n binding,\n id: binding.node.addListener(({ value }) => binding.apply(value)),\n }))\n for (const { binding } of subscriptions) {\n binding.apply(binding.node.__getValue())\n }\n return () => {\n for (const { binding, id } of subscriptions) {\n binding.node.removeListener(id)\n }\n }\n // Re-bind when the animated node identities change.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [opacity, translateX, translateY, node])\n\n return (\n <GtkBox\n ref={widgetRef}\n name={testID}\n cssClasses={cssClass ? [cssClass] : []}\n >\n <HostNodeContext.Provider\n value={{ engine: host.engine, node, widgetRef }}\n >\n {children}\n </HostNodeContext.Provider>\n </GtkBox>\n )\n}\n\nexport const Animated = {\n ...api,\n View: AnimatedView,\n}\n\nexport { Easing } from \"../animated/index\"\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ComponentType } from "react";
|
|
2
|
+
type ComponentProvider = () => ComponentType<Record<string, unknown>>;
|
|
3
|
+
export type RunApplicationParams = {
|
|
4
|
+
initialProps?: Record<string, unknown>;
|
|
5
|
+
title?: string;
|
|
6
|
+
width?: number;
|
|
7
|
+
height?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare const AppRegistry: {
|
|
10
|
+
registerComponent(appKey: string, provider: ComponentProvider): string;
|
|
11
|
+
getAppKeys(): string[];
|
|
12
|
+
runApplication(appKey: string, params?: RunApplicationParams): void;
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useLayoutEffect } from "react";
|
|
3
|
+
import { createRoot, Gtk, GtkApplication, GtkApplicationWindow, quit, } from "../gtkx/bridge/index";
|
|
4
|
+
import { Root } from "./root";
|
|
5
|
+
const registry = new Map();
|
|
6
|
+
// RN parity: system "reduce animations" hints never auto-stop RN animations
|
|
7
|
+
// (ActivityIndicator keeps spinning; honoring reduce-motion is an explicit
|
|
8
|
+
// opt-in via AccessibilityInfo). Our Animated runs on GLib timers and already
|
|
9
|
+
// ignores the hint, so GTK-internal animations (GtkSpinner, switch slides)
|
|
10
|
+
// must behave the same — otherwise e.g. GNOME under software rendering
|
|
11
|
+
// reports enable-animations=false through the settings portal and spinners
|
|
12
|
+
// freeze while Animated keeps moving.
|
|
13
|
+
let animationsForced = false;
|
|
14
|
+
const forceEnableAnimations = () => {
|
|
15
|
+
if (animationsForced) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const settings = Gtk.Settings.getDefault();
|
|
19
|
+
if (!settings) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
animationsForced = true;
|
|
23
|
+
// Application-set GtkSettings values outrank the desktop backend, so a
|
|
24
|
+
// later portal update cannot flip this back.
|
|
25
|
+
settings.gtkEnableAnimations = true;
|
|
26
|
+
};
|
|
27
|
+
const WindowContent = ({ App, initialProps, initialWidth, initialHeight, }) => {
|
|
28
|
+
// Settings need an initialized display, and writing them mid-render is
|
|
29
|
+
// unsafe — apply after the window mounts.
|
|
30
|
+
useLayoutEffect(() => {
|
|
31
|
+
forceEnableAnimations();
|
|
32
|
+
}, []);
|
|
33
|
+
// The Root is the window's direct child: RnGtkxLayout reports a zero
|
|
34
|
+
// minimum (the window shrinks freely — no ratchet) and adopts the actual
|
|
35
|
+
// content-area allocation as the layout viewport. No scrollable wrapper
|
|
36
|
+
// means a window can never scroll its own root — RN semantics, scrolling
|
|
37
|
+
// stays opt-in via <ScrollView>.
|
|
38
|
+
return (_jsx(Root, { width: initialWidth, height: initialHeight, followAllocation: true, children: _jsx(App, { ...initialProps }) }));
|
|
39
|
+
};
|
|
40
|
+
export const AppRegistry = {
|
|
41
|
+
registerComponent(appKey, provider) {
|
|
42
|
+
registry.set(appKey, provider);
|
|
43
|
+
return appKey;
|
|
44
|
+
},
|
|
45
|
+
getAppKeys() {
|
|
46
|
+
return [...registry.keys()];
|
|
47
|
+
},
|
|
48
|
+
runApplication(appKey, params = {}) {
|
|
49
|
+
const provider = registry.get(appKey);
|
|
50
|
+
if (!provider) {
|
|
51
|
+
throw new Error(`AppRegistry: no component registered for "${appKey}". ` +
|
|
52
|
+
`Registered: ${[...registry.keys()].join(", ") || "(none)"}`);
|
|
53
|
+
}
|
|
54
|
+
const App = provider();
|
|
55
|
+
const width = params.width ?? 800;
|
|
56
|
+
const height = params.height ?? 600;
|
|
57
|
+
const AppWindow = () => (_jsx(GtkApplicationWindow, { title: params.title ?? appKey, defaultWidth: width, defaultHeight: height, onCloseRequest: quit, children: _jsx(WindowContent, { App: App, initialProps: params.initialProps ?? {}, initialWidth: width, initialHeight: height }) }));
|
|
58
|
+
createRoot().render(_jsx(GtkApplication, { children: _jsx(AppWindow, {}) }));
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=app-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-registry.js","sourceRoot":"","sources":["../../src/components/app-registry.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useLayoutEffect, type ComponentType } from \"react\"\nimport {\n createRoot,\n Gtk,\n GtkApplication,\n GtkApplicationWindow,\n quit,\n} from \"../gtkx/bridge/index\"\nimport { Root } from \"./root\"\n\ntype ComponentProvider = () => ComponentType<Record<string, unknown>>\n\nconst registry = new Map<string, ComponentProvider>()\n\nexport type RunApplicationParams = {\n initialProps?: Record<string, unknown>\n title?: string\n width?: number\n height?: number\n}\n\n// RN parity: system \"reduce animations\" hints never auto-stop RN animations\n// (ActivityIndicator keeps spinning; honoring reduce-motion is an explicit\n// opt-in via AccessibilityInfo). Our Animated runs on GLib timers and already\n// ignores the hint, so GTK-internal animations (GtkSpinner, switch slides)\n// must behave the same — otherwise e.g. GNOME under software rendering\n// reports enable-animations=false through the settings portal and spinners\n// freeze while Animated keeps moving.\nlet animationsForced = false\nconst forceEnableAnimations = (): void => {\n if (animationsForced) {\n return\n }\n const settings = Gtk.Settings.getDefault()\n if (!settings) {\n return\n }\n animationsForced = true\n // Application-set GtkSettings values outrank the desktop backend, so a\n // later portal update cannot flip this back.\n settings.gtkEnableAnimations = true\n}\n\nconst WindowContent = ({\n App,\n initialProps,\n initialWidth,\n initialHeight,\n}: {\n App: ComponentType<Record<string, unknown>>\n initialProps: Record<string, unknown>\n initialWidth: number\n initialHeight: number\n}) => {\n // Settings need an initialized display, and writing them mid-render is\n // unsafe — apply after the window mounts.\n useLayoutEffect(() => {\n forceEnableAnimations()\n }, [])\n\n // The Root is the window's direct child: RnGtkxLayout reports a zero\n // minimum (the window shrinks freely — no ratchet) and adopts the actual\n // content-area allocation as the layout viewport. No scrollable wrapper\n // means a window can never scroll its own root — RN semantics, scrolling\n // stays opt-in via <ScrollView>.\n return (\n <Root\n width={initialWidth}\n height={initialHeight}\n followAllocation\n >\n <App {...initialProps} />\n </Root>\n )\n}\n\nexport const AppRegistry = {\n registerComponent(appKey: string, provider: ComponentProvider): string {\n registry.set(appKey, provider)\n return appKey\n },\n\n getAppKeys(): string[] {\n return [...registry.keys()]\n },\n\n runApplication(appKey: string, params: RunApplicationParams = {}): void {\n const provider = registry.get(appKey)\n if (!provider) {\n throw new Error(\n `AppRegistry: no component registered for \"${appKey}\". ` +\n `Registered: ${[...registry.keys()].join(\", \") || \"(none)\"}`,\n )\n }\n const App = provider()\n const width = params.width ?? 800\n const height = params.height ?? 600\n\n const AppWindow = () => (\n <GtkApplicationWindow\n title={params.title ?? appKey}\n defaultWidth={width}\n defaultHeight={height}\n onCloseRequest={quit}\n >\n <WindowContent\n App={App}\n initialProps={params.initialProps ?? {}}\n initialWidth={width}\n initialHeight={height}\n />\n </GtkApplicationWindow>\n )\n\n createRoot().render(\n <GtkApplication>\n <AppWindow />\n </GtkApplication>,\n )\n },\n}\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type ComponentType, type ReactElement } from "react";
|
|
2
|
+
import type { StyleProp } from "../contracts";
|
|
3
|
+
import type { ScrollViewProps } from "./scroll-view";
|
|
4
|
+
import { type ItemLayout, type ListRenderItemInfo, type ViewabilityConfig, type ViewToken, type VirtualizedListHandle } from "./virtualized-list";
|
|
5
|
+
export type { ListRenderItemInfo, ViewabilityConfig, ViewToken, } from "./virtualized-list";
|
|
6
|
+
export type { VirtualizedListHandle as FlatListHandle } from "./virtualized-list";
|
|
7
|
+
export type FlatListProps<T> = Omit<ScrollViewProps, "children"> & {
|
|
8
|
+
data: readonly T[];
|
|
9
|
+
renderItem: (info: ListRenderItemInfo<T>) => ReactElement | null;
|
|
10
|
+
keyExtractor?: (item: T, index: number) => string;
|
|
11
|
+
ItemSeparatorComponent?: ComponentType | null;
|
|
12
|
+
ListHeaderComponent?: ComponentType | ReactElement | null;
|
|
13
|
+
ListFooterComponent?: ComponentType | ReactElement | null;
|
|
14
|
+
ListEmptyComponent?: ComponentType | ReactElement | null;
|
|
15
|
+
onEndReached?: () => void;
|
|
16
|
+
onEndReachedThreshold?: number;
|
|
17
|
+
onViewableItemsChanged?: (info: {
|
|
18
|
+
viewableItems: ViewToken<T>[];
|
|
19
|
+
changed: ViewToken<T>[];
|
|
20
|
+
}) => void;
|
|
21
|
+
viewabilityConfig?: ViewabilityConfig;
|
|
22
|
+
estimatedItemSize?: number;
|
|
23
|
+
getItemLayout?: (data: readonly T[], index: number) => ItemLayout;
|
|
24
|
+
windowSize?: number;
|
|
25
|
+
initialNumToRender?: number;
|
|
26
|
+
extraData?: unknown;
|
|
27
|
+
inverted?: boolean;
|
|
28
|
+
refreshing?: boolean;
|
|
29
|
+
onRefresh?: () => void;
|
|
30
|
+
style?: StyleProp;
|
|
31
|
+
};
|
|
32
|
+
export declare const FlatList: <T>(props: FlatListProps<T> & {
|
|
33
|
+
ref?: React.Ref<VirtualizedListHandle>;
|
|
34
|
+
}) => ReactElement;
|
|
35
|
+
export type SectionListData<T> = {
|
|
36
|
+
title: string;
|
|
37
|
+
data: readonly T[];
|
|
38
|
+
};
|
|
39
|
+
export type SectionListProps<T> = Omit<FlatListProps<T>, "data" | "renderItem" | "getItemLayout" | "onViewableItemsChanged" | "viewabilityConfig"> & {
|
|
40
|
+
sections: readonly SectionListData<T>[];
|
|
41
|
+
renderItem: (info: ListRenderItemInfo<T>) => ReactElement | null;
|
|
42
|
+
renderSectionHeader?: (info: {
|
|
43
|
+
section: SectionListData<T>;
|
|
44
|
+
}) => ReactElement | null;
|
|
45
|
+
stickySectionHeadersEnabled?: boolean;
|
|
46
|
+
ref?: React.Ref<VirtualizedListHandle>;
|
|
47
|
+
};
|
|
48
|
+
export declare const SectionList: <T>({ sections, renderItem, renderSectionHeader, stickySectionHeadersEnabled, ref, ...rest }: SectionListProps<T>) => ReactElement;
|