@r2digisolutions/components 0.19.3 → 0.19.4
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.
|
@@ -17,15 +17,19 @@
|
|
|
17
17
|
categoryLabel?: string;
|
|
18
18
|
installed?: boolean;
|
|
19
19
|
/**
|
|
20
|
-
* Estado legible en el listado (p. ej. «
|
|
21
|
-
* Si no se pasa y `installed`, se usa «
|
|
20
|
+
* Estado legible en el listado (p. ej. «Activo», «En licencia», «No incluido»).
|
|
21
|
+
* Si no se pasa y `installed`, se usa «Activo».
|
|
22
22
|
*/
|
|
23
23
|
statusLabel?: string;
|
|
24
24
|
/** landscape promotional card */
|
|
25
25
|
featured?: boolean;
|
|
26
|
+
/** Compact row for list view (ignored when featured). */
|
|
27
|
+
layout?: 'grid' | 'list';
|
|
26
28
|
tags?: StoreProductTag[];
|
|
27
29
|
icon: Component;
|
|
28
30
|
accentClass?: string;
|
|
31
|
+
/** Prefer link navigation when set (store detail URLs). */
|
|
32
|
+
href?: string;
|
|
29
33
|
onclick?: () => void;
|
|
30
34
|
/** Optional custom badge area */
|
|
31
35
|
badge?: Snippet;
|
|
@@ -39,9 +43,11 @@
|
|
|
39
43
|
installed = false,
|
|
40
44
|
statusLabel = '',
|
|
41
45
|
featured = false,
|
|
46
|
+
layout = 'grid',
|
|
42
47
|
tags = [],
|
|
43
48
|
icon: Icon,
|
|
44
49
|
accentClass = 'from-neutral-800 to-neutral-600',
|
|
50
|
+
href = '',
|
|
45
51
|
onclick,
|
|
46
52
|
badge
|
|
47
53
|
}: Props = $props();
|
|
@@ -58,13 +64,24 @@
|
|
|
58
64
|
);
|
|
59
65
|
|
|
60
66
|
const resolvedStatus = $derived(
|
|
61
|
-
statusLabel.trim() || (installed ? '
|
|
67
|
+
statusLabel.trim() || (installed ? 'Activo' : '')
|
|
68
|
+
);
|
|
69
|
+
const statusToneOk = $derived(
|
|
70
|
+
installed || resolvedStatus === 'Activo' || resolvedStatus === 'Instalado'
|
|
71
|
+
);
|
|
72
|
+
const isList = $derived(!featured && layout === 'list');
|
|
73
|
+
const rootClass = $derived(
|
|
74
|
+
[
|
|
75
|
+
'group ms-tile',
|
|
76
|
+
featured && 'ms-tile--featured',
|
|
77
|
+
isList && 'ms-tile--list'
|
|
78
|
+
]
|
|
79
|
+
.filter(Boolean)
|
|
80
|
+
.join(' ')
|
|
62
81
|
);
|
|
63
|
-
const statusToneOk = $derived(installed || resolvedStatus === 'Instalado');
|
|
64
82
|
|
|
65
83
|
function tagVariant(tag: StoreProductTag): 'info' | 'warning' | 'default' {
|
|
66
84
|
if (tag === 'new') return 'info';
|
|
67
|
-
// Featured uses custom amber + white via tagClass (avoid warning’s amber text).
|
|
68
85
|
if (tag === 'featured') return 'default';
|
|
69
86
|
return 'default';
|
|
70
87
|
}
|
|
@@ -78,14 +95,15 @@
|
|
|
78
95
|
}
|
|
79
96
|
return '';
|
|
80
97
|
}
|
|
98
|
+
|
|
99
|
+
function onActivate(e: MouseEvent) {
|
|
100
|
+
if (href) return;
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
onclick?.();
|
|
103
|
+
}
|
|
81
104
|
</script>
|
|
82
105
|
|
|
83
|
-
|
|
84
|
-
type="button"
|
|
85
|
-
class="group ms-tile"
|
|
86
|
-
class:ms-tile--featured={featured}
|
|
87
|
-
{onclick}
|
|
88
|
-
>
|
|
106
|
+
{#snippet body()}
|
|
89
107
|
{#if featured}
|
|
90
108
|
<div class="ms-tile__promo bg-gradient-to-br {accentClass}">
|
|
91
109
|
<div class="ms-tile__promo-mesh" aria-hidden="true"></div>
|
|
@@ -127,6 +145,41 @@
|
|
|
127
145
|
<Icon class="size-10 text-white drop-shadow" />
|
|
128
146
|
</div>
|
|
129
147
|
</div>
|
|
148
|
+
{:else if isList}
|
|
149
|
+
<div class="ms-tile__list-icon bg-gradient-to-br {accentClass}">
|
|
150
|
+
<div class="ms-tile__icon-shine" aria-hidden="true"></div>
|
|
151
|
+
<Icon class="relative size-7 text-white drop-shadow-sm" />
|
|
152
|
+
</div>
|
|
153
|
+
<div class="ms-tile__list-body">
|
|
154
|
+
<div class="ms-tile__list-top">
|
|
155
|
+
<span class="ms-tile__name">{name}</span>
|
|
156
|
+
{#if resolvedStatus}
|
|
157
|
+
<Badge variant={statusToneOk ? 'success' : 'secondary'} size="sm">
|
|
158
|
+
{resolvedStatus}
|
|
159
|
+
</Badge>
|
|
160
|
+
{:else if displayTags[0]}
|
|
161
|
+
<Badge
|
|
162
|
+
variant={tagVariant(displayTags[0])}
|
|
163
|
+
size="sm"
|
|
164
|
+
class={tagClass(displayTags[0])}
|
|
165
|
+
>
|
|
166
|
+
{TAG_LABELS[displayTags[0]]}
|
|
167
|
+
</Badge>
|
|
168
|
+
{/if}
|
|
169
|
+
</div>
|
|
170
|
+
{#if description}
|
|
171
|
+
<span class="ms-tile__list-desc">{description}</span>
|
|
172
|
+
{/if}
|
|
173
|
+
<div class="ms-tile__list-meta">
|
|
174
|
+
{#if categoryLabel}
|
|
175
|
+
<span>{categoryLabel}</span>
|
|
176
|
+
<span aria-hidden="true">·</span>
|
|
177
|
+
{/if}
|
|
178
|
+
<span class="ms-tile__price">{priceLabel}</span>
|
|
179
|
+
<span aria-hidden="true">·</span>
|
|
180
|
+
<span class="ms-tile__publisher">Evoteg</span>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
130
183
|
{:else}
|
|
131
184
|
<div class="ms-tile__icon-shell">
|
|
132
185
|
<div class="ms-tile__icon bg-gradient-to-br {accentClass}">
|
|
@@ -135,7 +188,7 @@
|
|
|
135
188
|
</div>
|
|
136
189
|
{#if statusToneOk}
|
|
137
190
|
<span class="ms-tile__corner">
|
|
138
|
-
<Badge variant="success" size="sm">{resolvedStatus || '
|
|
191
|
+
<Badge variant="success" size="sm">{resolvedStatus || 'Activo'}</Badge>
|
|
139
192
|
</span>
|
|
140
193
|
{:else if displayTags[0]}
|
|
141
194
|
<span class="ms-tile__corner">
|
|
@@ -167,7 +220,17 @@
|
|
|
167
220
|
<span class="ms-tile__price">{priceLabel}</span>
|
|
168
221
|
</div>
|
|
169
222
|
{/if}
|
|
170
|
-
|
|
223
|
+
{/snippet}
|
|
224
|
+
|
|
225
|
+
{#if href}
|
|
226
|
+
<a class={rootClass} {href} data-sveltekit-preload-data="hover">
|
|
227
|
+
{@render body()}
|
|
228
|
+
</a>
|
|
229
|
+
{:else}
|
|
230
|
+
<button type="button" class={rootClass} onclick={onActivate}>
|
|
231
|
+
{@render body()}
|
|
232
|
+
</button>
|
|
233
|
+
{/if}
|
|
171
234
|
|
|
172
235
|
<style>
|
|
173
236
|
.ms-tile {
|
|
@@ -182,6 +245,8 @@
|
|
|
182
245
|
padding: 0;
|
|
183
246
|
cursor: pointer;
|
|
184
247
|
border-radius: 1rem;
|
|
248
|
+
text-decoration: none;
|
|
249
|
+
color: inherit;
|
|
185
250
|
transition:
|
|
186
251
|
transform 200ms cubic-bezier(0.22, 1, 0.36, 1),
|
|
187
252
|
filter 200ms ease;
|
|
@@ -193,6 +258,71 @@
|
|
|
193
258
|
outline: 2px solid var(--color-brand-500, #2563eb);
|
|
194
259
|
outline-offset: 4px;
|
|
195
260
|
}
|
|
261
|
+
.ms-tile--list {
|
|
262
|
+
flex-direction: row;
|
|
263
|
+
align-items: center;
|
|
264
|
+
gap: 0.9rem;
|
|
265
|
+
padding: 0.75rem 0.85rem;
|
|
266
|
+
border-radius: 1rem;
|
|
267
|
+
background: rgb(255 255 255 / 0.78);
|
|
268
|
+
border: 1px solid rgb(0 0 0 / 0.06);
|
|
269
|
+
box-shadow: 0 6px 18px rgb(0 0 0 / 0.04);
|
|
270
|
+
}
|
|
271
|
+
.ms-tile--list:hover {
|
|
272
|
+
transform: translateY(-1px);
|
|
273
|
+
border-color: rgb(0 0 0 / 0.1);
|
|
274
|
+
}
|
|
275
|
+
:global(.dark) .ms-tile--list {
|
|
276
|
+
background: rgb(23 23 23 / 0.88);
|
|
277
|
+
border-color: rgb(255 255 255 / 0.06);
|
|
278
|
+
}
|
|
279
|
+
.ms-tile__list-icon {
|
|
280
|
+
position: relative;
|
|
281
|
+
display: grid;
|
|
282
|
+
place-items: center;
|
|
283
|
+
width: 3.25rem;
|
|
284
|
+
height: 3.25rem;
|
|
285
|
+
border-radius: 22%;
|
|
286
|
+
flex-shrink: 0;
|
|
287
|
+
overflow: hidden;
|
|
288
|
+
box-shadow:
|
|
289
|
+
0 8px 18px rgb(0 0 0 / 0.2),
|
|
290
|
+
0 1px 0 rgb(255 255 255 / 0.2) inset;
|
|
291
|
+
}
|
|
292
|
+
.ms-tile__list-body {
|
|
293
|
+
min-width: 0;
|
|
294
|
+
flex: 1;
|
|
295
|
+
display: flex;
|
|
296
|
+
flex-direction: column;
|
|
297
|
+
gap: 0.2rem;
|
|
298
|
+
}
|
|
299
|
+
.ms-tile__list-top {
|
|
300
|
+
display: flex;
|
|
301
|
+
align-items: center;
|
|
302
|
+
justify-content: space-between;
|
|
303
|
+
gap: 0.75rem;
|
|
304
|
+
}
|
|
305
|
+
.ms-tile__list-desc {
|
|
306
|
+
font-size: 0.8rem;
|
|
307
|
+
line-height: 1.35;
|
|
308
|
+
color: var(--color-neutral-600, #525252);
|
|
309
|
+
display: -webkit-box;
|
|
310
|
+
-webkit-line-clamp: 1;
|
|
311
|
+
line-clamp: 1;
|
|
312
|
+
-webkit-box-orient: vertical;
|
|
313
|
+
overflow: hidden;
|
|
314
|
+
}
|
|
315
|
+
:global(.dark) .ms-tile__list-desc {
|
|
316
|
+
color: var(--color-neutral-400, #a3a3a3);
|
|
317
|
+
}
|
|
318
|
+
.ms-tile__list-meta {
|
|
319
|
+
display: flex;
|
|
320
|
+
flex-wrap: wrap;
|
|
321
|
+
align-items: center;
|
|
322
|
+
gap: 0.35rem;
|
|
323
|
+
font-size: 0.75rem;
|
|
324
|
+
color: var(--color-neutral-500, #737373);
|
|
325
|
+
}
|
|
196
326
|
.ms-tile__icon-shell {
|
|
197
327
|
position: relative;
|
|
198
328
|
width: 100%;
|
|
@@ -7,15 +7,19 @@ type Props = {
|
|
|
7
7
|
categoryLabel?: string;
|
|
8
8
|
installed?: boolean;
|
|
9
9
|
/**
|
|
10
|
-
* Estado legible en el listado (p. ej. «
|
|
11
|
-
* Si no se pasa y `installed`, se usa «
|
|
10
|
+
* Estado legible en el listado (p. ej. «Activo», «En licencia», «No incluido»).
|
|
11
|
+
* Si no se pasa y `installed`, se usa «Activo».
|
|
12
12
|
*/
|
|
13
13
|
statusLabel?: string;
|
|
14
14
|
/** landscape promotional card */
|
|
15
15
|
featured?: boolean;
|
|
16
|
+
/** Compact row for list view (ignored when featured). */
|
|
17
|
+
layout?: 'grid' | 'list';
|
|
16
18
|
tags?: StoreProductTag[];
|
|
17
19
|
icon: Component;
|
|
18
20
|
accentClass?: string;
|
|
21
|
+
/** Prefer link navigation when set (store detail URLs). */
|
|
22
|
+
href?: string;
|
|
19
23
|
onclick?: () => void;
|
|
20
24
|
/** Optional custom badge area */
|
|
21
25
|
badge?: Snippet;
|