@spunto/design-system 0.14.0 → 0.14.2

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": "@spunto/design-system",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "description": "Spunto's shared design system — warm/flame tokens, color constants, and UI primitives.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -24,6 +24,7 @@ export interface TagChipsProps {
24
24
  onRemove?: (tag: string, next: string[]) => void
25
25
  /** Longest accepted tag; anything past it is truncated on commit. */
26
26
  maxLength?: number
27
+ /** Posée sur le GROUPE (les chips et leur bouton « + »), pas sur chaque chip. */
27
28
  className?: string
28
29
  }
29
30
 
@@ -66,7 +67,11 @@ export function TagChips({ tags, onAdd, onRemove, maxLength = 32, className }: T
66
67
  if (!shown.length && !editable) return null
67
68
 
68
69
  return (
69
- <>
70
+ // Les chips ET le bouton « + » forment UNE unité de retour à la ligne. Sur
71
+ // une carte étroite (grille à trois colonnes, téléphone), l'en-tête wrappe —
72
+ // et laissé libre, c'est le « + » qui atterrit seul sur la ligne suivante
73
+ // sous une première ligne pleine. Groupé, il emmène les tags avec lui.
74
+ <span data-slot="tag-chips" className={cn("inline-flex flex-wrap items-center gap-2", className)}>
70
75
  {shown.map((tag) => {
71
76
  const c = tagColor(tag)
72
77
  return (
@@ -76,8 +81,7 @@ export function TagChips({ tags, onAdd, onRemove, maxLength = 32, className }: T
76
81
  "inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[10px] font-medium leading-none",
77
82
  c.bg,
78
83
  c.text,
79
- c.border,
80
- className
84
+ c.border
81
85
  )}
82
86
  >
83
87
  {tag}
@@ -134,6 +138,6 @@ export function TagChips({ tags, onAdd, onRemove, maxLength = 32, className }: T
134
138
  <PlusIcon className="h-2.5 w-2.5" />
135
139
  </button>
136
140
  ))}
137
- </>
141
+ </span>
138
142
  )
139
143
  }
@@ -149,7 +149,13 @@ export function WorkerCard({
149
149
  // full-width row on a phone — and a 290 px card in a sidebar on a 27"
150
150
  // screen is exactly as cramped as a phone.
151
151
  className={cn(
152
- "@container overflow-hidden rounded-xl border border-border bg-card transition-colors hover:shadow-sm",
152
+ // `flex h-full flex-col`, avec le pied en `mt-auto` : dans une grille de
153
+ // cartes, les cellules s'étirent sur la plus haute, et sans ça le bouton
154
+ // s'arrête là où le contenu s'arrête — une rangée de cartes finit avec
155
+ // des bandes de carte vide sous les boutons, à des hauteurs différentes.
156
+ // Hors grille, `height: 100%` d'un parent en hauteur automatique se
157
+ // résout en automatique : rien ne change.
158
+ "@container flex h-full flex-col overflow-hidden rounded-xl border border-border bg-card transition-colors hover:shadow-sm",
153
159
  className
154
160
  )}
155
161
  >
@@ -172,27 +178,28 @@ export function WorkerCard({
172
178
  <TagChips tags={worker.tags ?? []} onAdd={onAddTag} onRemove={onRemoveTag} />
173
179
  </div>
174
180
 
175
- {/* Meta line. Each item carries its own leading separator instead of
176
- the separators being siblings: this row wraps onto two lines as
177
- soon as the card is narrow, and a sibling "·" then ends up
178
- stranded at the end of a line, pointing at nothing. Attached to
179
- the item, the worst case is a line that *starts* with "·", which
180
- reads as a continuation. */}
181
- <div className="mt-1.5 flex flex-wrap items-center gap-x-2 gap-y-1">
181
+ {/* Meta line, sans « · » entre les items : cette ligne wrappe dès que
182
+ la carte est étroite (grilles à deux ou trois colonnes,
183
+ téléphone), et un séparateur est un enfant flex comme un autre —
184
+ il wrappe comme un autre, donc la ligne du dessus se termine sur
185
+ un point suspendu dans le vide. Chaque item après l'auteur porte
186
+ sa propre icône, qui les sépare bien assez ; l'espacement fait le
187
+ reste. */}
188
+ <div className="mt-1.5 flex flex-wrap items-center gap-x-3 gap-y-1">
182
189
  {creator && (
183
- <MetaItem first>
190
+ <MetaItem>
184
191
  <CreatorAvatar creator={creator} />
185
192
  <span className="text-muted-foreground">{creator.name}</span>
186
193
  </MetaItem>
187
194
  )}
188
195
  {nodeName && (
189
- <MetaItem first={!creator}>
196
+ <MetaItem>
190
197
  <ServerIcon className="h-3 w-3 shrink-0" />
191
198
  <span className="truncate">{nodeName}</span>
192
199
  </MetaItem>
193
200
  )}
194
201
  {worker.createdAt && (
195
- <MetaItem first={!creator && !nodeName} title={new Date(worker.createdAt).toLocaleString()}>
202
+ <MetaItem title={new Date(worker.createdAt).toLocaleString()}>
196
203
  <ClockIcon className="h-3 w-3 shrink-0" />
197
204
  {formatRelativeTime(worker.createdAt)}
198
205
  </MetaItem>
@@ -280,7 +287,7 @@ export function WorkerCard({
280
287
  )}
281
288
 
282
289
  {(footer ?? href) && (
283
- <div className="border-t border-border/50 bg-muted/20 px-3 py-2">
290
+ <div className="mt-auto border-t border-border/50 bg-muted/20 px-3 py-2">
284
291
  {footer ?? (
285
292
  <Link href={href!} className={cn(buttonVariants({ variant: "default", size: "sm" }), "h-7 w-full gap-1.5 text-xs")}>
286
293
  {viewLabel}
@@ -301,24 +308,9 @@ export function WorkerCard({
301
308
  * entirely: under ~26 rem the row is two lines deep anyway and the icons already tell
302
309
  * the items apart, so the dots are pure noise there.
303
310
  */
304
- function MetaItem({
305
- first = false,
306
- title,
307
- children,
308
- }: {
309
- first?: boolean
310
- title?: string
311
- children: ReactNode
312
- }) {
311
+ function MetaItem({ title, children }: { title?: string; children: ReactNode }) {
313
312
  return (
314
- <span
315
- title={title}
316
- className={cn(
317
- "flex min-w-0 items-center gap-1 text-[11px] text-muted-foreground/60",
318
- !first &&
319
- "before:hidden before:text-muted-foreground/30 before:content-['·'] @min-[26rem]:before:mr-1 @min-[26rem]:before:inline"
320
- )}
321
- >
313
+ <span title={title} className="flex min-w-0 items-center gap-1 text-[11px] text-muted-foreground/60">
322
314
  {children}
323
315
  </span>
324
316
  )