@moises.ai/design-system 4.14.7 → 4.14.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moises.ai/design-system",
3
- "version": "4.14.7",
3
+ "version": "4.14.8",
4
4
  "description": "Design System package based on @radix-ui/themes with custom defaults",
5
5
  "private": false,
6
6
  "type": "module",
@@ -138,6 +138,9 @@ const CardDetails = ({
138
138
  onAvatarClick,
139
139
  avatarContent,
140
140
  seeDetailsText = 'Details',
141
+ actions,
142
+ loading,
143
+ disabled,
141
144
  children,
142
145
  style,
143
146
  ...props
@@ -154,10 +157,19 @@ const CardDetails = ({
154
157
  : itemAvatar
155
158
 
156
159
  return (
157
- <div className={styles.cardWrapper}>
160
+ <div className={classNames(
161
+ styles.cardWrapper,
162
+ loading && styles.cardWrapperLoading,
163
+ disabled && styles.cardWrapperDisabled,
164
+ )}>
158
165
  <RadioCards.Item
159
166
  value={itemId}
160
- className={classNames(className, styles.listCardsItem)}
167
+ className={classNames(
168
+ className,
169
+ styles.listCardsItem,
170
+ loading && styles.listCardsItemLoading,
171
+ disabled && styles.listCardsItemDisabled,
172
+ )}
161
173
  style={{
162
174
  '--color-surface': 'transparent',
163
175
  width: '100%',
@@ -170,13 +182,20 @@ const CardDetails = ({
170
182
  gap="2"
171
183
  width="100%"
172
184
  style={{
173
- paddingRight: onSeeDetails || onAvatarClick ? '90px' : '0',
185
+ paddingRight:
186
+ actions || onSeeDetails || onAvatarClick ? '90px' : '0',
174
187
  paddingLeft: onAvatarClick ? '68px' : '0',
175
188
  overflow: 'hidden',
176
189
  }}
177
190
  >
178
191
  {!onAvatarClick && (
179
- <Avatar src={avatarUrl} className={styles.listCardsAvatar} />
192
+ avatarContent ? (
193
+ <div className={styles.listCardsAvatarIcon}>
194
+ {avatarContent}
195
+ </div>
196
+ ) : (
197
+ <Avatar src={avatarUrl} className={styles.listCardsAvatar} />
198
+ )
180
199
  )}
181
200
  <Flex direction="column" justify="center">
182
201
  <Text as="div" size="2" className={styles.listCardsItemText}>
@@ -224,45 +243,56 @@ const CardDetails = ({
224
243
  )}
225
244
 
226
245
  <div className={styles.cardActions}>
227
- <Flex
228
- direction="column"
229
- align="end"
230
- gap="2"
231
- height="100%"
232
- justify={onFavorite ? 'between' : 'end'}
233
- >
234
- {onFavorite && (
235
- <div
236
- className={classNames(
237
- styles.favoriteButton,
238
- styles.seeDetailsButton,
239
- )}
240
- onClick={(e) => {
241
- e.stopPropagation()
242
- e.preventDefault()
243
- onFavorite(e)
244
- }}
245
- >
246
- {favorite ? <StarFilledIcon /> : <StarIcon />}
247
- </div>
248
- )}
246
+ {actions ? (
247
+ <Flex
248
+ align="start"
249
+ justify="start"
250
+ height="100%"
251
+ className={styles.customActions}
252
+ >
253
+ {actions}
254
+ </Flex>
255
+ ) : (
256
+ <Flex
257
+ direction="column"
258
+ align="end"
259
+ gap="2"
260
+ height="100%"
261
+ justify={onFavorite ? 'between' : 'end'}
262
+ >
263
+ {onFavorite && (
264
+ <div
265
+ className={classNames(
266
+ styles.favoriteButton,
267
+ !favorite && styles.seeDetailsButton,
268
+ )}
269
+ onClick={(e) => {
270
+ e.stopPropagation()
271
+ e.preventDefault()
272
+ onFavorite(e)
273
+ }}
274
+ >
275
+ {favorite ? <StarFilledIcon /> : <StarIcon />}
276
+ </div>
277
+ )}
249
278
 
250
- {onSeeDetails && (
251
- <div
252
- className={classNames(
253
- styles.buttonGhost,
254
- styles.seeDetailsButton,
255
- )}
256
- onClick={(e) => {
257
- e.stopPropagation()
258
- e.preventDefault()
259
- onSeeDetails(e)
260
- }}
261
- >
262
- {seeDetailsText}
263
- </div>
264
- )}
265
- </Flex>
279
+ {onSeeDetails && (
280
+ <div
281
+ className={classNames(
282
+ styles.buttonGhost,
283
+ styles.seeDetailsButton,
284
+ )}
285
+ onClick={(e) => {
286
+ e.stopPropagation()
287
+ e.preventDefault()
288
+ onSeeDetails(e)
289
+ }}
290
+ >
291
+ {seeDetailsText}
292
+ </div>
293
+ )}
294
+ </Flex>
295
+ )}
266
296
  </div>
267
297
  </div>
268
298
  )
@@ -226,6 +226,80 @@
226
226
  outline: 1px solid var(--neutral-alpha-6);
227
227
  outline-offset: -1px;
228
228
  }
229
+ .listCardsItemDisabled {
230
+ pointer-events: none;
231
+ }
232
+
233
+ .listCardsItemDisabled:hover {
234
+ background-color: transparent !important;
235
+ outline: 1px solid var(--neutral-alpha-4);
236
+ outline-offset: -1px;
237
+ }
238
+
239
+ .cardWrapperDisabled {
240
+ cursor: default;
241
+ }
242
+
243
+ .cardWrapperDisabled:hover .listCardsItem {
244
+ background-color: transparent !important;
245
+ outline: 1px solid var(--neutral-alpha-4) !important;
246
+ outline-offset: -1px;
247
+ }
248
+
249
+ .listCardsItemLoading {
250
+ outline: none !important;
251
+ }
252
+
253
+ .cardWrapperLoading {
254
+ position: relative;
255
+ }
256
+
257
+ .cardWrapperLoading::before {
258
+ content: '';
259
+ position: absolute;
260
+ inset: -1px;
261
+ border-radius: 9px;
262
+ padding: 1px;
263
+ background: conic-gradient(
264
+ from var(--loading-angle, 0deg),
265
+ transparent 0%,
266
+ transparent 60%,
267
+ rgba(25, 228, 241, 0.6) 80%,
268
+ rgba(25, 228, 241, 1) 90%,
269
+ transparent 100%
270
+ );
271
+ -webkit-mask:
272
+ linear-gradient(#fff 0 0) content-box,
273
+ linear-gradient(#fff 0 0);
274
+ -webkit-mask-composite: xor;
275
+ mask:
276
+ linear-gradient(#fff 0 0) content-box,
277
+ linear-gradient(#fff 0 0);
278
+ mask-composite: exclude;
279
+ animation: listCardsLoadingSweep 2s linear infinite;
280
+ pointer-events: none;
281
+ z-index: 1;
282
+ }
283
+
284
+ @property --loading-angle {
285
+ syntax: "<angle>";
286
+ initial-value: 0deg;
287
+ inherits: false;
288
+ }
289
+
290
+ @keyframes listCardsLoadingSweep {
291
+ 0% {
292
+ --loading-angle: 0deg;
293
+ }
294
+ 100% {
295
+ --loading-angle: 360deg;
296
+ }
297
+ }
298
+
299
+ .customActions {
300
+ pointer-events: auto;
301
+ }
302
+
229
303
  .gridContainer {
230
304
  display: grid;
231
305
  gap: 8px;
@@ -1,7 +1,16 @@
1
1
  import React, { useState } from 'react'
2
2
  import { ListCards } from './ListCards'
3
- import { Flex, Avatar } from '@radix-ui/themes'
4
- import { MusicIcon, DrumsIcon, PianoIcon } from '../../icons'
3
+ import { Flex, Avatar, Text } from '@radix-ui/themes'
4
+ import {
5
+ MusicIcon,
6
+ DrumsIcon,
7
+ PianoIcon,
8
+ AlertIcon,
9
+ TrashIcon,
10
+ } from '../../icons'
11
+ import { DropdownMenu } from '../DropdownMenu/DropdownMenu'
12
+ import { IconButton } from '../IconButton/IconButton'
13
+ import { MoreButton } from '../MoreButton/MoreButton'
5
14
 
6
15
  export default {
7
16
  title: 'Components/ListCards',
@@ -309,6 +318,121 @@ const sampleItemsForSizes = [
309
318
  },
310
319
  ]
311
320
 
321
+ const voiceItems = [
322
+ {
323
+ id: '1',
324
+ name: 'Ana',
325
+ description: 'Training: 100 rounds completed...',
326
+ isLoading: true,
327
+ },
328
+ {
329
+ id: '2',
330
+ name: 'Carlos',
331
+ description: 'Training: 50 rounds completed...',
332
+ isLoading: true,
333
+ },
334
+ {
335
+ id: '3',
336
+ name: 'Maria',
337
+ description: 'Ready to use',
338
+ isLoading: false,
339
+ },
340
+ {
341
+ id: '4',
342
+ name: 'Ana',
343
+ description: 'Failed',
344
+ isLoading: false,
345
+ isFailed: true,
346
+ },
347
+ ]
348
+
349
+ const menuOptions = [
350
+ {
351
+ type: 'item',
352
+ key: 'rename',
353
+ label: 'Rename',
354
+ onClick: () => console.log('Rename clicked'),
355
+ },
356
+ {
357
+ type: 'item',
358
+ key: 'duplicate',
359
+ label: 'Duplicate',
360
+ onClick: () => console.log('Duplicate clicked'),
361
+ },
362
+ { type: 'separator', key: 'sep1' },
363
+ {
364
+ type: 'item',
365
+ key: 'delete',
366
+ label: 'Delete',
367
+ onClick: () => console.log('Delete clicked'),
368
+ },
369
+ ]
370
+
371
+ export const WithCustomActions = {
372
+ render: (args) => {
373
+ const [selectedId, setSelectedId] = useState('1')
374
+
375
+ const handleSelect = (id) => {
376
+ setSelectedId(id)
377
+ }
378
+
379
+ return (
380
+ <Flex height="400px" width="328px">
381
+ <ListCards>
382
+ {voiceItems.map((item) => (
383
+ <ListCards.CardDetails
384
+ key={item.id}
385
+ item={item}
386
+ loading={item.isLoading}
387
+ disabled={item.isFailed}
388
+ checked={item.isFailed ? false : item.id === selectedId}
389
+ onClick={item.isFailed ? undefined : () => handleSelect(item.id)}
390
+ avatarContent={
391
+ item.isFailed ? (
392
+ <AlertIcon
393
+ width={18}
394
+ height={18}
395
+ style={{ color: '#FF9592' }}
396
+ />
397
+ ) : undefined
398
+ }
399
+ actions={
400
+ item.isFailed ? (
401
+ <IconButton
402
+ variant="ghost"
403
+ size="1"
404
+ color="neutral"
405
+ onClick={(e) => {
406
+ e.stopPropagation()
407
+ console.log('Delete clicked for', item.name)
408
+ }}
409
+ >
410
+ <TrashIcon width={16} height={16} />
411
+ </IconButton>
412
+ ) : (
413
+ <DropdownMenu
414
+ trigger={<MoreButton />}
415
+ options={menuOptions}
416
+ />
417
+ )
418
+ }
419
+ >
420
+ <Text
421
+ as="div"
422
+ size="1"
423
+ style={item.isFailed ? { color: '#FF9592' } : undefined}
424
+ color={item.isFailed ? undefined : 'gray'}
425
+ >
426
+ {item.description}
427
+ </Text>
428
+ </ListCards.CardDetails>
429
+ ))}
430
+ </ListCards>
431
+ </Flex>
432
+ )
433
+ },
434
+ }
435
+
312
436
  export const WithSizes = {
313
437
  render: (args) => {
314
438
  const [selectedId1, setSelectedId1] = useState(null)
@@ -9,10 +9,8 @@
9
9
  background: transparent;
10
10
  border-radius: 9999px;
11
11
  cursor: pointer;
12
- color: var(--neutral-alpha-7);
13
- transition:
14
- background-color 0.15s ease,
15
- color 0.15s ease;
12
+ color: var(--neutral-11);
13
+ transition: color 0.15s ease;
16
14
  }
17
15
 
18
16
  @media (pointer: coarse) {
@@ -27,8 +25,7 @@
27
25
 
28
26
  .MoreButton:hover,
29
27
  .MoreButton.hovered {
30
- background-color: var(--neutral-alpha-3);
31
- color: var(--neutral-alpha-11);
28
+ color: var(--neutral-12);
32
29
  }
33
30
 
34
31
  .MoreButton:focus-visible {