@crewlethq/ui 0.9.0 → 0.10.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/README.md +15 -0
- package/dist/Avatar/Avatar.d.ts +45 -14
- package/dist/Avatar/AvatarStack.d.ts +1 -3
- package/dist/Avatar/index.d.ts +2 -2
- package/dist/Avatar/index.js +2 -2
- package/dist/{Avatar-JAU77SHZ.css → Avatar-QHYOFID3.css} +83 -25
- package/dist/CharacterPicker/index.js +2 -2
- package/dist/EntityChip/index.js +3 -3
- package/dist/ImageUpload/index.js +3 -3
- package/dist/OrgLabel/index.js +3 -3
- package/dist/OrgNode/index.js +4 -4
- package/dist/OrgTable/index.js +4 -4
- package/dist/{chunk-OAH4IEQJ.js → chunk-3UK4VFSK.js} +2 -3
- package/dist/{chunk-J3IS2TOA.js → chunk-6OF2DBKY.js} +1 -1
- package/dist/{chunk-JB6AN4ZC.js → chunk-7FFDJQ23.js} +1 -1
- package/dist/{chunk-Y2V3TSQC.js → chunk-DDTDN5L2.js} +1 -1
- package/dist/chunk-HI6Q2UXQ.js +169 -0
- package/dist/{chunk-K7OS4O2U.js → chunk-IHGKPEEV.js} +1 -1
- package/dist/{chunk-E3HDS4F7.js → chunk-LAQK4V3Z.js} +1 -1
- package/dist/{chunk-IKH3Y4MP.js → chunk-UO5UK7V2.js} +1 -1
- package/dist/generated/index.js +8 -8
- package/dist/index.js +8 -8
- package/dist/styles.css +86 -28
- package/package.json +3 -3
- package/dist/chunk-UDW3DAP5.js +0 -125
package/README.md
CHANGED
|
@@ -191,6 +191,21 @@ places:
|
|
|
191
191
|
- A surface that pans or zooms dispatches `LAYER_REPOSITION_EVENT` on its host
|
|
192
192
|
when the content beneath it moves, and every panel anchored inside follows.
|
|
193
193
|
|
|
194
|
+
## Breaking changes in 0.10.0
|
|
195
|
+
|
|
196
|
+
0.10.0 moves an agent's state off the ring round its badge and onto a small badge on its corner.
|
|
197
|
+
|
|
198
|
+
**A state is a status, never a ring.** `Avatar` takes `status`: `working`, `needs` (waiting on a person) or `stopped`, and none for idle. It draws a round badge on the lower-right corner, the state's fill carrying a glyph whose shape says it (play, a question mark, a square) in `--color-text-inverse`, which the tokens' palette suite now holds at 3:1 on each fill (`MARK_ON_FILL`). The badge sits in a notch cut out of the face with a mask, so it reads on any ground without knowing its colour. A badge with a status is drawn inside a `.crewlet-avatar-frame` of the face's own size, which takes your `className` and `style`; a badge that names itself appends the state to its accessible name (`Software Engineer avatar, stopped`), and a decorative one says nothing, so say the state in words beside it. `AVATAR_STATUSES` and `AVATAR_STATUS_LABELS` list the statuses and their words. A ring of a state's hue round a plate in the agent's own hue put two colours on one small mark, and framed what the agent was doing louder than who it is.
|
|
199
|
+
|
|
200
|
+
| Was | Is |
|
|
201
|
+
|---|---|
|
|
202
|
+
| `<Avatar ring="info">`, `ring="warning"`, `ring="danger"` for what a seat is doing | `status="working"`, `status="needs"`, `status="stopped"` |
|
|
203
|
+
| `<Avatar ring="success">` | no status; say a finished state in words beside the badge |
|
|
204
|
+
| `AvatarRing` naming `info`, `warning`, `danger` or `success` | `AvatarRing` is `'brand'` alone, the selected ring; a state is an `AvatarStatus` |
|
|
205
|
+
| an `AvatarStack` member's `ring` | nothing: each member overlaps the one before it, so a corner badge would be hidden; say what the members are doing beside the stack |
|
|
206
|
+
| a stylesheet of your own reading `.crewlet-avatar--ring-info`, `-warning`, `-danger` or `-success` | `.crewlet-avatar__status--working`, `--needs` or `--stopped` |
|
|
207
|
+
| a `ring="brand"` and a `status` on one badge | the status alone; the notch is cut from the outline the ring would follow, so a badge with a status draws no ring |
|
|
208
|
+
|
|
194
209
|
## Changes in 0.9.0
|
|
195
210
|
|
|
196
211
|
0.9.0 gives an agent a face of its own: one of the thirty Crewlet characters in `@crewlethq/icons/characters`, drawn in one of the six node hues an operator chooses for it.
|
package/dist/Avatar/Avatar.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { HTMLAttributes } from 'react';
|
|
2
2
|
import { type CrewletCharacterId } from '@crewlethq/icons/characters';
|
|
3
3
|
import type { NodeHue } from '../utils/nodeHue.js';
|
|
4
|
-
import type { Tone } from '../utils/tone.js';
|
|
5
4
|
/**
|
|
6
5
|
* WHAT THE BADGE STANDS FOR, drawn as its outline.
|
|
7
6
|
*
|
|
@@ -37,16 +36,37 @@ export type AvatarKind = 'agent' | 'human';
|
|
|
37
36
|
*/
|
|
38
37
|
export type AvatarTone = 'neutral' | 'seeded';
|
|
39
38
|
/**
|
|
40
|
-
* The
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* `
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
|
|
39
|
+
* The SELECTED ring: a 1.5px line 2px outside the badge, in the accent.
|
|
40
|
+
*
|
|
41
|
+
* It is the one ring there is. A ring used to carry a state too (`info`,
|
|
42
|
+
* `warning`, `danger`, `success`), and on a character plate that already
|
|
43
|
+
* wears its own hue it put a second colour round a 32px mark, framing what
|
|
44
|
+
* the agent was doing louder than who it is. A state is a [AvatarStatus]
|
|
45
|
+
* now, a small badge on the corner whose SHAPE says it.
|
|
46
|
+
*/
|
|
47
|
+
export type AvatarRing = 'brand';
|
|
48
|
+
/**
|
|
49
|
+
* WHAT AN AGENT IS DOING, drawn as a small round badge on the lower-right
|
|
50
|
+
* corner: `working`, `needs` (it is waiting on a person) or `stopped`. An idle
|
|
51
|
+
* badge carries none, because a mark that means "nothing is happening" is one
|
|
52
|
+
* a reader learns to skip.
|
|
53
|
+
*
|
|
54
|
+
* SHAPE FIRST, colour second. Each badge is a state's fill step carrying a
|
|
55
|
+
* glyph, play for working, a question for needs and a square for stopped, so
|
|
56
|
+
* it reads to somebody who cannot separate the hues and in forced-colors mode,
|
|
57
|
+
* where every fill is one system colour. The glyph is in the inverse ink,
|
|
58
|
+
* which the tokens' palette suite holds at 3:1 on each fill (`MARK_ON_FILL`).
|
|
59
|
+
*
|
|
60
|
+
* THE BADGE IS NOT THE ONLY CARRIER. A row that draws a badge with a status
|
|
61
|
+
* says the state in words as well; a badge drawn alone (a breadcrumb, a stack)
|
|
62
|
+
* is the case the glyph exists for. A badge that names itself appends the
|
|
63
|
+
* state to its accessible name.
|
|
48
64
|
*/
|
|
49
|
-
export type
|
|
65
|
+
export type AvatarStatus = 'working' | 'needs' | 'stopped';
|
|
66
|
+
/** Every status, in the order a legend lists them. */
|
|
67
|
+
export declare const AVATAR_STATUSES: readonly ["working", "needs", "stopped"];
|
|
68
|
+
/** What each status is called in a sentence: the accessible name's last words. */
|
|
69
|
+
export declare const AVATAR_STATUS_LABELS: Readonly<Record<AvatarStatus, string>>;
|
|
50
70
|
/** The four steps, in px. A number is accepted for anything outside them. */
|
|
51
71
|
export declare const AVATAR_SIZES: {
|
|
52
72
|
readonly xs: 20;
|
|
@@ -81,8 +101,13 @@ export interface AvatarProps extends HTMLAttributes<HTMLElement> {
|
|
|
81
101
|
/** An agent (the default) is a squircle; a human is a circle. */
|
|
82
102
|
kind?: AvatarKind | undefined;
|
|
83
103
|
tone?: AvatarTone | undefined;
|
|
84
|
-
/**
|
|
104
|
+
/**
|
|
105
|
+
* The selected ring, or none. Not drawn on a badge with a `status`: the
|
|
106
|
+
* corner badge is cut out of the outline the ring would follow.
|
|
107
|
+
*/
|
|
85
108
|
ring?: AvatarRing | undefined;
|
|
109
|
+
/** What the agent is doing, as a corner badge; none is idle. */
|
|
110
|
+
status?: AvatarStatus | undefined;
|
|
86
111
|
/**
|
|
87
112
|
* The name is already printed beside this badge, so the badge itself says
|
|
88
113
|
* nothing. Without it a row reads "Carlos Diaz avatar, Carlos Diaz".
|
|
@@ -164,7 +189,13 @@ export declare function avatarCorner(pixels: number): number;
|
|
|
164
189
|
*
|
|
165
190
|
* If the image fails to load (a stale CDN URL, an expired signature) it
|
|
166
191
|
* degrades to the initials rather than to a broken-image glyph. Either way it
|
|
167
|
-
* keeps its kind's outline and its
|
|
168
|
-
* says nothing about what they are or what they are doing.
|
|
192
|
+
* keeps its kind's outline, its ring and its status: whether somebody has
|
|
193
|
+
* uploaded a photo says nothing about what they are or what they are doing.
|
|
194
|
+
*
|
|
195
|
+
* A BADGE WITH A STATUS IS FRAMED: the face (character, image or initials)
|
|
196
|
+
* stands in a box of its own size beside the corner badge, and the face has a
|
|
197
|
+
* notch cut where the badge sits, so the badge reads on any ground without
|
|
198
|
+
* knowing what colour that ground is. The frame takes the caller's class and
|
|
199
|
+
* style, which is where a layout reaches for the badge.
|
|
169
200
|
*/
|
|
170
|
-
export declare const Avatar: ({ src, name, size, kind, tone, ring, decorative, colorSeed, character, hue, className, style, ...rest }: AvatarProps) => import("react").JSX.Element;
|
|
201
|
+
export declare const Avatar: ({ src, name, size, kind, tone, ring, status, decorative, colorSeed, character, hue, className, style, ...rest }: AvatarProps) => import("react").JSX.Element;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HTMLAttributes } from 'react';
|
|
2
2
|
import type { CrewletCharacterId } from '@crewlethq/icons/characters';
|
|
3
3
|
import type { NodeHue } from '../utils/nodeHue.js';
|
|
4
|
-
import { type AvatarKind, type
|
|
4
|
+
import { type AvatarKind, type AvatarSizeStep } from './Avatar.js';
|
|
5
5
|
/** One badge in a stack. */
|
|
6
6
|
export interface AvatarStackMember {
|
|
7
7
|
/** Who: the initials, and a word of the stack's accessible name. */
|
|
@@ -9,8 +9,6 @@ export interface AvatarStackMember {
|
|
|
9
9
|
/** An agent (the default) is a squircle; a human is a circle. */
|
|
10
10
|
kind?: AvatarKind | undefined;
|
|
11
11
|
src?: string | undefined;
|
|
12
|
-
/** A state ring on this badge, as `Avatar` draws it. */
|
|
13
|
-
ring?: AvatarRing | undefined;
|
|
14
12
|
/** The Crewlet character an agent member is drawn as, as `Avatar` draws it. */
|
|
15
13
|
character?: CrewletCharacterId | undefined;
|
|
16
14
|
/** The hue an agent member's character is drawn in, as `Avatar` draws it. */
|
package/dist/Avatar/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import './Avatar.css';
|
|
2
2
|
import './AvatarStack.css';
|
|
3
|
-
export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, Avatar, avatarCorner, avatarPixels, avatarTint, getInitials, } from './Avatar.js';
|
|
4
|
-
export type { AvatarKind, AvatarProps, AvatarRing, AvatarSize, AvatarSizeStep, AvatarTone } from './Avatar.js';
|
|
3
|
+
export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, AVATAR_STATUS_LABELS, AVATAR_STATUSES, Avatar, avatarCorner, avatarPixels, avatarTint, getInitials, } from './Avatar.js';
|
|
4
|
+
export type { AvatarKind, AvatarProps, AvatarRing, AvatarSize, AvatarSizeStep, AvatarStatus, AvatarTone, } from './Avatar.js';
|
|
5
5
|
export { AvatarStack, avatarStackLabel } from './AvatarStack.js';
|
|
6
6
|
export type { AvatarStackMember, AvatarStackProps } from './AvatarStack.js';
|
package/dist/Avatar/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { AvatarStack, avatarStackLabel } from '../chunk-
|
|
2
|
-
export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, Avatar, avatarCorner, avatarPixels, avatarTint, getInitials } from '../chunk-
|
|
1
|
+
export { AvatarStack, avatarStackLabel } from '../chunk-3UK4VFSK.js';
|
|
2
|
+
export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, AVATAR_STATUSES, AVATAR_STATUS_LABELS, Avatar, avatarCorner, avatarPixels, avatarTint, getInitials } from '../chunk-HI6Q2UXQ.js';
|
|
3
3
|
import '../chunk-ODEQTPFM.js';
|
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
* OUTLINE (a squircle for an agent, a circle for a person), the monogram and
|
|
11
11
|
* the name, and for an agent an operator gave one, its character and its hue.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* A STATE IS A CORNER BADGE, NEVER A LINE ROUND THE PLATE. A ring in a state's
|
|
14
|
+
* hue round a plate in the agent's own hue put two colours on a 32px mark and
|
|
15
|
+
* framed what the agent was doing louder than who it is. The one ring left is
|
|
16
|
+
* SELECTED, in the accent.
|
|
15
17
|
*
|
|
16
18
|
* The seeded tints stay for the one case that earns them, a roster somebody
|
|
17
19
|
* scans, and their grounds are TOKENS: measured under white initials and held
|
|
@@ -211,11 +213,12 @@
|
|
|
211
213
|
color: var(--color-node-blue);
|
|
212
214
|
}
|
|
213
215
|
|
|
214
|
-
/* ── the
|
|
216
|
+
/* ── the selected ring ────────────────────────────────────────────────── */
|
|
215
217
|
|
|
216
218
|
/*
|
|
217
219
|
* A 1.5px LINE 2px OUTSIDE THE BADGE, which is the design's ring: it draws a
|
|
218
220
|
* 3.5px shadow over a 2px one in the card's colour, and 3.5 less 2 is 1.5.
|
|
221
|
+
* Longhands, so nothing else that sets an outline resets the ring's geometry.
|
|
219
222
|
*
|
|
220
223
|
* AN OUTLINE RATHER THAN THAT SHADOW PAIR, for three reasons. The gap is
|
|
221
224
|
* TRANSPARENT, so the ring reads on whatever the badge stands on, where the
|
|
@@ -223,42 +226,97 @@
|
|
|
223
226
|
* other ground. An outline follows the corner, the squircle's included, in
|
|
224
227
|
* every engine this package supports. And forced-colors mode keeps an outline
|
|
225
228
|
* and drops every shadow, so the ring is still drawn for the readers who most
|
|
226
|
-
* need a boundary
|
|
227
|
-
* state is always said in words beside the badge as well.
|
|
229
|
+
* need a boundary.
|
|
228
230
|
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
* a mark on every opaque surface by @crewlethq/tokens
|
|
232
|
-
* boundary a reader has to see is held to.
|
|
231
|
+
* SELECTED, in the accent, which is what the accent means: where the reader
|
|
232
|
+
* is. It is the only place a badge spends the accent, and the accent is
|
|
233
|
+
* measured at 3:1 as a mark on every opaque surface by @crewlethq/tokens.
|
|
233
234
|
*/
|
|
234
|
-
.crewlet-avatar--ring-info,
|
|
235
|
-
.crewlet-avatar--ring-warning,
|
|
236
|
-
.crewlet-avatar--ring-danger,
|
|
237
|
-
.crewlet-avatar--ring-success,
|
|
238
235
|
.crewlet-avatar--ring-brand {
|
|
239
236
|
outline-style: solid;
|
|
240
237
|
outline-width: 1.5px;
|
|
241
238
|
outline-offset: 2px;
|
|
239
|
+
outline-color: var(--color-brand-accent);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/* ── the status badge ─────────────────────────────────────────────────── */
|
|
243
|
+
|
|
244
|
+
/*
|
|
245
|
+
* THE FRAME is the face's own box, so a badge with a status takes exactly the
|
|
246
|
+
* room one without takes: the corner badge hangs past it rather than growing
|
|
247
|
+
* it, and a row lays out the same either way. The badge is 0.42 of the box,
|
|
248
|
+
* never under 10px, which is the size its glyph stays a shape at.
|
|
249
|
+
*/
|
|
250
|
+
.crewlet-avatar-frame {
|
|
251
|
+
--crewlet-avatar-status-size: max(10px, calc(var(--crewlet-avatar-size) * 0.42));
|
|
252
|
+
--crewlet-avatar-status-overhang: 2px;
|
|
253
|
+
--crewlet-avatar-status-gap: 1.5px;
|
|
254
|
+
position: relative;
|
|
255
|
+
display: inline-flex;
|
|
256
|
+
flex: none;
|
|
257
|
+
width: var(--crewlet-avatar-size);
|
|
258
|
+
height: var(--crewlet-avatar-size);
|
|
259
|
+
vertical-align: middle;
|
|
242
260
|
}
|
|
243
261
|
|
|
244
|
-
|
|
245
|
-
|
|
262
|
+
/*
|
|
263
|
+
* THE NOTCH: the face is masked by a circle a gap wider than the badge, centred
|
|
264
|
+
* where the badge sits, so the gap shows whatever the badge stands on. A ring
|
|
265
|
+
* of the ground's colour would need to know that ground, and a badge on a card,
|
|
266
|
+
* a hovered row and the page would each need a different one. A mask reads only
|
|
267
|
+
* alpha, so its black is opacity rather than a colour.
|
|
268
|
+
*/
|
|
269
|
+
.crewlet-avatar--notched {
|
|
270
|
+
--crewlet-avatar-status-centre: calc(
|
|
271
|
+
100% + var(--crewlet-avatar-status-overhang) - var(--crewlet-avatar-status-size) / 2
|
|
272
|
+
);
|
|
273
|
+
--crewlet-avatar-status-cut: calc(var(--crewlet-avatar-status-size) / 2 + var(--crewlet-avatar-status-gap));
|
|
274
|
+
-webkit-mask-image: radial-gradient(
|
|
275
|
+
circle at var(--crewlet-avatar-status-centre) var(--crewlet-avatar-status-centre),
|
|
276
|
+
transparent var(--crewlet-avatar-status-cut),
|
|
277
|
+
#000 calc(var(--crewlet-avatar-status-cut) + 0.5px)
|
|
278
|
+
);
|
|
279
|
+
mask-image: radial-gradient(
|
|
280
|
+
circle at var(--crewlet-avatar-status-centre) var(--crewlet-avatar-status-centre),
|
|
281
|
+
transparent var(--crewlet-avatar-status-cut),
|
|
282
|
+
#000 calc(var(--crewlet-avatar-status-cut) + 0.5px)
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/*
|
|
287
|
+
* THE BADGE: a state's fill step carrying its glyph in the inverse ink, which
|
|
288
|
+
* the tokens' palette suite holds at 3:1 on each fill (`MARK_ON_FILL`). The
|
|
289
|
+
* transparent outline is drawn only in forced-colors mode, where the fill
|
|
290
|
+
* becomes the page's own colour and the outline is what keeps a boundary.
|
|
291
|
+
*/
|
|
292
|
+
.crewlet-avatar__status {
|
|
293
|
+
position: absolute;
|
|
294
|
+
right: calc(var(--crewlet-avatar-status-overhang) * -1);
|
|
295
|
+
bottom: calc(var(--crewlet-avatar-status-overhang) * -1);
|
|
296
|
+
display: grid;
|
|
297
|
+
place-items: center;
|
|
298
|
+
width: var(--crewlet-avatar-status-size);
|
|
299
|
+
height: var(--crewlet-avatar-status-size);
|
|
300
|
+
border-radius: var(--radius-circle);
|
|
301
|
+
outline: 1px solid transparent;
|
|
302
|
+
color: var(--color-text-inverse);
|
|
303
|
+
pointer-events: none;
|
|
246
304
|
}
|
|
247
305
|
|
|
248
|
-
.crewlet-
|
|
249
|
-
|
|
306
|
+
.crewlet-avatar__status > svg {
|
|
307
|
+
display: block;
|
|
308
|
+
width: 100%;
|
|
309
|
+
height: 100%;
|
|
250
310
|
}
|
|
251
311
|
|
|
252
|
-
.crewlet-
|
|
253
|
-
|
|
312
|
+
.crewlet-avatar__status--working {
|
|
313
|
+
background: var(--color-feedback-info);
|
|
254
314
|
}
|
|
255
315
|
|
|
256
|
-
.crewlet-
|
|
257
|
-
|
|
316
|
+
.crewlet-avatar__status--needs {
|
|
317
|
+
background: var(--color-feedback-warning);
|
|
258
318
|
}
|
|
259
319
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
.crewlet-avatar--ring-brand {
|
|
263
|
-
outline-color: var(--color-brand-accent);
|
|
320
|
+
.crewlet-avatar__status--stopped {
|
|
321
|
+
background: var(--color-feedback-danger);
|
|
264
322
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { CHARACTER_PICKER_COLUMNS, CharacterPicker } from '../chunk-
|
|
1
|
+
export { CHARACTER_PICKER_COLUMNS, CharacterPicker } from '../chunk-UO5UK7V2.js';
|
|
2
2
|
import '../chunk-CBOICT64.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-HI6Q2UXQ.js';
|
|
4
4
|
import '../chunk-ODEQTPFM.js';
|
package/dist/EntityChip/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { EntityChip } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { EntityChip } from '../chunk-DDTDN5L2.js';
|
|
2
|
+
import '../chunk-3UK4VFSK.js';
|
|
3
|
+
import '../chunk-HI6Q2UXQ.js';
|
|
4
4
|
import '../chunk-ODEQTPFM.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ImageUpload } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { ImageUpload } from '../chunk-LAQK4V3Z.js';
|
|
2
|
+
import '../chunk-3UK4VFSK.js';
|
|
3
|
+
import '../chunk-HI6Q2UXQ.js';
|
|
4
4
|
import '../chunk-ODEQTPFM.js';
|
package/dist/OrgLabel/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { OrgLabel } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { OrgLabel } from '../chunk-6OF2DBKY.js';
|
|
2
|
+
import '../chunk-3UK4VFSK.js';
|
|
3
|
+
import '../chunk-HI6Q2UXQ.js';
|
|
4
4
|
import '../chunk-ODEQTPFM.js';
|
package/dist/OrgNode/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { OrgNodeDisclosure, OrgNodeLabel, OrgNodeLead } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
1
|
+
export { OrgNodeDisclosure, OrgNodeLabel, OrgNodeLead } from '../chunk-IHGKPEEV.js';
|
|
2
|
+
import '../chunk-6OF2DBKY.js';
|
|
3
|
+
import '../chunk-3UK4VFSK.js';
|
|
4
|
+
import '../chunk-HI6Q2UXQ.js';
|
|
5
5
|
import '../chunk-ODEQTPFM.js';
|
package/dist/OrgTable/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export { OrgTable, OrgTableActions, OrgTableAdd, OrgTableName } from '../chunk-
|
|
1
|
+
export { OrgTable, OrgTableActions, OrgTableAdd, OrgTableName } from '../chunk-7FFDJQ23.js';
|
|
2
2
|
import '../chunk-SX2DFTQV.js';
|
|
3
3
|
import '../chunk-S3BCVWTU.js';
|
|
4
|
-
import '../chunk-
|
|
4
|
+
import '../chunk-6OF2DBKY.js';
|
|
5
5
|
import '../chunk-53DVJCVW.js';
|
|
6
6
|
import '../chunk-74WGARJE.js';
|
|
7
7
|
import '../chunk-7RPGY3JE.js';
|
|
8
8
|
import '../chunk-R25RGPUB.js';
|
|
9
9
|
import '../chunk-4FQT6ZAY.js';
|
|
10
|
-
import '../chunk-
|
|
11
|
-
import '../chunk-
|
|
10
|
+
import '../chunk-3UK4VFSK.js';
|
|
11
|
+
import '../chunk-HI6Q2UXQ.js';
|
|
12
12
|
import '../chunk-BZFWDIV6.js';
|
|
13
13
|
import '../chunk-ODEQTPFM.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AVATAR_SIZES, Avatar } from './chunk-
|
|
1
|
+
import { AVATAR_SIZES, Avatar } from './chunk-HI6Q2UXQ.js';
|
|
2
2
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
3
|
-
import './Avatar-
|
|
3
|
+
import './Avatar-QHYOFID3.css';
|
|
4
4
|
import './AvatarStack-GEJBNV7E.css';
|
|
5
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
6
|
|
|
@@ -48,7 +48,6 @@ function AvatarStack({
|
|
|
48
48
|
name: member.name,
|
|
49
49
|
kind: member.kind,
|
|
50
50
|
src: member.src,
|
|
51
|
-
ring: member.ring,
|
|
52
51
|
character: member.character,
|
|
53
52
|
hue: member.hue,
|
|
54
53
|
size,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TreeGrid } from './chunk-SX2DFTQV.js';
|
|
2
2
|
import { createTreeModel, treeParent } from './chunk-S3BCVWTU.js';
|
|
3
|
-
import { OrgLabel } from './chunk-
|
|
3
|
+
import { OrgLabel } from './chunk-6OF2DBKY.js';
|
|
4
4
|
import { AddPill } from './chunk-74WGARJE.js';
|
|
5
5
|
import { IconButton } from './chunk-4FQT6ZAY.js';
|
|
6
6
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import { CrewletCharacter } from '@crewlethq/icons/characters';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var AVATAR_STATUSES = ["working", "needs", "stopped"];
|
|
7
|
+
var AVATAR_STATUS_LABELS = {
|
|
8
|
+
working: "working",
|
|
9
|
+
needs: "needs you",
|
|
10
|
+
stopped: "stopped"
|
|
11
|
+
};
|
|
12
|
+
var AVATAR_SIZES = { xs: 20, sm: 26, md: 32, lg: 40 };
|
|
13
|
+
var AVATAR_CORNER_RATIO = 0.29;
|
|
14
|
+
var AVATAR_CHARACTER_FULL_DETAIL = 56;
|
|
15
|
+
var getInitials = (name) => {
|
|
16
|
+
if (!name) return "?";
|
|
17
|
+
const words = name.trim().split(/[\s\-_.]+/).filter(Boolean);
|
|
18
|
+
if (words.length === 0) return "?";
|
|
19
|
+
const first = (word2) => (Array.from(word2)[0] ?? "").toUpperCase();
|
|
20
|
+
if (words.length >= 2) return words.slice(0, 2).map(first).join("") || "?";
|
|
21
|
+
const word = words[0];
|
|
22
|
+
const humps = word.split(/(?<=\p{Ll})(?=\p{Lu})/u);
|
|
23
|
+
if (humps.length >= 2) return humps.slice(0, 2).map(first).join("");
|
|
24
|
+
return Array.from(word).slice(0, 2).map((character) => character.toUpperCase()).join("") || "?";
|
|
25
|
+
};
|
|
26
|
+
var TINT_COUNT = 10;
|
|
27
|
+
var avatarTint = (seed) => {
|
|
28
|
+
let hash = 0;
|
|
29
|
+
for (let i = 0; i < seed.length; i += 1) {
|
|
30
|
+
hash = hash * 31 + seed.charCodeAt(i) >>> 0;
|
|
31
|
+
}
|
|
32
|
+
return hash % TINT_COUNT;
|
|
33
|
+
};
|
|
34
|
+
function avatarPixels(size) {
|
|
35
|
+
return typeof size === "number" ? size : AVATAR_SIZES[size];
|
|
36
|
+
}
|
|
37
|
+
function avatarCorner(pixels) {
|
|
38
|
+
return pixels * AVATAR_CORNER_RATIO;
|
|
39
|
+
}
|
|
40
|
+
var Avatar = ({
|
|
41
|
+
src,
|
|
42
|
+
name,
|
|
43
|
+
size = "md",
|
|
44
|
+
kind = "agent",
|
|
45
|
+
tone = "neutral",
|
|
46
|
+
ring,
|
|
47
|
+
status,
|
|
48
|
+
decorative = false,
|
|
49
|
+
colorSeed,
|
|
50
|
+
character,
|
|
51
|
+
hue,
|
|
52
|
+
className,
|
|
53
|
+
style,
|
|
54
|
+
...rest
|
|
55
|
+
}) => {
|
|
56
|
+
const [imageFailed, setImageFailed] = useState(false);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
setImageFailed(false);
|
|
59
|
+
}, [src]);
|
|
60
|
+
const step = typeof size === "number" ? null : size;
|
|
61
|
+
const pixels = avatarPixels(size);
|
|
62
|
+
const measured = step === null ? {
|
|
63
|
+
"--crewlet-avatar-size": `${pixels}px`,
|
|
64
|
+
fontSize: Math.max(9, Math.round(pixels * 0.36))
|
|
65
|
+
} : {};
|
|
66
|
+
const seeded = tone === "seeded" ? avatarTint(colorSeed ?? name ?? "") : null;
|
|
67
|
+
const framed = status !== void 0;
|
|
68
|
+
const label = name ? `${name} avatar` : "Avatar";
|
|
69
|
+
const spoken = framed ? `${label}, ${AVATAR_STATUS_LABELS[status]}` : label;
|
|
70
|
+
const classes = cx(
|
|
71
|
+
"crewlet-avatar",
|
|
72
|
+
`crewlet-avatar--${kind}`,
|
|
73
|
+
step === null ? null : `crewlet-avatar--${step}`,
|
|
74
|
+
framed ? "crewlet-avatar--notched" : null,
|
|
75
|
+
ring === void 0 || framed ? null : `crewlet-avatar--ring-${ring}`,
|
|
76
|
+
framed ? null : className
|
|
77
|
+
);
|
|
78
|
+
const faceStyle = framed ? measured : { ...measured, ...style };
|
|
79
|
+
function drawFace() {
|
|
80
|
+
if (character !== void 0 && kind === "agent") {
|
|
81
|
+
return /* @__PURE__ */ jsx(
|
|
82
|
+
"span",
|
|
83
|
+
{
|
|
84
|
+
...rest,
|
|
85
|
+
className: cx(
|
|
86
|
+
classes,
|
|
87
|
+
"crewlet-avatar--character",
|
|
88
|
+
hue === void 0 ? "crewlet-avatar--neutral" : `crewlet-avatar--hue-${hue}`
|
|
89
|
+
),
|
|
90
|
+
style: faceStyle,
|
|
91
|
+
role: decorative ? void 0 : "img",
|
|
92
|
+
"aria-hidden": decorative ? true : void 0,
|
|
93
|
+
"aria-label": decorative ? void 0 : spoken,
|
|
94
|
+
children: /* @__PURE__ */ jsx(
|
|
95
|
+
CrewletCharacter,
|
|
96
|
+
{
|
|
97
|
+
className: "crewlet-avatar__character",
|
|
98
|
+
character,
|
|
99
|
+
detail: pixels >= AVATAR_CHARACTER_FULL_DETAIL ? "full" : "compact"
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
if (src && !imageFailed) {
|
|
106
|
+
return /* @__PURE__ */ jsx(
|
|
107
|
+
"img",
|
|
108
|
+
{
|
|
109
|
+
...rest,
|
|
110
|
+
className: cx(classes, "crewlet-avatar--image"),
|
|
111
|
+
style: faceStyle,
|
|
112
|
+
src,
|
|
113
|
+
alt: decorative ? "" : framed ? `${name ?? ""}, ${AVATAR_STATUS_LABELS[status]}` : name ?? "",
|
|
114
|
+
"aria-hidden": decorative ? true : void 0,
|
|
115
|
+
onError: () => setImageFailed(true)
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
return /* @__PURE__ */ jsx(
|
|
120
|
+
"span",
|
|
121
|
+
{
|
|
122
|
+
...rest,
|
|
123
|
+
className: cx(
|
|
124
|
+
classes,
|
|
125
|
+
"crewlet-avatar--fallback",
|
|
126
|
+
`crewlet-avatar--${tone}`,
|
|
127
|
+
seeded === null ? null : `crewlet-avatar--tint-${seeded}`
|
|
128
|
+
),
|
|
129
|
+
style: faceStyle,
|
|
130
|
+
role: decorative ? void 0 : "img",
|
|
131
|
+
"aria-hidden": decorative ? true : void 0,
|
|
132
|
+
"aria-label": decorative ? void 0 : spoken,
|
|
133
|
+
children: getInitials(name)
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
const face = drawFace();
|
|
138
|
+
if (!framed) return face;
|
|
139
|
+
return /* @__PURE__ */ jsxs(
|
|
140
|
+
"span",
|
|
141
|
+
{
|
|
142
|
+
className: cx("crewlet-avatar-frame", className),
|
|
143
|
+
style: { "--crewlet-avatar-size": `${pixels}px`, ...style },
|
|
144
|
+
children: [
|
|
145
|
+
face,
|
|
146
|
+
/* @__PURE__ */ jsx("span", { className: `crewlet-avatar__status crewlet-avatar__status--${status}`, "aria-hidden": "true", children: STATUS_GLYPHS[status] })
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
};
|
|
151
|
+
var STATUS_GLYPHS = {
|
|
152
|
+
working: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 14 14", focusable: "false", children: /* @__PURE__ */ jsx("path", { d: "M5.4 3.9 10.2 7l-4.8 3.1z", fill: "currentColor" }) }),
|
|
153
|
+
needs: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 14 14", focusable: "false", children: [
|
|
154
|
+
/* @__PURE__ */ jsx(
|
|
155
|
+
"path",
|
|
156
|
+
{
|
|
157
|
+
d: "M5.1 5.3a1.9 1.9 0 1 1 2.7 1.7c-.55.27-.8.62-.8 1.15v.3",
|
|
158
|
+
fill: "none",
|
|
159
|
+
stroke: "currentColor",
|
|
160
|
+
strokeWidth: "1.5",
|
|
161
|
+
strokeLinecap: "round"
|
|
162
|
+
}
|
|
163
|
+
),
|
|
164
|
+
/* @__PURE__ */ jsx("circle", { cx: "7", cy: "10.45", r: ".85", fill: "currentColor" })
|
|
165
|
+
] }),
|
|
166
|
+
stopped: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 14 14", focusable: "false", children: /* @__PURE__ */ jsx("rect", { x: "4.6", y: "4.6", width: "4.8", height: "4.8", rx: ".7", fill: "currentColor" }) })
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, AVATAR_STATUSES, AVATAR_STATUS_LABELS, Avatar, avatarCorner, avatarPixels, avatarTint, getInitials };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useRoving, tabStop } from './chunk-CBOICT64.js';
|
|
2
|
-
import { Avatar } from './chunk-
|
|
2
|
+
import { Avatar } from './chunk-HI6Q2UXQ.js';
|
|
3
3
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
4
4
|
import './CharacterPicker-ZEYIKUNQ.css';
|
|
5
5
|
import { CREWLET_CHARACTERS, CREWLET_CHARACTER_GEOMETRY } from '@crewlethq/icons/characters';
|
package/dist/generated/index.js
CHANGED
|
@@ -26,11 +26,11 @@ export { SegmentedMeter, segmentedMeterLabel } from '../chunk-4AK52VHB.js';
|
|
|
26
26
|
export { Select } from '../chunk-SEFMO2EV.js';
|
|
27
27
|
export { matchesShortcut, useShortcut } from '../chunk-2FPENTCF.js';
|
|
28
28
|
export { NewItemsNotice } from '../chunk-PXU6HOZB.js';
|
|
29
|
-
export { OrgNodeDisclosure, OrgNodeLabel, OrgNodeLead } from '../chunk-
|
|
30
|
-
export { OrgTable, OrgTableActions, OrgTableAdd, OrgTableName } from '../chunk-
|
|
29
|
+
export { OrgNodeDisclosure, OrgNodeLabel, OrgNodeLead } from '../chunk-IHGKPEEV.js';
|
|
30
|
+
export { OrgTable, OrgTableActions, OrgTableAdd, OrgTableName } from '../chunk-7FFDJQ23.js';
|
|
31
31
|
export { TreeGrid } from '../chunk-SX2DFTQV.js';
|
|
32
32
|
export { SIZE_EPSILON, TYPE_AHEAD_RESET_MS, createTreeModel, isTypeAheadKey, layoutConnectors, layoutForest, placeGroups, treeAllExpandable, treeAncestors, treeCollapseOrAscend, treeExpandOrDescend, treeExpandTo, treeExpandable, treeFirst, treeFirstChild, treeItemAction, treeLast, treeLevel, treeNext, treeParent, treePosInSet, treePrevious, treeSetSize, treeStep, treeTypeAhead, treeVisible, typeAheadBuffer, useLayoutAnchor, useMeasuredSizes, useTreeState } from '../chunk-S3BCVWTU.js';
|
|
33
|
-
export { OrgLabel } from '../chunk-
|
|
33
|
+
export { OrgLabel } from '../chunk-6OF2DBKY.js';
|
|
34
34
|
export { PricingCard } from '../chunk-UCYIRDND.js';
|
|
35
35
|
export { Tag } from '../chunk-LOECRMHA.js';
|
|
36
36
|
export { StatusDot } from '../chunk-WIATRXEJ.js';
|
|
@@ -45,13 +45,13 @@ export { HuePicker } from '../chunk-26TXVHN2.js';
|
|
|
45
45
|
export { NODE_HUES, NODE_HUE_NAMES, isNodeHue } from '../chunk-AYKXMIOR.js';
|
|
46
46
|
export { SegmentedControl } from '../chunk-LPHHDCN3.js';
|
|
47
47
|
export { TabPanel, Tabs, tabId } from '../chunk-HEOVQZL7.js';
|
|
48
|
+
export { ImageUpload } from '../chunk-LAQK4V3Z.js';
|
|
48
49
|
export { InlineCode } from '../chunk-NN62JQLR.js';
|
|
49
|
-
export { ImageUpload } from '../chunk-E3HDS4F7.js';
|
|
50
50
|
export { DescriptionList, DescriptionListItem } from '../chunk-XN4JBAN3.js';
|
|
51
51
|
export { DIFF_LIST_LABELS, DiffList } from '../chunk-LFHCXZO5.js';
|
|
52
52
|
export { Disclosure } from '../chunk-MICH6QSJ.js';
|
|
53
53
|
export { EmptyState } from '../chunk-RA2ULG6H.js';
|
|
54
|
-
export { EntityChip } from '../chunk-
|
|
54
|
+
export { EntityChip } from '../chunk-DDTDN5L2.js';
|
|
55
55
|
export { ErrorBoundary } from '../chunk-XX2VQE55.js';
|
|
56
56
|
export { Eyebrow } from '../chunk-RK4XPHVG.js';
|
|
57
57
|
export { Combobox } from '../chunk-UYK72NOS.js';
|
|
@@ -76,7 +76,7 @@ export { CANVAS_COMPOSE_CONTEXT, CANVAS_FIT_MAX_ZOOM, CANVAS_FIT_PADDING, CANVAS
|
|
|
76
76
|
import '../chunk-53DVJCVW.js';
|
|
77
77
|
export { Card } from '../chunk-CEOXFO3E.js';
|
|
78
78
|
export { useCardHeaderSlot } from '../chunk-AV2DXAEL.js';
|
|
79
|
-
export { CHARACTER_PICKER_COLUMNS, CharacterPicker } from '../chunk-
|
|
79
|
+
export { CHARACTER_PICKER_COLUMNS, CharacterPicker } from '../chunk-UO5UK7V2.js';
|
|
80
80
|
import '../chunk-CBOICT64.js';
|
|
81
81
|
export { ActivityStrip, BarList, ChartTooltip, DATA_COLORS, DATA_COLOR_OTHER, Legend, Sparkline, StackedBar, StackedColumns, TimeSeries, dataColor, niceScale, useChartHover } from '../chunk-4WNNEDKO.js';
|
|
82
82
|
export { Checkbox } from '../chunk-YCTMKKRA.js';
|
|
@@ -93,8 +93,8 @@ export { AppShell, AppShellRail, AppShellRailRow, AppShellToggle, AppShellTopbar
|
|
|
93
93
|
export { LAYER_GAP, LAYER_REPOSITION_EVENT, LayerHost, outsideBounds, placePopup, useLayerContainer, viewportBounds } from '../chunk-7RPGY3JE.js';
|
|
94
94
|
export { focusables, isComposing, isModalLayerOpen, layerCount, useBodyScrollLock, useModalLayer, usePopupLayer } from '../chunk-R25RGPUB.js';
|
|
95
95
|
export { IconButton } from '../chunk-4FQT6ZAY.js';
|
|
96
|
-
export { AvatarStack, avatarStackLabel } from '../chunk-
|
|
97
|
-
export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, Avatar, avatarCorner, avatarPixels, avatarTint, getInitials } from '../chunk-
|
|
96
|
+
export { AvatarStack, avatarStackLabel } from '../chunk-3UK4VFSK.js';
|
|
97
|
+
export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, AVATAR_STATUSES, AVATAR_STATUS_LABELS, Avatar, avatarCorner, avatarPixels, avatarTint, getInitials } from '../chunk-HI6Q2UXQ.js';
|
|
98
98
|
export { BrandLockup } from '../chunk-7KBNFFM3.js';
|
|
99
99
|
export { Button, ButtonLink } from '../chunk-OG6CL3EB.js';
|
|
100
100
|
export { VisuallyHidden } from '../chunk-BZFWDIV6.js';
|
package/dist/index.js
CHANGED
|
@@ -26,11 +26,11 @@ export { SegmentedMeter, segmentedMeterLabel } from './chunk-4AK52VHB.js';
|
|
|
26
26
|
export { Select } from './chunk-SEFMO2EV.js';
|
|
27
27
|
export { matchesShortcut, useShortcut } from './chunk-2FPENTCF.js';
|
|
28
28
|
export { NewItemsNotice } from './chunk-PXU6HOZB.js';
|
|
29
|
-
export { OrgNodeDisclosure, OrgNodeLabel, OrgNodeLead } from './chunk-
|
|
30
|
-
export { OrgTable, OrgTableActions, OrgTableAdd, OrgTableName } from './chunk-
|
|
29
|
+
export { OrgNodeDisclosure, OrgNodeLabel, OrgNodeLead } from './chunk-IHGKPEEV.js';
|
|
30
|
+
export { OrgTable, OrgTableActions, OrgTableAdd, OrgTableName } from './chunk-7FFDJQ23.js';
|
|
31
31
|
export { TreeGrid } from './chunk-SX2DFTQV.js';
|
|
32
32
|
export { SIZE_EPSILON, TYPE_AHEAD_RESET_MS, createTreeModel, isTypeAheadKey, layoutConnectors, layoutForest, placeGroups, treeAllExpandable, treeAncestors, treeCollapseOrAscend, treeExpandOrDescend, treeExpandTo, treeExpandable, treeFirst, treeFirstChild, treeItemAction, treeLast, treeLevel, treeNext, treeParent, treePosInSet, treePrevious, treeSetSize, treeStep, treeTypeAhead, treeVisible, typeAheadBuffer, useLayoutAnchor, useMeasuredSizes, useTreeState } from './chunk-S3BCVWTU.js';
|
|
33
|
-
export { OrgLabel } from './chunk-
|
|
33
|
+
export { OrgLabel } from './chunk-6OF2DBKY.js';
|
|
34
34
|
export { PricingCard } from './chunk-UCYIRDND.js';
|
|
35
35
|
export { Tag } from './chunk-LOECRMHA.js';
|
|
36
36
|
export { StatusDot } from './chunk-WIATRXEJ.js';
|
|
@@ -45,13 +45,13 @@ export { HuePicker } from './chunk-26TXVHN2.js';
|
|
|
45
45
|
export { NODE_HUES, NODE_HUE_NAMES, isNodeHue } from './chunk-AYKXMIOR.js';
|
|
46
46
|
export { SegmentedControl } from './chunk-LPHHDCN3.js';
|
|
47
47
|
export { TabPanel, Tabs, tabId } from './chunk-HEOVQZL7.js';
|
|
48
|
+
export { ImageUpload } from './chunk-LAQK4V3Z.js';
|
|
48
49
|
export { InlineCode } from './chunk-NN62JQLR.js';
|
|
49
|
-
export { ImageUpload } from './chunk-E3HDS4F7.js';
|
|
50
50
|
export { DescriptionList, DescriptionListItem } from './chunk-XN4JBAN3.js';
|
|
51
51
|
export { DIFF_LIST_LABELS, DiffList } from './chunk-LFHCXZO5.js';
|
|
52
52
|
export { Disclosure } from './chunk-MICH6QSJ.js';
|
|
53
53
|
export { EmptyState } from './chunk-RA2ULG6H.js';
|
|
54
|
-
export { EntityChip } from './chunk-
|
|
54
|
+
export { EntityChip } from './chunk-DDTDN5L2.js';
|
|
55
55
|
export { ErrorBoundary } from './chunk-XX2VQE55.js';
|
|
56
56
|
export { Eyebrow } from './chunk-RK4XPHVG.js';
|
|
57
57
|
export { Combobox } from './chunk-UYK72NOS.js';
|
|
@@ -76,7 +76,7 @@ export { CANVAS_COMPOSE_CONTEXT, CANVAS_FIT_MAX_ZOOM, CANVAS_FIT_PADDING, CANVAS
|
|
|
76
76
|
import './chunk-53DVJCVW.js';
|
|
77
77
|
export { Card } from './chunk-CEOXFO3E.js';
|
|
78
78
|
export { useCardHeaderSlot } from './chunk-AV2DXAEL.js';
|
|
79
|
-
export { CHARACTER_PICKER_COLUMNS, CharacterPicker } from './chunk-
|
|
79
|
+
export { CHARACTER_PICKER_COLUMNS, CharacterPicker } from './chunk-UO5UK7V2.js';
|
|
80
80
|
import './chunk-CBOICT64.js';
|
|
81
81
|
export { ActivityStrip, BarList, ChartTooltip, DATA_COLORS, DATA_COLOR_OTHER, Legend, Sparkline, StackedBar, StackedColumns, TimeSeries, dataColor, niceScale, useChartHover } from './chunk-4WNNEDKO.js';
|
|
82
82
|
export { Checkbox } from './chunk-YCTMKKRA.js';
|
|
@@ -93,8 +93,8 @@ export { AppShell, AppShellRail, AppShellRailRow, AppShellToggle, AppShellTopbar
|
|
|
93
93
|
export { LAYER_GAP, LAYER_REPOSITION_EVENT, LayerHost, outsideBounds, placePopup, useLayerContainer, viewportBounds } from './chunk-7RPGY3JE.js';
|
|
94
94
|
export { focusables, isComposing, isModalLayerOpen, layerCount, useBodyScrollLock, useModalLayer, usePopupLayer } from './chunk-R25RGPUB.js';
|
|
95
95
|
export { IconButton } from './chunk-4FQT6ZAY.js';
|
|
96
|
-
export { AvatarStack, avatarStackLabel } from './chunk-
|
|
97
|
-
export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, Avatar, avatarCorner, avatarPixels, avatarTint, getInitials } from './chunk-
|
|
96
|
+
export { AvatarStack, avatarStackLabel } from './chunk-3UK4VFSK.js';
|
|
97
|
+
export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, AVATAR_STATUSES, AVATAR_STATUS_LABELS, Avatar, avatarCorner, avatarPixels, avatarTint, getInitials } from './chunk-HI6Q2UXQ.js';
|
|
98
98
|
export { BrandLockup } from './chunk-7KBNFFM3.js';
|
|
99
99
|
export { Button, ButtonLink } from './chunk-OG6CL3EB.js';
|
|
100
100
|
export { VisuallyHidden } from './chunk-BZFWDIV6.js';
|
package/dist/styles.css
CHANGED
|
@@ -1088,7 +1088,7 @@
|
|
|
1088
1088
|
}
|
|
1089
1089
|
|
|
1090
1090
|
|
|
1091
|
-
/* Avatar-
|
|
1091
|
+
/* Avatar-QHYOFID3.css */
|
|
1092
1092
|
/*
|
|
1093
1093
|
* The identity badge.
|
|
1094
1094
|
*
|
|
@@ -1101,8 +1101,10 @@
|
|
|
1101
1101
|
* OUTLINE (a squircle for an agent, a circle for a person), the monogram and
|
|
1102
1102
|
* the name, and for an agent an operator gave one, its character and its hue.
|
|
1103
1103
|
*
|
|
1104
|
-
*
|
|
1105
|
-
*
|
|
1104
|
+
* A STATE IS A CORNER BADGE, NEVER A LINE ROUND THE PLATE. A ring in a state's
|
|
1105
|
+
* hue round a plate in the agent's own hue put two colours on a 32px mark and
|
|
1106
|
+
* framed what the agent was doing louder than who it is. The one ring left is
|
|
1107
|
+
* SELECTED, in the accent.
|
|
1106
1108
|
*
|
|
1107
1109
|
* The seeded tints stay for the one case that earns them, a roster somebody
|
|
1108
1110
|
* scans, and their grounds are TOKENS: measured under white initials and held
|
|
@@ -1302,11 +1304,12 @@
|
|
|
1302
1304
|
color: var(--color-node-blue);
|
|
1303
1305
|
}
|
|
1304
1306
|
|
|
1305
|
-
/* ── the
|
|
1307
|
+
/* ── the selected ring ────────────────────────────────────────────────── */
|
|
1306
1308
|
|
|
1307
1309
|
/*
|
|
1308
1310
|
* A 1.5px LINE 2px OUTSIDE THE BADGE, which is the design's ring: it draws a
|
|
1309
1311
|
* 3.5px shadow over a 2px one in the card's colour, and 3.5 less 2 is 1.5.
|
|
1312
|
+
* Longhands, so nothing else that sets an outline resets the ring's geometry.
|
|
1310
1313
|
*
|
|
1311
1314
|
* AN OUTLINE RATHER THAN THAT SHADOW PAIR, for three reasons. The gap is
|
|
1312
1315
|
* TRANSPARENT, so the ring reads on whatever the badge stands on, where the
|
|
@@ -1314,44 +1317,99 @@
|
|
|
1314
1317
|
* other ground. An outline follows the corner, the squircle's included, in
|
|
1315
1318
|
* every engine this package supports. And forced-colors mode keeps an outline
|
|
1316
1319
|
* and drops every shadow, so the ring is still drawn for the readers who most
|
|
1317
|
-
* need a boundary
|
|
1318
|
-
*
|
|
1319
|
-
*
|
|
1320
|
-
*
|
|
1321
|
-
*
|
|
1322
|
-
|
|
1323
|
-
* boundary a reader has to see is held to.
|
|
1324
|
-
*/
|
|
1325
|
-
.crewlet-avatar--ring-info,
|
|
1326
|
-
.crewlet-avatar--ring-warning,
|
|
1327
|
-
.crewlet-avatar--ring-danger,
|
|
1328
|
-
.crewlet-avatar--ring-success,
|
|
1320
|
+
* need a boundary.
|
|
1321
|
+
*
|
|
1322
|
+
* SELECTED, in the accent, which is what the accent means: where the reader
|
|
1323
|
+
* is. It is the only place a badge spends the accent, and the accent is
|
|
1324
|
+
* measured at 3:1 as a mark on every opaque surface by @crewlethq/tokens.
|
|
1325
|
+
*/
|
|
1329
1326
|
.crewlet-avatar--ring-brand {
|
|
1330
1327
|
outline-style: solid;
|
|
1331
1328
|
outline-width: 1.5px;
|
|
1332
1329
|
outline-offset: 2px;
|
|
1330
|
+
outline-color: var(--color-brand-accent);
|
|
1333
1331
|
}
|
|
1334
1332
|
|
|
1335
|
-
|
|
1336
|
-
|
|
1333
|
+
/* ── the status badge ─────────────────────────────────────────────────── */
|
|
1334
|
+
|
|
1335
|
+
/*
|
|
1336
|
+
* THE FRAME is the face's own box, so a badge with a status takes exactly the
|
|
1337
|
+
* room one without takes: the corner badge hangs past it rather than growing
|
|
1338
|
+
* it, and a row lays out the same either way. The badge is 0.42 of the box,
|
|
1339
|
+
* never under 10px, which is the size its glyph stays a shape at.
|
|
1340
|
+
*/
|
|
1341
|
+
.crewlet-avatar-frame {
|
|
1342
|
+
--crewlet-avatar-status-size: max(10px, calc(var(--crewlet-avatar-size) * 0.42));
|
|
1343
|
+
--crewlet-avatar-status-overhang: 2px;
|
|
1344
|
+
--crewlet-avatar-status-gap: 1.5px;
|
|
1345
|
+
position: relative;
|
|
1346
|
+
display: inline-flex;
|
|
1347
|
+
flex: none;
|
|
1348
|
+
width: var(--crewlet-avatar-size);
|
|
1349
|
+
height: var(--crewlet-avatar-size);
|
|
1350
|
+
vertical-align: middle;
|
|
1337
1351
|
}
|
|
1338
1352
|
|
|
1339
|
-
|
|
1340
|
-
|
|
1353
|
+
/*
|
|
1354
|
+
* THE NOTCH: the face is masked by a circle a gap wider than the badge, centred
|
|
1355
|
+
* where the badge sits, so the gap shows whatever the badge stands on. A ring
|
|
1356
|
+
* of the ground's colour would need to know that ground, and a badge on a card,
|
|
1357
|
+
* a hovered row and the page would each need a different one. A mask reads only
|
|
1358
|
+
* alpha, so its black is opacity rather than a colour.
|
|
1359
|
+
*/
|
|
1360
|
+
.crewlet-avatar--notched {
|
|
1361
|
+
--crewlet-avatar-status-centre: calc(
|
|
1362
|
+
100% + var(--crewlet-avatar-status-overhang) - var(--crewlet-avatar-status-size) / 2
|
|
1363
|
+
);
|
|
1364
|
+
--crewlet-avatar-status-cut: calc(var(--crewlet-avatar-status-size) / 2 + var(--crewlet-avatar-status-gap));
|
|
1365
|
+
-webkit-mask-image: radial-gradient(
|
|
1366
|
+
circle at var(--crewlet-avatar-status-centre) var(--crewlet-avatar-status-centre),
|
|
1367
|
+
transparent var(--crewlet-avatar-status-cut),
|
|
1368
|
+
#000 calc(var(--crewlet-avatar-status-cut) + 0.5px)
|
|
1369
|
+
);
|
|
1370
|
+
mask-image: radial-gradient(
|
|
1371
|
+
circle at var(--crewlet-avatar-status-centre) var(--crewlet-avatar-status-centre),
|
|
1372
|
+
transparent var(--crewlet-avatar-status-cut),
|
|
1373
|
+
#000 calc(var(--crewlet-avatar-status-cut) + 0.5px)
|
|
1374
|
+
);
|
|
1341
1375
|
}
|
|
1342
1376
|
|
|
1343
|
-
|
|
1344
|
-
|
|
1377
|
+
/*
|
|
1378
|
+
* THE BADGE: a state's fill step carrying its glyph in the inverse ink, which
|
|
1379
|
+
* the tokens' palette suite holds at 3:1 on each fill (`MARK_ON_FILL`). The
|
|
1380
|
+
* transparent outline is drawn only in forced-colors mode, where the fill
|
|
1381
|
+
* becomes the page's own colour and the outline is what keeps a boundary.
|
|
1382
|
+
*/
|
|
1383
|
+
.crewlet-avatar__status {
|
|
1384
|
+
position: absolute;
|
|
1385
|
+
right: calc(var(--crewlet-avatar-status-overhang) * -1);
|
|
1386
|
+
bottom: calc(var(--crewlet-avatar-status-overhang) * -1);
|
|
1387
|
+
display: grid;
|
|
1388
|
+
place-items: center;
|
|
1389
|
+
width: var(--crewlet-avatar-status-size);
|
|
1390
|
+
height: var(--crewlet-avatar-status-size);
|
|
1391
|
+
border-radius: var(--radius-circle);
|
|
1392
|
+
outline: 1px solid transparent;
|
|
1393
|
+
color: var(--color-text-inverse);
|
|
1394
|
+
pointer-events: none;
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
.crewlet-avatar__status > svg {
|
|
1398
|
+
display: block;
|
|
1399
|
+
width: 100%;
|
|
1400
|
+
height: 100%;
|
|
1345
1401
|
}
|
|
1346
1402
|
|
|
1347
|
-
.crewlet-
|
|
1348
|
-
|
|
1403
|
+
.crewlet-avatar__status--working {
|
|
1404
|
+
background: var(--color-feedback-info);
|
|
1349
1405
|
}
|
|
1350
1406
|
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1407
|
+
.crewlet-avatar__status--needs {
|
|
1408
|
+
background: var(--color-feedback-warning);
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
.crewlet-avatar__status--stopped {
|
|
1412
|
+
background: var(--color-feedback-danger);
|
|
1355
1413
|
}
|
|
1356
1414
|
|
|
1357
1415
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crewlethq/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Crewlet shared React components built on @crewlethq/tokens and @crewlethq/icons.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"clean": "rm -rf dist src/generated"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@crewlethq/icons": "0.
|
|
46
|
-
"@crewlethq/tokens": "0.
|
|
45
|
+
"@crewlethq/icons": "0.10.0",
|
|
46
|
+
"@crewlethq/tokens": "0.10.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"react": ">=18",
|
package/dist/chunk-UDW3DAP5.js
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { cx } from './chunk-ODEQTPFM.js';
|
|
2
|
-
import { useState, useEffect } from 'react';
|
|
3
|
-
import { CrewletCharacter } from '@crewlethq/icons/characters';
|
|
4
|
-
import { jsx } from 'react/jsx-runtime';
|
|
5
|
-
|
|
6
|
-
var AVATAR_SIZES = { xs: 20, sm: 26, md: 32, lg: 40 };
|
|
7
|
-
var AVATAR_CORNER_RATIO = 0.29;
|
|
8
|
-
var AVATAR_CHARACTER_FULL_DETAIL = 56;
|
|
9
|
-
var getInitials = (name) => {
|
|
10
|
-
if (!name) return "?";
|
|
11
|
-
const words = name.trim().split(/[\s\-_.]+/).filter(Boolean);
|
|
12
|
-
if (words.length === 0) return "?";
|
|
13
|
-
const first = (word2) => (Array.from(word2)[0] ?? "").toUpperCase();
|
|
14
|
-
if (words.length >= 2) return words.slice(0, 2).map(first).join("") || "?";
|
|
15
|
-
const word = words[0];
|
|
16
|
-
const humps = word.split(/(?<=\p{Ll})(?=\p{Lu})/u);
|
|
17
|
-
if (humps.length >= 2) return humps.slice(0, 2).map(first).join("");
|
|
18
|
-
return Array.from(word).slice(0, 2).map((character) => character.toUpperCase()).join("") || "?";
|
|
19
|
-
};
|
|
20
|
-
var TINT_COUNT = 10;
|
|
21
|
-
var avatarTint = (seed) => {
|
|
22
|
-
let hash = 0;
|
|
23
|
-
for (let i = 0; i < seed.length; i += 1) {
|
|
24
|
-
hash = hash * 31 + seed.charCodeAt(i) >>> 0;
|
|
25
|
-
}
|
|
26
|
-
return hash % TINT_COUNT;
|
|
27
|
-
};
|
|
28
|
-
function avatarPixels(size) {
|
|
29
|
-
return typeof size === "number" ? size : AVATAR_SIZES[size];
|
|
30
|
-
}
|
|
31
|
-
function avatarCorner(pixels) {
|
|
32
|
-
return pixels * AVATAR_CORNER_RATIO;
|
|
33
|
-
}
|
|
34
|
-
var Avatar = ({
|
|
35
|
-
src,
|
|
36
|
-
name,
|
|
37
|
-
size = "md",
|
|
38
|
-
kind = "agent",
|
|
39
|
-
tone = "neutral",
|
|
40
|
-
ring,
|
|
41
|
-
decorative = false,
|
|
42
|
-
colorSeed,
|
|
43
|
-
character,
|
|
44
|
-
hue,
|
|
45
|
-
className,
|
|
46
|
-
style,
|
|
47
|
-
...rest
|
|
48
|
-
}) => {
|
|
49
|
-
const [imageFailed, setImageFailed] = useState(false);
|
|
50
|
-
useEffect(() => {
|
|
51
|
-
setImageFailed(false);
|
|
52
|
-
}, [src]);
|
|
53
|
-
const step = typeof size === "number" ? null : size;
|
|
54
|
-
const pixels = avatarPixels(size);
|
|
55
|
-
const measured = step === null ? {
|
|
56
|
-
"--crewlet-avatar-size": `${pixels}px`,
|
|
57
|
-
fontSize: Math.max(9, Math.round(pixels * 0.36))
|
|
58
|
-
} : {};
|
|
59
|
-
const seeded = tone === "seeded" ? avatarTint(colorSeed ?? name ?? "") : null;
|
|
60
|
-
const classes = cx(
|
|
61
|
-
"crewlet-avatar",
|
|
62
|
-
`crewlet-avatar--${kind}`,
|
|
63
|
-
step === null ? null : `crewlet-avatar--${step}`,
|
|
64
|
-
ring === void 0 ? null : `crewlet-avatar--ring-${ring}`,
|
|
65
|
-
className
|
|
66
|
-
);
|
|
67
|
-
if (character !== void 0 && kind === "agent") {
|
|
68
|
-
return /* @__PURE__ */ jsx(
|
|
69
|
-
"span",
|
|
70
|
-
{
|
|
71
|
-
...rest,
|
|
72
|
-
className: cx(
|
|
73
|
-
classes,
|
|
74
|
-
"crewlet-avatar--character",
|
|
75
|
-
hue === void 0 ? "crewlet-avatar--neutral" : `crewlet-avatar--hue-${hue}`
|
|
76
|
-
),
|
|
77
|
-
style: { ...measured, ...style },
|
|
78
|
-
role: decorative ? void 0 : "img",
|
|
79
|
-
"aria-hidden": decorative ? true : void 0,
|
|
80
|
-
"aria-label": decorative ? void 0 : name ? `${name} avatar` : "Avatar",
|
|
81
|
-
children: /* @__PURE__ */ jsx(
|
|
82
|
-
CrewletCharacter,
|
|
83
|
-
{
|
|
84
|
-
className: "crewlet-avatar__character",
|
|
85
|
-
character,
|
|
86
|
-
detail: pixels >= AVATAR_CHARACTER_FULL_DETAIL ? "full" : "compact"
|
|
87
|
-
}
|
|
88
|
-
)
|
|
89
|
-
}
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
if (src && !imageFailed) {
|
|
93
|
-
return /* @__PURE__ */ jsx(
|
|
94
|
-
"img",
|
|
95
|
-
{
|
|
96
|
-
...rest,
|
|
97
|
-
className: cx(classes, "crewlet-avatar--image"),
|
|
98
|
-
style: { ...measured, ...style },
|
|
99
|
-
src,
|
|
100
|
-
alt: decorative ? "" : name ?? "",
|
|
101
|
-
"aria-hidden": decorative ? true : void 0,
|
|
102
|
-
onError: () => setImageFailed(true)
|
|
103
|
-
}
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
return /* @__PURE__ */ jsx(
|
|
107
|
-
"span",
|
|
108
|
-
{
|
|
109
|
-
...rest,
|
|
110
|
-
className: cx(
|
|
111
|
-
classes,
|
|
112
|
-
"crewlet-avatar--fallback",
|
|
113
|
-
`crewlet-avatar--${tone}`,
|
|
114
|
-
seeded === null ? null : `crewlet-avatar--tint-${seeded}`
|
|
115
|
-
),
|
|
116
|
-
style: { ...measured, ...style },
|
|
117
|
-
role: decorative ? void 0 : "img",
|
|
118
|
-
"aria-hidden": decorative ? true : void 0,
|
|
119
|
-
"aria-label": decorative ? void 0 : name ? `${name} avatar` : "Avatar",
|
|
120
|
-
children: getInitials(name)
|
|
121
|
-
}
|
|
122
|
-
);
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
export { AVATAR_CHARACTER_FULL_DETAIL, AVATAR_CORNER_RATIO, AVATAR_SIZES, Avatar, avatarCorner, avatarPixels, avatarTint, getInitials };
|