@ctrl-ui/react 0.8.18 → 0.8.19
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/blocks/coding-agent.js +1 -1
- package/dist/blocks/design-canvas-inspector.js +1 -1
- package/dist/blocks/design-canvas.js +9 -5
- package/dist/blocks/discussion-markdown-input.d.ts +12 -0
- package/dist/blocks/discussion-markdown-input.js +34 -0
- package/dist/blocks/discussion.d.ts +7 -3
- package/dist/blocks/discussion.js +77 -16
- package/dist/blocks/file-explorer.js +4 -4
- package/dist/blocks/settings.js +5 -3
- package/dist/knob-contracts/label-knobs.d.ts +4 -0
- package/dist/knob-contracts/label-knobs.js +4 -0
- package/dist/knob-contracts/markdown-editor-knobs.d.ts +4 -0
- package/dist/knob-contracts/markdown-editor-knobs.js +16 -0
- package/dist/knob-contracts/switch-knobs.d.ts +1 -1
- package/dist/knob-contracts/switch-knobs.js +1 -0
- package/dist/markdown-editor/context.d.ts +22 -0
- package/dist/markdown-editor/context.js +10 -0
- package/dist/markdown-editor/extensions.d.ts +10 -0
- package/dist/markdown-editor/extensions.js +139 -0
- package/dist/markdown-editor/toolbar.d.ts +9 -0
- package/dist/markdown-editor/toolbar.js +336 -0
- package/dist/markdown-editor/uploads.d.ts +23 -0
- package/dist/markdown-editor/uploads.js +32 -0
- package/dist/markdown-editor/use-image-uploads.d.ts +12 -0
- package/dist/markdown-editor/use-image-uploads.js +120 -0
- package/dist/markdown-editor.d.ts +27 -0
- package/dist/markdown-editor.js +192 -0
- package/dist/styles/index.css +4 -2
- package/dist/styles/recipes/code.css +4 -0
- package/dist/styles/recipes/field.css +1 -1
- package/dist/styles/recipes/label.css +19 -0
- package/dist/styles/recipes/markdown-editor.css +196 -0
- package/dist/styles/recipes/switch.css +17 -5
- package/dist/ui/app-shell.js +1 -1
- package/dist/ui/autocomplete.js +1 -1
- package/dist/ui/code.js +1 -0
- package/dist/ui/combobox.js +1 -1
- package/dist/ui/command.js +1 -1
- package/dist/ui/dockable-panel.js +1 -1
- package/dist/ui/label.d.ts +8 -0
- package/dist/ui/label.js +14 -0
- package/dist/ui/markdown.d.ts +2 -1
- package/dist/ui/markdown.js +3 -3
- package/dist/ui/responsive-dialog.js +1 -1
- package/dist/ui/sidebar-menu.js +1 -1
- package/dist/ui/sidebar.js +1 -1
- package/dist/ui/typography.d.ts +44 -0
- package/dist/ui/typography.js +59 -0
- package/dist/ui/use-switch-drag.js +1 -1
- package/package.json +37 -1
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "./lib/cn.js";
|
|
3
|
+
import { Textarea } from "./ui/textarea.js";
|
|
4
|
+
import { MarkdownEditorContext, useMarkdownEditor } from "./markdown-editor/context.js";
|
|
5
|
+
import { createMarkdownCodec, hasMarkdownContent, markdownExtensions, requiresMarkdownSource } from "./markdown-editor/extensions.js";
|
|
6
|
+
import { useImageUploads } from "./markdown-editor/use-image-uploads.js";
|
|
7
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { Slice } from "@tiptap/pm/model";
|
|
10
|
+
import { EditorState } from "@tiptap/pm/state";
|
|
11
|
+
import { EditorContent, useEditor } from "@tiptap/react";
|
|
12
|
+
//#region src/markdown-editor.tsx
|
|
13
|
+
function MarkdownEditor({ value, defaultValue = "", onValueChange, disabled = false, onUploadImage, maxImageBytes = 10485760, onStatusChange, children, className, ...props }) {
|
|
14
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
15
|
+
const markdown = value ?? internalValue;
|
|
16
|
+
const [sourceMode, setSourceMode] = useState(false);
|
|
17
|
+
const [contentAttributes, setContentAttributes] = useState({
|
|
18
|
+
role: "textbox",
|
|
19
|
+
"aria-multiline": "true"
|
|
20
|
+
});
|
|
21
|
+
const [codec] = useState(createMarkdownCodec);
|
|
22
|
+
const sourceRequired = useMemo(() => requiresMarkdownSource(markdown, codec), [markdown, codec]);
|
|
23
|
+
const source = sourceMode || sourceRequired;
|
|
24
|
+
const lastValue = useRef(markdown);
|
|
25
|
+
const [extensions] = useState(markdownExtensions);
|
|
26
|
+
const handlers = useRef(null);
|
|
27
|
+
function setMarkdown(next) {
|
|
28
|
+
lastValue.current = next;
|
|
29
|
+
setInternalValue(next);
|
|
30
|
+
onValueChange?.(next);
|
|
31
|
+
}
|
|
32
|
+
const editor = useEditor({
|
|
33
|
+
extensions,
|
|
34
|
+
immediatelyRender: false,
|
|
35
|
+
shouldRerenderOnTransaction: false,
|
|
36
|
+
content: sourceRequired ? "" : markdown,
|
|
37
|
+
contentType: "markdown",
|
|
38
|
+
editable: !disabled,
|
|
39
|
+
onUpdate: ({ editor: currentEditor }) => setMarkdown(currentEditor.getMarkdown()),
|
|
40
|
+
editorProps: {
|
|
41
|
+
attributes: contentAttributes,
|
|
42
|
+
handlePaste: (view, event) => {
|
|
43
|
+
if (disabled) return false;
|
|
44
|
+
const files = Array.from(event.clipboardData?.files ?? []);
|
|
45
|
+
if (onUploadImage && files.length > 0) {
|
|
46
|
+
event.preventDefault();
|
|
47
|
+
handlers.current?.upload(files);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
const text = event.clipboardData?.getData("text/plain");
|
|
51
|
+
if (!text || event.clipboardData?.getData("text/html") || requiresMarkdownSource(text, codec)) return false;
|
|
52
|
+
const document = view.state.schema.nodeFromJSON(codec.parse(text));
|
|
53
|
+
event.preventDefault();
|
|
54
|
+
view.dispatch(view.state.tr.replaceSelection(Slice.maxOpen(document.content)).scrollIntoView());
|
|
55
|
+
return true;
|
|
56
|
+
},
|
|
57
|
+
handleDrop: (view, event, _slice, moved) => {
|
|
58
|
+
const files = Array.from(event.dataTransfer?.files ?? []);
|
|
59
|
+
if (moved || !onUploadImage || disabled || files.length === 0) return false;
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
const position = view.posAtCoords({
|
|
62
|
+
left: event.clientX,
|
|
63
|
+
top: event.clientY
|
|
64
|
+
})?.pos;
|
|
65
|
+
handlers.current?.upload(files, position);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
const imageUploads = useImageUploads(editor, onUploadImage, maxImageBytes);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
handlers.current = imageUploads;
|
|
73
|
+
});
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (!editor) return;
|
|
76
|
+
editor.setEditable(!disabled, false);
|
|
77
|
+
}, [editor, disabled]);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (!editor) return;
|
|
80
|
+
const externalReset = lastValue.current !== markdown;
|
|
81
|
+
if (externalReset) handlers.current?.cancelAll();
|
|
82
|
+
if (source) {
|
|
83
|
+
lastValue.current = markdown;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (editor.getMarkdown() !== markdown) {
|
|
87
|
+
editor.commands.setContent(markdown, {
|
|
88
|
+
contentType: "markdown",
|
|
89
|
+
emitUpdate: false
|
|
90
|
+
});
|
|
91
|
+
if (externalReset) {
|
|
92
|
+
editor.view.updateState(EditorState.create({
|
|
93
|
+
schema: editor.schema,
|
|
94
|
+
doc: editor.state.doc,
|
|
95
|
+
plugins: editor.state.plugins
|
|
96
|
+
}));
|
|
97
|
+
editor.view.dispatch(editor.state.tr);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
lastValue.current = markdown;
|
|
101
|
+
}, [
|
|
102
|
+
editor,
|
|
103
|
+
markdown,
|
|
104
|
+
source
|
|
105
|
+
]);
|
|
106
|
+
const isEmpty = source ? markdown.trim() === "" : !hasMarkdownContent(codec.parse(markdown));
|
|
107
|
+
const hasPendingUploads = imageUploads.uploads.length > 0;
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
onStatusChange?.({
|
|
110
|
+
isEmpty,
|
|
111
|
+
hasPendingUploads
|
|
112
|
+
});
|
|
113
|
+
}, [
|
|
114
|
+
onStatusChange,
|
|
115
|
+
isEmpty,
|
|
116
|
+
hasPendingUploads
|
|
117
|
+
]);
|
|
118
|
+
return /* @__PURE__ */ jsx(MarkdownEditorContext, {
|
|
119
|
+
value: {
|
|
120
|
+
editor,
|
|
121
|
+
disabled,
|
|
122
|
+
source,
|
|
123
|
+
markdown,
|
|
124
|
+
sourceRequired,
|
|
125
|
+
setSource: setSourceMode,
|
|
126
|
+
setMarkdown,
|
|
127
|
+
setContentAttributes,
|
|
128
|
+
canUpload: Boolean(onUploadImage),
|
|
129
|
+
...imageUploads
|
|
130
|
+
},
|
|
131
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
132
|
+
"data-control-ui": "markdown-editor",
|
|
133
|
+
"data-control-family": "markdown-editor",
|
|
134
|
+
"data-slot": "root",
|
|
135
|
+
"data-disabled": disabled ? "" : void 0,
|
|
136
|
+
className: cn("min-w-0", className),
|
|
137
|
+
...props,
|
|
138
|
+
children
|
|
139
|
+
})
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
function MarkdownEditorContent({ label, placeholder, autoFocus = false, className }) {
|
|
143
|
+
const { editor, disabled, source, sourceRequired, markdown, setMarkdown, setContentAttributes } = useMarkdownEditor();
|
|
144
|
+
useEffect(() => {
|
|
145
|
+
setContentAttributes({
|
|
146
|
+
role: "textbox",
|
|
147
|
+
"aria-multiline": "true",
|
|
148
|
+
"aria-label": label,
|
|
149
|
+
"aria-disabled": String(disabled),
|
|
150
|
+
"data-placeholder": placeholder ?? ""
|
|
151
|
+
});
|
|
152
|
+
}, [
|
|
153
|
+
setContentAttributes,
|
|
154
|
+
label,
|
|
155
|
+
disabled,
|
|
156
|
+
placeholder
|
|
157
|
+
]);
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
if (editor && autoFocus && !source && !disabled) editor.commands.focus("end");
|
|
160
|
+
}, [
|
|
161
|
+
editor,
|
|
162
|
+
autoFocus,
|
|
163
|
+
source,
|
|
164
|
+
disabled
|
|
165
|
+
]);
|
|
166
|
+
if (source || !editor) return /* @__PURE__ */ jsxs("div", {
|
|
167
|
+
"data-control-ui": "markdown-editor",
|
|
168
|
+
"data-control-family": "markdown-editor",
|
|
169
|
+
"data-slot": "source",
|
|
170
|
+
className,
|
|
171
|
+
children: [sourceRequired ? /* @__PURE__ */ jsx("p", {
|
|
172
|
+
role: "status",
|
|
173
|
+
children: "This content uses Markdown that is only available in source mode. Its source is preserved."
|
|
174
|
+
}) : null, /* @__PURE__ */ jsx(Textarea, {
|
|
175
|
+
"aria-label": label,
|
|
176
|
+
placeholder,
|
|
177
|
+
value: markdown,
|
|
178
|
+
disabled: disabled || !editor,
|
|
179
|
+
onChange: (event) => setMarkdown(event.target.value),
|
|
180
|
+
rows: 5
|
|
181
|
+
})]
|
|
182
|
+
});
|
|
183
|
+
return /* @__PURE__ */ jsx(EditorContent, {
|
|
184
|
+
editor,
|
|
185
|
+
"data-control-ui": "markdown-editor",
|
|
186
|
+
"data-control-family": "markdown-editor",
|
|
187
|
+
"data-slot": "content",
|
|
188
|
+
className
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
//#endregion
|
|
192
|
+
export { MarkdownEditor, MarkdownEditorContent };
|
package/dist/styles/index.css
CHANGED
|
@@ -51,7 +51,11 @@
|
|
|
51
51
|
@import "./recipes/resizable.css";
|
|
52
52
|
@import "./recipes/separator.css";
|
|
53
53
|
@import "./recipes/toolbar.css";
|
|
54
|
+
@import "./type-scale.css";
|
|
54
55
|
@import "./recipes/kbd.css";
|
|
56
|
+
@import "./recipes/markdown.css";
|
|
57
|
+
@import "./recipes/label.css";
|
|
58
|
+
@import "./recipes/markdown-editor.css";
|
|
55
59
|
@import "./recipes/dockable-panel.css";
|
|
56
60
|
@import "./recipes/item.css";
|
|
57
61
|
@import "./recipes/dropzone.css";
|
|
@@ -68,7 +72,6 @@
|
|
|
68
72
|
@import "./recipes/inline-attachment.css";
|
|
69
73
|
@import "./recipes/source-badge.css";
|
|
70
74
|
@import "./recipes/inline-citation.css";
|
|
71
|
-
@import "./recipes/markdown.css";
|
|
72
75
|
@import "./recipes/markdown-block.css";
|
|
73
76
|
@import "./recipes/range.css";
|
|
74
77
|
@import "./recipes/morphing-panel.css";
|
|
@@ -86,6 +89,5 @@
|
|
|
86
89
|
@import "./recipes/popup-toast.css";
|
|
87
90
|
@import "./recipes/transcript-divider.css";
|
|
88
91
|
@import "./recipes/tree.css";
|
|
89
|
-
@import "./type-scale.css";
|
|
90
92
|
@import "./recipes/user-ask.css";
|
|
91
93
|
@import "./recipes/user-ask-details.css";
|
|
@@ -59,6 +59,10 @@
|
|
|
59
59
|
margin-inline-start: auto;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
:where([data-control-family="code"][data-slot="floating-frame"]) {
|
|
63
|
+
padding-block-start: calc(var(--spacing) * 9);
|
|
64
|
+
}
|
|
65
|
+
|
|
62
66
|
:where([data-control-family="code"][data-slot="line"]) {
|
|
63
67
|
min-block-size: calc(var(--spacing) * 5);
|
|
64
68
|
}
|
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
:where([data-control-family="field"][data-field-kind="field"][data-slot="root"]) {
|
|
190
|
-
gap: calc(var(--spacing) * 3);
|
|
190
|
+
gap: calc(var(--spacing) * 1.5) calc(var(--spacing) * 3);
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
:where([data-control-family="field"][data-field-kind="field"][data-slot="content"]) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
:where([data-control-family="label"][data-slot="root"]) {
|
|
3
|
+
--cui-label-root-foreground: var(--foreground);
|
|
4
|
+
color: var(--cui-label-root-foreground);
|
|
5
|
+
font-size: var(--text-label);
|
|
6
|
+
font-weight: var(--font-weight-medium);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
:where([data-control-family="label"][data-slot="root"]:has(:disabled, [data-disabled])) {
|
|
10
|
+
cursor: not-allowed;
|
|
11
|
+
opacity: var(--disabled-opacity);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@property --cui-label-root-foreground {
|
|
16
|
+
syntax: "<color>";
|
|
17
|
+
inherits: true;
|
|
18
|
+
initial-value: transparent;
|
|
19
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
:where([data-control-family="markdown-editor"][data-slot="root"]) {
|
|
3
|
+
--cui-markdown-editor-background: var(--background);
|
|
4
|
+
--cui-markdown-editor-foreground: var(--foreground);
|
|
5
|
+
--cui-markdown-editor-border-width: var(--control-rim-width);
|
|
6
|
+
--cui-markdown-editor-border-color: var(--border);
|
|
7
|
+
--cui-markdown-editor-radius: var(--radius-panel);
|
|
8
|
+
--cui-markdown-editor-padding: calc(var(--spacing) * 3);
|
|
9
|
+
--cui-markdown-editor-min-height: calc(var(--spacing) * 32);
|
|
10
|
+
--cui-markdown-editor-max-height: 60dvh;
|
|
11
|
+
--cui-markdown-editor-gap: calc(var(--spacing) * 3);
|
|
12
|
+
--cui-markdown-editor-muted-foreground: var(--muted-foreground);
|
|
13
|
+
--cui-markdown-editor-code-background: var(--muted);
|
|
14
|
+
color: var(--cui-markdown-editor-foreground);
|
|
15
|
+
background: var(--cui-markdown-editor-background);
|
|
16
|
+
border: var(--cui-markdown-editor-border-width) solid var(--cui-markdown-editor-border-color);
|
|
17
|
+
border-radius: var(--cui-markdown-editor-radius);
|
|
18
|
+
overflow: clip;
|
|
19
|
+
font-size: var(--text-body);
|
|
20
|
+
line-height: var(--leading-relaxed);
|
|
21
|
+
}
|
|
22
|
+
:where([data-control-family="markdown-editor"][data-slot="content"] .tiptap) {
|
|
23
|
+
min-block-size: var(--cui-markdown-editor-min-height);
|
|
24
|
+
max-block-size: var(--cui-markdown-editor-max-height);
|
|
25
|
+
overflow: auto;
|
|
26
|
+
padding: var(--cui-markdown-editor-padding);
|
|
27
|
+
overflow-wrap: anywhere;
|
|
28
|
+
white-space: pre-wrap;
|
|
29
|
+
}
|
|
30
|
+
:where([data-control-family="markdown-editor"] .tiptap:focus-visible) {
|
|
31
|
+
outline: 2px solid var(--ring);
|
|
32
|
+
outline-offset: -2px;
|
|
33
|
+
}
|
|
34
|
+
:where([data-control-family="markdown-editor"][data-slot="source"]),
|
|
35
|
+
:where([data-control-family="markdown-editor"][data-slot="uploads"]) {
|
|
36
|
+
padding: var(--cui-markdown-editor-padding);
|
|
37
|
+
}
|
|
38
|
+
:where([data-control-family="markdown-editor"] .tiptap > * + *) {
|
|
39
|
+
margin-block-start: var(--cui-markdown-editor-gap);
|
|
40
|
+
}
|
|
41
|
+
:where([data-control-family="markdown-editor"] .tiptap:has(> p:only-child > br:only-child))::before {
|
|
42
|
+
content: attr(data-placeholder);
|
|
43
|
+
color: var(--cui-markdown-editor-muted-foreground);
|
|
44
|
+
pointer-events: none;
|
|
45
|
+
float: inline-start;
|
|
46
|
+
block-size: 0;
|
|
47
|
+
}
|
|
48
|
+
:where([data-control-family="markdown-editor"] .tiptap h1) {
|
|
49
|
+
font-size: var(--text-heading-2);
|
|
50
|
+
font-weight: var(--font-weight-semibold);
|
|
51
|
+
}
|
|
52
|
+
:where([data-control-family="markdown-editor"] .tiptap h2) {
|
|
53
|
+
font-size: var(--text-heading-3);
|
|
54
|
+
font-weight: var(--font-weight-semibold);
|
|
55
|
+
}
|
|
56
|
+
:where([data-control-family="markdown-editor"] .tiptap :is(h3, h4, h5, h6)) {
|
|
57
|
+
font-size: var(--text-heading-4);
|
|
58
|
+
font-weight: var(--font-weight-semibold);
|
|
59
|
+
}
|
|
60
|
+
:where([data-control-family="markdown-editor"] .tiptap strong) {
|
|
61
|
+
font-weight: var(--font-weight-semibold);
|
|
62
|
+
}
|
|
63
|
+
:where([data-control-family="markdown-editor"] .tiptap em) {
|
|
64
|
+
font-style: italic;
|
|
65
|
+
}
|
|
66
|
+
:where([data-control-family="markdown-editor"] .tiptap s) {
|
|
67
|
+
text-decoration: line-through;
|
|
68
|
+
}
|
|
69
|
+
:where([data-control-family="markdown-editor"] .tiptap a) {
|
|
70
|
+
text-decoration: underline;
|
|
71
|
+
color: var(--primary);
|
|
72
|
+
}
|
|
73
|
+
:where([data-control-family="markdown-editor"] .tiptap ul) {
|
|
74
|
+
list-style: disc;
|
|
75
|
+
padding-inline-start: calc(var(--spacing) * 6);
|
|
76
|
+
}
|
|
77
|
+
:where([data-control-family="markdown-editor"] .tiptap ol) {
|
|
78
|
+
list-style: decimal;
|
|
79
|
+
padding-inline-start: calc(var(--spacing) * 6);
|
|
80
|
+
}
|
|
81
|
+
:where([data-control-family="markdown-editor"] .tiptap ul[data-type="taskList"]) {
|
|
82
|
+
list-style: none;
|
|
83
|
+
padding-inline-start: 0;
|
|
84
|
+
}
|
|
85
|
+
:where([data-control-family="markdown-editor"] .tiptap li[data-type="taskItem"]) {
|
|
86
|
+
display: flex;
|
|
87
|
+
align-items: baseline;
|
|
88
|
+
gap: var(--cui-markdown-editor-gap);
|
|
89
|
+
}
|
|
90
|
+
:where([data-control-family="markdown-editor"] .tiptap li[data-type="taskItem"] > div) {
|
|
91
|
+
flex: 1;
|
|
92
|
+
min-inline-size: 0;
|
|
93
|
+
}
|
|
94
|
+
:where([data-control-family="markdown-editor"] .tiptap blockquote) {
|
|
95
|
+
border-inline-start: var(--cui-markdown-editor-border-width) solid var(--cui-markdown-editor-border-color);
|
|
96
|
+
padding-inline-start: var(--cui-markdown-editor-padding);
|
|
97
|
+
color: var(--cui-markdown-editor-muted-foreground);
|
|
98
|
+
}
|
|
99
|
+
:where([data-control-family="markdown-editor"] .tiptap :is(code, pre)) {
|
|
100
|
+
font-family: var(--font-mono);
|
|
101
|
+
background: var(--cui-markdown-editor-code-background);
|
|
102
|
+
border-radius: var(--radius-sm);
|
|
103
|
+
}
|
|
104
|
+
:where([data-control-family="markdown-editor"] .tiptap pre) {
|
|
105
|
+
padding: var(--cui-markdown-editor-padding);
|
|
106
|
+
overflow: auto;
|
|
107
|
+
}
|
|
108
|
+
:where([data-control-family="markdown-editor"] .tiptap img[src]) {
|
|
109
|
+
display: block;
|
|
110
|
+
max-inline-size: 100%;
|
|
111
|
+
block-size: auto;
|
|
112
|
+
border-radius: var(--radius-sm);
|
|
113
|
+
}
|
|
114
|
+
:where([data-control-family="markdown-editor"] .tiptap .ProseMirror-selectednode) {
|
|
115
|
+
outline: 2px solid var(--ring);
|
|
116
|
+
}
|
|
117
|
+
:where([data-control-family="markdown-editor"] .tiptap [data-image-upload]) {
|
|
118
|
+
padding: var(--cui-markdown-editor-padding);
|
|
119
|
+
border: var(--cui-markdown-editor-border-width) dashed var(--cui-markdown-editor-border-color);
|
|
120
|
+
color: var(--cui-markdown-editor-muted-foreground);
|
|
121
|
+
}
|
|
122
|
+
:where([data-control-family="markdown-editor"] .tiptap table) {
|
|
123
|
+
border-collapse: collapse;
|
|
124
|
+
inline-size: 100%;
|
|
125
|
+
}
|
|
126
|
+
:where([data-control-family="markdown-editor"] .tiptap :is(td, th)) {
|
|
127
|
+
border: var(--cui-markdown-editor-border-width) solid var(--cui-markdown-editor-border-color);
|
|
128
|
+
padding: var(--cui-markdown-editor-padding);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@property --cui-markdown-editor-background {
|
|
133
|
+
syntax: "<color>";
|
|
134
|
+
inherits: true;
|
|
135
|
+
initial-value: transparent;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@property --cui-markdown-editor-foreground {
|
|
139
|
+
syntax: "<color>";
|
|
140
|
+
inherits: true;
|
|
141
|
+
initial-value: transparent;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@property --cui-markdown-editor-border-color {
|
|
145
|
+
syntax: "<color>";
|
|
146
|
+
inherits: true;
|
|
147
|
+
initial-value: transparent;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@property --cui-markdown-editor-radius {
|
|
151
|
+
syntax: "<length-percentage>";
|
|
152
|
+
inherits: true;
|
|
153
|
+
initial-value: 0px;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@property --cui-markdown-editor-padding {
|
|
157
|
+
syntax: "<length>";
|
|
158
|
+
inherits: true;
|
|
159
|
+
initial-value: 0px;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@property --cui-markdown-editor-min-height {
|
|
163
|
+
syntax: "<length>";
|
|
164
|
+
inherits: true;
|
|
165
|
+
initial-value: 0px;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@property --cui-markdown-editor-max-height {
|
|
169
|
+
syntax: "<length>";
|
|
170
|
+
inherits: true;
|
|
171
|
+
initial-value: 0px;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@property --cui-markdown-editor-gap {
|
|
175
|
+
syntax: "<length>";
|
|
176
|
+
inherits: true;
|
|
177
|
+
initial-value: 0px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@property --cui-markdown-editor-muted-foreground {
|
|
181
|
+
syntax: "<color>";
|
|
182
|
+
inherits: true;
|
|
183
|
+
initial-value: transparent;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@property --cui-markdown-editor-code-background {
|
|
187
|
+
syntax: "<color>";
|
|
188
|
+
inherits: true;
|
|
189
|
+
initial-value: transparent;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@property --cui-markdown-editor-border-width {
|
|
193
|
+
syntax: "<length>";
|
|
194
|
+
inherits: true;
|
|
195
|
+
initial-value: 0px;
|
|
196
|
+
}
|
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
--cui-switch-height: calc(var(--spacing) * 5);
|
|
5
5
|
--cui-switch-padding: calc(var(--spacing) * 0.5);
|
|
6
6
|
--cui-switch-thumb-inline-size: calc(var(--spacing) * 4);
|
|
7
|
-
--cui-switch-thumb-press-
|
|
7
|
+
--cui-switch-thumb-press-inline-size: calc(var(--cui-switch-thumb-inline-size) * 1.25);
|
|
8
|
+
--cui-switch-thumb-press-scale: 1;
|
|
8
9
|
--cui-switch-thumb-backdrop-filter: none;
|
|
9
10
|
--_switch-direction: 1;
|
|
10
11
|
--_switch-progress: 0;
|
|
11
|
-
--_switch-
|
|
12
|
+
--_switch-thumb-inline-size: var(--cui-switch-thumb-inline-size);
|
|
13
|
+
--_switch-travel: calc(var(--cui-switch-inline-size) - var(--cui-switch-padding) * 2 - var(--_switch-thumb-inline-size));
|
|
12
14
|
block-size: var(--cui-switch-height);
|
|
13
15
|
inline-size: var(--cui-switch-inline-size);
|
|
14
16
|
padding: var(--cui-switch-padding);
|
|
@@ -79,13 +81,13 @@
|
|
|
79
81
|
border-radius: var(--cui-switch-thumb-radius);
|
|
80
82
|
background: var(--cui-switch-thumb-background);
|
|
81
83
|
box-shadow: var(--cui-switch-thumb-shadow);
|
|
82
|
-
inline-size: var(--
|
|
84
|
+
inline-size: var(--_switch-thumb-inline-size);
|
|
83
85
|
block-size: calc(var(--cui-switch-height) - var(--cui-switch-padding) * 2);
|
|
84
86
|
translate: calc(var(--_switch-direction) * var(--_switch-travel) * var(--_switch-progress)) 0;
|
|
85
87
|
transform-origin: left center;
|
|
86
88
|
-webkit-backdrop-filter: var(--cui-switch-thumb-backdrop-filter);
|
|
87
89
|
backdrop-filter: var(--cui-switch-thumb-backdrop-filter);
|
|
88
|
-
transition-property: translate, scale, background-color, box-shadow;
|
|
90
|
+
transition-property: translate, inline-size, scale, background-color, box-shadow;
|
|
89
91
|
transition-duration: var(--duration-base);
|
|
90
92
|
transition-timing-function: var(--ease-emphasized);
|
|
91
93
|
}
|
|
@@ -136,6 +138,10 @@
|
|
|
136
138
|
transform-origin: left center;
|
|
137
139
|
}
|
|
138
140
|
|
|
141
|
+
:where([data-control-family="switch"][data-slot="root"]:is(:active, [data-dragging]):not([data-disabled], [data-readonly])) {
|
|
142
|
+
--_switch-thumb-inline-size: var(--cui-switch-thumb-press-inline-size);
|
|
143
|
+
}
|
|
144
|
+
|
|
139
145
|
:where(
|
|
140
146
|
[data-control-family="switch"][data-slot="root"]:is(:active, [data-dragging]):not([data-disabled], [data-readonly]) [data-slot="thumb"]
|
|
141
147
|
) {
|
|
@@ -157,7 +163,7 @@
|
|
|
157
163
|
}
|
|
158
164
|
|
|
159
165
|
:where([data-control-family="switch"][data-slot="root"][data-dragging] [data-slot="thumb"]) {
|
|
160
|
-
transition-property: scale, background-color, box-shadow;
|
|
166
|
+
transition-property: inline-size, scale, background-color, box-shadow;
|
|
161
167
|
}
|
|
162
168
|
}
|
|
163
169
|
|
|
@@ -255,6 +261,12 @@
|
|
|
255
261
|
initial-value: 16px;
|
|
256
262
|
}
|
|
257
263
|
|
|
264
|
+
@property --cui-switch-thumb-press-inline-size {
|
|
265
|
+
syntax: "<length>";
|
|
266
|
+
inherits: true;
|
|
267
|
+
initial-value: 20px;
|
|
268
|
+
}
|
|
269
|
+
|
|
258
270
|
@property --cui-switch-thumb-press-scale {
|
|
259
271
|
syntax: "*";
|
|
260
272
|
inherits: true;
|
package/dist/ui/app-shell.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { PageScrollContext, usePageScroll } from "./page-layout.js";
|
|
3
4
|
import { SidebarProvider } from "./sidebar-provider.js";
|
|
4
5
|
import { SidebarInset } from "./sidebar.js";
|
|
5
|
-
import { PageScrollContext, usePageScroll } from "./page-layout.js";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
//#region src/ui/app-shell.tsx
|
|
8
8
|
function AppShell({ scroll = "auto", layout = "viewport", className, ...props }) {
|
package/dist/ui/autocomplete.js
CHANGED
|
@@ -85,7 +85,7 @@ function AutocompleteContent({ className, children, sideOffset = 6, ...props })
|
|
|
85
85
|
function AutocompleteList({ className, children, ...props }) {
|
|
86
86
|
return /* @__PURE__ */ jsx(ScrollArea, {
|
|
87
87
|
className: "w-full",
|
|
88
|
-
viewportClassName: "overscroll-contain",
|
|
88
|
+
viewportClassName: "overscroll-y-contain",
|
|
89
89
|
maxHeight: "min(18rem, var(--available-height))",
|
|
90
90
|
lockAxis: "x",
|
|
91
91
|
children: /* @__PURE__ */ jsx(Autocomplete$1.List, {
|
package/dist/ui/code.js
CHANGED
|
@@ -112,6 +112,7 @@ function CodeCopy({ value, copiedLabel, copiedAriaLabel = "Copied to clipboard",
|
|
|
112
112
|
}
|
|
113
113
|
function CodeFloatingCopy({ className, ...props }) {
|
|
114
114
|
return /* @__PURE__ */ jsx(CodeCopy, {
|
|
115
|
+
variant: "surface",
|
|
115
116
|
"data-code-floating": "true",
|
|
116
117
|
className: cn("absolute z-10", className),
|
|
117
118
|
...props
|
package/dist/ui/combobox.js
CHANGED
|
@@ -115,7 +115,7 @@ function ComboboxContent({ className, children, sideOffset = 6, anchor, ...props
|
|
|
115
115
|
function ComboboxList({ className, children, ...props }) {
|
|
116
116
|
return /* @__PURE__ */ jsx(ScrollArea, {
|
|
117
117
|
className: "w-full",
|
|
118
|
-
viewportClassName: "overscroll-contain",
|
|
118
|
+
viewportClassName: "overscroll-y-contain",
|
|
119
119
|
maxHeight: "min(18rem, var(--available-height))",
|
|
120
120
|
lockAxis: "x",
|
|
121
121
|
children: /* @__PURE__ */ jsx(Combobox$1.List, {
|
package/dist/ui/command.js
CHANGED
|
@@ -3,8 +3,8 @@ import { cn } from "../lib/cn.js";
|
|
|
3
3
|
import { LiveStatus } from "./live-status.js";
|
|
4
4
|
import { ScrollArea } from "./scroll-area.js";
|
|
5
5
|
import { popupItemStructureClasses } from "../surface-variants.js";
|
|
6
|
-
import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "./empty.js";
|
|
7
6
|
import { Dialog, DialogContent, DialogDescription, DialogTitle } from "./dialog.js";
|
|
7
|
+
import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "./empty.js";
|
|
8
8
|
import { useEffect, useRef } from "react";
|
|
9
9
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
import { Command as Command$1, useCommandState } from "cmdk";
|
|
@@ -4,8 +4,8 @@ import { Button } from "./button.js";
|
|
|
4
4
|
import { LiveStatus } from "./live-status.js";
|
|
5
5
|
import { ScrollArea } from "./scroll-area.js";
|
|
6
6
|
import { useIsMobile } from "../hooks/use-mobile.js";
|
|
7
|
-
import { Drawer, DrawerBody, DrawerContent } from "./drawer.js";
|
|
8
7
|
import { clampDockablePanelPosition, dockablePanelSideAt, dockablePanelSideForKey, oppositeDockablePanelSide } from "./dockable-panel-geometry.js";
|
|
8
|
+
import { Drawer, DrawerBody, DrawerContent } from "./drawer.js";
|
|
9
9
|
import { createContext, use, useEffect, useEffectEvent, useId, useRef, useState } from "react";
|
|
10
10
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
//#region src/ui/dockable-panel.tsx
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LabelKnobStyle } from "../knob-contracts/label-knobs.js";
|
|
2
|
+
import { CSSProperties, ComponentProps } from "react";
|
|
3
|
+
//#region src/ui/label.d.ts
|
|
4
|
+
export type LabelProps = Omit<ComponentProps<"label">, "style"> & {
|
|
5
|
+
style?: CSSProperties & LabelKnobStyle;
|
|
6
|
+
};
|
|
7
|
+
export declare function Label({ htmlFor, children, ...props }: LabelProps): import("react").JSX.Element;
|
|
8
|
+
//#endregion
|
package/dist/ui/label.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
//#region src/ui/label.tsx
|
|
3
|
+
function Label({ htmlFor, children, ...props }) {
|
|
4
|
+
return /* @__PURE__ */ jsx("label", {
|
|
5
|
+
...props,
|
|
6
|
+
htmlFor,
|
|
7
|
+
"data-control-ui": "label",
|
|
8
|
+
"data-control-family": "label",
|
|
9
|
+
"data-slot": "root",
|
|
10
|
+
children
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { Label };
|
package/dist/ui/markdown.d.ts
CHANGED
|
@@ -6,9 +6,10 @@ export type MarkdownRootProps = Omit<ComponentProps<"div">, "style"> & {
|
|
|
6
6
|
};
|
|
7
7
|
export type MarkdownProps = Omit<MarkdownRootProps, "children"> & {
|
|
8
8
|
content: string;
|
|
9
|
+
mode?: "streaming" | "static";
|
|
9
10
|
};
|
|
10
11
|
export declare function MarkdownRoot({ className, ...props }: MarkdownRootProps): import("react").JSX.Element;
|
|
11
12
|
export declare function MarkdownFlow(props: MarkdownRootProps): import("react").JSX.Element;
|
|
12
|
-
export declare function Markdown({ content, className, ...props }: MarkdownProps): import("react").JSX.Element;
|
|
13
|
+
export declare function Markdown({ content, mode, className, ...props }: MarkdownProps): import("react").JSX.Element;
|
|
13
14
|
export type MarkdownComponentProps = ComponentProps<typeof Markdown>;
|
|
14
15
|
//#endregion
|
package/dist/ui/markdown.js
CHANGED
|
@@ -21,13 +21,13 @@ function MarkdownFlow(props) {
|
|
|
21
21
|
...props
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
|
-
function Markdown({ content, className, ...props }) {
|
|
24
|
+
function Markdown({ content, mode = "streaming", className, ...props }) {
|
|
25
25
|
return /* @__PURE__ */ jsx(MarkdownRoot, {
|
|
26
26
|
className,
|
|
27
27
|
...props,
|
|
28
28
|
children: /* @__PURE__ */ jsx(MarkdownFlow, { children: /* @__PURE__ */ jsx(Streamdown, {
|
|
29
|
-
mode
|
|
30
|
-
parseIncompleteMarkdown:
|
|
29
|
+
mode,
|
|
30
|
+
parseIncompleteMarkdown: mode === "streaming",
|
|
31
31
|
controls: false,
|
|
32
32
|
components: markdownComponents,
|
|
33
33
|
className: "cui-markdown-streamdown [&>[data-control-family]]:[margin-block:revert-layer]",
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
3
|
import { Button } from "./button.js";
|
|
4
4
|
import { PopupCloseButton } from "../popup-parts.js";
|
|
5
|
-
import { Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger } from "./drawer.js";
|
|
6
5
|
import { Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "./dialog.js";
|
|
6
|
+
import { Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger } from "./drawer.js";
|
|
7
7
|
import { createContext, useContext, useState, useSyncExternalStore } from "react";
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
//#region src/ui/responsive-dialog.tsx
|
package/dist/ui/sidebar-menu.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
3
|
import { useSkin } from "../skin-provider.js";
|
|
4
4
|
import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.js";
|
|
5
|
-
import { SidebarSurfaceContext, useSidebar } from "./sidebar-provider.js";
|
|
6
5
|
import { TrackHighlight } from "../extensions/track-highlight.js";
|
|
6
|
+
import { SidebarSurfaceContext, useSidebar } from "./sidebar-provider.js";
|
|
7
7
|
import { createContext, useContext, useRef, useState } from "react";
|
|
8
8
|
import { useRender } from "@base-ui/react/use-render";
|
|
9
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
package/dist/ui/sidebar.js
CHANGED
|
@@ -257,7 +257,7 @@ function SidebarContent({ className, children, ...props }) {
|
|
|
257
257
|
"data-slot": "content",
|
|
258
258
|
className: cn("min-h-0 flex-1 group-data-[collapsible=icon]:overflow-hidden", className),
|
|
259
259
|
lockAxis: "x",
|
|
260
|
-
viewportClassName: "overscroll-contain",
|
|
260
|
+
viewportClassName: "overscroll-y-contain",
|
|
261
261
|
...props,
|
|
262
262
|
children: /* @__PURE__ */ jsx("div", {
|
|
263
263
|
"data-control-ui": "sidebar",
|