ruby_everywhere 0.2.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/README.md +255 -0
- data/bridge/README.md +48 -0
- data/bridge/everywhere/bridge.js +388 -3
- data/bridge/everywhere/native.css +203 -0
- data/bridge/package.json +6 -3
- data/lib/everywhere/android_resources.rb +217 -0
- data/lib/everywhere/android_sdk.rb +330 -0
- data/lib/everywhere/asset_catalog.rb +185 -0
- data/lib/everywhere/auth_handoff.rb +398 -0
- data/lib/everywhere/auth_token.rb +118 -0
- data/lib/everywhere/builders/android.rb +844 -0
- data/lib/everywhere/builders/ios.rb +72 -3
- data/lib/everywhere/commands/build.rb +51 -9
- data/lib/everywhere/commands/clean.rb +10 -5
- data/lib/everywhere/commands/dev.rb +46 -8
- data/lib/everywhere/commands/doctor.rb +89 -3
- data/lib/everywhere/commands/install.rb +1 -1
- data/lib/everywhere/commands/logs.rb +117 -8
- data/lib/everywhere/config.rb +513 -14
- data/lib/everywhere/emulator.rb +405 -0
- data/lib/everywhere/engine.rb +21 -0
- data/lib/everywhere/icon.rb +196 -0
- data/lib/everywhere/log_filter.rb +74 -0
- data/lib/everywhere/mobile_config_endpoint.rb +13 -0
- data/lib/everywhere/mobile_configs_controller.rb +18 -0
- data/lib/everywhere/native_helper.rb +198 -5
- data/lib/everywhere/omniauth.rb +88 -0
- data/lib/everywhere/paths.rb +47 -0
- data/lib/everywhere/version.rb +1 -1
- data/support/mobile/android/README.md +217 -0
- data/support/mobile/android/app/build.gradle.kts +156 -0
- data/support/mobile/android/app/everywhere.properties +8 -0
- data/support/mobile/android/app/native-packages.gradle.kts +16 -0
- data/support/mobile/android/app/proguard-rules.pro +21 -0
- data/support/mobile/android/app/src/debug/res/xml/network_security_config.xml +30 -0
- data/support/mobile/android/app/src/main/AndroidManifest.xml +42 -0
- data/support/mobile/android/app/src/main/assets/everywhere.json +9 -0
- data/support/mobile/android/app/src/main/assets/fonts/MaterialIcons-Regular.codepoints +2235 -0
- data/support/mobile/android/app/src/main/assets/fonts/MaterialIcons-Regular.ttf +0 -0
- data/support/mobile/android/app/src/main/assets/json/path-configuration.json +19 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/AuthFlow.kt +268 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereApplication.kt +178 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereConfig.kt +409 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereEvents.kt +68 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/EverywhereHost.kt +101 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/IconFont.kt +211 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/MainActivity.kt +975 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/MainTabs.kt +201 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/WebBottomSheetFragment.kt +13 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/WebFragment.kt +36 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/BiometricsComponent.kt +535 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/HapticsComponent.kt +141 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/MenuComponent.kt +361 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/NotificationComponent.kt +151 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/PermissionsComponent.kt +271 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/StorageComponent.kt +101 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/bridge/WebControlChannel.kt +204 -0
- data/support/mobile/android/app/src/main/java/com/rubyeverywhere/shell/extensions/EverywhereExtensions.kt +51 -0
- data/support/mobile/android/app/src/main/res/color/bottom_navigation_active_indicator.xml +4 -0
- data/support/mobile/android/app/src/main/res/color/bottom_navigation_item.xml +11 -0
- data/support/mobile/android/app/src/main/res/drawable/ic_launcher_foreground.xml +26 -0
- data/support/mobile/android/app/src/main/res/drawable/ic_tab_placeholder.xml +28 -0
- data/support/mobile/android/app/src/main/res/layout/activity_main.xml +116 -0
- data/support/mobile/android/app/src/main/res/layout/bridge_menu_sheet.xml +83 -0
- data/support/mobile/android/app/src/main/res/layout/bridge_menu_sheet_item.xml +35 -0
- data/support/mobile/android/app/src/main/res/layout/tab_more_sheet.xml +48 -0
- data/support/mobile/android/app/src/main/res/layout/tab_more_sheet_item.xml +35 -0
- data/support/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +12 -0
- data/support/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +6 -0
- data/support/mobile/android/app/src/main/res/values/colors.xml +21 -0
- data/support/mobile/android/app/src/main/res/values/ic_launcher_background.xml +5 -0
- data/support/mobile/android/app/src/main/res/values/strings.xml +18 -0
- data/support/mobile/android/app/src/main/res/values/styles.xml +32 -0
- data/support/mobile/android/app/src/main/res/values/themes.xml +53 -0
- data/support/mobile/android/app/src/main/res/values-night/colors.xml +11 -0
- data/support/mobile/android/app/src/main/res/values-night/themes.xml +33 -0
- data/support/mobile/android/app/src/main/res/xml/network_security_config.xml +12 -0
- data/support/mobile/android/app/src/stamped/AndroidManifest.xml +34 -0
- data/support/mobile/android/build.gradle.kts +8 -0
- data/support/mobile/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- data/support/mobile/android/gradle/wrapper/gradle-wrapper.properties +10 -0
- data/support/mobile/android/gradle.properties +14 -0
- data/support/mobile/android/gradlew +251 -0
- data/support/mobile/android/gradlew.bat +94 -0
- data/support/mobile/android/settings.gradle.kts +28 -0
- data/support/mobile/ios/App/AppDelegate.swift +7 -1
- data/support/mobile/ios/App/AuthFlow.swift +101 -0
- data/support/mobile/ios/App/Bridge/MenuComponent.swift +192 -0
- data/support/mobile/ios/App/EverywhereConfig.swift +105 -0
- data/support/mobile/ios/App/SceneDelegate.swift +144 -0
- data/support/mobile/ios/App.xcodeproj/project.pbxproj +8 -0
- data/support/mobile/ios/README.md +10 -0
- metadata +69 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7ffb921df597efe047c25240e7d8b92aaad49c00c90d546020e053eac618739a
|
|
4
|
+
data.tar.gz: 17315b4c5d91eced13b44d7147942d7d6357ee791b8622425ab655eb97b1ab27
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 71d9ba1ea63abe51a7262f02f069ef9f068d3192bb20800bdd0fba8bcd50f36f2daa83bb3f758e7273576b69b88be5541428b41f93021579cc1b5054532099ad
|
|
7
|
+
data.tar.gz: 59632bacae03ade28233832d0193d2500e4e3f85c07b7e61a39f1e086cc398b40f66d48091ffc9e336a11e2f91994b666ea60fc7ab2cbef2b76252d6fb0ada60
|
data/README.md
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# RubyEverywhere
|
|
2
|
+
|
|
3
|
+
**Ship desktop and mobile apps from the Ruby web apps you already know how to build.**
|
|
4
|
+
|
|
5
|
+
[rubyeverywhere.com](https://rubyeverywhere.com) · by [Andrea Fomera](https://afomera.dev)
|
|
6
|
+
|
|
7
|
+
RubyEverywhere takes a Rails (or Sinatra, or Hanami) app and gives it a native
|
|
8
|
+
life on the platforms your users are already on:
|
|
9
|
+
|
|
10
|
+
- **Desktop** — a [Tauri](https://tauri.app)-based shell. In *local* mode your
|
|
11
|
+
whole app is pressed into a single-file binary with
|
|
12
|
+
[Tebako](https://github.com/tamatebako/tebako) and runs on-device, no Ruby
|
|
13
|
+
install required; in *remote* mode the shell is a thin native wrapper around
|
|
14
|
+
your deployed app.
|
|
15
|
+
- **iOS** — a [Hotwire Native](https://native.hotwired.dev) shell with a real
|
|
16
|
+
tab bar, nav-bar buttons, menus, action sheets, notifications, haptics,
|
|
17
|
+
biometrics, deep links, and native sign-in.
|
|
18
|
+
- **Android** — a feature-for-feature Hotwire Native Android port of the same
|
|
19
|
+
shell, stamped from the same `config/everywhere.yml`.
|
|
20
|
+
|
|
21
|
+
One config file, one CLI, one JavaScript API. The web app stays the source of
|
|
22
|
+
truth — most of what you'd normally rebuild natively (tabs, routes, menus,
|
|
23
|
+
badges) deploys with your Rails app rather than through an app-store review.
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
gem install ruby_everywhere
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This gives you two equivalent executables — `every` and `rbe` — plus the
|
|
32
|
+
packaging toolchain (the `rbe-tebako` fork) as a dependency.
|
|
33
|
+
|
|
34
|
+
Or add it to your app's Gemfile, which also wires up the Rails engine (bridge
|
|
35
|
+
asset serving, importmap pin, view helpers, the live mobile config endpoint):
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
gem "ruby_everywhere"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Requires Ruby >= 3.2.
|
|
42
|
+
|
|
43
|
+
**The gem is free, and it always will be.** Everything here — the CLI, the
|
|
44
|
+
desktop shell, both mobile shells, the bridge — is MIT licensed and yours to
|
|
45
|
+
use, forever, with no account and no key. Local builds run on a Mac today
|
|
46
|
+
(pressing, code signing, Xcode and the Android SDK all want a macOS host).
|
|
47
|
+
If you don't own one, or you'd rather not keep a build toolchain healthy, the
|
|
48
|
+
[RubyEverywhere Platform](https://rubyeverywhere.com) is a paid service coming
|
|
49
|
+
soon that runs the exact same builds for you — see
|
|
50
|
+
[Hosted builds](#hosted-builds) below. It's a convenience, never a gate: nothing
|
|
51
|
+
in this gem is held back for it.
|
|
52
|
+
|
|
53
|
+
## Quick start
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
cd path/to/your/app
|
|
57
|
+
|
|
58
|
+
every install # remote mode: a native shell around your deployed app
|
|
59
|
+
every install --local # local mode: compile and ship the app itself
|
|
60
|
+
|
|
61
|
+
every doctor # check the toolchain before your first build
|
|
62
|
+
|
|
63
|
+
every dev # dev server + native shells on demand, live reload
|
|
64
|
+
every dev --ios # ...straight into the iOS Simulator
|
|
65
|
+
every dev --android # ...straight into the Android emulator
|
|
66
|
+
|
|
67
|
+
every build # package the macOS .app
|
|
68
|
+
every build --ios # build the iOS shell
|
|
69
|
+
every build --android # build the APK/AAB
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`every install` is idempotent — it adds `config/everywhere.yml`, a boot stub,
|
|
73
|
+
and the framework-specific config tweaks it needs, and skips anything already
|
|
74
|
+
in place. For Rails it does the surgery for you; for Sinatra and Hanami it
|
|
75
|
+
vendors the bridge and prints the remaining wiring rather than guessing at your
|
|
76
|
+
boot files.
|
|
77
|
+
|
|
78
|
+
`every dev` never packages anything: it runs your ordinary dev server and points
|
|
79
|
+
the native shells at it, so the edit-refresh loop is untouched Rails.
|
|
80
|
+
|
|
81
|
+
## Configuration
|
|
82
|
+
|
|
83
|
+
Everything per-app lives in `config/everywhere.yml`. The native shell templates
|
|
84
|
+
are frozen — the CLI stamps a copy per app and only ever writes the identity,
|
|
85
|
+
config, icon, and color files, so a shell upgrade never collides with your app.
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
app:
|
|
89
|
+
name: My Really Awesome App
|
|
90
|
+
bundle_id: com.example.myapp # set it once; renaming moves users' data
|
|
91
|
+
version: 1.2.0
|
|
92
|
+
entry_path: /dashboard # where the app opens
|
|
93
|
+
icon: icon.png
|
|
94
|
+
|
|
95
|
+
appearance:
|
|
96
|
+
tint_color: "#CC342D"
|
|
97
|
+
background_color: # one hex string, or split by system theme
|
|
98
|
+
light: "#FAF9F7"
|
|
99
|
+
dark: "#1C1B1A"
|
|
100
|
+
|
|
101
|
+
remote:
|
|
102
|
+
url: https://app.example.com # remote mode: the deployed app to wrap
|
|
103
|
+
|
|
104
|
+
tabs: # the native mobile tab bar
|
|
105
|
+
- name: Builds
|
|
106
|
+
path: /builds
|
|
107
|
+
icons:
|
|
108
|
+
ios: hammer # SF Symbol
|
|
109
|
+
android: build # Material icon
|
|
110
|
+
|
|
111
|
+
permissions: # only declared permissions can ever prompt
|
|
112
|
+
notifications: true
|
|
113
|
+
camera: "Scan QR codes to pair devices." # the sentence iOS shows
|
|
114
|
+
|
|
115
|
+
rules: # Hotwire Native path configuration
|
|
116
|
+
- patterns: ["/preferences$"]
|
|
117
|
+
properties:
|
|
118
|
+
context: modal
|
|
119
|
+
|
|
120
|
+
build:
|
|
121
|
+
ruby: "4.0.6"
|
|
122
|
+
targets: [macos-arm64, ios-arm64, android-arm64]
|
|
123
|
+
|
|
124
|
+
updates: # self-hosted, signed auto-updates
|
|
125
|
+
url: https://updates.example.com
|
|
126
|
+
public_key: RWQ…
|
|
127
|
+
auto: check # off | check | download | install
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Also supported: `auth:` (native OAuth sign-in with a callback scheme),
|
|
131
|
+
`deep_linking:` (universal links / App Links — the gem serves the
|
|
132
|
+
`apple-app-site-association` and `assetlinks.json` files for you), and
|
|
133
|
+
`native:` for "supernative" extensions — Swift you keep in your app repo under
|
|
134
|
+
`native/ios/` that `every build` compiles into the shell, including SwiftUI
|
|
135
|
+
screens, bridge components, a custom splash, and pinned SPM packages.
|
|
136
|
+
|
|
137
|
+
Tabs and path rules ship two ways from that one source: baked into the app
|
|
138
|
+
bundle for offline/first launch, and served live from
|
|
139
|
+
`/everywhere/{ios,android}_v1.json`, so changing them deploys with your web app.
|
|
140
|
+
`Everywhere.filter_tabs` lets you vary the tab bar per request — it shares the
|
|
141
|
+
app's session, so signed-out users can get a different bar without a release.
|
|
142
|
+
|
|
143
|
+
## The JavaScript bridge
|
|
144
|
+
|
|
145
|
+
The gem ships `@rubyeverywhere/bridge` — one API for the browser, the desktop
|
|
146
|
+
shell, and the mobile shells. Rails apps get it served and importmap-pinned
|
|
147
|
+
automatically; Sinatra and Hanami get it vendored to `public/bridge.js`.
|
|
148
|
+
|
|
149
|
+
```js
|
|
150
|
+
import Everywhere from "@rubyeverywhere/bridge"
|
|
151
|
+
|
|
152
|
+
Everywhere.platform // "desktop" | "mobile" | "browser"
|
|
153
|
+
Everywhere.native // true inside a RubyEverywhere app
|
|
154
|
+
|
|
155
|
+
Everywhere.notify({ title, body })
|
|
156
|
+
Everywhere.menu({ title, items })
|
|
157
|
+
Everywhere.haptics.impact("medium")
|
|
158
|
+
Everywhere.badge.setTab("/inbox", 3)
|
|
159
|
+
Everywhere.permissions.request("camera")
|
|
160
|
+
Everywhere.storage.set("theme", "dark")
|
|
161
|
+
Everywhere.updates.check()
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Everything degrades gracefully — the same page works in a plain browser tab and
|
|
165
|
+
gains native powers inside the app. See
|
|
166
|
+
[`bridge/README.md`](bridge/README.md) for the full surface.
|
|
167
|
+
|
|
168
|
+
Most native chrome needs no JavaScript at all. Tag ordinary markup and the
|
|
169
|
+
bridge lifts it into real native controls; tapping the native control just
|
|
170
|
+
`.click()`s the element it mirrors, so behavior stays defined once in the DOM.
|
|
171
|
+
Rails ships helpers that emit exactly that markup:
|
|
172
|
+
|
|
173
|
+
```erb
|
|
174
|
+
<%= everywhere_nav_button "New", new_note_path, icons: { ios: "plus", android: "add" } %>
|
|
175
|
+
<%= everywhere_fab new_note_path %>
|
|
176
|
+
<%= everywhere_nav_menu "More" do %>
|
|
177
|
+
<%= everywhere_menu_item "Delete", note_path(@note), method: :delete, style: "destructive" %>
|
|
178
|
+
<% end %>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Plus `native_app?`, `native_platform`, `everywhere_badge`,
|
|
182
|
+
`everywhere_biometric_lock`, and friends.
|
|
183
|
+
|
|
184
|
+
## Commands
|
|
185
|
+
|
|
186
|
+
| Command | What it does |
|
|
187
|
+
| --- | --- |
|
|
188
|
+
| `every install` | Prepare an app (boot stub, `config/everywhere.yml`, config tweaks) |
|
|
189
|
+
| `every doctor` | Check the toolchain — Tebako, Rust, brew deps, Xcode, Android SDK/JDK |
|
|
190
|
+
| `every dev` | Dev server with native shells on demand (`--desktop --ios --android --browser`) |
|
|
191
|
+
| `every logs` | Stream shell logs from the Simulator or Android device |
|
|
192
|
+
| `every build` | Package natively — desktop, `--ios`, or `--android` |
|
|
193
|
+
| `every icon` | Generate `.icns` / `.ico` / Linux icons from a source PNG |
|
|
194
|
+
| `every release` | Sign, notarize, staple, and emit a `release.json` receipt |
|
|
195
|
+
| `every updates keygen` | Generate a minisign-compatible update-signing keypair |
|
|
196
|
+
| `every publish` | Publish a release to your update bucket |
|
|
197
|
+
| `every clean` | Remove the shell build caches |
|
|
198
|
+
| `every shell-dir` | Print the path of the bundled shell template |
|
|
199
|
+
| `every platform …` | Hosted builds: `login`, `logout`, `auth status`, `build` |
|
|
200
|
+
|
|
201
|
+
Run `every` with no arguments for the full list, or `every <command> --help` for
|
|
202
|
+
a command's flags.
|
|
203
|
+
|
|
204
|
+
## Auto-updates
|
|
205
|
+
|
|
206
|
+
Desktop releases can update themselves from a bucket you own, with no service in
|
|
207
|
+
the middle:
|
|
208
|
+
|
|
209
|
+
```sh
|
|
210
|
+
every updates keygen # once, per app
|
|
211
|
+
every release # build, sign, notarize, staple
|
|
212
|
+
every publish --notes-file NOTES.md # sign the manifest, upload, flip latest.json
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The public key ships in the app; the secret key never leaves your machine. Apps
|
|
216
|
+
can check, install, and switch channels at runtime via `Everywhere.updates`.
|
|
217
|
+
|
|
218
|
+
## Hosted builds
|
|
219
|
+
|
|
220
|
+
Don't have a Mac, or want iOS and Android built without babysitting Xcode, the
|
|
221
|
+
Android SDK, and a signing setup? The **RubyEverywhere Platform** — a paid
|
|
222
|
+
service, coming soon — runs the same builds on managed machines and hands back
|
|
223
|
+
the artifacts. The CLI already speaks to it:
|
|
224
|
+
|
|
225
|
+
```sh
|
|
226
|
+
every platform login
|
|
227
|
+
every platform build --target ios-arm64,android-arm64
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Same gem, same `config/everywhere.yml`, same output — you're paying for the
|
|
231
|
+
build machines and the toolchain upkeep, not for features. The gem stays free
|
|
232
|
+
and complete on its own.
|
|
233
|
+
|
|
234
|
+
## Project layout
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
lib/everywhere/ the CLI, config, builders, and Rails engine
|
|
238
|
+
exe/every, exe/rbe the executables
|
|
239
|
+
bridge/ @rubyeverywhere/bridge — the JS half
|
|
240
|
+
support/shell/ the Tauri desktop shell template
|
|
241
|
+
support/mobile/ios/ the Hotwire Native iOS shell template
|
|
242
|
+
support/mobile/android/ the Hotwire Native Android shell template
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The shell templates have their own READMEs documenting the freeze rules — what
|
|
246
|
+
the CLI stamps per app and what it must never touch:
|
|
247
|
+
[iOS](support/mobile/ios/README.md) · [Android](support/mobile/android/README.md).
|
|
248
|
+
|
|
249
|
+
## Contributing
|
|
250
|
+
|
|
251
|
+
Bug reports and pull requests are welcome. Run the test suite with `rake test`.
|
|
252
|
+
|
|
253
|
+
## License
|
|
254
|
+
|
|
255
|
+
Released under the [MIT License](LICENSE.txt). Copyright © 2026 Andrea Fomera.
|
data/bridge/README.md
CHANGED
|
@@ -33,6 +33,11 @@ Everywhere.confirm("Sure?") // Promise<boolean>, native dialog when pos
|
|
|
33
33
|
Everywhere.on("menu", handler) // shell events; returns an unsubscribe fn
|
|
34
34
|
Everywhere.visit("/settings") // Turbo.visit with location fallback
|
|
35
35
|
|
|
36
|
+
Everywhere.menu({ title, items }) // Promise<item | null> — native action
|
|
37
|
+
// sheet in the shell, a styled bottom
|
|
38
|
+
// sheet everywhere else. items:
|
|
39
|
+
// [{ title, id?, style?, disabled? }]
|
|
40
|
+
|
|
36
41
|
Everywhere.clipboard.write(text) // Promise<void>
|
|
37
42
|
Everywhere.clipboard.read() // Promise<string | null>
|
|
38
43
|
|
|
@@ -61,6 +66,49 @@ Everywhere.storage.clear() // Promise<boolean> — clears app keys onl
|
|
|
61
66
|
// desktop shell. Settings, not secrets — tokens go in biometrics.credential.
|
|
62
67
|
```
|
|
63
68
|
|
|
69
|
+
### Native chrome (nav bar buttons, menus, action sheets)
|
|
70
|
+
|
|
71
|
+
Tag ordinary markup, and inside the mobile shell the bridge lifts it into real
|
|
72
|
+
native controls — a nav-bar button, a pull-down / overflow menu, or an action
|
|
73
|
+
sheet. Tapping the native control just `.click()`s the element it mirrors, so a
|
|
74
|
+
link navigates, a submit submits, and behavior stays defined once in the DOM. In
|
|
75
|
+
a browser the same markup is the plain HTML it already is. No JavaScript, no
|
|
76
|
+
Stimulus — CSP-safe.
|
|
77
|
+
|
|
78
|
+
```html
|
|
79
|
+
<!-- becomes a nav-bar button (right side); icons are per-platform like tabs -->
|
|
80
|
+
<a href="/notes/new" data-everywhere-nav-button
|
|
81
|
+
data-everywhere-nav-title="New"
|
|
82
|
+
data-everywhere-nav-icon-ios="plus"
|
|
83
|
+
data-everywhere-nav-icon-android="add">New</a>
|
|
84
|
+
|
|
85
|
+
<!-- a submit button in the nav bar -->
|
|
86
|
+
<button type="submit" data-everywhere-nav-button
|
|
87
|
+
data-everywhere-nav-title="Save" data-everywhere-nav-style="done">Save</button>
|
|
88
|
+
|
|
89
|
+
<!-- a nav-bar pull-down / overflow menu (defaults to the ⋯ icon) -->
|
|
90
|
+
<div data-everywhere-nav-menu data-everywhere-nav-title="More">
|
|
91
|
+
<a href="/share" data-everywhere-menu-item data-everywhere-menu-title="Share">Share</a>
|
|
92
|
+
<button form="delete_1" data-everywhere-menu-item
|
|
93
|
+
data-everywhere-menu-title="Delete"
|
|
94
|
+
data-everywhere-menu-style="destructive">Delete</button>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<!-- an in-content action sheet: a trigger and the items it opens -->
|
|
98
|
+
<div data-everywhere-menu>
|
|
99
|
+
<button data-everywhere-menu-trigger>Options</button>
|
|
100
|
+
<div data-everywhere-menu-items>
|
|
101
|
+
<a href="/x/edit" data-everywhere-menu-item>Edit</a>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Rails ships helpers that emit exactly this — `everywhere_nav_button`,
|
|
107
|
+
`everywhere_submit_button`, `everywhere_nav_menu` / `everywhere_menu_item`,
|
|
108
|
+
`everywhere_menu`, and `everywhere_fab` (a floating action button). Include
|
|
109
|
+
`everywhere/native.css` for the FAB, the action-sheet fallback, and the
|
|
110
|
+
safe-area utilities.
|
|
111
|
+
|
|
64
112
|
### Multi-instance apps
|
|
65
113
|
|
|
66
114
|
Apps whose users pick a server — one hosted platform, many instances — opt in
|