@aglyn/plugins-mui 1.0.0-beta.215 → 1.0.0-beta.216

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 (57) hide show
  1. package/package.json +7 -7
  2. package/src/lib/components/collection-author-links.d.ts +41 -0
  3. package/src/lib/components/collection-author-links.js +135 -0
  4. package/src/lib/components/collection-author-links.js.map +1 -0
  5. package/src/lib/components/collection-author-profile.d.ts +67 -0
  6. package/src/lib/components/collection-author-profile.js +269 -0
  7. package/src/lib/components/collection-author-profile.js.map +1 -0
  8. package/src/lib/components/collection-categories.d.ts +52 -0
  9. package/src/lib/components/collection-categories.js +163 -0
  10. package/src/lib/components/collection-categories.js.map +1 -0
  11. package/src/lib/components/collection-common.d.ts +104 -0
  12. package/src/lib/components/collection-common.js +95 -0
  13. package/src/lib/components/collection-common.js.map +1 -0
  14. package/src/lib/components/collection-entries.d.ts +137 -0
  15. package/src/lib/components/collection-entries.js +358 -0
  16. package/src/lib/components/collection-entries.js.map +1 -0
  17. package/src/lib/components/collection-entry-author.d.ts +81 -0
  18. package/src/lib/components/collection-entry-author.js +259 -0
  19. package/src/lib/components/collection-entry-author.js.map +1 -0
  20. package/src/lib/components/collection-entry-body.d.ts +44 -0
  21. package/src/lib/components/collection-entry-body.js +328 -0
  22. package/src/lib/components/collection-entry-body.js.map +1 -0
  23. package/src/lib/components/collection-entry-meta.d.ts +88 -0
  24. package/src/lib/components/collection-entry-meta.js +331 -0
  25. package/src/lib/components/collection-entry-meta.js.map +1 -0
  26. package/src/lib/components/collection-presets.d.ts +18 -0
  27. package/src/lib/components/collection-presets.js +328 -0
  28. package/src/lib/components/collection-presets.js.map +1 -0
  29. package/src/lib/components/collection-related.d.ts +101 -0
  30. package/src/lib/components/collection-related.js +536 -0
  31. package/src/lib/components/collection-related.js.map +1 -0
  32. package/src/lib/components/collection-search-box.d.ts +92 -0
  33. package/src/lib/components/collection-search-box.js +334 -0
  34. package/src/lib/components/collection-search-box.js.map +1 -0
  35. package/src/lib/components/collection-search-fuse.d.ts +28 -0
  36. package/src/lib/components/collection-search-fuse.js +28 -0
  37. package/src/lib/components/collection-search-fuse.js.map +1 -0
  38. package/src/lib/components/collection-search.d.ts +62 -0
  39. package/src/lib/components/collection-search.js +140 -0
  40. package/src/lib/components/collection-search.js.map +1 -0
  41. package/src/lib/components/collection-share.d.ts +31 -0
  42. package/src/lib/components/collection-share.js +154 -0
  43. package/src/lib/components/collection-share.js.map +1 -0
  44. package/src/lib/components/collection.d.ts +19 -497
  45. package/src/lib/components/collection.js +19 -2982
  46. package/src/lib/components/collection.js.map +1 -1
  47. package/src/lib/components/image-list.d.ts +2 -2
  48. package/src/lib/components/image-list.js +4 -6
  49. package/src/lib/components/image-list.js.map +1 -1
  50. package/src/lib/element-tier.d.ts +9 -1
  51. package/src/lib/element-tier.js +12 -1
  52. package/src/lib/element-tier.js.map +1 -1
  53. package/src/lib/plugin.js +20 -12
  54. package/src/lib/plugin.js.map +1 -1
  55. package/src/lib/utils/to-count.d.ts +25 -0
  56. package/src/lib/utils/to-count.js +30 -0
  57. package/src/lib/utils/to-count.js.map +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aglyn/plugins-mui",
3
- "version": "1.0.0-beta.215",
3
+ "version": "1.0.0-beta.216",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://aglyn.com",
6
6
  "repository": {
@@ -25,12 +25,12 @@
25
25
  "./package.json": "./package.json"
26
26
  },
27
27
  "dependencies": {
28
- "@aglyn/aglyn": "1.0.0-beta.215",
29
- "@aglyn/shared-data-enums": "1.0.0-beta.215",
30
- "@aglyn/shared-data-mdi": "1.0.0-beta.215",
31
- "@aglyn/shared-ui-jsx": "1.0.0-beta.215",
32
- "@aglyn/shared-ui-theme": "1.0.0-beta.215",
33
- "@aglyn/shared-util-vendor": "1.0.0-beta.215",
28
+ "@aglyn/aglyn": "1.0.0-beta.216",
29
+ "@aglyn/shared-data-enums": "1.0.0-beta.216",
30
+ "@aglyn/shared-data-mdi": "1.0.0-beta.216",
31
+ "@aglyn/shared-ui-jsx": "1.0.0-beta.216",
32
+ "@aglyn/shared-ui-theme": "1.0.0-beta.216",
33
+ "@aglyn/shared-util-vendor": "1.0.0-beta.216",
34
34
  "@swc/helpers": "0.5.23",
35
35
  "mobx": "^6.16.1",
36
36
  "mobx-react-lite": "^4.1.1"
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import * as Aglyn from '@aglyn/aglyn';
18
+ /**
19
+ * The author's profile links as a row of marks (AGL-2516).
20
+ *
21
+ * Shared by the article's Entry Author card and the Author Profile block on
22
+ * the author's own page (AGL-2518) — the one part of the two that would
23
+ * genuinely drift, since an icon row is where the accessible-name rule and
24
+ * the `rel` on an off-site profile live.
25
+ *
26
+ * Renders nothing for an empty list, so a caller can drop it in
27
+ * unconditionally rather than guarding at every call site.
28
+ */
29
+ export declare function AuthorLinkRows(props: {
30
+ links: readonly Aglyn.ContentAuthorLink[];
31
+ /** Glyph scale; the profile draws them a step larger than the card. */
32
+ size?: number;
33
+ }): import("react").JSX.Element;
34
+ /**
35
+ * The rows a card will actually draw, guarded at the boundary.
36
+ *
37
+ * These arrive as PROPS, so a link can reach a renderer without ever passing
38
+ * through the store's normalizer — the reason the byline's own `url` is
39
+ * checked twice as well.
40
+ */
41
+ export declare function safeAuthorLinks(links: readonly Aglyn.ContentAuthorLink[] | undefined, show: boolean | undefined): Aglyn.ContentAuthorLink[];
@@ -0,0 +1,135 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import * as Aglyn from "@aglyn/aglyn";
18
+ import { mdiEmail, mdiFacebook, mdiGithub, mdiInstagram, mdiLinkVariant, mdiLinkedin, mdiMastodon, mdiRss, mdiTwitter, mdiWeb, mdiYoutube } from "@aglyn/shared-data-mdi";
19
+ import { AppLink, MdiIcon } from "@aglyn/shared-ui-jsx";
20
+ import MuiStack from "@mui/material/Stack";
21
+ /**
22
+ * An author's profile links as a row of marks (AGL-2516), shared by the Entry
23
+ * Author card and the Author Profile block, and by nothing else — its own
24
+ * module so the other collection elements do not download ten platform marks
25
+ * (AGL-3401).
26
+ */ /**
27
+ * The mark for each platform the author model knows (AGL-2516).
28
+ *
29
+ * Imported rather than resolved through the icon catalog, because this set is
30
+ * CLOSED and known at build time — the catalog is ~2.9 MB and only picker
31
+ * surfaces load it, so a renderer that reached for it to draw ten glyphs
32
+ * would ship the whole thing to every visitor of every article.
33
+ *
34
+ * Keyed by the registry's `icon`, so adding a platform is one entry there and
35
+ * one import here, and a platform whose mark was never imported falls through
36
+ * to the generic link glyph rather than rendering nothing.
37
+ */ const AUTHOR_LINK_ICON_PATHS = {
38
+ twitter: mdiTwitter.path,
39
+ linkedin: mdiLinkedin.path,
40
+ github: mdiGithub.path,
41
+ mastodon: mdiMastodon.path,
42
+ youtube: mdiYoutube.path,
43
+ instagram: mdiInstagram.path,
44
+ facebook: mdiFacebook.path,
45
+ web: mdiWeb.path,
46
+ email: mdiEmail.path,
47
+ rss: mdiRss.path
48
+ };
49
+ /**
50
+ * What one link row draws.
51
+ *
52
+ * A known platform takes its mark from the table above. A CUSTOM link takes
53
+ * the path the console stored beside the picked id (AGL-1212) — and falls back
54
+ * to a generic link glyph rather than to nothing, because a row with a label
55
+ * and a url is still a working link whose icon simply failed to resolve.
56
+ */ function authorLinkIconPath(link) {
57
+ var _link_iconPath;
58
+ const platform = Aglyn.authorLinkPlatform(link.platform);
59
+ if (platform) {
60
+ var _AUTHOR_LINK_ICON_PATHS_platform_icon;
61
+ return (_AUTHOR_LINK_ICON_PATHS_platform_icon = AUTHOR_LINK_ICON_PATHS[platform.icon]) != null ? _AUTHOR_LINK_ICON_PATHS_platform_icon : mdiLinkVariant.path;
62
+ }
63
+ return ((_link_iconPath = link.iconPath) != null ? _link_iconPath : '').trim() || mdiLinkVariant.path;
64
+ }
65
+ /**
66
+ * Schemes a rendered author link may use — the model's own guard, restated at
67
+ * the boundary that produces the `href`.
68
+ *
69
+ * `normalizeContentAuthorLinks` already drops everything else, and this is
70
+ * deliberately not trusting that: the props on this component are authorable,
71
+ * so a link can reach the renderer without ever passing through the store's
72
+ * normalizer. Two checks, because only one of them is on the path an attacker
73
+ * would use.
74
+ */ const SAFE_AUTHOR_LINK_HREF = /^(https:\/\/|mailto:)/i;
75
+ /**
76
+ * The author's profile links as a row of marks (AGL-2516).
77
+ *
78
+ * Shared by the article's Entry Author card and the Author Profile block on
79
+ * the author's own page (AGL-2518) — the one part of the two that would
80
+ * genuinely drift, since an icon row is where the accessible-name rule and
81
+ * the `rel` on an off-site profile live.
82
+ *
83
+ * Renders nothing for an empty list, so a caller can drop it in
84
+ * unconditionally rather than guarding at every call site.
85
+ */ export function AuthorLinkRows(props) {
86
+ if (!props.links.length) return null;
87
+ return /*#__PURE__*/ _jsx(MuiStack, {
88
+ direction: "row",
89
+ spacing: 0.5,
90
+ sx: {
91
+ flexWrap: 'wrap',
92
+ ml: -1
93
+ },
94
+ children: props.links.map((link, index)=>{
95
+ var _link_url, _props_size;
96
+ const label = Aglyn.authorLinkLabel(link);
97
+ return /*#__PURE__*/ _jsx(AppLink, {
98
+ componentVariant: "icon-button",
99
+ href: ((_link_url = link.url) != null ? _link_url : '').trim(),
100
+ // The name IS the icon here, so it has to be announced — a row of
101
+ // unlabelled icon buttons is a row a screen reader reads as
102
+ // "link, link, link".
103
+ "aria-label": label,
104
+ title: label,
105
+ size: "small",
106
+ sx: {
107
+ color: 'text.secondary'
108
+ },
109
+ // A profile lives off this site by definition, and `mailto:` must
110
+ // not replace the article either.
111
+ target: "_blank",
112
+ rel: "noopener noreferrer me",
113
+ children: /*#__PURE__*/ _jsx(MdiIcon, {
114
+ path: authorLinkIconPath(link),
115
+ size: (_props_size = props.size) != null ? _props_size : 0.85
116
+ })
117
+ }, index);
118
+ })
119
+ });
120
+ }
121
+ /**
122
+ * The rows a card will actually draw, guarded at the boundary.
123
+ *
124
+ * These arrive as PROPS, so a link can reach a renderer without ever passing
125
+ * through the store's normalizer — the reason the byline's own `url` is
126
+ * checked twice as well.
127
+ */ export function safeAuthorLinks(links, show) {
128
+ if (show === false) return [];
129
+ return (links != null ? links : []).filter((link)=>{
130
+ var _ref;
131
+ return SAFE_AUTHOR_LINK_HREF.test(((_ref = link == null ? void 0 : link.url) != null ? _ref : '').trim());
132
+ });
133
+ }
134
+
135
+ //# sourceMappingURL=collection-author-links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/collection-author-links.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as Aglyn from '@aglyn/aglyn'\nimport {\n mdiEmail,\n mdiFacebook,\n mdiGithub,\n mdiInstagram,\n mdiLinkVariant,\n mdiLinkedin,\n mdiMastodon,\n mdiRss,\n mdiTwitter,\n mdiWeb,\n mdiYoutube,\n} from '@aglyn/shared-data-mdi'\nimport { AppLink, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport MuiStack from '@mui/material/Stack'\n\n/**\n * An author's profile links as a row of marks (AGL-2516), shared by the Entry\n * Author card and the Author Profile block, and by nothing else — its own\n * module so the other collection elements do not download ten platform marks\n * (AGL-3401).\n */\n\n/**\n * The mark for each platform the author model knows (AGL-2516).\n *\n * Imported rather than resolved through the icon catalog, because this set is\n * CLOSED and known at build time — the catalog is ~2.9 MB and only picker\n * surfaces load it, so a renderer that reached for it to draw ten glyphs\n * would ship the whole thing to every visitor of every article.\n *\n * Keyed by the registry's `icon`, so adding a platform is one entry there and\n * one import here, and a platform whose mark was never imported falls through\n * to the generic link glyph rather than rendering nothing.\n */\nconst AUTHOR_LINK_ICON_PATHS: Record<string, string> = {\n twitter: mdiTwitter.path,\n linkedin: mdiLinkedin.path,\n github: mdiGithub.path,\n mastodon: mdiMastodon.path,\n youtube: mdiYoutube.path,\n instagram: mdiInstagram.path,\n facebook: mdiFacebook.path,\n web: mdiWeb.path,\n email: mdiEmail.path,\n rss: mdiRss.path,\n}\n\n/**\n * What one link row draws.\n *\n * A known platform takes its mark from the table above. A CUSTOM link takes\n * the path the console stored beside the picked id (AGL-1212) — and falls back\n * to a generic link glyph rather than to nothing, because a row with a label\n * and a url is still a working link whose icon simply failed to resolve.\n */\nfunction authorLinkIconPath(link: Aglyn.ContentAuthorLink): string {\n const platform = Aglyn.authorLinkPlatform(link.platform)\n if (platform) {\n return AUTHOR_LINK_ICON_PATHS[platform.icon] ?? mdiLinkVariant.path\n }\n return (link.iconPath ?? '').trim() || mdiLinkVariant.path\n}\n\n/**\n * Schemes a rendered author link may use — the model's own guard, restated at\n * the boundary that produces the `href`.\n *\n * `normalizeContentAuthorLinks` already drops everything else, and this is\n * deliberately not trusting that: the props on this component are authorable,\n * so a link can reach the renderer without ever passing through the store's\n * normalizer. Two checks, because only one of them is on the path an attacker\n * would use.\n */\nconst SAFE_AUTHOR_LINK_HREF = /^(https:\\/\\/|mailto:)/i\n\n/**\n * The author's profile links as a row of marks (AGL-2516).\n *\n * Shared by the article's Entry Author card and the Author Profile block on\n * the author's own page (AGL-2518) — the one part of the two that would\n * genuinely drift, since an icon row is where the accessible-name rule and\n * the `rel` on an off-site profile live.\n *\n * Renders nothing for an empty list, so a caller can drop it in\n * unconditionally rather than guarding at every call site.\n */\nexport function AuthorLinkRows(props: {\n links: readonly Aglyn.ContentAuthorLink[]\n /** Glyph scale; the profile draws them a step larger than the card. */\n size?: number\n}) {\n if (!props.links.length) return null\n return (\n <MuiStack direction=\"row\" spacing={0.5} sx={{ flexWrap: 'wrap', ml: -1 }}>\n {props.links.map((link, index) => {\n const label = Aglyn.authorLinkLabel(link)\n return (\n <AppLink\n key={index}\n componentVariant=\"icon-button\"\n href={(link.url ?? '').trim()}\n // The name IS the icon here, so it has to be announced — a row of\n // unlabelled icon buttons is a row a screen reader reads as\n // \"link, link, link\".\n aria-label={label}\n title={label}\n size=\"small\"\n sx={{ color: 'text.secondary' }}\n // A profile lives off this site by definition, and `mailto:` must\n // not replace the article either.\n target=\"_blank\"\n rel=\"noopener noreferrer me\"\n >\n <MdiIcon path={authorLinkIconPath(link)} size={props.size ?? 0.85} />\n </AppLink>\n )\n })}\n </MuiStack>\n )\n}\n\n/**\n * The rows a card will actually draw, guarded at the boundary.\n *\n * These arrive as PROPS, so a link can reach a renderer without ever passing\n * through the store's normalizer — the reason the byline's own `url` is\n * checked twice as well.\n */\nexport function safeAuthorLinks(\n links: readonly Aglyn.ContentAuthorLink[] | undefined,\n show: boolean | undefined,\n): Aglyn.ContentAuthorLink[] {\n if (show === false) return []\n return (links ?? []).filter((link) =>\n SAFE_AUTHOR_LINK_HREF.test((link?.url ?? '').trim()),\n )\n}\n"],"names":["Aglyn","mdiEmail","mdiFacebook","mdiGithub","mdiInstagram","mdiLinkVariant","mdiLinkedin","mdiMastodon","mdiRss","mdiTwitter","mdiWeb","mdiYoutube","AppLink","MdiIcon","MuiStack","AUTHOR_LINK_ICON_PATHS","twitter","path","linkedin","github","mastodon","youtube","instagram","facebook","web","email","rss","authorLinkIconPath","link","platform","authorLinkPlatform","icon","iconPath","trim","SAFE_AUTHOR_LINK_HREF","AuthorLinkRows","props","links","length","direction","spacing","sx","flexWrap","ml","map","index","label","authorLinkLabel","componentVariant","href","url","aria-label","title","size","color","target","rel","safeAuthorLinks","show","filter","test"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,YAAYA,WAAW,eAAc;AACrC,SACEC,QAAQ,EACRC,WAAW,EACXC,SAAS,EACTC,YAAY,EACZC,cAAc,EACdC,WAAW,EACXC,WAAW,EACXC,MAAM,EACNC,UAAU,EACVC,MAAM,EACNC,UAAU,QACL,yBAAwB;AAC/B,SAASC,OAAO,EAAEC,OAAO,QAAQ,uBAAsB;AACvD,OAAOC,cAAc,sBAAqB;AAE1C;;;;;CAKC,GAED;;;;;;;;;;;CAWC,GACD,MAAMC,yBAAiD;IACrDC,SAASP,WAAWQ,IAAI;IACxBC,UAAUZ,YAAYW,IAAI;IAC1BE,QAAQhB,UAAUc,IAAI;IACtBG,UAAUb,YAAYU,IAAI;IAC1BI,SAASV,WAAWM,IAAI;IACxBK,WAAWlB,aAAaa,IAAI;IAC5BM,UAAUrB,YAAYe,IAAI;IAC1BO,KAAKd,OAAOO,IAAI;IAChBQ,OAAOxB,SAASgB,IAAI;IACpBS,KAAKlB,OAAOS,IAAI;AAClB;AAEA;;;;;;;CAOC,GACD,SAASU,mBAAmBC,IAA6B;QAK/CA;IAJR,MAAMC,WAAW7B,MAAM8B,kBAAkB,CAACF,KAAKC,QAAQ;IACvD,IAAIA,UAAU;YACLd;QAAP,QAAOA,wCAAAA,sBAAsB,CAACc,SAASE,IAAI,CAAC,YAArChB,wCAAyCV,eAAeY,IAAI;IACrE;IACA,OAAO,EAACW,iBAAAA,KAAKI,QAAQ,YAAbJ,iBAAiB,IAAIK,IAAI,MAAM5B,eAAeY,IAAI;AAC5D;AAEA;;;;;;;;;CASC,GACD,MAAMiB,wBAAwB;AAE9B;;;;;;;;;;CAUC,GACD,OAAO,SAASC,eAAeC,KAI9B;IACC,IAAI,CAACA,MAAMC,KAAK,CAACC,MAAM,EAAE,OAAO;IAChC,qBACE,KAACxB;QAASyB,WAAU;QAAMC,SAAS;QAAKC,IAAI;YAAEC,UAAU;YAAQC,IAAI,CAAC;QAAE;kBACpEP,MAAMC,KAAK,CAACO,GAAG,CAAC,CAAChB,MAAMiB;gBAMXjB,WAawCQ;YAlBnD,MAAMU,QAAQ9C,MAAM+C,eAAe,CAACnB;YACpC,qBACE,KAAChB;gBAECoC,kBAAiB;gBACjBC,MAAM,EAACrB,YAAAA,KAAKsB,GAAG,YAARtB,YAAY,IAAIK,IAAI;gBAC3B,kEAAkE;gBAClE,4DAA4D;gBAC5D,sBAAsB;gBACtBkB,cAAYL;gBACZM,OAAON;gBACPO,MAAK;gBACLZ,IAAI;oBAAEa,OAAO;gBAAiB;gBAC9B,kEAAkE;gBAClE,kCAAkC;gBAClCC,QAAO;gBACPC,KAAI;0BAEJ,cAAA,KAAC3C;oBAAQI,MAAMU,mBAAmBC;oBAAOyB,IAAI,GAAEjB,cAAAA,MAAMiB,IAAI,YAAVjB,cAAc;;eAfxDS;QAkBX;;AAGN;AAEA;;;;;;CAMC,GACD,OAAO,SAASY,gBACdpB,KAAqD,EACrDqB,IAAyB;IAEzB,IAAIA,SAAS,OAAO,OAAO,EAAE;IAC7B,OAAO,CAACrB,gBAAAA,QAAS,EAAE,EAAEsB,MAAM,CAAC,CAAC/B;;eAC3BM,sBAAsB0B,IAAI,CAAC,SAAChC,wBAAAA,KAAMsB,GAAG,mBAAI,IAAIjB,IAAI;;AAErD"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import * as Aglyn from '@aglyn/aglyn';
18
+ import { type StackProps } from '@mui/material/Stack';
19
+ export declare const AUTHOR_PROFILE_ID: Aglyn.ComponentId;
20
+ export interface ContentAuthorProfileProps extends StackProps {
21
+ /**
22
+ * The byline. Server-filled from the routed author on their own page
23
+ * (`expandContentAuthorProfile`); set it — or bind `{{author.name}}` —
24
+ * only to override.
25
+ */
26
+ name?: string;
27
+ /** The blurb from their record; bind `{{author.bio}}` to override. */
28
+ bio?: string;
29
+ /**
30
+ * Portrait or logo — a media reference (AGL-1215) or any URL, filled from
31
+ * the record so the face follows the person rather than the template.
32
+ */
33
+ image?: string;
34
+ /** Person only — what they do; blank on an Organization. */
35
+ jobTitle?: string;
36
+ /** Person only — who they write for. */
37
+ worksFor?: string;
38
+ /**
39
+ * Their OWN site. The name links here; blank renders it as plain text.
40
+ * This block already IS the author's page, so it does not link to itself.
41
+ */
42
+ url?: string;
43
+ /** Their profile links, server-filled from the record (AGL-2516). */
44
+ links?: Aglyn.ContentAuthorLink[];
45
+ showBio?: boolean;
46
+ showAvatar?: boolean;
47
+ showRole?: boolean;
48
+ showLinks?: boolean;
49
+ }
50
+ /**
51
+ * Who an author page is about (AGL-2518) — portrait, name, role, bio, links.
52
+ *
53
+ * The Entry Author card renders the same person as a footnote under an
54
+ * article. This renders them as the SUBJECT of a page, which is why it has
55
+ * the two fields that card has no room for: `jobTitle` and `worksFor` are
56
+ * what tell a stranger who they are looking at, and they are already on the
57
+ * record because `schema.org/Person` defines them (AGL-2486).
58
+ *
59
+ * Every field is independently overridable and every one collapses when
60
+ * empty, exactly as the card's do — an author with no portrait renders the
61
+ * text alone rather than a gap where a face would be. On an editing surface
62
+ * the block previews its own shape with sample text, because a template is
63
+ * designed before any author is routed through it.
64
+ */
65
+ declare const ContentAuthorProfile: import("react").ForwardRefExoticComponent<Omit<ContentAuthorProfileProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
66
+ export { ContentAuthorProfile };
67
+ export declare const contentAuthorProfileSchema: Aglyn.ComponentSchema<ContentAuthorProfileProps>;
@@ -0,0 +1,269 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ /**
5
+ * @license
6
+ * Copyright 2026 Aglyn LLC
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */ import * as Aglyn from "@aglyn/aglyn";
20
+ import { mdiAccountCircleOutline } from "@aglyn/shared-data-mdi";
21
+ import { AppLink } from "@aglyn/shared-ui-jsx";
22
+ import Box from "@mui/material/Box";
23
+ import MuiStack from "@mui/material/Stack";
24
+ import Typography from "@mui/material/Typography";
25
+ import { forwardRef, useContext } from "react";
26
+ import { BUNDLE_ID } from "../constants/bundle-common.js";
27
+ import { UNRESOLVED_TOKEN, ENTRY_SAMPLE_AUTHOR, ENTRY_SAMPLE_BIO, samplePortraitSx, metaValue, SAFE_AUTHOR_HREF, EXTERNAL_AUTHOR_HREF } from "./collection-common.js";
28
+ import { AuthorLinkRows, safeAuthorLinks } from "./collection-author-links.js";
29
+ // Persisted component id (AGL-551/582); the compose pipeline references it
30
+ // through the @aglyn/aglyn constant. Never rename.
31
+ export const AUTHOR_PROFILE_ID = Aglyn.CONTENT_AUTHOR_PROFILE_COMPONENT_ID;
32
+ /** The page subject's portrait — a step up from the card's 48px. */ const PROFILE_AVATAR_SIZE = 96;
33
+ /**
34
+ * Who an author page is about (AGL-2518) — portrait, name, role, bio, links.
35
+ *
36
+ * The Entry Author card renders the same person as a footnote under an
37
+ * article. This renders them as the SUBJECT of a page, which is why it has
38
+ * the two fields that card has no room for: `jobTitle` and `worksFor` are
39
+ * what tell a stranger who they are looking at, and they are already on the
40
+ * record because `schema.org/Person` defines them (AGL-2486).
41
+ *
42
+ * Every field is independently overridable and every one collapses when
43
+ * empty, exactly as the card's do — an author with no portrait renders the
44
+ * text alone rather than a gap where a face would be. On an editing surface
45
+ * the block previews its own shape with sample text, because a template is
46
+ * designed before any author is routed through it.
47
+ */ const ContentAuthorProfile = /*#__PURE__*/ forwardRef((props, ref)=>{
48
+ // None of these are DOM attributes (`name` least of all), so they are
49
+ // destructured rather than spread — the stack.ts pattern.
50
+ const { name, bio, image, jobTitle, worksFor, url, links, showBio, showAvatar, showRole, showLinks } = props, rest = _object_without_properties_loose(props, [
51
+ "name",
52
+ "bio",
53
+ "image",
54
+ "jobTitle",
55
+ "worksFor",
56
+ "url",
57
+ "links",
58
+ "showBio",
59
+ "showAvatar",
60
+ "showRole",
61
+ "showLinks"
62
+ ]);
63
+ const nodeSx = Array.isArray(props['sx']) ? props['sx'] : [
64
+ props['sx']
65
+ ];
66
+ const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext);
67
+ const { hostId } = Aglyn.useSite();
68
+ const nameValue = metaValue(name, suppressNavigation);
69
+ const bioValue = showBio !== false ? metaValue(bio, suppressNavigation) : '';
70
+ const jobValue = showRole !== false ? metaValue(jobTitle, suppressNavigation) : '';
71
+ const worksForValue = showRole !== false ? metaValue(worksFor, suppressNavigation) : '';
72
+ const urlRaw = metaValue(url, suppressNavigation);
73
+ const urlValue = SAFE_AUTHOR_HREF.test(urlRaw) ? urlRaw : '';
74
+ // An unresolved token empties on EVERY surface, as in the byline: a literal
75
+ // `{{…}}` in a src is a broken portrait in the canvas.
76
+ const imageRaw = (image != null ? image : '').trim();
77
+ const imageSrc = showAvatar !== false && imageRaw && !UNRESOLVED_TOKEN.test(imageRaw) ? Aglyn.resolveMediaSrc(imageRaw, {
78
+ hostId
79
+ }) : '';
80
+ const linkRows = safeAuthorLinks(links, showLinks);
81
+ // Nothing routed and nothing typed: an editing surface previews the block's
82
+ // own markup at its own settings, and a published page renders nothing at
83
+ // all. Every part still answers its own switch, so a block with Show bio
84
+ // off previews as portrait and name.
85
+ const sample = !nameValue && !bioValue && !jobValue && !imageSrc && !linkRows.length && Boolean(suppressNavigation);
86
+ const displayName = sample ? ENTRY_SAMPLE_AUTHOR : nameValue;
87
+ const displayBio = sample && showBio !== false ? ENTRY_SAMPLE_BIO : bioValue;
88
+ const samplePortrait = sample && showAvatar !== false;
89
+ /**
90
+ * "Founder at Aglyn" — one line, from two fields, and a middle dot would be
91
+ * wrong here: this is a phrase, not a list of facts like the byline's
92
+ * `name · date`. Either field alone still reads.
93
+ */ const roleLine = [
94
+ jobValue,
95
+ worksForValue
96
+ ].filter(Boolean).join(' at ');
97
+ if (!displayName && !displayBio && !roleLine && !imageSrc && !samplePortrait && !linkRows.length) {
98
+ return /*#__PURE__*/ _jsx(Box, _extends({
99
+ ref: ref
100
+ }, rest));
101
+ }
102
+ return /*#__PURE__*/ _jsxs(MuiStack, _extends({
103
+ ref: ref,
104
+ direction: "row",
105
+ spacing: 3
106
+ }, rest, {
107
+ // MERGE, never replace (AGL-1450): `rest.sx` is the array leaf.tsx
108
+ // builds, and spreading it into an object drops every authored value.
109
+ sx: [
110
+ {
111
+ alignItems: 'flex-start'
112
+ },
113
+ ...nodeSx
114
+ ],
115
+ children: [
116
+ imageSrc ? /*#__PURE__*/ _jsx(Box, _extends({
117
+ component: "img",
118
+ src: imageSrc,
119
+ // Decorative: the block names the author in text right beside it.
120
+ alt: "",
121
+ sx: {
122
+ display: 'block',
123
+ flexShrink: 0,
124
+ width: PROFILE_AVATAR_SIZE,
125
+ height: PROFILE_AVATAR_SIZE,
126
+ borderRadius: '50%',
127
+ objectFit: 'cover'
128
+ }
129
+ }, Aglyn.DEFERRED_IMAGE_ATTRIBUTES)) : samplePortrait ? /*#__PURE__*/ _jsx(Box, {
130
+ "aria-hidden": true,
131
+ sx: samplePortraitSx(PROFILE_AVATAR_SIZE)
132
+ }) : null,
133
+ /*#__PURE__*/ _jsxs(MuiStack, {
134
+ spacing: 1,
135
+ sx: {
136
+ minWidth: 0
137
+ },
138
+ children: [
139
+ displayName ? // `h1` because the author IS this page's subject — the one heading
140
+ // rule a built-in body has to get right, since the template around
141
+ // it cannot know what the block will be handed.
142
+ /*#__PURE__*/ _jsx(Typography, {
143
+ component: "h1",
144
+ variant: "h4",
145
+ children: urlValue ? /*#__PURE__*/ _jsx(AppLink, _extends({
146
+ href: urlValue,
147
+ sx: {
148
+ color: 'inherit'
149
+ },
150
+ underline: "hover"
151
+ }, EXTERNAL_AUTHOR_HREF.test(urlValue) ? {
152
+ target: '_blank',
153
+ rel: 'noopener noreferrer'
154
+ } : {}, {
155
+ children: displayName
156
+ })) : displayName
157
+ }) : null,
158
+ roleLine ? /*#__PURE__*/ _jsx(Typography, {
159
+ variant: "subtitle2",
160
+ sx: {
161
+ color: 'text.secondary'
162
+ },
163
+ children: roleLine
164
+ }) : null,
165
+ displayBio ? /*#__PURE__*/ _jsx(Typography, {
166
+ variant: "body1",
167
+ sx: {
168
+ color: 'text.secondary'
169
+ },
170
+ children: displayBio
171
+ }) : null,
172
+ /*#__PURE__*/ _jsx(AuthorLinkRows, {
173
+ links: linkRows,
174
+ size: 1
175
+ })
176
+ ]
177
+ })
178
+ ]
179
+ }));
180
+ });
181
+ ContentAuthorProfile.displayName = 'AglynContentAuthorProfile';
182
+ export { ContentAuthorProfile };
183
+ export const contentAuthorProfileSchema = {
184
+ $id: AUTHOR_PROFILE_ID,
185
+ pluginId: BUNDLE_ID,
186
+ displayName: 'Author Profile',
187
+ description: 'Who an author page is about — portrait, name, role, bio and links.',
188
+ category: Aglyn.ComponentCategory.TEXT,
189
+ icon: {
190
+ path: mdiAccountCircleOutline.path,
191
+ sx: {
192
+ color: 'secondary.main'
193
+ }
194
+ },
195
+ flags: {
196
+ selfClosing: Aglyn.FEATURE_FLAG.ENABLED
197
+ },
198
+ attributes: [
199
+ {
200
+ name: 'name',
201
+ label: 'Name',
202
+ description: 'Blank shows the name of the author whose page this is. Type here ' + '(or bind {{author.name}}) only to override it.',
203
+ component: Aglyn.FieldComponentType.TEXT_FIELD
204
+ },
205
+ {
206
+ name: 'bio',
207
+ label: 'Bio',
208
+ description: 'Blank shows the bio from the author’s record. Type here (or bind ' + '{{author.bio}}) only to override it.',
209
+ component: Aglyn.FieldComponentType.TEXTAREA
210
+ },
211
+ {
212
+ name: 'image',
213
+ label: 'Portrait',
214
+ description: 'Blank shows the portrait of the author whose page this is, at the ' + 'larger size a profile takes. Pick from your media library only to ' + 'override it.',
215
+ component: Aglyn.FieldComponentType.TEXT_FIELD
216
+ },
217
+ {
218
+ name: 'jobTitle',
219
+ label: 'Role',
220
+ description: 'Blank shows the job title from the author’s record. Only a person ' + 'has one — an author record set to Organization leaves it empty.',
221
+ component: Aglyn.FieldComponentType.TEXT_FIELD
222
+ },
223
+ {
224
+ name: 'worksFor',
225
+ label: 'Organization',
226
+ description: 'Blank shows who the author writes for, from their record. Shown ' + 'after the role as "Role at Organization".',
227
+ component: Aglyn.FieldComponentType.TEXT_FIELD
228
+ },
229
+ {
230
+ name: 'url',
231
+ label: 'Link',
232
+ description: 'Blank uses the author’s own url. The name links here; with no url ' + 'it renders as plain text. This block is already the author’s page ' + 'on this site, so it never links to itself.',
233
+ component: Aglyn.FieldComponentType.TEXT_FIELD
234
+ },
235
+ {
236
+ name: 'showLinks',
237
+ label: 'Show links',
238
+ description: 'Off hides the row of profile links under the bio — the place a ' + 'reader follows this author elsewhere. Turning it off on a page ' + 'about them is rarely what you want.',
239
+ component: Aglyn.FieldComponentType.SWITCH,
240
+ // Unset means SHOWN in the renderer above, so the switch has to open
241
+ // in that position or it lies about the block in front of the author
242
+ // (AGL-2506).
243
+ initialValue: true
244
+ },
245
+ {
246
+ name: 'showBio',
247
+ label: 'Show bio',
248
+ description: 'Off leaves the block as a portrait, a name and a role.',
249
+ component: Aglyn.FieldComponentType.SWITCH,
250
+ initialValue: true
251
+ },
252
+ {
253
+ name: 'showRole',
254
+ label: 'Show role',
255
+ description: 'Off hides the "Role at Organization" line under the name.',
256
+ component: Aglyn.FieldComponentType.SWITCH,
257
+ initialValue: true
258
+ },
259
+ {
260
+ name: 'showAvatar',
261
+ label: 'Show portrait',
262
+ description: 'Off drops the portrait and lets the name and bio run the full ' + 'width, with no space held for a picture.',
263
+ component: Aglyn.FieldComponentType.SWITCH,
264
+ initialValue: true
265
+ }
266
+ ]
267
+ };
268
+
269
+ //# sourceMappingURL=collection-author-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/collection-author-profile.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as Aglyn from '@aglyn/aglyn'\nimport { mdiAccountCircleOutline } from '@aglyn/shared-data-mdi'\nimport { AppLink } from '@aglyn/shared-ui-jsx'\nimport Box from '@mui/material/Box'\nimport MuiStack, { type StackProps } from '@mui/material/Stack'\nimport Typography from '@mui/material/Typography'\nimport { forwardRef, useContext } from 'react'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport {\n UNRESOLVED_TOKEN,\n ENTRY_SAMPLE_AUTHOR,\n ENTRY_SAMPLE_BIO,\n samplePortraitSx,\n metaValue,\n SAFE_AUTHOR_HREF,\n EXTERNAL_AUTHOR_HREF,\n} from './collection-common'\nimport { AuthorLinkRows, safeAuthorLinks } from './collection-author-links'\n\n// Persisted component id (AGL-551/582); the compose pipeline references it\n// through the @aglyn/aglyn constant. Never rename.\nexport const AUTHOR_PROFILE_ID: Aglyn.ComponentId =\n Aglyn.CONTENT_AUTHOR_PROFILE_COMPONENT_ID\n\nexport interface ContentAuthorProfileProps extends StackProps {\n /**\n * The byline. Server-filled from the routed author on their own page\n * (`expandContentAuthorProfile`); set it — or bind `{{author.name}}` —\n * only to override.\n */\n name?: string\n /** The blurb from their record; bind `{{author.bio}}` to override. */\n bio?: string\n /**\n * Portrait or logo — a media reference (AGL-1215) or any URL, filled from\n * the record so the face follows the person rather than the template.\n */\n image?: string\n /** Person only — what they do; blank on an Organization. */\n jobTitle?: string\n /** Person only — who they write for. */\n worksFor?: string\n /**\n * Their OWN site. The name links here; blank renders it as plain text.\n * This block already IS the author's page, so it does not link to itself.\n */\n url?: string\n /** Their profile links, server-filled from the record (AGL-2516). */\n links?: Aglyn.ContentAuthorLink[]\n showBio?: boolean\n showAvatar?: boolean\n showRole?: boolean\n showLinks?: boolean\n}\n\n/** The page subject's portrait — a step up from the card's 48px. */\nconst PROFILE_AVATAR_SIZE = 96\n\n/**\n * Who an author page is about (AGL-2518) — portrait, name, role, bio, links.\n *\n * The Entry Author card renders the same person as a footnote under an\n * article. This renders them as the SUBJECT of a page, which is why it has\n * the two fields that card has no room for: `jobTitle` and `worksFor` are\n * what tell a stranger who they are looking at, and they are already on the\n * record because `schema.org/Person` defines them (AGL-2486).\n *\n * Every field is independently overridable and every one collapses when\n * empty, exactly as the card's do — an author with no portrait renders the\n * text alone rather than a gap where a face would be. On an editing surface\n * the block previews its own shape with sample text, because a template is\n * designed before any author is routed through it.\n */\nconst ContentAuthorProfile = forwardRef<\n HTMLDivElement,\n ContentAuthorProfileProps\n>((props, ref) => {\n // None of these are DOM attributes (`name` least of all), so they are\n // destructured rather than spread — the stack.ts pattern.\n const {\n name,\n bio,\n image,\n jobTitle,\n worksFor,\n url,\n links,\n showBio,\n showAvatar,\n showRole,\n showLinks,\n ...rest\n } = props\n const nodeSx = Array.isArray(props['sx']) ? props['sx'] : [props['sx']]\n const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext)\n const { hostId } = Aglyn.useSite()\n const nameValue = metaValue(name, suppressNavigation)\n const bioValue = showBio !== false ? metaValue(bio, suppressNavigation) : ''\n const jobValue = showRole !== false ? metaValue(jobTitle, suppressNavigation) : ''\n const worksForValue =\n showRole !== false ? metaValue(worksFor, suppressNavigation) : ''\n const urlRaw = metaValue(url, suppressNavigation)\n const urlValue = SAFE_AUTHOR_HREF.test(urlRaw) ? urlRaw : ''\n // An unresolved token empties on EVERY surface, as in the byline: a literal\n // `{{…}}` in a src is a broken portrait in the canvas.\n const imageRaw = (image ?? '').trim()\n const imageSrc =\n showAvatar !== false && imageRaw && !UNRESOLVED_TOKEN.test(imageRaw)\n ? Aglyn.resolveMediaSrc(imageRaw, { hostId })\n : ''\n const linkRows = safeAuthorLinks(links, showLinks)\n // Nothing routed and nothing typed: an editing surface previews the block's\n // own markup at its own settings, and a published page renders nothing at\n // all. Every part still answers its own switch, so a block with Show bio\n // off previews as portrait and name.\n const sample =\n !nameValue &&\n !bioValue &&\n !jobValue &&\n !imageSrc &&\n !linkRows.length &&\n Boolean(suppressNavigation)\n const displayName = sample ? ENTRY_SAMPLE_AUTHOR : nameValue\n const displayBio = sample && showBio !== false ? ENTRY_SAMPLE_BIO : bioValue\n const samplePortrait = sample && showAvatar !== false\n /**\n * \"Founder at Aglyn\" — one line, from two fields, and a middle dot would be\n * wrong here: this is a phrase, not a list of facts like the byline's\n * `name · date`. Either field alone still reads.\n */\n const roleLine = [jobValue, worksForValue].filter(Boolean).join(' at ')\n if (\n !displayName &&\n !displayBio &&\n !roleLine &&\n !imageSrc &&\n !samplePortrait &&\n !linkRows.length\n ) {\n return <Box ref={ref} {...rest} />\n }\n return (\n <MuiStack\n ref={ref}\n direction=\"row\"\n spacing={3}\n {...rest}\n // MERGE, never replace (AGL-1450): `rest.sx` is the array leaf.tsx\n // builds, and spreading it into an object drops every authored value.\n sx={[{ alignItems: 'flex-start' }, ...nodeSx]}\n >\n {imageSrc ? (\n <Box\n component=\"img\"\n src={imageSrc}\n // Decorative: the block names the author in text right beside it.\n alt=\"\"\n sx={{\n display: 'block',\n flexShrink: 0,\n width: PROFILE_AVATAR_SIZE,\n height: PROFILE_AVATAR_SIZE,\n borderRadius: '50%',\n objectFit: 'cover',\n }}\n {...Aglyn.DEFERRED_IMAGE_ATTRIBUTES}\n />\n ) : samplePortrait ? (\n <Box aria-hidden sx={samplePortraitSx(PROFILE_AVATAR_SIZE)} />\n ) : null}\n <MuiStack spacing={1} sx={{ minWidth: 0 }}>\n {displayName ? (\n // `h1` because the author IS this page's subject — the one heading\n // rule a built-in body has to get right, since the template around\n // it cannot know what the block will be handed.\n <Typography component=\"h1\" variant=\"h4\">\n {urlValue ? (\n <AppLink\n href={urlValue}\n sx={{ color: 'inherit' }}\n underline=\"hover\"\n {...(EXTERNAL_AUTHOR_HREF.test(urlValue)\n ? { target: '_blank', rel: 'noopener noreferrer' }\n : {})}\n >\n {displayName}\n </AppLink>\n ) : (\n displayName\n )}\n </Typography>\n ) : null}\n {roleLine ? (\n <Typography variant=\"subtitle2\" sx={{ color: 'text.secondary' }}>\n {roleLine}\n </Typography>\n ) : null}\n {displayBio ? (\n <Typography variant=\"body1\" sx={{ color: 'text.secondary' }}>\n {displayBio}\n </Typography>\n ) : null}\n <AuthorLinkRows links={linkRows} size={1} />\n </MuiStack>\n </MuiStack>\n )\n})\nContentAuthorProfile.displayName = 'AglynContentAuthorProfile'\n\nexport { ContentAuthorProfile }\n\nexport const contentAuthorProfileSchema: Aglyn.ComponentSchema<ContentAuthorProfileProps> =\n {\n $id: AUTHOR_PROFILE_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Author Profile',\n description:\n 'Who an author page is about — portrait, name, role, bio and links.',\n category: Aglyn.ComponentCategory.TEXT,\n icon: {\n path: mdiAccountCircleOutline.path,\n sx: { color: 'secondary.main' },\n },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'name',\n label: 'Name',\n description:\n 'Blank shows the name of the author whose page this is. Type here ' +\n '(or bind {{author.name}}) only to override it.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'bio',\n label: 'Bio',\n description:\n 'Blank shows the bio from the author’s record. Type here (or bind ' +\n '{{author.bio}}) only to override it.',\n component: Aglyn.FieldComponentType.TEXTAREA,\n },\n {\n name: 'image',\n label: 'Portrait',\n description:\n 'Blank shows the portrait of the author whose page this is, at the ' +\n 'larger size a profile takes. Pick from your media library only to ' +\n 'override it.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'jobTitle',\n label: 'Role',\n description:\n 'Blank shows the job title from the author’s record. Only a person ' +\n 'has one — an author record set to Organization leaves it empty.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'worksFor',\n label: 'Organization',\n description:\n 'Blank shows who the author writes for, from their record. Shown ' +\n 'after the role as \"Role at Organization\".',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'url',\n label: 'Link',\n description:\n 'Blank uses the author’s own url. The name links here; with no url ' +\n 'it renders as plain text. This block is already the author’s page ' +\n 'on this site, so it never links to itself.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'showLinks',\n label: 'Show links',\n description:\n 'Off hides the row of profile links under the bio — the place a ' +\n 'reader follows this author elsewhere. Turning it off on a page ' +\n 'about them is rarely what you want.',\n component: Aglyn.FieldComponentType.SWITCH,\n // Unset means SHOWN in the renderer above, so the switch has to open\n // in that position or it lies about the block in front of the author\n // (AGL-2506).\n initialValue: true,\n },\n {\n name: 'showBio',\n label: 'Show bio',\n description:\n 'Off leaves the block as a portrait, a name and a role.',\n component: Aglyn.FieldComponentType.SWITCH,\n initialValue: true,\n },\n {\n name: 'showRole',\n label: 'Show role',\n description:\n 'Off hides the \"Role at Organization\" line under the name.',\n component: Aglyn.FieldComponentType.SWITCH,\n initialValue: true,\n },\n {\n name: 'showAvatar',\n label: 'Show portrait',\n description:\n 'Off drops the portrait and lets the name and bio run the full ' +\n 'width, with no space held for a picture.',\n component: Aglyn.FieldComponentType.SWITCH,\n initialValue: true,\n },\n ],\n }\n"],"names":["Aglyn","mdiAccountCircleOutline","AppLink","Box","MuiStack","Typography","forwardRef","useContext","BUNDLE_ID","UNRESOLVED_TOKEN","ENTRY_SAMPLE_AUTHOR","ENTRY_SAMPLE_BIO","samplePortraitSx","metaValue","SAFE_AUTHOR_HREF","EXTERNAL_AUTHOR_HREF","AuthorLinkRows","safeAuthorLinks","AUTHOR_PROFILE_ID","CONTENT_AUTHOR_PROFILE_COMPONENT_ID","PROFILE_AVATAR_SIZE","ContentAuthorProfile","props","ref","name","bio","image","jobTitle","worksFor","url","links","showBio","showAvatar","showRole","showLinks","rest","nodeSx","Array","isArray","suppressNavigation","ScreenLinkContext","hostId","useSite","nameValue","bioValue","jobValue","worksForValue","urlRaw","urlValue","test","imageRaw","trim","imageSrc","resolveMediaSrc","linkRows","sample","length","Boolean","displayName","displayBio","samplePortrait","roleLine","filter","join","direction","spacing","sx","alignItems","component","src","alt","display","flexShrink","width","height","borderRadius","objectFit","DEFERRED_IMAGE_ATTRIBUTES","aria-hidden","minWidth","variant","href","color","underline","target","rel","size","contentAuthorProfileSchema","$id","pluginId","description","category","ComponentCategory","TEXT","icon","path","flags","selfClosing","FEATURE_FLAG","ENABLED","attributes","label","FieldComponentType","TEXT_FIELD","TEXTAREA","SWITCH","initialValue"],"mappings":";;;AAAA;;;;;;;;;;;;;;;CAeC,GAED,YAAYA,WAAW,eAAc;AACrC,SAASC,uBAAuB,QAAQ,yBAAwB;AAChE,SAASC,OAAO,QAAQ,uBAAsB;AAC9C,OAAOC,SAAS,oBAAmB;AACnC,OAAOC,cAAmC,sBAAqB;AAC/D,OAAOC,gBAAgB,2BAA0B;AACjD,SAASC,UAAU,EAAEC,UAAU,QAAQ,QAAO;AAC9C,SAASC,SAAS,QAAQ,gCAA4B;AACtD,SACEC,gBAAgB,EAChBC,mBAAmB,EACnBC,gBAAgB,EAChBC,gBAAgB,EAChBC,SAAS,EACTC,gBAAgB,EAChBC,oBAAoB,QACf,yBAAqB;AAC5B,SAASC,cAAc,EAAEC,eAAe,QAAQ,+BAA2B;AAE3E,2EAA2E;AAC3E,mDAAmD;AACnD,OAAO,MAAMC,oBACXlB,MAAMmB,mCAAmC,CAAA;AAiC3C,kEAAkE,GAClE,MAAMC,sBAAsB;AAE5B;;;;;;;;;;;;;;CAcC,GACD,MAAMC,qCAAuBf,WAG3B,CAACgB,OAAOC;IACR,sEAAsE;IACtE,0DAA0D;IAC1D,MAAM,EACJC,IAAI,EACJC,GAAG,EACHC,KAAK,EACLC,QAAQ,EACRC,QAAQ,EACRC,GAAG,EACHC,KAAK,EACLC,OAAO,EACPC,UAAU,EACVC,QAAQ,EACRC,SAAS,EAEV,GAAGZ,OADCa,wCACDb;;;;;;;;;;;;;IACJ,MAAMc,SAASC,MAAMC,OAAO,CAAChB,KAAK,CAAC,KAAK,IAAIA,KAAK,CAAC,KAAK,GAAG;QAACA,KAAK,CAAC,KAAK;KAAC;IACvE,MAAM,EAAEiB,kBAAkB,EAAE,GAAGhC,WAAWP,MAAMwC,iBAAiB;IACjE,MAAM,EAAEC,MAAM,EAAE,GAAGzC,MAAM0C,OAAO;IAChC,MAAMC,YAAY9B,UAAUW,MAAMe;IAClC,MAAMK,WAAWb,YAAY,QAAQlB,UAAUY,KAAKc,sBAAsB;IAC1E,MAAMM,WAAWZ,aAAa,QAAQpB,UAAUc,UAAUY,sBAAsB;IAChF,MAAMO,gBACJb,aAAa,QAAQpB,UAAUe,UAAUW,sBAAsB;IACjE,MAAMQ,SAASlC,UAAUgB,KAAKU;IAC9B,MAAMS,WAAWlC,iBAAiBmC,IAAI,CAACF,UAAUA,SAAS;IAC1D,4EAA4E;IAC5E,uDAAuD;IACvD,MAAMG,WAAW,CAACxB,gBAAAA,QAAS,IAAIyB,IAAI;IACnC,MAAMC,WACJpB,eAAe,SAASkB,YAAY,CAACzC,iBAAiBwC,IAAI,CAACC,YACvDlD,MAAMqD,eAAe,CAACH,UAAU;QAAET;IAAO,KACzC;IACN,MAAMa,WAAWrC,gBAAgBa,OAAOI;IACxC,4EAA4E;IAC5E,0EAA0E;IAC1E,yEAAyE;IACzE,qCAAqC;IACrC,MAAMqB,SACJ,CAACZ,aACD,CAACC,YACD,CAACC,YACD,CAACO,YACD,CAACE,SAASE,MAAM,IAChBC,QAAQlB;IACV,MAAMmB,cAAcH,SAAS7C,sBAAsBiC;IACnD,MAAMgB,aAAaJ,UAAUxB,YAAY,QAAQpB,mBAAmBiC;IACpE,MAAMgB,iBAAiBL,UAAUvB,eAAe;IAChD;;;;GAIC,GACD,MAAM6B,WAAW;QAAChB;QAAUC;KAAc,CAACgB,MAAM,CAACL,SAASM,IAAI,CAAC;IAChE,IACE,CAACL,eACD,CAACC,cACD,CAACE,YACD,CAACT,YACD,CAACQ,kBACD,CAACN,SAASE,MAAM,EAChB;QACA,qBAAO,KAACrD;YAAIoB,KAAKA;WAASY;IAC5B;IACA,qBACE,MAAC/B;QACCmB,KAAKA;QACLyC,WAAU;QACVC,SAAS;OACL9B;QACJ,mEAAmE;QACnE,sEAAsE;QACtE+B,IAAI;YAAC;gBAAEC,YAAY;YAAa;eAAM/B;SAAO;;YAE5CgB,yBACC,KAACjD;gBACCiE,WAAU;gBACVC,KAAKjB;gBACL,kEAAkE;gBAClEkB,KAAI;gBACJJ,IAAI;oBACFK,SAAS;oBACTC,YAAY;oBACZC,OAAOrD;oBACPsD,QAAQtD;oBACRuD,cAAc;oBACdC,WAAW;gBACb;eACI5E,MAAM6E,yBAAyB,KAEnCjB,+BACF,KAACzD;gBAAI2E,aAAW;gBAACZ,IAAItD,iBAAiBQ;iBACpC;0BACJ,MAAChB;gBAAS6D,SAAS;gBAAGC,IAAI;oBAAEa,UAAU;gBAAE;;oBACrCrB,cACC,mEAAmE;oBACnE,mEAAmE;oBACnE,gDAAgD;kCAChD,KAACrD;wBAAW+D,WAAU;wBAAKY,SAAQ;kCAChChC,yBACC,KAAC9C;4BACC+E,MAAMjC;4BACNkB,IAAI;gCAAEgB,OAAO;4BAAU;4BACvBC,WAAU;2BACLpE,qBAAqBkC,IAAI,CAACD,YAC3B;4BAAEoC,QAAQ;4BAAUC,KAAK;wBAAsB,IAC/C,CAAC;sCAEJ3B;8BAGHA;yBAGF;oBACHG,yBACC,KAACxD;wBAAW2E,SAAQ;wBAAYd,IAAI;4BAAEgB,OAAO;wBAAiB;kCAC3DrB;yBAED;oBACHF,2BACC,KAACtD;wBAAW2E,SAAQ;wBAAQd,IAAI;4BAAEgB,OAAO;wBAAiB;kCACvDvB;yBAED;kCACJ,KAAC3C;wBAAec,OAAOwB;wBAAUgC,MAAM;;;;;;AAI/C;AACAjE,qBAAqBqC,WAAW,GAAG;AAEnC,SAASrC,oBAAoB,GAAE;AAE/B,OAAO,MAAMkE,6BACX;IACEC,KAAKtE;IACLuE,UAAUjF;IACVkD,aAAa;IACbgC,aACE;IACFC,UAAU3F,MAAM4F,iBAAiB,CAACC,IAAI;IACtCC,MAAM;QACJC,MAAM9F,wBAAwB8F,IAAI;QAClC7B,IAAI;YAAEgB,OAAO;QAAiB;IAChC;IACAc,OAAO;QAAEC,aAAajG,MAAMkG,YAAY,CAACC,OAAO;IAAC;IACjDC,YAAY;QACV;YACE5E,MAAM;YACN6E,OAAO;YACPX,aACE,sEACA;YACFtB,WAAWpE,MAAMsG,kBAAkB,CAACC,UAAU;QAChD;QACA;YACE/E,MAAM;YACN6E,OAAO;YACPX,aACE,sEACA;YACFtB,WAAWpE,MAAMsG,kBAAkB,CAACE,QAAQ;QAC9C;QACA;YACEhF,MAAM;YACN6E,OAAO;YACPX,aACE,uEACA,uEACA;YACFtB,WAAWpE,MAAMsG,kBAAkB,CAACC,UAAU;QAChD;QACA;YACE/E,MAAM;YACN6E,OAAO;YACPX,aACE,uEACA;YACFtB,WAAWpE,MAAMsG,kBAAkB,CAACC,UAAU;QAChD;QACA;YACE/E,MAAM;YACN6E,OAAO;YACPX,aACE,qEACA;YACFtB,WAAWpE,MAAMsG,kBAAkB,CAACC,UAAU;QAChD;QACA;YACE/E,MAAM;YACN6E,OAAO;YACPX,aACE,uEACA,uEACA;YACFtB,WAAWpE,MAAMsG,kBAAkB,CAACC,UAAU;QAChD;QACA;YACE/E,MAAM;YACN6E,OAAO;YACPX,aACE,oEACA,oEACA;YACFtB,WAAWpE,MAAMsG,kBAAkB,CAACG,MAAM;YAC1C,qEAAqE;YACrE,qEAAqE;YACrE,cAAc;YACdC,cAAc;QAChB;QACA;YACElF,MAAM;YACN6E,OAAO;YACPX,aACE;YACFtB,WAAWpE,MAAMsG,kBAAkB,CAACG,MAAM;YAC1CC,cAAc;QAChB;QACA;YACElF,MAAM;YACN6E,OAAO;YACPX,aACE;YACFtB,WAAWpE,MAAMsG,kBAAkB,CAACG,MAAM;YAC1CC,cAAc;QAChB;QACA;YACElF,MAAM;YACN6E,OAAO;YACPX,aACE,mEACA;YACFtB,WAAWpE,MAAMsG,kBAAkB,CAACG,MAAM;YAC1CC,cAAc;QAChB;KACD;AACH,EAAC"}