@satinhq/kit 0.1.0-beta.2 → 0.1.0-beta.4
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/NOTICE +2 -2
- package/README.md +2 -3
- package/dist/acknowledgements/inventory.json +5 -5
- package/dist/actions/RowActions.d.ts +4 -4
- package/dist/actions/RowActions.js +93 -27
- package/dist/actions/fullSwipeContact.d.ts +73 -0
- package/dist/actions/fullSwipeContact.js +186 -0
- package/dist/actions/rowScrub.d.ts +7 -4
- package/dist/actions/rowScrub.js +39 -37
- package/dist/actions/types.d.ts +13 -7
- package/dist/app/InstallComponents.d.ts +4 -7
- package/dist/app/InstallComponents.js +7 -7
- package/dist/app/InstallationDiagnostics.d.ts +2 -1
- package/dist/app/InstallationDiagnostics.js +2 -1
- package/dist/app/appearance.d.ts +5 -3
- package/dist/app/appearance.js +5 -3
- package/dist/app/appearanceStore.d.ts +3 -2
- package/dist/app/buildInfo.d.ts +4 -4
- package/dist/app/buildInfo.js +2 -2
- package/dist/app/definition.d.ts +11 -3
- package/dist/app/definition.js +2 -0
- package/dist/app/head.d.ts +2 -1
- package/dist/app/head.js +13 -16
- package/dist/app/inlineCSP.d.ts +6 -0
- package/dist/app/inlineCSP.js +25 -0
- package/dist/app/install.d.ts +1 -0
- package/dist/app/install.js +5 -2
- package/dist/app/installCheck.js +32 -86
- package/dist/app/installContext.d.ts +10 -5
- package/dist/app/installContext.js +2 -0
- package/dist/app/installCustom.js +1 -0
- package/dist/app/installExperience.js +0 -60
- package/dist/app/installationFailure.d.ts +3 -2
- package/dist/app/installationFailure.js +1 -1
- package/dist/app/launchScreen.d.ts +6 -2
- package/dist/app/launchScreen.js +104 -1
- package/dist/app/launchScreenRuntime.d.ts +31 -4
- package/dist/app/launchScreenRuntime.js +150 -22
- package/dist/app/launchWatchdog.js +25 -65
- package/dist/app/platformScripts.js +11 -0
- package/dist/app/styles.d.ts +3 -0
- package/dist/app/styles.js +42 -0
- package/dist/app/viewportValue.d.ts +2 -1
- package/dist/app/vite.d.ts +4 -0
- package/dist/app/vite.js +22 -24
- package/dist/content/content.d.ts +35 -30
- package/dist/content/content.js +19 -16
- package/dist/content/layout.d.ts +10 -2
- package/dist/content/layout.js +4 -2
- package/dist/content/scaledMetric.d.ts +2 -1
- package/dist/content/scaledMetric.js +2 -1
- package/dist/controls/ColorPicker.d.ts +2 -4
- package/dist/controls/ColorPicker.js +2 -4
- package/dist/controls/DatePicker.d.ts +4 -4
- package/dist/controls/DatePicker.js +2 -2
- package/dist/controls/ProgressView.d.ts +4 -4
- package/dist/controls/ProgressView.js +1 -2
- package/dist/controls/civilDate.d.ts +1 -1
- package/dist/controls/civilDate.js +1 -1
- package/dist/data/database.d.ts +9 -8
- package/dist/data/database.js +4 -4
- package/dist/docs/components/file-importer.md +1 -1
- package/dist/docs/components/paste-button.md +1 -1
- package/dist/docs/components/photos-picker.md +1 -1
- package/dist/docs/components/share-link.md +1 -1
- package/dist/docs/limitations.md +1 -1
- package/dist/docs/push.md +3 -3
- package/dist/docs/reference.md +1888 -0
- package/dist/docs/tailwind.md +76 -0
- package/dist/docs/tokens.md +1 -1
- package/dist/gestures/GestureView.d.ts +3 -1
- package/dist/gestures/GestureView.js +2 -1
- package/dist/gestures/gesture.d.ts +22 -2
- package/dist/gestures/gesture.js +7 -2
- package/dist/glass/GlassEffect.d.ts +2 -1
- package/dist/glass/GlassEffect.js +2 -1
- package/dist/glass/GlassPresentation.d.ts +1 -0
- package/dist/glass/GlassPresentation.js +21 -4
- package/dist/glass/TabBar.js +23 -1
- package/dist/glass/errorAlert.js +2 -1
- package/dist/glass/errors.d.ts +3 -1
- package/dist/glass/fallback/runtime.d.ts +1 -0
- package/dist/glass/fallback/runtime.js +8 -1
- package/dist/glass/lens/controlLift.d.ts +1 -1
- package/dist/glass/lens/controlLift.js +1 -1
- package/dist/glass/lens/interactivePress.d.ts +2 -2
- package/dist/glass/lens/interactivePress.js +2 -2
- package/dist/glass/lens/menu-opening-native-fits.json +1 -1
- package/dist/glass/lens/menuContextFit.json +1 -1
- package/dist/glass/lens/menuDropFit.json +1 -1
- package/dist/glass/lens/menuField.d.ts +2 -2
- package/dist/glass/lens/menuField.js +3 -3
- package/dist/glass/lens/menuGlyphDropFit.json +1 -1
- package/dist/glass/lens/menuMorphFit.json +1 -1
- package/dist/glass/lens/menuMorphPhoneFit.json +1 -1
- package/dist/glass/lens/tabAccessoryMotion.d.ts +1 -1
- package/dist/glass/lens/tabSearchMember.d.ts +1 -1
- package/dist/glass/lens/tabSearchMember.js +1 -1
- package/dist/glass/liquidContext.d.ts +2 -0
- package/dist/glass/menuPresenter.d.ts +2 -0
- package/dist/glass/menuPresenter.js +1 -1
- package/dist/glass/regions.d.ts +3 -2
- package/dist/glass/regions.js +1 -1
- package/dist/glass/renderSpecs.d.ts +1 -0
- package/dist/glass/renderSpecs.js +1 -0
- package/dist/glass/shapeTrack.d.ts +1 -1
- package/dist/glass/submenuMotion.d.ts +1 -1
- package/dist/glass/submenuMotion.js +1 -1
- package/dist/glass/webgpu/controlRim.d.ts +29 -0
- package/dist/glass/webgpu/controlRim.js +68 -0
- package/dist/glass/webgpu/entry.worker.js +3 -6
- package/dist/glass/webgpu/frameClock.d.ts +6 -2
- package/dist/glass/webgpu/frameClock.js +9 -2
- package/dist/glass/webgpu/frameProbe.d.ts +1 -1
- package/dist/glass/webgpu/frameProbe.js +3 -3
- package/dist/glass/webgpu/passes.d.ts +2 -2
- package/dist/glass/webgpu/production.d.ts +1 -0
- package/dist/glass/webgpu/production.js +31 -1
- package/dist/glass/webgpu/raster.d.ts +18 -0
- package/dist/glass/webgpu/raster.js +105 -15
- package/dist/glass/webgpu/rasterMaterial.d.ts +4 -0
- package/dist/glass/webgpu/rasterMaterial.js +17 -1
- package/dist/glass/webgpu/rasterUniforms.js +9 -0
- package/dist/glass/webgpu/regionScene.d.ts +4 -1
- package/dist/glass/webgpu/regionScene.js +30 -1
- package/dist/glass/webgpu/renderer.js +23 -7
- package/dist/glass/webgpu/shaders.d.ts +2 -2
- package/dist/glass/webgpu/shaders.js +5 -1
- package/dist/haptics/SensoryButton.d.ts +4 -4
- package/dist/haptics/SensoryButton.js +3 -3
- package/dist/image/Image.d.ts +6 -3
- package/dist/image/Image.js +4 -3
- package/dist/image/asset.d.ts +2 -1
- package/dist/keyboard/adapter.d.ts +3 -4
- package/dist/keyboard/adapter.js +2 -2
- package/dist/keyboard/avoidance.d.ts +1 -1
- package/dist/keyboard/avoidance.js +1 -1
- package/dist/keyboard/geometry.d.ts +1 -1
- package/dist/keyboard/motion.d.ts +1 -1
- package/dist/keyboard/motion.js +1 -1
- package/dist/list-form/ListForm.d.ts +10 -9
- package/dist/list-form/ListForm.js +3 -3
- package/dist/list-form/ListItem.js +1 -1
- package/dist/list-form/RowLabel.d.ts +1 -1
- package/dist/list-form/RowLabel.js +1 -1
- package/dist/list-form/Slider.js +1 -1
- package/dist/list-form/editMotion.js +1 -1
- package/dist/list-form/editing.d.ts +10 -11
- package/dist/list-form/editing.js +5 -6
- package/dist/list-form/offsets.d.ts +2 -2
- package/dist/list-form/offsets.js +2 -2
- package/dist/media/react.d.ts +2 -1
- package/dist/media/react.js +2 -1
- package/dist/media/types.d.ts +6 -3
- package/dist/motion/TransitionView.d.ts +4 -2
- package/dist/motion/TransitionView.js +3 -2
- package/dist/motion/animationValue.d.ts +2 -2
- package/dist/motion/animationValue.js +9 -10
- package/dist/motion/matchedGeometry.d.ts +10 -9
- package/dist/motion/matchedGeometry.js +9 -9
- package/dist/motion/springTrack.d.ts +1 -2
- package/dist/motion/springTrack.js +10 -5
- package/dist/motion/transition.d.ts +4 -1
- package/dist/motion/transition.js +2 -0
- package/dist/navigation/DetailList.d.ts +1 -1
- package/dist/navigation/DetailList.js +1 -1
- package/dist/navigation/ScreenContainer.js +1 -1
- package/dist/navigation/Sidebar.d.ts +3 -1
- package/dist/navigation/Sidebar.js +1 -1
- package/dist/navigation/SidebarSymbol.d.ts +2 -1
- package/dist/navigation/SidebarSymbol.js +2 -1
- package/dist/navigation/chromeCurves.js +1 -1
- package/dist/navigation/navigationContext.d.ts +2 -1
- package/dist/navigation/navigationContext.js +2 -1
- package/dist/navigation/splitContext.d.ts +2 -1
- package/dist/navigation/splitContext.js +2 -1
- package/dist/navigation/toolbarMinimization.d.ts +4 -3
- package/dist/navigation/types.d.ts +8 -6
- package/dist/navigation/zoomGeometry.js +1 -1
- package/dist/navigation/zoomMotion.d.ts +1 -1
- package/dist/navigation/zoomMotion.js +2 -2
- package/dist/navigation/zoomTransition.js +3 -4
- package/dist/presentation/Presentation.d.ts +10 -9
- package/dist/presentation/Presentation.js +4 -3
- package/dist/presentation/model.d.ts +2 -1
- package/dist/presentation/presentationSource.js +1 -1
- package/dist/press/Pressable.d.ts +5 -1
- package/dist/press/Pressable.js +2 -0
- package/dist/press/stateMachine.d.ts +1 -1
- package/dist/public/Label.d.ts +2 -1
- package/dist/public/Label.js +2 -1
- package/dist/public/Screen.d.ts +4 -6
- package/dist/public/actions.d.ts +2 -1
- package/dist/public/actions.js +2 -1
- package/dist/public/buttonBorderShape.d.ts +2 -1
- package/dist/public/colors.d.ts +7 -4
- package/dist/public/colors.js +3 -2
- package/dist/public/controlStyle.d.ts +17 -14
- package/dist/public/controls.d.ts +29 -28
- package/dist/public/controls.js +25 -24
- package/dist/public/deviceActions.d.ts +6 -4
- package/dist/public/deviceActions.js +4 -2
- package/dist/public/environment.d.ts +16 -13
- package/dist/public/environment.js +11 -9
- package/dist/public/filePickers.d.ts +6 -4
- package/dist/public/filePickers.js +3 -2
- package/dist/public/glass.d.ts +8 -6
- package/dist/public/glass.js +2 -2
- package/dist/public/glassValue.d.ts +3 -4
- package/dist/public/glassValue.js +3 -4
- package/dist/public/keyboard.d.ts +4 -1
- package/dist/public/keyboard.js +2 -1
- package/dist/public/navigationTransition.d.ts +6 -6
- package/dist/public/navigationTransition.js +3 -3
- package/dist/public/presentation.d.ts +8 -7
- package/dist/public/presentation.js +5 -5
- package/dist/public/runtime.d.ts +9 -8
- package/dist/public/runtime.js +7 -7
- package/dist/public/scroll.d.ts +6 -3
- package/dist/public/scroll.js +3 -1
- package/dist/public/structure.d.ts +2 -2
- package/dist/public/toolbar.d.ts +15 -11
- package/dist/public/toolbar.js +13 -8
- package/dist/reachability/model.d.ts +4 -3
- package/dist/reachability/react.d.ts +4 -1
- package/dist/reachability/react.js +2 -1
- package/dist/root/SatinRoot.d.ts +3 -3
- package/dist/root/SatinRoot.js +12 -36
- package/dist/root/mountSatin.d.ts +1 -1
- package/dist/root/mountSatin.js +26 -35
- package/dist/root/runtimeContext.d.ts +2 -1
- package/dist/root/runtimeContext.js +2 -1
- package/dist/safe-area/Overlay.d.ts +3 -2
- package/dist/safe-area/Overlay.js +2 -1
- package/dist/safe-area/SafeAreaInset.d.ts +11 -7
- package/dist/safe-area/SafeAreaInset.js +10 -9
- package/dist/safe-area/context.d.ts +3 -3
- package/dist/safe-area/context.js +1 -1
- package/dist/safe-area/displayCorners.d.ts +4 -2
- package/dist/safe-area/displayCorners.js +4 -2
- package/dist/safe-area/modifiers.d.ts +14 -10
- package/dist/safe-area/modifiers.js +10 -6
- package/dist/safe-area/useSafeAreaMetrics.js +2 -2
- package/dist/scroll/ScrollSurface.d.ts +5 -5
- package/dist/scroll/ScrollSurface.js +6 -2
- package/dist/scroll/ScrollTarget.d.ts +1 -1
- package/dist/scroll/ScrollTarget.js +1 -1
- package/dist/scroll/edgePolicy.d.ts +2 -2
- package/dist/scroll/position.d.ts +5 -3
- package/dist/scroll/position.js +1 -1
- package/dist/scroll/screenGeometry.d.ts +1 -1
- package/dist/scroll/screenGeometry.js +1 -1
- package/dist/scroll/types.d.ts +1 -1
- package/dist/search/PadSearchDrawer.d.ts +7 -0
- package/dist/search/PadSearchDrawer.js +8 -0
- package/dist/search/PadSearchPresentationContext.d.ts +6 -0
- package/dist/search/PadSearchPresentationContext.js +4 -0
- package/dist/search/SearchDrawer.d.ts +1 -1
- package/dist/search/SearchDrawer.js +7 -2
- package/dist/search/SearchSuggestionsPopover.d.ts +6 -0
- package/dist/search/SearchSuggestionsPopover.js +42 -0
- package/dist/search/SearchToolbarField.d.ts +2 -1
- package/dist/search/SearchToolbarField.js +28 -7
- package/dist/search/padSearchBarMotion.d.ts +69 -0
- package/dist/search/padSearchBarMotion.js +73 -0
- package/dist/search/padSearchFieldSamples.json +491 -0
- package/dist/search/searchMotion.d.ts +1 -1
- package/dist/search/searchMotion.js +1 -1
- package/dist/search/searchPlacement.d.ts +3 -0
- package/dist/search/searchPlacement.js +7 -0
- package/dist/search/searchable.d.ts +14 -12
- package/dist/search/usePadSearchFieldMotion.d.ts +4 -0
- package/dist/search/usePadSearchFieldMotion.js +100 -0
- package/dist/search/useSearchPresentation.d.ts +2 -1
- package/dist/search/useSearchPresentation.js +24 -6
- package/dist/server.d.ts +4 -4
- package/dist/server.js +4 -4
- package/dist/shapes/corners.d.ts +3 -3
- package/dist/shapes/corners.js +2 -3
- package/dist/styles.css +8302 -8236
- package/dist/sw/vite.d.ts +4 -0
- package/dist/sw/vite.js +2 -0
- package/dist/symbols/Symbol.d.ts +7 -5
- package/dist/symbols/Symbol.js +5 -3
- package/dist/symbols/catalogue.d.ts +1 -1
- package/dist/symbols/types.d.ts +6 -4
- package/dist/tabs/TabSection.d.ts +3 -2
- package/dist/tabs/TabSection.js +2 -1
- package/dist/tabs/TabView.js +54 -51
- package/dist/tasks/useTask.d.ts +5 -4
- package/dist/tasks/useTask.js +4 -3
- package/dist/testing.d.ts +3 -2
- package/dist/testing.js +3 -2
- package/dist/text-input/TextEditor.js +7 -3
- package/dist/text-input/focusChain.d.ts +4 -3
- package/dist/text-input/focusChain.js +3 -2
- package/dist/text-input/kinds.d.ts +1 -1
- package/dist/web/WebView.d.ts +10 -3
- package/dist/web/WebView.js +3 -2
- package/dist/web/authentication.d.ts +12 -1
- package/dist/web/authentication.js +2 -1
- package/dist/web/openURL.d.ts +10 -4
- package/dist/web/openURL.js +4 -2
- package/dist/web/useWebAuthentication.d.ts +2 -1
- package/dist/web/useWebAuthentication.js +2 -1
- package/dist/zoom/Zoomable.d.ts +3 -3
- package/dist/zoom/Zoomable.js +2 -2
- package/package.json +4 -4
- package/dist/docs/swiftui-reference.md +0 -1895
package/dist/sw/vite.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Plugin } from 'vite';
|
|
2
|
+
/** Options for the service worker build plugin: extra files to precache, public routes, legacy
|
|
3
|
+
* cache names and diagnostic headers. */
|
|
2
4
|
export interface SatinAppShellPluginOptions {
|
|
3
5
|
readonly mediaProbe?: string;
|
|
4
6
|
readonly shellFile?: string;
|
|
@@ -12,6 +14,8 @@ export interface SatinAppShellPluginOptions {
|
|
|
12
14
|
/** Explicit diagnostic build only; production serves cached responses unchanged. */
|
|
13
15
|
readonly diagnosticTimingHeaders?: boolean;
|
|
14
16
|
}
|
|
17
|
+
/** The Vite build plugin that generates the app's service worker and precache list. `satinApp`
|
|
18
|
+
* includes it; use it directly only in Satin tooling. */
|
|
15
19
|
export declare function satinAppShell(options?: SatinAppShellPluginOptions): Plugin;
|
|
16
20
|
export { satinApp, satinAppFixtures, type SatinAppOptions } from '../app/vite.js';
|
|
17
21
|
export { defineApp } from '../public/definition.js';
|
package/dist/sw/vite.js
CHANGED
|
@@ -2,6 +2,8 @@ import { copyFile, mkdir } from 'node:fs/promises';
|
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import { APP_SHELL_VERSION_FILE } from './protocol.js';
|
|
4
4
|
import { generateAppShell } from './generator.js';
|
|
5
|
+
/** The Vite build plugin that generates the app's service worker and precache list. `satinApp`
|
|
6
|
+
* includes it; use it directly only in Satin tooling. */
|
|
5
7
|
export function satinAppShell(options = {}) {
|
|
6
8
|
let config;
|
|
7
9
|
let outputWritten = false;
|
package/dist/symbols/Symbol.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { type ReactNode, type SVGProps } from 'react';
|
|
2
2
|
import { type CoreSymbolName } from './catalogue.js';
|
|
3
3
|
import type { SymbolGlyph, SymbolSource, SymbolWeight, SymbolScale, SymbolRenderingMode } from './types.js';
|
|
4
|
-
/** A symbol name
|
|
5
|
-
*
|
|
4
|
+
/** A symbol name, such as `'plus'` or `'trash.fill'`. The bundled names autocomplete; any string
|
|
5
|
+
* is accepted for glyphs added through `SymbolProvider`. */
|
|
6
6
|
export type SymbolName = CoreSymbolName | (string & {});
|
|
7
7
|
export declare const SymbolSelectionContext: import("react").Context<boolean>;
|
|
8
|
-
/**
|
|
8
|
+
/** Adds or replaces symbol glyphs for everything inside it. Paths must be original, or
|
|
9
|
+
* redistributable with their provenance recorded. */
|
|
9
10
|
export declare function SymbolProvider({ glyphs, children, }: {
|
|
10
11
|
glyphs: SymbolSource;
|
|
11
12
|
children: ReactNode;
|
|
@@ -24,8 +25,9 @@ export type SymbolImageProps = Omit<SVGProps<SVGSVGElement>, 'name' | 'children'
|
|
|
24
25
|
glyph?: SymbolGlyph;
|
|
25
26
|
};
|
|
26
27
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
28
|
+
* Draws a named vector symbol that sizes with the surrounding font and takes its colour. A
|
|
29
|
+
* `.fill` variant is chosen automatically where the context calls for it, such as a selected
|
|
30
|
+
* tab.
|
|
29
31
|
*
|
|
30
32
|
* @example
|
|
31
33
|
* <SymbolImage name="star.fill" />
|
package/dist/symbols/Symbol.js
CHANGED
|
@@ -6,7 +6,8 @@ import { symbolGeometry, symbolNormalization, symbolNormalizationTransform, symb
|
|
|
6
6
|
import { useInheritedSymbolWeight } from './inheritedWeight.js';
|
|
7
7
|
const SourceContext = createContext(coreSymbols);
|
|
8
8
|
export const SymbolSelectionContext = createContext(false);
|
|
9
|
-
/**
|
|
9
|
+
/** Adds or replaces symbol glyphs for everything inside it. Paths must be original, or
|
|
10
|
+
* redistributable with their provenance recorded. */
|
|
10
11
|
export function SymbolProvider({ glyphs, children, }) {
|
|
11
12
|
const inherited = useContext(SourceContext);
|
|
12
13
|
return _jsx(SourceContext, { value: { ...inherited, ...glyphs }, children: children });
|
|
@@ -20,8 +21,9 @@ export function resolveSymbol(source, name, selected = false) {
|
|
|
20
21
|
return Object.hasOwn(source, name) ? source[name] : undefined;
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
24
|
+
* Draws a named vector symbol that sizes with the surrounding font and takes its colour. A
|
|
25
|
+
* `.fill` variant is chosen automatically where the context calls for it, such as a selected
|
|
26
|
+
* tab.
|
|
25
27
|
*
|
|
26
28
|
* @example
|
|
27
29
|
* <SymbolImage name="star.fill" />
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { SymbolGlyph } from './types.js';
|
|
2
|
-
/**
|
|
2
|
+
/** Every symbol name in the bundled catalogue. */
|
|
3
3
|
export type CoreSymbolName = "pin" | "pin.fill" | "pin.slash" | "pin.slash.fill" | "star" | "star.fill" | "house" | "house.fill" | "bell" | "bell.fill" | "person" | "person.fill" | "calendar" | "clock" | "clock.fill" | "trash" | "trash.fill" | "heart" | "heart.fill" | "folder" | "folder.fill" | "pencil" | "checkmark" | "checkmark.circle" | "checkmark.circle.fill" | "xmark" | "xmark.circle" | "xmark.circle.fill" | "info.circle" | "info.circle.fill" | "ellipsis" | "ellipsis.circle" | "ellipsis.circle.fill" | "plus" | "minus" | "chevron.left" | "chevron.right" | "chevron.up" | "chevron.down" | "circle" | "circle.fill" | "chart.bar" | "chart.bar.fill" | "photo" | "photo.fill" | "envelope" | "envelope.fill" | "bookmark" | "bookmark.fill" | "timer" | "timer.fill" | "stopwatch" | "stopwatch.fill" | "book" | "book.fill" | "doc.text" | "doc.text.fill" | "rectangle.stack" | "rectangle.stack.fill" | "slider.horizontal.3" | "square.and.arrow.up" | "square.and.arrow.up.fill" | "square.and.pencil" | "square.and.pencil.fill" | "gearshape" | "gearshape.fill" | "magnifyingglass" | "sidebar.left" | "arrowshape.turn.up.left" | "arrowshape.turn.up.left.fill" | "chevron.up.chevron.down" | "questionmark.square" | "questionmark.square.fill" | "play" | "play.fill" | "pause" | "pause.fill" | "arrow.clockwise" | "bolt" | "bolt.fill" | "flag" | "flag.fill" | "tray" | "tray.fill" | "cart" | "cart.fill" | "list.bullet" | "person.crop.circle" | "person.crop.circle.fill" | "dot.radiowaves.left.right" | "square.grid.2x2" | "square.grid.2x2.fill" | "battery.100" | "camera" | "camera.fill" | "car" | "device.phone.portrait" | "globe" | "keyboard" | "lock" | "lock.fill" | "moon" | "moon.fill" | "hand.raised" | "hand.raised.fill" | "sparkles" | "textformat" | "hourglass" | "arrow.up" | "arrow.down" | "arrow.down.circle" | "arrow.down.circle.fill" | "stop" | "stop.fill" | "doc.on.doc" | "doc.on.doc.fill" | "face.smiling" | "face.smiling.fill" | "bell.slash" | "bell.slash.fill" | "envelope.open" | "envelope.open.fill" | "envelope.badge" | "envelope.badge.fill" | "hand.thumbsup" | "hand.thumbsup.fill" | "hand.thumbsdown" | "hand.thumbsdown.fill" | "line.3.horizontal" | "line.3.horizontal.decrease" | "photo.on.rectangle" | "square.stack" | "square.stack.fill" | "forward" | "forward.fill" | "backward" | "backward.fill" | "shuffle" | "repeat" | "repeat.1" | "music.note" | "music.note.list" | "music.mic" | "music.house" | "music.house.fill" | "speaker" | "speaker.fill" | "speaker.wave.3" | "speaker.wave.3.fill" | "quote.bubble" | "quote.bubble.fill" | "tv.music.note" | "tv.music.note.fill" | "waveform" | "play.circle" | "play.circle.fill" | "play.rectangle" | "play.rectangle.fill" | "plus.circle" | "plus.circle.fill" | "checkmark.square" | "checkmark.square.fill" | "heart.slash" | "heart.slash.fill" | "flag.slash" | "flag.slash.fill" | "person.2" | "person.2.fill" | "arrowshape.turn.up.right" | "arrowshape.turn.up.right.fill" | "bubble.left.and.bubble.right" | "bubble.left.and.bubble.right.fill" | "text.insert" | "text.append" | "text.badge.plus" | "viewfinder" | "sun.max" | "sun.max.fill" | "gift" | "gift.fill" | "airplane" | "pawprint" | "briefcase" | "briefcase.fill" | "list.number" | "dot.radiowaves.left.and.right" | "exclamationmark.triangle" | "exclamationmark.triangle.fill" | "arrow.right" | "arrow.left" | "square.and.arrow.down" | "square.and.arrow.down.fill" | "gear" | "link" | "arrow.counterclockwise" | "arrow.uturn.backward" | "arrow.uturn.forward" | "archivebox" | "archivebox.fill" | "line.3.horizontal.decrease.circle" | "line.3.horizontal.decrease.circle.fill" | "questionmark.circle" | "questionmark.circle.fill" | "arrow.up.arrow.down" | "tag" | "tag.fill" | "paperplane" | "paperplane.fill" | "flame" | "flame.fill" | "location" | "location.fill" | "doc" | "doc.fill" | "mappin" | "mappin.and.ellipse" | "arrow.up.right" | "at" | "drop" | "drop.fill" | "headphones" | "bed.double" | "bed.double.fill" | "pause.circle" | "pause.circle.fill" | "display" | "dollarsign.circle" | "dollarsign.circle.fill" | "checkmark.seal" | "checkmark.seal.fill" | "tray.full" | "tray.full.fill" | "person.badge.plus" | "person.badge.plus.fill" | "folder.badge.plus" | "arrow.2.squarepath" | "dumbbell" | "figure.run" | "leaf" | "clock.arrow.circlepath" | "receipt" | "airplayaudio" | "bell.badge.fill" | "bell.badge" | "bicycle" | "book.closed.fill" | "book.closed" | "brain.head.profile" | "calendar.badge.clock" | "chart.line.uptrend.xyaxis" | "checklist" | "cross.case.fill" | "cross.case" | "cup.and.saucer.fill" | "cup.and.saucer" | "dumbbell.fill" | "exclamationmark.2" | "eye.fill" | "eye.slash.fill" | "eye.slash" | "eye" | "fork.knife" | "graduationcap.fill" | "graduationcap" | "key.fill" | "key" | "leaf.fill" | "list.bullet.clipboard.fill" | "list.bullet.clipboard" | "note.text.fill" | "note.text" | "pill.fill" | "pill" | "receipt.fill" | "scalemass.fill" | "scalemass" | "server.rack.fill" | "server.rack";
|
|
4
4
|
export declare const coreSymbols: Readonly<Record<CoreSymbolName, SymbolGlyph>>;
|
package/dist/symbols/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FontWeight } from '../content/content.js';
|
|
2
|
-
/**
|
|
2
|
+
/** A symbol's artwork: filled SVG paths on a 56-unit grid, with optional layers for hierarchical
|
|
3
|
+
* and palette rendering, and its provenance. No font, HTML or external resource. */
|
|
3
4
|
export type SymbolGlyph = Readonly<{
|
|
4
5
|
paths: readonly Readonly<{
|
|
5
6
|
d: string;
|
|
@@ -22,9 +23,10 @@ export type SymbolGlyph = Readonly<{
|
|
|
22
23
|
}>;
|
|
23
24
|
/** Glyphs by symbol name, for `SymbolProvider`. */
|
|
24
25
|
export type SymbolSource = Readonly<Record<string, SymbolGlyph>>;
|
|
25
|
-
/**
|
|
26
|
+
/** The weight a symbol is drawn at. It uses the same names as font weights. */
|
|
26
27
|
export type SymbolWeight = FontWeight;
|
|
27
|
-
/** `
|
|
28
|
+
/** A symbol's size relative to the text around it: `small`, `medium` or `large`. */
|
|
28
29
|
export type SymbolScale = 'small' | 'medium' | 'large';
|
|
29
|
-
/** `
|
|
30
|
+
/** How a symbol's layers are coloured: `monochrome` in one colour, `hierarchical` in shades of
|
|
31
|
+
* one colour, or `palette` with a colour per layer. */
|
|
30
32
|
export type SymbolRenderingMode = 'monochrome' | 'hierarchical' | 'palette';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
-
/**
|
|
2
|
+
/** A sidebar group's title, optional id and placement, and its `Tab` children. */
|
|
3
3
|
export type TabSectionProps = Readonly<{
|
|
4
4
|
title: string;
|
|
5
5
|
/** Stable section identity when titles change or two sections have the same title. */
|
|
@@ -8,5 +8,6 @@ export type TabSectionProps = Readonly<{
|
|
|
8
8
|
tabPlacement?: 'sidebarOnly';
|
|
9
9
|
children: ReactNode;
|
|
10
10
|
}>;
|
|
11
|
-
/**
|
|
11
|
+
/** Groups `Tab`s under a collapsible header in the `TabView` sidebar. It adds no navigator of its
|
|
12
|
+
* own. */
|
|
12
13
|
export declare function TabSection({ children }: TabSectionProps): ReactNode;
|
package/dist/tabs/TabSection.js
CHANGED
package/dist/tabs/TabView.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PadSearchPresentationContext, PadSearchTabContext, } from '../search/PadSearchPresentationContext.js';
|
|
2
3
|
import { TabSidebarSurface } from './TabSidebarSurface.js';
|
|
3
4
|
import { ScrollSurface } from '../scroll/ScrollSurface.js';
|
|
4
5
|
import { TabSection } from './TabSection.js';
|
|
@@ -53,6 +54,8 @@ function RetainedTab({ active, presented, id, children, register, focusOnActivat
|
|
|
53
54
|
}
|
|
54
55
|
/** Lazy, retained tabs. Hidden app effects remain app-owned; Satin work pauses. */
|
|
55
56
|
export function TabView({ children, selection, defaultSelection, onSelectionChange, bottomAccessory, bottomAccessoryMaterial = 'glass', tabViewStyle = 'automatic', }) {
|
|
57
|
+
const [searchOwner, setSearchOwner] = useState(null);
|
|
58
|
+
const searchPresentation = useMemo(() => ({ owner: searchOwner, setOwner: setSearchOwner }), [searchOwner]);
|
|
56
59
|
const layout = useLayoutClass();
|
|
57
60
|
const { metrics } = useSatinLayoutRuntime();
|
|
58
61
|
const canShowSidebar = tabViewStyle === 'sidebarAdaptable' &&
|
|
@@ -204,55 +207,55 @@ export function TabView({ children, selection, defaultSelection, onSelectionChan
|
|
|
204
207
|
if (overlaySidebar)
|
|
205
208
|
changeSidebar(false);
|
|
206
209
|
}, children: [item.role === 'search' ? (_jsx(SymbolImage, { name: "magnifyingglass" })) : item.symbol ? (_jsx(SymbolImage, { name: item.symbol })) : (item.icon), _jsx("span", { children: item.label })] }, item.id));
|
|
207
|
-
return (_jsxs("div", { ref: container, "data-satin-tab-view": "true", "data-satin-tab-sidebar-expanded": showSidebar || undefined, "data-satin-tab-sidebar-overlay": overlaySidebar || undefined, "data-satin-tab-sidebar-collapsed-overlay": didCollapseOverlay || undefined, "data-satin-tab-sidebar-expanded-from-tabs": (showSidebar && !overlaySidebar && expandedFromTabs) || undefined, style: didCollapseOverlay
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
210
|
+
return (_jsx(PadSearchPresentationContext, { value: searchPresentation, children: _jsxs("div", { ref: container, "data-satin-tab-view": "true", "data-satin-tab-sidebar-expanded": showSidebar || undefined, "data-satin-tab-sidebar-overlay": overlaySidebar || undefined, "data-satin-tab-sidebar-collapsed-overlay": didCollapseOverlay || undefined, "data-satin-tab-sidebar-expanded-from-tabs": (showSidebar && !overlaySidebar && expandedFromTabs) || undefined, style: didCollapseOverlay
|
|
211
|
+
? {
|
|
212
|
+
'--satin-tab-sidebar-return-inset': `${metrics.physicalInsets.top}px`,
|
|
213
|
+
}
|
|
214
|
+
: undefined, children: [showSidebar && (_jsxs(TabSidebarSurface, { overlay: overlaySidebar, onDismiss: () => changeSidebar(false), children: [_jsx("div", { "data-satin-tab-sidebar-toggle-host": "true", children: _jsx(GlassButton, { "data-satin-tab-sidebar-hide": "true", iconOnly: true, "aria-label": "Hide Tab Sidebar", onPress: () => changeSidebar(false), children: _jsx(SymbolImage, { name: "tab-sidebar-collapse", glyph: tabSidebarCollapseGlyph, width: 25.3, height: 25.3 }) }) }), _jsxs(ScrollSurface, { id: `${scopeId}-sidebar-scroll`, primary: false, role: "tablist", "aria-orientation": "vertical", onKeyDown: handleTabKeyDown, children: [sidebarItems
|
|
215
|
+
.filter(item => item.role === 'search' || !grouped.has(item.id))
|
|
216
|
+
.map(sidebarRow), sections.map(section => {
|
|
217
|
+
const expanded = !collapsedSections.has(section.id);
|
|
218
|
+
const groupId = `${scopeId}-section-${encodeURIComponent(section.id)}`;
|
|
219
|
+
return (_jsxs("div", { "data-satin-tab-section": "true", children: [_jsxs(Pressable, { "aria-label": section.title, "aria-expanded": expanded, "aria-controls": groupId, "data-satin-tab-section-header": "true", onPress: () => setCollapsedSections(previous => {
|
|
220
|
+
const next = new Set(previous);
|
|
221
|
+
if (expanded)
|
|
222
|
+
next.add(section.id);
|
|
223
|
+
else
|
|
224
|
+
next.delete(section.id);
|
|
225
|
+
return next;
|
|
226
|
+
}), children: [_jsx("span", { children: section.title }), _jsx(SymbolImage, { name: expanded ? 'chevron.down' : 'chevron.right' })] }), _jsx("div", { id: groupId, role: "group", "aria-label": section.title, hidden: !expanded, children: sidebarItems
|
|
227
|
+
.filter(item => item.role !== 'search' && section.tabs.includes(item.id))
|
|
228
|
+
.map(sidebarRow) })] }, section.id));
|
|
229
|
+
})] })] })), _jsx(SafeAreaInset, { inert: showSidebar && overlaySidebar, edge: "bottom", spacing: 0, content: _jsxs("div", { ref: bottomChrome, "data-satin-tab-bottom-chrome": readDeviceIdiom() === 'phone' ? 'phone' : 'pad',
|
|
230
|
+
// Search's compact hit target uses the full dock, even when its resting bar hugs
|
|
231
|
+
// two or three items. Only an actual accessory makes that resting bar full-width.
|
|
232
|
+
style: (bottomAccessory != null || searchTab) && readDeviceIdiom() === 'phone'
|
|
233
|
+
? {
|
|
234
|
+
width: glassDockWidth(metrics.layoutViewport.width, metrics.screen, metrics.insets, metrics.layoutViewport.height),
|
|
235
|
+
marginInline: 'auto',
|
|
236
|
+
transform: `translateX(${(metrics.insets.left - metrics.insets.right) / 2}px)`,
|
|
237
|
+
}
|
|
238
|
+
: undefined, children: [bottomAccessory != null && (_jsx("div", { ref: accessoryContact, "data-satin-tab-bottom-accessory": "true",
|
|
239
|
+
// Native iPad: 24 pt edge margins, 48 pt minimum row. In portrait
|
|
240
|
+
// only this floating chrome clears the 280 pt modal sidebar;
|
|
241
|
+
// landscape's parent already owns the native sidebar column.
|
|
242
|
+
style: readDeviceIdiom() === 'pad'
|
|
243
|
+
? {
|
|
244
|
+
marginLeft: showSidebar && overlaySidebar ? 304 : 24,
|
|
245
|
+
marginRight: 24,
|
|
246
|
+
// The installed iPad can report a 25 pt system inset.
|
|
247
|
+
// Compensate it fully to retain the native 24 pt edge gap.
|
|
248
|
+
marginBottom: 24 - metrics.physicalInsets.bottom,
|
|
249
|
+
minHeight: 48,
|
|
250
|
+
}
|
|
251
|
+
: undefined, children: _jsx("div", { "data-satin-accessory-clip": "true", children: _jsx("div", { "data-satin-accessory-content": "true", children: bottomAccessoryMaterial === 'custom' ? (bottomAccessory) : (_jsx(GlassEffect, { style: { width: '100%', height: '100%' }, children: bottomAccessory })) }) }) })), selected !== undefined && (!showSidebar || overlaySidebar) && (_jsx(TabBarAccessoryContext, { value: bottomAccessory != null, children: _jsx(TabBar, { inert: showSidebar && overlaySidebar, "aria-hidden": (showSidebar && overlaySidebar) || undefined, style: showSidebar && overlaySidebar ? { visibility: 'hidden' } : undefined, items: barItems, selected: selected, onSelect: select, onShowSidebar: canShowSidebar ? () => changeSidebar(true) : undefined }) })), searchTab && (_jsx("div", { "data-satin-tab-compact-search": "true", children: _jsx("button", { type: "button", "aria-label": searchTab.accessibilityLabel ?? searchTab.label, disabled: searchTab.disabled, onClick: () => {
|
|
252
|
+
restoreCompactTabBar(bottomChrome.current);
|
|
253
|
+
// A selected Search shortcut reforms the bar without reselecting its stack.
|
|
254
|
+
if (selected !== searchTab.id)
|
|
255
|
+
select(searchTab.id);
|
|
256
|
+
} }) }))] }), children: tabs.map((tab, index) => (_jsx(RetainedTab, { panelId: items[index].panelId, tabId: showSidebar
|
|
257
|
+
? `${items[index].tabId}-sidebar`
|
|
258
|
+
: barItems.some(item => item.id === tab.id)
|
|
259
|
+
? items[index].tabId
|
|
260
|
+
: undefined, label: tab.label, focusOnActivate: tab.id !== initialSelection, id: tab.id, active: tab.id === requested, presented: tab.id === selected, register: register, children: _jsx(PadSearchTabContext, { value: tab.role === 'search' && tab.id === selected ? tab.id : null, children: mounted.includes(tab.id) ? tab.children : null }) }, tab.id))) })] }) }));
|
|
258
261
|
}
|
package/dist/tasks/useTask.d.ts
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
export type TaskCommit = (update: () => void) => boolean;
|
|
3
3
|
/** The work `useTask` runs: pass `signal` to fetches and publish state through `commit`. */
|
|
4
4
|
export type TaskAction = (signal: AbortSignal, commit: TaskCommit) => void | Promise<void>;
|
|
5
|
-
/** `
|
|
5
|
+
/** Options for `useTask`. A change of `id` cancels the current run and starts a new one. */
|
|
6
6
|
export type TaskOptions = Readonly<{
|
|
7
7
|
id?: unknown;
|
|
8
8
|
}>;
|
|
9
9
|
/** Cancels the current run and starts the task again; resolves when that run ends. */
|
|
10
10
|
export type TaskRunner = () => Promise<void>;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* Runs async work while its screen is showing. It cancels the run when the screen is covered,
|
|
13
|
+
* its tab is hidden or the component unmounts, and starts again when it shows. Pass `signal` to
|
|
14
|
+
* `fetch` and publish results through `commit`. An error the task throws reaches the nearest
|
|
15
|
+
* error boundary. The returned runner cancels and replaces the current run.
|
|
15
16
|
*/
|
|
16
17
|
export declare function useTask(action: TaskAction, { id }?: TaskOptions): TaskRunner;
|
package/dist/tasks/useTask.js
CHANGED
|
@@ -2,9 +2,10 @@ import { useCallback, useContext, useLayoutEffect, useRef, useState } from 'reac
|
|
|
2
2
|
import { ScreenContext } from '../navigation/navigationContext.js';
|
|
3
3
|
import { TabActivityContext } from '../tabs/context.js';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Runs async work while its screen is showing. It cancels the run when the screen is covered,
|
|
6
|
+
* its tab is hidden or the component unmounts, and starts again when it shows. Pass `signal` to
|
|
7
|
+
* `fetch` and publish results through `commit`. An error the task throws reaches the nearest
|
|
8
|
+
* error boundary. The returned runner cancels and replaces the current run.
|
|
8
9
|
*/
|
|
9
10
|
export function useTask(action, { id } = {}) {
|
|
10
11
|
const screen = useContext(ScreenContext);
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Throws unless the visible screen in `container` is the route `screen`. For app tests. */
|
|
2
2
|
export declare function assertNavigation(container: ParentNode, screen: string): void;
|
|
3
|
-
/**
|
|
3
|
+
/** Sends a test notification through a push relay and returns how many devices accepted it. The
|
|
4
|
+
* token is requested when called and never stored. */
|
|
4
5
|
export declare function sendTestNotification(relay: {
|
|
5
6
|
url: string;
|
|
6
7
|
token: () => string | Promise<string>;
|
package/dist/testing.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { createPushRelayAdapter } from './push/notifications.js';
|
|
2
|
-
/**
|
|
2
|
+
/** Throws unless the visible screen in `container` is the route `screen`. For app tests. */
|
|
3
3
|
export function assertNavigation(container, screen) {
|
|
4
4
|
const active = container.querySelector('[data-satin-screen-container][data-satin-covered="false"]');
|
|
5
5
|
if (active?.getAttribute('data-satin-screen') !== screen)
|
|
6
6
|
throw new Error(`Expected active route ${screen}`);
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
8
|
+
/** Sends a test notification through a push relay and returns how many devices accepted it. The
|
|
9
|
+
* token is requested when called and never stored. */
|
|
9
10
|
export function sendTestNotification(relay) {
|
|
10
11
|
return createPushRelayAdapter(relay).sendTest();
|
|
11
12
|
}
|
|
@@ -24,7 +24,11 @@ export const TextEditor = forwardRef(function TextEditor({ value, onChange, labe
|
|
|
24
24
|
// Only a scroll surface bounds growth. A content-sized parent is the editor's own height,
|
|
25
25
|
// so reading it as a limit would stop the editor from ever growing.
|
|
26
26
|
const containerHeight = surface?.clientHeight ?? Infinity;
|
|
27
|
-
|
|
27
|
+
// A sheet enters from outside the viewport. Its transformed screen position is
|
|
28
|
+
// not an editing limit: transforms do not deliver a ResizeObserver notification
|
|
29
|
+
// when the sheet settles. Only intersect screen geometry for an open keyboard.
|
|
30
|
+
const keyboardVisible = keyboard.height > 0 && keyboard.viewportHeight > 0;
|
|
31
|
+
const visibleHeight = keyboardVisible
|
|
28
32
|
? keyboard.viewportHeight -
|
|
29
33
|
Math.max(0, (surface?.getBoundingClientRect().top ?? 0) - keyboard.offsetTop)
|
|
30
34
|
: containerHeight;
|
|
@@ -32,7 +36,7 @@ export const TextEditor = forwardRef(function TextEditor({ value, onChange, labe
|
|
|
32
36
|
// to measure it: use an isolated, non-focusable copy with the same text layout instead.
|
|
33
37
|
const available = maxLines === undefined
|
|
34
38
|
? Math.min(containerHeight, visibleHeight) - 24
|
|
35
|
-
: Math.min(Math.max(minLines, maxLines) * lineHeight + padding,
|
|
39
|
+
: Math.min(Math.max(minLines, maxLines) * lineHeight + padding, keyboardVisible ? visibleHeight - 24 : Infinity);
|
|
36
40
|
const height = editorHeight(measureEditorContentHeight(element), minLines, lineHeight, padding, available);
|
|
37
41
|
if (element.style.height === `${height}px`)
|
|
38
42
|
return;
|
|
@@ -65,7 +69,7 @@ export const TextEditor = forwardRef(function TextEditor({ value, onChange, labe
|
|
|
65
69
|
observer.disconnect();
|
|
66
70
|
element.removeEventListener('input', resize);
|
|
67
71
|
};
|
|
68
|
-
}, [value, minLines, maxLines, keyboard.viewportHeight, keyboard.offsetTop]);
|
|
72
|
+
}, [value, minLines, maxLines, keyboard.height, keyboard.viewportHeight, keyboard.offsetTop]);
|
|
69
73
|
useLayoutEffect(() => {
|
|
70
74
|
if (autoFocus && ref.current)
|
|
71
75
|
focusFromFramework(ref.current, { preventScroll: true });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** The
|
|
1
|
+
/** The parts of a field element that `useFocusChain` uses to move focus. */
|
|
2
2
|
export type FocusChainField = Pick<HTMLInputElement, 'focus' | 'blur' | 'disabled' | 'readOnly' | 'isConnected' | 'closest'>;
|
|
3
3
|
/** Explicit order survives conditional rendering; disabled/unmounted fields are skipped. */
|
|
4
4
|
export declare function createFocusChain<Key extends string>(order: readonly Key[]): {
|
|
@@ -10,8 +10,9 @@ export declare function createFocusChain<Key extends string>(order: readonly Key
|
|
|
10
10
|
dismiss(): void;
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
* last one dismisses the keyboard.
|
|
13
|
+
* Moves focus through a form's fields in `order`. The return key goes to the next field and the
|
|
14
|
+
* last one dismisses the keyboard. Disabled and unmounted fields are skipped. Spread
|
|
15
|
+
* `field(key)` onto each field.
|
|
15
16
|
*
|
|
16
17
|
* @example
|
|
17
18
|
* const focus = useFocusChain(['name', 'email'])
|
|
@@ -49,8 +49,9 @@ export function createFocusChain(order) {
|
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
53
|
-
* last one dismisses the keyboard.
|
|
52
|
+
* Moves focus through a form's fields in `order`. The return key goes to the next field and the
|
|
53
|
+
* last one dismisses the keyboard. Disabled and unmounted fields are skipped. Spread
|
|
54
|
+
* `field(key)` onto each field.
|
|
54
55
|
*
|
|
55
56
|
* @example
|
|
56
57
|
* const focus = useFocusChain(['name', 'email'])
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { InputHTMLAttributes } from 'react';
|
|
2
2
|
/** What a field holds, setting its keyboard, autofill and autocorrection together. */
|
|
3
3
|
export type TextFieldKind = 'text' | 'name' | 'email' | 'url' | 'tel' | 'number' | 'decimal' | 'search' | 'username' | 'new-password' | 'current-password' | 'one-time-code';
|
|
4
|
-
/**
|
|
4
|
+
/** The return key's title: `done`, `go`, `next`, `search` or `send`. */
|
|
5
5
|
export type SubmitLabel = 'done' | 'go' | 'next' | 'search' | 'send';
|
|
6
6
|
type Attributes = Pick<InputHTMLAttributes<HTMLInputElement>, 'type' | 'inputMode' | 'autoComplete' | 'autoCapitalize' | 'autoCorrect' | 'spellCheck' | 'enterKeyHint'>;
|
|
7
7
|
export declare function textFieldAttributes(kind?: TextFieldKind, submitLabel?: SubmitLabel): Attributes;
|
package/dist/web/WebView.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type CSSProperties } from 'react';
|
|
2
|
+
/** The embedded page's load state. A cross-origin page reports `unverified`, because its contents
|
|
3
|
+
* cannot be read. */
|
|
2
4
|
export type WebFrameState = {
|
|
3
5
|
status: 'idle' | 'loading';
|
|
4
6
|
} | {
|
|
@@ -12,20 +14,24 @@ export type WebFrameState = {
|
|
|
12
14
|
status: 'unavailable';
|
|
13
15
|
reason: 'invalid-url' | 'load-error';
|
|
14
16
|
};
|
|
17
|
+
/** Whether a `reload` or `stop` request was sent to the frame, or why not. */
|
|
15
18
|
export type WebFrameActionResult = {
|
|
16
19
|
status: 'dispatched';
|
|
17
20
|
} | {
|
|
18
21
|
status: 'unavailable';
|
|
19
22
|
reason: 'not-mounted' | 'cross-origin-or-denied';
|
|
20
23
|
};
|
|
21
|
-
/**
|
|
24
|
+
/** Reads a `WebView`'s state and sends it `reload` and `stop`. Only same-origin frames expose
|
|
25
|
+
* their current page or accept these commands. */
|
|
22
26
|
export interface WebFrameController {
|
|
23
27
|
readonly state: WebFrameState;
|
|
24
28
|
reload(): WebFrameActionResult;
|
|
25
29
|
stop(): WebFrameActionResult;
|
|
26
30
|
}
|
|
27
|
-
/**
|
|
31
|
+
/** Makes a controller to pass to a `WebView`, for reading its state and reloading or stopping it. */
|
|
28
32
|
export declare function useWebFrame(): WebFrameController;
|
|
33
|
+
/** The page URL, its accessible title, an optional controller, and what the page may run. Scripts
|
|
34
|
+
* and forms are off by default. */
|
|
29
35
|
export interface WebViewProps {
|
|
30
36
|
url: string;
|
|
31
37
|
/** Accessible name for the embedded page. */
|
|
@@ -38,5 +44,6 @@ export interface WebViewProps {
|
|
|
38
44
|
style?: CSSProperties;
|
|
39
45
|
onStateChange?: (state: WebFrameState) => void;
|
|
40
46
|
}
|
|
41
|
-
/**
|
|
47
|
+
/** Embeds a web page in a sandboxed frame. The browser decides whether the page may be framed, and
|
|
48
|
+
* the frame's storage is partitioned from the app's. */
|
|
42
49
|
export declare function WebView({ url: input, title, controller, className, style, onStateChange, allowsJavaScript, allowsForms, }: WebViewProps): import("react").JSX.Element | null;
|
package/dist/web/WebView.js
CHANGED
|
@@ -50,7 +50,7 @@ function createFrameStore() {
|
|
|
50
50
|
},
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
/**
|
|
53
|
+
/** Makes a controller to pass to a `WebView`, for reading its state and reloading or stopping it. */
|
|
54
54
|
export function useWebFrame() {
|
|
55
55
|
const store = useMemo(() => {
|
|
56
56
|
const value = createFrameStore();
|
|
@@ -60,7 +60,8 @@ export function useWebFrame() {
|
|
|
60
60
|
useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
61
61
|
return store.controller;
|
|
62
62
|
}
|
|
63
|
-
/**
|
|
63
|
+
/** Embeds a web page in a sandboxed frame. The browser decides whether the page may be framed, and
|
|
64
|
+
* the frame's storage is partitioned from the app's. */
|
|
64
65
|
export function WebView({ url: input, title, controller, className, style, onStateChange, allowsJavaScript = false, allowsForms = false, }) {
|
|
65
66
|
const local = useWebFrame();
|
|
66
67
|
const store = stores.get(controller ?? local);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** The OAuth provider, client, callback and app URLs for `defineWebAuthentication`, and the
|
|
2
|
+
* `exchange` function that finishes sign-in on your server. */
|
|
1
3
|
export interface WebAuthenticationConfiguration {
|
|
2
4
|
/** Stable name, unique within this app origin. */
|
|
3
5
|
id: string;
|
|
@@ -16,6 +18,8 @@ export interface WebAuthenticationConfiguration {
|
|
|
16
18
|
/** Establish your session on the server. Never return or message tokens to another window. */
|
|
17
19
|
exchange: (request: WebAuthenticationExchange) => Promise<void>;
|
|
18
20
|
}
|
|
21
|
+
/** What `exchange` receives: the authorization code, the PKCE verifier and the values your
|
|
22
|
+
* server needs to redeem and check it. */
|
|
19
23
|
export interface WebAuthenticationExchange {
|
|
20
24
|
code: string;
|
|
21
25
|
codeVerifier: string;
|
|
@@ -26,6 +30,7 @@ export interface WebAuthenticationExchange {
|
|
|
26
30
|
expectedIssuer?: string;
|
|
27
31
|
signal: AbortSignal;
|
|
28
32
|
}
|
|
33
|
+
/** Where a sign-in stands, from `idle` through `pending` and `completing` to a final status. */
|
|
29
34
|
export type WebAuthenticationState = {
|
|
30
35
|
status: 'idle';
|
|
31
36
|
} | {
|
|
@@ -38,6 +43,7 @@ export type WebAuthenticationState = {
|
|
|
38
43
|
status: 'failed' | 'unavailable';
|
|
39
44
|
reason: string;
|
|
40
45
|
};
|
|
46
|
+
/** Whether `start` opened the provider in a popup or a redirect, or why it could not. */
|
|
41
47
|
export type WebAuthenticationStartResult = {
|
|
42
48
|
status: 'dispatched';
|
|
43
49
|
transport: 'popup' | 'redirect';
|
|
@@ -45,6 +51,7 @@ export type WebAuthenticationStartResult = {
|
|
|
45
51
|
status: 'unavailable';
|
|
46
52
|
reason: string;
|
|
47
53
|
};
|
|
54
|
+
/** The outcome of `complete` on the callback page: the URL to return to, or why it was rejected. */
|
|
48
55
|
export type WebAuthenticationCallbackResult = {
|
|
49
56
|
status: 'completed';
|
|
50
57
|
returnURL: string;
|
|
@@ -52,12 +59,15 @@ export type WebAuthenticationCallbackResult = {
|
|
|
52
59
|
status: 'rejected' | 'unavailable';
|
|
53
60
|
reason: string;
|
|
54
61
|
};
|
|
62
|
+
/** A prepared sign-in. Call `start` from the user's press. */
|
|
55
63
|
export interface WebAuthenticationRequest {
|
|
56
64
|
/** Call synchronously in the user's press handler. A blocked popup may retry as redirect. */
|
|
57
65
|
start(options?: {
|
|
58
66
|
transport?: 'popup' | 'redirect';
|
|
59
67
|
}): WebAuthenticationStartResult;
|
|
60
68
|
}
|
|
69
|
+
/** A sign-in flow made by `defineWebAuthentication`: prepare, start, complete and resume it, or
|
|
70
|
+
* subscribe to its state. */
|
|
61
71
|
export interface WebAuthentication {
|
|
62
72
|
/** Generate PKCE and durably register the transaction before enabling the sign-in button. */
|
|
63
73
|
prepare(): Promise<WebAuthenticationRequest>;
|
|
@@ -71,5 +81,6 @@ export interface WebAuthentication {
|
|
|
71
81
|
/** Attach bounded popup monitoring and lifecycle listeners. Returns their cleanup. */
|
|
72
82
|
connect(): () => void;
|
|
73
83
|
}
|
|
74
|
-
/**
|
|
84
|
+
/** Sets up an OAuth authorization-code sign-in with PKCE. The transaction is stored durably, so
|
|
85
|
+
* it survives a redirect or a suspended app. Your server redeems the code. */
|
|
75
86
|
export declare function defineWebAuthentication(configuration: WebAuthenticationConfiguration): WebAuthentication;
|
|
@@ -29,7 +29,8 @@ function callbackValue(value, state) {
|
|
|
29
29
|
return { state, error: response.error };
|
|
30
30
|
return null;
|
|
31
31
|
}
|
|
32
|
-
/**
|
|
32
|
+
/** Sets up an OAuth authorization-code sign-in with PKCE. The transaction is stored durably, so
|
|
33
|
+
* it survives a redirect or a suspended app. Your server redeems the code. */
|
|
33
34
|
export function defineWebAuthentication(configuration) {
|
|
34
35
|
const app = secureWebURL(configuration.appURL, configuration.appURL);
|
|
35
36
|
const callback = secureWebURL(configuration.callbackURL, app.href);
|
package/dist/web/openURL.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
-
/**
|
|
2
|
+
/** How to open a web page. `prefersInApp` is a preference; the browser decides how the page is
|
|
3
|
+
* presented. */
|
|
3
4
|
export interface OpenURLOptions {
|
|
4
5
|
/** Defaults to true. A strict external-browser request is unavailable on this runtime. */
|
|
5
6
|
prefersInApp?: boolean;
|
|
6
7
|
}
|
|
7
|
-
/**
|
|
8
|
+
/** What happened to an open request: `handled` in the app, `dispatched` to the browser, or
|
|
9
|
+
* `unavailable` with a reason. `dispatched` does not mean the page loaded. */
|
|
8
10
|
export type OpenURLResult = {
|
|
9
11
|
status: 'handled';
|
|
10
12
|
destination: 'app';
|
|
@@ -15,6 +17,7 @@ export type OpenURLResult = {
|
|
|
15
17
|
status: 'unavailable';
|
|
16
18
|
reason: 'invalid-url' | 'external-browser' | 'unregistered-app-url' | 'navigation-failed' | 'popup-blocked';
|
|
17
19
|
};
|
|
20
|
+
/** The function `useOpenURL` returns. It opens a URL and reports the result at once. */
|
|
18
21
|
export type OpenURLAction = (url: string, options?: OpenURLOptions) => OpenURLResult;
|
|
19
22
|
/** Internal factory keeps the same policy in component and imperative actions. */
|
|
20
23
|
export declare function createOpenURLAction(options: {
|
|
@@ -22,8 +25,10 @@ export declare function createOpenURLAction(options: {
|
|
|
22
25
|
openInternal: (url: string) => boolean;
|
|
23
26
|
dispatch: (url: string) => boolean;
|
|
24
27
|
}): OpenURLAction;
|
|
25
|
-
/**
|
|
28
|
+
/** Returns a function that opens a URL from an action. App URLs that match a registered route
|
|
29
|
+
* navigate inside the app; other URLs go to the browser. */
|
|
26
30
|
export declare function useOpenURL(): OpenURLAction;
|
|
31
|
+
/** The link's destination URL, its content and an optional result callback. */
|
|
27
32
|
export interface LinkProps extends OpenURLOptions {
|
|
28
33
|
destination: string;
|
|
29
34
|
children: ReactNode;
|
|
@@ -33,5 +38,6 @@ export interface LinkProps extends OpenURLOptions {
|
|
|
33
38
|
/** Receives dispatch or rejection immediately, never inferred page completion. */
|
|
34
39
|
onResult?: (result: OpenURLResult) => void;
|
|
35
40
|
}
|
|
36
|
-
/**
|
|
41
|
+
/** Opens a URL when pressed, like `useOpenURL`. A press that turns into a scroll does not open
|
|
42
|
+
* it. */
|
|
37
43
|
export declare function Link({ destination, prefersInApp, onResult, children, ...props }: LinkProps): import("react").JSX.Element;
|