@makolabs/ripple 3.0.2 → 3.0.3
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/charts/Chart.svelte +8 -36
- 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/forms/DateRange.svelte +19 -17
- package/dist/forms/calendar/Calendar.svelte +0 -1
- package/dist/forms/date-picker/DatePicker.svelte +8 -1
- package/dist/forms/month-picker/MonthPicker.svelte +9 -2
- package/dist/modal/modal.js +4 -4
- package/package.json +1 -1
package/dist/charts/Chart.svelte
CHANGED
|
@@ -143,38 +143,6 @@
|
|
|
143
143
|
return rgbToHex(r * (1 - amount), g * (1 - amount), b * (1 - amount));
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
147
|
-
function barGradient(baseHex: string, stacked: boolean): any {
|
|
148
|
-
if (stacked) {
|
|
149
|
-
// Horizontal sheen — same light direction for all segments
|
|
150
|
-
return {
|
|
151
|
-
type: 'linear',
|
|
152
|
-
x: 0,
|
|
153
|
-
y: 0,
|
|
154
|
-
x2: 1,
|
|
155
|
-
y2: 0,
|
|
156
|
-
colorStops: [
|
|
157
|
-
{ offset: 0, color: baseHex },
|
|
158
|
-
{ offset: 0.5, color: lighten(baseHex, 0.1) },
|
|
159
|
-
{ offset: 1, color: baseHex }
|
|
160
|
-
]
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
// Standalone bars — top-to-bottom depth
|
|
164
|
-
return {
|
|
165
|
-
type: 'linear',
|
|
166
|
-
x: 0,
|
|
167
|
-
y: 0,
|
|
168
|
-
x2: 0,
|
|
169
|
-
y2: 1,
|
|
170
|
-
colorStops: [
|
|
171
|
-
{ offset: 0, color: lighten(baseHex, 0.2) },
|
|
172
|
-
{ offset: 0.6, color: baseHex },
|
|
173
|
-
{ offset: 1, color: darken(baseHex, 0.15) }
|
|
174
|
-
]
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
|
|
178
146
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
179
147
|
function lineGradient(baseHex: string): any {
|
|
180
148
|
return {
|
|
@@ -435,9 +403,10 @@
|
|
|
435
403
|
color: getColor(seriesConfig.color),
|
|
436
404
|
emphasis: seriesConfig.emphasis || {
|
|
437
405
|
focus: 'series',
|
|
438
|
-
blurScope: 'global'
|
|
406
|
+
blurScope: 'global',
|
|
407
|
+
itemStyle: { borderRadius: 0 }
|
|
439
408
|
},
|
|
440
|
-
blur: { itemStyle: { opacity: 0.25 }, lineStyle: { opacity: 0.25 } },
|
|
409
|
+
blur: { itemStyle: { opacity: 0.25, borderRadius: 0 }, lineStyle: { opacity: 0.25 } },
|
|
441
410
|
animation: true,
|
|
442
411
|
animationDuration: AnimationDuration,
|
|
443
412
|
...(axisMarkLine && { markLine: axisMarkLine }),
|
|
@@ -475,8 +444,11 @@
|
|
|
475
444
|
barGap: '10%',
|
|
476
445
|
color: getColor(seriesConfig.color),
|
|
477
446
|
itemStyle: {
|
|
478
|
-
color:
|
|
479
|
-
opacity: seriesConfig.opacity ?? 1
|
|
447
|
+
color: getColor(seriesConfig.color) ?? '#6366f1',
|
|
448
|
+
opacity: seriesConfig.opacity ?? 1,
|
|
449
|
+
borderColor: darken(getColor(seriesConfig.color) ?? '#6366f1', 0.15),
|
|
450
|
+
borderWidth: 1,
|
|
451
|
+
borderRadius: [0, 0, 0, 0]
|
|
480
452
|
}
|
|
481
453
|
}),
|
|
482
454
|
|
|
@@ -37,8 +37,7 @@
|
|
|
37
37
|
header: headerVClass,
|
|
38
38
|
body,
|
|
39
39
|
footer: footerVClass,
|
|
40
|
-
title: titleVClass
|
|
41
|
-
closeButton
|
|
40
|
+
title: titleVClass
|
|
42
41
|
} = $derived(
|
|
43
42
|
drawer({
|
|
44
43
|
open,
|
|
@@ -54,7 +53,6 @@
|
|
|
54
53
|
const headerClasses = $derived(cn(headerVClass(), headerClass));
|
|
55
54
|
const bodyClasses = $derived(cn(body(), bodyClass));
|
|
56
55
|
const titleClasses = $derived(cn(titleVClass(), titleClass));
|
|
57
|
-
const closeButtonClasses = $derived(cn(closeButton(), ''));
|
|
58
56
|
const footerClasses = $derived(cn(footerVClass(), 'mt-auto', footerClass));
|
|
59
57
|
|
|
60
58
|
function handleBackdropClick(e: MouseEvent) {
|
|
@@ -181,41 +179,36 @@
|
|
|
181
179
|
data-testid={buildTestId('drawer', 'dialog', testId)}
|
|
182
180
|
>
|
|
183
181
|
<div class={contentClasses}>
|
|
182
|
+
<!-- Always-visible close button -->
|
|
183
|
+
<button
|
|
184
|
+
type="button"
|
|
185
|
+
class="bg-default-100 text-default-600 hover:bg-default-200 hover:text-default-900 absolute top-2 right-2 z-10 flex size-8 cursor-pointer items-center justify-center rounded-full transition-colors"
|
|
186
|
+
onclick={handleCloseClick}
|
|
187
|
+
aria-label="Close drawer"
|
|
188
|
+
data-testid={buildTestId('drawer', 'close', testId)}
|
|
189
|
+
>
|
|
190
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 12 12">
|
|
191
|
+
<path
|
|
192
|
+
fill="currentColor"
|
|
193
|
+
d="m1.897 2.054l.073-.084a.75.75 0 0 1 .976-.073l.084.073L6 4.939l2.97-2.97a.75.75 0 1 1 1.06 1.061L7.061 6l2.97 2.97a.75.75 0 0 1 .072.976l-.073.084a.75.75 0 0 1-.976.073l-.084-.073L6 7.061l-2.97 2.97A.75.75 0 1 1 1.97 8.97L4.939 6l-2.97-2.97a.75.75 0 0 1-.072-.976l.073-.084z"
|
|
194
|
+
/>
|
|
195
|
+
</svg>
|
|
196
|
+
</button>
|
|
197
|
+
|
|
184
198
|
<!-- Header -->
|
|
185
|
-
{#if
|
|
199
|
+
{#if title}
|
|
200
|
+
<div class={headerClasses}>
|
|
201
|
+
<h3
|
|
202
|
+
id="drawer-title"
|
|
203
|
+
class={titleClasses}
|
|
204
|
+
data-testid={buildTestId('drawer', 'title', testId)}
|
|
205
|
+
>
|
|
206
|
+
{title}
|
|
207
|
+
</h3>
|
|
208
|
+
</div>
|
|
209
|
+
{:else if header}
|
|
186
210
|
<div class={headerClasses}>
|
|
187
|
-
{
|
|
188
|
-
{@render header()}
|
|
189
|
-
{:else}
|
|
190
|
-
{#if title}
|
|
191
|
-
<h3
|
|
192
|
-
id="drawer-title"
|
|
193
|
-
class={titleClasses}
|
|
194
|
-
data-testid={buildTestId('drawer', 'title', testId)}
|
|
195
|
-
>
|
|
196
|
-
{title}
|
|
197
|
-
</h3>
|
|
198
|
-
{/if}
|
|
199
|
-
<button
|
|
200
|
-
type="button"
|
|
201
|
-
class={closeButtonClasses}
|
|
202
|
-
onclick={handleCloseClick}
|
|
203
|
-
aria-label="Close drawer"
|
|
204
|
-
data-testid={buildTestId('drawer', 'close', testId)}
|
|
205
|
-
>
|
|
206
|
-
<svg
|
|
207
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
208
|
-
width="12"
|
|
209
|
-
height="12"
|
|
210
|
-
viewBox="0 0 12 12"
|
|
211
|
-
>
|
|
212
|
-
<path
|
|
213
|
-
fill="currentColor"
|
|
214
|
-
d="m1.897 2.054l.073-.084a.75.75 0 0 1 .976-.073l.084.073L6 4.939l2.97-2.97a.75.75 0 1 1 1.06 1.061L7.061 6l2.97 2.97a.75.75 0 0 1 .072.976l-.073.084a.75.75 0 0 1-.976.073l-.084-.073L6 7.061l-2.97 2.97A.75.75 0 1 1 1.97 8.97L4.939 6l-2.97-2.97a.75.75 0 0 1-.072-.976l.073-.084z"
|
|
215
|
-
/>
|
|
216
|
-
</svg>
|
|
217
|
-
</button>
|
|
218
|
-
{/if}
|
|
211
|
+
{@render header()}
|
|
219
212
|
</div>
|
|
220
213
|
{/if}
|
|
221
214
|
|
package/dist/drawer/drawer.js
CHANGED
|
@@ -4,8 +4,8 @@ export const drawer = tv({
|
|
|
4
4
|
slots: {
|
|
5
5
|
base: 'fixed inset-0 z-50 flex overflow-hidden',
|
|
6
6
|
backdrop: 'fixed inset-0 transition-opacity bg-black/50',
|
|
7
|
-
contentWrapper: 'absolute flex flex-col transform transition-transform',
|
|
8
|
-
content: 'flex flex-col h-full w-full overflow-y-auto bg-white',
|
|
7
|
+
contentWrapper: 'absolute flex flex-col transform transition-transform max-w-[100vw]',
|
|
8
|
+
content: 'relative flex flex-col h-full w-full overflow-y-auto bg-white',
|
|
9
9
|
header: 'flex items-center justify-between px-4 py-3 border-b border-default-200',
|
|
10
10
|
body: 'flex-1 overflow-y-auto p-4',
|
|
11
11
|
footer: 'flex justify-end border-t border-default-200 p-4',
|
|
@@ -97,12 +97,15 @@
|
|
|
97
97
|
const v = (e.currentTarget as HTMLInputElement).value;
|
|
98
98
|
query = v;
|
|
99
99
|
open = true;
|
|
100
|
+
// Fire onsearch immediately (documented "every keystroke" contract).
|
|
101
|
+
// Only debounce local filtering so rapid typing doesn't churn the
|
|
102
|
+
// DOM with intermediate filter results.
|
|
103
|
+
onsearch?.(v);
|
|
100
104
|
clearTimeout(debounceTimer);
|
|
101
105
|
debounceTimer = setTimeout(() => {
|
|
102
106
|
debouncedQuery = v;
|
|
103
107
|
highlightedIndex = 0;
|
|
104
|
-
|
|
105
|
-
}, 1000);
|
|
108
|
+
}, 300);
|
|
106
109
|
}
|
|
107
110
|
|
|
108
111
|
$effect(() => {
|
|
@@ -206,10 +209,7 @@
|
|
|
206
209
|
else openMenu();
|
|
207
210
|
}
|
|
208
211
|
}}
|
|
209
|
-
class=
|
|
210
|
-
'text-default-400 hover:text-default-700 flex cursor-pointer items-center justify-center rounded',
|
|
211
|
-
!disabled && 'hover:text-default-600'
|
|
212
|
-
)}
|
|
212
|
+
class="text-default-400 hover:text-default-600 flex cursor-pointer items-center justify-center rounded"
|
|
213
213
|
aria-label={open ? 'Close suggestions' : 'Open suggestions'}
|
|
214
214
|
{disabled}
|
|
215
215
|
>
|
|
@@ -216,19 +216,17 @@
|
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
function handleClickOutside(event: MouseEvent) {
|
|
219
|
-
|
|
219
|
+
if (!open) return;
|
|
220
|
+
// On mobile the sheet handles its own close via backdrop.
|
|
221
|
+
if (isMobile) return;
|
|
220
222
|
const portalContent = document.querySelector('.ripple-portal .portal-content');
|
|
221
|
-
|
|
222
|
-
// If the click is inside either the label (trigger) or the portal content, don't close
|
|
223
|
+
const target = event.target as Node;
|
|
223
224
|
if (
|
|
224
|
-
(labelRef && labelRef.contains(
|
|
225
|
-
(portalContent && portalContent.contains(
|
|
226
|
-
!open
|
|
225
|
+
(labelRef && labelRef.contains(target)) ||
|
|
226
|
+
(portalContent && portalContent.contains(target))
|
|
227
227
|
) {
|
|
228
228
|
return;
|
|
229
229
|
}
|
|
230
|
-
|
|
231
|
-
// Otherwise close the dropdown
|
|
232
230
|
open = false;
|
|
233
231
|
onclose();
|
|
234
232
|
}
|
|
@@ -333,24 +333,26 @@
|
|
|
333
333
|
{/if}
|
|
334
334
|
|
|
335
335
|
{#if isOpen && isMobile}
|
|
336
|
-
<
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
<div class="
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
336
|
+
<Portal target={datePickerRef}>
|
|
337
|
+
<button
|
|
338
|
+
type="button"
|
|
339
|
+
class="fixed inset-0 z-[9998] bg-black/40 backdrop-blur-sm"
|
|
340
|
+
aria-label="Close"
|
|
341
|
+
onclick={() => (isOpen = false)}
|
|
342
|
+
></button>
|
|
343
|
+
<div
|
|
344
|
+
class="fixed inset-x-0 bottom-0 z-[9999] flex max-h-[85vh] min-h-48 flex-col overflow-hidden rounded-t-2xl bg-white shadow-2xl"
|
|
345
|
+
transition:fly={{ y: 300, duration: 200, easing: quintOut }}
|
|
346
|
+
bind:this={calendarRef}
|
|
347
|
+
>
|
|
348
|
+
<div class="flex justify-center py-2">
|
|
349
|
+
<div class="bg-default-300 h-1 w-8 rounded-full"></div>
|
|
350
|
+
</div>
|
|
351
|
+
<div class="flex-1 cursor-pointer overflow-y-auto p-4">
|
|
352
|
+
{@render calendarContent()}
|
|
353
|
+
</div>
|
|
352
354
|
</div>
|
|
353
|
-
</
|
|
355
|
+
</Portal>
|
|
354
356
|
{/if}
|
|
355
357
|
</div>
|
|
356
358
|
|
|
@@ -127,7 +127,14 @@
|
|
|
127
127
|
</button>
|
|
128
128
|
|
|
129
129
|
{#snippet content()}
|
|
130
|
-
<Calendar
|
|
130
|
+
<Calendar
|
|
131
|
+
{value}
|
|
132
|
+
{minDate}
|
|
133
|
+
{maxDate}
|
|
134
|
+
{size}
|
|
135
|
+
class="max-sm:w-full max-sm:rounded-none max-sm:border-0 max-sm:shadow-none"
|
|
136
|
+
onselect={(d) => handleSelect(d as Date)}
|
|
137
|
+
/>
|
|
131
138
|
{/snippet}
|
|
132
139
|
</Popover>
|
|
133
140
|
|
|
@@ -118,7 +118,10 @@
|
|
|
118
118
|
|
|
119
119
|
function setThisMonth() {
|
|
120
120
|
const now = new Date();
|
|
121
|
-
|
|
121
|
+
const d = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
122
|
+
if (minDate && d < new Date(minDate.getFullYear(), minDate.getMonth(), 1)) return;
|
|
123
|
+
if (maxDate && d > new Date(maxDate.getFullYear(), maxDate.getMonth(), 1)) return;
|
|
124
|
+
value = d;
|
|
122
125
|
onselect?.(value);
|
|
123
126
|
open = false;
|
|
124
127
|
}
|
|
@@ -142,7 +145,11 @@
|
|
|
142
145
|
</label>
|
|
143
146
|
{/if}
|
|
144
147
|
|
|
145
|
-
<input
|
|
148
|
+
<input
|
|
149
|
+
type="hidden"
|
|
150
|
+
{name}
|
|
151
|
+
value={value ? `${value.getFullYear()}-${String(value.getMonth() + 1).padStart(2, '0')}` : ''}
|
|
152
|
+
/>
|
|
146
153
|
|
|
147
154
|
<Popover trigger="manual" bind:open placement="bottom" {disabled}>
|
|
148
155
|
<button
|
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',
|