@fieldia/map 0.17.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/README.md +75 -10
  2. package/package.json +4 -4
  3. package/src/index.d.mts +5 -0
  4. package/src/index.d.ts +5 -0
  5. package/src/index.js +4 -1
  6. package/src/index.js.map +1 -1
  7. package/src/index.mjs +2 -0
  8. package/src/index.mjs.map +1 -1
  9. package/src/lib/address-labels.d.mts +21 -0
  10. package/src/lib/address-labels.d.ts +21 -0
  11. package/src/lib/address-labels.js +16 -0
  12. package/src/lib/address-labels.js.map +1 -0
  13. package/src/lib/address-labels.mjs +12 -0
  14. package/src/lib/address-labels.mjs.map +1 -0
  15. package/src/lib/address-line.d.mts +2 -0
  16. package/src/lib/address-line.d.ts +2 -0
  17. package/src/lib/address-line.js +34 -0
  18. package/src/lib/address-line.js.map +1 -0
  19. package/src/lib/address-line.mjs +31 -0
  20. package/src/lib/address-line.mjs.map +1 -0
  21. package/src/lib/address-parts.d.mts +28 -0
  22. package/src/lib/address-parts.d.ts +28 -0
  23. package/src/lib/address-parts.js +47 -0
  24. package/src/lib/address-parts.js.map +1 -0
  25. package/src/lib/address-parts.mjs +38 -0
  26. package/src/lib/address-parts.mjs.map +1 -0
  27. package/src/lib/address-search.d.mts +21 -0
  28. package/src/lib/address-search.d.ts +21 -0
  29. package/src/lib/address-search.js +52 -0
  30. package/src/lib/address-search.js.map +1 -0
  31. package/src/lib/address-search.mjs +49 -0
  32. package/src/lib/address-search.mjs.map +1 -0
  33. package/src/lib/address-suggest.d.mts +18 -0
  34. package/src/lib/address-suggest.d.ts +18 -0
  35. package/src/lib/address-suggest.js +140 -0
  36. package/src/lib/address-suggest.js.map +1 -0
  37. package/src/lib/address-suggest.mjs +137 -0
  38. package/src/lib/address-suggest.mjs.map +1 -0
  39. package/src/lib/area-count.d.mts +47 -0
  40. package/src/lib/area-count.d.ts +47 -0
  41. package/src/lib/area-count.js +123 -0
  42. package/src/lib/area-count.js.map +1 -0
  43. package/src/lib/area-count.mjs +116 -0
  44. package/src/lib/area-count.mjs.map +1 -0
  45. package/src/lib/card.d.mts +16 -6
  46. package/src/lib/card.d.ts +16 -6
  47. package/src/lib/card.js +71 -14
  48. package/src/lib/card.js.map +1 -1
  49. package/src/lib/card.mjs +70 -14
  50. package/src/lib/card.mjs.map +1 -1
  51. package/src/lib/cluster.d.mts +6 -1
  52. package/src/lib/cluster.d.ts +6 -1
  53. package/src/lib/cluster.js +11 -5
  54. package/src/lib/cluster.js.map +1 -1
  55. package/src/lib/cluster.mjs +11 -5
  56. package/src/lib/cluster.mjs.map +1 -1
  57. package/src/lib/embed.d.mts +86 -0
  58. package/src/lib/embed.d.ts +86 -0
  59. package/src/lib/embed.js +96 -0
  60. package/src/lib/embed.js.map +1 -0
  61. package/src/lib/embed.mjs +93 -0
  62. package/src/lib/embed.mjs.map +1 -0
  63. package/src/lib/form-map.d.mts +2 -1
  64. package/src/lib/form-map.d.ts +2 -1
  65. package/src/lib/form-map.js +159 -20
  66. package/src/lib/form-map.js.map +1 -1
  67. package/src/lib/form-map.mjs +161 -22
  68. package/src/lib/form-map.mjs.map +1 -1
  69. package/src/lib/kinds.d.mts +6 -4
  70. package/src/lib/kinds.d.ts +6 -4
  71. package/src/lib/kinds.js +49 -2
  72. package/src/lib/kinds.js.map +1 -1
  73. package/src/lib/kinds.mjs +49 -2
  74. package/src/lib/kinds.mjs.map +1 -1
  75. package/src/lib/labels.d.mts +5 -0
  76. package/src/lib/labels.d.ts +5 -0
  77. package/src/lib/labels.js +12 -4
  78. package/src/lib/labels.js.map +1 -1
  79. package/src/lib/labels.mjs +12 -4
  80. package/src/lib/labels.mjs.map +1 -1
  81. package/src/lib/leaflet.js +1 -0
  82. package/src/lib/leaflet.js.map +1 -1
  83. package/src/lib/leaflet.mjs +1 -0
  84. package/src/lib/leaflet.mjs.map +1 -1
  85. package/src/lib/list-view.d.mts +37 -1
  86. package/src/lib/list-view.d.ts +37 -1
  87. package/src/lib/list-view.js +103 -50
  88. package/src/lib/list-view.js.map +1 -1
  89. package/src/lib/list-view.mjs +103 -51
  90. package/src/lib/list-view.mjs.map +1 -1
  91. package/src/lib/map-core.d.mts +8 -3
  92. package/src/lib/map-core.d.ts +8 -3
  93. package/src/lib/map-core.js +21 -10
  94. package/src/lib/map-core.js.map +1 -1
  95. package/src/lib/map-core.mjs +21 -10
  96. package/src/lib/map-core.mjs.map +1 -1
  97. package/src/lib/marks.d.mts +11 -0
  98. package/src/lib/marks.d.ts +11 -0
  99. package/src/lib/marks.js +26 -1
  100. package/src/lib/marks.js.map +1 -1
  101. package/src/lib/marks.mjs +23 -0
  102. package/src/lib/marks.mjs.map +1 -1
  103. package/src/lib/pins.d.mts +20 -8
  104. package/src/lib/pins.d.ts +20 -8
  105. package/src/lib/pins.js +60 -15
  106. package/src/lib/pins.js.map +1 -1
  107. package/src/lib/pins.mjs +60 -17
  108. package/src/lib/pins.mjs.map +1 -1
  109. package/src/lib/place.js +2 -1
  110. package/src/lib/place.js.map +1 -1
  111. package/src/lib/place.mjs +2 -1
  112. package/src/lib/place.mjs.map +1 -1
  113. package/src/lib/providers.d.mts +31 -5
  114. package/src/lib/providers.d.ts +31 -5
  115. package/src/lib/providers.js +80 -58
  116. package/src/lib/providers.js.map +1 -1
  117. package/src/lib/providers.mjs +80 -58
  118. package/src/lib/providers.mjs.map +1 -1
  119. package/src/lib/regions.js +18 -1
  120. package/src/lib/regions.js.map +1 -1
  121. package/src/lib/regions.mjs +18 -1
  122. package/src/lib/regions.mjs.map +1 -1
  123. package/src/lib/search-box.d.mts +7 -1
  124. package/src/lib/search-box.d.ts +7 -1
  125. package/src/lib/search-box.js +15 -10
  126. package/src/lib/search-box.js.map +1 -1
  127. package/src/lib/search-box.mjs +15 -10
  128. package/src/lib/search-box.mjs.map +1 -1
  129. package/src/lib/settings.d.mts +19 -2
  130. package/src/lib/settings.d.ts +19 -2
  131. package/src/lib/styles.d.mts +13 -2
  132. package/src/lib/styles.d.ts +13 -2
  133. package/src/lib/styles.js +69 -4
  134. package/src/lib/styles.js.map +1 -1
  135. package/src/lib/styles.mjs +67 -3
  136. package/src/lib/styles.mjs.map +1 -1
  137. package/src/lib/tools.d.mts +6 -3
  138. package/src/lib/tools.d.ts +6 -3
  139. package/src/lib/tools.js +52 -1
  140. package/src/lib/tools.js.map +1 -1
  141. package/src/lib/tools.mjs +52 -1
  142. package/src/lib/tools.mjs.map +1 -1
  143. package/src/lib/view-box.d.mts +18 -0
  144. package/src/lib/view-box.d.ts +18 -0
  145. package/src/lib/view-box.js +31 -0
  146. package/src/lib/view-box.js.map +1 -0
  147. package/src/lib/view-box.mjs +25 -0
  148. package/src/lib/view-box.mjs.map +1 -0
  149. package/src/lib/widgets.d.mts +3 -0
  150. package/src/lib/widgets.d.ts +3 -0
  151. package/src/lib/widgets.js +10 -1
  152. package/src/lib/widgets.js.map +1 -1
  153. package/src/lib/widgets.mjs +10 -1
  154. package/src/lib/widgets.mjs.map +1 -1
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.inBox = inBox;
4
+ exports.boxWithin = boxWithin;
5
+ exports.ownBox = ownBox;
6
+ exports.lastAsk = lastAsk;
7
+ exports.areaCounter = areaCounter;
8
+ const view_box_1 = require("./view-box");
9
+ /**
10
+ * How many records a list map's view holds, said on "Search this area"
11
+ * before it is pressed: counted among the records on hand when they can
12
+ * tell, asked otherwise. Its code comes the first time the button shows.
13
+ */
14
+ /** Whether a place lies in a box, its edges included, as `between` takes them. */
15
+ function inBox(at, box) {
16
+ if (at.lat < box.south || at.lat > box.north)
17
+ return false;
18
+ return box.west <= box.east ? at.lng >= box.west && at.lng <= box.east : at.lng >= box.west || at.lng <= box.east;
19
+ }
20
+ /** Whether one box lies within another. */
21
+ function boxWithin(inner, outer) {
22
+ if (inner.south < outer.south || inner.north > outer.north)
23
+ return false;
24
+ if ((0, view_box_1.whole)(outer))
25
+ return true;
26
+ // Each as a stretch eastwards from its west edge; the inner one a world further round, if that is where it fits.
27
+ const span = (box) => [box.west, box.east < box.west ? box.east + 360 : box.east];
28
+ const [w, e] = span(outer);
29
+ const [iw, ie] = span(inner);
30
+ return [0, 360].some((by) => iw + by >= w && ie + by <= e);
31
+ }
32
+ /**
33
+ * The view a search already holds, as the map's "Search this area" puts it
34
+ * (its very conditions, found among the search's), and the search's other
35
+ * conditions: a new view takes its place, as a search bar keeps one.
36
+ */
37
+ function ownBox(spec, filter) {
38
+ const said = filter.map((item) => JSON.stringify(item));
39
+ const numbers = (value) => (Array.isArray(value) && value.length === 2 && value.every((n) => typeof n === 'number') ? value : null);
40
+ const boxes = [];
41
+ for (const item of filter) {
42
+ if ('any' in item || 'all' in item)
43
+ continue;
44
+ const v = item.value;
45
+ if (spec.point) {
46
+ if (item.field === spec.point && item.op === 'within' && v && ['south', 'west', 'north', 'east'].every((k) => typeof v[k] === 'number'))
47
+ boxes.push(v);
48
+ continue;
49
+ }
50
+ const lat = item.field === spec.latitude && item.op === 'between' ? numbers(v) : null;
51
+ if (!lat)
52
+ continue;
53
+ // Its longitudes: a range, either side of the antimeridian, or (tried last) the world round.
54
+ const sides = [];
55
+ for (const other of filter) {
56
+ if ('any' in other && other.any.length === 2) {
57
+ const [a, b] = other.any;
58
+ if (a.field === spec.longitude && b.field === spec.longitude && typeof a.value === 'number' && typeof b.value === 'number')
59
+ sides.push([a.value, b.value]);
60
+ }
61
+ else if (!('all' in other) && !('any' in other) && other.field === spec.longitude && other.op === 'between' && numbers(other.value))
62
+ sides.push(numbers(other.value));
63
+ }
64
+ for (const [west, east] of [...sides, [-180, 180]])
65
+ boxes.push({ south: lat[0], west, north: lat[1], east });
66
+ }
67
+ for (const box of boxes) {
68
+ const own = (0, view_box_1.boxFilter)(spec, box).map((item) => JSON.stringify(item));
69
+ if (!own.every((item) => said.includes(item)))
70
+ continue;
71
+ return { box: { ...box }, rest: filter.filter((_, i) => !own.includes(said[i])) };
72
+ }
73
+ return null;
74
+ }
75
+ /**
76
+ * One question at a time, the last one winning: each ask waits `wait`
77
+ * milliseconds (a run of moves asks once), aborts the one before it, and an
78
+ * answer that comes after a newer ask is dropped. A refusal says nothing.
79
+ */
80
+ function lastAsk(wait) {
81
+ let timer;
82
+ let asking = null;
83
+ let asked = 0;
84
+ const stop = () => {
85
+ clearTimeout(timer);
86
+ asking?.abort();
87
+ asking = null;
88
+ asked++;
89
+ };
90
+ return {
91
+ ask(question, answer) {
92
+ stop();
93
+ const mine = asked;
94
+ timer = setTimeout(() => {
95
+ const controller = (asking = new AbortController());
96
+ question(controller.signal).then((value) => mine === asked && !controller.signal.aborted && answer(value), () => undefined);
97
+ }, wait);
98
+ },
99
+ stop,
100
+ };
101
+ }
102
+ /**
103
+ * The count for a view: the records on hand say it when they are all the
104
+ * search finds and the view lies within any area it already holds;
105
+ * otherwise `ask` (the app's count, or its source's) is asked, for the
106
+ * search with the view in the area's place, a moment after the map stops;
107
+ * otherwise there is no number.
108
+ */
109
+ function areaCounter(spec, ask, say) {
110
+ const asker = lastAsk(400);
111
+ return {
112
+ count(view, shown) {
113
+ asker.stop();
114
+ const own = ownBox(spec, shown.filter);
115
+ if (shown.all && (!own || boxWithin(view, own.box)))
116
+ return say(shown.places.filter((at) => at && inBox(at, view)).length);
117
+ if (ask)
118
+ asker.ask((signal) => ask([...(own ? own.rest : shown.filter), ...(0, view_box_1.boxFilter)(spec, view)], signal), say);
119
+ },
120
+ stop: asker.stop,
121
+ };
122
+ }
123
+ //# sourceMappingURL=area-count.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"area-count.js","sourceRoot":"","sources":["../../../../../libs/map/src/lib/area-count.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ import { boxFilter, whole } from './view-box.mjs';
2
+ /**
3
+ * How many records a list map's view holds, said on "Search this area"
4
+ * before it is pressed: counted among the records on hand when they can
5
+ * tell, asked otherwise. Its code comes the first time the button shows.
6
+ */
7
+ /** Whether a place lies in a box, its edges included, as `between` takes them. */
8
+ export function inBox(at, box) {
9
+ if (at.lat < box.south || at.lat > box.north)
10
+ return false;
11
+ return box.west <= box.east ? at.lng >= box.west && at.lng <= box.east : at.lng >= box.west || at.lng <= box.east;
12
+ }
13
+ /** Whether one box lies within another. */
14
+ export function boxWithin(inner, outer) {
15
+ if (inner.south < outer.south || inner.north > outer.north)
16
+ return false;
17
+ if (whole(outer))
18
+ return true;
19
+ // Each as a stretch eastwards from its west edge; the inner one a world further round, if that is where it fits.
20
+ const span = (box) => [box.west, box.east < box.west ? box.east + 360 : box.east];
21
+ const [w, e] = span(outer);
22
+ const [iw, ie] = span(inner);
23
+ return [0, 360].some((by) => iw + by >= w && ie + by <= e);
24
+ }
25
+ /**
26
+ * The view a search already holds, as the map's "Search this area" puts it
27
+ * (its very conditions, found among the search's), and the search's other
28
+ * conditions: a new view takes its place, as a search bar keeps one.
29
+ */
30
+ export function ownBox(spec, filter) {
31
+ const said = filter.map((item) => JSON.stringify(item));
32
+ const numbers = (value) => (Array.isArray(value) && value.length === 2 && value.every((n) => typeof n === 'number') ? value : null);
33
+ const boxes = [];
34
+ for (const item of filter) {
35
+ if ('any' in item || 'all' in item)
36
+ continue;
37
+ const v = item.value;
38
+ if (spec.point) {
39
+ if (item.field === spec.point && item.op === 'within' && v && ['south', 'west', 'north', 'east'].every((k) => typeof v[k] === 'number'))
40
+ boxes.push(v);
41
+ continue;
42
+ }
43
+ const lat = item.field === spec.latitude && item.op === 'between' ? numbers(v) : null;
44
+ if (!lat)
45
+ continue;
46
+ // Its longitudes: a range, either side of the antimeridian, or (tried last) the world round.
47
+ const sides = [];
48
+ for (const other of filter) {
49
+ if ('any' in other && other.any.length === 2) {
50
+ const [a, b] = other.any;
51
+ if (a.field === spec.longitude && b.field === spec.longitude && typeof a.value === 'number' && typeof b.value === 'number')
52
+ sides.push([a.value, b.value]);
53
+ }
54
+ else if (!('all' in other) && !('any' in other) && other.field === spec.longitude && other.op === 'between' && numbers(other.value))
55
+ sides.push(numbers(other.value));
56
+ }
57
+ for (const [west, east] of [...sides, [-180, 180]])
58
+ boxes.push({ south: lat[0], west, north: lat[1], east });
59
+ }
60
+ for (const box of boxes) {
61
+ const own = boxFilter(spec, box).map((item) => JSON.stringify(item));
62
+ if (!own.every((item) => said.includes(item)))
63
+ continue;
64
+ return { box: { ...box }, rest: filter.filter((_, i) => !own.includes(said[i])) };
65
+ }
66
+ return null;
67
+ }
68
+ /**
69
+ * One question at a time, the last one winning: each ask waits `wait`
70
+ * milliseconds (a run of moves asks once), aborts the one before it, and an
71
+ * answer that comes after a newer ask is dropped. A refusal says nothing.
72
+ */
73
+ export function lastAsk(wait) {
74
+ let timer;
75
+ let asking = null;
76
+ let asked = 0;
77
+ const stop = () => {
78
+ clearTimeout(timer);
79
+ asking?.abort();
80
+ asking = null;
81
+ asked++;
82
+ };
83
+ return {
84
+ ask(question, answer) {
85
+ stop();
86
+ const mine = asked;
87
+ timer = setTimeout(() => {
88
+ const controller = (asking = new AbortController());
89
+ question(controller.signal).then((value) => mine === asked && !controller.signal.aborted && answer(value), () => undefined);
90
+ }, wait);
91
+ },
92
+ stop,
93
+ };
94
+ }
95
+ /**
96
+ * The count for a view: the records on hand say it when they are all the
97
+ * search finds and the view lies within any area it already holds;
98
+ * otherwise `ask` (the app's count, or its source's) is asked, for the
99
+ * search with the view in the area's place, a moment after the map stops;
100
+ * otherwise there is no number.
101
+ */
102
+ export function areaCounter(spec, ask, say) {
103
+ const asker = lastAsk(400);
104
+ return {
105
+ count(view, shown) {
106
+ asker.stop();
107
+ const own = ownBox(spec, shown.filter);
108
+ if (shown.all && (!own || boxWithin(view, own.box)))
109
+ return say(shown.places.filter((at) => at && inBox(at, view)).length);
110
+ if (ask)
111
+ asker.ask((signal) => ask([...(own ? own.rest : shown.filter), ...boxFilter(spec, view)], signal), say);
112
+ },
113
+ stop: asker.stop,
114
+ };
115
+ }
116
+ //# sourceMappingURL=area-count.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"area-count.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/area-count.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,18 @@
1
- import type { Locale, MapCard, Page } from '@fieldia/core';
1
+ import { type CardLine, type Locale, type MapCard, type Page, type Value } from '@fieldia/core';
2
2
  import { type ListMapLabels, type MapLabels } from './labels.mjs';
3
3
  import { type MapRecord } from './pins.mjs';
4
4
  /**
5
5
  * The card a pin opens on a list's map: the record's picture, its title,
6
- * the few fields the page names, a box to choose it (the same choice as its
6
+ * the lines the page names, a box to choose it (the same choice as its
7
7
  * row's) and a button to open it. Written in the page's direction, though
8
- * the map under it is left to right; every word goes in as text.
8
+ * the map under it is left to right; every word goes in as text, and each
9
+ * of the record's words in its own direction: an English name on an Arabic
10
+ * page reads as typed, "280 m²" stays "280 m²".
11
+ *
12
+ * A page may write its lines bare ("13,900,000 EGP", "Sheikh Zayed · 4 beds
13
+ * · 280 m²"), their labels kept for a screen reader; lead with the first;
14
+ * link the title and the picture to the record's own address; and leave the
15
+ * box to choose off a map people only look at.
9
16
  */
10
17
  export interface CardOptions {
11
18
  document: Document;
@@ -16,8 +23,8 @@ export interface CardOptions {
16
23
  card: MapCard;
17
24
  /** The field that names the record. */
18
25
  title: string;
19
- /** The fields the card shows, in order. */
20
- fields: string[];
26
+ /** The lines the card shows, in order: a field, a field with its words, or several on one line. */
27
+ fields: CardLine[];
21
28
  record: MapRecord;
22
29
  /** A box to choose the record, as its row's is: a list's map has one, a form's does not. */
23
30
  chosen?: boolean;
@@ -38,8 +45,10 @@ export interface Card {
38
45
  /** Where focus goes when the card was opened from the keyboard. */
39
46
  focus(): void;
40
47
  }
48
+ /** A record's address on the web, when a link may go there: a web, mail or phone address, or a path of this site; never a script. */
49
+ export declare function webAddress(value: Value | undefined): string;
41
50
  export declare function drawCard(options: CardOptions): Card;
42
- /** Pins on one spot that no zoom parts: a list of them, each opening its own card. */
51
+ /** Pins on one spot that no zoom parts: a list of them, each opening its own card; one with no card is only named. */
43
52
  export declare function drawCrowd(options: {
44
53
  document: Document;
45
54
  labels: ListMapLabels;
@@ -47,6 +56,7 @@ export declare function drawCrowd(options: {
47
56
  records: {
48
57
  record: MapRecord;
49
58
  name: string;
59
+ plain?: boolean;
50
60
  }[];
51
61
  pick(record: MapRecord): void;
52
62
  close(): void;
package/src/lib/card.d.ts CHANGED
@@ -1,11 +1,18 @@
1
- import type { Locale, MapCard, Page } from '@fieldia/core';
1
+ import { type CardLine, type Locale, type MapCard, type Page, type Value } from '@fieldia/core';
2
2
  import { type ListMapLabels, type MapLabels } from './labels';
3
3
  import { type MapRecord } from './pins';
4
4
  /**
5
5
  * The card a pin opens on a list's map: the record's picture, its title,
6
- * the few fields the page names, a box to choose it (the same choice as its
6
+ * the lines the page names, a box to choose it (the same choice as its
7
7
  * row's) and a button to open it. Written in the page's direction, though
8
- * the map under it is left to right; every word goes in as text.
8
+ * the map under it is left to right; every word goes in as text, and each
9
+ * of the record's words in its own direction: an English name on an Arabic
10
+ * page reads as typed, "280 m²" stays "280 m²".
11
+ *
12
+ * A page may write its lines bare ("13,900,000 EGP", "Sheikh Zayed · 4 beds
13
+ * · 280 m²"), their labels kept for a screen reader; lead with the first;
14
+ * link the title and the picture to the record's own address; and leave the
15
+ * box to choose off a map people only look at.
9
16
  */
10
17
  export interface CardOptions {
11
18
  document: Document;
@@ -16,8 +23,8 @@ export interface CardOptions {
16
23
  card: MapCard;
17
24
  /** The field that names the record. */
18
25
  title: string;
19
- /** The fields the card shows, in order. */
20
- fields: string[];
26
+ /** The lines the card shows, in order: a field, a field with its words, or several on one line. */
27
+ fields: CardLine[];
21
28
  record: MapRecord;
22
29
  /** A box to choose the record, as its row's is: a list's map has one, a form's does not. */
23
30
  chosen?: boolean;
@@ -38,8 +45,10 @@ export interface Card {
38
45
  /** Where focus goes when the card was opened from the keyboard. */
39
46
  focus(): void;
40
47
  }
48
+ /** A record's address on the web, when a link may go there: a web, mail or phone address, or a path of this site; never a script. */
49
+ export declare function webAddress(value: Value | undefined): string;
41
50
  export declare function drawCard(options: CardOptions): Card;
42
- /** Pins on one spot that no zoom parts: a list of them, each opening its own card. */
51
+ /** Pins on one spot that no zoom parts: a list of them, each opening its own card; one with no card is only named. */
43
52
  export declare function drawCrowd(options: {
44
53
  document: Document;
45
54
  labels: ListMapLabels;
@@ -47,6 +56,7 @@ export declare function drawCrowd(options: {
47
56
  records: {
48
57
  record: MapRecord;
49
58
  name: string;
59
+ plain?: boolean;
50
60
  }[];
51
61
  pick(record: MapRecord): void;
52
62
  close(): void;
package/src/lib/card.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.webAddress = webAddress;
3
4
  exports.drawCard = drawCard;
4
5
  exports.drawCrowd = drawCrowd;
6
+ const core_1 = require("@fieldia/core");
5
7
  const labels_1 = require("./labels");
6
8
  const pins_1 = require("./pins");
7
9
  function make(doc, tag, className, ...children) {
@@ -18,30 +20,83 @@ function closeButton(doc, labels, close) {
18
20
  button.addEventListener('click', close);
19
21
  return button;
20
22
  }
23
+ /** A record's address on the web, when a link may go there: a web, mail or phone address, or a path of this site; never a script. */
24
+ function webAddress(value) {
25
+ const text = typeof value === 'string' ? value.trim() : '';
26
+ const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(text)?.[1].toLowerCase();
27
+ return text && (!scheme || ['http', 'https', 'mailto', 'tel'].includes(scheme)) ? text : '';
28
+ }
29
+ const plurals = new Map();
30
+ /** The words after a number, in the plural form the page's language gives it: "1 bed", "4 beds". */
31
+ function unitWords(unit, value, locale) {
32
+ if (typeof unit === 'string')
33
+ return unit;
34
+ let rules = plurals.get(locale);
35
+ if (!rules)
36
+ plurals.set(locale, (rules = new Intl.PluralRules(locale)));
37
+ const form = typeof value === 'number' ? rules.select(value) : 'other';
38
+ return unit[form] ?? unit.other;
39
+ }
40
+ /** A part of a line as words: its value as the field shows it, and its own words after it, kept on one line with it. */
41
+ function partWords(page, part, values, locale) {
42
+ const said = (0, pins_1.shown)(page, part.field, values, locale);
43
+ if (said === '' || part.unit === undefined)
44
+ return said;
45
+ const unit = unitWords(part.unit, values[part.field], locale);
46
+ return unit ? `${said}\u00a0${unit}` : said;
47
+ }
21
48
  function drawCard(options) {
22
- const { document: doc, page, locale, labels, record } = options;
49
+ const { document: doc, page, locale, labels, record, card } = options;
23
50
  const title = (0, pins_1.shown)(page, options.title, record.values, locale) || String(record.id);
24
51
  const element = make(doc, 'div', 'fd-map-card');
25
52
  element.dir = options.dir;
26
53
  element.setAttribute('role', 'group');
27
54
  element.setAttribute('aria-label', title);
28
55
  element.dataset['id'] = String(record.id);
29
- const picture = options.card.image ? (0, pins_1.imageSource)(record.values[options.card.image]) : '';
56
+ const href = card.href ? webAddress(record.values[card.href]) : '';
57
+ /** A link to the record's own address: one a person can open in a new tab, or copy. */
58
+ const link = (className, ...children) => {
59
+ const a = make(doc, 'a', className, ...children);
60
+ a.href = href;
61
+ return a;
62
+ };
63
+ const picture = card.image ? (0, pins_1.imageSource)(record.values[card.image]) : '';
30
64
  if (picture) {
31
65
  const img = make(doc, 'img', 'fd-map-card-image');
32
66
  img.alt = '';
33
67
  img.decoding = 'async';
34
68
  img.src = picture;
35
- element.append(img);
69
+ // The picture goes where the title does; the title's link is the one the keys and a screen reader reach.
70
+ if (href) {
71
+ const to = link('fd-map-card-picture', img);
72
+ to.tabIndex = -1;
73
+ to.setAttribute('aria-hidden', 'true');
74
+ element.append(to);
75
+ }
76
+ else
77
+ element.append(img);
36
78
  }
37
79
  const body = make(doc, 'div', 'fd-map-card-body');
38
80
  const close = closeButton(doc, labels, options.close);
39
- body.append(make(doc, 'div', 'fd-map-card-head', make(doc, 'strong', 'fd-map-card-title', title), close));
40
- const lines = options.fields
41
- .map((name) => [page.fields[name]?.label ?? name, (0, pins_1.shown)(page, name, record.values, locale)])
42
- .filter(([, value]) => value !== '');
43
- if (lines.length)
44
- body.append(make(doc, 'dl', 'fd-map-card-fields', ...lines.map(([label, value]) => make(doc, 'div', '', make(doc, 'dt', '', label), make(doc, 'dd', '', value)))));
81
+ const name = make(doc, 'bdi', '', title);
82
+ body.append(make(doc, 'div', 'fd-map-card-head', make(doc, 'strong', 'fd-map-card-title', href ? link('fd-map-card-link', name) : name), close));
83
+ // Each line: its label (or its parts' labels), and its parts, each a value in its own direction, parted by a dot.
84
+ const lines = (0, core_1.cardLines)({ fields: options.fields })
85
+ .map((parts) => parts.map((part) => ({ part, said: partWords(page, part, record.values, locale) })).filter(({ said }) => said !== ''))
86
+ .filter((parts) => parts.length);
87
+ if (lines.length) {
88
+ const list = make(doc, 'dl', 'fd-map-card-fields', ...lines.map((parts) => {
89
+ const label = parts.map(({ part }) => page.fields[part.field]?.label ?? part.field).join(' · ');
90
+ const value = make(doc, 'dd', '', ...parts.flatMap(({ said }, i) => [...(i ? [' · '] : []), make(doc, 'bdi', '', said)]));
91
+ return make(doc, 'div', '', make(doc, 'dt', '', label), value);
92
+ }));
93
+ // Bare values, their labels said to a screen reader alone; the first line leading.
94
+ if (card.labels === false)
95
+ list.dataset['labels'] = 'hidden';
96
+ if (card.lead)
97
+ list.toggleAttribute('data-lead', true);
98
+ body.append(list);
99
+ }
45
100
  const box = make(doc, 'input', 'fd-map-card-check');
46
101
  box.type = 'checkbox';
47
102
  box.checked = !!options.chosen;
@@ -56,7 +111,7 @@ function drawCard(options) {
56
111
  actions.append(button);
57
112
  first = button;
58
113
  }
59
- if (options.open && options.card.open !== false) {
114
+ if (options.open && card.open !== false) {
60
115
  const open = make(doc, 'button', 'fd-button fd-button-primary fd-map-card-open', labels.openRecord);
61
116
  open.type = 'button';
62
117
  open.addEventListener('click', () => options.open?.());
@@ -72,7 +127,7 @@ function drawCard(options) {
72
127
  focus: () => first.focus(),
73
128
  };
74
129
  }
75
- /** Pins on one spot that no zoom parts: a list of them, each opening its own card. */
130
+ /** Pins on one spot that no zoom parts: a list of them, each opening its own card; one with no card is only named. */
76
131
  function drawCrowd(options) {
77
132
  const { document: doc, labels } = options;
78
133
  const heading = (0, labels_1.fill)(labels.crowd, { n: options.records.length });
@@ -81,8 +136,10 @@ function drawCrowd(options) {
81
136
  element.setAttribute('role', 'group');
82
137
  element.setAttribute('aria-label', heading);
83
138
  const close = closeButton(doc, labels, options.close);
84
- const items = options.records.map(({ record, name }) => {
85
- const button = make(doc, 'button', 'fd-map-crowd-item', name);
139
+ const items = options.records.map(({ record, name, plain }) => {
140
+ if (plain)
141
+ return make(doc, 'li', '', make(doc, 'span', 'fd-map-crowd-item', make(doc, 'bdi', '', name)));
142
+ const button = make(doc, 'button', 'fd-map-crowd-item', make(doc, 'bdi', '', name));
86
143
  button.type = 'button';
87
144
  button.dataset['id'] = String(record.id);
88
145
  button.addEventListener('click', () => options.pick(record));
@@ -92,7 +149,7 @@ function drawCrowd(options) {
92
149
  return {
93
150
  element,
94
151
  setChosen: () => undefined,
95
- focus: () => (items[0]?.querySelector('button') ?? close).focus(),
152
+ focus: () => (element.querySelector('.fd-map-crowd-list button') ?? close).focus(),
96
153
  };
97
154
  }
98
155
  //# sourceMappingURL=card.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"card.js","sourceRoot":"","sources":["../../../../../libs/map/src/lib/card.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"card.js","sourceRoot":"","sources":["../../../../../libs/map/src/lib/card.ts"],"names":[],"mappings":"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"}