@fieldia/map 0.18.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 (126) hide show
  1. package/README.md +53 -0
  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 +14 -5
  46. package/src/lib/card.d.ts +14 -5
  47. package/src/lib/card.js +67 -12
  48. package/src/lib/card.js.map +1 -1
  49. package/src/lib/card.mjs +66 -12
  50. package/src/lib/card.mjs.map +1 -1
  51. package/src/lib/embed.d.mts +86 -0
  52. package/src/lib/embed.d.ts +86 -0
  53. package/src/lib/embed.js +96 -0
  54. package/src/lib/embed.js.map +1 -0
  55. package/src/lib/embed.mjs +93 -0
  56. package/src/lib/embed.mjs.map +1 -0
  57. package/src/lib/kinds.d.mts +6 -4
  58. package/src/lib/kinds.d.ts +6 -4
  59. package/src/lib/kinds.js +49 -2
  60. package/src/lib/kinds.js.map +1 -1
  61. package/src/lib/kinds.mjs +49 -2
  62. package/src/lib/kinds.mjs.map +1 -1
  63. package/src/lib/labels.d.mts +2 -0
  64. package/src/lib/labels.d.ts +2 -0
  65. package/src/lib/labels.js +4 -0
  66. package/src/lib/labels.js.map +1 -1
  67. package/src/lib/labels.mjs +4 -0
  68. package/src/lib/labels.mjs.map +1 -1
  69. package/src/lib/list-view.d.mts +37 -1
  70. package/src/lib/list-view.d.ts +37 -1
  71. package/src/lib/list-view.js +97 -37
  72. package/src/lib/list-view.js.map +1 -1
  73. package/src/lib/list-view.mjs +97 -38
  74. package/src/lib/list-view.mjs.map +1 -1
  75. package/src/lib/map-core.d.mts +6 -1
  76. package/src/lib/map-core.d.ts +6 -1
  77. package/src/lib/map-core.js +13 -5
  78. package/src/lib/map-core.js.map +1 -1
  79. package/src/lib/map-core.mjs +13 -5
  80. package/src/lib/map-core.mjs.map +1 -1
  81. package/src/lib/pins.d.mts +20 -8
  82. package/src/lib/pins.d.ts +20 -8
  83. package/src/lib/pins.js +60 -15
  84. package/src/lib/pins.js.map +1 -1
  85. package/src/lib/pins.mjs +60 -17
  86. package/src/lib/pins.mjs.map +1 -1
  87. package/src/lib/place.js +2 -1
  88. package/src/lib/place.js.map +1 -1
  89. package/src/lib/place.mjs +2 -1
  90. package/src/lib/place.mjs.map +1 -1
  91. package/src/lib/providers.d.mts +10 -0
  92. package/src/lib/providers.d.ts +10 -0
  93. package/src/lib/providers.js +50 -40
  94. package/src/lib/providers.js.map +1 -1
  95. package/src/lib/providers.mjs +50 -40
  96. package/src/lib/providers.mjs.map +1 -1
  97. package/src/lib/regions.js +18 -1
  98. package/src/lib/regions.js.map +1 -1
  99. package/src/lib/regions.mjs +18 -1
  100. package/src/lib/regions.mjs.map +1 -1
  101. package/src/lib/search-box.d.mts +7 -1
  102. package/src/lib/search-box.d.ts +7 -1
  103. package/src/lib/search-box.js +15 -10
  104. package/src/lib/search-box.js.map +1 -1
  105. package/src/lib/search-box.mjs +15 -10
  106. package/src/lib/search-box.mjs.map +1 -1
  107. package/src/lib/settings.d.mts +19 -2
  108. package/src/lib/settings.d.ts +19 -2
  109. package/src/lib/styles.d.mts +12 -1
  110. package/src/lib/styles.d.ts +12 -1
  111. package/src/lib/styles.js +61 -3
  112. package/src/lib/styles.js.map +1 -1
  113. package/src/lib/styles.mjs +59 -2
  114. package/src/lib/styles.mjs.map +1 -1
  115. package/src/lib/view-box.d.mts +18 -0
  116. package/src/lib/view-box.d.ts +18 -0
  117. package/src/lib/view-box.js +31 -0
  118. package/src/lib/view-box.js.map +1 -0
  119. package/src/lib/view-box.mjs +25 -0
  120. package/src/lib/view-box.mjs.map +1 -0
  121. package/src/lib/widgets.d.mts +3 -0
  122. package/src/lib/widgets.d.ts +3 -0
  123. package/src/lib/widgets.js +10 -1
  124. package/src/lib/widgets.js.map +1 -1
  125. package/src/lib/widgets.mjs +10 -1
  126. package/src/lib/widgets.mjs.map +1 -1
@@ -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,6 +45,8 @@ 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
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: {
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,6 +45,8 @@ 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
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: {
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?.());
@@ -83,8 +138,8 @@ function drawCrowd(options) {
83
138
  const close = closeButton(doc, labels, options.close);
84
139
  const items = options.records.map(({ record, name, plain }) => {
85
140
  if (plain)
86
- return make(doc, 'li', '', make(doc, 'span', 'fd-map-crowd-item', name));
87
- const button = make(doc, 'button', 'fd-map-crowd-item', name);
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));
88
143
  button.type = 'button';
89
144
  button.dataset['id'] = String(record.id);
90
145
  button.addEventListener('click', () => options.pick(record));
@@ -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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"}
package/src/lib/card.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { cardLines } from '@fieldia/core';
1
2
  import { fill } from './labels.mjs';
2
3
  import { imageSource, shown } from './pins.mjs';
3
4
  function make(doc, tag, className, ...children) {
@@ -14,30 +15,83 @@ function closeButton(doc, labels, close) {
14
15
  button.addEventListener('click', close);
15
16
  return button;
16
17
  }
18
+ /** 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. */
19
+ export function webAddress(value) {
20
+ const text = typeof value === 'string' ? value.trim() : '';
21
+ const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(text)?.[1].toLowerCase();
22
+ return text && (!scheme || ['http', 'https', 'mailto', 'tel'].includes(scheme)) ? text : '';
23
+ }
24
+ const plurals = new Map();
25
+ /** The words after a number, in the plural form the page's language gives it: "1 bed", "4 beds". */
26
+ function unitWords(unit, value, locale) {
27
+ if (typeof unit === 'string')
28
+ return unit;
29
+ let rules = plurals.get(locale);
30
+ if (!rules)
31
+ plurals.set(locale, (rules = new Intl.PluralRules(locale)));
32
+ const form = typeof value === 'number' ? rules.select(value) : 'other';
33
+ return unit[form] ?? unit.other;
34
+ }
35
+ /** 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. */
36
+ function partWords(page, part, values, locale) {
37
+ const said = shown(page, part.field, values, locale);
38
+ if (said === '' || part.unit === undefined)
39
+ return said;
40
+ const unit = unitWords(part.unit, values[part.field], locale);
41
+ return unit ? `${said}\u00a0${unit}` : said;
42
+ }
17
43
  export function drawCard(options) {
18
- const { document: doc, page, locale, labels, record } = options;
44
+ const { document: doc, page, locale, labels, record, card } = options;
19
45
  const title = shown(page, options.title, record.values, locale) || String(record.id);
20
46
  const element = make(doc, 'div', 'fd-map-card');
21
47
  element.dir = options.dir;
22
48
  element.setAttribute('role', 'group');
23
49
  element.setAttribute('aria-label', title);
24
50
  element.dataset['id'] = String(record.id);
25
- const picture = options.card.image ? imageSource(record.values[options.card.image]) : '';
51
+ const href = card.href ? webAddress(record.values[card.href]) : '';
52
+ /** A link to the record's own address: one a person can open in a new tab, or copy. */
53
+ const link = (className, ...children) => {
54
+ const a = make(doc, 'a', className, ...children);
55
+ a.href = href;
56
+ return a;
57
+ };
58
+ const picture = card.image ? imageSource(record.values[card.image]) : '';
26
59
  if (picture) {
27
60
  const img = make(doc, 'img', 'fd-map-card-image');
28
61
  img.alt = '';
29
62
  img.decoding = 'async';
30
63
  img.src = picture;
31
- element.append(img);
64
+ // The picture goes where the title does; the title's link is the one the keys and a screen reader reach.
65
+ if (href) {
66
+ const to = link('fd-map-card-picture', img);
67
+ to.tabIndex = -1;
68
+ to.setAttribute('aria-hidden', 'true');
69
+ element.append(to);
70
+ }
71
+ else
72
+ element.append(img);
32
73
  }
33
74
  const body = make(doc, 'div', 'fd-map-card-body');
34
75
  const close = closeButton(doc, labels, options.close);
35
- body.append(make(doc, 'div', 'fd-map-card-head', make(doc, 'strong', 'fd-map-card-title', title), close));
36
- const lines = options.fields
37
- .map((name) => [page.fields[name]?.label ?? name, shown(page, name, record.values, locale)])
38
- .filter(([, value]) => value !== '');
39
- if (lines.length)
40
- body.append(make(doc, 'dl', 'fd-map-card-fields', ...lines.map(([label, value]) => make(doc, 'div', '', make(doc, 'dt', '', label), make(doc, 'dd', '', value)))));
76
+ const name = make(doc, 'bdi', '', title);
77
+ 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));
78
+ // Each line: its label (or its parts' labels), and its parts, each a value in its own direction, parted by a dot.
79
+ const lines = cardLines({ fields: options.fields })
80
+ .map((parts) => parts.map((part) => ({ part, said: partWords(page, part, record.values, locale) })).filter(({ said }) => said !== ''))
81
+ .filter((parts) => parts.length);
82
+ if (lines.length) {
83
+ const list = make(doc, 'dl', 'fd-map-card-fields', ...lines.map((parts) => {
84
+ const label = parts.map(({ part }) => page.fields[part.field]?.label ?? part.field).join(' · ');
85
+ const value = make(doc, 'dd', '', ...parts.flatMap(({ said }, i) => [...(i ? [' · '] : []), make(doc, 'bdi', '', said)]));
86
+ return make(doc, 'div', '', make(doc, 'dt', '', label), value);
87
+ }));
88
+ // Bare values, their labels said to a screen reader alone; the first line leading.
89
+ if (card.labels === false)
90
+ list.dataset['labels'] = 'hidden';
91
+ if (card.lead)
92
+ list.toggleAttribute('data-lead', true);
93
+ body.append(list);
94
+ }
41
95
  const box = make(doc, 'input', 'fd-map-card-check');
42
96
  box.type = 'checkbox';
43
97
  box.checked = !!options.chosen;
@@ -52,7 +106,7 @@ export function drawCard(options) {
52
106
  actions.append(button);
53
107
  first = button;
54
108
  }
55
- if (options.open && options.card.open !== false) {
109
+ if (options.open && card.open !== false) {
56
110
  const open = make(doc, 'button', 'fd-button fd-button-primary fd-map-card-open', labels.openRecord);
57
111
  open.type = 'button';
58
112
  open.addEventListener('click', () => options.open?.());
@@ -79,8 +133,8 @@ export function drawCrowd(options) {
79
133
  const close = closeButton(doc, labels, options.close);
80
134
  const items = options.records.map(({ record, name, plain }) => {
81
135
  if (plain)
82
- return make(doc, 'li', '', make(doc, 'span', 'fd-map-crowd-item', name));
83
- const button = make(doc, 'button', 'fd-map-crowd-item', name);
136
+ return make(doc, 'li', '', make(doc, 'span', 'fd-map-crowd-item', make(doc, 'bdi', '', name)));
137
+ const button = make(doc, 'button', 'fd-map-crowd-item', make(doc, 'bdi', '', name));
84
138
  button.type = 'button';
85
139
  button.dataset['id'] = String(record.id);
86
140
  button.addEventListener('click', () => options.pick(record));
@@ -1 +1 @@
1
- {"version":3,"file":"card.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/card.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"card.mjs","sourceRoot":"","sources":["../../../../../libs/map/src/lib/card.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import { type DataSource, type Page, type RecordId, type ResolvedFilter, type SortOrder } from '@fieldia/core';
2
+ import type { ListViewPart } from '@fieldia/viewer';
3
+ import type { IconSet } from '@fieldia/widgets';
4
+ import type { LatLng } from './geo.mjs';
5
+ import { type MapSearch, type MapViewChange } from './list-view.mjs';
6
+ import type { MapRecord } from './pins.mjs';
7
+ import type { MapSettings } from './settings.mjs';
8
+ /**
9
+ * A list's map in a page of the app's own, outside the viewer: the page's
10
+ * own list, filters and address beside it, the map drawn by Fieldia. The
11
+ * app gives the page that describes the records (a list with `map`), where
12
+ * the records come from, the search they were found by, and what to do when
13
+ * the map asks for something; it gets the map back, to reload and destroy.
14
+ * The map brings its own base (its buttons, a part hidden, words for a
15
+ * screen reader) on its own element, and Fieldia's colours as tokens the
16
+ * page can set: none of it reaches the page round it.
17
+ *
18
+ * const map = mountListMap(element, {
19
+ * page, // a list page with "map"
20
+ * provider: azureMaps({ key }),
21
+ * dataSource, // or records: [...]
22
+ * filter: () => searchNow(), // the conditions the records are found by
23
+ * start: { center: { lat: 30.05, lng: 31.23 }, zoom: 12 }, // from the address, say
24
+ * onSearch: ({ kind, filter }) => { keep(kind, filter); map.reload(); },
25
+ * onViewChange: ({ center, zoom }) => history.replaceState(null, '', `?at=${center.lat},${center.lng},${zoom}`),
26
+ * onOpenRecord: (id) => location.assign(`/homes/${id}`),
27
+ * onHighlight: (id) => lightRow(id),
28
+ * });
29
+ */
30
+ export interface ListMapOptions extends MapSettings {
31
+ /** The page that describes the records: their fields, and a list with `map` (where each is, its pin, its card, its height, its gestures). */
32
+ page: Page;
33
+ /** Where the records come from: a source with `list`, asked with the search, the list's order and the map's `limit`. */
34
+ dataSource?: DataSource;
35
+ /** Or the records themselves, found already: each `{ id, values }`, or a function giving them, asked again at each `reload()`. */
36
+ records?: readonly MapRecord[] | (() => readonly MapRecord[] | Promise<readonly MapRecord[]>);
37
+ /** The language: a tag such as `ar-EG`; Fieldia's words in English, Arabic, French or German, and the page's own `translations`. The document's language unless said. */
38
+ locale?: string;
39
+ /**
40
+ * The conditions the records are found by now, as a search bar's are: the
41
+ * map asks its source with them, draws the areas among them, and counts
42
+ * a view within them. A search the map asked for is among them once the app
43
+ * has taken it.
44
+ */
45
+ filter?: readonly ResolvedFilter[] | (() => readonly ResolvedFilter[]);
46
+ /** The order the records come in: the map shows the same first ones as the page's own list. */
47
+ sort?: readonly SortOrder[] | (() => readonly SortOrder[]);
48
+ /** Where the map opens, from the page's address, say: there it fits no records at first, until the search changes. */
49
+ start?: {
50
+ center: LatLng;
51
+ zoom: number;
52
+ };
53
+ /** The app's icons for the pins, besides Fieldia's and the map's own. */
54
+ icons?: IconSet;
55
+ /** The page's buttons for one record, offered on its card: "Book a viewing". */
56
+ actions?: {
57
+ id: string;
58
+ label: string;
59
+ style?: 'primary' | 'secondary' | 'danger' | 'link';
60
+ }[];
61
+ /** A card's Open: the card has the button when this is given. */
62
+ onOpenRecord?: (id: RecordId) => void;
63
+ /** A pin under the pointer or the focus (null when none): light the record in the page's own list. */
64
+ onHighlight?: (id: RecordId | null) => void;
65
+ /**
66
+ * The map asks for a search: its view (`kind: 'view'`, "Search this area"),
67
+ * an area drawn (`drawn`), or a shaded area pressed (`region`). The app
68
+ * keeps one of each kind, a new one in the last one's place, as a search bar
69
+ * does, puts its conditions in `filter`, and calls `reload()`. Without it the
70
+ * map offers no search: no "Search this area", no tools to draw an area.
71
+ */
72
+ onSearch?: (search: MapSearch) => void;
73
+ /** The map has stopped, after a move or a zoom: where it stands, to keep in the page's address. Each view once. */
74
+ onViewChange?: (view: MapViewChange) => void;
75
+ /** Whether a record is chosen, and a choice made on its card; the map keeps its own choice when these are not given. */
76
+ isChosen?: (id: RecordId) => boolean;
77
+ onChoose?: (id: RecordId, chosen: boolean) => void;
78
+ /** One of `actions` pressed on a record's card: the button is busy until it is done. */
79
+ onAction?: (id: string, ids: RecordId[]) => void | Promise<void>;
80
+ /** "Nearest first" pressed: the order the page's own list should take too (null: its own again). */
81
+ onSort?: (order: SortOrder[] | null) => void;
82
+ }
83
+ /** A list's map in a page: its element (already in the page), and what the page asks of it. */
84
+ export type ListMapHandle = ListViewPart;
85
+ /** Puts a list's map into `host`, loads its records, and hands it back. Throws when the page cannot be shown, saying why. */
86
+ export declare function mountListMap(host: HTMLElement, options: ListMapOptions): ListMapHandle;