@goway.to/maps 0.1.0 → 0.1.2

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/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to `@goway.to/maps`. Semantic versioning with the 0.x rule:
4
4
  while the major version is 0, a MINOR release may break the API.
5
5
 
6
+ ## 0.1.2
7
+
8
+ - The map resolves its style through `@goway.to/sdk/map`, which has no HTTP
9
+ client and no zod, instead of the SDK's root entry. A web app no longer
10
+ bundles GoWay's whole contract to draw a map: in Homiio that was about
11
+ 170 KB of gzipped JavaScript. Needs `@goway.to/sdk` 0.7.0.
12
+
13
+ ## 0.1.1
14
+
15
+ - A `MapView` given a `height` keeps it. The root was `flex: 1`, a zero flex
16
+ basis on both platforms, which overrode the caller's height: a map inside a
17
+ scroll view (an address picker in a form) rendered 0 tall. It now grows from
18
+ its own size, so it still fills a bounded parent when given no size.
19
+ - The GoWay mark has an accessible name on the web. `react-native-svg` hands
20
+ its props to the DOM `<svg>` unchanged, so the logo's React Native
21
+ accessibility props landed there as unknown attributes — no name in a
22
+ browser, and a React warning about `accessible` on every map. The web now
23
+ gets `role="img"` and `aria-label`; iOS and Android are unchanged.
24
+
6
25
  ## 0.1.0
7
26
 
8
27
  The first release: GoWay's map as an SDK, with GoWay's own app as its first
@@ -40,7 +40,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
40
40
  import { memo, useCallback } from 'react';
41
41
  import { Linking, Pressable, StyleSheet, View, } from 'react-native';
42
42
  import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated';
43
- import { localizedLabel } from '@goway.to/sdk';
43
+ import { localizedLabel } from '@goway.to/sdk/map';
44
44
  import { useBloomLocale } from '@oxy.so/bloom/locale';
45
45
  import { useBottomEdgeInset } from '@oxy.so/bloom/layout';
46
46
  import { RiInformationLine } from '@oxy.so/bloom/icons/RiInformationLine';
package/dist/MapView.js CHANGED
@@ -39,14 +39,10 @@ const WORLD_VIEW = { latitude: 20, longitude: 0, zoom: 1.5 };
39
39
  export const MapView = forwardRef(function MapView(props, ref) {
40
40
  const { mapStyle = DEFAULT_MAP_STYLE, lightPreset, initialViewState, camera, light, interaction, credits, creditDisclosure, onPress, onCameraChanged, onLabelsChange, onReady, onError, style, testID, children, } = props;
41
41
  const theme = useTheme();
42
- let styleUrl = null;
43
- let styleError = null;
44
- try {
45
- styleUrl = resolveStyleUrl(mapStyle, lightPreset, theme.isDark);
46
- }
47
- catch (cause) {
48
- styleError = { reason: 'style', message: String(cause) };
49
- }
42
+ const styleUrl = resolveStyleUrl(mapStyle, lightPreset, theme.isDark);
43
+ const styleError = styleUrl === null
44
+ ? { reason: 'style', message: `not a published GoWay style: ${mapStyle}` }
45
+ : null;
50
46
  const mapRef = useRef(null);
51
47
  const cameraRef = useRef(null);
52
48
  const [error, setError] = useState(null);
@@ -415,6 +411,11 @@ function createNativeMapApi(mapRef, cameraRef, reports) {
415
411
  return api;
416
412
  }
417
413
  const styles = StyleSheet.create({
418
- root: { flex: 1, position: 'relative', overflow: 'hidden' },
414
+ // `flexGrow`, not `flex: 1`: `flex: 1` is a zero flex BASIS (react-native-web
415
+ // writes `flex: 1 1 0%`, and Yoga reads it the same way), which overrides a
416
+ // caller's `height` and collapses a map in a scroll view or any parent of
417
+ // auto height to nothing. Growing from its own size, the map fills a bounded
418
+ // parent when given no size and keeps the one it is given.
419
+ root: { flexGrow: 1, position: 'relative', overflow: 'hidden' },
419
420
  fill: { flex: 1 },
420
421
  });
@@ -57,14 +57,10 @@ export const MapView = forwardRef(function MapView(props, ref) {
57
57
  // bound once per engine: a new inline `onPress` must not rebuild the map.
58
58
  const latest = useRef(props);
59
59
  latest.current = props;
60
- let styleUrl = null;
61
- let styleError = null;
62
- try {
63
- styleUrl = resolveStyleUrl(mapStyle, lightPreset, theme.isDark);
64
- }
65
- catch (cause) {
66
- styleError = { reason: 'style', message: String(cause) };
67
- }
60
+ const styleUrl = resolveStyleUrl(mapStyle, lightPreset, theme.isDark);
61
+ const styleError = styleUrl === null
62
+ ? { reason: 'style', message: `not a published GoWay style: ${mapStyle}` }
63
+ : null;
68
64
  const [retry, setRetry] = useState(0);
69
65
  const [engine, setEngine] = useState(null);
70
66
  const [zoomLevel, setZoomLevel] = useState(() => Math.floor(openingZoom(props.initialViewState)));
@@ -408,6 +404,11 @@ function labelAt(map, point, coordinate, layers) {
408
404
  });
409
405
  }
410
406
  const styles = StyleSheet.create({
411
- root: { flex: 1, position: 'relative', overflow: 'hidden' },
407
+ // `flexGrow`, not `flex: 1`: `flex: 1` is a zero flex BASIS (react-native-web
408
+ // writes `flex: 1 1 0%`, and Yoga reads it the same way), which overrides a
409
+ // caller's `height` and collapses a map in a scroll view or any parent of
410
+ // auto height to nothing. Growing from its own size, the map fills a bounded
411
+ // parent when given no size and keeps the one it is given.
412
+ root: { flexGrow: 1, position: 'relative', overflow: 'hidden' },
412
413
  engine: { flex: 1 },
413
414
  });
@@ -24,8 +24,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
24
24
  * every call site instead of cropping in some of them.
25
25
  */
26
26
  import { memo } from 'react';
27
+ import { Platform } from 'react-native';
27
28
  import Svg, { Path } from 'react-native-svg';
28
29
  import { GOWAY_INK, GOWAY_MARK, GOWAY_WORDMARK, aspectRatio } from './artwork';
30
+ import { logoAccessibility } from './logoAccessibility';
29
31
  const ARTWORK = {
30
32
  wordmark: GOWAY_WORDMARK,
31
33
  mark: GOWAY_MARK,
@@ -37,10 +39,7 @@ export function gowayLogoHeight(width, variant = 'wordmark') {
37
39
  function GowayLogoComponent({ width, variant = 'wordmark', label = 'GoWay', testID, }) {
38
40
  const artwork = ARTWORK[variant];
39
41
  const height = gowayLogoHeight(width, variant);
40
- return (_jsx(Svg, { width: width, height: height, viewBox: artwork.viewBox,
41
- // A decorative logo beside its own name is noise in a screen reader, so
42
- // an empty label hides it rather than forcing callers to wrap it.
43
- accessible: label !== '', accessibilityRole: "image", accessibilityLabel: label || undefined, testID: testID, children: artwork.paths.map((path, index) => (
42
+ return (_jsx(Svg, { width: width, height: height, viewBox: artwork.viewBox, ...logoAccessibility(label, Platform.OS), testID: testID, children: artwork.paths.map((path, index) => (
44
43
  // Index keys: the array is a fixed, ordered drawing, never reordered
45
44
  // and never filtered by anything but `part`. Draw order is the artwork
46
45
  // (see `artwork.ts`), so a key that survived a reorder would be a bug.
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The logo's accessible name, in each platform's own vocabulary.
3
+ *
4
+ * `react-native-svg` on the web hands its props to the DOM `<svg>` as they
5
+ * are, so React Native's `accessible` / `accessibilityRole` /
6
+ * `accessibilityLabel` landed there as unknown attributes: the logo had no
7
+ * accessible name in a browser, and React warned about `accessible` on every
8
+ * map. The web gets ARIA; iOS and Android keep React Native's props, which
9
+ * the native SVG view does read.
10
+ *
11
+ * An empty label hides the logo from assistive technology on both: a
12
+ * decorative logo beside its own name is noise in a screen reader.
13
+ */
14
+ export type LogoAccessibility = {
15
+ role: 'img';
16
+ 'aria-label': string;
17
+ } | {
18
+ 'aria-hidden': true;
19
+ } | {
20
+ accessible: true;
21
+ accessibilityRole: 'image';
22
+ accessibilityLabel: string;
23
+ } | {
24
+ accessible: false;
25
+ };
26
+ export declare function logoAccessibility(label: string, os: string): LogoAccessibility;
@@ -0,0 +1,7 @@
1
+ export function logoAccessibility(label, os) {
2
+ if (os === 'web')
3
+ return label ? { role: 'img', 'aria-label': label } : { 'aria-hidden': true };
4
+ return label
5
+ ? { accessible: true, accessibilityRole: 'image', accessibilityLabel: label }
6
+ : { accessible: false };
7
+ }
package/dist/labels.js CHANGED
@@ -41,7 +41,7 @@
41
41
  * what the collision system actually PLACED, not with what the tiles
42
42
  * contain.
43
43
  */
44
- import { OPENMAPTILES_SOURCE_LAYERS as SL } from '@goway.to/sdk';
44
+ import { OPENMAPTILES_SOURCE_LAYERS as SL } from '@goway.to/sdk/map';
45
45
  import { isDrawableCoordinate } from './shared';
46
46
  /**
47
47
  * How far around the tap the engine is asked to look, in px (web) / dp (native).
@@ -7,13 +7,16 @@
7
7
  * app's theme — day in light mode, night in dark — unless the screen pins a
8
8
  * light. Any other URL is used as it is.
9
9
  */
10
- import { type MapLightPreset } from '@goway.to/sdk';
10
+ import { type MapLightPreset } from '@goway.to/sdk/map';
11
11
  /** The style a `MapView` draws when it is given none: GoWay Standard. */
12
12
  export declare const DEFAULT_MAP_STYLE: string;
13
13
  /**
14
14
  * The document URL for `mapStyle`, in `lightPreset` or the theme's light.
15
- * Throws `GoWayValidationError` for a `goway://` name that is not a published
16
- * style — the map reports that as a style failure rather than drawing a
17
- * different map than the one asked for.
15
+ * `null` for a `goway://` name that is not a published style — the map
16
+ * reports that as a style failure rather than drawing a different map than
17
+ * the one asked for.
18
+ *
19
+ * Through `@goway.to/sdk/map`, which has no HTTP client and no schema: a map
20
+ * resolving its style must not carry GoWay's whole contract into an app.
18
21
  */
19
- export declare function resolveStyleUrl(mapStyle: string, lightPreset: MapLightPreset | undefined, dark: boolean): string;
22
+ export declare function resolveStyleUrl(mapStyle: string, lightPreset: MapLightPreset | undefined, dark: boolean): string | null;
package/dist/styleUrl.js CHANGED
@@ -7,16 +7,18 @@
7
7
  * app's theme — day in light mode, night in dark — unless the screen pins a
8
8
  * light. Any other URL is used as it is.
9
9
  */
10
- import { createGoWayClient, gowayStyleUrl } from '@goway.to/sdk';
10
+ import { gowayStyleUrl, styleDocumentUrl } from '@goway.to/sdk/map';
11
11
  /** The style a `MapView` draws when it is given none: GoWay Standard. */
12
12
  export const DEFAULT_MAP_STYLE = gowayStyleUrl('standard');
13
- const links = createGoWayClient().links;
14
13
  /**
15
14
  * The document URL for `mapStyle`, in `lightPreset` or the theme's light.
16
- * Throws `GoWayValidationError` for a `goway://` name that is not a published
17
- * style — the map reports that as a style failure rather than drawing a
18
- * different map than the one asked for.
15
+ * `null` for a `goway://` name that is not a published style — the map
16
+ * reports that as a style failure rather than drawing a different map than
17
+ * the one asked for.
18
+ *
19
+ * Through `@goway.to/sdk/map`, which has no HTTP client and no schema: a map
20
+ * resolving its style must not carry GoWay's whole contract into an app.
19
21
  */
20
22
  export function resolveStyleUrl(mapStyle, lightPreset, dark) {
21
- return links.styleUrl(mapStyle, lightPreset ?? (dark ? 'night' : 'day'));
23
+ return styleDocumentUrl(mapStyle, lightPreset ?? (dark ? 'night' : 'day'));
22
24
  }
package/dist/types.d.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import type { ReactNode } from 'react';
11
11
  import type { StyleProp, ViewStyle } from 'react-native';
12
- import type { MapLightPreset } from '@goway.to/sdk';
12
+ import type { MapLightPreset } from '@goway.to/sdk/map';
13
13
  import type { GeoBoundingBox, GeoCoordinate } from '@goway.to/sdk/geo';
14
14
  export type { GeoBoundingBox, GeoCoordinate };
15
15
  /** Where the camera is. `bearing` and `pitch` are optional on input and always present on output. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goway.to/maps",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "GoWay's maps SDK for React and React Native: one declarative map for web and native — GoWay styles that follow your theme, Bloom markers with clustering, a camera framed by value, user location without a prompt on mount.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "The Oxy Collective, Inc.",
@@ -77,7 +77,7 @@
77
77
  "supercluster": "^8.0.1"
78
78
  },
79
79
  "peerDependencies": {
80
- "@goway.to/sdk": ">=0.6.0",
80
+ "@goway.to/sdk": ">=0.7.0",
81
81
  "@maplibre/maplibre-react-native": ">=11.4.0",
82
82
  "@oxy.so/bloom": ">=10.16.0",
83
83
  "expo-location": "*",
@@ -100,7 +100,7 @@
100
100
  }
101
101
  },
102
102
  "devDependencies": {
103
- "@goway.to/sdk": "0.6.0",
103
+ "@goway.to/sdk": "0.7.0",
104
104
  "@maplibre/maplibre-react-native": "^11.4.0",
105
105
  "@oxy.so/bloom": "^10.16.1",
106
106
  "@types/react": "^19.2.17",