@maple-kit/ui 0.1.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/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +39 -0
- package/dist/composer/actions.d.ts +15 -0
- package/dist/composer/actions.js +59 -0
- package/dist/composer/attachments.d.ts +33 -0
- package/dist/composer/attachments.js +166 -0
- package/dist/composer/badge.d.ts +13 -0
- package/dist/composer/badge.js +25 -0
- package/dist/composer/body.d.ts +13 -0
- package/dist/composer/body.js +119 -0
- package/dist/composer/composer.d.ts +23 -0
- package/dist/composer/composer.js +122 -0
- package/dist/composer/css.js +559 -0
- package/dist/composer/detail.d.ts +32 -0
- package/dist/composer/detail.js +102 -0
- package/dist/composer/emoji.d.ts +54 -0
- package/dist/composer/emoji.js +131 -0
- package/dist/composer/index.d.ts +15 -0
- package/dist/composer/index.js +15 -0
- package/dist/composer/inset.js +20 -0
- package/dist/composer/leave.d.ts +19 -0
- package/dist/composer/leave.js +34 -0
- package/dist/composer/peek.d.ts +21 -0
- package/dist/composer/peek.js +29 -0
- package/dist/composer/phrase.d.ts +27 -0
- package/dist/composer/phrase.js +30 -0
- package/dist/composer/picker-emoji.d.ts +34 -0
- package/dist/composer/picker-emoji.js +48 -0
- package/dist/composer/prompt.js +31 -0
- package/dist/composer/scope.d.ts +11 -0
- package/dist/composer/scope.js +16 -0
- package/dist/composer/target.d.ts +13 -0
- package/dist/composer/target.js +45 -0
- package/dist/context.d.ts +21 -0
- package/dist/context.js +16 -0
- package/dist/data.d.ts +52 -0
- package/dist/data.js +30 -0
- package/dist/icons/branch.d.ts +4 -0
- package/dist/icons/branch.js +8 -0
- package/dist/icons/cog.d.ts +4 -0
- package/dist/icons/cog.js +8 -0
- package/dist/icons/commit.d.ts +4 -0
- package/dist/icons/commit.js +5 -0
- package/dist/icons/crossfade.d.ts +15 -0
- package/dist/icons/crossfade.js +27 -0
- package/dist/icons/element.d.ts +4 -0
- package/dist/icons/element.js +5 -0
- package/dist/icons/icon.d.ts +24 -0
- package/dist/icons/icon.js +27 -0
- package/dist/icons/index.d.ts +13 -0
- package/dist/icons/index.js +13 -0
- package/dist/icons/noplace.d.ts +4 -0
- package/dist/icons/noplace.js +5 -0
- package/dist/icons/region.d.ts +4 -0
- package/dist/icons/region.js +8 -0
- package/dist/icons/smiley.d.ts +4 -0
- package/dist/icons/smiley.js +8 -0
- package/dist/icons/sparkle.d.ts +4 -0
- package/dist/icons/sparkle.js +8 -0
- package/dist/icons/target.d.ts +4 -0
- package/dist/icons/target.js +5 -0
- package/dist/icons/text.d.ts +4 -0
- package/dist/icons/text.js +5 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -0
- package/dist/island/account.d.ts +10 -0
- package/dist/island/account.js +52 -0
- package/dist/island/comments.d.ts +24 -0
- package/dist/island/comments.js +40 -0
- package/dist/island/content.d.ts +10 -0
- package/dist/island/content.js +26 -0
- package/dist/island/context.d.ts +58 -0
- package/dist/island/context.js +23 -0
- package/dist/island/css.d.ts +13 -0
- package/dist/island/css.js +1020 -0
- package/dist/island/drag.d.ts +10 -0
- package/dist/island/drag.js +77 -0
- package/dist/island/filters.d.ts +10 -0
- package/dist/island/filters.js +63 -0
- package/dist/island/header.d.ts +32 -0
- package/dist/island/header.js +47 -0
- package/dist/island/index.d.ts +18 -0
- package/dist/island/index.js +18 -0
- package/dist/island/island.d.ts +12 -0
- package/dist/island/island.js +111 -0
- package/dist/island/item.d.ts +12 -0
- package/dist/island/item.js +158 -0
- package/dist/island/language.d.ts +55 -0
- package/dist/island/language.js +125 -0
- package/dist/island/leaf.js +17 -0
- package/dist/island/list.d.ts +12 -0
- package/dist/island/list.js +31 -0
- package/dist/island/new-comment.d.ts +18 -0
- package/dist/island/new-comment.js +56 -0
- package/dist/island/settings.d.ts +10 -0
- package/dist/island/settings.js +134 -0
- package/dist/island/stagger.d.ts +12 -0
- package/dist/island/stagger.js +4 -0
- package/dist/island/time.d.ts +17 -0
- package/dist/island/time.js +29 -0
- package/dist/island/trigger.d.ts +10 -0
- package/dist/island/trigger.js +39 -0
- package/dist/language.d.ts +45 -0
- package/dist/language.js +66 -0
- package/dist/maple.d.ts +25 -0
- package/dist/maple.js +65 -0
- package/dist/marks/avatar.d.ts +16 -0
- package/dist/marks/avatar.js +36 -0
- package/dist/marks/css.d.ts +12 -0
- package/dist/marks/css.js +371 -0
- package/dist/marks/frame.d.ts +25 -0
- package/dist/marks/frame.js +53 -0
- package/dist/marks/geometry.d.ts +55 -0
- package/dist/marks/geometry.js +61 -0
- package/dist/marks/index.d.ts +14 -0
- package/dist/marks/index.js +14 -0
- package/dist/marks/label.d.ts +23 -0
- package/dist/marks/label.js +31 -0
- package/dist/marks/layer.d.ts +16 -0
- package/dist/marks/layer.js +194 -0
- package/dist/marks/leaf.d.ts +18 -0
- package/dist/marks/leaf.js +7 -0
- package/dist/marks/mark.d.ts +28 -0
- package/dist/marks/mark.js +43 -0
- package/dist/marks/nudge.d.ts +50 -0
- package/dist/marks/nudge.js +76 -0
- package/dist/marks/paint.d.ts +11 -0
- package/dist/marks/paint.js +19 -0
- package/dist/marks/placement.d.ts +24 -0
- package/dist/marks/placement.js +28 -0
- package/dist/marks/ring.d.ts +28 -0
- package/dist/marks/ring.js +85 -0
- package/dist/marks/shape.d.ts +21 -0
- package/dist/marks/shape.js +51 -0
- package/dist/notice/css.d.ts +11 -0
- package/dist/notice/css.js +74 -0
- package/dist/notice/index.d.ts +4 -0
- package/dist/notice/index.js +4 -0
- package/dist/notice/language.d.ts +15 -0
- package/dist/notice/language.js +14 -0
- package/dist/notice/notice.d.ts +14 -0
- package/dist/notice/notice.js +49 -0
- package/dist/part.d.ts +9 -0
- package/dist/part.js +11 -0
- package/dist/picker/css.d.ts +13 -0
- package/dist/picker/css.js +141 -0
- package/dist/picker/index.d.ts +6 -0
- package/dist/picker/index.js +6 -0
- package/dist/picker/language.d.ts +14 -0
- package/dist/picker/language.js +17 -0
- package/dist/picker/picker.d.ts +18 -0
- package/dist/picker/picker.js +164 -0
- package/dist/picker/session.d.ts +16 -0
- package/dist/picker/session.js +35 -0
- package/dist/picker/target.d.ts +23 -0
- package/dist/picker/target.js +37 -0
- package/dist/root.d.ts +42 -0
- package/dist/root.js +75 -0
- package/dist/shots.js +32 -0
- package/dist/slot.d.ts +28 -0
- package/dist/slot.js +52 -0
- package/dist/slots.d.ts +24 -0
- package/dist/slots.js +75 -0
- package/dist/stylesheet.d.ts +15 -0
- package/dist/stylesheet.js +188 -0
- package/dist/theme.d.ts +20 -0
- package/dist/theme.js +13 -0
- package/dist/tip.d.ts +40 -0
- package/dist/tip.js +82 -0
- package/dist/tokens.d.ts +28 -0
- package/dist/tokens.js +180 -0
- package/package.json +56 -0
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
import "../tokens.js";
|
|
2
|
+
//#region src/composer/css.ts
|
|
3
|
+
const NARROW = `@media (max-width: 639px)`;
|
|
4
|
+
function composerCss() {
|
|
5
|
+
return `
|
|
6
|
+
${shellCss()}
|
|
7
|
+
|
|
8
|
+
${partsCss()}
|
|
9
|
+
|
|
10
|
+
${controlCss()}
|
|
11
|
+
|
|
12
|
+
${NARROW} {
|
|
13
|
+
${sheetCss()}
|
|
14
|
+
}
|
|
15
|
+
`.trim();
|
|
16
|
+
}
|
|
17
|
+
function shellCss() {
|
|
18
|
+
return `
|
|
19
|
+
.mk-composer {
|
|
20
|
+
position: absolute;
|
|
21
|
+
top: 0;
|
|
22
|
+
right: 0;
|
|
23
|
+
bottom: 0;
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
gap: 11px;
|
|
27
|
+
overflow-x: hidden;
|
|
28
|
+
overflow-y: auto;
|
|
29
|
+
width: var(--mk-composer-w);
|
|
30
|
+
max-width: 100%;
|
|
31
|
+
border-radius: var(--mk-composer-r);
|
|
32
|
+
border-left: 1px solid var(--mk-line-firm);
|
|
33
|
+
background: var(--mk-bg);
|
|
34
|
+
box-shadow: var(--mk-sh3);
|
|
35
|
+
opacity: 0;
|
|
36
|
+
transform: translateX(var(--mk-shift-composer));
|
|
37
|
+
pointer-events: none;
|
|
38
|
+
transition:
|
|
39
|
+
opacity var(--mk-dur-composer-close) var(--mk-ease-surface),
|
|
40
|
+
transform var(--mk-dur-composer-close) var(--mk-ease-surface);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:host([data-mk-scheme="dark"]) .mk-composer {
|
|
44
|
+
box-shadow: var(--mk-sh3), inset 0 1px 0 oklch(1 0 0 / 0.045);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.mk-composer[data-mk-open="true"] {
|
|
48
|
+
opacity: 1;
|
|
49
|
+
transform: translateX(0);
|
|
50
|
+
pointer-events: auto;
|
|
51
|
+
transition:
|
|
52
|
+
opacity var(--mk-dur-composer-open) var(--mk-ease-surface),
|
|
53
|
+
transform var(--mk-dur-composer-open) var(--mk-ease-surface);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.mk-composer[data-mk-moving="true"] {
|
|
57
|
+
will-change: transform, opacity;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.mk-composer[data-mk-open="true"][data-mk-peek="true"] {
|
|
61
|
+
opacity: 0.08;
|
|
62
|
+
pointer-events: none;
|
|
63
|
+
transition: opacity var(--mk-dur-fade) var(--mk-ease-surface);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.mk-composer-head {
|
|
67
|
+
position: sticky;
|
|
68
|
+
top: 0;
|
|
69
|
+
z-index: 1;
|
|
70
|
+
flex: none;
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
gap: 8px;
|
|
74
|
+
padding: 10px 12px;
|
|
75
|
+
border-bottom: 1px solid var(--mk-line);
|
|
76
|
+
background: var(--mk-bg);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.mk-composer-fill {
|
|
80
|
+
flex: 1 1 auto;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.mk-composer-row {
|
|
84
|
+
flex: none;
|
|
85
|
+
margin: 0 12px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.mk-composer-foot {
|
|
89
|
+
position: sticky;
|
|
90
|
+
bottom: 0;
|
|
91
|
+
margin-top: auto;
|
|
92
|
+
flex: none;
|
|
93
|
+
display: flex;
|
|
94
|
+
align-items: center;
|
|
95
|
+
gap: 8px;
|
|
96
|
+
padding: 9px 12px;
|
|
97
|
+
border-top: 1px solid var(--mk-line);
|
|
98
|
+
background: var(--mk-sunk);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.mk-grab {
|
|
102
|
+
display: none;
|
|
103
|
+
}
|
|
104
|
+
`.trim();
|
|
105
|
+
}
|
|
106
|
+
function emojiCss() {
|
|
107
|
+
return `
|
|
108
|
+
.mk-emoji {
|
|
109
|
+
position: absolute;
|
|
110
|
+
right: 6px;
|
|
111
|
+
bottom: 6px;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.mk-emoji-open {
|
|
115
|
+
display: grid;
|
|
116
|
+
place-items: center;
|
|
117
|
+
width: 24px;
|
|
118
|
+
height: 24px;
|
|
119
|
+
border: 0;
|
|
120
|
+
border-radius: var(--mk-r-xs);
|
|
121
|
+
background: transparent;
|
|
122
|
+
color: var(--mk-muted);
|
|
123
|
+
font: inherit;
|
|
124
|
+
line-height: 0;
|
|
125
|
+
cursor: pointer;
|
|
126
|
+
transition:
|
|
127
|
+
background-color var(--mk-dur-swap) var(--mk-ease-swap),
|
|
128
|
+
color var(--mk-dur-swap) var(--mk-ease-swap);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.mk-emoji-open:hover,
|
|
132
|
+
.mk-emoji-open[aria-expanded="true"] {
|
|
133
|
+
background: var(--mk-sunk);
|
|
134
|
+
color: var(--mk-fg);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.mk-emoji-grid {
|
|
138
|
+
position: absolute;
|
|
139
|
+
right: 0;
|
|
140
|
+
bottom: calc(100% + 6px);
|
|
141
|
+
z-index: 6;
|
|
142
|
+
display: grid;
|
|
143
|
+
grid-template-columns: repeat(6, 1fr);
|
|
144
|
+
gap: 1px;
|
|
145
|
+
padding: 5px;
|
|
146
|
+
border: 1px solid var(--mk-line-firm);
|
|
147
|
+
border-radius: var(--mk-r-sm);
|
|
148
|
+
background: var(--mk-bg);
|
|
149
|
+
box-shadow: var(--mk-sh2);
|
|
150
|
+
transform-origin: bottom right;
|
|
151
|
+
animation: mk-pop-in var(--mk-dur-tooltip) var(--mk-ease-surface);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* The shortcode menu is the same grid against the field rather than against
|
|
155
|
+
the control, because it belongs to the word being typed. */
|
|
156
|
+
.mk-emoji-menu {
|
|
157
|
+
right: auto;
|
|
158
|
+
left: 8px;
|
|
159
|
+
bottom: auto;
|
|
160
|
+
top: calc(100% - 2px);
|
|
161
|
+
grid-template-columns: repeat(auto-fit, 26px);
|
|
162
|
+
transform-origin: top left;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.mk-emoji-one {
|
|
166
|
+
width: 26px;
|
|
167
|
+
height: 26px;
|
|
168
|
+
border: 0;
|
|
169
|
+
border-radius: var(--mk-r-xs);
|
|
170
|
+
background: transparent;
|
|
171
|
+
font-size: 15px;
|
|
172
|
+
line-height: 1;
|
|
173
|
+
cursor: pointer;
|
|
174
|
+
transition: background-color var(--mk-dur-swap) var(--mk-ease-swap);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.mk-emoji-one:hover,
|
|
178
|
+
.mk-emoji-one[aria-selected="true"] {
|
|
179
|
+
background: var(--mk-sunk);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.mk-emoji-one[aria-selected="true"] {
|
|
183
|
+
box-shadow: inset 0 0 0 1px var(--mk-line-firm);
|
|
184
|
+
}
|
|
185
|
+
`.trim();
|
|
186
|
+
}
|
|
187
|
+
function contextAndShots() {
|
|
188
|
+
return `
|
|
189
|
+
/* Two pairs to a row: seven facts one per line ran the card down half the
|
|
190
|
+
panel. Labels keep their own column, so every value still lines up. */
|
|
191
|
+
.mk-ctx {
|
|
192
|
+
display: grid;
|
|
193
|
+
grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr);
|
|
194
|
+
gap: 7px 10px;
|
|
195
|
+
margin: 2px 16px 4px;
|
|
196
|
+
padding: 11px 13px;
|
|
197
|
+
border: 1px solid var(--mk-line);
|
|
198
|
+
border-radius: var(--mk-r-sm);
|
|
199
|
+
background: var(--mk-sunk);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.mk-ctx dt {
|
|
203
|
+
align-self: baseline;
|
|
204
|
+
color: var(--mk-faint);
|
|
205
|
+
font-size: 9px;
|
|
206
|
+
font-weight: 700;
|
|
207
|
+
letter-spacing: 0.08em;
|
|
208
|
+
text-transform: uppercase;
|
|
209
|
+
white-space: nowrap;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.mk-ctx dd {
|
|
213
|
+
margin: 0;
|
|
214
|
+
min-width: 0;
|
|
215
|
+
color: var(--mk-fg);
|
|
216
|
+
font-size: 12px;
|
|
217
|
+
font-variant-numeric: tabular-nums;
|
|
218
|
+
overflow-wrap: anywhere;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.mk-ctx dd em {
|
|
222
|
+
color: var(--mk-muted);
|
|
223
|
+
font-style: normal;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.mk-ctx dd.mk-mono {
|
|
227
|
+
font-size: 11px;
|
|
228
|
+
word-break: break-all;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* One pair to a row, not two: these values are sentences, and the context
|
|
232
|
+
badge's four columns cut them to a word each. */
|
|
233
|
+
.mk-detail {
|
|
234
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* Dashed, because nobody asked for what is inside it: the shot arrives on its
|
|
238
|
+
own at pick time, and a dashed edge is how this surface already says
|
|
239
|
+
"provisional" — it is what an unsent comment's mark is drawn with. */
|
|
240
|
+
.mk-shots {
|
|
241
|
+
display: flex;
|
|
242
|
+
align-items: center;
|
|
243
|
+
gap: 9px;
|
|
244
|
+
padding: 8px 9px;
|
|
245
|
+
border: 1px dashed var(--mk-line-firm);
|
|
246
|
+
border-radius: var(--mk-r-sm);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.mk-shots img {
|
|
250
|
+
display: block;
|
|
251
|
+
flex: none;
|
|
252
|
+
width: 72px;
|
|
253
|
+
height: 46px;
|
|
254
|
+
object-fit: cover;
|
|
255
|
+
object-position: top;
|
|
256
|
+
border-radius: var(--mk-r-xs);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* The strip says where its image came from, or how to put one there. It is a
|
|
260
|
+
sentence, not a chip: a chip is a fact, and this is an instruction. */
|
|
261
|
+
.mk-shot-said {
|
|
262
|
+
flex: 1 1 auto;
|
|
263
|
+
min-width: 0;
|
|
264
|
+
display: flex;
|
|
265
|
+
align-items: center;
|
|
266
|
+
gap: 5px;
|
|
267
|
+
color: var(--mk-faint);
|
|
268
|
+
font-size: 11px;
|
|
269
|
+
line-height: 1.4;
|
|
270
|
+
text-wrap: pretty;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.mk-shot-said svg {
|
|
274
|
+
flex: none;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/* What Maple noticed on its own, in the one warm colour nothing a reviewer
|
|
278
|
+
did uses. No fill and no solid edge: a filled panel in a warm colour reads
|
|
279
|
+
as an error, and nothing is wrong when this shows. The dashed border was
|
|
280
|
+
already how this surface says "provisional"; it only changes colour. */
|
|
281
|
+
.mk-shots[data-mk-maple] {
|
|
282
|
+
border-color: color-mix(in oklab, var(--mk-maple) 55%, transparent);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.mk-shot-said[data-mk-maple],
|
|
286
|
+
.mk-ctx dd[data-mk-maple] {
|
|
287
|
+
color: var(--mk-maple);
|
|
288
|
+
font-weight: 550;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* The same, for a fact the panel raises rather than one the comment carries. */
|
|
292
|
+
.mk-ctx dd[data-mk-maple] em {
|
|
293
|
+
color: color-mix(in oklab, var(--mk-maple) 78%, var(--mk-muted));
|
|
294
|
+
font-weight: 450;
|
|
295
|
+
}
|
|
296
|
+
`.trim();
|
|
297
|
+
}
|
|
298
|
+
function partsCss() {
|
|
299
|
+
return `
|
|
300
|
+
.mk-target {
|
|
301
|
+
display: inline-flex;
|
|
302
|
+
align-items: center;
|
|
303
|
+
gap: 6px;
|
|
304
|
+
min-width: 0;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* The icon is optically centred, not box-centred: its 16-unit box has more
|
|
308
|
+
air under the glyph than over it, so the square needs the difference back. */
|
|
309
|
+
.mk-target-kind {
|
|
310
|
+
display: grid;
|
|
311
|
+
place-items: center;
|
|
312
|
+
flex: none;
|
|
313
|
+
width: 22px;
|
|
314
|
+
height: 22px;
|
|
315
|
+
border: 1px solid var(--mk-line);
|
|
316
|
+
border-radius: var(--mk-r-xs);
|
|
317
|
+
background: var(--mk-sunk);
|
|
318
|
+
color: var(--mk-muted);
|
|
319
|
+
line-height: 0;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.mk-target-kind svg {
|
|
323
|
+
display: block;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.mk-target-on {
|
|
327
|
+
font-size: 12px;
|
|
328
|
+
color: var(--mk-muted);
|
|
329
|
+
overflow: hidden;
|
|
330
|
+
text-overflow: ellipsis;
|
|
331
|
+
white-space: nowrap;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.mk-target-on b {
|
|
335
|
+
color: var(--mk-fg);
|
|
336
|
+
font-weight: 600;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/* The passage itself, quoted: a reviewer who selected six words reads those
|
|
340
|
+
six words back rather than the name of the paragraph they were in. */
|
|
341
|
+
.mk-target-quote {
|
|
342
|
+
color: var(--mk-fg);
|
|
343
|
+
font-style: italic;
|
|
344
|
+
font-weight: 500;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.mk-chip {
|
|
348
|
+
display: inline-flex;
|
|
349
|
+
align-items: center;
|
|
350
|
+
gap: 4px;
|
|
351
|
+
flex: none;
|
|
352
|
+
padding: 1px 7px 1px 5px;
|
|
353
|
+
border-radius: 999px;
|
|
354
|
+
border: 1px solid var(--mk-line);
|
|
355
|
+
background: var(--mk-sunk);
|
|
356
|
+
color: var(--mk-muted);
|
|
357
|
+
font-size: 10.5px;
|
|
358
|
+
font-weight: 650;
|
|
359
|
+
white-space: nowrap;
|
|
360
|
+
font-variant-numeric: tabular-nums;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/* The field and the control in its corner are one box, so the focus ring goes
|
|
364
|
+
round both and the caret never leaves the thing it is typing into. */
|
|
365
|
+
.mk-field-wrap {
|
|
366
|
+
position: relative;
|
|
367
|
+
display: flex;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.mk-field {
|
|
371
|
+
flex: 1 1 auto;
|
|
372
|
+
width: auto;
|
|
373
|
+
min-height: 78px;
|
|
374
|
+
padding: 8px 34px 8px 10px;
|
|
375
|
+
resize: vertical;
|
|
376
|
+
border: 1px solid var(--mk-line-firm);
|
|
377
|
+
border-radius: var(--mk-r-sm);
|
|
378
|
+
background: var(--mk-bg);
|
|
379
|
+
color: var(--mk-fg);
|
|
380
|
+
font-family: var(--mk-font);
|
|
381
|
+
font-size: 13px;
|
|
382
|
+
line-height: 1.5;
|
|
383
|
+
outline: none;
|
|
384
|
+
transition:
|
|
385
|
+
border-color var(--mk-dur-fade) var(--mk-ease-surface),
|
|
386
|
+
box-shadow var(--mk-dur-fade) var(--mk-ease-surface);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.mk-field:focus {
|
|
390
|
+
border-color: var(--mk-accent);
|
|
391
|
+
box-shadow: 0 0 0 3px color-mix(in oklab, var(--mk-accent) 22%, transparent);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/* A comment already written is read, not edited: one body per comment, so
|
|
395
|
+
there is no field here to put a caret in. */
|
|
396
|
+
.mk-read {
|
|
397
|
+
margin: 0 12px;
|
|
398
|
+
padding: 0;
|
|
399
|
+
color: var(--mk-fg);
|
|
400
|
+
font-size: 13.5px;
|
|
401
|
+
line-height: 1.62;
|
|
402
|
+
text-wrap: pretty;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
${emojiCss()}
|
|
406
|
+
|
|
407
|
+
${contextAndShots()}
|
|
408
|
+
|
|
409
|
+
.mk-leave {
|
|
410
|
+
position: absolute;
|
|
411
|
+
top: 12px;
|
|
412
|
+
left: 50%;
|
|
413
|
+
z-index: 3;
|
|
414
|
+
max-width: calc(100% - 24px);
|
|
415
|
+
padding: 11px 13px;
|
|
416
|
+
border: 1px solid var(--mk-line-firm);
|
|
417
|
+
border-radius: var(--mk-r);
|
|
418
|
+
background: var(--mk-bg);
|
|
419
|
+
box-shadow: var(--mk-sh3);
|
|
420
|
+
opacity: 0;
|
|
421
|
+
transform: translateX(-50%) scale(var(--mk-scale-island));
|
|
422
|
+
pointer-events: none;
|
|
423
|
+
transition:
|
|
424
|
+
opacity var(--mk-dur-island-close) var(--mk-ease-surface),
|
|
425
|
+
transform var(--mk-dur-island-close) var(--mk-ease-surface);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.mk-leave[data-mk-open="true"] {
|
|
429
|
+
opacity: 1;
|
|
430
|
+
transform: translateX(-50%) scale(1);
|
|
431
|
+
pointer-events: auto;
|
|
432
|
+
transition:
|
|
433
|
+
opacity var(--mk-dur-island-open) var(--mk-ease-surface),
|
|
434
|
+
transform var(--mk-dur-island-open) var(--mk-ease-surface);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
.mk-leave-say {
|
|
438
|
+
margin: 0 0 9px;
|
|
439
|
+
font-size: 12.5px;
|
|
440
|
+
font-weight: 600;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.mk-leave-ask {
|
|
444
|
+
display: flex;
|
|
445
|
+
align-items: center;
|
|
446
|
+
justify-content: flex-end;
|
|
447
|
+
gap: 8px;
|
|
448
|
+
}
|
|
449
|
+
`.trim();
|
|
450
|
+
}
|
|
451
|
+
function controlCss() {
|
|
452
|
+
return `
|
|
453
|
+
.mk-btn {
|
|
454
|
+
display: inline-flex;
|
|
455
|
+
align-items: center;
|
|
456
|
+
justify-content: center;
|
|
457
|
+
gap: 6px;
|
|
458
|
+
flex: none;
|
|
459
|
+
padding: 3px 8px;
|
|
460
|
+
border: 1px solid var(--mk-line-firm);
|
|
461
|
+
border-radius: var(--mk-r-sm);
|
|
462
|
+
background: var(--mk-bg);
|
|
463
|
+
color: var(--mk-fg);
|
|
464
|
+
box-shadow: var(--mk-sh1);
|
|
465
|
+
font-family: var(--mk-font);
|
|
466
|
+
font-size: 11.5px;
|
|
467
|
+
font-weight: 550;
|
|
468
|
+
cursor: pointer;
|
|
469
|
+
transition:
|
|
470
|
+
background-color var(--mk-dur-fade) var(--mk-ease-surface),
|
|
471
|
+
color var(--mk-dur-fade) var(--mk-ease-surface),
|
|
472
|
+
filter var(--mk-dur-fade) var(--mk-ease-surface),
|
|
473
|
+
transform var(--mk-dur-fade) var(--mk-ease-surface);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.mk-btn:hover {
|
|
477
|
+
background: var(--mk-sunk);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
.mk-btn[disabled] {
|
|
481
|
+
opacity: 0.45;
|
|
482
|
+
pointer-events: none;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.mk-btn-primary {
|
|
486
|
+
border-color: transparent;
|
|
487
|
+
background: var(--mk-accent);
|
|
488
|
+
color: var(--mk-accent-ink);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
.mk-btn-primary:hover {
|
|
492
|
+
background: var(--mk-accent);
|
|
493
|
+
filter: brightness(1.07);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.mk-btn-quiet {
|
|
497
|
+
border-color: transparent;
|
|
498
|
+
background: transparent;
|
|
499
|
+
box-shadow: none;
|
|
500
|
+
color: var(--mk-muted);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.mk-btn-quiet:hover {
|
|
504
|
+
background: var(--mk-sunk);
|
|
505
|
+
color: var(--mk-fg);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.mk-shut {
|
|
509
|
+
padding: 3px 7px;
|
|
510
|
+
font-size: 12px;
|
|
511
|
+
line-height: 1;
|
|
512
|
+
}
|
|
513
|
+
`.trim();
|
|
514
|
+
}
|
|
515
|
+
function sheetCss() {
|
|
516
|
+
return `
|
|
517
|
+
.mk-composer {
|
|
518
|
+
top: auto;
|
|
519
|
+
left: 0;
|
|
520
|
+
right: 0;
|
|
521
|
+
bottom: 0;
|
|
522
|
+
max-height: 78%;
|
|
523
|
+
border-left: 0;
|
|
524
|
+
border-top: 1px solid var(--mk-line-firm);
|
|
525
|
+
transform: translateY(var(--mk-shift-composer));
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.mk-composer[data-mk-open="true"] {
|
|
529
|
+
transform: translateY(0);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
.mk-composer[data-mk-detent="half"] {
|
|
533
|
+
max-height: 46%;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
.mk-composer-head {
|
|
537
|
+
top: 11px;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.mk-grab {
|
|
541
|
+
position: sticky;
|
|
542
|
+
top: 0;
|
|
543
|
+
z-index: 2;
|
|
544
|
+
display: block;
|
|
545
|
+
flex: none;
|
|
546
|
+
width: 34px;
|
|
547
|
+
height: 4px;
|
|
548
|
+
margin: 7px auto 0;
|
|
549
|
+
padding: 0;
|
|
550
|
+
border: 0;
|
|
551
|
+
border-radius: 999px;
|
|
552
|
+
background: var(--mk-line-firm);
|
|
553
|
+
cursor: grab;
|
|
554
|
+
touch-action: none;
|
|
555
|
+
}
|
|
556
|
+
`.trimEnd();
|
|
557
|
+
}
|
|
558
|
+
//#endregion
|
|
559
|
+
export { composerCss };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { AsChildProps } from "../slot.js";
|
|
2
|
+
import { ComposerTarget, Detail } from "@maple-kit/core/client";
|
|
3
|
+
import { Comment } from "@maple-kit/core";
|
|
4
|
+
//#region src/composer/detail.d.ts
|
|
5
|
+
/** The block. Takes `asChild` and nothing that changes its look. */
|
|
6
|
+
export interface MapleDetailProps extends AsChildProps {
|
|
7
|
+
readonly className?: string;
|
|
8
|
+
}
|
|
9
|
+
/** One labelled line. `mono` is for a value that is a path, not a phrase. */
|
|
10
|
+
interface DetailRow {
|
|
11
|
+
readonly label: string;
|
|
12
|
+
readonly value: string;
|
|
13
|
+
readonly note?: string;
|
|
14
|
+
readonly mono?: boolean;
|
|
15
|
+
/** Drawn in the one warm colour: something Maple noticed, not a status. */
|
|
16
|
+
readonly noticed?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** The panel's account of what it has open. Absent when it has nothing. */
|
|
19
|
+
export declare const MapleDetail: import("react").ForwardRefExoticComponent<MapleDetailProps & import("react").RefAttributes<HTMLElement>>;
|
|
20
|
+
/** What the block is built from. Everything but the detail may be missing. */
|
|
21
|
+
interface DetailInput {
|
|
22
|
+
readonly comment: Comment | undefined;
|
|
23
|
+
readonly target?: ComposerTarget;
|
|
24
|
+
readonly detail: Detail;
|
|
25
|
+
readonly root: ParentNode;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Who and where-in-its-life first, because those are true of every comment;
|
|
29
|
+
* the cascade's own account after, and only when it was asked for.
|
|
30
|
+
*/
|
|
31
|
+
export declare function detailRows(input: DetailInput): readonly DetailRow[];
|
|
32
|
+
//#endregion
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { useMapleUi } from "../context.js";
|
|
2
|
+
import { confidenceFor } from "../data.js";
|
|
3
|
+
import { DETAIL_COPY, ORPHAN_LABELS, PROVENANCE_SENTENCES, RUNG_LABELS, STATUS_LABELS, STATUS_SENTENCES, orphanTitle, rungLabel } from "../language.js";
|
|
4
|
+
import { Slot } from "../slot.js";
|
|
5
|
+
import { Fragment, createElement, forwardRef } from "react";
|
|
6
|
+
import { useMaple } from "@maple-kit/react";
|
|
7
|
+
import { kindOf, resolveAnchor } from "@maple-kit/core/anchor";
|
|
8
|
+
//#region src/composer/detail.ts
|
|
9
|
+
const PART = "Maple.Detail";
|
|
10
|
+
const MapleDetail = forwardRef(function MapleDetail(props, ref) {
|
|
11
|
+
const { comments, composer, detail } = useMaple();
|
|
12
|
+
const { container } = useMapleUi(PART);
|
|
13
|
+
const Element = props.asChild ? Slot : "dl";
|
|
14
|
+
const rows = detailRows({
|
|
15
|
+
comment: comments.find((one) => one.id === composer.viewing),
|
|
16
|
+
detail,
|
|
17
|
+
root: container.ownerDocument,
|
|
18
|
+
...composer.target === void 0 ? {} : { target: composer.target }
|
|
19
|
+
});
|
|
20
|
+
if (rows.length === 0) return null;
|
|
21
|
+
const className = [
|
|
22
|
+
"mk-composer-row",
|
|
23
|
+
"mk-ctx",
|
|
24
|
+
"mk-detail",
|
|
25
|
+
props.className
|
|
26
|
+
].filter(Boolean).join(" ");
|
|
27
|
+
return createElement(Element, {
|
|
28
|
+
ref,
|
|
29
|
+
className,
|
|
30
|
+
"data-mk-detail": detail
|
|
31
|
+
}, ...rows.map(lineOf));
|
|
32
|
+
});
|
|
33
|
+
function detailRows(input) {
|
|
34
|
+
const anchor = input.comment?.anchor ?? input.target?.anchor;
|
|
35
|
+
if (!anchor) return [];
|
|
36
|
+
const found = resolveAnchor(anchor, { root: input.root });
|
|
37
|
+
return [
|
|
38
|
+
...about(input.comment),
|
|
39
|
+
...lost(found),
|
|
40
|
+
...technical(anchor, found, input.detail)
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
function lost(found) {
|
|
44
|
+
if (found.status !== "orphaned") return [];
|
|
45
|
+
return [{
|
|
46
|
+
label: DETAIL_COPY.lost,
|
|
47
|
+
value: ORPHAN_LABELS[found.reason],
|
|
48
|
+
note: orphanTitle(found.reason, found.tried).replace(`${ORPHAN_LABELS[found.reason]}. `, ""),
|
|
49
|
+
noticed: true
|
|
50
|
+
}];
|
|
51
|
+
}
|
|
52
|
+
function about(comment) {
|
|
53
|
+
if (!comment) return [];
|
|
54
|
+
return [{
|
|
55
|
+
label: DETAIL_COPY.author,
|
|
56
|
+
value: comment.author.name,
|
|
57
|
+
note: PROVENANCE_SENTENCES[comment.author.provenance]
|
|
58
|
+
}, {
|
|
59
|
+
label: DETAIL_COPY.status,
|
|
60
|
+
value: STATUS_LABELS[comment.status],
|
|
61
|
+
note: STATUS_SENTENCES[comment.status]
|
|
62
|
+
}];
|
|
63
|
+
}
|
|
64
|
+
function technical(anchor, found, detail) {
|
|
65
|
+
if (detail !== "developer") return [];
|
|
66
|
+
return [
|
|
67
|
+
...found.status === "resolved" ? [rung(found)] : [],
|
|
68
|
+
...kindOf(anchor) === "region" && anchor.region ? [area(anchor.region)] : [],
|
|
69
|
+
...pathRow(DETAIL_COPY.source, anchor.source),
|
|
70
|
+
...pathRow(DETAIL_COPY.selector, anchor.selector)
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
function rung(found) {
|
|
74
|
+
return {
|
|
75
|
+
label: DETAIL_COPY.rung,
|
|
76
|
+
value: `${RUNG_LABELS[found.by]} · ${rungLabel(Math.round(found.confidence * 100))}`,
|
|
77
|
+
note: `${confidenceFor(found.confidence)} — ${DETAIL_COPY.rungNote}`
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function area(region) {
|
|
81
|
+
const percent = (value) => `${String(Math.round(value * 100))}%`;
|
|
82
|
+
return {
|
|
83
|
+
label: DETAIL_COPY.area,
|
|
84
|
+
value: `${percent(region.width)} × ${percent(region.height)}`,
|
|
85
|
+
note: DETAIL_COPY.areaNote
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function pathRow(label, value) {
|
|
89
|
+
return value === void 0 ? [] : [{
|
|
90
|
+
label,
|
|
91
|
+
value,
|
|
92
|
+
mono: true
|
|
93
|
+
}];
|
|
94
|
+
}
|
|
95
|
+
function lineOf(row) {
|
|
96
|
+
return createElement(Fragment, { key: row.label }, createElement("dt", null, row.label), createElement("dd", {
|
|
97
|
+
...row.mono === true ? { className: "mk-mono" } : {},
|
|
98
|
+
...row.noticed === true ? { "data-mk-maple": "true" } : {}
|
|
99
|
+
}, row.value, row.note === void 0 ? null : createElement("em", null, ` · ${row.note}`)));
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
102
|
+
export { MapleDetail, detailRows };
|