@makolabs/ripple 3.0.2 → 3.0.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.
- package/dist/ai/ai-types.d.ts +7 -0
- package/dist/charts/Chart.svelte +18 -37
- package/dist/charts/chart-types.d.ts +7 -0
- package/dist/drawer/Drawer.svelte +29 -36
- package/dist/drawer/drawer.js +2 -2
- package/dist/elements/combobox/ComboBox.svelte +6 -6
- package/dist/elements/dropdown/Select.svelte +6 -8
- package/dist/elements/popover/Popover.svelte +1 -1
- package/dist/elements/progress/Progress.svelte +18 -5
- package/dist/elements/progress/progress-types.d.ts +8 -0
- package/dist/file-browser/FileBrowser.svelte +6 -3
- package/dist/filters/CompactFilters.svelte +78 -68
- package/dist/filters/filter-types.d.ts +11 -0
- package/dist/forms/DateRange.svelte +31 -20
- package/dist/forms/NumberInput.svelte +6 -2
- package/dist/forms/Tags.svelte +9 -4
- package/dist/forms/Toggle.svelte +8 -6
- package/dist/forms/calendar/Calendar.svelte +8 -2
- package/dist/forms/calendar/calendar-types.d.ts +9 -0
- package/dist/forms/date-picker/DatePicker.svelte +8 -1
- package/dist/forms/form-types.d.ts +23 -0
- package/dist/forms/month-picker/MonthPicker.svelte +12 -3
- package/dist/forms/month-picker/month-picker-types.d.ts +7 -0
- package/dist/header/Breadcrumbs.svelte +19 -5
- package/dist/header/header-types.d.ts +7 -0
- package/dist/layout/activity-list/ActivityList.svelte +29 -7
- package/dist/layout/activity-list/activity-list-types.d.ts +8 -0
- package/dist/layout/card/MetricCard.svelte +34 -8
- package/dist/layout/card/RankedCard.svelte +34 -10
- package/dist/layout/card/card-types.d.ts +8 -0
- package/dist/layout/card/ranked-card.d.ts +10 -0
- package/dist/layout/table/Table.svelte +5 -0
- package/dist/layout/table/table-types.d.ts +8 -0
- package/dist/modal/modal.js +4 -4
- package/dist/pipeline/Pipeline.svelte +7 -3
- package/dist/pipeline/pipeline-types.d.ts +6 -0
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { cn } from '../../helper/cls.js';
|
|
3
|
+
import { buildTestId } from '../../helper/testid.js';
|
|
3
4
|
import { metricCard } from './metric-card.js';
|
|
4
5
|
import type { MetricCardProps } from '../../index.js';
|
|
5
6
|
import Progress from '../../elements/progress/Progress.svelte';
|
|
@@ -16,7 +17,8 @@
|
|
|
16
17
|
onclick,
|
|
17
18
|
action,
|
|
18
19
|
actionHover,
|
|
19
|
-
loading = false
|
|
20
|
+
loading = false,
|
|
21
|
+
testId
|
|
20
22
|
}: MetricCardProps = $props();
|
|
21
23
|
|
|
22
24
|
const interactive = $derived(!!onclick);
|
|
@@ -54,6 +56,7 @@
|
|
|
54
56
|
<span
|
|
55
57
|
class={cn(actionSlot(), hasHoverSwap && 'group-hover:opacity-0')}
|
|
56
58
|
data-metric-card-action=""
|
|
59
|
+
data-testid={buildTestId('metric-card', 'action', testId)}
|
|
57
60
|
aria-hidden="true"
|
|
58
61
|
>
|
|
59
62
|
{#if action}
|
|
@@ -90,17 +93,24 @@
|
|
|
90
93
|
</div>
|
|
91
94
|
{:else}
|
|
92
95
|
{#if title}
|
|
93
|
-
<div class={titleSlot()}
|
|
96
|
+
<div class={titleSlot()} data-testid={buildTestId('metric-card', 'label', testId)}>
|
|
97
|
+
{title}
|
|
98
|
+
</div>
|
|
94
99
|
{/if}
|
|
95
100
|
|
|
96
101
|
{#if value !== undefined}
|
|
97
|
-
<div class={valueSlot()}
|
|
102
|
+
<div class={valueSlot()} data-testid={buildTestId('metric-card', 'value', testId)}>
|
|
103
|
+
{value}
|
|
104
|
+
</div>
|
|
98
105
|
{/if}
|
|
99
106
|
|
|
100
107
|
{#if details.length > 0}
|
|
101
108
|
<div class={detailSlot()}>
|
|
102
109
|
{#each details as detail, index (detail.label + index)}
|
|
103
|
-
<div
|
|
110
|
+
<div
|
|
111
|
+
class="flex justify-between text-xs"
|
|
112
|
+
data-testid={buildTestId('metric-card', 'detail', testId, index)}
|
|
113
|
+
>
|
|
104
114
|
<span class="text-default-500">{detail.label}</span>
|
|
105
115
|
<span class="font-medium {detail.color || 'text-default-900'}">{detail.value}</span>
|
|
106
116
|
</div>
|
|
@@ -109,7 +119,10 @@
|
|
|
109
119
|
{/if}
|
|
110
120
|
|
|
111
121
|
{#if segments}
|
|
112
|
-
<div
|
|
122
|
+
<div
|
|
123
|
+
class={cn(progressSlot(), 'pt-2')}
|
|
124
|
+
data-testid={buildTestId('metric-card', 'trend', testId)}
|
|
125
|
+
>
|
|
113
126
|
<Progress
|
|
114
127
|
value={0}
|
|
115
128
|
{segments}
|
|
@@ -120,7 +133,10 @@
|
|
|
120
133
|
/>
|
|
121
134
|
</div>
|
|
122
135
|
{:else if percent !== undefined}
|
|
123
|
-
<div
|
|
136
|
+
<div
|
|
137
|
+
class={cn(progressSlot(), 'pt-2')}
|
|
138
|
+
data-testid={buildTestId('metric-card', 'trend', testId)}
|
|
139
|
+
>
|
|
124
140
|
<Progress value={percent} size={Size.SM} color={Color.SUCCESS} showLabel={false} />
|
|
125
141
|
</div>
|
|
126
142
|
{/if}
|
|
@@ -128,11 +144,21 @@
|
|
|
128
144
|
{/snippet}
|
|
129
145
|
|
|
130
146
|
{#if interactive}
|
|
131
|
-
<button
|
|
147
|
+
<button
|
|
148
|
+
type="button"
|
|
149
|
+
class={baseClass}
|
|
150
|
+
data-metric-card=""
|
|
151
|
+
data-testid={buildTestId('metric-card', undefined, testId)}
|
|
152
|
+
onclick={handleClick}
|
|
153
|
+
>
|
|
132
154
|
{@render body()}
|
|
133
155
|
</button>
|
|
134
156
|
{:else}
|
|
135
|
-
<div
|
|
157
|
+
<div
|
|
158
|
+
class={baseClass}
|
|
159
|
+
data-metric-card=""
|
|
160
|
+
data-testid={buildTestId('metric-card', undefined, testId)}
|
|
161
|
+
>
|
|
136
162
|
{@render body()}
|
|
137
163
|
</div>
|
|
138
164
|
{/if}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { cn } from '../../helper/cls.js';
|
|
3
|
+
import { buildTestId } from '../../helper/testid.js';
|
|
3
4
|
import { rankedCard, type RankedCardProps } from './ranked-card.js';
|
|
4
5
|
|
|
5
|
-
let { items, columns = 3, class: className = '' }: RankedCardProps = $props();
|
|
6
|
+
let { items, columns = 3, class: className = '', testId }: RankedCardProps = $props();
|
|
6
7
|
|
|
7
8
|
const {
|
|
8
9
|
container,
|
|
@@ -22,28 +23,51 @@
|
|
|
22
23
|
const containerClass = $derived(cn(container(), className));
|
|
23
24
|
</script>
|
|
24
25
|
|
|
25
|
-
<div class={containerClass}>
|
|
26
|
-
{#each items as item (item.rank)}
|
|
27
|
-
<div class={card()}>
|
|
26
|
+
<div class={containerClass} data-testid={buildTestId('ranked-card', undefined, testId)}>
|
|
27
|
+
{#each items as item, index (item.rank)}
|
|
28
|
+
<div class={card()} data-testid={buildTestId('ranked-card', 'card', testId, index)}>
|
|
28
29
|
<!-- Header with Rank and Title -->
|
|
29
30
|
<div class={header()}>
|
|
30
|
-
<span class={rank()}
|
|
31
|
-
|
|
31
|
+
<span class={rank()} data-testid={buildTestId('ranked-card', 'rank', testId, index)}
|
|
32
|
+
>#{item.rank}</span
|
|
33
|
+
>
|
|
34
|
+
<h4 class={title()} data-testid={buildTestId('ranked-card', 'title', testId, index)}>
|
|
35
|
+
{item.title}
|
|
36
|
+
</h4>
|
|
32
37
|
</div>
|
|
33
38
|
|
|
34
39
|
<!-- Metrics -->
|
|
35
40
|
<div class={metricsContainer()}>
|
|
36
|
-
{#each item.metrics as metric (metric.label)}
|
|
41
|
+
{#each item.metrics as metric, metricIndex (metric.label)}
|
|
37
42
|
<div class={metricRow()}>
|
|
38
|
-
<span
|
|
39
|
-
|
|
43
|
+
<span
|
|
44
|
+
class={metricLabel()}
|
|
45
|
+
data-testid={buildTestId(
|
|
46
|
+
'ranked-card',
|
|
47
|
+
'metric-label',
|
|
48
|
+
testId,
|
|
49
|
+
`${index}-${metricIndex}`
|
|
50
|
+
)}>{metric.label}:</span
|
|
51
|
+
>
|
|
52
|
+
<span
|
|
53
|
+
class={cn(metricValue(), metric.color || '')}
|
|
54
|
+
data-testid={buildTestId(
|
|
55
|
+
'ranked-card',
|
|
56
|
+
'metric-value',
|
|
57
|
+
testId,
|
|
58
|
+
`${index}-${metricIndex}`
|
|
59
|
+
)}>{metric.value}</span
|
|
60
|
+
>
|
|
40
61
|
</div>
|
|
41
62
|
{/each}
|
|
42
63
|
</div>
|
|
43
64
|
|
|
44
65
|
<!-- Action/Recommendation -->
|
|
45
66
|
{#if item.action}
|
|
46
|
-
<div
|
|
67
|
+
<div
|
|
68
|
+
class={actionContainer()}
|
|
69
|
+
data-testid={buildTestId('ranked-card', 'action', testId, index)}
|
|
70
|
+
>
|
|
47
71
|
<p class={actionText()}>
|
|
48
72
|
<span class={actionLabel()}>Action:</span>
|
|
49
73
|
<span class={item.action.color || ''}>{item.action.text}</span>
|
|
@@ -168,5 +168,13 @@ export type MetricCardProps = {
|
|
|
168
168
|
* data is loading. @default false
|
|
169
169
|
*/
|
|
170
170
|
loading?: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Test ID prefix. When set, the component emits these selectors:
|
|
173
|
+
* - `{testId}-metric-card` — root wrapper
|
|
174
|
+
* - `{testId}-metric-card-value` — big number
|
|
175
|
+
* - `{testId}-metric-card-label` — label text
|
|
176
|
+
* - `{testId}-metric-card-detail-{i}` — each detail row
|
|
177
|
+
* - `{testId}-metric-card-action` — action area
|
|
178
|
+
*/
|
|
171
179
|
testId?: string;
|
|
172
180
|
};
|
|
@@ -102,4 +102,14 @@ export type RankedCardProps = {
|
|
|
102
102
|
items: RankedCardItem[];
|
|
103
103
|
columns?: 1 | 2 | 3 | 4;
|
|
104
104
|
class?: ClassValue;
|
|
105
|
+
/**
|
|
106
|
+
* Test ID prefix. When set, the component emits these selectors:
|
|
107
|
+
* - `{testId}-ranked-card` — root wrapper
|
|
108
|
+
* - `{testId}-ranked-card-item-{i}` — each card
|
|
109
|
+
* - `{testId}-ranked-card-rank-{i}` — rank number
|
|
110
|
+
* - `{testId}-ranked-card-title-{i}` — title
|
|
111
|
+
* - `{testId}-ranked-card-metric-label-{i}-{j}` — metric label
|
|
112
|
+
* - `{testId}-ranked-card-metric-value-{i}-{j}` — metric value
|
|
113
|
+
*/
|
|
114
|
+
testId?: string;
|
|
105
115
|
};
|
|
@@ -202,5 +202,13 @@ export type TableProps<T = DataRow> = {
|
|
|
202
202
|
rowKey?: string;
|
|
203
203
|
/** Allow rows to expand/collapse showing `expandedContent`. @default false */
|
|
204
204
|
expandable?: boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Test ID prefix. When set, the component emits these selectors:
|
|
207
|
+
* - `{testId}-table` — root table element
|
|
208
|
+
* - `{testId}-table-head` — thead
|
|
209
|
+
* - `{testId}-table-data` — hidden element containing the current
|
|
210
|
+
* page's row data as JSON, so test automation can read values
|
|
211
|
+
* without parsing individual cells
|
|
212
|
+
*/
|
|
205
213
|
testId?: string;
|
|
206
214
|
};
|
package/dist/modal/modal.js
CHANGED
|
@@ -2,11 +2,11 @@ import { tv } from 'tailwind-variants';
|
|
|
2
2
|
import { Size } from '../index.js';
|
|
3
3
|
export const modal = tv({
|
|
4
4
|
slots: {
|
|
5
|
-
base: 'fixed inset-0 z-50 flex items-center justify-center p-4',
|
|
5
|
+
base: 'fixed inset-0 z-50 flex items-center justify-center p-2 sm:p-4',
|
|
6
6
|
backdrop: 'fixed inset-0 bg-black/50 backdrop-blur-sm',
|
|
7
|
-
container: 'relative w-full flex flex-col bg-white rounded-xl shadow-2xl',
|
|
8
|
-
header: 'px-6 py-4 border-b border-default-200 flex items-center justify-between shrink-0',
|
|
9
|
-
body: 'flex-1 px-6 py-4 overflow-y-auto',
|
|
7
|
+
container: 'relative w-full flex flex-col bg-white rounded-xl shadow-2xl max-sm:max-w-none max-sm:max-h-[95vh]',
|
|
8
|
+
header: 'px-4 py-3 sm:px-6 sm:py-4 border-b border-default-200 flex items-center justify-between shrink-0',
|
|
9
|
+
body: 'flex-1 px-4 py-3 sm:px-6 sm:py-4 overflow-y-auto',
|
|
10
10
|
footer: 'bg-default-50/80 rounded-b-xl shrink-0',
|
|
11
11
|
title: 'text-lg font-semibold text-default-900',
|
|
12
12
|
description: 'text-sm text-default-600 mt-1',
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
class: className = '',
|
|
12
12
|
size = 'md',
|
|
13
13
|
equalWidth = true,
|
|
14
|
-
chevronGap =
|
|
14
|
+
chevronGap = 4,
|
|
15
15
|
selectedClass,
|
|
16
16
|
unselectedClass,
|
|
17
17
|
disabledClass,
|
|
@@ -74,9 +74,13 @@
|
|
|
74
74
|
{#if children}
|
|
75
75
|
{@render children(stage, index)}
|
|
76
76
|
{:else}
|
|
77
|
-
<span class={s.label()}
|
|
77
|
+
<span class={s.label()} data-testid={buildTestId('pipeline', 'label', testId, index)}
|
|
78
|
+
>{stage.label}</span
|
|
79
|
+
>
|
|
78
80
|
{#if stage.count !== undefined}
|
|
79
|
-
<span class={s.count()}
|
|
81
|
+
<span class={s.count()} data-testid={buildTestId('pipeline', 'count', testId, index)}
|
|
82
|
+
>{stage.count}</span
|
|
83
|
+
>
|
|
80
84
|
{/if}
|
|
81
85
|
{/if}
|
|
82
86
|
</div>
|
|
@@ -86,5 +86,11 @@ export type PipelineProps = {
|
|
|
86
86
|
onstagehover?: (e: PipelineStagePointerEvent) => void;
|
|
87
87
|
/** Fires on stage mouseleave. */
|
|
88
88
|
onstageleave?: (e: PipelineStagePointerEvent) => void;
|
|
89
|
+
/**
|
|
90
|
+
* Test ID prefix. When set, the component emits these selectors:
|
|
91
|
+
* - `{testId}-pipeline` — root wrapper
|
|
92
|
+
* - `{testId}-pipeline-label-{i}` — stage label
|
|
93
|
+
* - `{testId}-pipeline-count-{i}` — stage count
|
|
94
|
+
*/
|
|
89
95
|
testId?: string;
|
|
90
96
|
};
|