@devalok/shilp-sutra 0.6.2 → 0.8.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/_virtual/client.js +5 -0
- package/dist/_virtual/index.js +5 -0
- package/dist/_virtual/react-dom-client.development.js +5 -0
- package/dist/_virtual/react-dom-client.production.js +5 -0
- package/dist/_virtual/scheduler.development.js +5 -0
- package/dist/_virtual/scheduler.production.js +5 -0
- package/dist/composed/command-palette.d.ts.map +1 -1
- package/dist/composed/command-palette.js +84 -73
- package/dist/composed/confirm-dialog.d.ts +27 -0
- package/dist/composed/confirm-dialog.d.ts.map +1 -0
- package/dist/composed/confirm-dialog.js +45 -0
- package/dist/composed/extensions/emoji-suggestion.d.ts +9 -0
- package/dist/composed/extensions/emoji-suggestion.d.ts.map +1 -0
- package/dist/composed/extensions/emoji-suggestion.js +119 -0
- package/dist/composed/extensions/file-attachment.d.ts +4 -0
- package/dist/composed/extensions/file-attachment.d.ts.map +1 -0
- package/dist/composed/extensions/file-attachment.js +55 -0
- package/dist/composed/extensions/mention-suggestion.d.ts +10 -0
- package/dist/composed/extensions/mention-suggestion.d.ts.map +1 -0
- package/dist/composed/extensions/mention-suggestion.js +79 -0
- package/dist/composed/index.d.ts +3 -1
- package/dist/composed/index.d.ts.map +1 -1
- package/dist/composed/index.js +28 -26
- package/dist/composed/rich-text-editor.d.ts +19 -0
- package/dist/composed/rich-text-editor.d.ts.map +1 -1
- package/dist/composed/rich-text-editor.js +347 -176
- package/dist/composed/status-badge.d.ts +11 -1
- package/dist/composed/status-badge.d.ts.map +1 -1
- package/dist/composed/status-badge.js +48 -20
- package/dist/hooks/use-color-mode.d.ts.map +1 -1
- package/dist/hooks/use-color-mode.js +8 -4
- package/dist/hooks/use-mobile.d.ts +5 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -1
- package/dist/node_modules/.pnpm/@emoji-mart_data@1.2.1/node_modules/@emoji-mart/data/sets/15/native.json.js +40141 -0
- package/dist/node_modules/.pnpm/@emoji-mart_react@1.1.1_emoji-mart@5.6.0_react@19.2.4/node_modules/@emoji-mart/react/dist/module.js +17 -0
- package/dist/node_modules/.pnpm/emoji-mart@5.6.0/node_modules/emoji-mart/dist/module.js +2958 -0
- package/dist/node_modules/.pnpm/react-dom@19.2.4_react@19.2.4/node_modules/react-dom/cjs/react-dom-client.development.js +17062 -0
- package/dist/node_modules/.pnpm/react-dom@19.2.4_react@19.2.4/node_modules/react-dom/cjs/react-dom-client.production.js +9790 -0
- package/dist/node_modules/.pnpm/react-dom@19.2.4_react@19.2.4/node_modules/react-dom/client.js +20 -0
- package/dist/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler.development.js +237 -0
- package/dist/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler.production.js +234 -0
- package/dist/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/index.js +11 -0
- package/dist/primitives/_internal/react-arrow.js +8 -19
- package/dist/primitives/_internal/react-compose-refs.js +14 -14
- package/dist/primitives/_internal/react-context.js +41 -39
- package/dist/primitives/_internal/react-dismissable-layer.js +62 -90
- package/dist/primitives/_internal/react-popper.js +107 -169
- package/dist/primitives/_internal/react-portal.js +1 -1
- package/dist/primitives/_internal/react-primitive.js +1 -1
- package/dist/primitives/_internal/react-use-size.js +8 -8
- package/dist/primitives/react-slot.js +12 -12
- package/dist/shell/app-command-palette.d.ts +3 -1
- package/dist/shell/app-command-palette.d.ts.map +1 -1
- package/dist/shell/app-command-palette.js +35 -34
- package/dist/shell/bottom-navbar.d.ts.map +1 -1
- package/dist/shell/bottom-navbar.js +31 -31
- package/dist/shell/index.d.ts +1 -1
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/notification-center.d.ts +10 -0
- package/dist/shell/notification-center.d.ts.map +1 -1
- package/dist/shell/notification-center.js +129 -117
- package/dist/shell/top-bar.d.ts +20 -0
- package/dist/shell/top-bar.d.ts.map +1 -1
- package/dist/shell/top-bar.js +100 -70
- package/dist/tailwind/index.cjs +3 -0
- package/dist/tailwind/preset.d.ts.map +1 -1
- package/dist/tailwind/preset.js +3 -0
- package/dist/tokens/semantic.css +10 -1
- package/dist/ui/alert.js +42 -63
- package/dist/ui/avatar.js +20 -62
- package/dist/ui/badge.d.ts +1 -1
- package/dist/ui/badge.d.ts.map +1 -1
- package/dist/ui/badge.js +89 -112
- package/dist/ui/banner.js +12 -12
- package/dist/ui/button-group.js +14 -29
- package/dist/ui/button.js +64 -108
- package/dist/ui/card.js +18 -62
- package/dist/ui/checkbox.js +1 -21
- package/dist/ui/chip.d.ts.map +1 -1
- package/dist/ui/chip.js +1 -1
- package/dist/ui/color-input.d.ts +17 -0
- package/dist/ui/color-input.d.ts.map +1 -0
- package/dist/ui/color-input.js +88 -0
- package/dist/ui/combobox.d.ts +20 -11
- package/dist/ui/combobox.d.ts.map +1 -1
- package/dist/ui/dialog.js +9 -9
- package/dist/ui/form.js +14 -35
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +314 -312
- package/dist/ui/input.d.ts.map +1 -1
- package/dist/ui/input.js +31 -56
- package/dist/ui/label.js +1 -15
- package/dist/ui/number-input.d.ts.map +1 -1
- package/dist/ui/number-input.js +39 -35
- package/dist/ui/popover.js +6 -6
- package/dist/ui/separator.js +4 -19
- package/dist/ui/sheet.js +21 -21
- package/dist/ui/spinner.js +1 -36
- package/dist/ui/switch.js +1 -20
- package/dist/ui/tabs.js +20 -47
- package/dist/ui/textarea.d.ts.map +1 -1
- package/dist/ui/textarea.js +30 -24
- package/dist/ui/toast.js +18 -18
- package/dist/ui/tooltip.js +6 -17
- package/llms-full.txt +123 -13
- package/llms.txt +9 -6
- package/package.json +80 -11
package/dist/ui/toast.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as
|
|
2
|
+
import { jsx as o } from "react/jsx-runtime";
|
|
3
3
|
import * as r from "react";
|
|
4
4
|
import { Provider as p, Root as i, Action as d, Close as n, Description as l, Title as c, Viewport as m } from "../primitives/react-toast.js";
|
|
5
5
|
import { cva as u } from "class-variance-authority";
|
|
6
|
-
import { IconX as
|
|
6
|
+
import { IconX as x } from "@tabler/icons-react";
|
|
7
7
|
import { cn as a } from "./lib/utils.js";
|
|
8
|
-
const C = p,
|
|
8
|
+
const C = p, b = r.forwardRef(({ className: e, ...t }, s) => /* @__PURE__ */ o(
|
|
9
9
|
m,
|
|
10
10
|
{
|
|
11
|
-
ref:
|
|
11
|
+
ref: s,
|
|
12
12
|
className: a(
|
|
13
13
|
"fixed top-0 z-toast flex max-h-screen w-full flex-col-reverse p-ds-05 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
|
|
14
14
|
e
|
|
@@ -16,7 +16,7 @@ const C = p, x = r.forwardRef(({ className: e, ...t }, o) => /* @__PURE__ */ s(
|
|
|
16
16
|
...t
|
|
17
17
|
}
|
|
18
18
|
));
|
|
19
|
-
|
|
19
|
+
b.displayName = m.displayName;
|
|
20
20
|
const v = u(
|
|
21
21
|
"group pointer-events-auto relative flex w-full items-center justify-between space-x-ds-03 overflow-hidden rounded-ds-md border p-ds-05 pr-ds-06 shadow-03 transition-all duration-moderate-02 data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
|
|
22
22
|
{
|
|
@@ -33,21 +33,21 @@ const v = u(
|
|
|
33
33
|
color: "neutral"
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
), w = r.forwardRef(({ className: e, color: t, ...
|
|
36
|
+
), w = r.forwardRef(({ className: e, color: t, ...s }, f) => /* @__PURE__ */ o(
|
|
37
37
|
i,
|
|
38
38
|
{
|
|
39
39
|
ref: f,
|
|
40
40
|
role: "status",
|
|
41
41
|
"aria-live": "polite",
|
|
42
42
|
className: a(v({ color: t }), e),
|
|
43
|
-
...
|
|
43
|
+
...s
|
|
44
44
|
}
|
|
45
45
|
));
|
|
46
46
|
w.displayName = i.displayName;
|
|
47
|
-
const y = r.forwardRef(({ className: e, ...t },
|
|
47
|
+
const y = r.forwardRef(({ className: e, ...t }, s) => /* @__PURE__ */ o(
|
|
48
48
|
d,
|
|
49
49
|
{
|
|
50
|
-
ref:
|
|
50
|
+
ref: s,
|
|
51
51
|
className: a(
|
|
52
52
|
"inline-flex h-ds-sm shrink-0 items-center justify-center rounded-ds-md border border-border bg-transparent px-ds-04 text-ds-md font-medium transition-colors hover:bg-layer-02 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-[0.38] group-[.destructive]:border-border-error group-[.destructive]:hover:bg-error-surface",
|
|
53
53
|
e
|
|
@@ -56,33 +56,33 @@ const y = r.forwardRef(({ className: e, ...t }, o) => /* @__PURE__ */ s(
|
|
|
56
56
|
}
|
|
57
57
|
));
|
|
58
58
|
y.displayName = d.displayName;
|
|
59
|
-
const g = r.forwardRef(({ className: e, ...t },
|
|
59
|
+
const g = r.forwardRef(({ className: e, ...t }, s) => /* @__PURE__ */ o(
|
|
60
60
|
n,
|
|
61
61
|
{
|
|
62
|
-
ref:
|
|
62
|
+
ref: s,
|
|
63
63
|
className: a(
|
|
64
|
-
"absolute right-ds-02 top-ds-02 min-h-
|
|
64
|
+
"absolute right-ds-02 top-ds-02 min-h-ds-xs min-w-ds-xs flex items-center justify-center rounded-ds-md p-ds-02 text-text-secondary opacity-70 transition-opacity hover:text-text-primary hover:opacity-100 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus",
|
|
65
65
|
e
|
|
66
66
|
),
|
|
67
67
|
"toast-close": "",
|
|
68
68
|
...t,
|
|
69
|
-
children: /* @__PURE__ */
|
|
69
|
+
children: /* @__PURE__ */ o(x, { className: "h-ico-sm w-ico-sm" })
|
|
70
70
|
}
|
|
71
71
|
));
|
|
72
72
|
g.displayName = n.displayName;
|
|
73
|
-
const N = r.forwardRef(({ className: e, ...t },
|
|
73
|
+
const N = r.forwardRef(({ className: e, ...t }, s) => /* @__PURE__ */ o(
|
|
74
74
|
c,
|
|
75
75
|
{
|
|
76
|
-
ref:
|
|
76
|
+
ref: s,
|
|
77
77
|
className: a("text-ds-md font-semibold [&+div]:text-ds-sm", e),
|
|
78
78
|
...t
|
|
79
79
|
}
|
|
80
80
|
));
|
|
81
81
|
N.displayName = c.displayName;
|
|
82
|
-
const h = r.forwardRef(({ className: e, ...t },
|
|
82
|
+
const h = r.forwardRef(({ className: e, ...t }, s) => /* @__PURE__ */ o(
|
|
83
83
|
l,
|
|
84
84
|
{
|
|
85
|
-
ref:
|
|
85
|
+
ref: s,
|
|
86
86
|
className: a("text-ds-md opacity-[0.9]", e),
|
|
87
87
|
...t
|
|
88
88
|
}
|
|
@@ -95,5 +95,5 @@ export {
|
|
|
95
95
|
h as ToastDescription,
|
|
96
96
|
C as ToastProvider,
|
|
97
97
|
N as ToastTitle,
|
|
98
|
-
|
|
98
|
+
b as ToastViewport
|
|
99
99
|
};
|
package/dist/ui/tooltip.js
CHANGED
|
@@ -1,24 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as t } from "react/jsx-runtime";
|
|
3
|
-
import * as
|
|
4
|
-
import { Root as
|
|
5
|
-
import { cn as
|
|
6
|
-
const u = n, T =
|
|
7
|
-
|
|
8
|
-
{
|
|
9
|
-
ref: d,
|
|
10
|
-
sideOffset: a,
|
|
11
|
-
className: p(
|
|
12
|
-
"z-tooltip overflow-hidden rounded-ds-md bg-text-primary px-ds-04 py-ds-02b text-ds-sm text-text-inverse shadow-02 duration-fast-02 ease-productive-entrance animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
13
|
-
e
|
|
14
|
-
),
|
|
15
|
-
...i
|
|
16
|
-
}
|
|
17
|
-
) }));
|
|
18
|
-
f.displayName = o.displayName;
|
|
3
|
+
import * as s from "react";
|
|
4
|
+
import { Root as r, Provider as n, Trigger as m, Portal as l, Content as o } from "../primitives/react-tooltip.js";
|
|
5
|
+
import { cn as f } from "./lib/utils.js";
|
|
6
|
+
const u = n, T = r, h = m, p = s.forwardRef(({ className: e, sideOffset: a = 4, ...i }, d) => t(l, { children: t(o, { ref: d, sideOffset: a, className: f("z-tooltip overflow-hidden rounded-ds-md bg-text-primary px-ds-04 py-ds-02b text-ds-sm text-text-inverse shadow-02 duration-fast-02 ease-productive-entrance animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", e), ...i }) }));
|
|
7
|
+
p.displayName = o.displayName;
|
|
19
8
|
export {
|
|
20
9
|
T as Tooltip,
|
|
21
|
-
|
|
10
|
+
p as TooltipContent,
|
|
22
11
|
u as TooltipProvider,
|
|
23
12
|
h as TooltipTrigger
|
|
24
13
|
};
|
package/llms-full.txt
CHANGED
|
@@ -197,7 +197,7 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
197
197
|
- Props:
|
|
198
198
|
variant: "subtle" | "solid" | "outline" | "secondary" (alias->subtle) | "destructive" (alias->solid+error)
|
|
199
199
|
color: "default" | "info" | "success" | "error" | "warning" | "brand" | "accent" | "teal" | "amber" | "slate" | "indigo" | "cyan" | "orange" | "emerald"
|
|
200
|
-
size: "sm" | "md" | "lg"
|
|
200
|
+
size: "xs" | "sm" | "md" | "lg"
|
|
201
201
|
dot: boolean (shows leading dot indicator)
|
|
202
202
|
onDismiss: () => void (shows X button when provided)
|
|
203
203
|
children: ReactNode
|
|
@@ -353,6 +353,24 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
353
353
|
<Code variant="block">{`const x = 1;\nconsole.log(x);`}</Code>
|
|
354
354
|
- Gotchas: "block" renders as <pre><code>, "inline" renders as <code>
|
|
355
355
|
|
|
356
|
+
## ColorInput
|
|
357
|
+
- Import: @devalok/shilp-sutra/ui/color-input
|
|
358
|
+
- Server-safe: No
|
|
359
|
+
- Props:
|
|
360
|
+
value: string (hex color, e.g. "#d33163")
|
|
361
|
+
onChange: (value: string) => void
|
|
362
|
+
presets: string[] (optional preset color swatches)
|
|
363
|
+
disabled: boolean
|
|
364
|
+
className: string
|
|
365
|
+
- Defaults: value="#000000", disabled=false
|
|
366
|
+
- Example:
|
|
367
|
+
<ColorInput
|
|
368
|
+
value={color}
|
|
369
|
+
onChange={setColor}
|
|
370
|
+
presets={['#d33163', '#2563eb', '#16a34a']}
|
|
371
|
+
/>
|
|
372
|
+
- Gotchas: Uses native color picker under the hood; value must be a valid hex string
|
|
373
|
+
|
|
356
374
|
## Collapsible
|
|
357
375
|
- Import: @devalok/shilp-sutra/ui/collapsible
|
|
358
376
|
- Server-safe: No
|
|
@@ -372,12 +390,12 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
372
390
|
- Server-safe: No
|
|
373
391
|
- Props:
|
|
374
392
|
options: ComboboxOption[] (REQUIRED) — { value: string, label: string, description?: string, icon?: ReactNode, disabled?: boolean }
|
|
375
|
-
|
|
376
|
-
|
|
393
|
+
DISCRIMINATED UNION — type depends on `multiple` flag:
|
|
394
|
+
Single (default): multiple?: false, value: string, onValueChange: (value: string) => void
|
|
395
|
+
Multiple: multiple: true, value: string[], onValueChange: (value: string[]) => void
|
|
377
396
|
placeholder: string (default: "Select...")
|
|
378
397
|
searchPlaceholder: string (default: "Search...")
|
|
379
398
|
emptyMessage: string (default: "No results found")
|
|
380
|
-
multiple: boolean (default: false)
|
|
381
399
|
disabled: boolean
|
|
382
400
|
triggerClassName: string
|
|
383
401
|
maxVisible: number (default: 6, max dropdown items before scroll)
|
|
@@ -387,7 +405,7 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
387
405
|
multiple
|
|
388
406
|
options={tagOptions}
|
|
389
407
|
value={selectedTags}
|
|
390
|
-
onValueChange={
|
|
408
|
+
onValueChange={setSelectedTags}
|
|
391
409
|
placeholder="Select tags..."
|
|
392
410
|
/>
|
|
393
411
|
- Gotchas:
|
|
@@ -575,6 +593,7 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
575
593
|
- Gotchas:
|
|
576
594
|
- HTML native "size" attribute is excluded — use CSS width instead
|
|
577
595
|
- state="error" sets aria-invalid automatically
|
|
596
|
+
- Inside FormField: auto-inherits state, aria-describedby, aria-required from context (explicit props override)
|
|
578
597
|
|
|
579
598
|
## InputOTP
|
|
580
599
|
- Import: @devalok/shilp-sutra/ui/input-otp
|
|
@@ -1116,6 +1135,7 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
1116
1135
|
- Example:
|
|
1117
1136
|
<Textarea size="lg" state="error" placeholder="Describe the issue..." />
|
|
1118
1137
|
- Gotchas: state="error" sets aria-invalid automatically; all sizes are vertically resizable
|
|
1138
|
+
- Inside FormField: auto-inherits state, aria-describedby, aria-required from context (explicit props override)
|
|
1119
1139
|
|
|
1120
1140
|
## Toast / Toaster
|
|
1121
1141
|
- Import: @devalok/shilp-sutra/ui/toast, @devalok/shilp-sutra/ui/toaster
|
|
@@ -1302,6 +1322,36 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
1302
1322
|
/>
|
|
1303
1323
|
- Gotchas: Opens with Ctrl+K / Cmd+K by default
|
|
1304
1324
|
|
|
1325
|
+
## ConfirmDialog
|
|
1326
|
+
- Import: @devalok/shilp-sutra/composed/confirm-dialog
|
|
1327
|
+
- Server-safe: No
|
|
1328
|
+
- Props:
|
|
1329
|
+
open: boolean (REQUIRED, controlled)
|
|
1330
|
+
onOpenChange: (open: boolean) => void (REQUIRED)
|
|
1331
|
+
title: string (REQUIRED)
|
|
1332
|
+
description: string (REQUIRED)
|
|
1333
|
+
confirmText: string (default: "Confirm")
|
|
1334
|
+
cancelText: string (default: "Cancel")
|
|
1335
|
+
color: "default" | "error" (controls confirm button color)
|
|
1336
|
+
loading: boolean (default: false, disables buttons and shows spinner)
|
|
1337
|
+
onConfirm: () => void | Promise<void> (REQUIRED)
|
|
1338
|
+
- Defaults: confirmText="Confirm", cancelText="Cancel", color="default", loading=false
|
|
1339
|
+
- Example:
|
|
1340
|
+
const [open, setOpen] = useState(false)
|
|
1341
|
+
<ConfirmDialog
|
|
1342
|
+
open={open}
|
|
1343
|
+
onOpenChange={setOpen}
|
|
1344
|
+
title="Delete project?"
|
|
1345
|
+
description="This action cannot be undone."
|
|
1346
|
+
color="error"
|
|
1347
|
+
confirmText="Delete"
|
|
1348
|
+
loading={isDeleting}
|
|
1349
|
+
onConfirm={async () => { await deleteProject(); setOpen(false) }}
|
|
1350
|
+
/>
|
|
1351
|
+
- Gotchas:
|
|
1352
|
+
- Dialog stays open after confirm — consumer must close it via onOpenChange
|
|
1353
|
+
- Built on AlertDialog internally
|
|
1354
|
+
|
|
1305
1355
|
## ContentCard
|
|
1306
1356
|
- Import: @devalok/shilp-sutra/composed/content-card
|
|
1307
1357
|
- Server-safe: Yes
|
|
@@ -1486,13 +1536,41 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
1486
1536
|
onChange: (html: string) => void
|
|
1487
1537
|
className: string
|
|
1488
1538
|
editable: boolean (default: true)
|
|
1539
|
+
onImageUpload?: (file: File) => Promise<string> — return URL. If omitted, images paste as base64
|
|
1540
|
+
onFileUpload?: (file: File) => Promise<{ url: string; name: string; size: number }> — enables file attachments. If omitted, non-image files ignored
|
|
1541
|
+
mentions?: MentionItem[] — static list for @mention autocomplete
|
|
1542
|
+
onMentionSearch?: (query: string) => Promise<MentionItem[]> — async search, takes precedence over static mentions
|
|
1543
|
+
onMentionSelect?: (item: MentionItem) => void — callback when mention selected
|
|
1544
|
+
- MentionItem: { id: string; label: string; avatar?: string }
|
|
1489
1545
|
- Props (RichTextViewer):
|
|
1490
1546
|
content: string (REQUIRED, HTML string)
|
|
1491
1547
|
className: string
|
|
1548
|
+
- Features:
|
|
1549
|
+
Formatting: bold, italic, underline, strikethrough, highlight, headings (H2/H3), blockquote
|
|
1550
|
+
Lists: bullet, ordered, task lists (checkboxes)
|
|
1551
|
+
Code: inline code, code blocks
|
|
1552
|
+
Links: auto-link, inline URL editor popover
|
|
1553
|
+
Images: paste/drop/toolbar upload, base64 fallback or custom upload callback
|
|
1554
|
+
File attachments: drop/paste/toolbar, renders as download card [icon filename (size)]
|
|
1555
|
+
Mentions: type @ for autocomplete dropdown (static or async)
|
|
1556
|
+
Emoji: toolbar picker (emoji-mart, lazy loaded) + :shortcode: inline suggestions
|
|
1557
|
+
Text alignment: left/center/right
|
|
1558
|
+
Horizontal rule
|
|
1492
1559
|
- Example:
|
|
1493
1560
|
<RichTextEditor content={html} onChange={setHtml} placeholder="Write your message..." />
|
|
1561
|
+
<RichTextEditor
|
|
1562
|
+
content={html}
|
|
1563
|
+
onChange={setHtml}
|
|
1564
|
+
mentions={[{ id: '1', label: 'Aarav' }]}
|
|
1565
|
+
onImageUpload={async (file) => uploadAndReturnUrl(file)}
|
|
1566
|
+
onFileUpload={async (file) => ({ url: uploadUrl, name: file.name, size: file.size })}
|
|
1567
|
+
/>
|
|
1494
1568
|
<RichTextViewer content={savedHtml} />
|
|
1495
|
-
- Gotchas:
|
|
1569
|
+
- Gotchas:
|
|
1570
|
+
Requires Tiptap peer deps: @tiptap/react, @tiptap/starter-kit, @tiptap/extension-placeholder, plus extension-specific peers (image, link, underline, highlight, task-list, task-item, text-align, mention, suggestion)
|
|
1571
|
+
Emoji picker requires @emoji-mart/react + @emoji-mart/data peers
|
|
1572
|
+
Images without onImageUpload are stored as base64 in HTML — large images bloat content
|
|
1573
|
+
Mention rendering in viewer always works (no mention props needed, just the HTML)
|
|
1496
1574
|
|
|
1497
1575
|
## ScheduleView
|
|
1498
1576
|
- Import: @devalok/shilp-sutra/composed/schedule-view
|
|
@@ -1558,17 +1636,20 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
1558
1636
|
- Server-safe: No
|
|
1559
1637
|
- Props:
|
|
1560
1638
|
user: AppCommandPaletteUser | null — { name, role? }
|
|
1639
|
+
isAdmin: boolean (shows admin command groups regardless of user.role; takes precedence over role-based detection)
|
|
1561
1640
|
extraGroups: CommandGroup[]
|
|
1562
1641
|
onNavigate: (path: string) => void
|
|
1563
1642
|
onSearch: (query: string) => void
|
|
1564
1643
|
searchResults: SearchResult[] — { id, title, snippet?, entityType, projectId?, metadata? }
|
|
1565
|
-
|
|
1644
|
+
isSearching: boolean (shows loading state while search is in progress)
|
|
1645
|
+
onSearchResultSelect: (result: SearchResult) => void
|
|
1566
1646
|
- Example:
|
|
1567
1647
|
<AppCommandPalette
|
|
1568
1648
|
user={{ name: 'John', role: 'admin' }}
|
|
1649
|
+
isAdmin={true}
|
|
1569
1650
|
onNavigate={(path) => router.push(path)}
|
|
1570
1651
|
searchResults={results}
|
|
1571
|
-
|
|
1652
|
+
onSearchResultSelect={(r) => router.push(`/${r.entityType}/${r.id}`)}
|
|
1572
1653
|
/>
|
|
1573
1654
|
|
|
1574
1655
|
## AppSidebar
|
|
@@ -1601,7 +1682,7 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
1601
1682
|
- Server-safe: No
|
|
1602
1683
|
- Props:
|
|
1603
1684
|
currentPath: string
|
|
1604
|
-
user: BottomNavbarUser | null — { name, role? }
|
|
1685
|
+
user: BottomNavbarUser | null (optional) — { name, role? }. Not required to render.
|
|
1605
1686
|
primaryItems: BottomNavItem[] (max 4 recommended) — { title, href, icon, exact? }
|
|
1606
1687
|
moreItems: BottomNavItem[] (overflow items in "More" menu)
|
|
1607
1688
|
className: string
|
|
@@ -1642,13 +1723,25 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
1642
1723
|
onFetchMore: () => void
|
|
1643
1724
|
onMarkRead: (id: string) => void
|
|
1644
1725
|
onMarkAllRead: () => void
|
|
1645
|
-
|
|
1726
|
+
onNavigate: (path: string) => void — called when a notification with a route is clicked
|
|
1727
|
+
getNotificationRoute: (notification: Notification) => string | null — returns route for a notification; defaults to () => null when not provided (no hardcoded routes)
|
|
1728
|
+
footerSlot: ReactNode — content rendered in a sticky footer below the scroll area (e.g., "View all" link)
|
|
1729
|
+
emptyState: ReactNode — replaces the default empty state UI when there are no notifications
|
|
1730
|
+
headerActions: ReactNode — extra action buttons rendered after the "Mark all read" button in the header
|
|
1731
|
+
popoverClassName: string — override default popover dimensions via className
|
|
1732
|
+
onDismiss: (id: string) => void — when provided, each notification shows a dismiss/close button; called with the notification id
|
|
1646
1733
|
- Example:
|
|
1647
1734
|
<NotificationCenter
|
|
1648
1735
|
notifications={notifications}
|
|
1649
1736
|
onMarkRead={markAsRead}
|
|
1650
1737
|
onMarkAllRead={markAllAsRead}
|
|
1651
|
-
|
|
1738
|
+
onNavigate={(path) => router.push(path)}
|
|
1739
|
+
getNotificationRoute={(n) => n.entityType === 'task' ? `/tasks/${n.entityId}` : null}
|
|
1740
|
+
onDismiss={(id) => dismissNotification(id)}
|
|
1741
|
+
footerSlot={<Link href="/notifications">View all notifications</Link>}
|
|
1742
|
+
emptyState={<p>You're all caught up!</p>}
|
|
1743
|
+
headerActions={<Button variant="ghost" size="sm">Settings</Button>}
|
|
1744
|
+
popoverClassName="w-[480px]"
|
|
1652
1745
|
/>
|
|
1653
1746
|
|
|
1654
1747
|
## NotificationPreferences
|
|
@@ -1658,13 +1751,18 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
1658
1751
|
preferences: NotificationPreference[] — { id, userId?, projectId, channel, minTier, muted }
|
|
1659
1752
|
projects: NotificationProject[] — { id, title }
|
|
1660
1753
|
isLoading: boolean
|
|
1661
|
-
onSave: (preference: { projectId, channel, minTier, muted }) => void
|
|
1662
|
-
|
|
1754
|
+
onSave: (preference: { projectId, channel, minTier, muted }) => void | Promise<void>
|
|
1755
|
+
onToggleMute: (preference: NotificationPreference) => void | Promise<void>
|
|
1756
|
+
onUpdateTier: (preference: NotificationPreference, newTier: string) => void | Promise<void>
|
|
1757
|
+
onDelete: (preferenceId: string) => void | Promise<void>
|
|
1758
|
+
className: string
|
|
1663
1759
|
- Example:
|
|
1664
1760
|
<NotificationPreferences
|
|
1665
1761
|
preferences={prefs}
|
|
1666
1762
|
projects={projectList}
|
|
1667
1763
|
onSave={handleSavePref}
|
|
1764
|
+
onToggleMute={handleToggleMute}
|
|
1765
|
+
onUpdateTier={handleUpdateTier}
|
|
1668
1766
|
onDelete={handleDeletePref}
|
|
1669
1767
|
/>
|
|
1670
1768
|
|
|
@@ -1680,7 +1778,15 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
1680
1778
|
onAiChatClick: () => void
|
|
1681
1779
|
mobileLogo: ReactNode
|
|
1682
1780
|
notificationSlot: ReactNode (render NotificationCenter here)
|
|
1781
|
+
userMenuItems?: UserMenuItem[] — custom items between Profile and Dark/Light Mode toggle
|
|
1683
1782
|
className: string
|
|
1783
|
+
- UserMenuItem: { label: string, icon?: ReactNode, href?: string, onClick?: () => void, separator?: boolean, color?: string, badge?: string | boolean, disabled?: boolean }
|
|
1784
|
+
href — navigates via onNavigate callback
|
|
1785
|
+
onClick — custom action (takes precedence over href)
|
|
1786
|
+
separator — renders a DropdownMenuSeparator before this item
|
|
1787
|
+
color — semantic text color (e.g. "error" → text-error)
|
|
1788
|
+
badge — string for count badge, true for dot indicator
|
|
1789
|
+
disabled — greys out the item
|
|
1684
1790
|
- Example:
|
|
1685
1791
|
<TopBar
|
|
1686
1792
|
pageTitle="Dashboard"
|
|
@@ -1688,6 +1794,10 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
1688
1794
|
onNavigate={(p) => router.push(p)}
|
|
1689
1795
|
onLogout={handleLogout}
|
|
1690
1796
|
notificationSlot={<NotificationCenter notifications={notifications} />}
|
|
1797
|
+
userMenuItems={[
|
|
1798
|
+
{ label: 'Changelog', icon: <IconNews />, href: '/changelog', badge: '3' },
|
|
1799
|
+
{ label: 'Shortcuts', icon: <IconKeyboard />, onClick: () => openModal() },
|
|
1800
|
+
]}
|
|
1691
1801
|
/>
|
|
1692
1802
|
|
|
1693
1803
|
---
|
package/llms.txt
CHANGED
|
@@ -65,6 +65,7 @@ Components with two-axis system: Button, Badge, Alert, Chip, Toast, Banner, Prog
|
|
|
65
65
|
- SearchInput: size(sm|md|lg) + loading, onClear
|
|
66
66
|
- NumberInput: value + onValueChange, min, max, step (controlled only)
|
|
67
67
|
- Textarea: size(sm|md|lg) state(default|error|warning|success)
|
|
68
|
+
- ColorInput: value(hex string) onChange(value) presets(string[]) disabled
|
|
68
69
|
- Checkbox: checked, onCheckedChange, error(boolean), indeterminate(boolean)
|
|
69
70
|
- Switch: checked, onCheckedChange, error(boolean)
|
|
70
71
|
- RadioGroup > RadioGroupItem(value)
|
|
@@ -87,7 +88,7 @@ NOTIFICATION SELECTION GUIDE:
|
|
|
87
88
|
- Toast: transient notification triggered by user action (needs Toaster + useToast)
|
|
88
89
|
|
|
89
90
|
### Data Display
|
|
90
|
-
- Badge: variant(subtle|solid|outline) color(default|info|success|error|warning|brand|accent + 7 category colors) size(sm|md|lg) + onDismiss
|
|
91
|
+
- Badge: variant(subtle|solid|outline) color(default|info|success|error|warning|brand|accent + 7 category colors) size(xs|sm|md|lg) + onDismiss
|
|
91
92
|
- Chip: variant(subtle|outline) color(default|primary|success|error|warning|info + 7 category) size(sm|md|lg) label(string, REQUIRED) + onDismiss, onClick
|
|
92
93
|
- Avatar: size(xs|sm|md|lg|xl) shape(circle|square|rounded) status(online|offline|busy|away) > AvatarImage + AvatarFallback
|
|
93
94
|
- Card: variant(default|elevated|outline|flat) interactive(boolean) > CardHeader > CardTitle, CardDescription; CardContent; CardFooter
|
|
@@ -128,6 +129,7 @@ NOTIFICATION SELECTION GUIDE:
|
|
|
128
129
|
- Wire accessibility: const { state, helperTextId } = useFormField(); then aria-describedby={helperTextId}, aria-invalid={state === 'error'}
|
|
129
130
|
|
|
130
131
|
### Composed Components
|
|
132
|
+
- ConfirmDialog: open, onOpenChange, title, description, onConfirm + confirmText, cancelText, color(default|error), loading
|
|
131
133
|
- PageHeader: title, subtitle, breadcrumbs[], actions(ReactNode)
|
|
132
134
|
- AvatarGroup: users[], max(number), size(sm|md|lg), showTooltip
|
|
133
135
|
- StatusBadge: status(active|pending|approved|rejected|completed|blocked|cancelled|draft) color(success|warning|error|info|neutral) size(sm|md)
|
|
@@ -136,17 +138,18 @@ NOTIFICATION SELECTION GUIDE:
|
|
|
136
138
|
- PriorityIndicator: priority(LOW|MEDIUM|HIGH|URGENT) display(compact|full)
|
|
137
139
|
- SimpleTooltip: wraps Tooltip compound into single component
|
|
138
140
|
- DatePicker, DateRangePicker, DateTimePicker, TimePicker
|
|
139
|
-
- RichTextEditor,
|
|
141
|
+
- RichTextEditor: Tiptap editor — bold/italic/underline/strike/highlight, headings, blockquote, lists (bullet/ordered/task), code, links, images (paste/drop/upload), file attachments, @mentions, emoji picker + :shortcode:, text alignment, HR. Props: onImageUpload?, onFileUpload?, mentions?, onMentionSearch?, onMentionSelect?
|
|
142
|
+
- RichTextViewer: read-only renderer for RichTextEditor HTML content (renders all above content types)
|
|
140
143
|
- CommandPalette, MemberPicker
|
|
141
144
|
- ErrorDisplay, GlobalLoading
|
|
142
145
|
- Loading skeletons: CardSkeleton, TableSkeleton, BoardSkeleton, ListSkeleton, DashboardSkeleton, etc.
|
|
143
146
|
|
|
144
147
|
### Shell Components (app-level layout)
|
|
145
|
-
- TopBar: pageTitle, user, onNavigate, onLogout, notificationSlot, mobileLogo
|
|
148
|
+
- TopBar: pageTitle, user, onNavigate, onLogout, notificationSlot, mobileLogo, userMenuItems?(UserMenuItem[] — custom items between Profile and theme toggle, supports icon, href, onClick, separator, badge, disabled, color)
|
|
146
149
|
- AppSidebar: navigation tree with NavItem[], NavGroup[]
|
|
147
|
-
- BottomNavbar: mobile navigation
|
|
148
|
-
- NotificationCenter: notifications[],
|
|
149
|
-
- AppCommandPalette:
|
|
150
|
+
- BottomNavbar: mobile navigation, user is optional (not required to render)
|
|
151
|
+
- NotificationCenter: notifications[], onMarkRead, onMarkAllRead, onNavigate, getNotificationRoute?(returns string|null, fallback null), footerSlot?, emptyState?, headerActions?, popoverClassName?, onDismiss?(id)
|
|
152
|
+
- AppCommandPalette: user, isAdmin, onNavigate, onSearch, searchResults, isSearching, onSearchResultSelect
|
|
150
153
|
|
|
151
154
|
### Hooks
|
|
152
155
|
- useToast(): returns { toast, toasts, dismiss } — toast({ title, description, color })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devalok/shilp-sutra",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Devalok Design System — tokens, components, and patterns for Next.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -81,6 +81,10 @@
|
|
|
81
81
|
"import": "./dist/ui/code.js",
|
|
82
82
|
"types": "./dist/ui/code.d.ts"
|
|
83
83
|
},
|
|
84
|
+
"./ui/color-input": {
|
|
85
|
+
"import": "./dist/ui/color-input.js",
|
|
86
|
+
"types": "./dist/ui/color-input.d.ts"
|
|
87
|
+
},
|
|
84
88
|
"./ui/collapsible": {
|
|
85
89
|
"import": "./dist/ui/collapsible.js",
|
|
86
90
|
"types": "./dist/ui/collapsible.d.ts"
|
|
@@ -289,6 +293,10 @@
|
|
|
289
293
|
"import": "./dist/composed/command-palette.js",
|
|
290
294
|
"types": "./dist/composed/command-palette.d.ts"
|
|
291
295
|
},
|
|
296
|
+
"./composed/confirm-dialog": {
|
|
297
|
+
"import": "./dist/composed/confirm-dialog.js",
|
|
298
|
+
"types": "./dist/composed/confirm-dialog.d.ts"
|
|
299
|
+
},
|
|
292
300
|
"./composed/content-card": {
|
|
293
301
|
"import": "./dist/composed/content-card.js",
|
|
294
302
|
"types": "./dist/composed/content-card.d.ts"
|
|
@@ -398,6 +406,10 @@
|
|
|
398
406
|
"import": "./dist/tailwind/index.js",
|
|
399
407
|
"types": "./dist/tailwind/index.d.ts"
|
|
400
408
|
},
|
|
409
|
+
"./utils": {
|
|
410
|
+
"import": "./dist/ui/lib/utils.js",
|
|
411
|
+
"types": "./dist/ui/lib/utils.d.ts"
|
|
412
|
+
},
|
|
401
413
|
"./fonts/*": "./fonts/*"
|
|
402
414
|
},
|
|
403
415
|
"files": [
|
|
@@ -416,14 +428,23 @@
|
|
|
416
428
|
"prepublishOnly": "pnpm build"
|
|
417
429
|
},
|
|
418
430
|
"peerDependencies": {
|
|
419
|
-
"
|
|
420
|
-
"react
|
|
431
|
+
"@emoji-mart/data": "^1.0.0",
|
|
432
|
+
"@emoji-mart/react": "^1.0.0",
|
|
421
433
|
"@tabler/icons-react": "^3.0.0",
|
|
422
434
|
"@tanstack/react-table": "^8.0.0",
|
|
423
435
|
"@tanstack/react-virtual": "^3.0.0",
|
|
436
|
+
"@tiptap/extension-highlight": "^2.0.0",
|
|
437
|
+
"@tiptap/extension-image": "^2.0.0",
|
|
438
|
+
"@tiptap/extension-link": "^2.0.0",
|
|
439
|
+
"@tiptap/extension-mention": "^2.0.0",
|
|
440
|
+
"@tiptap/extension-placeholder": "^2.0.0",
|
|
441
|
+
"@tiptap/extension-task-item": "^2.0.0",
|
|
442
|
+
"@tiptap/extension-task-list": "^2.0.0",
|
|
443
|
+
"@tiptap/extension-text-align": "^2.0.0",
|
|
444
|
+
"@tiptap/extension-underline": "^2.0.0",
|
|
424
445
|
"@tiptap/react": "^2.0.0",
|
|
425
446
|
"@tiptap/starter-kit": "^2.0.0",
|
|
426
|
-
"@tiptap/
|
|
447
|
+
"@tiptap/suggestion": "^2.0.0",
|
|
427
448
|
"d3-array": "^3.0.0",
|
|
428
449
|
"d3-axis": "^3.0.0",
|
|
429
450
|
"d3-format": "^3.0.0",
|
|
@@ -435,12 +456,12 @@
|
|
|
435
456
|
"d3-transition": "^3.0.0",
|
|
436
457
|
"date-fns": "^4.0.0",
|
|
437
458
|
"input-otp": "^1.0.0",
|
|
438
|
-
"react
|
|
459
|
+
"react": "^18 || ^19",
|
|
460
|
+
"react-dom": "^18 || ^19",
|
|
461
|
+
"react-markdown": "^10.0.0",
|
|
462
|
+
"tailwindcss": "^3.4.0"
|
|
439
463
|
},
|
|
440
464
|
"peerDependenciesMeta": {
|
|
441
|
-
"@tabler/icons-react": {
|
|
442
|
-
"optional": true
|
|
443
|
-
},
|
|
444
465
|
"@tanstack/react-table": {
|
|
445
466
|
"optional": true
|
|
446
467
|
},
|
|
@@ -453,9 +474,42 @@
|
|
|
453
474
|
"@tiptap/starter-kit": {
|
|
454
475
|
"optional": true
|
|
455
476
|
},
|
|
477
|
+
"@tiptap/extension-highlight": {
|
|
478
|
+
"optional": true
|
|
479
|
+
},
|
|
480
|
+
"@tiptap/extension-image": {
|
|
481
|
+
"optional": true
|
|
482
|
+
},
|
|
483
|
+
"@tiptap/extension-link": {
|
|
484
|
+
"optional": true
|
|
485
|
+
},
|
|
486
|
+
"@tiptap/extension-mention": {
|
|
487
|
+
"optional": true
|
|
488
|
+
},
|
|
456
489
|
"@tiptap/extension-placeholder": {
|
|
457
490
|
"optional": true
|
|
458
491
|
},
|
|
492
|
+
"@tiptap/extension-task-item": {
|
|
493
|
+
"optional": true
|
|
494
|
+
},
|
|
495
|
+
"@tiptap/extension-task-list": {
|
|
496
|
+
"optional": true
|
|
497
|
+
},
|
|
498
|
+
"@tiptap/extension-text-align": {
|
|
499
|
+
"optional": true
|
|
500
|
+
},
|
|
501
|
+
"@tiptap/extension-underline": {
|
|
502
|
+
"optional": true
|
|
503
|
+
},
|
|
504
|
+
"@tiptap/suggestion": {
|
|
505
|
+
"optional": true
|
|
506
|
+
},
|
|
507
|
+
"@emoji-mart/data": {
|
|
508
|
+
"optional": true
|
|
509
|
+
},
|
|
510
|
+
"@emoji-mart/react": {
|
|
511
|
+
"optional": true
|
|
512
|
+
},
|
|
459
513
|
"d3-array": {
|
|
460
514
|
"optional": true
|
|
461
515
|
},
|
|
@@ -491,6 +545,9 @@
|
|
|
491
545
|
},
|
|
492
546
|
"react-markdown": {
|
|
493
547
|
"optional": true
|
|
548
|
+
},
|
|
549
|
+
"tailwindcss": {
|
|
550
|
+
"optional": true
|
|
494
551
|
}
|
|
495
552
|
},
|
|
496
553
|
"dependencies": {
|
|
@@ -502,12 +559,24 @@
|
|
|
502
559
|
"tailwind-merge": "^3.0.1"
|
|
503
560
|
},
|
|
504
561
|
"devDependencies": {
|
|
562
|
+
"@emoji-mart/data": "^1.2.1",
|
|
563
|
+
"@emoji-mart/react": "^1.1.1",
|
|
505
564
|
"@tabler/icons-react": "^3.37.1",
|
|
506
565
|
"@tanstack/react-table": "^8.21.2",
|
|
507
566
|
"@tanstack/react-virtual": "^3.13.19",
|
|
508
|
-
"@tiptap/
|
|
509
|
-
"@tiptap/
|
|
510
|
-
"@tiptap/
|
|
567
|
+
"@tiptap/core": "^2.27.2",
|
|
568
|
+
"@tiptap/extension-highlight": "^2.27.2",
|
|
569
|
+
"@tiptap/extension-image": "^2.27.2",
|
|
570
|
+
"@tiptap/extension-link": "^2.27.2",
|
|
571
|
+
"@tiptap/extension-mention": "^2.27.2",
|
|
572
|
+
"@tiptap/extension-placeholder": "^2.27.2",
|
|
573
|
+
"@tiptap/extension-task-item": "^2.27.2",
|
|
574
|
+
"@tiptap/extension-task-list": "^2.27.2",
|
|
575
|
+
"@tiptap/extension-text-align": "^2.27.2",
|
|
576
|
+
"@tiptap/extension-underline": "^2.27.2",
|
|
577
|
+
"@tiptap/react": "^2.27.2",
|
|
578
|
+
"@tiptap/starter-kit": "^2.27.2",
|
|
579
|
+
"@tiptap/suggestion": "^2.27.2",
|
|
511
580
|
"d3-array": "^3.2.4",
|
|
512
581
|
"d3-axis": "^3.0.0",
|
|
513
582
|
"d3-format": "^3.1.2",
|