create-satin 0.1.0-beta.2 → 0.1.0-beta.3
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/package.json +2 -2
- package/template/AGENTS.md +81 -81
- package/template/GETTING-STARTED.md +6 -4
- package/template/package.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-satin",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.3",
|
|
4
4
|
"description": "Create a Satin iPhone Home Screen app.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
|
28
28
|
"url": "git+https://github.com/satinhq/satin.git",
|
|
29
|
-
"directory": "packages/create-
|
|
29
|
+
"directory": "packages/create-satin"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"oxlint": "^1.79.0"
|
package/template/AGENTS.md
CHANGED
|
@@ -13,7 +13,7 @@ move testing to the supported runtime instead of changing `src/app.ts` to bypass
|
|
|
13
13
|
This is a developer preview. An exported API is available to compile, not a promise of native equivalence. Use the installed package's version of these offline references:
|
|
14
14
|
|
|
15
15
|
- [Getting started](GETTING-STARTED.md) explains setup and primary navigation. [IOS-DESIGN.md](IOS-DESIGN.md) explains screen composition.
|
|
16
|
-
- The [Satin API reference](node_modules/@satinhq/kit/dist/docs/
|
|
16
|
+
- The [Satin API reference](node_modules/@satinhq/kit/dist/docs/reference.md) is the naming and coverage authority. It is keyed by Satin export, with behavior, limits and declaration links for every entry point. Search the export name, then follow its declaration link for accepted props, callbacks, overloads and related types. Import type-only contracts with `import type`; they are not controls.
|
|
17
17
|
- The [package README](node_modules/@satinhq/kit/README.md) has complete examples for routes, controls, restoration, notifications, symbols, data and adaptive navigation. [Application recipes](node_modules/@satinhq/kit/dist/docs/app-recipes.md) covers editing, failed saves, date editing and progress compositions. Copy a complete example before adapting it, then run `npm run typecheck` and `npm run build` in this app.
|
|
18
18
|
- [Local data](node_modules/@satinhq/kit/dist/docs/data.md), [networking](node_modules/@satinhq/kit/dist/docs/networking.md), [messaging scroll](node_modules/@satinhq/kit/dist/docs/messaging-scroll.md) and [geometry tokens](node_modules/@satinhq/kit/dist/docs/tokens.md) describe the supported compositions and their limits. For a growing message composer, follow the messaging guide’s bottom `SafeAreaInset` + `TextEditor minLines/maxLines` recipe; do not add keyboard-height padding or a hidden draft mirror.
|
|
19
19
|
|
|
@@ -73,87 +73,87 @@ createServer((request, response) => {
|
|
|
73
73
|
<!-- framework-api:start -->
|
|
74
74
|
Generated from the same reviewed metadata as the shipped Satin API reference. Links open the exact package declarations; related type-only exports are listed in that reference.
|
|
75
75
|
|
|
76
|
-
|
|
|
76
|
+
| Satin exports and declarations | Behavior and ownership | Limits |
|
|
77
77
|
| --- | --- | --- |
|
|
78
|
-
|
|
|
79
|
-
|
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
99
|
-
|
|
|
100
|
-
|
|
|
101
|
-
|
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
|
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
|
113
|
-
|
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
|
|
|
131
|
-
|
|
|
132
|
-
|
|
|
133
|
-
|
|
|
134
|
-
|
|
|
135
|
-
|
|
|
136
|
-
|
|
|
137
|
-
|
|
|
138
|
-
|
|
|
139
|
-
|
|
|
140
|
-
|
|
|
141
|
-
|
|
|
142
|
-
|
|
|
143
|
-
|
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
147
|
-
|
|
|
148
|
-
|
|
|
149
|
-
|
|
|
150
|
-
|
|
|
151
|
-
|
|
|
152
|
-
|
|
|
153
|
-
|
|
|
154
|
-
|
|
|
155
|
-
|
|
|
156
|
-
|
|
|
78
|
+
| [`Overlay`](node_modules/@satinhq/kit/dist/safe-area/Overlay.d.ts) | Layer content over a view without changing its frame. Overlay content respects the enclosing SafeAreaInset and follows the composer on its existing keyboard carrier. | Bottom composer geometry shares the existing inset store. This is the view-content overload; shape-style overlay is not implemented. |
|
|
79
|
+
| [`ProgressView`](node_modules/@satinhq/kit/dist/controls/ProgressView.d.ts) | Choose linear, circular or automatic through progressViewStyle. iOS circular uses the shared activity indicator even with a value; indeterminate linear draws an empty track. | Automatic preserves the value-dependent defaults. Circular progress uses the shared activity indicator; indeterminate linear progress draws an empty track. |
|
|
80
|
+
| [`GeometryReader`](node_modules/@satinhq/kit/dist/content/layout.d.ts) | Report allocated size through a render-prop proxy; frame reads current viewport or element-relative coordinates. | CSS needs a definite proposal on scrolling axes. Native safeAreaInsets and transformed proposal semantics are unsupported. |
|
|
81
|
+
| [`ViewThatFits`](node_modules/@satinhq/kit/dist/content/layout.d.ts) | Select the first child whose CSS ideal size fits the constrained axes, or the last child when none fits. | Give vertical proposals a definite height. Candidates remain mounted; hidden candidates are inert and pause framework tasks and activity indicators. Arbitrary app effects remain active. Selection uses CSS ideal sizes and retains each candidate; hidden children do not unmount. |
|
|
82
|
+
| [`useScaledMetric`](node_modules/@satinhq/kit/dist/content/scaledMetric.d.ts) | Scale a finite dimension relative to a WebKit system text style and the measured default system text size. | System font probes are shared per subscribed style and use the same font definitions as Text. largeTitle and callout use fixed-size fallbacks because WebKit lacks their system font keywords. |
|
|
83
|
+
| [`Text`](node_modules/@satinhq/kit/dist/content/content.d.ts), [`VStack`](node_modules/@satinhq/kit/dist/content/content.d.ts), [`HStack`](node_modules/@satinhq/kit/dist/content/content.d.ts), [`ZStack`](node_modules/@satinhq/kit/dist/content/content.d.ts), [`Spacer`](node_modules/@satinhq/kit/dist/content/content.d.ts), [`Divider`](node_modules/@satinhq/kit/dist/content/content.d.ts) | Compose content with system text styles, semantic colors, padding and frame props. Plain React and HTML remain supported. | Default spacing and frame proposal differences are documented in content.md. No arbitrary modifier ordering. |
|
|
84
|
+
| [`LazyVStack`](node_modules/@satinhq/kit/dist/content/content.d.ts), [`LazyHStack`](node_modules/@satinhq/kit/dist/content/content.d.ts), [`LazyVGrid`](node_modules/@satinhq/kit/dist/content/content.d.ts), [`LazyHGrid`](node_modules/@satinhq/kit/dist/content/content.d.ts), [`GridItem`](node_modules/@satinhq/kit/dist/content/content.d.ts) | Stable eager layouts propose track widths with per-track spacing and alignment. Import these layouts and their types from @satinhq/kit. Use List for long data. | Eager rendering without virtualization. Mixed adaptive tracks and Grid/GridRow are deferred. |
|
|
85
|
+
| [`useTask`](node_modules/@satinhq/kit/dist/tasks/useTask.d.ts) | Run cancellable appearance work; an id change or returned runner replaces the current run. Pass the AbortSignal to fetch and publish through commit. | Cancellation is cooperative. Arbitrary setters outside commit cannot be intercepted. Native lifecycle has been measured; this is foreground work, not a Web Worker or background scheduler. |
|
|
86
|
+
| [`List`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`ScrollView`](node_modules/@satinhq/kit/dist/public/scroll.d.ts) | Await a refreshable action on a vertical scroll surface. | The refresh indicator holds a 60-point content inset while the action runs. Its activity animation is shared with ProgressView. |
|
|
87
|
+
| [`defineApp`](node_modules/@satinhq/kit/dist/public/definition.d.ts), [`runApp`](node_modules/@satinhq/kit/dist/public/runtime.d.ts), [`defineNavigation`](node_modules/@satinhq/kit/dist/public/structure.d.ts) | Declare install metadata and primary navigation, then mount through runApp once. | One app root and the Home Screen WebKit target. No native multi-window Scene builder. |
|
|
88
|
+
| [`preferredColorScheme`](node_modules/@satinhq/kit/dist/app/appearance.d.ts), [`PreferredColorScheme`](node_modules/@satinhq/kit/dist/app/appearanceStore.d.ts), [`runApp`](node_modules/@satinhq/kit/dist/public/runtime.d.ts), [`useColorScheme`](node_modules/@satinhq/kit/dist/public/environment.d.ts) | Set the document scene to light, dark or system through the shared appearance store; runApp accepts an initial preferredColorScheme option. | System or null clears the override. Persist and reapply the choice with useAppStorage. Whole-scene scope including presentations; no per-view or independent sheet preference. |
|
|
89
|
+
| [`NavigationStack`](node_modules/@satinhq/kit/dist/public/runtime.d.ts), [`defineRoutes`](node_modules/@satinhq/kit/dist/public/routes.d.ts), [`route`](node_modules/@satinhq/kit/dist/public/routes.d.ts), [`param`](node_modules/@satinhq/kit/dist/push/schema.d.ts), [`useNavigation`](node_modules/@satinhq/kit/dist/public/runtime.d.ts), [`NavigationLink`](node_modules/@satinhq/kit/dist/public/controls.d.ts) | Declare typed destinations and use the framework in-memory navigation stack. | No browser-history router. Route parameters must satisfy the declared schema. |
|
|
90
|
+
| [`TabView`](node_modules/@satinhq/kit/dist/public/runtime.d.ts), [`Tab`](node_modules/@satinhq/kit/dist/public/runtime.d.ts) | Retain independent declared tab stacks and restore the selected tab. Optional Tab and TabSection children compose every declared ID once. | Only declared tab styles are supported; no desktop browser support. |
|
|
91
|
+
| [`TabSection`](node_modules/@satinhq/kit/dist/tabs/TabSection.d.ts) | Group declared Tab destinations under collapsible sidebar headers. tabPlacement=sidebarOnly excludes group members from floating and compact bars while retaining their stack identities. | Only explicit sidebarOnly placement is supported; automatic section representation in the top bar, tab customization and section header actions are unavailable. Section expansion is retained for this mounted TabView. With no available sidebar, a sidebar-only selection presents the first available primary tab. |
|
|
92
|
+
| [`Screen`](node_modules/@satinhq/kit/dist/public/Screen.d.ts) | Set the retained entry title and titleDisplay through Screen. An automatic untitled root omits its bar unless toolbar or back controls need it. | Only the options in ScreenProps exist. Use only the props documented in the declaration. |
|
|
93
|
+
| [`ToolbarItem`](node_modules/@satinhq/kit/dist/public/toolbar.d.ts), [`ToolbarItemGroup`](node_modules/@satinhq/kit/dist/public/toolbar.d.ts), [`ToolbarSpacer`](node_modules/@satinhq/kit/dist/public/toolbar.d.ts) | Declare toolbar content through Screen. subtitle replaces inline subtitle content without growing the bar; largeTitle and largeSubtitle replace intrinsically sized expanded rows that scroll away. | Toolbar items use the available capsule and principal placements. Use the declared ToolbarItem props for grouping and sizing. |
|
|
94
|
+
| [`List`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`Form`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`Section`](node_modules/@satinhq/kit/dist/list-form/ListForm.d.ts), [`ListRow`](node_modules/@satinhq/kit/dist/list-form/ListForm.d.ts) | Own vertical scrolling, grouped or plain rows and section headers and footers. | ListRow siblings compose within one row. Use separate ListRow elements for separate rows. |
|
|
95
|
+
| [`List`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`Form`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`ListProps`](node_modules/@satinhq/kit/dist/public/controls.d.ts) | Choose default or compact section spacing, or specify a finite nonnegative gap in points. Hide the scroll surface background while retaining row fills. | Compact spacing uses inset-grouped allocations. Numeric gaps change the margin between sections while retaining header/footer allocations. visible retains style and presentation defaults; it does not force an opaque sheet. |
|
|
96
|
+
| [`ListRow`](node_modules/@satinhq/kit/dist/list-form/ListForm.d.ts) | Set per-row insets, background and separators through ListRowProps. | Framework geometry ownership still applies. No raw viewport or safe-area CSS. |
|
|
97
|
+
| [`ForEach`](node_modules/@satinhq/kit/dist/list-form/editing.d.ts), [`ListRow`](node_modules/@satinhq/kit/dist/list-form/ListForm.d.ts) | Identify rows by id. onDelete adds swipe-to-delete and the edit-mode delete control; onMove adds the reorder handle and drag. Both receive offsets into the declared row sequence. | ForEach must sit directly in a List or Section. Selected-group moves, two-finger selection and VoiceOver move actions are not implemented. |
|
|
98
|
+
| [`moving`](node_modules/@satinhq/kit/dist/list-form/offsets.d.ts), [`removing`](node_modules/@satinhq/kit/dist/list-form/offsets.d.ts) | Apply ForEach onMove and onDelete offsets to the data: moving(items, { fromOffsets, toOffset }) and removing(items, offsets) return a new array. | Returns a new array. Store the result with setState to update the rendered rows. |
|
|
99
|
+
| [`List`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`EditButton`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`useEditMode`](node_modules/@satinhq/kit/dist/list-form/editing.d.ts), [`ListRow`](node_modules/@satinhq/kit/dist/list-form/ListForm.d.ts) | Select one optional id or a Set of ids; EditButton toggles the screen edit mode, showing selection circles for a Set. | Selection identity comes from ForEach ids (no tag). Edit mode is per screen; there is no environment override binding. Plain rows outside edit mode are not keyboard-focusable for selection. |
|
|
100
|
+
| [`ScrollView`](node_modules/@satinhq/kit/dist/public/scroll.d.ts), [`ScrollTarget`](node_modules/@satinhq/kit/dist/scroll/ScrollTarget.d.ts) | Own a named scroll region, vertical by default, and address declared targets through its handle or position binding. Standalone views own mount-local scroll state without navigation chrome or scene restoration. | Supported anchoring is in ScrollViewProps, including defaultScrollAnchor and maintainVisibleContentPosition. Only the declared scroll options are supported. |
|
|
101
|
+
| [`SafeAreaInset`](node_modules/@satinhq/kit/dist/safe-area/SafeAreaInset.d.ts), [`useSafeAreaInsets`](node_modules/@satinhq/kit/dist/public/environment.d.ts) | Place an accessory on any edge with SafeAreaInset; it joins the one inset chain with the bar, the tab bar, bottom bars and the keyboard. A top accessory sits below the bar (or the large title) and its root background reaches the screen top. | A top inset under a large title stays at the expanded title edge while the title collapses. On an installed iPhone the status band is a flat WebKit fill (top-edge-limitation.md). |
|
|
102
|
+
| [`SafeAreaPadding`](node_modules/@satinhq/kit/dist/safe-area/modifiers.d.ts) | Grow the safe area of the content below: scroll views inset their content, Lists lay out their cards inside the padded width, other content is padded. | Bottom padding on a scroll view is a trailing spacer in its content. Nested padding adds up as chained modifiers do. |
|
|
103
|
+
| [`ContentMargins`](node_modules/@satinhq/kit/dist/safe-area/modifiers.d.ts) | Margin the content of every scroll view below; a List takes a horizontal margin as its layout margin. | placement scrollIndicators has no effect: Satin draws the indicator in the screen frame. |
|
|
104
|
+
| [`SafeAreaBar`](node_modules/@satinhq/kit/dist/safe-area/modifiers.d.ts) | A top or bottom safeAreaInset with no spacing and its own scroll edge blur. | The bar material is a CSS backdrop blur, not the navigation bar edge effect; it does not extend the navigation bar edge or its seam. |
|
|
105
|
+
| [`IgnoresSafeArea`](node_modules/@satinhq/kit/dist/safe-area/modifiers.d.ts), [`ScrollView`](node_modules/@satinhq/kit/dist/public/scroll.d.ts) | Wrap any view: one at the top safe edge draws from the screen top and keeps its layout slot; a primary scroll view inside runs under the bars; the keyboard region keeps a bottom SafeAreaInset above the home indicator. | Only a view that starts the screen content extends upward. The bottom edge of non-scroll content is not extended. |
|
|
106
|
+
| [`Button`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`Pressable`](node_modules/@satinhq/kit/dist/press/Pressable.d.ts), [`ControlStyleProvider`](node_modules/@satinhq/kit/dist/public/controlStyle.d.ts) | Use onPress and framework control styles, size and inherited disabled state. buttonBorderShape selects automatic, capsule or a fixed roundedRectangle radius through the shared material shape. | Native style names apply only to the supported styles. Circle and container-concentric button borders are not exposed; plain and List-row buttons have no painted border. Custom ButtonStyle.makeBody controls the visual content; Satin retains button interaction and accessibility. |
|
|
107
|
+
| [`Label`](node_modules/@satinhq/kit/dist/public/Label.d.ts), [`LabeledContent`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`RowLabel`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`RowIcon`](node_modules/@satinhq/kit/dist/list-form/ListForm.d.ts) | Compose accessible titles, symbols and values with framework row and label styles. Automatic leading List Label symbols inherit app or control tint; explicit symbol colors remain authored. | Custom labels must obey the public noninteractive label contract. |
|
|
108
|
+
| [`Toggle`](node_modules/@satinhq/kit/dist/public/controls.d.ts) | Edit a controlled boolean through a framework switch or supported toggle style. | This does not provide every platform ToggleStyle. |
|
|
109
|
+
| [`Picker`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`Choice`](node_modules/@satinhq/kit/dist/list-form/ListForm.d.ts) | Select controlled options using menu, navigationLink, inline or segmented style. | Supported option values and styles come from PickerProps. |
|
|
110
|
+
| [`Stepper`](node_modules/@satinhq/kit/dist/public/controls.d.ts) | Increment or decrement a controlled value within declared bounds. | Use a controlled numeric value and the declared Stepper props. |
|
|
111
|
+
| [`Slider`](node_modules/@satinhq/kit/dist/public/controls.d.ts) | Drag a controlled value within min...max (default 0...1), continuous or snapped to step, with optional tick marks; the held thumb lifts into the glass control lens. | No minimum/maximum value labels or custom tick content; label is accessibility-only. Only the thumb takes a drag. |
|
|
112
|
+
| [`TextField`](node_modules/@satinhq/kit/dist/public/controls.d.ts) | Edit controlled text with prompt, keyboard intent and automatic row placement; vertical axis uses the shared editor with lineLimit. | Plain styling uses textFieldStyle="plain". The style prop accepts inline CSS. WebKit owns the system keyboard; arbitrary native text layout is not exposed. |
|
|
113
|
+
| [`SecureField`](node_modules/@satinhq/kit/dist/public/controls.d.ts) | Edit controlled password text through secure system input. | No access to system password-manager internals. |
|
|
114
|
+
| [`TextEditor`](node_modules/@satinhq/kit/dist/public/controls.d.ts) | Edit controlled multiline text with framework keyboard geometry. | Only TextEditorProps apply; no arbitrary native text-layout engine. |
|
|
115
|
+
| [`useFocusChain`](node_modules/@satinhq/kit/dist/text-input/focusChain.d.ts) | Register and traverse named text-input focus targets with the framework focus chain. | Focus registration uses framework hooks; custom keyboard replacement is unsupported. |
|
|
116
|
+
| [`Sheet`](node_modules/@satinhq/kit/dist/public/presentation.d.ts) | Bind sheet visibility and use supported detents and modal navigation. Supplying selection requires onSelectionChange; omitting selection keeps the detent uncontrolled. | Visibility starts closed after relaunch. Persist editor drafts separately, never presentation flags. |
|
|
117
|
+
| [`FullScreenCover`](node_modules/@satinhq/kit/dist/public/presentation.d.ts), [`useDismiss`](node_modules/@satinhq/kit/dist/presentation/dismiss.d.ts) | Bind cover visibility; useDismiss pops a pushed screen or dismisses the enclosing presentation. | No interactive dismissal on covers. Visibility starts closed after relaunch. |
|
|
118
|
+
| [`Alert`](node_modules/@satinhq/kit/dist/presentation/Presentation.d.ts), [`ConfirmationDialog`](node_modules/@satinhq/kit/dist/presentation/Presentation.d.ts) | Bind framework-owned presentations and declare shared ActionItem actions. Alert text fields use prompt with value/onChange. | Cold launch closes legacy restored flags. Destructive confirmations must start closed. |
|
|
119
|
+
| [`Menu`](node_modules/@satinhq/kit/dist/public/actions.d.ts), [`ContextMenu`](node_modules/@satinhq/kit/dist/actions/RowActions.d.ts), [`Action`](node_modules/@satinhq/kit/dist/actions/types.d.ts) | Use one shared action contract for menus and supported list row interactions. | Native VoiceOver Actions rotor entries are unavailable; accessible named actions exist. |
|
|
120
|
+
| [`Image`](node_modules/@satinhq/kit/dist/image/Image.d.ts), [`AsyncImage`](node_modules/@satinhq/kit/dist/image/Image.d.ts) | Render packaged or remote artwork with framework-owned geometry, placeholders and failed-content handling. AsyncImage publishes empty, success and failure phases through onPhaseChange. | Remote loading is not a native URLSession cache. The phase callback reports loading state; it does not build alternate content. No Photos library authorization API. |
|
|
121
|
+
| [`SymbolImage`](node_modules/@satinhq/kit/dist/symbols/Symbol.d.ts), [`SymbolProvider`](node_modules/@satinhq/kit/dist/symbols/Symbol.d.ts) | Resolve a named catalogue glyph or provider glyph with supported weight, scale and rendering mode. | The bundled catalogue uses Framework7 Icons 5.0.5 (MIT) plus Satin-drawn clean-room additions, not Apple SF Symbols assets. Preserve copyright and license notices. Provider glyphs need their own provenance. Only shipped or registered names exist. |
|
|
122
|
+
| [`Glass`](node_modules/@satinhq/kit/dist/public/glassValue.d.ts), [`GlassEffect`](node_modules/@satinhq/kit/dist/public/glass.d.ts), [`GlassEffectContainer`](node_modules/@satinhq/kit/dist/glass/GlassEffect.d.ts) | Use the shared WebGPU glass material and grouped region contract. | Low-level field/outline helpers compute geometry, not a general view modifier. Released apps use blur-and-tint fallback material for unrecoverable WebGPU failures unless strict glass is requested; development builds report the failure. |
|
|
123
|
+
| [`useScenePhase`](node_modules/@satinhq/kit/dist/public/environment.d.ts), [`useScreenLifecycle`](node_modules/@satinhq/kit/dist/navigation/navigationContext.d.ts) | Read app foreground state and retained screen lifecycle through framework hooks. | Browser execution can stop when suspended. Screen lifecycle is distinct from app foreground state. |
|
|
124
|
+
| [`useSceneStorage`](node_modules/@satinhq/kit/dist/public/environment.d.ts) | Checkpoint an entry-scoped JSON-serializable draft; repeated pushes have independent state. Nullable transitions are supported when allowed by the TypeScript type; runtime validation checks serializability only. | Not presentation visibility. Checkpoints cannot guarantee recovery after storage eviction or every process crash. |
|
|
125
|
+
| [`useAppStorage`](node_modules/@satinhq/kit/dist/public/environment.d.ts) | Persist a small app preference across relaunches. | Origin-local WebKit storage, not UserDefaults or an iCloud key-value store. |
|
|
126
|
+
| [`useColorScheme`](node_modules/@satinhq/kit/dist/public/environment.d.ts), [`useHorizontalSizeClass`](node_modules/@satinhq/kit/dist/public/environment.d.ts), [`useVerticalSizeClass`](node_modules/@satinhq/kit/dist/public/environment.d.ts), [`systemColor`](node_modules/@satinhq/kit/dist/public/colors.d.ts), [`semanticColor`](node_modules/@satinhq/kit/dist/public/colors.d.ts) | Read accepted appearance and adaptive size classes. systemColor resolves the 18 UIKit system colors; semanticColor resolves document content, fill, background, separator and tint roles, including body portals. | Values follow measured normal-contrast iOS 27 traits. Increased contrast and Display P3 are not supported. Semantic label colors and composited secondary/tertiary foreground can differ. |
|
|
127
|
+
| [`SensoryButton`](node_modules/@satinhq/kit/dist/haptics/SensoryButton.d.ts) | SensoryButton selection uses browser native switch-label activation where available. | Only selection and false are accepted. Other feedback kinds are unsupported. Keyboard/assistive activation do not promise a native tick. |
|
|
128
|
+
| [`collection`](node_modules/@satinhq/kit/dist/data/database.d.ts), [`defineDatabase`](node_modules/@satinhq/kit/dist/data/database.d.ts), [`newId`](node_modules/@satinhq/kit/dist/data/database.d.ts), [`useQuery`](node_modules/@satinhq/kit/dist/data/database.d.ts), [`useRecord`](node_modules/@satinhq/kit/dist/data/database.d.ts), [`Query`](node_modules/@satinhq/kit/dist/data/database.d.ts), [`storageQuota`](node_modules/@satinhq/kit/dist/public/storage.d.ts) | Use the reactive local database, schema declarations and explicit durability promises. | This is IndexedDB, not SwiftData, Core Data or CloudKit. Storage may be evicted; writes can fail. |
|
|
129
|
+
| [`MediaPlayer`](node_modules/@satinhq/kit/dist/media/types.d.ts), [`useMediaPlayer`](node_modules/@satinhq/kit/dist/media/react.d.ts) | Control an app-root media queue and its exposed playback snapshot. | Audio transport only; no VideoPlayer, AVKit or background audio entitlement. Playback depends on WebKit codec support and the server delivering compatible media with byte-range support. |
|
|
130
|
+
| [`useNotifications`](node_modules/@satinhq/kit/dist/public/environment.d.ts), [`NotificationPermissionExplainer`](node_modules/@satinhq/kit/dist/public/environment.d.ts) | Request permission from a gesture and use the supported push and badge contract. | Installed Home Screen permission is required. Local scheduled notification delivery is unavailable; use an app-owned authenticated server scheduler. |
|
|
131
|
+
| [`useUnsavedChanges`](node_modules/@satinhq/kit/dist/root/runtimeContext.d.ts) | Register unsaved work with the framework navigation and update guard. | This is a framework guard, not a general native interactiveDismissDisabled guarantee. |
|
|
132
|
+
| [`useAppUpdate`](node_modules/@satinhq/kit/dist/public/environment.d.ts) | Read the completed update outcome after app launch readiness. defineApp advanced.updateProfile preview admits iOS Safari tabs and live updates. | Preview may reload on update. Release remains the installed production default. |
|
|
133
|
+
| [`useReachability`](node_modules/@satinhq/kit/dist/reachability/react.d.ts) | Read framework network and configured server reachability. | No native Network framework path monitor or guarantee that a request will succeed. |
|
|
134
|
+
| [`Selectable`](node_modules/@satinhq/kit/dist/root/SatinRoot.d.ts), [`Zoomable`](node_modules/@satinhq/kit/dist/zoom/Zoomable.d.ts) | Declare text selection or an owned zoomable content region. | Page zoom remains disabled by the installed shell; general-purpose gesture composition is unsupported. |
|
|
135
|
+
| [`ContentUnavailableView`](node_modules/@satinhq/kit/dist/public/controls.d.ts) | Compose an unavailable-content title, symbol, optional description and actions. Required offline routes use this view. | Supports the explicit title, icon, description and actions composition; no automatic search variant. |
|
|
136
|
+
| [`NavigationSplitView`](node_modules/@satinhq/kit/dist/public/runtime.d.ts) | Render the declared primary sidebar root and retained detail stack; compact width collapses to a stack. | Select an existing declared tab; modal and ad hoc root props are not supported. |
|
|
137
|
+
| [`Screen`](node_modules/@satinhq/kit/dist/public/Screen.d.ts), [`List`](node_modules/@satinhq/kit/dist/public/controls.d.ts), [`Searchable`](node_modules/@satinhq/kit/dist/search/searchable.d.ts), [`SearchScopes`](node_modules/@satinhq/kit/dist/search/searchable.d.ts), [`SearchSuggestion`](node_modules/@satinhq/kit/dist/search/searchable.d.ts), [`SearchFieldPlacement`](node_modules/@satinhq/kit/dist/search/searchable.d.ts) | Pass searchable={{ text, onChange, prompt, placement, scopes, suggestions, onSubmit }} to Screen or List. placement automatic (default) uses platform placement: on iPhone the bottom toolbar when the screen has no other bottom bar items, else the navigation bar drawer; iPad and scoped fields use the drawer. The drawer owns the field, clear and close buttons, scope bar, suggestions and collapse on scroll; the bottom field rides above the keyboard with a close button while presented. isPresented/onPresentedChange mirror isPresented:. | Bottom toolbar presentation is not animated yet and its scope bar is not drawn (scoped fields stay in the drawer). The search tab bottom field is not drawn; a declared tab role="search" is metadata. Never hand-build a search bar. |
|
|
138
|
+
| [`DefaultToolbarItem`](node_modules/@satinhq/kit/dist/public/toolbar.d.ts) | Place <DefaultToolbarItem kind="search" placement="bottomBar" /> in a Screen toolbar to put its searchable field in the bottom bar beside other bottom items (Messages: search, ToolbarSpacer, compose). | Only kind search. Without a ToolbarSpacer the neighbouring item is not merged into the search capsule as natively; iPad keeps the drawer. |
|
|
139
|
+
| [`DatePicker`](node_modules/@satinhq/kit/dist/controls/DatePicker.d.ts) | Compact (automatic) style: grey value capsules open the system date or time picker. selection is a Date, or a civil string with no time zone (YYYY-MM-DD, HH:mm, YYYY-MM-DDTHH:mm) for days that must not move across time zones. displayedComponents and in (lowerBound/upperBound, clamped like UIDatePicker). | graphical and wheel styles are unsupported. The open picker is the system UIDatePicker but WebKit adds Reset and Done buttons, centres it rather than anchoring it under the capsule, and does not grey out days outside the range (choices are clamped). See controls.md. |
|
|
140
|
+
| [`ColorPicker`](node_modules/@satinhq/kit/dist/controls/ColorPicker.d.ts) | A row with the native colour well; tapping it opens the system colour picker (grid, spectrum, sliders, eyedropper, saved colours). supportsOpacity shows its opacity slider. selection is #RRGGBB or #RRGGBBAA. | The system picker is titled "Colors" instead of the label. Output is sRGB hex; Display P3 choices are converted to sRGB. See controls.md. |
|
|
141
|
+
| [`ProgressView`](node_modules/@satinhq/kit/dist/controls/ProgressView.d.ts) | Render labeled indeterminate activity or clamped determinate linear progress with inherited tint and accessible progress values. | Shares the activity animation used by the refresh indicator. See controls.md. |
|
|
142
|
+
| [`PhotosPicker`](node_modules/@satinhq/kit/dist/public/filePickers.d.ts), [`PhotosPickerProps`](node_modules/@satinhq/kit/dist/public/filePickers.d.ts), [`FileImporter`](node_modules/@satinhq/kit/dist/public/filePickers.d.ts), [`FileImporterProps`](node_modules/@satinhq/kit/dist/public/filePickers.d.ts) | Use the system file chooser to receive photo or document bytes. Cancel preserves accepted selection; observed owner changes reject stale delivery. | FileImporter uses React component spelling. MIME hints are not content validation. No PhotosPickerItem identity, persistent file access or exact overlapping chooser attribution. Installed acceptance remains pending. |
|
|
143
|
+
| [`ScrollView`](node_modules/@satinhq/kit/dist/public/scroll.d.ts), [`ScrollEdgeEffectStyle`](node_modules/@satinhq/kit/dist/scroll/edgePolicy.d.ts), [`ScrollEdgeEffectHidden`](node_modules/@satinhq/kit/dist/scroll/edgePolicy.d.ts), [`ScrollEdgeSelection`](node_modules/@satinhq/kit/dist/scroll/edgePolicy.d.ts) | Select soft/automatic top material and edge-specific visibility through ScrollView props. Boolean visibility selects the top edge. | Hard top material throws an unsupported error. The navigation engine renders only the top edge; selecting other edges creates no material. |
|
|
144
|
+
| [`Screen`](node_modules/@satinhq/kit/dist/public/Screen.d.ts), [`ToolbarMinimizationBehavior`](node_modules/@satinhq/kit/dist/navigation/toolbarMinimization.d.ts), [`ToolbarMinimizationRestoration`](node_modules/@satinhq/kit/dist/navigation/toolbarMinimization.d.ts), [`ToolbarMinimizationSafeAreaAdjustment`](node_modules/@satinhq/kit/dist/navigation/toolbarMinimization.d.ts) | Opt into navigation-bar minimization on scroll down/up, reversal or atScrollEdge restoration, and automatic/enabled/disabled safe-area adjustment through Screen or route options. | Opt-in navigation-bar minimization. Use never to keep the bar expanded. |
|
|
145
|
+
| [`TabView`](node_modules/@satinhq/kit/dist/public/runtime.d.ts) | Render bottomAccessory content in the retained TabView bottom inset slot. TabView supplies capsule glass by default; set bottomAccessoryMaterial="custom" when the app draws its own material. | A tab can declare role="search" in defineNavigation. No minimizeBehavior or public useBottomAccessoryPlacement contract exists at this revision. The native collapse/inline morph remains incomplete. |
|
|
146
|
+
| [`ShareLink`](node_modules/@satinhq/kit/dist/public/deviceActions.d.ts), [`ShareLinkProps`](node_modules/@satinhq/kit/dist/public/deviceActions.d.ts) | Share prepared text, URLs or files through the system share sheet during activation; check file sharing support before handing off. | No Transferable or file-provider integration. Completion is platform handoff, not recipient delivery; AbortError also covers no suitable target. Installed acceptance remains pending. |
|
|
147
|
+
| [`PasteButton`](node_modules/@satinhq/kit/dist/public/deviceActions.d.ts), [`PasteButtonProps`](node_modules/@satinhq/kit/dist/public/deviceActions.d.ts) | Read plain text during the user press, with browser permission UI and owner-scoped asynchronous delivery. | No clipboard preflight, arbitrary Transferable content, or reliable distinction between dismissal and denial. WebKit can require an additional Paste confirmation. Installed acceptance remains pending. |
|
|
148
|
+
| [`useNamespace`](node_modules/@satinhq/kit/dist/motion/matchedGeometry.d.ts) | Wrap one element with an id and a namespace. In a withAnimation change, a view whose id is removed and re-inserted moves from the old frame to the new one while the pair cross-fades; a matched view that moves animates from its presented frame; an unpaired one fades. Motion is transform and opacity on the compositor; the removed view stays on screen as its own decoded node until the fade ends. | Frame matching only (properties .frame, anchor .center). Corner radius scales with the frame during flight rather than remaining fixed in points. A non-source view does not follow its source outside an animation. Removed glass presenters do not travel. |
|
|
149
|
+
| [`MatchedTransitionSource`](node_modules/@satinhq/kit/dist/public/navigationTransition.d.ts), [`NavigationTransition`](node_modules/@satinhq/kit/dist/public/navigationTransition.d.ts), [`defineNamespace`](node_modules/@satinhq/kit/dist/motion/matchedGeometry.d.ts) | Mark the view a push starts from with MatchedTransitionSource (id, namespace) and give the pushed Screen navigationTransition={NavigationTransition.zoom({ sourceID, in })}. The screen grows out of the source on push and shrinks back into it on Back, on the edge back swipe and on a downward drag (scrolled to top); the screen behind dims and recedes. Motion is fitted to an iOS 27 stock native fixture (centre and size springs, tile cross-fade, dim, corner radius, drag geometry) and runs as compositor transforms; only the corner radius is a main-thread value. defineNamespace() shares a namespace between routes. When multiple visible sources share an ID, a user activation selects that copy for both push and return; if it disappears, navigation falls back to the ordinary transition instead of choosing another copy. | Pushed screens only: FullScreenCover and Sheet zooms are not available. The source must be on screen in the covered screen, otherwise the push slides. Downward dismissal accepts initial travel within about 26.6 degrees of vertical. Zoom glass uses the projected navigation route atlas. |
|
|
150
|
+
| [`withAnimation`](node_modules/@satinhq/kit/dist/motion/matchedGeometry.d.ts), [`Animation`](node_modules/@satinhq/kit/dist/motion/animationValue.d.ts), [`SpringOptions`](node_modules/@satinhq/kit/dist/motion/animationValue.d.ts) | Stable Satin exports apply synchronous state changes from an event handler, return the callback result and propagate errors. Keyed ForEach rows in List animate reorders; experimental MatchedGeometryEffect views also participate. Animation provides opaque default, smooth, snappy, bouncy and spring({ durationMs, bounce }) values. Existing unstable imports remain compatible. | Other state and style changes do not animate. Use ForEach identities for keyed List animation. No null animation, easing curves, repeatCount, delay, completion or per-update nested timing. Use one outer synchronous update. Negative bounces are not offered. |
|
|
151
|
+
| [`useBuildInfo`](node_modules/@satinhq/kit/dist/app/buildInfo.d.ts), [`BuildInfo`](node_modules/@satinhq/kit/dist/app/buildInfo.d.ts) | Read the framework version, unique app build identifier and build time embedded in the running app bundle, including offline launches. | The app build ID is not a git revision or service-worker cache hash. Builds that bypass satinApp report unavailable metadata. Server fetch receipts are separate evidence, not proof of which cached bundle is running. |
|
|
152
|
+
| [`Link`](node_modules/@satinhq/kit/dist/web/openURL.d.ts), [`useOpenURL`](node_modules/@satinhq/kit/dist/web/openURL.d.ts), [`WebView`](node_modules/@satinhq/kit/dist/web/WebView.d.ts), [`useWebFrame`](node_modules/@satinhq/kit/dist/web/WebView.d.ts) | Open registered app URLs through in-memory navigation, request an auxiliary web page, or embed an explicitly permissioned frame. | External browser selection is unavailable. Web dispatch is not page completion. Cross-origin or denied frames report status unverified; reload and stop require same-origin access. |
|
|
153
|
+
| [`defineWebAuthentication`](node_modules/@satinhq/kit/dist/web/authentication.d.ts), [`useWebAuthentication`](node_modules/@satinhq/kit/dist/web/useWebAuthentication.d.ts) | Prepare a durable authorization-code transaction with PKCE, dispatch popup or redirect from a gesture, and reconcile its callback on return. | Requires secure context, local storage, Web Locks, dedicated uncached callback and server exchange. Bridge reads require a private transaction proof. Token and OpenID Connect validation belong to the server. No native-session or background-completion guarantee. |
|
|
154
|
+
| [`cornerClipPath`](node_modules/@satinhq/kit/dist/shapes/corners.d.ts) | Return a CSS clip path for explicit width and height, with continuous or circular rounded corners, a capsule, or an ellipse. Swipe action configurations accept the same shape choices for their revealed row face. | The caller owns sizing outside framework rows. This helper does not change a glass renderer mask. Continuous path coordinates use the measured iOS 27 corner profile. |
|
|
155
|
+
| [`useGlassErrors`](node_modules/@satinhq/kit/dist/public/environment.d.ts) | Inspect scoped installation failures, appearance receipts and glass errors using the existing framework diagnostics. | Diagnostic receipts are not native fidelity or installed acceptance evidence. |
|
|
156
|
+
| [`useKeyboardMetrics`](node_modules/@satinhq/kit/dist/public/keyboard.d.ts) | Read the framework keyboard adapter metrics for supported editing integration. | No native keyboard-frame API or permission to add an independent keyboard lifecycle. |
|
|
157
157
|
<!-- framework-api:end -->
|
|
158
158
|
|
|
159
159
|
Use `Sheet` for short independent edits, `Alert` for a brief message or text entry, and `ConfirmationDialog` for destructive choices. Each uses `isPresented` and `onPresentedChange`. Give actions stable ids and explicit cancel/destructive roles. Pass the trigger ref as `anchor` for an iPad confirmation. Only the destructive action may write data; handle rejected writes before reporting success. `no-browser-dialog` forbids browser alert, confirm and prompt. See the application recipes for a complete confirmation and failed-save example.
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Build a personal React app for the installed iPhone or iPad Home Screen runtime. This public beta targets iOS 27. For the shortest path from the published package, follow the [Quick start](https://github.com/satinhq/satin/blob/main/docs/learn/quick-start.md). This guide is the full reference: start with the local package instructions below, then read [current limitations](https://github.com/satinhq/satin/blob/main/docs/limitations.md) for supported behavior and platform constraints.
|
|
4
4
|
|
|
5
|
+
Satin's APIs follow the declarative style people already use to build iPhone and iPad apps. If you've used SwiftUI, Jetpack Compose or Flutter, it will feel familiar.
|
|
6
|
+
|
|
5
7
|
## Create an app from this checkout
|
|
6
8
|
|
|
7
9
|
Use Node 22.12 or later in the 22.x series, or Node 24 or later, and pnpm 10. The following commands pack the preview and its scaffolder locally. Other app dependencies still need registry access. Run the first block at the repository root:
|
|
@@ -10,8 +12,8 @@ Use Node 22.12 or later in the 22.x series, or Node 24 or later, and pnpm 10. Th
|
|
|
10
12
|
pnpm install --frozen-lockfile
|
|
11
13
|
PREVIEW_DIR="$(mktemp -d "${TMPDIR:-/tmp}/satin-preview.XXXXXX")"
|
|
12
14
|
mkdir -p "$PREVIEW_DIR/packages" "$PREVIEW_DIR/scaffolder"
|
|
13
|
-
KIT_ARCHIVE="$(node -p "const { name, version } = require('./packages/
|
|
14
|
-
CREATE_ARCHIVE="$(node -p "const { name, version } = require('./packages/create-
|
|
15
|
+
KIT_ARCHIVE="$(node -p "const { name, version } = require('./packages/kit/package.json'); name.replace(/^@/, '').replaceAll('/', '-') + '-' + version + '.tgz'")"
|
|
16
|
+
CREATE_ARCHIVE="$(node -p "const { name, version } = require('./packages/create-satin/package.json'); name.replace(/^@/, '').replaceAll('/', '-') + '-' + version + '.tgz'")"
|
|
15
17
|
pnpm --filter @satinhq/kit pack --pack-destination "$PREVIEW_DIR/packages"
|
|
16
18
|
pnpm --filter create-satin pack --pack-destination "$PREVIEW_DIR/packages"
|
|
17
19
|
tar -xzf "$PREVIEW_DIR/packages/$CREATE_ARCHIVE" -C "$PREVIEW_DIR/scaffolder"
|
|
@@ -124,13 +126,13 @@ For a built Safari-tab preview, add `updateProfile: 'preview'` to the generated
|
|
|
124
126
|
|
|
125
127
|
Import app APIs from `@satinhq/kit`, build integration from `@satinhq/kit/vite`, and load `@satinhq/kit/styles.css` once. `@satinhq/kit/internal` is for framework development; app lint rejects it. `@satinhq/kit/testing` belongs in tests. `@satinhq/kit/unstable` contains experimental compatibility APIs; consult its generated export inventory before use.
|
|
126
128
|
|
|
127
|
-
The generated [API reference](https://github.com/satinhq/satin/blob/main/packages/
|
|
129
|
+
The generated [API reference](https://github.com/satinhq/satin/blob/main/packages/kit/api/reference.md) describes supported exports and behavior. Its declaration links resolve inside the installed package. See the [package guide](https://github.com/satinhq/satin/blob/main/packages/kit/README.md) for examples. A planned feature does not imply that a React prop exists.
|
|
128
130
|
|
|
129
131
|
Use `NavigationLink` for a destination, `Button` for an action, `LabeledContent` for a value, and `RowLabel` for composed text. Use `Picker pickerStyle="segmented"` for segmented selection. Public fields and Alert's embedded field use `prompt`.
|
|
130
132
|
|
|
131
133
|
Let the app definition own install metadata and launch backgrounds. Keep the generated status style; components consume framework geometry rather than raw viewport units or safe-area CSS. Satin uses the system font. Do not add font files or recreate missing framework controls in app CSS.
|
|
132
134
|
|
|
133
|
-
Continue with [application recipes](https://github.com/satinhq/satin/blob/main/docs/app-recipes.md), [safe local data and backup restore](https://github.com/satinhq/satin/blob/main/docs/data.md), [geometry and theme tokens](https://github.com/satinhq/satin/blob/main/docs/tokens.md), [networking](https://github.com/satinhq/satin/blob/main/docs/networking.md) and [push sender setup](https://github.com/satinhq/satin/blob/main/packages/
|
|
135
|
+
Continue with [application recipes](https://github.com/satinhq/satin/blob/main/docs/app-recipes.md), [safe local data and backup restore](https://github.com/satinhq/satin/blob/main/docs/data.md), [geometry and theme tokens](https://github.com/satinhq/satin/blob/main/docs/tokens.md), [networking](https://github.com/satinhq/satin/blob/main/docs/networking.md) and [push sender setup](https://github.com/satinhq/satin/blob/main/packages/push/README.md). The [push relay](https://github.com/satinhq/satin/blob/main/packages/push/README.md) sends immediately; your backend owns reminder scheduling. DatePicker, ColorPicker and ProgressView are available with [documented styles and constraints](https://github.com/satinhq/satin/blob/main/docs/controls.md). Photo/file acquisition has no public chooser at this revision. Read the current limitations before depending on these capabilities.
|
|
134
136
|
|
|
135
137
|
## Screen content and controls
|
|
136
138
|
|