@juspay/svelte-ui-components 4.13.0 → 4.15.0
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/PieChart/PieChart.svelte +136 -11
- package/dist/PieChart/properties.d.ts +24 -0
- package/dist/Sheet/Sheet.svelte +37 -4
- package/dist-wc/index.js +4 -3
- package/package.json +1 -1
|
@@ -40,6 +40,9 @@
|
|
|
40
40
|
classes,
|
|
41
41
|
semiCircle = false,
|
|
42
42
|
legendShowValues = false,
|
|
43
|
+
legendPosition = 'bottom',
|
|
44
|
+
legendMaxItems,
|
|
45
|
+
onlegendmore,
|
|
43
46
|
percentDecimals = 0,
|
|
44
47
|
onchartready,
|
|
45
48
|
highlightedIndex = null,
|
|
@@ -49,6 +52,7 @@
|
|
|
49
52
|
|
|
50
53
|
// ── State ──────────────────────────────────────────────────────
|
|
51
54
|
|
|
55
|
+
let legendExpanded = $state(false);
|
|
52
56
|
let containerEl: HTMLDivElement | null = $state(null);
|
|
53
57
|
let chartWidth = $state(0);
|
|
54
58
|
let chartHeight = $state(0);
|
|
@@ -153,6 +157,57 @@
|
|
|
153
157
|
});
|
|
154
158
|
});
|
|
155
159
|
|
|
160
|
+
/* A cap only counts when it actually hides something: a legendMaxItems of 5
|
|
161
|
+
over 5 rows must render no control, since a control that reveals nothing
|
|
162
|
+
is worse than none. Non-positive and non-finite values are ignored rather
|
|
163
|
+
than clamping the list to empty -- a plain-JS or web-component caller can
|
|
164
|
+
hand this anything. */
|
|
165
|
+
const legendCap = $derived(
|
|
166
|
+
typeof legendMaxItems === 'number' && Number.isFinite(legendMaxItems) && legendMaxItems > 0
|
|
167
|
+
? Math.max(1, Math.floor(legendMaxItems))
|
|
168
|
+
: null
|
|
169
|
+
);
|
|
170
|
+
/* A changed list or cap starts a new collapsed view, not a stale expansion.
|
|
171
|
+
This has to be an effect rather than a derived key: collapsing depends on
|
|
172
|
+
the TRANSITION, not on the current values. A list that shrinks below the
|
|
173
|
+
cap and then returns to its former length must stay collapsed, and a key
|
|
174
|
+
built from (cap, length) would match its earlier self and silently
|
|
175
|
+
re-expand -- which is what the regression tests here caught when this was
|
|
176
|
+
written that way. The two values are passed as ordinary arguments so the
|
|
177
|
+
dependencies are real reads rather than `void` expressions. */
|
|
178
|
+
const collapseLegend = (_cap: number | null, _rowCount: number): void => {
|
|
179
|
+
legendExpanded = false;
|
|
180
|
+
};
|
|
181
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
182
|
+
$effect(() => {
|
|
183
|
+
collapseLegend(legendCap, data.length);
|
|
184
|
+
});
|
|
185
|
+
const legendHiddenCount = $derived(legendCap === null ? 0 : Math.max(0, data.length - legendCap));
|
|
186
|
+
const legendRows = $derived(
|
|
187
|
+
legendCap === null || legendExpanded ? data : data.slice(0, legendCap)
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
/* Excludes the empty state: with no rows there is no legend column to sit
|
|
191
|
+
beside, and turning the root into a flex row would make the empty message
|
|
192
|
+
a flex item rather than the full-width block it is documented to be. */
|
|
193
|
+
const legendBesideChart = $derived(
|
|
194
|
+
!isEmpty && showLegend && legendShowValues && legendPosition === 'right'
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
const instanceId = $props.id();
|
|
198
|
+
const legendListId = `pie-legend-${instanceId}`;
|
|
199
|
+
|
|
200
|
+
const handleLegendMore = (): void => {
|
|
201
|
+
/* A consumer opening their own modal must not also get the list expanding
|
|
202
|
+
underneath it, so the callback replaces the built-in behaviour rather
|
|
203
|
+
than firing alongside it. */
|
|
204
|
+
if (typeof onlegendmore === 'function') {
|
|
205
|
+
onlegendmore();
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
legendExpanded = !legendExpanded;
|
|
209
|
+
};
|
|
210
|
+
|
|
156
211
|
let legendItems = $derived<LegendItem[]>(
|
|
157
212
|
data.map((d, i) => ({ label: d.label, color: d.color ?? getColor(i) }))
|
|
158
213
|
);
|
|
@@ -290,6 +345,7 @@
|
|
|
290
345
|
|
|
291
346
|
<div
|
|
292
347
|
class="pie-chart {classes ?? ''}"
|
|
348
|
+
class:legend-right={legendBesideChart}
|
|
293
349
|
bind:this={containerEl}
|
|
294
350
|
data-pw={typeof testId === 'string' ? testId : null}
|
|
295
351
|
testID={typeof testId === 'string' ? testId : null}
|
|
@@ -358,17 +414,30 @@
|
|
|
358
414
|
{/if}
|
|
359
415
|
|
|
360
416
|
{#if showLegend && legendShowValues}
|
|
361
|
-
<
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
<
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
417
|
+
<div class="pie-legend-column">
|
|
418
|
+
<ul class="pie-legend-values" id={legendListId}>
|
|
419
|
+
{#each legendRows as d, i (i)}
|
|
420
|
+
<li class="pie-legend-row">
|
|
421
|
+
<span class="pie-legend-swatch" style="background: {d.color ?? getColor(i)}"></span>
|
|
422
|
+
<span class="pie-legend-label">{d.label}</span>
|
|
423
|
+
<span class="pie-legend-value">
|
|
424
|
+
{format(d.value)} {pctFormat(d.value)}
|
|
425
|
+
</span>
|
|
426
|
+
</li>
|
|
427
|
+
{/each}
|
|
428
|
+
</ul>
|
|
429
|
+
{#if legendHiddenCount > 0}
|
|
430
|
+
<button
|
|
431
|
+
type="button"
|
|
432
|
+
class="pie-legend-more"
|
|
433
|
+
aria-expanded={typeof onlegendmore === 'function' ? null : legendExpanded}
|
|
434
|
+
{...typeof onlegendmore === 'function' ? {} : { 'aria-controls': legendListId }}
|
|
435
|
+
onclick={handleLegendMore}
|
|
436
|
+
>
|
|
437
|
+
{legendExpanded ? 'Show less' : `+${legendHiddenCount} more`}
|
|
438
|
+
</button>
|
|
439
|
+
{/if}
|
|
440
|
+
</div>
|
|
372
441
|
{/if}
|
|
373
442
|
|
|
374
443
|
{#if typeof tooltipSnippet === 'function' && hoveredIndex !== null && data[hoveredIndex]}
|
|
@@ -469,4 +538,60 @@
|
|
|
469
538
|
min-width: var(--piechart-legend-value-min-width, 60px);
|
|
470
539
|
text-align: right;
|
|
471
540
|
}
|
|
541
|
+
|
|
542
|
+
/* The column wrapper is present in both placements so the markup does not
|
|
543
|
+
fork; as a plain block it changes nothing about the default below-chart
|
|
544
|
+
rendering. */
|
|
545
|
+
.pie-legend-column {
|
|
546
|
+
display: flex;
|
|
547
|
+
flex-direction: column;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/* Only the values legend moves beside the chart -- the plain top legend is
|
|
551
|
+
mutually exclusive with it, and the delta badge and tooltip are both
|
|
552
|
+
absolutely positioned, so they stay out of this flex row entirely. */
|
|
553
|
+
.pie-chart.legend-right {
|
|
554
|
+
display: flex;
|
|
555
|
+
flex-direction: row;
|
|
556
|
+
align-items: center;
|
|
557
|
+
gap: var(--piechart-legend-column-gap, 16px);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
.pie-chart.legend-right :global(.chart-container) {
|
|
561
|
+
/* flex-basis 0 rather than auto: the container carries width:100%, which
|
|
562
|
+
as a flex item would otherwise claim the whole row and squeeze the
|
|
563
|
+
legend to nothing. */
|
|
564
|
+
flex: 1 1 0;
|
|
565
|
+
min-width: 0;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
.pie-chart.legend-right .pie-legend-column {
|
|
569
|
+
flex: 0 0 auto;
|
|
570
|
+
max-width: var(--piechart-legend-column-max-width, 50%);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
.pie-chart.legend-right .pie-legend-values {
|
|
574
|
+
padding: var(--piechart-legend-column-padding, 0);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
.pie-legend-more {
|
|
578
|
+
align-self: flex-start;
|
|
579
|
+
margin-top: var(--piechart-legend-more-margin-top, 8px);
|
|
580
|
+
padding: var(--piechart-legend-more-padding, 2px 4px);
|
|
581
|
+
border: none;
|
|
582
|
+
background: none;
|
|
583
|
+
cursor: var(--cursor, pointer);
|
|
584
|
+
font-size: var(--piechart-legend-more-font-size, 12px);
|
|
585
|
+
font-family: inherit;
|
|
586
|
+
color: var(--piechart-legend-more-color, #2563eb);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.pie-legend-more:hover {
|
|
590
|
+
text-decoration: underline;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
.pie-legend-more:focus-visible {
|
|
594
|
+
outline: var(--piechart-legend-more-focus-outline, 2px solid currentColor);
|
|
595
|
+
outline-offset: 2px;
|
|
596
|
+
}
|
|
472
597
|
</style>
|
|
@@ -5,6 +5,8 @@ export type PieChartSlice = {
|
|
|
5
5
|
value: number;
|
|
6
6
|
color?: string;
|
|
7
7
|
};
|
|
8
|
+
/** Placement of the `legendShowValues` list. See `legendPosition`. */
|
|
9
|
+
export type PieChartLegendPosition = 'bottom' | 'right';
|
|
8
10
|
export type PieChartProperties = MandatoryPieChartProperties & OptionalPieChartProperties & PieChartEventProperties;
|
|
9
11
|
export type MandatoryPieChartProperties = {
|
|
10
12
|
data: PieChartSlice[];
|
|
@@ -33,6 +35,28 @@ export type OptionalPieChartProperties = {
|
|
|
33
35
|
classes?: string;
|
|
34
36
|
semiCircle?: boolean;
|
|
35
37
|
legendShowValues?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Where the `legendShowValues` list sits relative to the chart. `'bottom'`
|
|
40
|
+
* (the default) keeps today's below-chart placement; `'right'` renders it as
|
|
41
|
+
* a column beside the chart, which is the shape a donut legend usually
|
|
42
|
+
* wants once the labels carry values. Only affects the values legend —
|
|
43
|
+
* `showLegend` without `legendShowValues` still renders the plain top
|
|
44
|
+
* legend.
|
|
45
|
+
*/
|
|
46
|
+
legendPosition?: PieChartLegendPosition;
|
|
47
|
+
/**
|
|
48
|
+
* Show at most this many legend rows, followed by a `+N more` control. Omit
|
|
49
|
+
* it (the default) to show every row with no control at all. A cap that is
|
|
50
|
+
* not exceeded renders no control either, since it would do nothing.
|
|
51
|
+
*/
|
|
52
|
+
legendMaxItems?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Called when the `+N more` control is activated. Providing it SUPPRESSES
|
|
55
|
+
* the built-in in-place expansion, so a consumer opening their own modal or
|
|
56
|
+
* drawer does not have the legend expand underneath it as well. Without it,
|
|
57
|
+
* the control toggles the hidden rows in place.
|
|
58
|
+
*/
|
|
59
|
+
onlegendmore?: () => void;
|
|
36
60
|
percentDecimals?: number;
|
|
37
61
|
/**
|
|
38
62
|
* Called once on mount with the imperative highlight API. Pass the returned
|
package/dist/Sheet/Sheet.svelte
CHANGED
|
@@ -99,16 +99,26 @@
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
function scrollLockAction(
|
|
102
|
+
function scrollLockAction(node: HTMLElement) {
|
|
103
|
+
const previousFocus = document.activeElement;
|
|
104
|
+
let active = true;
|
|
103
105
|
lockBodyScroll();
|
|
104
106
|
tick().then(() => {
|
|
105
|
-
if (sheetPanel !== null) {
|
|
107
|
+
if (active && sheetPanel !== null) {
|
|
106
108
|
sheetPanel.focus();
|
|
107
109
|
}
|
|
108
110
|
});
|
|
109
111
|
return {
|
|
110
112
|
destroy() {
|
|
113
|
+
active = false;
|
|
111
114
|
unlockBodyScroll();
|
|
115
|
+
if (
|
|
116
|
+
previousFocus instanceof HTMLElement &&
|
|
117
|
+
previousFocus.isConnected &&
|
|
118
|
+
(document.activeElement === document.body || node.contains(document.activeElement))
|
|
119
|
+
) {
|
|
120
|
+
previousFocus.focus();
|
|
121
|
+
}
|
|
112
122
|
}
|
|
113
123
|
};
|
|
114
124
|
}
|
|
@@ -295,22 +305,45 @@
|
|
|
295
305
|
border-left: var(--sheet-border, none);
|
|
296
306
|
}
|
|
297
307
|
|
|
308
|
+
/* Top/bottom stretch edge to edge by default, exactly as before: --sheet-
|
|
309
|
+
band-width is `auto`, so `margin-inline: auto` has nothing to distribute
|
|
310
|
+
and the panel still spans --sheet-left to --sheet-right.
|
|
311
|
+
|
|
312
|
+
Setting --sheet-band-width (or --sheet-band-max-width) caps it, and the
|
|
313
|
+
auto margins then centre it between those same two insets -- which is the
|
|
314
|
+
shape a bottom "launch" sheet wants above phone widths, and previously
|
|
315
|
+
had to be faked with hand-computed calc() offsets.
|
|
316
|
+
|
|
317
|
+
Deliberately NOT --sheet-width/--sheet-max-width, even though the issue
|
|
318
|
+
proposed those names. Those already mean "the width of a left/right
|
|
319
|
+
panel", so a consumer who themes them for their side sheets would find
|
|
320
|
+
their bottom sheets silently reshaped by an upgrade. side="center" avoids
|
|
321
|
+
the same collision the same way, with its own --sheet-center-* tokens. */
|
|
298
322
|
.sheet-panel.top,
|
|
299
323
|
.sheet-panel.bottom {
|
|
300
324
|
left: var(--sheet-left, 0);
|
|
301
325
|
right: var(--sheet-right, 0);
|
|
302
326
|
height: var(--sheet-height, 300px);
|
|
303
327
|
max-height: var(--sheet-max-height, 100vh);
|
|
328
|
+
width: var(--sheet-band-width, auto);
|
|
329
|
+
max-width: var(--sheet-band-max-width, none);
|
|
330
|
+
box-sizing: var(--sheet-band-box-sizing, content-box);
|
|
331
|
+
margin-inline: auto;
|
|
332
|
+
border: var(--sheet-band-border, none);
|
|
304
333
|
}
|
|
305
334
|
|
|
335
|
+
/* A capped panel is a floating card and needs all four edges; an
|
|
336
|
+
edge-to-edge one deliberately draws only the edge it enters from. The
|
|
337
|
+
entering edge falls back through --sheet-border so an existing theme that
|
|
338
|
+
sets only that keeps rendering exactly as it did. */
|
|
306
339
|
.sheet-panel.top {
|
|
307
340
|
top: var(--sheet-top, 0);
|
|
308
|
-
border-bottom: var(--sheet-border, none);
|
|
341
|
+
border-bottom: var(--sheet-band-border, var(--sheet-border, none));
|
|
309
342
|
}
|
|
310
343
|
|
|
311
344
|
.sheet-panel.bottom {
|
|
312
345
|
bottom: var(--sheet-bottom, 0);
|
|
313
|
-
border-top: var(--sheet-border, none);
|
|
346
|
+
border-top: var(--sheet-band-border, var(--sheet-border, none));
|
|
314
347
|
}
|
|
315
348
|
|
|
316
349
|
/* `side="center"` is a fixed-size floating dialog, not an edge-anchored
|
package/dist-wc/index.js
CHANGED
|
@@ -17676,7 +17676,7 @@ customElements.define("sui-select", create_custom_element(Select_wc, {
|
|
|
17676
17676
|
//#region src/lib/Sheet/Sheet.svelte
|
|
17677
17677
|
var root$31 = /* @__PURE__ */ from_html("<span class=\"sheet-title svelte-1dln6bq\"> </span>"), root_1$28 = /* @__PURE__ */ from_html("<div class=\"sheet-close-button svelte-1dln6bq\"><!></div>"), root_2$22 = /* @__PURE__ */ from_html("<div class=\"sheet-header svelte-1dln6bq\"><!> <!></div>"), root_3$20 = /* @__PURE__ */ from_html("<div class=\"sheet-footer svelte-1dln6bq\"><!></div>"), root_4$16 = /* @__PURE__ */ from_html("<div tabindex=\"-1\"><div role=\"dialog\" aria-modal=\"true\" tabindex=\"-1\"><!> <div class=\"sheet-content svelte-1dln6bq\"><!></div> <!></div></div>"), $$css$33 = {
|
|
17678
17678
|
hash: "svelte-1dln6bq",
|
|
17679
|
-
code: ".sheet-overlay.svelte-1dln6bq {position:fixed;top:0;left:0;right:0;bottom:0;z-index:var(--sheet-overlay-z-index, 15);-webkit-tap-highlight-color:transparent;}.overlay-visible.svelte-1dln6bq {background-color:var(--sheet-overlay-background, #00000066);}.overlay-invisible.svelte-1dln6bq {background-color:transparent;}.overlay-interactive.svelte-1dln6bq {pointer-events:auto;}.overlay-noninteractive.svelte-1dln6bq {pointer-events:none;}.sheet-panel.svelte-1dln6bq {position:fixed;display:flex;flex-direction:column;background-color:var(--sheet-background, #ffffff);box-shadow:var(--sheet-box-shadow, -2px 0 8px rgba(0, 0, 0, 0.15));z-index:var(--sheet-z-index, 16);pointer-events:auto;outline:none;}\n\n /* The panel itself is the initial focus target on open (scrollLockAction\n focuses it directly, and it's the Tab-trap's own boundary), so removing\n its outline unconditionally left a keyboard user with no visible sign\n focus had moved into the sheet at all -- particularly visible on the\n \"Raw\" variant, which has no focusable child for focus to land on\n instead. :focus-visible restores a ring precisely when the browser\n judges it's from keyboard/programmatic focus rather than a mouse click,\n so clicking the trigger still shows nothing new. outline-offset is\n negative (inset) rather than the usual positive offset other components\n in this library use, because left/right/top/bottom panels sit flush\n against a viewport edge -- a positive offset would clip there. */.sheet-panel.svelte-1dln6bq:focus-visible {outline:var(--sheet-panel-focus-outline, 2px solid #2563eb);outline-offset:var(--sheet-panel-focus-outline-offset, -2px);}\n\n /* --sheet-top/-right/-bottom/-left all default to the previous hardcoded\n edge-to-edge values below, so an unconfigured Sheet renders unchanged.\n Overriding one (e.g. --sheet-top to clear a fixed header, or --sheet-bottom:\n auto to size to content) turns the panel from an edge-to-edge slide-in into\n an anchored floating panel, without needing a different component. */.sheet-panel.left.svelte-1dln6bq,\n .sheet-panel.right.svelte-1dln6bq {top:var(--sheet-top, 0);bottom:var(--sheet-bottom, 0);width:var(--sheet-width, 400px);max-width:var(--sheet-max-width, 100vw);}.sheet-panel.left.svelte-1dln6bq {left:var(--sheet-left, 0);border-right:var(--sheet-border, none);}.sheet-panel.right.svelte-1dln6bq {right:var(--sheet-right, 0);border-left:var(--sheet-border, none);}.sheet-panel.top.svelte-1dln6bq,\n .sheet-panel.bottom.svelte-1dln6bq {left:var(--sheet-left, 0);right:var(--sheet-right, 0);height:var(--sheet-height, 300px);max-height:var(--sheet-max-height, 100vh);}.sheet-panel.top.svelte-1dln6bq {top:var(--sheet-top, 0);border-bottom:var(--sheet-border, none);}.sheet-panel.bottom.svelte-1dln6bq {bottom:var(--sheet-bottom, 0);border-top:var(--sheet-border, none);}\n\n /* `side=\"center\"` is a fixed-size floating dialog, not an edge-anchored\n panel: no top/bottom/left/right offset, sized by its own tokens rather\n than --sheet-width/--sheet-height (so an existing left/right/top/bottom\n theme is untouched by adding this variant), and centered with a\n transform instead of stretching to an edge. */.sheet-panel.center.svelte-1dln6bq {top:50%;left:50%;transform:translate(-50%, -50%);width:var(--sheet-center-width, 480px);max-width:var(--sheet-center-max-width, calc(100vw - 32px));max-height:var(--sheet-center-max-height, 90vh);}.sheet-header.svelte-1dln6bq {display:flex;align-items:center;padding:var(--sheet-header-padding, 16px 20px);background-color:var(--sheet-header-background, inherit);border-bottom:var(--sheet-header-border-bottom, 1px solid #e0e0e0);flex-shrink:0;}.sheet-title.svelte-1dln6bq {flex:1;font-size:var(--sheet-title-font-size, 18px);font-weight:var(--sheet-title-font-weight, 600);font-family:var(--sheet-title-font-family, inherit);color:var(--sheet-title-color, #1a1a1a);line-height:var(--sheet-title-line-height, 1.4);}.sheet-close-button.svelte-1dln6bq {--button-width: var(--sheet-close-button-size, 32px);--button-height: var(--sheet-close-button-size, 32px);--button-border: none;--button-border-radius: var(--sheet-close-button-border-radius, var(--radius, 4px));--button-color: var(--sheet-close-button-background, transparent);--button-text-color: var(--sheet-close-button-color, #666666);--button-font-size: var(--sheet-close-button-font-size, 16px);--button-padding: 0;--button-hover-color: var(--sheet-close-button-hover-background, #f0f0f0);flex-shrink:0;display:flex;align-items:center;justify-content:center;}.sheet-content.svelte-1dln6bq {flex:1;overflow-y:var(--sheet-content-overflow-y, auto);padding:var(--sheet-content-padding, 20px);scrollbar-width:var(--sheet-scrollbar-width, none);}.sheet-content.svelte-1dln6bq::-webkit-scrollbar {display:none;}.sheet-footer.svelte-1dln6bq {padding:var(--sheet-footer-padding, 16px 20px);background-color:var(--sheet-footer-background, inherit);border-top:var(--sheet-footer-border-top, 1px solid #e0e0e0);flex-shrink:0;}"
|
|
17679
|
+
code: ".sheet-overlay.svelte-1dln6bq {position:fixed;top:0;left:0;right:0;bottom:0;z-index:var(--sheet-overlay-z-index, 15);-webkit-tap-highlight-color:transparent;}.overlay-visible.svelte-1dln6bq {background-color:var(--sheet-overlay-background, #00000066);}.overlay-invisible.svelte-1dln6bq {background-color:transparent;}.overlay-interactive.svelte-1dln6bq {pointer-events:auto;}.overlay-noninteractive.svelte-1dln6bq {pointer-events:none;}.sheet-panel.svelte-1dln6bq {position:fixed;display:flex;flex-direction:column;background-color:var(--sheet-background, #ffffff);box-shadow:var(--sheet-box-shadow, -2px 0 8px rgba(0, 0, 0, 0.15));z-index:var(--sheet-z-index, 16);pointer-events:auto;outline:none;}\n\n /* The panel itself is the initial focus target on open (scrollLockAction\n focuses it directly, and it's the Tab-trap's own boundary), so removing\n its outline unconditionally left a keyboard user with no visible sign\n focus had moved into the sheet at all -- particularly visible on the\n \"Raw\" variant, which has no focusable child for focus to land on\n instead. :focus-visible restores a ring precisely when the browser\n judges it's from keyboard/programmatic focus rather than a mouse click,\n so clicking the trigger still shows nothing new. outline-offset is\n negative (inset) rather than the usual positive offset other components\n in this library use, because left/right/top/bottom panels sit flush\n against a viewport edge -- a positive offset would clip there. */.sheet-panel.svelte-1dln6bq:focus-visible {outline:var(--sheet-panel-focus-outline, 2px solid #2563eb);outline-offset:var(--sheet-panel-focus-outline-offset, -2px);}\n\n /* --sheet-top/-right/-bottom/-left all default to the previous hardcoded\n edge-to-edge values below, so an unconfigured Sheet renders unchanged.\n Overriding one (e.g. --sheet-top to clear a fixed header, or --sheet-bottom:\n auto to size to content) turns the panel from an edge-to-edge slide-in into\n an anchored floating panel, without needing a different component. */.sheet-panel.left.svelte-1dln6bq,\n .sheet-panel.right.svelte-1dln6bq {top:var(--sheet-top, 0);bottom:var(--sheet-bottom, 0);width:var(--sheet-width, 400px);max-width:var(--sheet-max-width, 100vw);}.sheet-panel.left.svelte-1dln6bq {left:var(--sheet-left, 0);border-right:var(--sheet-border, none);}.sheet-panel.right.svelte-1dln6bq {right:var(--sheet-right, 0);border-left:var(--sheet-border, none);}\n\n /* Top/bottom stretch edge to edge by default, exactly as before: --sheet-\n band-width is `auto`, so `margin-inline: auto` has nothing to distribute\n and the panel still spans --sheet-left to --sheet-right.\n\n Setting --sheet-band-width (or --sheet-band-max-width) caps it, and the\n auto margins then centre it between those same two insets -- which is the\n shape a bottom \"launch\" sheet wants above phone widths, and previously\n had to be faked with hand-computed calc() offsets.\n\n Deliberately NOT --sheet-width/--sheet-max-width, even though the issue\n proposed those names. Those already mean \"the width of a left/right\n panel\", so a consumer who themes them for their side sheets would find\n their bottom sheets silently reshaped by an upgrade. side=\"center\" avoids\n the same collision the same way, with its own --sheet-center-* tokens. */.sheet-panel.top.svelte-1dln6bq,\n .sheet-panel.bottom.svelte-1dln6bq {left:var(--sheet-left, 0);right:var(--sheet-right, 0);height:var(--sheet-height, 300px);max-height:var(--sheet-max-height, 100vh);width:var(--sheet-band-width, auto);max-width:var(--sheet-band-max-width, none);box-sizing:var(--sheet-band-box-sizing, content-box);margin-inline:auto;border:var(--sheet-band-border, none);}\n\n /* A capped panel is a floating card and needs all four edges; an\n edge-to-edge one deliberately draws only the edge it enters from. The\n entering edge falls back through --sheet-border so an existing theme that\n sets only that keeps rendering exactly as it did. */.sheet-panel.top.svelte-1dln6bq {top:var(--sheet-top, 0);border-bottom:var(--sheet-band-border, var(--sheet-border, none));}.sheet-panel.bottom.svelte-1dln6bq {bottom:var(--sheet-bottom, 0);border-top:var(--sheet-band-border, var(--sheet-border, none));}\n\n /* `side=\"center\"` is a fixed-size floating dialog, not an edge-anchored\n panel: no top/bottom/left/right offset, sized by its own tokens rather\n than --sheet-width/--sheet-height (so an existing left/right/top/bottom\n theme is untouched by adding this variant), and centered with a\n transform instead of stretching to an edge. */.sheet-panel.center.svelte-1dln6bq {top:50%;left:50%;transform:translate(-50%, -50%);width:var(--sheet-center-width, 480px);max-width:var(--sheet-center-max-width, calc(100vw - 32px));max-height:var(--sheet-center-max-height, 90vh);}.sheet-header.svelte-1dln6bq {display:flex;align-items:center;padding:var(--sheet-header-padding, 16px 20px);background-color:var(--sheet-header-background, inherit);border-bottom:var(--sheet-header-border-bottom, 1px solid #e0e0e0);flex-shrink:0;}.sheet-title.svelte-1dln6bq {flex:1;font-size:var(--sheet-title-font-size, 18px);font-weight:var(--sheet-title-font-weight, 600);font-family:var(--sheet-title-font-family, inherit);color:var(--sheet-title-color, #1a1a1a);line-height:var(--sheet-title-line-height, 1.4);}.sheet-close-button.svelte-1dln6bq {--button-width: var(--sheet-close-button-size, 32px);--button-height: var(--sheet-close-button-size, 32px);--button-border: none;--button-border-radius: var(--sheet-close-button-border-radius, var(--radius, 4px));--button-color: var(--sheet-close-button-background, transparent);--button-text-color: var(--sheet-close-button-color, #666666);--button-font-size: var(--sheet-close-button-font-size, 16px);--button-padding: 0;--button-hover-color: var(--sheet-close-button-hover-background, #f0f0f0);flex-shrink:0;display:flex;align-items:center;justify-content:center;}.sheet-content.svelte-1dln6bq {flex:1;overflow-y:var(--sheet-content-overflow-y, auto);padding:var(--sheet-content-padding, 20px);scrollbar-width:var(--sheet-scrollbar-width, none);}.sheet-content.svelte-1dln6bq::-webkit-scrollbar {display:none;}.sheet-footer.svelte-1dln6bq {padding:var(--sheet-footer-padding, 16px 20px);background-color:var(--sheet-footer-background, inherit);border-top:var(--sheet-footer-border-top, 1px solid #e0e0e0);flex-shrink:0;}"
|
|
17680
17680
|
};
|
|
17681
17681
|
function Sheet(e, t) {
|
|
17682
17682
|
push(t, !0), append_styles$1(e, $$css$33);
|
|
@@ -17731,10 +17731,11 @@ function Sheet(e, t) {
|
|
|
17731
17731
|
}
|
|
17732
17732
|
}
|
|
17733
17733
|
function Re(e) {
|
|
17734
|
+
let t = document.activeElement, n = !0;
|
|
17734
17735
|
return lockBodyScroll(), tick().then(() => {
|
|
17735
|
-
get(te) !== null && get(te).focus();
|
|
17736
|
+
n && get(te) !== null && get(te).focus();
|
|
17736
17737
|
}), { destroy() {
|
|
17737
|
-
unlockBodyScroll();
|
|
17738
|
+
n = !1, unlockBodyScroll(), t instanceof HTMLElement && t.isConnected && (document.activeElement === document.body || e.contains(document.activeElement)) && t.focus();
|
|
17738
17739
|
} };
|
|
17739
17740
|
}
|
|
17740
17741
|
function Ue() {
|