@dxos/react-ui-card 0.8.2-staging.7ac8446 → 0.11.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 +102 -5
- package/dist/lib/index.mjs +288 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/translations.mjs +11 -0
- package/dist/lib/translations.mjs.map +1 -0
- package/dist/types/src/components/Avatar/Avatar.d.ts +14 -0
- package/dist/types/src/components/Avatar/Avatar.d.ts.map +1 -0
- package/dist/types/src/components/Avatar/Avatar.stories.d.ts +15 -0
- package/dist/types/src/components/Avatar/Avatar.stories.d.ts.map +1 -0
- package/dist/types/src/components/Avatar/avatar-name.d.ts +6 -0
- package/dist/types/src/components/Avatar/avatar-name.d.ts.map +1 -0
- package/dist/types/src/components/Avatar/index.d.ts +3 -0
- package/dist/types/src/components/Avatar/index.d.ts.map +1 -0
- package/dist/types/src/components/CardTile/CardTile.d.ts +46 -0
- package/dist/types/src/components/CardTile/CardTile.d.ts.map +1 -0
- package/dist/types/src/components/CardTile/CardTile.stories.d.ts +27 -0
- package/dist/types/src/components/CardTile/CardTile.stories.d.ts.map +1 -0
- package/dist/types/src/components/CardTile/index.d.ts +2 -0
- package/dist/types/src/components/CardTile/index.d.ts.map +1 -0
- package/dist/types/src/components/Row/Row.d.ts +100 -0
- package/dist/types/src/components/Row/Row.d.ts.map +1 -0
- package/dist/types/src/components/Row/Row.stories.d.ts +23 -0
- package/dist/types/src/components/Row/Row.stories.d.ts.map +1 -0
- package/dist/types/src/components/Row/index.d.ts +2 -0
- package/dist/types/src/components/Row/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +3 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useActorContact.d.ts +5 -0
- package/dist/types/src/hooks/useActorContact.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +2 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +11 -0
- package/dist/types/src/translations.d.ts.map +1 -0
- package/dist/types/src/util.d.ts +3 -0
- package/dist/types/src/util.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +39 -29
- package/src/components/Avatar/Avatar.stories.tsx +31 -0
- package/src/components/Avatar/Avatar.tsx +39 -0
- package/src/components/Avatar/avatar-name.ts +19 -0
- package/src/components/Avatar/index.ts +7 -0
- package/src/components/CardTile/CardTile.stories.tsx +54 -0
- package/src/components/CardTile/CardTile.tsx +103 -0
- package/src/components/CardTile/index.ts +5 -0
- package/src/components/Row/Row.stories.tsx +65 -0
- package/src/components/Row/Row.tsx +379 -0
- package/src/components/Row/index.ts +5 -0
- package/src/components/index.ts +4 -2
- package/src/hooks/index.ts +5 -0
- package/src/hooks/useActorContact.ts +31 -0
- package/src/index.ts +3 -2
- package/src/translations.ts +19 -0
- package/src/util.ts +7 -0
- package/README.md +0 -3
- package/dist/lib/browser/index.mjs +0 -159
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/node/index.cjs +0 -202
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node-esm/index.mjs +0 -161
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/types/src/components/Card.d.ts +0 -52
- package/dist/types/src/components/Card.d.ts.map +0 -1
- package/dist/types/src/components/Card.stories.d.ts +0 -57
- package/dist/types/src/components/Card.stories.d.ts.map +0 -1
- package/dist/types/src/theme.d.ts +0 -31
- package/dist/types/src/theme.d.ts.map +0 -1
- package/src/components/Card.stories.tsx +0 -217
- package/src/components/Card.tsx +0 -149
- package/src/theme.ts +0 -101
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { format, intervalToDuration } from 'date-fns';
|
|
6
|
+
import React, { type MouseEvent, useCallback, useRef } from 'react';
|
|
7
|
+
|
|
8
|
+
import { type Database, Obj } from '@dxos/echo';
|
|
9
|
+
import { EID, type URI } from '@dxos/keys';
|
|
10
|
+
import {
|
|
11
|
+
Card,
|
|
12
|
+
DxAnchorActivate,
|
|
13
|
+
Icon,
|
|
14
|
+
IconButton,
|
|
15
|
+
type IconButtonProps,
|
|
16
|
+
SystemIconButton,
|
|
17
|
+
Tag,
|
|
18
|
+
useTranslation,
|
|
19
|
+
} from '@dxos/react-ui';
|
|
20
|
+
import { type Actor, type Message } from '@dxos/types';
|
|
21
|
+
import { toHue } from '@dxos/ui-theme';
|
|
22
|
+
|
|
23
|
+
import { useActorContact } from '../../hooks';
|
|
24
|
+
import { translationKey } from '../../translations';
|
|
25
|
+
import { Avatar, avatarName } from '../Avatar';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Shared Card-row primitives rendered inside a `Card.Body`. These are the single source for the
|
|
29
|
+
* person/date/tags/ref/star rows used across the inbox tiles (`EventStack`/`InboxStack`), the preview
|
|
30
|
+
* cards (`EventCard`/`MessageCard`), and the article headers — so a row of each kind is defined exactly
|
|
31
|
+
* once and every surface composes from it.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
//
|
|
35
|
+
// AnchorIconButton — internal helper, not exported on Row.
|
|
36
|
+
//
|
|
37
|
+
|
|
38
|
+
type AnchorIconButtonProps = {
|
|
39
|
+
compact?: boolean;
|
|
40
|
+
icon: string;
|
|
41
|
+
fallbackIcon?: string;
|
|
42
|
+
label: string;
|
|
43
|
+
fallbackLabel?: string;
|
|
44
|
+
title?: string;
|
|
45
|
+
value?: URI.URI;
|
|
46
|
+
size?: 4 | 5 | 6;
|
|
47
|
+
onClick?: () => void;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Icon-only button that opens an ECHO object's preview card via `DxAnchorActivate`.
|
|
52
|
+
* Falls back to `onClick` when `value` is absent.
|
|
53
|
+
*/
|
|
54
|
+
const AnchorIconButton = ({
|
|
55
|
+
compact,
|
|
56
|
+
icon,
|
|
57
|
+
fallbackIcon,
|
|
58
|
+
label,
|
|
59
|
+
fallbackLabel,
|
|
60
|
+
title,
|
|
61
|
+
value,
|
|
62
|
+
size = 4,
|
|
63
|
+
onClick,
|
|
64
|
+
}: AnchorIconButtonProps) => {
|
|
65
|
+
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
66
|
+
|
|
67
|
+
const handleClick = useCallback(() => {
|
|
68
|
+
if (value) {
|
|
69
|
+
buttonRef.current?.dispatchEvent(
|
|
70
|
+
new DxAnchorActivate({
|
|
71
|
+
trigger: buttonRef.current,
|
|
72
|
+
dxn: value.toString(),
|
|
73
|
+
label,
|
|
74
|
+
kind: 'card',
|
|
75
|
+
title,
|
|
76
|
+
}),
|
|
77
|
+
);
|
|
78
|
+
} else {
|
|
79
|
+
onClick?.();
|
|
80
|
+
}
|
|
81
|
+
}, [value, label, title, onClick]);
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<IconButton
|
|
85
|
+
classNames={compact ? 'min-h-0' : 'aspect-square'}
|
|
86
|
+
variant='ghost'
|
|
87
|
+
disabled={!value && !onClick}
|
|
88
|
+
icon={value ? icon : (fallbackIcon ?? icon)}
|
|
89
|
+
iconOnly
|
|
90
|
+
size={size}
|
|
91
|
+
label={value ? label : (fallbackLabel ?? label)}
|
|
92
|
+
onClick={handleClick}
|
|
93
|
+
ref={buttonRef}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
//
|
|
99
|
+
// Date
|
|
100
|
+
//
|
|
101
|
+
|
|
102
|
+
type RowDateProps = {
|
|
103
|
+
start: Date;
|
|
104
|
+
end?: Date;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/** A Card.Row rendering a date or date range with a calendar icon. */
|
|
108
|
+
const RowDate = ({ start, end }: RowDateProps) => {
|
|
109
|
+
let { hours = 0, minutes = 0 } = (end && intervalToDuration({ start, end })) ?? {};
|
|
110
|
+
// Prefer 90m over 1h 30m.
|
|
111
|
+
if (hours === 1 && minutes !== 0) {
|
|
112
|
+
hours = 0;
|
|
113
|
+
minutes += 60;
|
|
114
|
+
}
|
|
115
|
+
const duration = [hours > 0 && `${hours}h`, minutes > 0 && `${minutes}m`].filter(Boolean).join(' ');
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<Card.Row>
|
|
119
|
+
<Card.Block>
|
|
120
|
+
<Icon icon='ph--calendar--regular' />
|
|
121
|
+
</Card.Block>
|
|
122
|
+
<div className='flex items-center gap-2 overflow-hidden whitespace-nowrap'>
|
|
123
|
+
<div className='truncate text-description'>{format(start, 'PPp')}</div>
|
|
124
|
+
{duration.length > 0 && <div className='text-description text-xs'>({duration})</div>}
|
|
125
|
+
</div>
|
|
126
|
+
</Card.Row>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
RowDate.displayName = 'Row.Date';
|
|
131
|
+
|
|
132
|
+
//
|
|
133
|
+
// Ref
|
|
134
|
+
//
|
|
135
|
+
|
|
136
|
+
type RowRefProps = {
|
|
137
|
+
object: Obj.Any;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/** A Card.Row rendering an ECHO ref/relation with a card-preview anchor icon. */
|
|
141
|
+
const RowRef = ({ object }: RowRefProps) => {
|
|
142
|
+
const label = Obj.getLabel(object, { fallback: 'typename' }) ?? 'object';
|
|
143
|
+
const icon = Obj.getIcon(object)?.icon ?? 'ph--cube--regular';
|
|
144
|
+
const echoUri = EID.tryParse(Obj.getURI(object).toString());
|
|
145
|
+
|
|
146
|
+
// TODO(burdon): Nav?
|
|
147
|
+
return (
|
|
148
|
+
<Card.Row>
|
|
149
|
+
<Card.Block>
|
|
150
|
+
<AnchorIconButton icon={icon} label={label} title={label} value={echoUri} />
|
|
151
|
+
</Card.Block>
|
|
152
|
+
<div className='flex items-center'>
|
|
153
|
+
<span className='truncate text-primary-text'>{label}</span>
|
|
154
|
+
</div>
|
|
155
|
+
</Card.Row>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
RowRef.displayName = 'Row.Ref';
|
|
160
|
+
|
|
161
|
+
//
|
|
162
|
+
// Person
|
|
163
|
+
//
|
|
164
|
+
|
|
165
|
+
/** Recipient/participant kind; drives the leading icon and accessible label. */
|
|
166
|
+
export type PersonRole = 'from' | 'to' | 'cc' | 'bcc' | 'attendee';
|
|
167
|
+
|
|
168
|
+
type RowPersonProps = {
|
|
169
|
+
actor: Actor.Actor;
|
|
170
|
+
/** Recipient/participant kind (icon + aria only; no visible prefix). */
|
|
171
|
+
role?: PersonRole;
|
|
172
|
+
/**
|
|
173
|
+
* Render a static `DxAvatar` in the gutter (hook-free) instead of the interactive contact anchor.
|
|
174
|
+
* Used by list tiles where resolving a contact per row (a hook) would be too costly.
|
|
175
|
+
*/
|
|
176
|
+
avatar?: boolean;
|
|
177
|
+
db?: Database.Database;
|
|
178
|
+
onContactCreate?: (actor: Actor.Actor) => void;
|
|
179
|
+
/** Render a trailing remove button (e.g. attendee rows in the editable event header). */
|
|
180
|
+
onRemove?: () => void;
|
|
181
|
+
/** Click handler for the avatar (e.g. select the message); avatar variant only. */
|
|
182
|
+
onClick?: (event: MouseEvent) => void;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Static avatar variant — no contact resolution. Suitable for virtualized list tiles.
|
|
187
|
+
*/
|
|
188
|
+
const PersonAvatarRow = ({ actor, onClick }: Pick<RowPersonProps, 'actor' | 'onClick'>) => (
|
|
189
|
+
<Card.Row>
|
|
190
|
+
<Card.Block>
|
|
191
|
+
<Avatar actor={actor} onClick={onClick} />
|
|
192
|
+
</Card.Block>
|
|
193
|
+
<Card.Text>{avatarName(actor) || actor.email}</Card.Text>
|
|
194
|
+
</Card.Row>
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Interactive variant — resolves the contact to a card-preview anchor, with a create-contact fallback.
|
|
199
|
+
*/
|
|
200
|
+
const PersonAnchorRow = ({
|
|
201
|
+
actor,
|
|
202
|
+
role,
|
|
203
|
+
db,
|
|
204
|
+
onContactCreate,
|
|
205
|
+
onRemove,
|
|
206
|
+
}: Omit<RowPersonProps, 'avatar' | 'onClick'>) => {
|
|
207
|
+
const { t } = useTranslation(translationKey);
|
|
208
|
+
const contactDXN = useActorContact(db, actor);
|
|
209
|
+
|
|
210
|
+
const handleContactCreate = useCallback(() => onContactCreate?.(actor), [actor, onContactCreate]);
|
|
211
|
+
|
|
212
|
+
// TODO(burdon): Reconcile with Avatar if space member.
|
|
213
|
+
return (
|
|
214
|
+
<Card.Row>
|
|
215
|
+
<Card.Block>
|
|
216
|
+
<AnchorIconButton
|
|
217
|
+
icon='ph--user--regular'
|
|
218
|
+
fallbackIcon='ph--user-plus--regular'
|
|
219
|
+
label={t('show-contact.label')}
|
|
220
|
+
fallbackLabel={t('create-contact.label')}
|
|
221
|
+
title={role ? `${role}: ${actor.name}` : actor.name}
|
|
222
|
+
value={contactDXN}
|
|
223
|
+
onClick={onContactCreate ? handleContactCreate : undefined}
|
|
224
|
+
/>
|
|
225
|
+
</Card.Block>
|
|
226
|
+
<Card.Text>{actor.name || actor.email}</Card.Text>
|
|
227
|
+
{onRemove && (
|
|
228
|
+
<Card.Block end>
|
|
229
|
+
<IconButton
|
|
230
|
+
variant='ghost'
|
|
231
|
+
iconOnly
|
|
232
|
+
icon='ph--x--regular'
|
|
233
|
+
label={t('remove-attendee.label')}
|
|
234
|
+
onClick={onRemove}
|
|
235
|
+
/>
|
|
236
|
+
</Card.Block>
|
|
237
|
+
)}
|
|
238
|
+
</Card.Row>
|
|
239
|
+
);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/** A Card.Row rendering a person (sender, recipient, attendee). */
|
|
243
|
+
const RowPerson = ({ avatar, onClick, ...props }: RowPersonProps) =>
|
|
244
|
+
avatar ? <PersonAvatarRow actor={props.actor} onClick={onClick} /> : <PersonAnchorRow {...props} />;
|
|
245
|
+
|
|
246
|
+
RowPerson.displayName = 'Row.Person';
|
|
247
|
+
|
|
248
|
+
//
|
|
249
|
+
// Tags
|
|
250
|
+
//
|
|
251
|
+
|
|
252
|
+
type TagItem = { id: string; label?: string; hue?: string };
|
|
253
|
+
|
|
254
|
+
type RowTagsProps = {
|
|
255
|
+
/** Optional — callers may pass an undefined/empty list (e.g. a message with no tags). */
|
|
256
|
+
tags?: TagItem[];
|
|
257
|
+
/** When provided, each chip is clickable and stops event propagation. */
|
|
258
|
+
onTagClick?: (label: string) => void;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
/** A Card.Row rendering a set of label+hue tag chips, optionally clickable. */
|
|
262
|
+
const RowTags = ({ tags, onTagClick }: RowTagsProps) => {
|
|
263
|
+
if (!tags?.length) {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return (
|
|
268
|
+
<Card.Row>
|
|
269
|
+
<Card.Block>
|
|
270
|
+
<Icon icon='ph--tag--regular' />
|
|
271
|
+
</Card.Block>
|
|
272
|
+
<div className='flex flex-wrap gap-1 py-1 -mx-0.5' data-testid='extracted-tags'>
|
|
273
|
+
{tags.map((tag) => (
|
|
274
|
+
<Tag
|
|
275
|
+
key={tag.id}
|
|
276
|
+
hue={toHue(tag.hue)}
|
|
277
|
+
data-testid={`message-tag-${tag.id}`}
|
|
278
|
+
onClick={
|
|
279
|
+
onTagClick
|
|
280
|
+
? (event) => {
|
|
281
|
+
event.stopPropagation();
|
|
282
|
+
onTagClick(tag.label ?? tag.id);
|
|
283
|
+
}
|
|
284
|
+
: undefined
|
|
285
|
+
}
|
|
286
|
+
>
|
|
287
|
+
{tag.label ?? tag.id}
|
|
288
|
+
</Tag>
|
|
289
|
+
))}
|
|
290
|
+
</div>
|
|
291
|
+
</Card.Row>
|
|
292
|
+
);
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
RowTags.displayName = 'Row.Tags';
|
|
296
|
+
|
|
297
|
+
//
|
|
298
|
+
// Attachments
|
|
299
|
+
//
|
|
300
|
+
|
|
301
|
+
type RowAttachmentsProps = {
|
|
302
|
+
/** Optional — callers may pass an undefined/empty list (e.g. a message with no attachments). */
|
|
303
|
+
attachments?: readonly Message.Attachment[];
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* A Card.Row listing a message's attachments by name with a generic file icon. Not yet clickable —
|
|
308
|
+
* resolving the attachment's ref to open/preview it is a follow-up.
|
|
309
|
+
*/
|
|
310
|
+
const RowAttachments = ({ attachments }: RowAttachmentsProps) => {
|
|
311
|
+
if (!attachments?.length) {
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return (
|
|
316
|
+
<Card.Row>
|
|
317
|
+
<Card.Block>
|
|
318
|
+
<Icon icon='ph--paperclip--regular' />
|
|
319
|
+
</Card.Block>
|
|
320
|
+
<div className='flex flex-wrap gap-1 py-1 -mx-0.5' data-testid='message-attachments'>
|
|
321
|
+
{attachments.map((attachment) => (
|
|
322
|
+
<Tag key={attachment.ref.uri} hue='neutral' classNames='inline-flex items-center gap-1'>
|
|
323
|
+
<Icon icon='ph--file--regular' size={3} />
|
|
324
|
+
{attachment.name ?? attachment.ref.uri}
|
|
325
|
+
</Tag>
|
|
326
|
+
))}
|
|
327
|
+
</div>
|
|
328
|
+
</Card.Row>
|
|
329
|
+
);
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
RowAttachments.displayName = 'Row.Attachments';
|
|
333
|
+
|
|
334
|
+
//
|
|
335
|
+
// Star
|
|
336
|
+
//
|
|
337
|
+
|
|
338
|
+
type RowStarProps = {
|
|
339
|
+
starred?: boolean;
|
|
340
|
+
/** Toggle handler; the button renders only when provided. */
|
|
341
|
+
onToggle?: () => void;
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Star toggle for a `Card.Block` leading gutter (shared by event/message tiles and headers). Stops
|
|
346
|
+
* the click from bubbling so starring doesn't also select/activate the surrounding tile or card.
|
|
347
|
+
*/
|
|
348
|
+
const RowStar = ({ starred, onToggle }: RowStarProps) => {
|
|
349
|
+
const handleClick = useCallback<NonNullable<IconButtonProps['onClick']>>(
|
|
350
|
+
(event) => {
|
|
351
|
+
event.stopPropagation();
|
|
352
|
+
onToggle?.();
|
|
353
|
+
},
|
|
354
|
+
[onToggle],
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
if (!onToggle) {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return <SystemIconButton.Star iconOnly variant='ghost' active={starred} onClick={handleClick} />;
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
RowStar.displayName = 'Row.Star';
|
|
365
|
+
|
|
366
|
+
//
|
|
367
|
+
// Row
|
|
368
|
+
//
|
|
369
|
+
|
|
370
|
+
export const Row = {
|
|
371
|
+
Date: RowDate,
|
|
372
|
+
Ref: RowRef,
|
|
373
|
+
Person: RowPerson,
|
|
374
|
+
Tags: RowTags,
|
|
375
|
+
Attachments: RowAttachments,
|
|
376
|
+
Star: RowStar,
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
export type { RowAttachmentsProps, RowDateProps, RowPersonProps, RowRefProps, RowStarProps, RowTagsProps };
|
package/src/components/index.ts
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { useMemo } from 'react';
|
|
6
|
+
|
|
7
|
+
import { type Database, Filter, Obj } from '@dxos/echo';
|
|
8
|
+
import { useQuery } from '@dxos/echo-react';
|
|
9
|
+
import { EID } from '@dxos/keys';
|
|
10
|
+
import { type Actor, Person } from '@dxos/types';
|
|
11
|
+
|
|
12
|
+
// TODO(burdon): Factor out lazy update pattern.
|
|
13
|
+
export const useActorContact = (db?: Database.Database, actor?: Actor.Actor): EID.EID | undefined => {
|
|
14
|
+
// Don't bother querying the space if there is already a reference to the contact.
|
|
15
|
+
const isLinked = !!actor?.contact;
|
|
16
|
+
const contacts = useQuery(isLinked ? undefined : db, Filter.type(Person.Person));
|
|
17
|
+
const existingContact = useMemo(
|
|
18
|
+
() => contacts.find((contact) => contact.emails?.find((email) => email.value === actor?.email)),
|
|
19
|
+
[contacts, actor?.email],
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
return useMemo(
|
|
23
|
+
() =>
|
|
24
|
+
actor?.contact
|
|
25
|
+
? EID.tryParse(actor.contact.uri)
|
|
26
|
+
: existingContact
|
|
27
|
+
? EID.parse(Obj.getURI(existingContact))
|
|
28
|
+
: undefined,
|
|
29
|
+
[actor?.contact, existingContact],
|
|
30
|
+
);
|
|
31
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Resource } from '@dxos/react-ui';
|
|
6
|
+
|
|
7
|
+
export const translationKey = '@dxos/react-ui-card';
|
|
8
|
+
|
|
9
|
+
export const translations = [
|
|
10
|
+
{
|
|
11
|
+
'en-US': {
|
|
12
|
+
[translationKey]: {
|
|
13
|
+
'show-contact.label': 'Show contact',
|
|
14
|
+
'create-contact.label': 'Create contact',
|
|
15
|
+
'remove-attendee.label': 'Remove attendee',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
] as const satisfies Resource[];
|
package/src/util.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
/** Deterministic string hash (djb2), used to map a name to a stable avatar hue. */
|
|
6
|
+
export const hashString = (str?: string): number =>
|
|
7
|
+
str ? Math.abs(str.split('').reduce((hash, char) => (hash << 5) + hash + char.charCodeAt(0), 0)) : 0;
|
package/README.md
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
// packages/ui/react-ui-card/src/components/Card.tsx
|
|
2
|
-
import { Circle, DotsSixVertical, DotsThreeVertical } from "@phosphor-icons/react";
|
|
3
|
-
import React, { forwardRef } from "react";
|
|
4
|
-
import { useDensityContext, DropdownMenu } from "@dxos/react-ui";
|
|
5
|
-
|
|
6
|
-
// packages/ui/react-ui-card/src/theme.ts
|
|
7
|
-
import { getSize, attentionSurface, mx } from "@dxos/react-ui-theme";
|
|
8
|
-
var defaults = {
|
|
9
|
-
width: "min-w-[256px]"
|
|
10
|
-
};
|
|
11
|
-
var cardRoot = ({ grow, square, rounded = true }, ...etc) => mx("flex flex-col group/card overflow-hidden", grow && "h-full", defaults.width, attentionSurface, "shadow", rounded && "rounded", square && "aspect-square", ...etc);
|
|
12
|
-
var cardHeader = ({ floating }, ...etc) => mx(floating ? "relative" : "flex w-full shrink-0 justify-between overflow-hidden items-center py-1", ...etc);
|
|
13
|
-
var cardTitle = ({ center }, ...etc) => mx("grow overflow-hidden truncate first:pl-4 last:pr-4", center && "text-center", ...etc);
|
|
14
|
-
var cardDragHandle = ({ density, position }, ...etc) => mx("flex shrink-0 items-center justify-center select-none", density === "fine" ? getSize(8) : getSize(10), position === "left" && "absolute top-1 left-1", position === "right" && "absolute top-1 right-1", position && "text-black group-hover/card:bg-white group-hover/card:bg-opacity-80", ...etc);
|
|
15
|
-
var cardDragHandleIcon = (_, ...etc) => mx(getSize(5), "cursor-pointer", ...etc);
|
|
16
|
-
var cardMenu = ({ density, position }, ...etc) => mx("flex shrink-0 items-center justify-center", density === "fine" ? getSize(8) : getSize(10), position === "left" && "absolute top-1 left-1", position === "right" && "absolute top-1 right-1", position && "text-black group-hover/card:bg-white group-hover/card:bg-opacity-80", ...etc);
|
|
17
|
-
var cardMenuIcon = (_, ...etc) => mx(getSize(5), "cursor-pointer");
|
|
18
|
-
var cardBody = ({ density, gutter, noPadding }, ...etc) => mx(
|
|
19
|
-
"grow overflow-auto",
|
|
20
|
-
!noPadding && "px-2",
|
|
21
|
-
// TODO(burdon): Create density-specific constants.
|
|
22
|
-
gutter && (density === "fine" ? "pl-0 ml-[32px]" : "pl-0 ml-[40px]"),
|
|
23
|
-
...etc
|
|
24
|
-
);
|
|
25
|
-
var cardMedia = ({ contain }, ...etc) => mx(
|
|
26
|
-
"grow max-h-[300px]",
|
|
27
|
-
// Hide broken image links (e.g., if offline).
|
|
28
|
-
"before:content-['\xA0'] before:block before:w-full before:h-full before:border-0",
|
|
29
|
-
contain ? "object-contain" : "object-cover",
|
|
30
|
-
...etc
|
|
31
|
-
);
|
|
32
|
-
var cardTheme = {
|
|
33
|
-
root: cardRoot,
|
|
34
|
-
header: cardHeader,
|
|
35
|
-
title: cardTitle,
|
|
36
|
-
dragHandle: cardDragHandle,
|
|
37
|
-
dragHandleIcon: cardDragHandleIcon,
|
|
38
|
-
menu: cardMenu,
|
|
39
|
-
menuIcon: cardMenuIcon,
|
|
40
|
-
body: cardBody,
|
|
41
|
-
media: cardMedia
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
// packages/ui/react-ui-card/src/components/Card.tsx
|
|
45
|
-
var CardRoot = /* @__PURE__ */ forwardRef(({ grow, square, noPadding, classNames, children, ...props }, forwardedRef) => {
|
|
46
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
47
|
-
...props,
|
|
48
|
-
ref: forwardedRef,
|
|
49
|
-
className: cardRoot({
|
|
50
|
-
grow,
|
|
51
|
-
square,
|
|
52
|
-
noPadding
|
|
53
|
-
}, classNames)
|
|
54
|
-
}, children);
|
|
55
|
-
});
|
|
56
|
-
var CardHeader = ({ floating, classNames, children, ...props }) => {
|
|
57
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
58
|
-
...props,
|
|
59
|
-
className: cardHeader({
|
|
60
|
-
floating
|
|
61
|
-
}, classNames)
|
|
62
|
-
}, children);
|
|
63
|
-
};
|
|
64
|
-
var CardTitle = ({ center, title, classNames, ...props }) => {
|
|
65
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
66
|
-
...props,
|
|
67
|
-
className: cardTitle({
|
|
68
|
-
center
|
|
69
|
-
}, classNames)
|
|
70
|
-
}, title);
|
|
71
|
-
};
|
|
72
|
-
var CardDragHandle = ({ position, classNames, ...props }) => {
|
|
73
|
-
const density = useDensityContext();
|
|
74
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
75
|
-
...props,
|
|
76
|
-
className: cardDragHandle({
|
|
77
|
-
density,
|
|
78
|
-
position
|
|
79
|
-
}, classNames)
|
|
80
|
-
}, /* @__PURE__ */ React.createElement(DotsSixVertical, {
|
|
81
|
-
className: cardDragHandleIcon({})
|
|
82
|
-
}));
|
|
83
|
-
};
|
|
84
|
-
var CardEndcap = ({ Icon = Circle, position, classNames, ...props }) => {
|
|
85
|
-
const density = useDensityContext();
|
|
86
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
87
|
-
...props,
|
|
88
|
-
className: cardMenu({
|
|
89
|
-
density,
|
|
90
|
-
position
|
|
91
|
-
}, classNames)
|
|
92
|
-
}, /* @__PURE__ */ React.createElement(Icon, {
|
|
93
|
-
className: cardMenuIcon({})
|
|
94
|
-
}));
|
|
95
|
-
};
|
|
96
|
-
var CardMenu = /* @__PURE__ */ forwardRef(({ children, position, classNames, ...props }, forwardRef2) => {
|
|
97
|
-
const density = useDensityContext();
|
|
98
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
99
|
-
...props,
|
|
100
|
-
className: cardMenu({
|
|
101
|
-
density,
|
|
102
|
-
position
|
|
103
|
-
}, classNames),
|
|
104
|
-
ref: forwardRef2
|
|
105
|
-
}, /* @__PURE__ */ React.createElement(DropdownMenu.Root, null, /* @__PURE__ */ React.createElement(DropdownMenu.Trigger, {
|
|
106
|
-
asChild: true
|
|
107
|
-
}, /* @__PURE__ */ React.createElement(DotsThreeVertical, {
|
|
108
|
-
className: cardMenuIcon({})
|
|
109
|
-
})), /* @__PURE__ */ React.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React.createElement(DropdownMenu.Viewport, null, children))));
|
|
110
|
-
});
|
|
111
|
-
var CardBody = ({ gutter, classNames, children, ...props }) => {
|
|
112
|
-
const density = useDensityContext();
|
|
113
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
114
|
-
...props,
|
|
115
|
-
className: cardBody({
|
|
116
|
-
density,
|
|
117
|
-
gutter
|
|
118
|
-
}, classNames)
|
|
119
|
-
}, children);
|
|
120
|
-
};
|
|
121
|
-
var CardMedia = ({ src, contain, classNames, ...props }) => {
|
|
122
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
123
|
-
className: "flex grow overflow-hidden"
|
|
124
|
-
}, /* @__PURE__ */ React.createElement("img", {
|
|
125
|
-
...props,
|
|
126
|
-
className: cardMedia({
|
|
127
|
-
contain
|
|
128
|
-
}, classNames),
|
|
129
|
-
src
|
|
130
|
-
}));
|
|
131
|
-
};
|
|
132
|
-
var Card = {
|
|
133
|
-
Root: CardRoot,
|
|
134
|
-
Header: CardHeader,
|
|
135
|
-
DragHandle: CardDragHandle,
|
|
136
|
-
Endcap: CardEndcap,
|
|
137
|
-
Menu: CardMenu,
|
|
138
|
-
Title: CardTitle,
|
|
139
|
-
Body: CardBody,
|
|
140
|
-
Media: CardMedia
|
|
141
|
-
};
|
|
142
|
-
export {
|
|
143
|
-
Card,
|
|
144
|
-
CardBody,
|
|
145
|
-
CardHeader,
|
|
146
|
-
CardMedia,
|
|
147
|
-
CardTitle,
|
|
148
|
-
cardBody,
|
|
149
|
-
cardDragHandle,
|
|
150
|
-
cardDragHandleIcon,
|
|
151
|
-
cardHeader,
|
|
152
|
-
cardMedia,
|
|
153
|
-
cardMenu,
|
|
154
|
-
cardMenuIcon,
|
|
155
|
-
cardRoot,
|
|
156
|
-
cardTheme,
|
|
157
|
-
cardTitle
|
|
158
|
-
};
|
|
159
|
-
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/Card.tsx", "../../../src/theme.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Circle, DotsSixVertical, DotsThreeVertical, type Icon } from '@phosphor-icons/react';\nimport { type Primitive } from '@radix-ui/react-primitive';\nimport React, {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type FC,\n forwardRef,\n type PropsWithChildren,\n} from 'react';\n\nimport { useDensityContext, DropdownMenu, type ThemedClassName } from '@dxos/react-ui';\n\nimport {\n cardBody,\n cardDragHandle,\n cardDragHandleIcon,\n cardHeader,\n cardMedia,\n cardMenu,\n cardMenuIcon,\n cardRoot,\n cardTitle,\n} from '../theme';\n\ntype CardRootProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.div>> & {\n grow?: boolean;\n square?: boolean;\n noPadding?: boolean;\n};\n\n// TODO(burdon): Forward refs for all components?\nconst CardRoot = forwardRef<HTMLDivElement, CardRootProps>(\n ({ grow, square, noPadding, classNames, children, ...props }, forwardedRef) => {\n return (\n <div {...props} ref={forwardedRef} className={cardRoot({ grow, square, noPadding }, classNames)}>\n {children}\n </div>\n );\n },\n);\n\ntype CardHeaderProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> & { floating?: boolean };\n\nexport const CardHeader: FC<CardHeaderProps> = ({ floating, classNames, children, ...props }) => {\n return (\n <div {...props} className={cardHeader({ floating }, classNames)}>\n {children}\n </div>\n );\n};\n\ntype CardTitleProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> & {\n center?: boolean;\n title?: string;\n};\n\nexport const CardTitle: FC<CardTitleProps> = ({ center, title, classNames, ...props }) => {\n return (\n <div {...props} className={cardTitle({ center }, classNames)}>\n {title}\n </div>\n );\n};\n\n// TODO(burdon): Reuse ListItemEndcap?\ntype CardDragHandleProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> & { position?: 'left' | 'right' };\n\nconst CardDragHandle: FC<CardDragHandleProps> = ({ position, classNames, ...props }) => {\n const density = useDensityContext();\n return (\n <div {...props} className={cardDragHandle({ density, position }, classNames)}>\n <DotsSixVertical className={cardDragHandleIcon({})} />\n </div>\n );\n};\n\ntype CardEndcapProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> & { Icon?: Icon; position?: 'left' | 'right' };\n\nconst CardEndcap: FC<CardEndcapProps> = ({ Icon = Circle, position, classNames, ...props }) => {\n const density = useDensityContext();\n return (\n <div {...props} className={cardMenu({ density, position }, classNames)}>\n <Icon className={cardMenuIcon({})} />\n </div>\n );\n};\n\ntype CardMenuProps = PropsWithChildren<\n ThemedClassName<ComponentPropsWithoutRef<'div'>> & { position?: 'left' | 'right' }\n>;\n\n// TODO(burdon): Reconcile with Endcap (remove dropdown from here). See ListItem.Endcap (style icon/size?)\nconst CardMenu = forwardRef<HTMLDivElement, CardMenuProps>(\n ({ children, position, classNames, ...props }, forwardRef) => {\n const density = useDensityContext();\n return (\n <div {...props} className={cardMenu({ density, position }, classNames)} ref={forwardRef}>\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <DotsThreeVertical className={cardMenuIcon({})} />\n </DropdownMenu.Trigger>\n {/* TODO(burdon): Position to the left of the menu button. */}\n <DropdownMenu.Content>\n <DropdownMenu.Viewport>{children}</DropdownMenu.Viewport>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n </div>\n );\n },\n);\n\ntype CardBodyProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> & { gutter?: boolean };\n\nexport const CardBody: FC<CardBodyProps> = ({ gutter, classNames, children, ...props }) => {\n const density = useDensityContext();\n return (\n <div {...props} className={cardBody({ density, gutter }, classNames)}>\n {children}\n </div>\n );\n};\n\ntype CardMediaProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> & { src?: string; contain?: boolean };\n\n// TODO(burdon): Option to set to 50% of height of card.\nexport const CardMedia: FC<CardMediaProps> = ({ src, contain, classNames, ...props }) => {\n return (\n <div className='flex grow overflow-hidden'>\n <img {...props} className={cardMedia({ contain }, classNames)} src={src} />\n </div>\n );\n};\n\nexport const Card = {\n Root: CardRoot,\n Header: CardHeader,\n DragHandle: CardDragHandle,\n Endcap: CardEndcap,\n Menu: CardMenu,\n Title: CardTitle,\n Body: CardBody,\n Media: CardMedia,\n};\n\nexport type { CardRootProps };\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type ComponentFunction, type Density, type Theme } from '@dxos/react-ui';\nimport { getSize, attentionSurface, mx } from '@dxos/react-ui-theme';\n\nconst defaults = {\n width: 'min-w-[256px]',\n};\n\nexport type CardStyleProps = Partial<{\n density: Density;\n grow?: boolean;\n square?: boolean;\n rounded?: boolean;\n noPadding?: boolean;\n}>;\n\nexport const cardRoot: ComponentFunction<CardStyleProps> = ({ grow, square, rounded = true }, ...etc) =>\n mx(\n 'flex flex-col group/card overflow-hidden',\n grow && 'h-full',\n defaults.width,\n attentionSurface,\n 'shadow', // TODO(burdon): Elevation?\n rounded && 'rounded',\n square && 'aspect-square',\n ...etc,\n );\n\nexport const cardHeader: ComponentFunction<CardStyleProps & { floating?: boolean }> = ({ floating }, ...etc) =>\n mx(floating ? 'relative' : 'flex w-full shrink-0 justify-between overflow-hidden items-center py-1', ...etc);\n\nexport const cardTitle: ComponentFunction<CardStyleProps & { center?: boolean }> = ({ center }, ...etc) =>\n mx('grow overflow-hidden truncate first:pl-4 last:pr-4', center && 'text-center', ...etc);\n\nexport const cardDragHandle: ComponentFunction<CardStyleProps & { position?: 'left' | 'right' }> = (\n { density, position },\n ...etc\n) =>\n mx(\n 'flex shrink-0 items-center justify-center select-none',\n density === 'fine' ? getSize(8) : getSize(10),\n position === 'left' && 'absolute top-1 left-1',\n position === 'right' && 'absolute top-1 right-1',\n position && 'text-black group-hover/card:bg-white group-hover/card:bg-opacity-80',\n ...etc,\n );\n\nexport const cardDragHandleIcon: ComponentFunction<CardStyleProps> = (_, ...etc) =>\n mx(getSize(5), 'cursor-pointer', ...etc);\n\n// TODO(burdon): Helper for DropdownMenu? Density, etc?\nexport const cardMenu: ComponentFunction<CardStyleProps & { position?: 'left' | 'right' }> = (\n { density, position },\n ...etc\n) =>\n mx(\n 'flex shrink-0 items-center justify-center',\n density === 'fine' ? getSize(8) : getSize(10),\n position === 'left' && 'absolute top-1 left-1',\n position === 'right' && 'absolute top-1 right-1',\n position && 'text-black group-hover/card:bg-white group-hover/card:bg-opacity-80',\n ...etc,\n );\n\nexport const cardMenuIcon: ComponentFunction<CardStyleProps> = (_, ...etc) => mx(getSize(5), 'cursor-pointer');\n\nexport const cardBody: ComponentFunction<CardStyleProps & { gutter?: boolean }> = (\n { density, gutter, noPadding },\n ...etc\n) =>\n mx(\n 'grow overflow-auto',\n !noPadding && 'px-2',\n // TODO(burdon): Create density-specific constants.\n gutter && (density === 'fine' ? 'pl-0 ml-[32px]' : 'pl-0 ml-[40px]'),\n ...etc,\n );\n\nexport const cardMedia: ComponentFunction<CardStyleProps & { contain?: boolean }> = ({ contain }, ...etc) =>\n mx(\n 'grow max-h-[300px]',\n // Hide broken image links (e.g., if offline).\n \"before:content-[' '] before:block before:w-full before:h-full before:border-0\",\n contain ? 'object-contain' : 'object-cover',\n ...etc,\n );\n\nexport const cardTheme: Theme<CardStyleProps> = {\n root: cardRoot,\n header: cardHeader,\n title: cardTitle,\n dragHandle: cardDragHandle,\n dragHandleIcon: cardDragHandleIcon,\n menu: cardMenu,\n menuIcon: cardMenuIcon,\n body: cardBody,\n media: cardMedia,\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["Circle", "DotsSixVertical", "DotsThreeVertical", "React", "forwardRef", "useDensityContext", "DropdownMenu", "getSize", "attentionSurface", "mx", "defaults", "width", "cardRoot", "grow", "square", "rounded", "etc", "mx", "attentionSurface", "cardHeader", "floating", "cardTitle", "center", "cardDragHandle", "density", "position", "getSize", "cardDragHandleIcon", "_", "cardMenu", "cardMenuIcon", "cardBody", "gutter", "noPadding", "cardMedia", "contain", "cardTheme", "root", "header", "title", "dragHandle", "dragHandleIcon", "menu", "menuIcon", "body", "media", "CardRoot", "forwardRef", "grow", "square", "noPadding", "classNames", "children", "props", "forwardedRef", "div", "ref", "className", "cardRoot", "CardHeader", "floating", "cardHeader", "CardTitle", "center", "title", "cardTitle", "CardDragHandle", "position", "density", "useDensityContext", "cardDragHandle", "DotsSixVertical", "cardDragHandleIcon", "CardEndcap", "Icon", "Circle", "cardMenu", "cardMenuIcon", "CardMenu", "DropdownMenu", "Root", "Trigger", "asChild", "DotsThreeVertical", "Content", "Viewport", "CardBody", "gutter", "cardBody", "CardMedia", "src", "contain", "img", "cardMedia", "Card", "Header", "DragHandle", "Endcap", "Menu", "Title", "Body", "Media"]
|
|
7
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"inputs":{"packages/ui/react-ui-card/src/theme.ts":{"bytes":9652,"imports":[{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-card/src/components/Card.tsx":{"bytes":14189,"imports":[{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-card/src/theme.ts","kind":"import-statement","original":"../theme"}],"format":"esm"},"packages/ui/react-ui-card/src/components/index.ts":{"bytes":500,"imports":[{"path":"packages/ui/react-ui-card/src/components/Card.tsx","kind":"import-statement","original":"./Card"}],"format":"esm"},"packages/ui/react-ui-card/src/index.ts":{"bytes":584,"imports":[{"path":"packages/ui/react-ui-card/src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"packages/ui/react-ui-card/src/theme.ts","kind":"import-statement","original":"./theme"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-card/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":12773},"packages/ui/react-ui-card/dist/lib/browser/index.mjs":{"imports":[{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true}],"exports":["Card","CardBody","CardHeader","CardMedia","CardTitle","cardBody","cardDragHandle","cardDragHandleIcon","cardHeader","cardMedia","cardMenu","cardMenuIcon","cardRoot","cardTheme","cardTitle"],"entryPoint":"packages/ui/react-ui-card/src/index.ts","inputs":{"packages/ui/react-ui-card/src/components/Card.tsx":{"bytesInOutput":3096},"packages/ui/react-ui-card/src/theme.ts":{"bytesInOutput":2207},"packages/ui/react-ui-card/src/components/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-card/src/index.ts":{"bytesInOutput":0}},"bytes":5704}}}
|