@bagelink/vue 1.15.129 → 1.15.133

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,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "1.15.129",
4
+ "version": "1.15.133",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Bagel Studio",
@@ -164,12 +164,14 @@ const hasFooter = computed<boolean>(() =>
164
164
  border: 1px solid var(--bgl-border-color);
165
165
  }
166
166
 
167
- /* Header row (title + action). Pulls out to the card edges via negative margins
168
- so its divider spans full-width regardless of the card's own padding, then
169
- restores breathing room below. On a p-0 card the negative margins resolve to 0. */
167
+ /* Header row (title + action). Content stays aligned with the card's own inline
168
+ padding no horizontal margin/padding of its own. Only the bottom border is
169
+ pulled full-bleed (via negative inline margins matched by equal padding) so the
170
+ divider spans edge-to-edge while the content stays put. Bottom padding scales
171
+ with the card so `thin`/`p-0` stay consistent with the rest of the card. */
170
172
  .card_header {
171
- margin: calc(var(--bgl-card-pad) * -1) calc(var(--bgl-card-pad) * -1) var(--bgl-card-pad);
172
- padding: 0.85rem var(--bgl-card-pad);
173
+ padding-bottom: calc(var(--bgl-card-pad) / 2);
174
+ margin-bottom: calc(var(--bgl-card-pad) / 2);
173
175
  border-bottom: 1px solid var(--bgl-border-color);
174
176
  min-height: 0;
175
177
  }
@@ -181,11 +183,13 @@ min-width: 0;
181
183
  font-weight: 600;
182
184
  }
183
185
 
184
- /* Footer row: mirrors the header — full-bleed divider via negative margins,
185
- border on top instead of bottom. */
186
+ /* Footer row: mirrors the header — content aligned to the card's inline padding,
187
+ only the top border pulled full-bleed. */
186
188
  .card_footer {
187
- margin: var(--bgl-card-pad) calc(var(--bgl-card-pad) * -1) calc(var(--bgl-card-pad) * -1);
188
- padding: 0.85rem var(--bgl-card-pad);
189
+ margin-inline: calc(var(--bgl-card-pad) * -1);
190
+ padding-inline: var(--bgl-card-pad);
191
+ padding-top: var(--bgl-card-pad);
192
+ margin-top: var(--bgl-card-pad);
189
193
  border-top: 1px solid var(--bgl-border-color);
190
194
  min-height: 0;
191
195
  }
@@ -206,9 +210,16 @@ background: var(--bgl-gray-tint);
206
210
  --bgl-card-pad: 1rem;
207
211
  padding: var(--bgl-card-pad);
208
212
  }
209
- /* When padding is stripped via the p-0 utility, the header supplies its own. */
213
+ /* When padding is stripped via the p-0 utility, the card has no inset for the
214
+ header/footer to inherit, so they supply their own inline+block padding and
215
+ drop the full-bleed margins (there's nothing to bleed into). */
210
216
  .bgl_card.p-0 { --bgl-card-pad: 0rem; }
211
- .bgl_card.p-0 .card_header { padding-inline: 1rem; padding-block: 0.75rem; margin-bottom: 0; }
217
+ .bgl_card.p-0 .card_header {
218
+ margin-inline: 0; padding-inline: 1rem; padding-block: 0.75rem; margin-bottom: 0;
219
+ }
220
+ .bgl_card.p-0 .card_footer {
221
+ margin-inline: 0; padding-inline: 1rem; padding-block: 0.75rem; margin-top: 0;
222
+ }
212
223
  .bgl_card.p-0 .card_label { padding-inline: 1rem; padding-top: 0.75rem; }
213
224
 
214
225
  .bgl_card.BagelTable {
@@ -21,6 +21,15 @@ const props = withDefaults(
21
21
  iconEnd?: IconType
22
22
  target?: '_blank' | '_self'
23
23
  thin?: boolean
24
+ /** Row size — scales text, leading icon-chip/avatar, and vertical padding.
25
+ Mirrors `Btn` (`size` prop or the boolean shorthands below). Default `md`. */
26
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
27
+ /** Boolean size shorthands: `<ListItem sm … />` (same scale as Btn). */
28
+ xs?: boolean
29
+ sm?: boolean
30
+ md?: boolean
31
+ lg?: boolean
32
+ xl?: boolean
24
33
  fullWidth?: boolean
25
34
  ellipsis?: boolean
26
35
  ripple?: boolean
@@ -63,6 +72,29 @@ const rootAttrs = computed(() => {
63
72
  return out
64
73
  })
65
74
 
75
+ // Resolve the effective size from the `size` prop or a boolean shorthand
76
+ // (mirrors Btn). `undefined` → the default `md` visuals (no size class emitted).
77
+ const computedSize = computed(() => {
78
+ if (props.size) { return props.size }
79
+ if (props.xs) { return 'xs' }
80
+ if (props.sm) { return 'sm' }
81
+ if (props.md) { return 'md' }
82
+ if (props.lg) { return 'lg' }
83
+ if (props.xl) { return 'xl' }
84
+ return undefined
85
+ })
86
+
87
+ // Avatar/icon glyph scale per size. When no size is given, preserve the historical
88
+ // behavior (thin → 30px avatar, else 38px; 1.2rem icon glyph).
89
+ const avatarSizeMap = { xs: 20, sm: 24, md: 38, lg: 46, xl: 56 } as const
90
+ const iconSizeMap = { xs: 0.8, sm: 0.9, md: 1.2, lg: 1.5, xl: 1.8 } as const
91
+ const avatarSize = computed(() =>
92
+ computedSize.value ? avatarSizeMap[computedSize.value] : (props.thin ? 30 : 38),
93
+ )
94
+ const iconSize = computed(() =>
95
+ computedSize.value ? iconSizeMap[computedSize.value] : 1.2,
96
+ )
97
+
66
98
  const hasTo = computed(() => props.to !== undefined && props.to !== '')
67
99
  const hasHref = computed(() => props.href !== undefined && props.href !== '')
68
100
  // A `@click` listener (with or without modifiers like `.stop`) shows up in
@@ -100,7 +132,10 @@ const bind = computed(() => {
100
132
  <div
101
133
  v-bind="rootAttrs"
102
134
  class="flex space-between list-item-row bg"
103
- :class="{ 'no-border-list': props.flat || rounded, 'list-item-flush': props.fullWidth, 'list-item-fullrow': isClickable, 'list-item-rounded': rounded, 'list-item-active': active }"
135
+ :class="[
136
+ { 'no-border-list': props.flat || rounded, 'list-item-flush': props.fullWidth, 'list-item-fullrow': isClickable, 'list-item-rounded': rounded, 'list-item-active': active },
137
+ computedSize ? `list-item-${computedSize}` : '',
138
+ ]"
104
139
  :style="color ? { '--bgl-list-item-accent': `var(--bgl-${color})` } : undefined"
105
140
  >
106
141
  <!-- Content rendered before the clickable area (e.g. a drag handle, avatar
@@ -119,9 +154,9 @@ const bind = computed(() => {
119
154
  <!-- Leading visual INSIDE the clickable area. Use #media for custom art
120
155
  (covers, thumbnails); `src`/`showAvatar` and `icon` are shortcuts. -->
121
156
  <slot name="media">
122
- <Avatar v-if="src || showAvatar" :name="title" :src="src" :size="thin ? 30 : 38" class="flex-shrink-0" />
157
+ <Avatar v-if="src || showAvatar" :name="title" :src="src" :size="avatarSize" class="flex-shrink-0" />
123
158
  <span v-if="icon" class="list-item-icon flex-shrink-0">
124
- <Icon size="1.2" :icon="icon" />
159
+ <Icon :size="iconSize" :icon="icon" />
125
160
  </span>
126
161
  </slot>
127
162
 
@@ -333,4 +368,34 @@ white-space: nowrap;
333
368
  }
334
369
  .list-item-end:empty { display: none; }
335
370
 
371
+ /* ── Size scale (mirrors Btn: xs · sm · md · lg · xl) ──────────────────────────
372
+ Each size scales the leading icon-chip, the title/subtitle/lead type, and the
373
+ row's vertical padding + horizontal gutter. `md` matches the historical
374
+ defaults, so unsized rows are unchanged. `size` composes with `thin` (which
375
+ only trims vertical padding). */
376
+ .list-item-xs { --list-item-padding-inline: 0.4rem; }
377
+ /* !important needed to beat the base .py-075/.py-05 utility classes. */
378
+ .list-item-xs .list-item { padding-block: 0.1rem !important; gap: 0.4rem; }
379
+ .list-item-xs .list-item-icon { width: 22px; height: 22px; border-radius: 6px; }
380
+ .list-item-xs .list-item-title { font-size: 0.75rem; }
381
+ .list-item-xs .list-item-subtitle { font-size: 0.625rem; }
382
+
383
+ .list-item-sm { --list-item-padding-inline: 0.55rem; }
384
+ .list-item-sm .list-item { padding-block: 0.2rem !important; gap: 0.5rem; }
385
+ .list-item-sm .list-item-icon { width: 26px; height: 26px; border-radius: 7px; }
386
+ .list-item-sm .list-item-title { font-size: 0.8125rem; }
387
+ .list-item-sm .list-item-subtitle { font-size: 0.6875rem; }
388
+
389
+ /* md = defaults (no overrides needed). */
390
+
391
+ .list-item-lg .list-item { padding-block: 0.85rem !important; gap: 0.85rem; }
392
+ .list-item-lg .list-item-icon { width: 42px; height: 42px; border-radius: 11px; }
393
+ .list-item-lg .list-item-title { font-size: 1.0625rem; }
394
+ .list-item-lg .list-item-subtitle { font-size: 0.875rem; }
395
+
396
+ .list-item-xl .list-item { padding-block: 1.1rem !important; gap: 1rem; }
397
+ .list-item-xl .list-item-icon { width: 50px; height: 50px; border-radius: 13px; }
398
+ .list-item-xl .list-item-title { font-size: 1.1875rem; }
399
+ .list-item-xl .list-item-subtitle { font-size: 0.9375rem; }
400
+
336
401
  </style>