@epicbagel/saas-kit 1.12.0 → 1.14.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/README.md +41 -0
- package/THIRD_PARTY_NOTICES.md +20 -0
- package/dist/chunk-34AS3OCC.cjs +256 -0
- package/dist/chunk-KI7SWNIN.js +53 -0
- package/dist/{chunk-5VMKDVB6.cjs → chunk-PD5UQEKY.cjs} +21 -2
- package/dist/chunk-SJB4DPGQ.cjs +51 -0
- package/dist/chunk-SRIGG5I5.js +51 -0
- package/dist/{chunk-2V7AVB2U.js → chunk-UBTLWSKK.js} +19 -0
- package/dist/chunk-VKYRB37O.cjs +53 -0
- package/dist/chunk-VT2WDFSU.js +256 -0
- package/dist/primitives/chat.cjs +15 -13
- package/dist/primitives/chat.js +6 -4
- package/dist/primitives/message-scroller.cjs +6 -2
- package/dist/primitives/message-scroller.d.cts +5 -1
- package/dist/primitives/message-scroller.d.ts +5 -1
- package/dist/primitives/message-scroller.js +5 -1
- package/dist/primitives/notes.cjs +259 -0
- package/dist/primitives/notes.d.cts +123 -0
- package/dist/primitives/notes.d.ts +123 -0
- package/dist/primitives/notes.js +259 -0
- package/dist/primitives/panel-section.cjs +4 -48
- package/dist/primitives/panel-section.js +3 -47
- package/dist/primitives/scroll-navigator.cjs +10 -0
- package/dist/primitives/scroll-navigator.d.cts +40 -0
- package/dist/primitives/scroll-navigator.d.ts +40 -0
- package/dist/primitives/scroll-navigator.js +10 -0
- package/dist/primitives/section-header.cjs +4 -45
- package/dist/primitives/section-header.js +4 -45
- package/package.json +21 -1
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import {
|
|
4
|
+
SectionHeader
|
|
5
|
+
} from "../chunk-SRIGG5I5.js";
|
|
6
|
+
import {
|
|
7
|
+
PanelSection
|
|
8
|
+
} from "../chunk-KI7SWNIN.js";
|
|
9
|
+
import {
|
|
10
|
+
Card
|
|
11
|
+
} from "../chunk-35YMAIEL.js";
|
|
12
|
+
import {
|
|
13
|
+
Textarea
|
|
14
|
+
} from "../chunk-6FC65AZQ.js";
|
|
15
|
+
import {
|
|
16
|
+
Stack
|
|
17
|
+
} from "../chunk-WNWBKEWV.js";
|
|
18
|
+
import {
|
|
19
|
+
Text
|
|
20
|
+
} from "../chunk-EIY5LLSP.js";
|
|
21
|
+
import {
|
|
22
|
+
Icon
|
|
23
|
+
} from "../chunk-KN4RPX35.js";
|
|
24
|
+
import "../chunk-H7TETFLB.js";
|
|
25
|
+
import {
|
|
26
|
+
Badge
|
|
27
|
+
} from "../chunk-D4ZL2OEQ.js";
|
|
28
|
+
import {
|
|
29
|
+
EmptyState
|
|
30
|
+
} from "../chunk-ET4THLFX.js";
|
|
31
|
+
import {
|
|
32
|
+
Skeleton
|
|
33
|
+
} from "../chunk-YEW65ASC.js";
|
|
34
|
+
import {
|
|
35
|
+
Button
|
|
36
|
+
} from "../chunk-W326GKML.js";
|
|
37
|
+
import "../chunk-G6SRSWXB.js";
|
|
38
|
+
|
|
39
|
+
// src/primitives/notes.tsx
|
|
40
|
+
import { Loader2, MessageSquare, Mic, Sparkles, StickyNote, Trash2 } from "lucide-react";
|
|
41
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
42
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
43
|
+
function present(value) {
|
|
44
|
+
return value != null && value !== false && value !== "";
|
|
45
|
+
}
|
|
46
|
+
function NoteList({
|
|
47
|
+
count,
|
|
48
|
+
loading = false,
|
|
49
|
+
title = "Notes",
|
|
50
|
+
empty = { title: "No notes yet" },
|
|
51
|
+
composer,
|
|
52
|
+
children,
|
|
53
|
+
border = "bottom",
|
|
54
|
+
...props
|
|
55
|
+
}) {
|
|
56
|
+
return /* @__PURE__ */ jsxs(PanelSection, { "data-slot": "note-list", border, ...props, children: [
|
|
57
|
+
/* @__PURE__ */ jsx(SectionHeader, { label: title, count: loading ? void 0 : count }),
|
|
58
|
+
loading ? /* @__PURE__ */ jsx(Stack, { direction: "vertical", gap: "sm", marginTop: "md", children: /* @__PURE__ */ jsx(Skeleton, { preset: "row", radius: "xl" }) }) : count > 0 ? /* @__PURE__ */ jsx(Stack, { direction: "vertical", gap: "sm", marginTop: "md", children }) : /* @__PURE__ */ jsx(
|
|
59
|
+
EmptyState,
|
|
60
|
+
{
|
|
61
|
+
variant: "empty",
|
|
62
|
+
size: "inline",
|
|
63
|
+
icon: StickyNote,
|
|
64
|
+
title: empty.title,
|
|
65
|
+
description: empty.description ?? ""
|
|
66
|
+
}
|
|
67
|
+
),
|
|
68
|
+
composer
|
|
69
|
+
] });
|
|
70
|
+
}
|
|
71
|
+
var NOTE_CARD_LABELS = {
|
|
72
|
+
voice: "\xB7 voice",
|
|
73
|
+
delete: "Delete note"
|
|
74
|
+
};
|
|
75
|
+
var NOTE_ICON = { voice: Mic, agent: Sparkles, note: MessageSquare };
|
|
76
|
+
function NoteCard({
|
|
77
|
+
author,
|
|
78
|
+
kind = "note",
|
|
79
|
+
pinned,
|
|
80
|
+
scope,
|
|
81
|
+
date,
|
|
82
|
+
text,
|
|
83
|
+
onDelete,
|
|
84
|
+
revealDelete = "hover",
|
|
85
|
+
labels,
|
|
86
|
+
...props
|
|
87
|
+
}) {
|
|
88
|
+
const voiceLabel = labels?.voice !== void 0 ? labels.voice : NOTE_CARD_LABELS.voice;
|
|
89
|
+
const deleteLabel = labels?.delete ?? NOTE_CARD_LABELS.delete;
|
|
90
|
+
return /* @__PURE__ */ jsxs(Card, { interaction: "group", surface: pinned ? "card" : "muted", padding: "row", ...props, children: [
|
|
91
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "horizontal", gap: "xs", align: "center", justify: "between", marginBottom: "md", minWidth: "zero", wrap: true, children: [
|
|
92
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "horizontal", gap: "sm", align: "center", textSize: "xs", tone: "muted", minWidth: "zero", className: "max-w-full", wrap: true, children: [
|
|
93
|
+
/* @__PURE__ */ jsxs(Text, { variant: "inherit", as: "span", display: "inline-flex", weight: "medium", tone: "soft", minWidth: "zero", className: "max-w-full", children: [
|
|
94
|
+
/* @__PURE__ */ jsx(Icon, { icon: NOTE_ICON[kind], size: "xs" }),
|
|
95
|
+
/* @__PURE__ */ jsx(Text, { variant: "inherit", as: "span", minWidth: "zero", className: "[overflow-wrap:anywhere]", children: author })
|
|
96
|
+
] }),
|
|
97
|
+
pinned && /* @__PURE__ */ jsx(Badge, { as: "span", variant: "info", size: "micro", weight: "semibold", title: pinned.title, className: "max-w-full whitespace-normal [overflow-wrap:anywhere]", children: pinned.label }),
|
|
98
|
+
kind === "voice" && present(voiceLabel) && /* @__PURE__ */ jsx(Text, { variant: "inherit", as: "span", tone: "subtle", children: voiceLabel }),
|
|
99
|
+
scope && /* @__PURE__ */ jsx(
|
|
100
|
+
Badge,
|
|
101
|
+
{
|
|
102
|
+
as: "span",
|
|
103
|
+
variant: scope.highlighted ? "info" : "default",
|
|
104
|
+
size: "micro",
|
|
105
|
+
weight: "semibold",
|
|
106
|
+
title: scope.title,
|
|
107
|
+
className: "max-w-full whitespace-normal [overflow-wrap:anywhere]",
|
|
108
|
+
children: scope.label
|
|
109
|
+
}
|
|
110
|
+
)
|
|
111
|
+
] }),
|
|
112
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "horizontal", gap: "xs", align: "center", minWidth: "zero", className: "max-w-full", children: [
|
|
113
|
+
present(date) ? /* @__PURE__ */ jsx(Text, { variant: "inherit", as: "span", size: "xs", tone: "muted", minWidth: "zero", className: "[overflow-wrap:anywhere]", children: date }) : null,
|
|
114
|
+
onDelete && /* @__PURE__ */ jsx(
|
|
115
|
+
Button,
|
|
116
|
+
{
|
|
117
|
+
type: "button",
|
|
118
|
+
size: "icon-sm",
|
|
119
|
+
reveal: revealDelete === "always" ? "always" : "parent-hover-responsive",
|
|
120
|
+
variant: "ghost-destructive",
|
|
121
|
+
onClick: () => onDelete(),
|
|
122
|
+
title: deleteLabel,
|
|
123
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: Trash2, size: "sm" })
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
] })
|
|
127
|
+
] }),
|
|
128
|
+
present(text) && /* @__PURE__ */ jsx(Text, { size: "sm", whitespace: "pre-wrap", className: "break-words [overflow-wrap:anywhere]", children: text })
|
|
129
|
+
] });
|
|
130
|
+
}
|
|
131
|
+
function Notes({ notes, ...props }) {
|
|
132
|
+
return /* @__PURE__ */ jsx(NoteList, { "data-slot": "notes", count: notes.length, ...props, children: notes.map(({ id, ...note }) => /* @__PURE__ */ jsx(NoteCard, { ...note }, id)) });
|
|
133
|
+
}
|
|
134
|
+
var COMPOSER_LABELS = {
|
|
135
|
+
voice: "Tap to speak",
|
|
136
|
+
type: "or type instead",
|
|
137
|
+
input: "Note",
|
|
138
|
+
placeholder: "Type your note\u2026",
|
|
139
|
+
cancel: "Cancel",
|
|
140
|
+
submit: "Add note",
|
|
141
|
+
error: "Could not save your note. Try again."
|
|
142
|
+
};
|
|
143
|
+
function NoteComposer({
|
|
144
|
+
onVoice,
|
|
145
|
+
onSubmit,
|
|
146
|
+
suggestions = [],
|
|
147
|
+
labels,
|
|
148
|
+
value,
|
|
149
|
+
onValueChange,
|
|
150
|
+
editing,
|
|
151
|
+
onEditingChange,
|
|
152
|
+
onCancel,
|
|
153
|
+
disabled = false,
|
|
154
|
+
error,
|
|
155
|
+
maxLength,
|
|
156
|
+
...props
|
|
157
|
+
}) {
|
|
158
|
+
const copy = { ...COMPOSER_LABELS, ...labels };
|
|
159
|
+
const [draft, setDraft] = useState("");
|
|
160
|
+
const [localEditing, setLocalEditing] = useState(false);
|
|
161
|
+
const [saving, setSaving] = useState(false);
|
|
162
|
+
const [failed, setFailed] = useState(false);
|
|
163
|
+
const pending = useRef(false);
|
|
164
|
+
const mounted = useRef(true);
|
|
165
|
+
const errorId = useId();
|
|
166
|
+
const text = value ?? draft;
|
|
167
|
+
const latestText = useRef(text);
|
|
168
|
+
latestText.current = text;
|
|
169
|
+
const busy = disabled || saving;
|
|
170
|
+
const message = error ?? (failed ? copy.error : null);
|
|
171
|
+
const typing = (editing ?? localEditing) || Boolean(text) || Boolean(message) || !onVoice;
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
mounted.current = true;
|
|
174
|
+
return () => {
|
|
175
|
+
mounted.current = false;
|
|
176
|
+
};
|
|
177
|
+
}, []);
|
|
178
|
+
function changeText(next) {
|
|
179
|
+
if (value === void 0) setDraft(next);
|
|
180
|
+
onValueChange?.(next);
|
|
181
|
+
latestText.current = next;
|
|
182
|
+
}
|
|
183
|
+
function changeEditing(next) {
|
|
184
|
+
if (editing === void 0) setLocalEditing(next);
|
|
185
|
+
onEditingChange?.(next);
|
|
186
|
+
}
|
|
187
|
+
function cancel() {
|
|
188
|
+
if (disabled || pending.current) return;
|
|
189
|
+
changeText("");
|
|
190
|
+
changeEditing(false);
|
|
191
|
+
setFailed(false);
|
|
192
|
+
onCancel?.();
|
|
193
|
+
}
|
|
194
|
+
async function submit(input) {
|
|
195
|
+
const trimmed = input.trim();
|
|
196
|
+
if (disabled || pending.current || !trimmed || maxLength != null && trimmed.length > maxLength) return;
|
|
197
|
+
pending.current = true;
|
|
198
|
+
setSaving(true);
|
|
199
|
+
setFailed(false);
|
|
200
|
+
const previous = latestText.current;
|
|
201
|
+
try {
|
|
202
|
+
await onSubmit(trimmed);
|
|
203
|
+
if (!mounted.current) return;
|
|
204
|
+
if (value === void 0 && latestText.current === previous) {
|
|
205
|
+
changeText("");
|
|
206
|
+
changeEditing(false);
|
|
207
|
+
}
|
|
208
|
+
} catch {
|
|
209
|
+
if (!mounted.current) return;
|
|
210
|
+
if (latestText.current === previous) changeText(input);
|
|
211
|
+
changeEditing(true);
|
|
212
|
+
setFailed(true);
|
|
213
|
+
} finally {
|
|
214
|
+
pending.current = false;
|
|
215
|
+
if (mounted.current) setSaving(false);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return /* @__PURE__ */ jsxs(Stack, { "data-slot": "note-composer", direction: "vertical", gap: "sm", marginTop: "md", "aria-busy": saving, ...props, children: [
|
|
219
|
+
message ? /* @__PURE__ */ jsx(Text, { id: errorId, role: "alert", size: "sm", tone: "destructive", children: message }) : null,
|
|
220
|
+
typing ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
221
|
+
/* @__PURE__ */ jsx(
|
|
222
|
+
Textarea,
|
|
223
|
+
{
|
|
224
|
+
"aria-label": copy.input,
|
|
225
|
+
"aria-describedby": message ? errorId : void 0,
|
|
226
|
+
resize: "vertical",
|
|
227
|
+
placeholder: copy.placeholder,
|
|
228
|
+
value: text,
|
|
229
|
+
onChange: (event) => changeText(event.target.value),
|
|
230
|
+
maxLength,
|
|
231
|
+
disabled: busy,
|
|
232
|
+
autoFocus: Boolean(onVoice)
|
|
233
|
+
}
|
|
234
|
+
),
|
|
235
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "horizontal", gap: "sm", align: "center", wrap: true, children: [
|
|
236
|
+
/* @__PURE__ */ jsx(Button, { type: "button", size: "sm", variant: "ghost", onClick: cancel, disabled: busy, children: copy.cancel }),
|
|
237
|
+
/* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", onClick: () => void submit(text), disabled: busy || !text.trim() || maxLength != null && text.trim().length > maxLength, children: [
|
|
238
|
+
saving ? /* @__PURE__ */ jsx(Icon, { icon: Loader2, size: "sm", spin: true }) : null,
|
|
239
|
+
copy.submit
|
|
240
|
+
] })
|
|
241
|
+
] })
|
|
242
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
243
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "vertical", gap: "sm", align: "center", paddingY: "md", children: [
|
|
244
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "voice", "aria-label": copy.voice, disabled: busy, onClick: () => {
|
|
245
|
+
if (!pending.current && !disabled) onVoice?.();
|
|
246
|
+
}, children: /* @__PURE__ */ jsx(Icon, { icon: Mic, size: 28, tone: "muted" }) }),
|
|
247
|
+
/* @__PURE__ */ jsx(Text, { variant: "inherit", as: "span", size: "sm", weight: "medium", children: copy.voice }),
|
|
248
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "quiet", size: "bare", disabled: busy, onClick: () => changeEditing(true), children: copy.type })
|
|
249
|
+
] }),
|
|
250
|
+
suggestions.length > 0 ? /* @__PURE__ */ jsx(Stack, { direction: "horizontal", gap: "xs", justify: "center", wrap: true, children: suggestions.map((suggestion) => /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline-muted", size: "suggestion", disabled: busy, onClick: () => void submit(suggestion), children: suggestion }, suggestion)) }) : null
|
|
251
|
+
] })
|
|
252
|
+
] });
|
|
253
|
+
}
|
|
254
|
+
export {
|
|
255
|
+
NoteCard,
|
|
256
|
+
NoteComposer,
|
|
257
|
+
NoteList,
|
|
258
|
+
Notes
|
|
259
|
+
};
|
|
@@ -1,52 +1,8 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var _chunkVKYRB37Ocjs = require('../chunk-VKYRB37O.cjs');
|
|
5
|
+
require('../chunk-KWLSBTB2.cjs');
|
|
5
6
|
|
|
6
|
-
// src/primitives/panel-section.tsx
|
|
7
|
-
var _react = require('react');
|
|
8
|
-
var _jsxruntime = require('react/jsx-runtime');
|
|
9
|
-
var borders = {
|
|
10
|
-
none: "",
|
|
11
|
-
top: "border-t",
|
|
12
|
-
bottom: "border-b"
|
|
13
|
-
};
|
|
14
|
-
var paddings = {
|
|
15
|
-
none: "",
|
|
16
|
-
compact: "px-[22px] py-[18px]",
|
|
17
|
-
default: "px-[26px] py-[26px]"
|
|
18
|
-
};
|
|
19
|
-
var PanelSection = _react.forwardRef.call(void 0,
|
|
20
|
-
function PanelSection2({ as, border = "none", padding = "default", paddingX = "none", paddingTop = "none", paddingBottom = "none", paddingY = "none", surface = "default", layout = "block", gap = "none", shrink = true, className, ...props }, ref) {
|
|
21
|
-
const Component = _nullishCoalesce(as, () => ( "section"));
|
|
22
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
23
|
-
Component,
|
|
24
|
-
{
|
|
25
|
-
ref,
|
|
26
|
-
className: _chunkKWLSBTB2cjs.cn.call(void 0,
|
|
27
|
-
borders[border],
|
|
28
|
-
paddings[padding],
|
|
29
|
-
paddingX === "md" && "px-[22px]",
|
|
30
|
-
paddingX === "lg" && "px-[26px]",
|
|
31
|
-
paddingTop === "sm" && "pt-2",
|
|
32
|
-
paddingTop === "md" && "pt-3",
|
|
33
|
-
paddingTop === "lg" && "pt-5",
|
|
34
|
-
paddingBottom === "xs" && "pb-1",
|
|
35
|
-
paddingBottom === "sm" && "pb-2",
|
|
36
|
-
paddingBottom === "md" && "pb-3",
|
|
37
|
-
paddingBottom === "lg" && "pb-4",
|
|
38
|
-
paddingY === "xl" && "py-12",
|
|
39
|
-
surface === "muted" && "bg-muted/40",
|
|
40
|
-
layout === "row" && "flex",
|
|
41
|
-
gap === "sm" && "gap-2",
|
|
42
|
-
!shrink && "shrink-0",
|
|
43
|
-
className
|
|
44
|
-
),
|
|
45
|
-
...props
|
|
46
|
-
}
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
);
|
|
50
7
|
|
|
51
|
-
|
|
52
|
-
exports.PanelSection = PanelSection;
|
|
8
|
+
exports.PanelSection = _chunkVKYRB37Ocjs.PanelSection;
|
|
@@ -1,52 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
|
|
6
|
-
// src/primitives/panel-section.tsx
|
|
7
|
-
import { forwardRef } from "react";
|
|
8
|
-
import { jsx } from "react/jsx-runtime";
|
|
9
|
-
var borders = {
|
|
10
|
-
none: "",
|
|
11
|
-
top: "border-t",
|
|
12
|
-
bottom: "border-b"
|
|
13
|
-
};
|
|
14
|
-
var paddings = {
|
|
15
|
-
none: "",
|
|
16
|
-
compact: "px-[22px] py-[18px]",
|
|
17
|
-
default: "px-[26px] py-[26px]"
|
|
18
|
-
};
|
|
19
|
-
var PanelSection = forwardRef(
|
|
20
|
-
function PanelSection2({ as, border = "none", padding = "default", paddingX = "none", paddingTop = "none", paddingBottom = "none", paddingY = "none", surface = "default", layout = "block", gap = "none", shrink = true, className, ...props }, ref) {
|
|
21
|
-
const Component = as ?? "section";
|
|
22
|
-
return /* @__PURE__ */ jsx(
|
|
23
|
-
Component,
|
|
24
|
-
{
|
|
25
|
-
ref,
|
|
26
|
-
className: cn(
|
|
27
|
-
borders[border],
|
|
28
|
-
paddings[padding],
|
|
29
|
-
paddingX === "md" && "px-[22px]",
|
|
30
|
-
paddingX === "lg" && "px-[26px]",
|
|
31
|
-
paddingTop === "sm" && "pt-2",
|
|
32
|
-
paddingTop === "md" && "pt-3",
|
|
33
|
-
paddingTop === "lg" && "pt-5",
|
|
34
|
-
paddingBottom === "xs" && "pb-1",
|
|
35
|
-
paddingBottom === "sm" && "pb-2",
|
|
36
|
-
paddingBottom === "md" && "pb-3",
|
|
37
|
-
paddingBottom === "lg" && "pb-4",
|
|
38
|
-
paddingY === "xl" && "py-12",
|
|
39
|
-
surface === "muted" && "bg-muted/40",
|
|
40
|
-
layout === "row" && "flex",
|
|
41
|
-
gap === "sm" && "gap-2",
|
|
42
|
-
!shrink && "shrink-0",
|
|
43
|
-
className
|
|
44
|
-
),
|
|
45
|
-
...props
|
|
46
|
-
}
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
);
|
|
3
|
+
PanelSection
|
|
4
|
+
} from "../chunk-KI7SWNIN.js";
|
|
5
|
+
import "../chunk-G6SRSWXB.js";
|
|
50
6
|
export {
|
|
51
7
|
PanelSection
|
|
52
8
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunk34AS3OCCcjs = require('../chunk-34AS3OCC.cjs');
|
|
6
|
+
require('../chunk-WABCLRBR.cjs');
|
|
7
|
+
require('../chunk-KWLSBTB2.cjs');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
exports.ScrollNavigator = _chunk34AS3OCCcjs.ScrollNavigator;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface ScrollNavigatorItem {
|
|
5
|
+
/** Stable within this list. Separate lists can contain the same IDs. */
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
imageSrc?: string | null;
|
|
9
|
+
/** Initials or an icon; defaults to the label's initials. */
|
|
10
|
+
fallback?: ReactNode;
|
|
11
|
+
content: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
interface ScrollNavigatorScrollOptions {
|
|
14
|
+
/** Space above the target, including the horizontal navigator when present. */
|
|
15
|
+
offset: number;
|
|
16
|
+
behavior: ScrollBehavior;
|
|
17
|
+
}
|
|
18
|
+
interface ScrollNavigatorProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
19
|
+
items: readonly ScrollNavigatorItem[];
|
|
20
|
+
label?: string;
|
|
21
|
+
/** Space below a sticky header inside the scroll viewport, in pixels. */
|
|
22
|
+
topOffset?: number;
|
|
23
|
+
/** The nearest vertically scrolling ancestor is detected by default. */
|
|
24
|
+
scrollRoot?: HTMLElement | null;
|
|
25
|
+
/** Return true when a host scroller has handled the jump. */
|
|
26
|
+
onNavigate?: (id: string, target: HTMLElement, options: ScrollNavigatorScrollOptions) => boolean | void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A list with an avatar index which follows the first item at the viewport's
|
|
30
|
+
* reading edge. The index lives only beside this list: it disappears before
|
|
31
|
+
* and after it. With no room in the left gutter it becomes a horizontal row.
|
|
32
|
+
* The row reserves space above the first item; later items scroll beneath it.
|
|
33
|
+
*
|
|
34
|
+
* Portalling the controls avoids clipping by cards, message bubbles and
|
|
35
|
+
* content-visibility containers. Their bounds still follow the list and its
|
|
36
|
+
* actual scroll viewport, never the full browser height of a nested pane.
|
|
37
|
+
*/
|
|
38
|
+
declare const ScrollNavigator: React.ForwardRefExoticComponent<ScrollNavigatorProps & React.RefAttributes<HTMLDivElement>>;
|
|
39
|
+
|
|
40
|
+
export { ScrollNavigator, type ScrollNavigatorItem, type ScrollNavigatorProps, type ScrollNavigatorScrollOptions };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface ScrollNavigatorItem {
|
|
5
|
+
/** Stable within this list. Separate lists can contain the same IDs. */
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
imageSrc?: string | null;
|
|
9
|
+
/** Initials or an icon; defaults to the label's initials. */
|
|
10
|
+
fallback?: ReactNode;
|
|
11
|
+
content: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
interface ScrollNavigatorScrollOptions {
|
|
14
|
+
/** Space above the target, including the horizontal navigator when present. */
|
|
15
|
+
offset: number;
|
|
16
|
+
behavior: ScrollBehavior;
|
|
17
|
+
}
|
|
18
|
+
interface ScrollNavigatorProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
19
|
+
items: readonly ScrollNavigatorItem[];
|
|
20
|
+
label?: string;
|
|
21
|
+
/** Space below a sticky header inside the scroll viewport, in pixels. */
|
|
22
|
+
topOffset?: number;
|
|
23
|
+
/** The nearest vertically scrolling ancestor is detected by default. */
|
|
24
|
+
scrollRoot?: HTMLElement | null;
|
|
25
|
+
/** Return true when a host scroller has handled the jump. */
|
|
26
|
+
onNavigate?: (id: string, target: HTMLElement, options: ScrollNavigatorScrollOptions) => boolean | void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A list with an avatar index which follows the first item at the viewport's
|
|
30
|
+
* reading edge. The index lives only beside this list: it disappears before
|
|
31
|
+
* and after it. With no room in the left gutter it becomes a horizontal row.
|
|
32
|
+
* The row reserves space above the first item; later items scroll beneath it.
|
|
33
|
+
*
|
|
34
|
+
* Portalling the controls avoids clipping by cards, message bubbles and
|
|
35
|
+
* content-visibility containers. Their bounds still follow the list and its
|
|
36
|
+
* actual scroll viewport, never the full browser height of a nested pane.
|
|
37
|
+
*/
|
|
38
|
+
declare const ScrollNavigator: React.ForwardRefExoticComponent<ScrollNavigatorProps & React.RefAttributes<HTMLDivElement>>;
|
|
39
|
+
|
|
40
|
+
export { ScrollNavigator, type ScrollNavigatorItem, type ScrollNavigatorProps, type ScrollNavigatorScrollOptions };
|
|
@@ -1,51 +1,10 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var _chunkSJB4DPGQcjs = require('../chunk-SJB4DPGQ.cjs');
|
|
5
|
+
require('../chunk-VGTINL5Q.cjs');
|
|
5
6
|
require('../chunk-I6GUOEBO.cjs');
|
|
7
|
+
require('../chunk-KWLSBTB2.cjs');
|
|
6
8
|
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// src/primitives/section-header.tsx
|
|
11
|
-
var _react = require('react');
|
|
12
|
-
var _classvarianceauthority = require('class-variance-authority');
|
|
13
|
-
var _jsxruntime = require('react/jsx-runtime');
|
|
14
|
-
var sectionHeaderVariants = _classvarianceauthority.cva.call(void 0, "flex items-center gap-1", {
|
|
15
|
-
variants: {
|
|
16
|
-
variant: {
|
|
17
|
-
muted: "text-xs font-semibold text-muted-foreground uppercase tracking-wide",
|
|
18
|
-
plain: "text-sm font-medium text-foreground"
|
|
19
|
-
},
|
|
20
|
-
spacing: {
|
|
21
|
-
tight: "mb-2",
|
|
22
|
-
loose: "mb-3",
|
|
23
|
-
none: ""
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
defaultVariants: {
|
|
27
|
-
variant: "muted",
|
|
28
|
-
spacing: "tight"
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
var SectionHeader = _react.forwardRef.call(void 0,
|
|
32
|
-
function SectionHeader2({ icon, label, count, action, variant, spacing, className, ...rest }, ref) {
|
|
33
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
34
|
-
"h3",
|
|
35
|
-
{
|
|
36
|
-
ref,
|
|
37
|
-
className: _chunkKWLSBTB2cjs.cn.call(void 0, sectionHeaderVariants({ variant, spacing }), className),
|
|
38
|
-
...rest,
|
|
39
|
-
children: [
|
|
40
|
-
icon,
|
|
41
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: label }),
|
|
42
|
-
typeof count === "number" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkVGTINL5Qcjs.CountBadge, { value: count, variant: "secondary" }),
|
|
43
|
-
action && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "ml-auto", children: action })
|
|
44
|
-
]
|
|
45
|
-
}
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
exports.SectionHeader = SectionHeader;
|
|
10
|
+
exports.SectionHeader = _chunkSJB4DPGQcjs.SectionHeader;
|
|
@@ -1,51 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "../chunk-
|
|
3
|
+
SectionHeader
|
|
4
|
+
} from "../chunk-SRIGG5I5.js";
|
|
5
|
+
import "../chunk-H7TETFLB.js";
|
|
5
6
|
import "../chunk-D4ZL2OEQ.js";
|
|
6
|
-
import
|
|
7
|
-
cn
|
|
8
|
-
} from "../chunk-G6SRSWXB.js";
|
|
9
|
-
|
|
10
|
-
// src/primitives/section-header.tsx
|
|
11
|
-
import { forwardRef } from "react";
|
|
12
|
-
import { cva } from "class-variance-authority";
|
|
13
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
-
var sectionHeaderVariants = cva("flex items-center gap-1", {
|
|
15
|
-
variants: {
|
|
16
|
-
variant: {
|
|
17
|
-
muted: "text-xs font-semibold text-muted-foreground uppercase tracking-wide",
|
|
18
|
-
plain: "text-sm font-medium text-foreground"
|
|
19
|
-
},
|
|
20
|
-
spacing: {
|
|
21
|
-
tight: "mb-2",
|
|
22
|
-
loose: "mb-3",
|
|
23
|
-
none: ""
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
defaultVariants: {
|
|
27
|
-
variant: "muted",
|
|
28
|
-
spacing: "tight"
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
var SectionHeader = forwardRef(
|
|
32
|
-
function SectionHeader2({ icon, label, count, action, variant, spacing, className, ...rest }, ref) {
|
|
33
|
-
return /* @__PURE__ */ jsxs(
|
|
34
|
-
"h3",
|
|
35
|
-
{
|
|
36
|
-
ref,
|
|
37
|
-
className: cn(sectionHeaderVariants({ variant, spacing }), className),
|
|
38
|
-
...rest,
|
|
39
|
-
children: [
|
|
40
|
-
icon,
|
|
41
|
-
/* @__PURE__ */ jsx("span", { children: label }),
|
|
42
|
-
typeof count === "number" && /* @__PURE__ */ jsx(CountBadge, { value: count, variant: "secondary" }),
|
|
43
|
-
action && /* @__PURE__ */ jsx("span", { className: "ml-auto", children: action })
|
|
44
|
-
]
|
|
45
|
-
}
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
);
|
|
7
|
+
import "../chunk-G6SRSWXB.js";
|
|
49
8
|
export {
|
|
50
9
|
SectionHeader
|
|
51
10
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epicbagel/saas-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "Accessible React primitives, layout components and design tokens for SaaS apps, built on Radix UI and Tailwind CSS v4.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -770,6 +770,16 @@
|
|
|
770
770
|
"default": "./dist/primitives/native-select.cjs"
|
|
771
771
|
}
|
|
772
772
|
},
|
|
773
|
+
"./primitives/notes": {
|
|
774
|
+
"import": {
|
|
775
|
+
"types": "./dist/primitives/notes.d.ts",
|
|
776
|
+
"default": "./dist/primitives/notes.js"
|
|
777
|
+
},
|
|
778
|
+
"require": {
|
|
779
|
+
"types": "./dist/primitives/notes.d.cts",
|
|
780
|
+
"default": "./dist/primitives/notes.cjs"
|
|
781
|
+
}
|
|
782
|
+
},
|
|
773
783
|
"./primitives/page-header-actions": {
|
|
774
784
|
"import": {
|
|
775
785
|
"types": "./dist/primitives/page-header-actions.d.ts",
|
|
@@ -940,6 +950,16 @@
|
|
|
940
950
|
"default": "./dist/primitives/scroll-area.cjs"
|
|
941
951
|
}
|
|
942
952
|
},
|
|
953
|
+
"./primitives/scroll-navigator": {
|
|
954
|
+
"import": {
|
|
955
|
+
"types": "./dist/primitives/scroll-navigator.d.ts",
|
|
956
|
+
"default": "./dist/primitives/scroll-navigator.js"
|
|
957
|
+
},
|
|
958
|
+
"require": {
|
|
959
|
+
"types": "./dist/primitives/scroll-navigator.d.cts",
|
|
960
|
+
"default": "./dist/primitives/scroll-navigator.cjs"
|
|
961
|
+
}
|
|
962
|
+
},
|
|
943
963
|
"./primitives/search-input": {
|
|
944
964
|
"import": {
|
|
945
965
|
"types": "./dist/primitives/search-input.d.ts",
|