@escape-game-over/atlas 0.1.94 → 0.1.96
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/docs/rich-text.md +4 -0
- package/package.json +4 -3
- package/src/astro/Phone.astro +34 -0
- package/src/astro/RichText.astro +10 -0
- package/src/jsonld/business.ts +11 -2
- package/src/jsonld/ids.ts +17 -5
package/docs/rich-text.md
CHANGED
|
@@ -252,6 +252,10 @@ per `[v:name]` and one for links — usually in a small wrapper
|
|
|
252
252
|
</p>
|
|
253
253
|
```
|
|
254
254
|
|
|
255
|
+
A `[tel]` link renders with `dir="ltr"`: a number has no letters to set its
|
|
256
|
+
direction, and on a right-to-left page it would otherwise read "0100 555 202 1+".
|
|
257
|
+
A number on its own, outside copy, is `@escape-game-over/atlas/astro/phone`.
|
|
258
|
+
|
|
255
259
|
`attrs` puts attributes on a variant's run, so a script can find it and rewrite
|
|
256
260
|
its words — see [client-scripts.md](client-scripts.md). A variant with neither a
|
|
257
261
|
class nor attrs still renders its words, and warns at build.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@escape-game-over/atlas",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.96",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Typed, data-driven machinery for static multi-locale, multi-deployment Astro sites.",
|
|
6
6
|
"private": false,
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"./astro/element": "./src/astro/AtlasElement.astro",
|
|
24
24
|
"./astro/google-map": "./src/astro/GoogleMap.astro",
|
|
25
25
|
"./astro/image": "./src/astro/Image.astro",
|
|
26
|
+
"./astro/phone": "./src/astro/Phone.astro",
|
|
26
27
|
"./astro/rich-text": "./src/astro/RichText.astro"
|
|
27
28
|
},
|
|
28
29
|
"bin": {
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
"check-fmt": "biome check . --error-on-warnings"
|
|
51
52
|
},
|
|
52
53
|
"dependencies": {
|
|
53
|
-
"@types/google.maps": "3.66.
|
|
54
|
+
"@types/google.maps": "3.66.10"
|
|
54
55
|
},
|
|
55
56
|
"peerDependencies": {
|
|
56
57
|
"@types/node": ">=22",
|
|
@@ -59,7 +60,7 @@
|
|
|
59
60
|
"vite": ">= 8"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
|
-
"@biomejs/biome": "2.6.
|
|
63
|
+
"@biomejs/biome": "2.6.6",
|
|
63
64
|
"@types/node": "26.6.6",
|
|
64
65
|
"@vitest/coverage-istanbul": "5.1.0",
|
|
65
66
|
"astro": "7.4.7",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* A phone number on the page, kept left to right on a right-to-left one.
|
|
4
|
+
*
|
|
5
|
+
* ```astro
|
|
6
|
+
* <a href={telHref(phone)}><Phone phone={phone} /></a>
|
|
7
|
+
* ```
|
|
8
|
+
*
|
|
9
|
+
* "+1 202 555 0100" has no letters to set its direction, so on an Arabic page
|
|
10
|
+
* the browser would lay it out right to left and show "0100 555 202 1+". Its own
|
|
11
|
+
* element with `dir="ltr"` keeps it whole, the way the page expects a number
|
|
12
|
+
* to read, and copies as just the number. An email needs none of this: its
|
|
13
|
+
* letters already make it read left to right.
|
|
14
|
+
*
|
|
15
|
+
* Where a number sits inside copy, the `[tel]` mark does the same; this is for
|
|
16
|
+
* a number on its own. `formatPhone` stays plain text, for an aria label or a
|
|
17
|
+
* sentence built as a string.
|
|
18
|
+
*/
|
|
19
|
+
import type { HTMLAttributes } from "astro/types";
|
|
20
|
+
import { formatPhone, type PhoneNumber } from "../contact.ts";
|
|
21
|
+
|
|
22
|
+
// Anything a span takes, but not `dir`: that is the point of the component.
|
|
23
|
+
type Props = Omit<HTMLAttributes<"span">, "dir"> & {
|
|
24
|
+
readonly phone: PhoneNumber;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const { phone, ...rest } = Astro.props;
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
<span
|
|
31
|
+
{...rest}
|
|
32
|
+
dir="ltr"
|
|
33
|
+
>{formatPhone(phone)}</span
|
|
34
|
+
>
|
package/src/astro/RichText.astro
CHANGED
|
@@ -74,10 +74,20 @@ const variantAttrs = (variant: string) =>
|
|
|
74
74
|
</a>
|
|
75
75
|
);
|
|
76
76
|
case "mail":
|
|
77
|
+
return (
|
|
78
|
+
<a
|
|
79
|
+
href={span.href}
|
|
80
|
+
class={link}>
|
|
81
|
+
{span.text}
|
|
82
|
+
</a>
|
|
83
|
+
);
|
|
84
|
+
// A number has no letters to set its direction; on a right-to-left
|
|
85
|
+
// page it would read "0100 555 202 1+". See `Phone.astro`.
|
|
77
86
|
case "tel":
|
|
78
87
|
return (
|
|
79
88
|
<a
|
|
80
89
|
href={span.href}
|
|
90
|
+
dir='ltr'
|
|
81
91
|
class={link}>
|
|
82
92
|
{span.text}
|
|
83
93
|
</a>
|
package/src/jsonld/business.ts
CHANGED
|
@@ -15,8 +15,17 @@ import { geoCoordinates, openingHours, postalAddress } from "./place.ts";
|
|
|
15
15
|
|
|
16
16
|
export interface LocalBusinessInput {
|
|
17
17
|
readonly name: string;
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* The page about it: the site, or one location's page on a site with
|
|
20
|
+
* several. Its origin carries the node's identity, see `@id` below.
|
|
21
|
+
*/
|
|
19
22
|
readonly url: HttpsUrl;
|
|
23
|
+
/**
|
|
24
|
+
* Which of the site's businesses this is, on a site with several: `north`
|
|
25
|
+
* makes the `@id` `<origin>#business-north`. Point at it with
|
|
26
|
+
* `businessId(url, location)`.
|
|
27
|
+
*/
|
|
28
|
+
readonly location?: string;
|
|
20
29
|
readonly address: PostalAddress;
|
|
21
30
|
/**
|
|
22
31
|
* Another name this venue actually goes by.
|
|
@@ -162,7 +171,7 @@ export interface LocalBusinessInput {
|
|
|
162
171
|
export function localBusiness(business: LocalBusinessInput): JsonLdNode {
|
|
163
172
|
return {
|
|
164
173
|
"@type": schemaType(business.type ?? "LocalBusiness"),
|
|
165
|
-
"@id": businessId(business.url),
|
|
174
|
+
"@id": businessId(business.url, business.location),
|
|
166
175
|
name: business.name,
|
|
167
176
|
...alternateName(business.name, business.alternateName),
|
|
168
177
|
url: business.url,
|
package/src/jsonld/ids.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type HttpsUrl, normalizeOrigin } from "../url.ts";
|
|
1
|
+
import { type HttpsUrl, isHttpsUrl, normalizeOrigin } from "../url.ts";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The `@id` each addressable node takes, and the types that keep them apart.
|
|
@@ -43,7 +43,9 @@ import { type HttpsUrl, normalizeOrigin } from "../url.ts";
|
|
|
43
43
|
* -checks, while the mistake this exists to stop — passing a bare URL where a
|
|
44
44
|
* reference belongs — does not.
|
|
45
45
|
*/
|
|
46
|
-
export type BusinessId =
|
|
46
|
+
export type BusinessId =
|
|
47
|
+
| `${HttpsUrl}#business`
|
|
48
|
+
| `${HttpsUrl}#business-${string}`;
|
|
47
49
|
|
|
48
50
|
/** The identity of a brand node. See `BusinessId`. */
|
|
49
51
|
export type OrganizationId = `${HttpsUrl}#organization`;
|
|
@@ -68,15 +70,25 @@ export type WebsiteId = `${HttpsUrl}#website`;
|
|
|
68
70
|
export type ServiceId = `${HttpsUrl}#service`;
|
|
69
71
|
|
|
70
72
|
/**
|
|
71
|
-
* The `@id` a business node takes
|
|
73
|
+
* The `@id` a business node takes: on the origin of `url`, whichever page of
|
|
74
|
+
* the site that is.
|
|
72
75
|
*
|
|
73
76
|
* Exported because a reference has to be built by whoever points at it, and the
|
|
74
77
|
* fragment must match exactly — a node linking to `#local-business` when the
|
|
75
78
|
* business calls itself `#business` is a dangling reference that no validator
|
|
76
79
|
* reports and no crawler resolves. One definition, used by both ends.
|
|
80
|
+
*
|
|
81
|
+
* A site with several businesses — one per location — names each:
|
|
82
|
+
* `businessId(origin, "north")` is `<origin>#business-north`.
|
|
83
|
+
* Without a name they would all be `#business`, and a crawler merges nodes
|
|
84
|
+
* that share an id, so the locations would read as one place.
|
|
77
85
|
*/
|
|
78
|
-
export function businessId(url: HttpsUrl): BusinessId {
|
|
79
|
-
|
|
86
|
+
export function businessId(url: HttpsUrl, location?: string): BusinessId {
|
|
87
|
+
const origin = new URL(url).origin;
|
|
88
|
+
if (!isHttpsUrl(origin)) throw new Error(`"${url}" has no https origin.`);
|
|
89
|
+
return location === undefined
|
|
90
|
+
? `${origin}#business`
|
|
91
|
+
: `${origin}#business-${location}`;
|
|
80
92
|
}
|
|
81
93
|
|
|
82
94
|
/** The `@id` a brand node takes. See `businessId`. */
|