@lapismd/design-core 0.1.2 → 0.2.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/CHANGELOG.md +22 -0
- package/LICENSE.md +3 -3
- package/README.md +20 -0
- package/package.json +24 -9
- package/spec/src/styling-and-themes.md +2 -0
- package/src/shared/ai/chat.css +23 -0
- package/src/shared/ai/chat.ts +12 -0
- package/src/shared/ai/context.svelte.ts +2 -0
- package/src/shared/ai/layout/Layout.svelte +116 -10
- package/src/shared/ai/message-list/MessageList.svelte +123 -43
- package/src/shared/ai/message-list/MessageListHistoryFixture.svelte +112 -0
- package/src/shared/ai/message-list/MessageListLegacyFixture.svelte +52 -0
- package/src/shared/ai/message-list/VirtualizedMessageRows.svelte +299 -0
- package/src/shared/ai/message-list/position.ts +7 -0
- package/src/shared/ai/new-messages.svelte.ts +24 -5
- package/src/shared/ai/stream-scroll.svelte.ts +135 -6
- package/src/shared/ai/tool-call-detail/ToolCallDetail.svelte +71 -0
- package/src/shared/ai/tool-call-detail/tool-call-detail.ts +209 -0
- package/src/shared/diff/core/merge/actions.ts +4 -3
- package/src/shared/diff/core/merge/render-model.ts +14 -10
- package/src/shared/diff/file-diff/FileDiff.css +68 -1
- package/src/shared/diff/file-diff/FileDiff.svelte +22 -6
- package/src/shared/diff/file-diff/FileDiffComposer.svelte +98 -16
- package/src/shared/diff/file-diff/index.ts +2 -0
- package/src/shared/diff/file-diff/types.ts +13 -0
- package/src/shared/diff/index.ts +2 -0
- package/src/shared/forms/confirm-button/ConfirmButton.svelte +38 -0
- package/src/shared/forms/confirm-button/ConfirmButtonExample.svelte +14 -0
- package/src/shared/forms/confirm-button/index.ts +1 -0
- package/src/shared/forms/confirm-dialog/ConfirmDialog.css +21 -0
- package/src/shared/forms/confirm-dialog/ConfirmDialog.svelte +116 -0
- package/src/shared/forms/confirm-dialog/ConfirmDialogExample.svelte +17 -0
- package/src/shared/forms/confirm-dialog/index.ts +2 -0
- package/src/shared/forms/dialog-frame/DialogFrame.css +130 -0
- package/src/shared/forms/dialog-frame/DialogFrame.svelte +108 -0
- package/src/shared/forms/dialog-frame/DialogFrameExample.svelte +37 -0
- package/src/shared/forms/dialog-frame/index.ts +6 -0
- package/src/shared/forms/dialog.ts +8 -0
- package/src/shared/forms/index.ts +11 -0
- package/src/shared/shadcn/button/button.svelte +4 -0
- package/src/shared/shadcn/code-block/highlightRanges.ts +10 -6
- package/src/shared/shadcn/code-block/syntax/defineSyntaxTheme.ts +4 -2
- package/src/shared/shadcn/code-block/tokenizer.ts +3 -3
- package/src/shared/shadcn/dialog/dialog-content.svelte +3 -4
- package/src/shared/shadcn/dialog/dialog-portal.svelte +10 -2
- package/src/shared/shadcn/tooltip/tooltip-content.svelte +10 -4
- package/src/shared/shadcn/tooltip/tooltip.tokens.ts +4 -0
- package/src/shared/shell/app-shell/AppShell.css +112 -32
- package/src/shared/shell/app-shell/AppShellMain.svelte +12 -1
- package/src/shared/shell/app-shell/AppShellRoot.svelte +27 -13
- package/src/shared/shell/app-shell/AppShellSidebar.svelte +121 -19
- package/src/shared/shell/app-shell/AppShellSidebarClose.svelte +17 -17
- package/src/shared/shell/app-shell/AppShellSidebarToggle.svelte +38 -58
- package/src/shared/shell/app-shell/AppShellSurfaceLayer.svelte +173 -0
- package/src/shared/shell/app-shell/AppShellSurfaceLayerBody.svelte +32 -0
- package/src/shared/shell/app-shell/AppShellSurfaceLayerHeader.svelte +26 -0
- package/src/shared/shell/app-shell/app-shell-context.svelte.ts +6 -3
- package/src/shared/shell/app-shell/app-shell-controller.svelte.ts +246 -2
- package/src/shared/shell/app-shell/app-shell-sidebar-context.svelte.ts +1 -0
- package/src/shared/shell/app-shell/examples/AppShellExamples.css +103 -0
- package/src/shared/shell/app-shell/examples/AppShellMultiPanelDemo.svelte +187 -0
- package/src/shared/shell/app-shell/index.ts +14 -0
- package/src/shared/shell/shell.tokens.css +2 -0
- package/src/shared/shell/shell.tokens.ts +5 -0
- package/src/theme.css +10 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { ComponentProps, Snippet } from "svelte";
|
|
3
|
+
import type * as DialogTypes from "../../shadcn/dialog/index.js";
|
|
4
|
+
|
|
5
|
+
export type DialogFrameSize = "compact" | "form" | "large" | "wide";
|
|
6
|
+
export type DialogFrameSurface = "plain" | "inset";
|
|
7
|
+
export type DialogFrameProps = Omit<
|
|
8
|
+
ComponentProps<typeof DialogTypes.Content>,
|
|
9
|
+
"children" | "title" | "showCloseButton" | "dataUiComponent" | "dataUiPart"
|
|
10
|
+
> & {
|
|
11
|
+
title: string | Snippet;
|
|
12
|
+
description?: string | Snippet;
|
|
13
|
+
descriptionHidden?: boolean;
|
|
14
|
+
size?: DialogFrameSize;
|
|
15
|
+
/** Visual treatment for the dialog shell and main content surface. */
|
|
16
|
+
surface?: DialogFrameSurface;
|
|
17
|
+
busy?: boolean;
|
|
18
|
+
closeLabel?: string;
|
|
19
|
+
sidebar?: Snippet;
|
|
20
|
+
headerActions?: Snippet;
|
|
21
|
+
footer?: Snippet;
|
|
22
|
+
children: Snippet;
|
|
23
|
+
bodyPadding?: "default" | "none";
|
|
24
|
+
};
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<script lang="ts">
|
|
28
|
+
import * as Dialog from "../../shadcn/dialog/index.js";
|
|
29
|
+
import { Button } from "../../shadcn/button/index.js";
|
|
30
|
+
import { ScrollArea } from "../../shadcn/scroll-area/index.js";
|
|
31
|
+
import XIcon from "@lucide/svelte/icons/x";
|
|
32
|
+
import "./DialogFrame.css";
|
|
33
|
+
|
|
34
|
+
let {
|
|
35
|
+
title,
|
|
36
|
+
description,
|
|
37
|
+
descriptionHidden = false,
|
|
38
|
+
size = "form",
|
|
39
|
+
surface = "plain",
|
|
40
|
+
busy = false,
|
|
41
|
+
closeLabel = "Close",
|
|
42
|
+
sidebar,
|
|
43
|
+
headerActions,
|
|
44
|
+
footer,
|
|
45
|
+
children,
|
|
46
|
+
bodyPadding = "default",
|
|
47
|
+
ref = $bindable(null),
|
|
48
|
+
onInteractOutside,
|
|
49
|
+
onEscapeKeydown,
|
|
50
|
+
...contentProps
|
|
51
|
+
}: DialogFrameProps = $props();
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<Dialog.Content
|
|
55
|
+
{...contentProps}
|
|
56
|
+
bind:ref
|
|
57
|
+
showCloseButton={false}
|
|
58
|
+
data-ui-dialog-frame=""
|
|
59
|
+
data-frame-size={size}
|
|
60
|
+
data-frame-surface={surface}
|
|
61
|
+
data-frame-padding={bodyPadding}
|
|
62
|
+
onInteractOutside={(event) => {
|
|
63
|
+
if (busy) event.preventDefault();
|
|
64
|
+
else onInteractOutside?.(event);
|
|
65
|
+
}}
|
|
66
|
+
onEscapeKeydown={(event) => {
|
|
67
|
+
if (busy) event.preventDefault();
|
|
68
|
+
else onEscapeKeydown?.(event);
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
<div data-ui-part="dialog-frame-header">
|
|
72
|
+
<div data-ui-part="dialog-frame-heading">
|
|
73
|
+
<Dialog.Title
|
|
74
|
+
>{#if typeof title === "string"}{title}{:else}{@render title()}{/if}</Dialog.Title
|
|
75
|
+
>
|
|
76
|
+
{#if description}<Dialog.Description
|
|
77
|
+
class={descriptionHidden ? "sr-only" : undefined}
|
|
78
|
+
>{#if typeof description === "string"}{description}{:else}{@render description()}{/if}</Dialog.Description
|
|
79
|
+
>{/if}
|
|
80
|
+
</div>
|
|
81
|
+
{@render headerActions?.()}
|
|
82
|
+
<Dialog.Close>
|
|
83
|
+
{#snippet child({ props })}
|
|
84
|
+
<Button
|
|
85
|
+
{...props}
|
|
86
|
+
variant="ghost"
|
|
87
|
+
size="icon-sm"
|
|
88
|
+
disabled={busy}
|
|
89
|
+
aria-label={closeLabel}
|
|
90
|
+
data-ui-part="dialog-frame-close"><XIcon aria-hidden="true" /></Button
|
|
91
|
+
>
|
|
92
|
+
{/snippet}
|
|
93
|
+
</Dialog.Close>
|
|
94
|
+
</div>
|
|
95
|
+
<div data-ui-part="dialog-frame-layout" data-has-sidebar={Boolean(sidebar)}>
|
|
96
|
+
{#if sidebar}<aside data-ui-part="dialog-frame-sidebar">
|
|
97
|
+
{@render sidebar()}
|
|
98
|
+
</aside>{/if}
|
|
99
|
+
<div data-ui-part="dialog-frame-main">
|
|
100
|
+
<ScrollArea class="ui-dialog-frame-scroll" type="always">
|
|
101
|
+
<div data-ui-part="dialog-frame-body">{@render children()}</div>
|
|
102
|
+
</ScrollArea>
|
|
103
|
+
{#if footer}<Dialog.Footer data-ui-part="dialog-frame-footer"
|
|
104
|
+
>{@render footer()}</Dialog.Footer
|
|
105
|
+
>{/if}
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
</Dialog.Content>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { DialogFrame } from "@lapismd/design-core/forms/dialog";
|
|
3
|
+
import * as Dialog from "@lapismd/design-core/shadcn/dialog";
|
|
4
|
+
import { Button } from "@lapismd/design-core/shadcn/button";
|
|
5
|
+
import { Input } from "@lapismd/design-core/shadcn/input";
|
|
6
|
+
let open = $state(false);
|
|
7
|
+
let name = $state("");
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<Dialog.Root bind:open>
|
|
11
|
+
<Dialog.Trigger
|
|
12
|
+
>{#snippet child({ props })}<Button {...props}>Edit record</Button
|
|
13
|
+
>{/snippet}</Dialog.Trigger
|
|
14
|
+
>
|
|
15
|
+
<DialogFrame
|
|
16
|
+
title="Edit record"
|
|
17
|
+
description={name
|
|
18
|
+
? `Editing ${name}`
|
|
19
|
+
: "The form scrolls while its actions remain visible."}
|
|
20
|
+
size="large"
|
|
21
|
+
surface="inset"
|
|
22
|
+
class={name ? "record-filled" : "record-empty"}
|
|
23
|
+
>
|
|
24
|
+
{#snippet sidebar()}<nav aria-label="Sections">
|
|
25
|
+
<Button variant="secondary">Details</Button>
|
|
26
|
+
</nav>{/snippet}
|
|
27
|
+
{#each Array.from({ length: 24 }) as _, index}<label
|
|
28
|
+
style="display: grid; gap: 0.5rem; margin-block: 1rem;"
|
|
29
|
+
>Field {index + 1}{#if index === 0}<Input
|
|
30
|
+
bind:value={name}
|
|
31
|
+
/>{:else}<Input />{/if}</label
|
|
32
|
+
>{/each}
|
|
33
|
+
{#snippet footer()}<Button variant="outline" onclick={() => (open = false)}
|
|
34
|
+
>Cancel</Button
|
|
35
|
+
><Button onclick={() => (open = false)}>Save</Button>{/snippet}
|
|
36
|
+
</DialogFrame>
|
|
37
|
+
</Dialog.Root>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { DialogFrame } from "./dialog-frame/index.js";
|
|
2
|
+
export type {
|
|
3
|
+
DialogFrameProps,
|
|
4
|
+
DialogFrameSize,
|
|
5
|
+
} from "./dialog-frame/index.js";
|
|
6
|
+
export { ConfirmDialog } from "./confirm-dialog/index.js";
|
|
7
|
+
export type { ConfirmDialogProps } from "./confirm-dialog/index.js";
|
|
8
|
+
export { ConfirmButton } from "./confirm-button/index.js";
|
|
@@ -129,3 +129,14 @@ export {
|
|
|
129
129
|
export type { InlineOptionPickerOption } from "./inline-option-picker/InlineOptionPicker.svelte";
|
|
130
130
|
export type { AddSectionOption } from "./add-section-chooser/AddSectionChooser.svelte";
|
|
131
131
|
export * from "./core/core";
|
|
132
|
+
|
|
133
|
+
export {
|
|
134
|
+
DialogFrame,
|
|
135
|
+
type DialogFrameProps,
|
|
136
|
+
type DialogFrameSize,
|
|
137
|
+
} from "./dialog-frame/index.js";
|
|
138
|
+
export {
|
|
139
|
+
ConfirmDialog,
|
|
140
|
+
type ConfirmDialogProps,
|
|
141
|
+
} from "./confirm-dialog/index.js";
|
|
142
|
+
export { ConfirmButton } from "./confirm-button/index.js";
|
|
@@ -276,6 +276,7 @@
|
|
|
276
276
|
}
|
|
277
277
|
[data-ui-component="button"][data-variant="outline"]:hover,
|
|
278
278
|
[data-ui-component="button"][data-variant="ghost"]:hover {
|
|
279
|
+
background-color: var(--accent);
|
|
279
280
|
color: var(--foreground);
|
|
280
281
|
}
|
|
281
282
|
[data-ui-component="button"][data-variant="link"]:hover {
|
|
@@ -294,6 +295,9 @@
|
|
|
294
295
|
);
|
|
295
296
|
}
|
|
296
297
|
}
|
|
298
|
+
[data-ui-component="button"][data-variant="ghost"]:focus-visible {
|
|
299
|
+
background-color: var(--accent);
|
|
300
|
+
}
|
|
297
301
|
[data-ui-component="button"]:focus-visible {
|
|
298
302
|
border-color: var(--ui-button-focus-ring-color, var(--ring));
|
|
299
303
|
}
|
|
@@ -179,8 +179,9 @@ function applyRangesToContainer(
|
|
|
179
179
|
for (let i = 0; i < lineDivs.length; i++) {
|
|
180
180
|
const tokenIndex = globalLineOffset + i;
|
|
181
181
|
const tokens = tokenLines[tokenIndex];
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
const lineDiv = lineDivs[i];
|
|
183
|
+
if (lineDiv && tokens && tokens.length > 0) {
|
|
184
|
+
applyLineRanges(lineDiv, tokens, results, resolve);
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
return results;
|
|
@@ -216,6 +217,7 @@ export function applyHighlightRangesChunked(
|
|
|
216
217
|
|
|
217
218
|
for (let i = 0; i < codeEl.children.length; i++) {
|
|
218
219
|
const child = codeEl.children[i];
|
|
220
|
+
if (!child) continue;
|
|
219
221
|
const lineDivs = child.querySelectorAll("[data-line]");
|
|
220
222
|
if (
|
|
221
223
|
lineDivs.length > 0 &&
|
|
@@ -235,8 +237,9 @@ export function applyHighlightRangesChunked(
|
|
|
235
237
|
const lineDivs = codeEl.querySelectorAll("[data-line]");
|
|
236
238
|
for (let i = 0; i < lineDivs.length; i++) {
|
|
237
239
|
const tokens = tokenLines[i];
|
|
238
|
-
|
|
239
|
-
|
|
240
|
+
const lineDiv = lineDivs[i];
|
|
241
|
+
if (lineDiv && tokens && tokens.length > 0) {
|
|
242
|
+
applyLineRanges(lineDiv, tokens, allRanges, resolve);
|
|
240
243
|
}
|
|
241
244
|
}
|
|
242
245
|
return () => cleanupRanges(allRanges);
|
|
@@ -253,7 +256,7 @@ export function applyHighlightRangesChunked(
|
|
|
253
256
|
const ranges = applyRangesToContainer(
|
|
254
257
|
wrapper,
|
|
255
258
|
tokenLines,
|
|
256
|
-
chunkLineOffsets[index],
|
|
259
|
+
chunkLineOffsets[index] ?? 0,
|
|
257
260
|
resolve,
|
|
258
261
|
);
|
|
259
262
|
chunkRanges.set(wrapper, ranges);
|
|
@@ -269,6 +272,7 @@ export function applyHighlightRangesChunked(
|
|
|
269
272
|
|
|
270
273
|
for (let i = 0; i < chunkWrappers.length; i++) {
|
|
271
274
|
const wrapper = chunkWrappers[i];
|
|
275
|
+
if (!wrapper) continue;
|
|
272
276
|
|
|
273
277
|
const handler = (e: Event) => {
|
|
274
278
|
// contentvisibilityautostatechange fires with .skipped = true when
|
|
@@ -347,7 +351,7 @@ export function applyHighlightRangesBatch(
|
|
|
347
351
|
|
|
348
352
|
const lineDiv = lineDivs[divIndex];
|
|
349
353
|
const tokens = tokenLines[i];
|
|
350
|
-
if (tokens && tokens.length > 0) {
|
|
354
|
+
if (lineDiv && tokens && tokens.length > 0) {
|
|
351
355
|
applyLineRanges(lineDiv, tokens, results, resolve);
|
|
352
356
|
}
|
|
353
357
|
}
|
|
@@ -60,11 +60,13 @@ export function resolveSyntaxTokenForMode(
|
|
|
60
60
|
mode: "light" | "dark",
|
|
61
61
|
): string {
|
|
62
62
|
if (Array.isArray(value)) {
|
|
63
|
-
return mode === "dark" ? value[1] : value[0];
|
|
63
|
+
return (mode === "dark" ? value[1] : value[0]) ?? "";
|
|
64
64
|
}
|
|
65
65
|
const match = value.match(/^light-dark\(([^,]+),([^)]+)\)$/);
|
|
66
66
|
if (match) {
|
|
67
|
-
return mode === "dark"
|
|
67
|
+
return mode === "dark"
|
|
68
|
+
? (match[2]?.trim() ?? "")
|
|
69
|
+
: (match[1]?.trim() ?? "");
|
|
68
70
|
}
|
|
69
71
|
return value;
|
|
70
72
|
}
|
|
@@ -517,13 +517,13 @@ export function flatTokensToLines(
|
|
|
517
517
|
for (const token of tokens) {
|
|
518
518
|
while (
|
|
519
519
|
lineIdx < lineStarts.length - 1 &&
|
|
520
|
-
token.start >= lineStarts[lineIdx + 1]
|
|
520
|
+
token.start >= (lineStarts[lineIdx + 1] ?? Number.POSITIVE_INFINITY)
|
|
521
521
|
) {
|
|
522
522
|
lineIdx++;
|
|
523
523
|
}
|
|
524
524
|
|
|
525
|
-
const lineStart = lineStarts[lineIdx];
|
|
526
|
-
result[lineIdx]
|
|
525
|
+
const lineStart = lineStarts[lineIdx] ?? 0;
|
|
526
|
+
result[lineIdx]?.push({
|
|
527
527
|
type: token.type,
|
|
528
528
|
start: token.start - lineStart,
|
|
529
529
|
end: token.end - lineStart,
|
|
@@ -50,7 +50,6 @@
|
|
|
50
50
|
variant="ghost"
|
|
51
51
|
size="icon-sm"
|
|
52
52
|
{...props}
|
|
53
|
-
dataUiComponent="dialog"
|
|
54
53
|
data-ui-part="dialog-content-anon-0"
|
|
55
54
|
data-slot="dialog-content-anon-0"
|
|
56
55
|
>
|
|
@@ -75,7 +74,7 @@
|
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
76
|
@layer utilities {
|
|
78
|
-
[data-ui-component="
|
|
77
|
+
[data-ui-component="button"][data-ui-part="dialog-content-anon-0"] {
|
|
79
78
|
position: absolute;
|
|
80
79
|
}
|
|
81
80
|
[data-ui-component="dialog"][data-ui-part="dialog-content"],
|
|
@@ -88,10 +87,10 @@
|
|
|
88
87
|
[data-ui-component="dialog"][data-ui-part="dialog-content"] {
|
|
89
88
|
top: 50%;
|
|
90
89
|
}
|
|
91
|
-
[data-ui-component="
|
|
90
|
+
[data-ui-component="button"][data-ui-part="dialog-content-anon-0"] {
|
|
92
91
|
top: calc(var(--spacing) * 4);
|
|
93
92
|
}
|
|
94
|
-
[data-ui-component="
|
|
93
|
+
[data-ui-component="button"][data-ui-part="dialog-content-anon-0"] {
|
|
95
94
|
right: calc(var(--spacing) * 4);
|
|
96
95
|
}
|
|
97
96
|
[data-ui-component="dialog"][data-ui-part="dialog-content"] {
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Dialog as DialogPrimitive } from "bits-ui";
|
|
3
3
|
|
|
4
|
-
let {
|
|
4
|
+
let { to, disabled, children }: DialogPrimitive.PortalProps = $props();
|
|
5
|
+
const target = $derived(to);
|
|
6
|
+
const portalDisabled = $derived(disabled);
|
|
5
7
|
</script>
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
<!-- Keep portal inputs independent of reactive content so updates do not remount it. -->
|
|
10
|
+
<DialogPrimitive.Portal
|
|
11
|
+
{...target === undefined ? {} : { to: target }}
|
|
12
|
+
{...portalDisabled === undefined ? {} : { disabled: portalDisabled }}
|
|
13
|
+
>
|
|
14
|
+
{@render children?.()}
|
|
15
|
+
</DialogPrimitive.Portal>
|
|
@@ -119,14 +119,20 @@
|
|
|
119
119
|
fill: var(--foreground);
|
|
120
120
|
}
|
|
121
121
|
[data-ui-component="tooltip"][data-ui-part="tooltip-content"] {
|
|
122
|
-
padding-inline:
|
|
122
|
+
padding-inline: var(
|
|
123
|
+
--ui-tooltip-padding-inline,
|
|
124
|
+
calc(var(--spacing) * 2.5)
|
|
125
|
+
);
|
|
123
126
|
}
|
|
124
127
|
[data-ui-component="tooltip"][data-ui-part="tooltip-content"] {
|
|
125
|
-
padding-block:
|
|
128
|
+
padding-block: var(
|
|
129
|
+
--ui-tooltip-padding-block,
|
|
130
|
+
calc(var(--spacing) * 1)
|
|
131
|
+
);
|
|
126
132
|
}
|
|
127
133
|
[data-ui-component="tooltip"][data-ui-part="tooltip-content"] {
|
|
128
|
-
font-size: var(--
|
|
129
|
-
line-height: var(--
|
|
134
|
+
font-size: var(--ui-tooltip-font-size, 0.6875rem);
|
|
135
|
+
line-height: var(--ui-tooltip-line-height, 1rem);
|
|
130
136
|
}
|
|
131
137
|
[data-ui-component="tooltip"][data-ui-part="tooltip-content"] {
|
|
132
138
|
color: var(--ui-tooltip-foreground, var(--background));
|
|
@@ -4,6 +4,10 @@ export const tooltipTokenNames = {
|
|
|
4
4
|
borderColor: "--ui-tooltip-border-color",
|
|
5
5
|
radius: "--ui-tooltip-radius",
|
|
6
6
|
focusRingColor: "--ui-tooltip-focus-ring-color",
|
|
7
|
+
fontSize: "--ui-tooltip-font-size",
|
|
8
|
+
lineHeight: "--ui-tooltip-line-height",
|
|
9
|
+
paddingInline: "--ui-tooltip-padding-inline",
|
|
10
|
+
paddingBlock: "--ui-tooltip-padding-block",
|
|
7
11
|
} as const;
|
|
8
12
|
|
|
9
13
|
export type TooltipToken =
|
|
@@ -64,6 +64,10 @@
|
|
|
64
64
|
background: transparent;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
.ui-minimal-app-shell__sidebar[hidden] {
|
|
68
|
+
display: none !important;
|
|
69
|
+
}
|
|
70
|
+
|
|
67
71
|
.ui-minimal-app-shell__sidebar[data-side="left"] {
|
|
68
72
|
width: var(--ui-shell-sidebar-size, var(--ui-shell-left-sidebar-width));
|
|
69
73
|
}
|
|
@@ -78,12 +82,19 @@
|
|
|
78
82
|
background: var(--background);
|
|
79
83
|
}
|
|
80
84
|
|
|
85
|
+
.ui-minimal-app-shell__sidebar[data-variant="rail"][data-presentation="inline"] {
|
|
86
|
+
margin-block: var(--ui-shell-main-block-inset);
|
|
87
|
+
border: 0;
|
|
88
|
+
border-radius: 0;
|
|
89
|
+
background: transparent;
|
|
90
|
+
box-shadow: none;
|
|
91
|
+
}
|
|
92
|
+
|
|
81
93
|
.ui-minimal-app-shell__sidebar[data-variant="outer"][data-side="left"][data-presentation="inline"] {
|
|
82
94
|
border-inline-end: 1px solid var(--border);
|
|
83
95
|
}
|
|
84
96
|
|
|
85
|
-
.ui-minimal-app-shell__sidebar[data-presentation="overlay"]
|
|
86
|
-
.ui-minimal-app-shell__sidebar[data-desktop-overlay-preview] {
|
|
97
|
+
.ui-minimal-app-shell__sidebar[data-presentation="overlay"] {
|
|
87
98
|
position: absolute;
|
|
88
99
|
z-index: 31;
|
|
89
100
|
inset-block: 0;
|
|
@@ -92,14 +103,12 @@
|
|
|
92
103
|
color-mix(in srgb, var(--foreground) 18%, transparent);
|
|
93
104
|
}
|
|
94
105
|
|
|
95
|
-
.ui-minimal-app-shell__sidebar[data-presentation="overlay"][data-side="left"]
|
|
96
|
-
.ui-minimal-app-shell__sidebar[data-desktop-overlay-preview][data-side="left"] {
|
|
106
|
+
.ui-minimal-app-shell__sidebar[data-presentation="overlay"][data-side="left"] {
|
|
97
107
|
inset-inline-start: 0;
|
|
98
108
|
border-inline-end: 1px solid var(--border);
|
|
99
109
|
}
|
|
100
110
|
|
|
101
|
-
.ui-minimal-app-shell__sidebar[data-presentation="overlay"][data-side="right"]
|
|
102
|
-
.ui-minimal-app-shell__sidebar[data-desktop-overlay-preview][data-side="right"] {
|
|
111
|
+
.ui-minimal-app-shell__sidebar[data-presentation="overlay"][data-side="right"] {
|
|
103
112
|
inset-inline-end: 0;
|
|
104
113
|
margin-inline-start: 0;
|
|
105
114
|
border-inline-start: 1px solid var(--border);
|
|
@@ -139,24 +148,27 @@
|
|
|
139
148
|
display: block;
|
|
140
149
|
}
|
|
141
150
|
|
|
142
|
-
.ui-minimal-app-
|
|
143
|
-
> .ui-minimal-app-shell__composition
|
|
144
|
-
> .ui-minimal-app-shell__sidebar[data-side="right"]:not(
|
|
145
|
-
[data-presentation="overlay"]
|
|
146
|
-
):not([data-desktop-overlay-preview]),
|
|
147
|
-
.ui-minimal-app-shell[data-desktop-overlay-left]
|
|
148
|
-
> .ui-minimal-app-shell__composition
|
|
149
|
-
> .ui-minimal-app-shell__sidebar[data-mobile-panel-id="left"]:not(
|
|
150
|
-
[data-presentation="overlay"]
|
|
151
|
-
):not([data-desktop-overlay-preview]),
|
|
152
|
-
.ui-minimal-app-shell[data-desktop-overlay-outer-left]
|
|
153
|
-
> .ui-minimal-app-shell__composition
|
|
154
|
-
> .ui-minimal-app-shell__sidebar[data-side="left"][data-variant="outer"]:not(
|
|
155
|
-
[data-presentation="overlay"]
|
|
156
|
-
):not([data-desktop-overlay-preview]) {
|
|
151
|
+
.ui-minimal-app-shell__sidebar[data-desktop-constrained][data-constrained-presentation="preview"][data-presentation="inline"] {
|
|
157
152
|
display: none;
|
|
158
153
|
}
|
|
159
154
|
|
|
155
|
+
.ui-minimal-app-shell__sidebar[data-presentation="replace-main"] {
|
|
156
|
+
position: absolute;
|
|
157
|
+
z-index: 31;
|
|
158
|
+
inset-block-start: var(--ui-shell-replacement-block-start, 0px);
|
|
159
|
+
inset-block-end: var(--ui-shell-replacement-block-end, 0px);
|
|
160
|
+
inset-inline-start: var(--ui-shell-replacement-inline-start, 0px);
|
|
161
|
+
inset-inline-end: var(--ui-shell-replacement-inline-end, 0px);
|
|
162
|
+
display: flex;
|
|
163
|
+
width: auto;
|
|
164
|
+
overflow: hidden;
|
|
165
|
+
margin: 0;
|
|
166
|
+
border: var(--ui-shell-main-border);
|
|
167
|
+
border-radius: var(--ui-shell-main-radius);
|
|
168
|
+
background: var(--background);
|
|
169
|
+
box-shadow: none;
|
|
170
|
+
}
|
|
171
|
+
|
|
160
172
|
.ui-minimal-app-shell__sidebar[data-side="right"][data-state="expanded"] {
|
|
161
173
|
border-inline-start: 1px solid var(--border);
|
|
162
174
|
}
|
|
@@ -171,13 +183,11 @@
|
|
|
171
183
|
min-width: 0;
|
|
172
184
|
}
|
|
173
185
|
|
|
174
|
-
.ui-minimal-app-shell__sidebar[data-presentation="overlay"][data-side="left"]
|
|
175
|
-
.ui-minimal-app-shell__sidebar[data-desktop-overlay-preview][data-side="left"] {
|
|
186
|
+
.ui-minimal-app-shell__sidebar[data-presentation="overlay"][data-side="left"] {
|
|
176
187
|
width: var(--ui-shell-sidebar-size, var(--ui-shell-left-sidebar-width));
|
|
177
188
|
}
|
|
178
189
|
|
|
179
|
-
.ui-minimal-app-shell__sidebar[data-presentation="overlay"][data-side="right"]
|
|
180
|
-
.ui-minimal-app-shell__sidebar[data-desktop-overlay-preview][data-side="right"] {
|
|
190
|
+
.ui-minimal-app-shell__sidebar[data-presentation="overlay"][data-side="right"] {
|
|
181
191
|
width: var(--ui-shell-sidebar-size, var(--ui-shell-right-sidebar-width));
|
|
182
192
|
}
|
|
183
193
|
|
|
@@ -271,6 +281,76 @@
|
|
|
271
281
|
box-shadow: var(--ui-shell-main-shadow);
|
|
272
282
|
}
|
|
273
283
|
|
|
284
|
+
.ui-minimal-app-shell__surface-layer {
|
|
285
|
+
position: absolute;
|
|
286
|
+
z-index: 32;
|
|
287
|
+
min-width: 0;
|
|
288
|
+
min-height: 0;
|
|
289
|
+
pointer-events: none;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.ui-minimal-app-shell__surface-layer-scrim {
|
|
293
|
+
position: absolute;
|
|
294
|
+
inset: 0;
|
|
295
|
+
padding: 0;
|
|
296
|
+
border: 0;
|
|
297
|
+
border-radius: var(--ui-shell-main-radius);
|
|
298
|
+
background: color-mix(in oklab, var(--background) 75%, transparent);
|
|
299
|
+
pointer-events: auto;
|
|
300
|
+
cursor: pointer;
|
|
301
|
+
transition: background-color 150ms ease;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.ui-minimal-app-shell__surface-layer-scrim:hover {
|
|
305
|
+
background: color-mix(in oklab, var(--background) 65%, transparent);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.ui-minimal-app-shell__surface-layer-surface {
|
|
309
|
+
position: absolute;
|
|
310
|
+
inset-block: 0;
|
|
311
|
+
inset-inline-start: var(--ui-shell-surface-layer-main-start-allowance);
|
|
312
|
+
inset-inline-end: var(--ui-shell-surface-layer-inline-end-inset);
|
|
313
|
+
display: grid;
|
|
314
|
+
min-width: 0;
|
|
315
|
+
min-height: 0;
|
|
316
|
+
overflow: hidden;
|
|
317
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
318
|
+
border: var(--ui-shell-main-border);
|
|
319
|
+
border-radius: var(--ui-shell-main-radius);
|
|
320
|
+
outline: none;
|
|
321
|
+
background: var(--background);
|
|
322
|
+
box-shadow: none;
|
|
323
|
+
pointer-events: auto;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.ui-minimal-app-shell__surface-layer-surface:focus-visible {
|
|
327
|
+
outline: 2px solid var(--ring);
|
|
328
|
+
outline-offset: -2px;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.ui-minimal-app-shell__surface-layer-header {
|
|
332
|
+
display: flex;
|
|
333
|
+
min-width: 0;
|
|
334
|
+
min-height: var(--ui-shell-toolbar-height);
|
|
335
|
+
align-items: center;
|
|
336
|
+
justify-content: space-between;
|
|
337
|
+
gap: 1rem;
|
|
338
|
+
padding: 0.625rem 0.75rem 0.625rem 1rem;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.ui-minimal-app-shell__surface-layer-body {
|
|
342
|
+
display: flex;
|
|
343
|
+
min-width: 0;
|
|
344
|
+
min-height: 0;
|
|
345
|
+
overflow: hidden;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.ui-minimal-app-shell__surface-layer-scroll-area {
|
|
349
|
+
flex: 1;
|
|
350
|
+
min-width: 0;
|
|
351
|
+
min-height: 0;
|
|
352
|
+
}
|
|
353
|
+
|
|
274
354
|
.ui-minimal-app-shell[data-display-mode="desktop"] .ui-minimal-app-shell__main {
|
|
275
355
|
min-width: min(100%, var(--ui-shell-desktop-min-main-width));
|
|
276
356
|
}
|
|
@@ -301,12 +381,6 @@
|
|
|
301
381
|
margin-inline-end: var(--ui-shell-main-block-inset);
|
|
302
382
|
}
|
|
303
383
|
|
|
304
|
-
.ui-minimal-app-shell[data-desktop-overlay-right]
|
|
305
|
-
> .ui-minimal-app-shell__composition
|
|
306
|
-
> .ui-minimal-app-shell__main {
|
|
307
|
-
margin-inline-end: var(--ui-shell-main-block-inset);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
384
|
.ui-minimal-app-shell__toolbar {
|
|
311
385
|
display: flex;
|
|
312
386
|
flex: none;
|
|
@@ -434,6 +508,11 @@
|
|
|
434
508
|
min-height: 0;
|
|
435
509
|
}
|
|
436
510
|
|
|
511
|
+
.ui-minimal-app-shell[data-display-mode="mobile"]
|
|
512
|
+
.ui-minimal-app-shell__surface-layer-surface {
|
|
513
|
+
inset-inline-start: 0;
|
|
514
|
+
}
|
|
515
|
+
|
|
437
516
|
.ui-minimal-app-shell[data-display-mode="mobile"]
|
|
438
517
|
> .ui-minimal-app-shell__composition {
|
|
439
518
|
display: none;
|
|
@@ -445,7 +524,8 @@
|
|
|
445
524
|
height: 100%;
|
|
446
525
|
min-width: 0;
|
|
447
526
|
min-height: 0;
|
|
448
|
-
|
|
527
|
+
/* Stage position belongs to the translated track, not focus scrolling. */
|
|
528
|
+
overflow: clip;
|
|
449
529
|
}
|
|
450
530
|
|
|
451
531
|
.ui-minimal-app-shell__mobile-track {
|
|
@@ -8,15 +8,24 @@
|
|
|
8
8
|
let {
|
|
9
9
|
ref = $bindable(null),
|
|
10
10
|
tabindex: _tabindex,
|
|
11
|
+
inert: inertProp,
|
|
12
|
+
"aria-hidden": ariaHidden,
|
|
11
13
|
class: className,
|
|
12
14
|
children,
|
|
13
15
|
...restProps
|
|
14
16
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
|
15
17
|
|
|
16
18
|
const controller = useAppShell();
|
|
19
|
+
let mainOccluded = $state(controller.mainOccluded);
|
|
20
|
+
const unsubscribeProjection = controller.onProjectionChange(() => {
|
|
21
|
+
mainOccluded = controller.mainOccluded;
|
|
22
|
+
});
|
|
17
23
|
|
|
18
24
|
$effect(() => controller.mobile.setMainElement(ref));
|
|
19
|
-
onDestroy(() =>
|
|
25
|
+
onDestroy(() => {
|
|
26
|
+
unsubscribeProjection();
|
|
27
|
+
controller.mobile.setMainElement(null);
|
|
28
|
+
});
|
|
20
29
|
</script>
|
|
21
30
|
|
|
22
31
|
<div
|
|
@@ -30,6 +39,8 @@
|
|
|
30
39
|
class={["ui-minimal-app-shell__main", className].filter(Boolean).join(" ")}
|
|
31
40
|
data-ui-component="app-shell"
|
|
32
41
|
data-ui-part="main"
|
|
42
|
+
inert={Boolean(inertProp) || mainOccluded}
|
|
43
|
+
aria-hidden={Boolean(inertProp) || mainOccluded ? "true" : ariaHidden}
|
|
33
44
|
>
|
|
34
45
|
{@render children?.()}
|
|
35
46
|
</div>
|