@justai/cuts 0.80.0 → 0.82.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.
- package/package.json +2 -2
- package/src/ChildPersona.astro +68 -36
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justai/cuts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.82.0",
|
|
4
4
|
"description": "A persona's named parts — the page shell that holds them, and the cuts themselves.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"repository": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@justai/core": "^0.
|
|
40
|
+
"@justai/core": "^0.12.0",
|
|
41
41
|
"@justai/ui": "^0",
|
|
42
42
|
"@justai/atrium": "^0.1.9"
|
|
43
43
|
}
|
package/src/ChildPersona.astro
CHANGED
|
@@ -103,6 +103,13 @@ interface Props {
|
|
|
103
103
|
bio?: string;
|
|
104
104
|
/** The small print under the bio — what it costs, what it keeps. */
|
|
105
105
|
meta?: string;
|
|
106
|
+
/** The child's own colours for its avatar well. Genuinely per-child taste: /me is a dark vault,
|
|
107
|
+
* /files is a light sheet of paper. */
|
|
108
|
+
avatarBg?: string;
|
|
109
|
+
avatarBgLight?: string;
|
|
110
|
+
avatarPad?: string;
|
|
111
|
+
/** The cover behind the profile. Defaults to the host persona's accent, which is the point. */
|
|
112
|
+
cover?: string;
|
|
106
113
|
/** The host persona's face, if the page already resolved it server-side. Otherwise `childFace()`
|
|
107
114
|
* fills it in at runtime from /api/face — see @justai/core. */
|
|
108
115
|
host?: { name?: string; avatar?: string; accent?: string };
|
|
@@ -121,51 +128,76 @@ const {
|
|
|
121
128
|
child, name, bio, meta, host,
|
|
122
129
|
parentHref = "/#kernel", parentLabel = "Home",
|
|
123
130
|
sectionsLabel = "Sections", profileLabel, kernelLabel, face = "page",
|
|
131
|
+
avatarBg = "linear-gradient(160deg, #1f2740, #11141f)",
|
|
132
|
+
avatarBgLight = "linear-gradient(160deg, #f4f6fb, #fff)",
|
|
133
|
+
avatarPad = "15px",
|
|
134
|
+
cover = "linear-gradient(135deg, color-mix(in srgb, var(--accent) 88%, #fff), var(--accent) 55%, color-mix(in srgb, var(--accent) 70%, #000))",
|
|
124
135
|
} = Astro.props;
|
|
125
136
|
// `page` is the default because it is the face a child shows when nobody asked for one — somebody
|
|
126
137
|
// typed the address. A guest is always ASKED for, which is why the caller names it.
|
|
127
138
|
const chrome = face === "page";
|
|
128
139
|
---
|
|
129
140
|
|
|
130
|
-
{/* `.pp` IS the child persona
|
|
131
|
-
|
|
132
|
-
<div class="pp" id="pp" data-child={child} data-face={face}>
|
|
133
|
-
{/* A PRESENTED CHILD SHOWS NO PROFILE AND NO ROW. It is content inside somebody's sheet, and a
|
|
134
|
-
biography there is the guest introducing itself while the host is mid-sentence. Standalone it
|
|
135
|
-
is a full persona page, because then it IS the page. */}
|
|
136
|
-
{chrome && (
|
|
137
|
-
<>
|
|
138
|
-
<Profile
|
|
139
|
-
name={name}
|
|
140
|
-
handle={`@${child}`}
|
|
141
|
-
bio={bio}
|
|
142
|
-
meta={meta}
|
|
143
|
-
kernelLabel={name}
|
|
144
|
-
avatarBg="#fff"
|
|
145
|
-
avatarPad="14px"
|
|
146
|
-
cover="linear-gradient(135deg, color-mix(in srgb, var(--accent) 88%, #fff), var(--accent) 55%, color-mix(in srgb, var(--accent) 70%, #000))"
|
|
147
|
-
>
|
|
148
|
-
<Fragment slot="avatar"><slot name="mark" /></Fragment>
|
|
149
|
-
</Profile>
|
|
141
|
+
{/* `.pp` IS the child persona — one wrapper, every face. `data-face` is how the kernel inside asks
|
|
142
|
+
which one it is in without re-deriving it from the URL.
|
|
150
143
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
144
|
+
IT RENDERS THE COLUMN ITSELF. An earlier draft styled `.pp .app` and left the consumer to emit
|
|
145
|
+
the element, which is precisely the homework law 1 forbids: a shell whose geometry only works if
|
|
146
|
+
somebody remembers a class name is a template, not a component. */}
|
|
147
|
+
<div class="pp" id="pp" data-child={child} data-face={face}>
|
|
148
|
+
<main class="app">
|
|
149
|
+
{/* THE `sheet` FACE SHOWS NO PROFILE AND NO ROW. It is content inside somebody's chrome, and a
|
|
150
|
+
biography there is the guest introducing itself while the host is mid-sentence. As a `page`
|
|
151
|
+
it IS the page, so it wears the whole persona shape. */}
|
|
152
|
+
{chrome ? (
|
|
153
|
+
<>
|
|
154
|
+
{/* queries: pnName pnHandle pnMeta · the child persona shows the wrong name · host identity
|
|
155
|
+
in a child's profile · why are there spans in these strings
|
|
156
|
+
THE IDS ARE THE CONTRACT, and they are here rather than in each child because both
|
|
157
|
+
children were already doing this identically.
|
|
158
|
+
A child persona ADOPTS ITS HOST'S IDENTITY at runtime: the page is built once and mounted
|
|
159
|
+
on every persona's host, so the name, the handle and the small print cannot be known at
|
|
160
|
+
build time. They are rendered as spans with stable ids and rewritten by `childFace()` in
|
|
161
|
+
@justai/core once /api/face answers. What the server renders is the honest fallback — the
|
|
162
|
+
child's own words, correct if the lookup never returns. */}
|
|
163
|
+
<Profile
|
|
164
|
+
name={`<span id="pnName">${name}</span><span class="pro" id="pnFacet"></span>`}
|
|
165
|
+
handle={`<span id="pnHandle">@${child}</span>`}
|
|
166
|
+
bio={bio ? `<span id="pnBio">${bio}</span>` : undefined}
|
|
167
|
+
meta={`<span id="pnMeta">${meta ?? ""}</span>`}
|
|
168
|
+
kernelLabel={name}
|
|
169
|
+
avatarBg={avatarBg}
|
|
170
|
+
avatarBgLight={avatarBgLight}
|
|
171
|
+
avatarPad={avatarPad}
|
|
172
|
+
cover={cover}
|
|
159
173
|
>
|
|
160
|
-
<Fragment slot="
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
<
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
174
|
+
<Fragment slot="avatar"><slot name="mark" /></Fragment>
|
|
175
|
+
</Profile>
|
|
176
|
+
|
|
177
|
+
<div class="below" id="below">
|
|
178
|
+
<Toolbar
|
|
179
|
+
sectionsLabel={sectionsLabel}
|
|
180
|
+
profileLabel={profileLabel ?? name}
|
|
181
|
+
kernelLabel={kernelLabel ?? name}
|
|
182
|
+
postsLabel="Posts"
|
|
183
|
+
parent={{ href: parentHref, label: parentLabel, icon: host?.avatar }}
|
|
184
|
+
files={false}
|
|
185
|
+
>
|
|
186
|
+
<Fragment slot="profileIcon"><slot name="mark" /></Fragment>
|
|
187
|
+
<slot name="langPicker" slot="langPicker" />
|
|
188
|
+
</Toolbar>
|
|
189
|
+
<section class="cut kernel" id="kernel"><slot /></section>
|
|
190
|
+
</div>
|
|
191
|
+
</>
|
|
192
|
+
) : (
|
|
193
|
+
<section class="cut kernel" id="kernel" data-guest><slot /></section>
|
|
194
|
+
)}
|
|
195
|
+
</main>
|
|
167
196
|
|
|
168
|
-
{
|
|
197
|
+
{/* Sheets, toasts, confirmations — inside `.pp` so they take the child's tokens, OUTSIDE `.app`
|
|
198
|
+
so the column does not clip or centre them. Every child has some; naming the slot is what
|
|
199
|
+
stops each one inventing a different place to put them. */}
|
|
200
|
+
<slot name="overlays" />
|
|
169
201
|
</div>
|
|
170
202
|
|
|
171
203
|
<style>
|