@eduardoalvarez/arrecife 0.7.0 → 0.9.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 (56) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +115 -41
  3. package/dist/brand/index.cjs +2 -2
  4. package/dist/brand/index.js +3 -3
  5. package/dist/chart/index.cjs +155 -2
  6. package/dist/chart/index.d.cts +136 -4
  7. package/dist/chart/index.d.ts +136 -4
  8. package/dist/chart/index.js +155 -5
  9. package/dist/{chunk-TA7TLWW4.js → chunk-5A5GH2PF.js} +1 -1
  10. package/dist/{chunk-727HCBD4.js → chunk-6IGD5REB.js} +1 -1
  11. package/dist/{chunk-2WPWEIMD.js → chunk-FAAGZG7A.js} +1 -1
  12. package/dist/{chunk-OMKSESQB.js → chunk-FGFNK72B.js} +3 -3
  13. package/dist/chunk-HOADZ6GS.js +72 -0
  14. package/dist/chunk-LXRGQKMG.js +145 -0
  15. package/dist/{chunk-JN3IS5OS.js → chunk-MPZBF2TZ.js} +2 -2
  16. package/dist/{chunk-WGNIRIN7.js → chunk-TRPBID2W.js} +1 -1
  17. package/dist/{chunk-E6KFUSKB.js → chunk-XXDATT3A.js} +1 -1
  18. package/dist/doctor.mjs +95 -13
  19. package/dist/form/index.cjs +2 -2
  20. package/dist/form/index.d.cts +1 -1
  21. package/dist/form/index.d.ts +1 -1
  22. package/dist/form/index.js +4 -4
  23. package/dist/icons/index.cjs +2 -2
  24. package/dist/icons/index.d.cts +2 -2
  25. package/dist/icons/index.d.ts +2 -2
  26. package/dist/icons/index.js +2 -2
  27. package/dist/{index-DlAO2JZs.d.cts → index-BbRplw_B.d.cts} +15 -4
  28. package/dist/{index-DlAO2JZs.d.ts → index-BbRplw_B.d.ts} +15 -4
  29. package/dist/index.cjs +264 -264
  30. package/dist/index.d.cts +212 -126
  31. package/dist/index.d.ts +212 -126
  32. package/dist/index.js +153 -236
  33. package/dist/{label-MgHFKnFy.d.ts → label-DJ4HuD-R.d.cts} +3 -2
  34. package/dist/{label-MgHFKnFy.d.cts → label-DJ4HuD-R.d.ts} +3 -2
  35. package/dist/og/index.js +1 -1
  36. package/dist/shiki/index.js +1 -1
  37. package/dist/social/data.cjs +161 -0
  38. package/dist/social/data.d.cts +161 -0
  39. package/dist/social/data.d.ts +161 -0
  40. package/dist/social/data.js +2 -0
  41. package/dist/social/index.cjs +124 -38
  42. package/dist/social/index.d.cts +1 -1
  43. package/dist/social/index.d.ts +1 -1
  44. package/dist/social/index.js +2 -1
  45. package/dist/tokens/index.cjs +3 -3
  46. package/dist/tokens/index.d.cts +5 -5
  47. package/dist/tokens/index.d.ts +5 -5
  48. package/dist/tokens/index.js +2 -2
  49. package/dist/tokens/theme.css +46 -19
  50. package/dist/variants/index.cjs +1 -1
  51. package/dist/variants/index.d.cts +2 -2
  52. package/dist/variants/index.d.ts +2 -2
  53. package/dist/variants/index.js +1 -1
  54. package/llms.txt +264 -140
  55. package/package.json +6 -1
  56. package/dist/chunk-45HVCTB7.js +0 -70
@@ -0,0 +1,161 @@
1
+ 'use strict';
2
+
3
+ // src/social/data.ts
4
+ var SOCIAL_STROKE_WIDTH = 1.6;
5
+ var SOCIAL_VIEW_BOX = "0 0 24 24";
6
+ var gitHubGlyph = {
7
+ kind: "brand",
8
+ shapes: [
9
+ {
10
+ tag: "path",
11
+ d: "M12 .5C5.73.5.5 5.73.5 12a11.5 11.5 0 0 0 7.86 10.91c.58.1.79-.25.79-.55 0-.27-.01-1.18-.02-2.14-3.2.7-3.88-1.36-3.88-1.36-.52-1.33-1.28-1.68-1.28-1.68-1.05-.72.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.03 1.77 2.7 1.26 3.36.96.1-.75.4-1.26.73-1.55-2.55-.29-5.24-1.28-5.24-5.69 0-1.26.45-2.29 1.19-3.09-.12-.29-.52-1.46.11-3.05 0 0 .97-.31 3.18 1.18a11 11 0 0 1 5.79 0c2.2-1.49 3.17-1.18 3.17-1.18.63 1.59.23 2.76.12 3.05.74.8 1.18 1.83 1.18 3.09 0 4.42-2.69 5.39-5.25 5.68.41.36.78 1.06.78 2.14 0 1.55-.01 2.79-.01 3.17 0 .3.2.66.79.55A11.5 11.5 0 0 0 23.5 12C23.5 5.73 18.27.5 12 .5Z"
12
+ }
13
+ ]
14
+ };
15
+ var linkedInGlyph = {
16
+ kind: "brand",
17
+ shapes: [
18
+ {
19
+ tag: "path",
20
+ d: "M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5ZM3 9h4v12H3V9Zm7 0h3.8v1.71h.05a4.17 4.17 0 0 1 3.75-2.06c4.01 0 4.75 2.64 4.75 6.07V21h-4v-5.4c0-1.29-.02-2.95-1.8-2.95-1.8 0-2.08 1.4-2.08 2.85V21h-3.97V9Z"
21
+ }
22
+ ]
23
+ };
24
+ var xGlyph = {
25
+ kind: "brand",
26
+ shapes: [
27
+ {
28
+ tag: "path",
29
+ d: "M17.53 3h3.06l-6.69 7.64L21.75 21h-6.16l-4.83-6.3L5.25 21H2.19l7.15-8.17L2.5 3h6.32l4.36 5.77L17.53 3Zm-1.07 16.17h1.7L7.62 4.74H5.8l10.66 14.43Z"
30
+ }
31
+ ]
32
+ };
33
+ var instagramGlyph = {
34
+ kind: "brand",
35
+ shapes: [
36
+ {
37
+ tag: "path",
38
+ d: "M12 2.16c3.2 0 3.58.01 4.85.07 1.17.05 1.8.25 2.23.41.56.22.96.48 1.38.9.42.42.68.82.9 1.38.16.42.36 1.06.41 2.23.06 1.27.07 1.65.07 4.85s-.01 3.58-.07 4.85c-.05 1.17-.25 1.8-.41 2.23-.22.56-.48.96-.9 1.38-.42.42-.82.68-1.38.9-.42.16-1.06.36-2.23.41-1.27.06-1.65.07-4.85.07s-3.58-.01-4.85-.07c-1.17-.05-1.8-.25-2.23-.41-.56-.22-.96-.48-1.38-.9-.42-.42-.68-.82-.9-1.38-.16-.42-.36-1.06-.41-2.23C2.17 15.58 2.16 15.2 2.16 12s.01-3.58.07-4.85c.05-1.17.25-1.8.41-2.23.22-.56.48-.96.9-1.38.42-.42.82-.68 1.38-.9.42-.16 1.06-.36 2.23-.41C8.42 2.17 8.8 2.16 12 2.16Zm0 3.68a6.16 6.16 0 1 0 0 12.32 6.16 6.16 0 0 0 0-12.32Zm0 10.16a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm7.85-10.4a1.44 1.44 0 1 1-2.88 0 1.44 1.44 0 0 1 2.88 0Z"
39
+ }
40
+ ]
41
+ };
42
+ var discordGlyph = {
43
+ kind: "brand",
44
+ shapes: [
45
+ {
46
+ tag: "path",
47
+ d: "M20.32 5.56A18.5 18.5 0 0 0 15.7 4.1a.07.07 0 0 0-.07.04c-.2.36-.42.82-.58 1.19a17 17 0 0 0-5.1 0c-.16-.38-.39-.83-.59-1.19a.07.07 0 0 0-.07-.04c-1.6.28-3.15.77-4.62 1.46a.06.06 0 0 0-.03.03C1.66 10 .9 14.28 1.28 18.5a.08.08 0 0 0 .03.05 18.6 18.6 0 0 0 5.6 2.84.07.07 0 0 0 .08-.03c.43-.59.81-1.21 1.14-1.86a.07.07 0 0 0-.04-.1c-.6-.23-1.18-.51-1.74-.83a.07.07 0 0 1-.01-.12l.35-.27a.07.07 0 0 1 .07-.01 13.3 13.3 0 0 0 11.3 0 .07.07 0 0 1 .08.01l.34.27c.04.04.04.1-.01.12-.55.33-1.13.6-1.74.83a.07.07 0 0 0-.04.1c.34.65.72 1.27 1.14 1.86a.07.07 0 0 0 .08.03 18.5 18.5 0 0 0 5.6-2.84.07.07 0 0 0 .04-.05c.45-4.88-.75-9.12-3.18-12.88a.06.06 0 0 0-.03-.03ZM8.4 15.93c-1.1 0-2.01-1.01-2.01-2.25 0-1.24.89-2.25 2.01-2.25 1.13 0 2.03 1.02 2.02 2.25 0 1.24-.9 2.25-2.02 2.25Zm7.22 0c-1.1 0-2.01-1.01-2.01-2.25 0-1.24.89-2.25 2.01-2.25 1.13 0 2.03 1.02 2.02 2.25 0 1.24-.89 2.25-2.02 2.25Z"
48
+ }
49
+ ]
50
+ };
51
+ var youTubeGlyph = {
52
+ kind: "brand",
53
+ shapes: [
54
+ {
55
+ tag: "path",
56
+ d: "M23.5 6.9a3 3 0 0 0-2.12-2.12C19.5 4.27 12 4.27 12 4.27s-7.5 0-9.38.51A3 3 0 0 0 .5 6.9 31.3 31.3 0 0 0 0 12a31.3 31.3 0 0 0 .5 5.1 3 3 0 0 0 2.12 2.12c1.88.51 9.38.51 9.38.51s7.5 0 9.38-.51a3 3 0 0 0 2.12-2.12A31.3 31.3 0 0 0 24 12a31.3 31.3 0 0 0-.5-5.1ZM9.6 15.6V8.4l6.24 3.6-6.24 3.6Z"
57
+ }
58
+ ]
59
+ };
60
+ var rssGlyph = {
61
+ kind: "functional",
62
+ shapes: [
63
+ { tag: "path", d: "M4 11a9 9 0 0 1 9 9M4 4a16 16 0 0 1 16 16" },
64
+ { tag: "circle", cx: 5, cy: 19, r: 1.6, solid: true }
65
+ ]
66
+ };
67
+ var emailGlyph = {
68
+ kind: "functional",
69
+ shapes: [
70
+ { tag: "rect", x: 2.75, y: 4.75, width: 18.5, height: 14.5, rx: 2 },
71
+ { tag: "path", d: "m3.5 7.5 7.4 5.2a2 2 0 0 0 2.2 0l7.4-5.2" }
72
+ ]
73
+ };
74
+ var newsletterGlyph = {
75
+ kind: "functional",
76
+ shapes: [
77
+ { tag: "path", d: "M18 8.5a6 6 0 1 0-12 0c0 5-2 6.5-2 6.5h16s-2-1.5-2-6.5" },
78
+ { tag: "path", d: "M13.7 19a2 2 0 0 1-3.4 0" }
79
+ ]
80
+ };
81
+ var websiteGlyph = {
82
+ kind: "functional",
83
+ shapes: [
84
+ { tag: "circle", cx: 12, cy: 12, r: 9.25 },
85
+ { tag: "path", d: "M2.75 12h18.5" },
86
+ { tag: "path", d: "M12 2.75a14 14 0 0 1 0 18.5a14 14 0 0 1 0-18.5" }
87
+ ]
88
+ };
89
+ var socialGlyphs = {
90
+ Discord: discordGlyph,
91
+ Email: emailGlyph,
92
+ GitHub: gitHubGlyph,
93
+ Instagram: instagramGlyph,
94
+ LinkedIn: linkedInGlyph,
95
+ Newsletter: newsletterGlyph,
96
+ Rss: rssGlyph,
97
+ Website: websiteGlyph,
98
+ X: xGlyph,
99
+ YouTube: youTubeGlyph
100
+ };
101
+ var socialNames = Object.keys(socialGlyphs);
102
+ var escape = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
103
+ var attributes = (pairs) => Object.entries(pairs).map(([key, value]) => ` ${key}="${escape(String(value))}"`).join("");
104
+ var shapeMarkup = (shape) => {
105
+ const solid = { fill: "currentColor", stroke: "none" };
106
+ if (shape.tag === "path") {
107
+ return `<path${attributes({ d: shape.d, ...shape.solid ? solid : {} })}/>`;
108
+ }
109
+ if (shape.tag === "circle") {
110
+ return `<circle${attributes({
111
+ cx: shape.cx,
112
+ cy: shape.cy,
113
+ r: shape.r,
114
+ ...shape.solid ? solid : {}
115
+ })}/>`;
116
+ }
117
+ return `<rect${attributes({
118
+ x: shape.x,
119
+ y: shape.y,
120
+ width: shape.width,
121
+ height: shape.height,
122
+ rx: shape.rx
123
+ })}/>`;
124
+ };
125
+ function socialSvg(name, extra = {}) {
126
+ const glyph = socialGlyphs[name];
127
+ const base = glyph.kind === "brand" ? { fill: "currentColor" } : {
128
+ fill: "none",
129
+ stroke: "currentColor",
130
+ "stroke-width": SOCIAL_STROKE_WIDTH,
131
+ "stroke-linecap": "round",
132
+ "stroke-linejoin": "round"
133
+ };
134
+ const open = attributes({
135
+ xmlns: "http://www.w3.org/2000/svg",
136
+ viewBox: SOCIAL_VIEW_BOX,
137
+ width: "1em",
138
+ height: "1em",
139
+ ...base,
140
+ "aria-hidden": "true",
141
+ focusable: "false",
142
+ ...extra
143
+ });
144
+ return `<svg${open}>${glyph.shapes.map(shapeMarkup).join("")}</svg>`;
145
+ }
146
+
147
+ exports.SOCIAL_STROKE_WIDTH = SOCIAL_STROKE_WIDTH;
148
+ exports.SOCIAL_VIEW_BOX = SOCIAL_VIEW_BOX;
149
+ exports.discordGlyph = discordGlyph;
150
+ exports.emailGlyph = emailGlyph;
151
+ exports.gitHubGlyph = gitHubGlyph;
152
+ exports.instagramGlyph = instagramGlyph;
153
+ exports.linkedInGlyph = linkedInGlyph;
154
+ exports.newsletterGlyph = newsletterGlyph;
155
+ exports.rssGlyph = rssGlyph;
156
+ exports.socialGlyphs = socialGlyphs;
157
+ exports.socialNames = socialNames;
158
+ exports.socialSvg = socialSvg;
159
+ exports.websiteGlyph = websiteGlyph;
160
+ exports.xGlyph = xGlyph;
161
+ exports.youTubeGlyph = youTubeGlyph;
@@ -0,0 +1,161 @@
1
+ /**
2
+ * The social glyphs as DATA, with no React attached.
3
+ *
4
+ * It is the third time the library answers the same question, and the answer has
5
+ * not changed: `./variants` publishes the class vocabulary so an `.astro` can
6
+ * write `buttonVariants({ variant: 'tertiary' })`, and the brand catalogue
7
+ * publishes the PNGs as `faces`, `poses` and `fins` so anybody can build the
8
+ * path. Both exist because a consumer that mounts no React still consumes the
9
+ * system — it copies instead of importing, and a copy is what goes stale.
10
+ *
11
+ * `links` is that consumer, and it is not an oversight in it: zero dependencies
12
+ * on `react`, `react-dom` or `@astrojs/react`, four `.astro` components, and a
13
+ * `check:replica` that fails the build when its class vocabulary drifts from the
14
+ * package's. What it could not replicate was a shape, so `SocialGlyph.astro`
15
+ * carried four `<path d="…">` pasted by hand — and `cursos` had six of them in
16
+ * its footer until the version before this one. That is the exact failure this
17
+ * library was built to stop, happening inside the library's own blind spot.
18
+ *
19
+ * So the shapes live HERE, in a module that imports nothing, and the React
20
+ * components in `index.tsx` are drawn FROM this file. There is one description of
21
+ * what a GitHub mark looks like, and two renderers for it. A change to a `d`
22
+ * reaches the `.astro` and the `.tsx` in the same commit or it reaches neither.
23
+ *
24
+ * The shapes are structured and not a blob of markup, because both renderers
25
+ * have to walk them: JSX needs elements and a string needs text, and neither is
26
+ * derivable from the other without parsing. Three tags cover the catalogue —
27
+ * `path`, `circle` and `rect` — and a fourth gets added when a glyph needs it,
28
+ * which is a decision and not a refactor.
29
+ *
30
+ * Every glyph is ALSO exported on its own, next to the record that collects
31
+ * them. That is what keeps `import { LinkedIn } from '…/social'` costing one
32
+ * shape instead of ten: `index.tsx` references the individual consts, so a
33
+ * bundler drops the nine it does not draw. Reach for `socialGlyphs` when you
34
+ * want to iterate the catalogue, and know that iterating it is asking for all of
35
+ * it.
36
+ *
37
+ * See `docs/decisions/0.8.md` § 42.
38
+ */
39
+ /** The stroke width of a functional glyph, from the document. */
40
+ declare const SOCIAL_STROKE_WIDTH = 1.6;
41
+ /** The grid every glyph is drawn on. */
42
+ declare const SOCIAL_VIEW_BOX = "0 0 24 24";
43
+ /**
44
+ * One drawn element of a glyph.
45
+ *
46
+ * `solid` fills the shape with `currentColor` and drops the stroke. It exists for
47
+ * exactly one case and it is not a loophole: `Rss`'s dot is a filled disc inside
48
+ * an otherwise stroked glyph, because a 1.6 ring at 19px reads as a smudge.
49
+ */
50
+ type SocialGlyphShape = {
51
+ readonly tag: 'path';
52
+ readonly d: string;
53
+ readonly solid?: true;
54
+ } | {
55
+ readonly tag: 'circle';
56
+ readonly cx: number;
57
+ readonly cy: number;
58
+ readonly r: number;
59
+ readonly solid?: true;
60
+ } | {
61
+ readonly tag: 'rect';
62
+ readonly x: number;
63
+ readonly y: number;
64
+ readonly width: number;
65
+ readonly height: number;
66
+ readonly rx: number;
67
+ };
68
+ /**
69
+ * How a glyph is drawn, which in this system is a rule and not a style.
70
+ *
71
+ * `brand` is a solid silhouette, because the shape belongs to somebody else and
72
+ * the GitHub mark does not exist in outline. `functional` is a 1.6 stroke,
73
+ * because there is no owner to be faithful to and the system draws its own
74
+ * symbols with a line. A row mixing the two is normal, not a mistake: the blog's
75
+ * footer already does it with `Email` and `Rss`.
76
+ */
77
+ type SocialGlyph = {
78
+ readonly kind: 'brand' | 'functional';
79
+ readonly shapes: readonly SocialGlyphShape[];
80
+ };
81
+ /** GitHub's mark. Brand, so it is a solid silhouette. */
82
+ declare const gitHubGlyph: SocialGlyph;
83
+ /** LinkedIn's mark. Brand, so it is a solid silhouette. */
84
+ declare const linkedInGlyph: SocialGlyph;
85
+ /** X's mark. Brand, so it is a solid silhouette. */
86
+ declare const xGlyph: SocialGlyph;
87
+ /** Instagram's mark. Brand, so it is a solid silhouette. */
88
+ declare const instagramGlyph: SocialGlyph;
89
+ /** Discord's mark. Brand, so it is a solid silhouette. */
90
+ declare const discordGlyph: SocialGlyph;
91
+ /** YouTube's mark. Brand, so it is a solid silhouette. */
92
+ declare const youTubeGlyph: SocialGlyph;
93
+ /** The feed. Functional, so it is a 1.6 stroke — with one filled dot, because a ring that small reads as a smudge. */
94
+ declare const rssGlyph: SocialGlyph;
95
+ /** The envelope. Functional, so it is a 1.6 stroke. */
96
+ declare const emailGlyph: SocialGlyph;
97
+ declare const newsletterGlyph: SocialGlyph;
98
+ /**
99
+ * «My other site», and the reason it is here rather than borrowed.
100
+ *
101
+ * The footer of `cursos` links to the personal site alongside six brand marks,
102
+ * and a personal site is not a social network — none of the other nine fits. It
103
+ * took Phosphor's `Globe`, which drew a correct globe with the wrong pen: the
104
+ * catalogue draws functional glyphs at 1.6 on a 24 grid, and an outside set
105
+ * carries its own weight and its own margins. The mismatch showed, and it was
106
+ * reported so the set could gain one.
107
+ *
108
+ * So it is drawn to this catalogue's proportions: r 9.25 leaves the same 2.75 of
109
+ * margin `Email`'s rectangle leaves, and the meridian's arc bulges to 37 % of
110
+ * the sphere's half-width, which is what stops it from reading as a vertical
111
+ * line at 19px. Circle, equator and meridian, and nothing else: a globe with
112
+ * latitude lines turns into a grey disc at footer size.
113
+ *
114
+ * It is functional and not a brand for the same reason `Email` is: there is no
115
+ * owner to be faithful to. A row that mixes it with GitHub and LinkedIn mixes a
116
+ * stroke with two fills, which is the normal case and not a defect.
117
+ */
118
+ declare const websiteGlyph: SocialGlyph;
119
+ /**
120
+ * The whole catalogue, keyed by the name each glyph is exported under in
121
+ * `./social`.
122
+ *
123
+ * Reaching for this is asking for all ten shapes: it names every one of them, so
124
+ * no bundler can drop the ones you do not draw. That is the right trade when you
125
+ * are iterating a catalogue — a footer built from a config array — and the wrong
126
+ * one when you want a single icon, which is what the loose consts above are for.
127
+ */
128
+ declare const socialGlyphs: {
129
+ readonly Discord: SocialGlyph;
130
+ readonly Email: SocialGlyph;
131
+ readonly GitHub: SocialGlyph;
132
+ readonly Instagram: SocialGlyph;
133
+ readonly LinkedIn: SocialGlyph;
134
+ readonly Newsletter: SocialGlyph;
135
+ readonly Rss: SocialGlyph;
136
+ readonly Website: SocialGlyph;
137
+ readonly X: SocialGlyph;
138
+ readonly YouTube: SocialGlyph;
139
+ };
140
+ /** The name of a glyph in the catalogue. */
141
+ type SocialName = keyof typeof socialGlyphs;
142
+ /** The ten names, in the order the catalogue declares them. */
143
+ declare const socialNames: readonly SocialName[];
144
+ /**
145
+ * One glyph as a complete `<svg>` string, for a template that cannot mount React.
146
+ *
147
+ * It is the whole point of this module for `links`: an `.astro` writes
148
+ * `<Fragment set:html={socialSvg('GitHub')} />` and stops maintaining a copy of
149
+ * the shape. Everything the React component sets is set here too — the 1em box,
150
+ * `currentColor`, `aria-hidden` — so the two renderings are the same drawing and
151
+ * not two drawings that agree today.
152
+ *
153
+ * `aria-hidden` is the default because it is right in the only place these are
154
+ * used: a glyph inside a link whose `aria-label` carries the accessible name.
155
+ * Anything passed in `extra` overrides a default, including that one, and the
156
+ * value is escaped — a `class` is the expected use and it arrives from the call
157
+ * site.
158
+ */
159
+ declare function socialSvg(name: SocialName, extra?: Readonly<Record<string, string | number>>): string;
160
+
161
+ export { SOCIAL_STROKE_WIDTH, SOCIAL_VIEW_BOX, type SocialGlyph, type SocialGlyphShape, type SocialName, discordGlyph, emailGlyph, gitHubGlyph, instagramGlyph, linkedInGlyph, newsletterGlyph, rssGlyph, socialGlyphs, socialNames, socialSvg, websiteGlyph, xGlyph, youTubeGlyph };
@@ -0,0 +1,161 @@
1
+ /**
2
+ * The social glyphs as DATA, with no React attached.
3
+ *
4
+ * It is the third time the library answers the same question, and the answer has
5
+ * not changed: `./variants` publishes the class vocabulary so an `.astro` can
6
+ * write `buttonVariants({ variant: 'tertiary' })`, and the brand catalogue
7
+ * publishes the PNGs as `faces`, `poses` and `fins` so anybody can build the
8
+ * path. Both exist because a consumer that mounts no React still consumes the
9
+ * system — it copies instead of importing, and a copy is what goes stale.
10
+ *
11
+ * `links` is that consumer, and it is not an oversight in it: zero dependencies
12
+ * on `react`, `react-dom` or `@astrojs/react`, four `.astro` components, and a
13
+ * `check:replica` that fails the build when its class vocabulary drifts from the
14
+ * package's. What it could not replicate was a shape, so `SocialGlyph.astro`
15
+ * carried four `<path d="…">` pasted by hand — and `cursos` had six of them in
16
+ * its footer until the version before this one. That is the exact failure this
17
+ * library was built to stop, happening inside the library's own blind spot.
18
+ *
19
+ * So the shapes live HERE, in a module that imports nothing, and the React
20
+ * components in `index.tsx` are drawn FROM this file. There is one description of
21
+ * what a GitHub mark looks like, and two renderers for it. A change to a `d`
22
+ * reaches the `.astro` and the `.tsx` in the same commit or it reaches neither.
23
+ *
24
+ * The shapes are structured and not a blob of markup, because both renderers
25
+ * have to walk them: JSX needs elements and a string needs text, and neither is
26
+ * derivable from the other without parsing. Three tags cover the catalogue —
27
+ * `path`, `circle` and `rect` — and a fourth gets added when a glyph needs it,
28
+ * which is a decision and not a refactor.
29
+ *
30
+ * Every glyph is ALSO exported on its own, next to the record that collects
31
+ * them. That is what keeps `import { LinkedIn } from '…/social'` costing one
32
+ * shape instead of ten: `index.tsx` references the individual consts, so a
33
+ * bundler drops the nine it does not draw. Reach for `socialGlyphs` when you
34
+ * want to iterate the catalogue, and know that iterating it is asking for all of
35
+ * it.
36
+ *
37
+ * See `docs/decisions/0.8.md` § 42.
38
+ */
39
+ /** The stroke width of a functional glyph, from the document. */
40
+ declare const SOCIAL_STROKE_WIDTH = 1.6;
41
+ /** The grid every glyph is drawn on. */
42
+ declare const SOCIAL_VIEW_BOX = "0 0 24 24";
43
+ /**
44
+ * One drawn element of a glyph.
45
+ *
46
+ * `solid` fills the shape with `currentColor` and drops the stroke. It exists for
47
+ * exactly one case and it is not a loophole: `Rss`'s dot is a filled disc inside
48
+ * an otherwise stroked glyph, because a 1.6 ring at 19px reads as a smudge.
49
+ */
50
+ type SocialGlyphShape = {
51
+ readonly tag: 'path';
52
+ readonly d: string;
53
+ readonly solid?: true;
54
+ } | {
55
+ readonly tag: 'circle';
56
+ readonly cx: number;
57
+ readonly cy: number;
58
+ readonly r: number;
59
+ readonly solid?: true;
60
+ } | {
61
+ readonly tag: 'rect';
62
+ readonly x: number;
63
+ readonly y: number;
64
+ readonly width: number;
65
+ readonly height: number;
66
+ readonly rx: number;
67
+ };
68
+ /**
69
+ * How a glyph is drawn, which in this system is a rule and not a style.
70
+ *
71
+ * `brand` is a solid silhouette, because the shape belongs to somebody else and
72
+ * the GitHub mark does not exist in outline. `functional` is a 1.6 stroke,
73
+ * because there is no owner to be faithful to and the system draws its own
74
+ * symbols with a line. A row mixing the two is normal, not a mistake: the blog's
75
+ * footer already does it with `Email` and `Rss`.
76
+ */
77
+ type SocialGlyph = {
78
+ readonly kind: 'brand' | 'functional';
79
+ readonly shapes: readonly SocialGlyphShape[];
80
+ };
81
+ /** GitHub's mark. Brand, so it is a solid silhouette. */
82
+ declare const gitHubGlyph: SocialGlyph;
83
+ /** LinkedIn's mark. Brand, so it is a solid silhouette. */
84
+ declare const linkedInGlyph: SocialGlyph;
85
+ /** X's mark. Brand, so it is a solid silhouette. */
86
+ declare const xGlyph: SocialGlyph;
87
+ /** Instagram's mark. Brand, so it is a solid silhouette. */
88
+ declare const instagramGlyph: SocialGlyph;
89
+ /** Discord's mark. Brand, so it is a solid silhouette. */
90
+ declare const discordGlyph: SocialGlyph;
91
+ /** YouTube's mark. Brand, so it is a solid silhouette. */
92
+ declare const youTubeGlyph: SocialGlyph;
93
+ /** The feed. Functional, so it is a 1.6 stroke — with one filled dot, because a ring that small reads as a smudge. */
94
+ declare const rssGlyph: SocialGlyph;
95
+ /** The envelope. Functional, so it is a 1.6 stroke. */
96
+ declare const emailGlyph: SocialGlyph;
97
+ declare const newsletterGlyph: SocialGlyph;
98
+ /**
99
+ * «My other site», and the reason it is here rather than borrowed.
100
+ *
101
+ * The footer of `cursos` links to the personal site alongside six brand marks,
102
+ * and a personal site is not a social network — none of the other nine fits. It
103
+ * took Phosphor's `Globe`, which drew a correct globe with the wrong pen: the
104
+ * catalogue draws functional glyphs at 1.6 on a 24 grid, and an outside set
105
+ * carries its own weight and its own margins. The mismatch showed, and it was
106
+ * reported so the set could gain one.
107
+ *
108
+ * So it is drawn to this catalogue's proportions: r 9.25 leaves the same 2.75 of
109
+ * margin `Email`'s rectangle leaves, and the meridian's arc bulges to 37 % of
110
+ * the sphere's half-width, which is what stops it from reading as a vertical
111
+ * line at 19px. Circle, equator and meridian, and nothing else: a globe with
112
+ * latitude lines turns into a grey disc at footer size.
113
+ *
114
+ * It is functional and not a brand for the same reason `Email` is: there is no
115
+ * owner to be faithful to. A row that mixes it with GitHub and LinkedIn mixes a
116
+ * stroke with two fills, which is the normal case and not a defect.
117
+ */
118
+ declare const websiteGlyph: SocialGlyph;
119
+ /**
120
+ * The whole catalogue, keyed by the name each glyph is exported under in
121
+ * `./social`.
122
+ *
123
+ * Reaching for this is asking for all ten shapes: it names every one of them, so
124
+ * no bundler can drop the ones you do not draw. That is the right trade when you
125
+ * are iterating a catalogue — a footer built from a config array — and the wrong
126
+ * one when you want a single icon, which is what the loose consts above are for.
127
+ */
128
+ declare const socialGlyphs: {
129
+ readonly Discord: SocialGlyph;
130
+ readonly Email: SocialGlyph;
131
+ readonly GitHub: SocialGlyph;
132
+ readonly Instagram: SocialGlyph;
133
+ readonly LinkedIn: SocialGlyph;
134
+ readonly Newsletter: SocialGlyph;
135
+ readonly Rss: SocialGlyph;
136
+ readonly Website: SocialGlyph;
137
+ readonly X: SocialGlyph;
138
+ readonly YouTube: SocialGlyph;
139
+ };
140
+ /** The name of a glyph in the catalogue. */
141
+ type SocialName = keyof typeof socialGlyphs;
142
+ /** The ten names, in the order the catalogue declares them. */
143
+ declare const socialNames: readonly SocialName[];
144
+ /**
145
+ * One glyph as a complete `<svg>` string, for a template that cannot mount React.
146
+ *
147
+ * It is the whole point of this module for `links`: an `.astro` writes
148
+ * `<Fragment set:html={socialSvg('GitHub')} />` and stops maintaining a copy of
149
+ * the shape. Everything the React component sets is set here too — the 1em box,
150
+ * `currentColor`, `aria-hidden` — so the two renderings are the same drawing and
151
+ * not two drawings that agree today.
152
+ *
153
+ * `aria-hidden` is the default because it is right in the only place these are
154
+ * used: a glyph inside a link whose `aria-label` carries the accessible name.
155
+ * Anything passed in `extra` overrides a default, including that one, and the
156
+ * value is escaped — a `class` is the expected use and it arrives from the call
157
+ * site.
158
+ */
159
+ declare function socialSvg(name: SocialName, extra?: Readonly<Record<string, string | number>>): string;
160
+
161
+ export { SOCIAL_STROKE_WIDTH, SOCIAL_VIEW_BOX, type SocialGlyph, type SocialGlyphShape, type SocialName, discordGlyph, emailGlyph, gitHubGlyph, instagramGlyph, linkedInGlyph, newsletterGlyph, rssGlyph, socialGlyphs, socialNames, socialSvg, websiteGlyph, xGlyph, youTubeGlyph };
@@ -0,0 +1,2 @@
1
+ export { SOCIAL_STROKE_WIDTH, SOCIAL_VIEW_BOX, discordGlyph, emailGlyph, gitHubGlyph, instagramGlyph, linkedInGlyph, newsletterGlyph, rssGlyph, socialGlyphs, socialNames, socialSvg, websiteGlyph, xGlyph, youTubeGlyph } from '../chunk-LXRGQKMG.js';
2
+ import '../chunk-MLKGABMK.js';