@devalok/shilp-sutra 0.32.0 → 0.33.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/LICENSE +21 -0
- package/dist/_chunks/date-time-picker.js +851 -0
- package/dist/_chunks/mention-suggestion.js +362 -0
- package/dist/_chunks/tiptap.js +11595 -7731
- package/dist/_chunks/use-calendar.js +115 -956
- package/dist/_chunks/vendor-client.js +1055 -894
- package/dist/composed/date-picker/index.js +9 -8
- package/dist/composed/emoji-picker.d.ts +8 -2
- package/dist/composed/emoji-picker.d.ts.map +1 -1
- package/dist/composed/emoji-picker.js +65 -56
- package/dist/composed/extensions/emoji-data.d.ts +35 -0
- package/dist/composed/extensions/emoji-data.d.ts.map +1 -0
- package/dist/composed/extensions/emoji-node.d.ts +11 -0
- package/dist/composed/extensions/emoji-node.d.ts.map +1 -0
- package/dist/composed/extensions/emoji-suggestion.d.ts +4 -6
- package/dist/composed/extensions/emoji-suggestion.d.ts.map +1 -1
- package/dist/composed/extensions/slash-command.d.ts +35 -0
- package/dist/composed/extensions/slash-command.d.ts.map +1 -0
- package/dist/composed/index.d.ts +7 -1
- package/dist/composed/index.d.ts.map +1 -1
- package/dist/composed/index.js +79 -70
- package/dist/composed/rich-chat-input/attachment-strip.d.ts +15 -0
- package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -0
- package/dist/composed/rich-chat-input/audio-player.d.ts +11 -0
- package/dist/composed/rich-chat-input/audio-player.d.ts.map +1 -0
- package/dist/composed/rich-chat-input/audio-waveform.d.ts +24 -0
- package/dist/composed/rich-chat-input/audio-waveform.d.ts.map +1 -0
- package/dist/composed/rich-chat-input/chat-toolbar.d.ts +51 -0
- package/dist/composed/rich-chat-input/chat-toolbar.d.ts.map +1 -0
- package/dist/composed/rich-chat-input/recording-overlay.d.ts +15 -0
- package/dist/composed/rich-chat-input/recording-overlay.d.ts.map +1 -0
- package/dist/composed/rich-chat-input/reply-banner.d.ts +8 -0
- package/dist/composed/rich-chat-input/reply-banner.d.ts.map +1 -0
- package/dist/composed/rich-chat-input/schedule-send.d.ts +22 -0
- package/dist/composed/rich-chat-input/schedule-send.d.ts.map +1 -0
- package/dist/composed/rich-chat-input/use-voice-recorder.d.ts +18 -0
- package/dist/composed/rich-chat-input/use-voice-recorder.d.ts.map +1 -0
- package/dist/composed/rich-chat-input.d.ts +91 -0
- package/dist/composed/rich-chat-input.d.ts.map +1 -0
- package/dist/composed/rich-chat-input.js +1861 -0
- package/dist/composed/rich-text-editor.d.ts +3 -0
- package/dist/composed/rich-text-editor.d.ts.map +1 -1
- package/dist/composed/rich-text-editor.js +278 -448
- package/dist/ui/button-group.d.ts +27 -37
- package/dist/ui/button-group.d.ts.map +1 -1
- package/dist/ui/button-group.js +95 -29
- package/dist/ui/button.d.ts.map +1 -1
- package/dist/ui/button.js +110 -106
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +335 -333
- package/dist/ui/split-button.d.ts +45 -0
- package/dist/ui/split-button.d.ts.map +1 -0
- package/dist/ui/split-button.js +282 -0
- package/docs/components/composed/emoji-picker.md +9 -0
- package/docs/components/composed/rich-chat-input.md +88 -0
- package/docs/components/composed/rich-text-editor.md +5 -0
- package/docs/components/ui/button-group.md +9 -0
- package/docs/components/ui/button.md +4 -0
- package/docs/components/ui/split-button.md +41 -0
- package/llms-full.txt +157 -1
- package/llms.txt +22 -2
- package/package.json +30 -26
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Placement } from '@floating-ui/dom';
|
|
3
|
+
import { VariantProps } from 'class-variance-authority';
|
|
4
|
+
import { buttonVariants } from './button';
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
type SplitButtonVariant = 'solid' | 'soft' | 'outline';
|
|
7
|
+
type SplitButtonColor = NonNullable<VariantProps<typeof buttonVariants>['color']>;
|
|
8
|
+
type SplitButtonSize = 'xs' | 'sm' | 'md' | 'icon-xs' | 'icon-sm' | 'icon-md';
|
|
9
|
+
export interface SplitButtonProps {
|
|
10
|
+
/** Primary action content (left side). */
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
/** Primary click handler (left side). */
|
|
13
|
+
onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
14
|
+
/** Content rendered inside the floating dropdown panel. */
|
|
15
|
+
dropdownContent?: React.ReactNode;
|
|
16
|
+
/** Controlled open state. */
|
|
17
|
+
open?: boolean;
|
|
18
|
+
/** Called when open state changes. Uncontrolled if omitted. */
|
|
19
|
+
onOpenChange?: (open: boolean) => void;
|
|
20
|
+
/** @default 'solid' */
|
|
21
|
+
variant?: SplitButtonVariant;
|
|
22
|
+
/** @default 'accent' */
|
|
23
|
+
color?: SplitButtonColor;
|
|
24
|
+
/** @default 'md' */
|
|
25
|
+
size?: SplitButtonSize;
|
|
26
|
+
/** Disable both halves. */
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
/** aria-label for the primary button. */
|
|
29
|
+
'aria-label'?: string;
|
|
30
|
+
/** aria-label for the dropdown trigger. @default 'More options' */
|
|
31
|
+
dropdownLabel?: string;
|
|
32
|
+
/** Custom icon for the dropdown trigger. Defaults to chevron-down. */
|
|
33
|
+
dropdownIcon?: React.ReactNode;
|
|
34
|
+
/** Which side the dropdown trigger sits on. @default 'right' */
|
|
35
|
+
triggerSide?: 'left' | 'right';
|
|
36
|
+
/** Preferred placement for the dropdown panel. @default 'top-end' */
|
|
37
|
+
placement?: Placement;
|
|
38
|
+
/** Width of the trigger (chevron) half. @default 'auto' */
|
|
39
|
+
triggerWidth?: number | string;
|
|
40
|
+
className?: string;
|
|
41
|
+
}
|
|
42
|
+
declare const SplitButton: React.ForwardRefExoticComponent<SplitButtonProps & React.RefAttributes<HTMLDivElement>>;
|
|
43
|
+
export { SplitButton };
|
|
44
|
+
export type { SplitButtonVariant, SplitButtonColor, SplitButtonSize };
|
|
45
|
+
//# sourceMappingURL=split-button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-button.d.ts","sourceRoot":"","sources":["../../src/ui/split-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEnG,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAKzC,KAAK,kBAAkB,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;AACtD,KAAK,gBAAgB,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;AACjF,KAAK,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;AAE7E,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,yCAAyC;IACzC,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAA;IACzD,2DAA2D;IAC3D,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACjC,6BAA6B;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,+DAA+D;IAC/D,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC,uBAAuB;IACvB,OAAO,CAAC,EAAE,kBAAkB,CAAA;IAC5B,wBAAwB;IACxB,KAAK,CAAC,EAAE,gBAAgB,CAAA;IACxB,oBAAoB;IACpB,IAAI,CAAC,EAAE,eAAe,CAAA;IACtB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,sEAAsE;IACtE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC9B,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAC9B,qEAAqE;IACrE,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA2FD,QAAA,MAAM,WAAW,yFAuNhB,CAAA;AAID,OAAO,EAAE,WAAW,EAAE,CAAA;AACtB,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAA"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as m, Fragment as C, jsx as s } from "react/jsx-runtime";
|
|
3
|
+
import * as n from "react";
|
|
4
|
+
import { d as G, q as J, i as Q, e as T, g as V } from "../_chunks/vendor-client.js";
|
|
5
|
+
import { cn as o } from "./lib/utils.js";
|
|
6
|
+
import { A as X, m as Y } from "../_chunks/framer.js";
|
|
7
|
+
const A = {
|
|
8
|
+
solid: {
|
|
9
|
+
accent: "bg-accent-11/20",
|
|
10
|
+
error: "bg-error-11/20",
|
|
11
|
+
success: "bg-success-11/20",
|
|
12
|
+
warning: "bg-warning-11/20",
|
|
13
|
+
neutral: "bg-neutral-8/30"
|
|
14
|
+
},
|
|
15
|
+
soft: {
|
|
16
|
+
accent: "bg-accent-6",
|
|
17
|
+
error: "bg-error-6",
|
|
18
|
+
success: "bg-success-6",
|
|
19
|
+
warning: "bg-warning-6",
|
|
20
|
+
neutral: "bg-surface-border"
|
|
21
|
+
},
|
|
22
|
+
outline: {
|
|
23
|
+
accent: "bg-accent-7",
|
|
24
|
+
error: "bg-error-7",
|
|
25
|
+
success: "bg-success-7",
|
|
26
|
+
warning: "bg-warning-7",
|
|
27
|
+
neutral: "bg-surface-border-strong"
|
|
28
|
+
}
|
|
29
|
+
}, N = {
|
|
30
|
+
xs: "h-ds-xs-plus",
|
|
31
|
+
sm: "h-ds-sm",
|
|
32
|
+
md: "h-ds-md",
|
|
33
|
+
"icon-xs": "h-ds-xs-plus",
|
|
34
|
+
"icon-sm": "h-ds-sm",
|
|
35
|
+
"icon-md": "h-ds-md"
|
|
36
|
+
}, Z = {
|
|
37
|
+
xs: "text-ds-sm",
|
|
38
|
+
sm: "text-ds-sm",
|
|
39
|
+
md: "text-ds-md",
|
|
40
|
+
"icon-xs": "text-ds-sm",
|
|
41
|
+
"icon-sm": "text-ds-sm",
|
|
42
|
+
"icon-md": "text-ds-md"
|
|
43
|
+
}, _ = {
|
|
44
|
+
xs: "px-ds-03 gap-1",
|
|
45
|
+
sm: "px-ds-04 gap-1.5",
|
|
46
|
+
md: "px-ds-05 gap-2",
|
|
47
|
+
"icon-xs": "px-ds-02",
|
|
48
|
+
"icon-sm": "px-ds-03",
|
|
49
|
+
"icon-md": "px-ds-04"
|
|
50
|
+
}, I = {
|
|
51
|
+
xs: "px-ds-02",
|
|
52
|
+
sm: "px-ds-02",
|
|
53
|
+
md: "px-ds-03",
|
|
54
|
+
"icon-xs": "px-ds-01",
|
|
55
|
+
"icon-sm": "px-ds-02",
|
|
56
|
+
"icon-md": "px-ds-02"
|
|
57
|
+
}, W = {
|
|
58
|
+
xs: "rounded-ds-md",
|
|
59
|
+
sm: "rounded-ds-md",
|
|
60
|
+
md: "rounded-ds-lg",
|
|
61
|
+
"icon-xs": "rounded-ds-sm",
|
|
62
|
+
"icon-sm": "rounded-ds-md",
|
|
63
|
+
"icon-md": "rounded-ds-md"
|
|
64
|
+
};
|
|
65
|
+
function z(c, i) {
|
|
66
|
+
const u = {
|
|
67
|
+
solid: {
|
|
68
|
+
accent: "bg-accent-9 text-accent-fg hover:bg-accent-10 active:bg-accent-11",
|
|
69
|
+
error: "bg-error-9 text-error-fg hover:bg-error-10 active:bg-error-11",
|
|
70
|
+
success: "bg-success-9 text-success-fg hover:bg-success-10 active:bg-success-11",
|
|
71
|
+
warning: "bg-warning-9 text-warning-fg hover:bg-warning-10 active:bg-warning-11",
|
|
72
|
+
neutral: "bg-neutral-5 text-surface-fg hover:bg-neutral-7 active:bg-neutral-8"
|
|
73
|
+
},
|
|
74
|
+
soft: {
|
|
75
|
+
accent: "bg-accent-3 text-accent-11 hover:bg-accent-4 active:bg-accent-5",
|
|
76
|
+
error: "bg-error-3 text-error-11 hover:bg-error-4 active:bg-error-5",
|
|
77
|
+
success: "bg-success-3 text-success-11 hover:bg-success-4 active:bg-success-5",
|
|
78
|
+
warning: "bg-warning-3 text-warning-11 hover:bg-warning-4 active:bg-warning-5",
|
|
79
|
+
neutral: "bg-surface-raised-hover text-surface-fg-muted hover:bg-surface-raised-active active:bg-neutral-5"
|
|
80
|
+
},
|
|
81
|
+
outline: {
|
|
82
|
+
accent: "bg-transparent text-accent-11 hover:bg-accent-3 active:bg-accent-4",
|
|
83
|
+
error: "bg-transparent text-error-11 hover:bg-error-3 active:bg-error-4",
|
|
84
|
+
success: "bg-transparent text-success-11 hover:bg-success-3 active:bg-success-4",
|
|
85
|
+
warning: "bg-transparent text-warning-11 hover:bg-warning-3 active:bg-warning-4",
|
|
86
|
+
neutral: "bg-transparent text-surface-fg hover:bg-surface-raised-hover active:bg-surface-raised-active"
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
return u[c][i] ?? u[c].accent;
|
|
90
|
+
}
|
|
91
|
+
function ee(c) {
|
|
92
|
+
const i = {
|
|
93
|
+
accent: "border-accent-7",
|
|
94
|
+
error: "border-error-7",
|
|
95
|
+
success: "border-success-7",
|
|
96
|
+
warning: "border-warning-7",
|
|
97
|
+
neutral: "border-surface-border-strong"
|
|
98
|
+
};
|
|
99
|
+
return i[c] ?? i.accent;
|
|
100
|
+
}
|
|
101
|
+
function M({ className: c }) {
|
|
102
|
+
return /* @__PURE__ */ s("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", className: c, "aria-hidden": "true", children: /* @__PURE__ */ s("path", { d: "M3 4.5L6 7.5L9 4.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
103
|
+
}
|
|
104
|
+
const se = n.forwardRef(
|
|
105
|
+
function({
|
|
106
|
+
children: i,
|
|
107
|
+
onClick: u,
|
|
108
|
+
dropdownContent: E,
|
|
109
|
+
open: j,
|
|
110
|
+
onOpenChange: p,
|
|
111
|
+
variant: l = "solid",
|
|
112
|
+
color: v = "accent",
|
|
113
|
+
size: r = "md",
|
|
114
|
+
disabled: x = !1,
|
|
115
|
+
"aria-label": L,
|
|
116
|
+
dropdownLabel: R = "More options",
|
|
117
|
+
dropdownIcon: B,
|
|
118
|
+
triggerSide: O = "right",
|
|
119
|
+
placement: S = "top-end",
|
|
120
|
+
triggerWidth: g,
|
|
121
|
+
className: q
|
|
122
|
+
}, D) {
|
|
123
|
+
const [F, H] = n.useState(!1), h = j !== void 0, e = h ? j : F, b = n.useRef(null), f = n.useRef(null), w = n.useId(), d = n.useCallback(
|
|
124
|
+
(t) => {
|
|
125
|
+
p && p(t), h || H(t);
|
|
126
|
+
},
|
|
127
|
+
[p, h]
|
|
128
|
+
);
|
|
129
|
+
n.useEffect(() => {
|
|
130
|
+
if (!e || !b.current || !f.current) return;
|
|
131
|
+
const t = b.current, a = f.current;
|
|
132
|
+
return G(t, a, () => {
|
|
133
|
+
J(t, a, {
|
|
134
|
+
placement: S,
|
|
135
|
+
middleware: [
|
|
136
|
+
Q(8),
|
|
137
|
+
T({ fallbackPlacements: ["bottom-end", "top-start", "bottom-start"] }),
|
|
138
|
+
V({ padding: 8 })
|
|
139
|
+
]
|
|
140
|
+
}).then(({ x: K, y: U }) => {
|
|
141
|
+
Object.assign(a.style, { left: `${K}px`, top: `${U}px` });
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}, [e, S]), n.useEffect(() => {
|
|
145
|
+
if (!e) return;
|
|
146
|
+
const t = (a) => {
|
|
147
|
+
const k = a.target;
|
|
148
|
+
b.current?.contains(k) || f.current?.contains(k) || d(!1);
|
|
149
|
+
};
|
|
150
|
+
return document.addEventListener("mousedown", t), () => document.removeEventListener("mousedown", t);
|
|
151
|
+
}, [e, d]), n.useEffect(() => {
|
|
152
|
+
if (!e) return;
|
|
153
|
+
const t = (a) => {
|
|
154
|
+
a.key === "Escape" && d(!1);
|
|
155
|
+
};
|
|
156
|
+
return document.addEventListener("keydown", t), () => document.removeEventListener("keydown", t);
|
|
157
|
+
}, [e, d]);
|
|
158
|
+
const y = z(l, v), $ = A[l][v] ?? A[l].accent, P = g != null ? { width: typeof g == "number" ? `${g}px` : g } : void 0;
|
|
159
|
+
return /* @__PURE__ */ m(C, { children: [
|
|
160
|
+
/* @__PURE__ */ s(
|
|
161
|
+
"div",
|
|
162
|
+
{
|
|
163
|
+
ref: D,
|
|
164
|
+
role: "group",
|
|
165
|
+
"aria-label": L ?? void 0,
|
|
166
|
+
className: o("relative inline-flex", q),
|
|
167
|
+
children: /* @__PURE__ */ m(
|
|
168
|
+
"div",
|
|
169
|
+
{
|
|
170
|
+
ref: b,
|
|
171
|
+
className: o(
|
|
172
|
+
"inline-flex items-stretch overflow-hidden",
|
|
173
|
+
W[r],
|
|
174
|
+
l === "solid" && "shadow-raised",
|
|
175
|
+
l === "outline" && `border ${ee(v)}`
|
|
176
|
+
),
|
|
177
|
+
children: [
|
|
178
|
+
O === "left" && /* @__PURE__ */ m(C, { children: [
|
|
179
|
+
/* @__PURE__ */ s(
|
|
180
|
+
"button",
|
|
181
|
+
{
|
|
182
|
+
type: "button",
|
|
183
|
+
onClick: () => d(!e),
|
|
184
|
+
disabled: x,
|
|
185
|
+
"aria-label": R,
|
|
186
|
+
"aria-haspopup": "menu",
|
|
187
|
+
"aria-expanded": e,
|
|
188
|
+
"aria-controls": e ? w : void 0,
|
|
189
|
+
className: o(
|
|
190
|
+
"inline-flex items-center justify-center select-none",
|
|
191
|
+
"transition-colors duration-fast-01 ease-productive-standard",
|
|
192
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-inset",
|
|
193
|
+
"disabled:pointer-events-none disabled:opacity-action-disabled",
|
|
194
|
+
y,
|
|
195
|
+
N[r],
|
|
196
|
+
I[r]
|
|
197
|
+
),
|
|
198
|
+
style: P,
|
|
199
|
+
children: B ?? /* @__PURE__ */ s(M, {})
|
|
200
|
+
}
|
|
201
|
+
),
|
|
202
|
+
/* @__PURE__ */ s("div", { className: o("w-px self-stretch", $) })
|
|
203
|
+
] }),
|
|
204
|
+
/* @__PURE__ */ s(
|
|
205
|
+
"button",
|
|
206
|
+
{
|
|
207
|
+
type: "button",
|
|
208
|
+
onClick: u,
|
|
209
|
+
disabled: x,
|
|
210
|
+
"aria-label": L,
|
|
211
|
+
className: o(
|
|
212
|
+
"inline-flex items-center justify-center font-semibold select-none whitespace-nowrap",
|
|
213
|
+
"transition-colors duration-fast-01 ease-productive-standard",
|
|
214
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-inset",
|
|
215
|
+
"disabled:pointer-events-none disabled:opacity-action-disabled",
|
|
216
|
+
y,
|
|
217
|
+
N[r],
|
|
218
|
+
Z[r],
|
|
219
|
+
_[r]
|
|
220
|
+
),
|
|
221
|
+
children: i
|
|
222
|
+
}
|
|
223
|
+
),
|
|
224
|
+
O === "right" && /* @__PURE__ */ m(C, { children: [
|
|
225
|
+
/* @__PURE__ */ s("div", { className: o("w-px self-stretch", $) }),
|
|
226
|
+
/* @__PURE__ */ s(
|
|
227
|
+
"button",
|
|
228
|
+
{
|
|
229
|
+
type: "button",
|
|
230
|
+
onClick: () => d(!e),
|
|
231
|
+
disabled: x,
|
|
232
|
+
"aria-label": R,
|
|
233
|
+
"aria-haspopup": "menu",
|
|
234
|
+
"aria-expanded": e,
|
|
235
|
+
"aria-controls": e ? w : void 0,
|
|
236
|
+
className: o(
|
|
237
|
+
"inline-flex items-center justify-center select-none",
|
|
238
|
+
"transition-colors duration-fast-01 ease-productive-standard",
|
|
239
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-inset",
|
|
240
|
+
"disabled:pointer-events-none disabled:opacity-action-disabled",
|
|
241
|
+
y,
|
|
242
|
+
N[r],
|
|
243
|
+
I[r]
|
|
244
|
+
),
|
|
245
|
+
style: P,
|
|
246
|
+
children: B ?? /* @__PURE__ */ s(M, {})
|
|
247
|
+
}
|
|
248
|
+
)
|
|
249
|
+
] })
|
|
250
|
+
]
|
|
251
|
+
}
|
|
252
|
+
)
|
|
253
|
+
}
|
|
254
|
+
),
|
|
255
|
+
/* @__PURE__ */ s(X, { children: e && E && /* @__PURE__ */ s(
|
|
256
|
+
"div",
|
|
257
|
+
{
|
|
258
|
+
ref: f,
|
|
259
|
+
id: w,
|
|
260
|
+
role: "menu",
|
|
261
|
+
className: "fixed z-popover",
|
|
262
|
+
style: { top: 0, left: 0 },
|
|
263
|
+
children: /* @__PURE__ */ s(
|
|
264
|
+
Y.div,
|
|
265
|
+
{
|
|
266
|
+
initial: { opacity: 0, scale: 0.95 },
|
|
267
|
+
animate: { opacity: 1, scale: 1 },
|
|
268
|
+
exit: { opacity: 0, scale: 0.95 },
|
|
269
|
+
transition: { duration: 0.15 },
|
|
270
|
+
className: "rounded-ds-lg border border-surface-border-strong bg-surface-overlay shadow-floating",
|
|
271
|
+
children: E
|
|
272
|
+
}
|
|
273
|
+
)
|
|
274
|
+
}
|
|
275
|
+
) })
|
|
276
|
+
] });
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
se.displayName = "SplitButton";
|
|
280
|
+
export {
|
|
281
|
+
se as SplitButton
|
|
282
|
+
};
|
|
@@ -41,3 +41,12 @@ EmojiPicker, EmojiPickerPopover
|
|
|
41
41
|
- Wraps `@emoji-mart/react` which is lazy-loaded — shows a Skeleton placeholder while loading
|
|
42
42
|
- `theme="auto"` reads the `.dark` class on `<html>` to pick light/dark
|
|
43
43
|
- EmojiPickerPopover auto-closes after selection
|
|
44
|
+
|
|
45
|
+
## Changes
|
|
46
|
+
|
|
47
|
+
### v0.33.0
|
|
48
|
+
- **Added** `set` prop on EmojiPicker and EmojiPickerPopover — `EmojiSet` type: 'native' | 'apple' | 'google' | 'twitter' | 'facebook'
|
|
49
|
+
- **Added** `EmojiNode` TipTap extension — inline atom node with spritesheet rendering for consistent emoji art styles
|
|
50
|
+
- **Added** `createEmojiSuggestion(set?)` factory — replaces `EmojiSuggestion` named export
|
|
51
|
+
- **Added** `EmojiSet` type exported from barrel
|
|
52
|
+
- **Breaking** `EmojiSuggestion` named export removed — use `createEmojiSuggestion()` factory
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# RichChatInput
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra/composed/rich-chat-input
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: composed
|
|
6
|
+
|
|
7
|
+
Compact rich text chat input for unified human+AI workspaces. Built on TipTap.
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
### RichChatInputProps
|
|
12
|
+
onSubmit: (html: string, plainText: string) => void (REQUIRED)
|
|
13
|
+
placeholder: string (default: "Type a message...")
|
|
14
|
+
disabled: boolean (default: false)
|
|
15
|
+
variant: 'compact' | 'expanded' | 'minimal' (default: 'compact')
|
|
16
|
+
maxRows: number
|
|
17
|
+
enterBehavior: 'send' | 'newline' (default: 'send')
|
|
18
|
+
maxLength: number — enables character counter
|
|
19
|
+
mentions: MentionItem[] — static list for @mention autocomplete
|
|
20
|
+
onMentionSearch: (query: string) => Promise<MentionItem[]> — async search
|
|
21
|
+
onMentionSelect: (item: MentionItem) => void
|
|
22
|
+
onFileUpload: (file: File) => Promise<{ url: string; name: string; size: number }>
|
|
23
|
+
onImageUpload: (file: File) => Promise<string>
|
|
24
|
+
slashCommands: SlashCommandGroup[] — enables / command palette
|
|
25
|
+
onTyping: (isTyping: boolean) => void — typing indicator callback
|
|
26
|
+
onEmpty: (isEmpty: boolean) => void
|
|
27
|
+
isStreaming: boolean (default: false) — shows stop button instead of send
|
|
28
|
+
onCancel: () => void — called when stop button is clicked
|
|
29
|
+
leadingSlot: ReactNode — rendered above the editor
|
|
30
|
+
trailingSlot: ReactNode — rendered below the toolbar
|
|
31
|
+
disclaimer: string — small text below the input
|
|
32
|
+
toolbar: boolean | ChatToolbarItem[] (default: true)
|
|
33
|
+
|
|
34
|
+
ChatToolbarItem: 'bold' | 'italic' | 'underline' | 'strike' | 'highlight' | 'code' | 'bulletList' | 'orderedList' | 'mention' | 'emoji' | 'attach' | 'slash'
|
|
35
|
+
|
|
36
|
+
MentionItem: { id: string; label: string; avatar?: string }
|
|
37
|
+
|
|
38
|
+
SlashCommand: { id: string; label: string; description?: string; icon?: ComponentType; action: (editor: Editor) => void }
|
|
39
|
+
|
|
40
|
+
SlashCommandGroup: { label: string; commands: SlashCommand[] }
|
|
41
|
+
|
|
42
|
+
## Variants
|
|
43
|
+
- `compact` (default) — 2-3 lines, inline toolbar
|
|
44
|
+
- `expanded` — 5+ lines, always-visible toolbar, suited for AI prompts
|
|
45
|
+
- `minimal` — single line, toolbar appears on focus
|
|
46
|
+
|
|
47
|
+
## Example
|
|
48
|
+
```jsx
|
|
49
|
+
<RichChatInput
|
|
50
|
+
onSubmit={(html, text) => sendMessage(html)}
|
|
51
|
+
mentions={teamMembers}
|
|
52
|
+
onFileUpload={uploadFile}
|
|
53
|
+
slashCommands={[{ label: 'Actions', commands: [...] }]}
|
|
54
|
+
/>
|
|
55
|
+
|
|
56
|
+
<RichChatInput
|
|
57
|
+
variant="expanded"
|
|
58
|
+
onSubmit={handleSubmit}
|
|
59
|
+
maxLength={2000}
|
|
60
|
+
disclaimer="AI-generated content may be inaccurate."
|
|
61
|
+
/>
|
|
62
|
+
|
|
63
|
+
<RichChatInput
|
|
64
|
+
variant="minimal"
|
|
65
|
+
enterBehavior="newline"
|
|
66
|
+
onSubmit={handleReply}
|
|
67
|
+
/>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Gotchas
|
|
71
|
+
- Tiptap is bundled — no need to install `@tiptap/*` packages separately
|
|
72
|
+
- Enter sends by default; use `enterBehavior="newline"` for long-form composition (Cmd/Ctrl+Enter always sends)
|
|
73
|
+
- `maxLength` enables both a character limit and the visual counter in the toolbar
|
|
74
|
+
- File/image upload buttons only appear when the corresponding handler is provided
|
|
75
|
+
- Slash command button only appears when `slashCommands` is provided
|
|
76
|
+
- Mention button only appears when `mentions` or `onMentionSearch` is provided
|
|
77
|
+
|
|
78
|
+
## Changes
|
|
79
|
+
### v0.33.0
|
|
80
|
+
- **Added** Custom EmojiNode with spritesheet rendering — `emojiSet` prop
|
|
81
|
+
- **Added** `onSchedule` prop — schedule send with smart presets + DateTimePicker, SplitButton UX
|
|
82
|
+
- **Added** `actionButton` prop — composable left-side button (replaces default attach, or pass false to hide)
|
|
83
|
+
- **Added** Animated mic ↔ send button transitions (AnimatePresence)
|
|
84
|
+
- **Changed** Voice recording buttons from outline to soft variant
|
|
85
|
+
- **Fixed** ToolbarButton width for custom-width buttons (e.g. "Refine" with text label)
|
|
86
|
+
|
|
87
|
+
### v0.32.0
|
|
88
|
+
- Initial release
|
|
@@ -55,6 +55,11 @@ MentionItem: { id: string; label: string; avatar?: string }
|
|
|
55
55
|
- Features: bold, italic, underline, strikethrough, highlight, headings, blockquote, lists, task lists, code, links, images, file attachments, mentions, emoji, text alignment, horizontal rule
|
|
56
56
|
|
|
57
57
|
## Changes
|
|
58
|
+
### v0.33.0
|
|
59
|
+
- **Added** `emojiSet` prop — `EmojiSet` type for consistent emoji art style rendering
|
|
60
|
+
- **Changed** TipTap v2 → v3 upgrade (useEditorState, immediatelyRender: false for SSR, ListKit)
|
|
61
|
+
- **Added** EmojiNode + createEmojiSuggestion(set) registered internally
|
|
62
|
+
|
|
58
63
|
### v0.30.0
|
|
59
64
|
- **Added** `toolbar` prop — whitelist of `ToolbarItem` names to control which toolbar buttons appear. Dividers render only between groups that have visible items. `ToolbarItem` type exported from barrel.
|
|
60
65
|
|
|
@@ -25,6 +25,15 @@
|
|
|
25
25
|
- Children can override variant/size individually
|
|
26
26
|
|
|
27
27
|
## Changes
|
|
28
|
+
### v0.33.0
|
|
29
|
+
- **Rebuilt** with compound component pattern — Button reads position from ButtonGroup context and applies border-radius inline
|
|
30
|
+
- **Added** `disabled` prop (propagates to all children via context)
|
|
31
|
+
- **Added** `attached` prop (default true; false = spaced with gap)
|
|
32
|
+
- **Added** `fullWidth` prop (stretch to fill container)
|
|
33
|
+
- **Added** Tonal divider elements between buttons for solid/soft/ghost variants
|
|
34
|
+
- **Added** Focus z-index isolation (focused button rises above siblings)
|
|
35
|
+
- **Fixed** Border-radius not working with custom `rounded-ds-*` design tokens
|
|
36
|
+
|
|
28
37
|
### v0.4.2
|
|
29
38
|
- **Fixed** `Omit<HTMLAttributes, 'color'>` resolves TS2320 conflict with CVA color prop
|
|
30
39
|
|
|
@@ -47,6 +47,10 @@
|
|
|
47
47
|
- Grain children (DevalokGrain) are auto-separated and rendered as direct button children for absolute positioning
|
|
48
48
|
|
|
49
49
|
## Changes
|
|
50
|
+
### v0.33.0
|
|
51
|
+
- **Added** `disabled` inherited from ButtonGroup context
|
|
52
|
+
- **Added** Position-aware border-radius when inside an attached ButtonGroup (compound component pattern)
|
|
53
|
+
|
|
50
54
|
### v0.29.0
|
|
51
55
|
- **Added** `soft` variant — tinted background, colored text (new middle ground between solid and ghost)
|
|
52
56
|
- **Added** 5 color options: `accent` (default), `error`, `success`, `warning`, `neutral` (replaces old `default`/`error`-only axis)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# SplitButton
|
|
2
|
+
|
|
3
|
+
A compound button that combines a primary action with a dropdown trigger, rendered as a single visual unit `[Action | ▼]`.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { SplitButton } from '@devalok/shilp-sutra'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<SplitButton onClick={handleSave} dropdownContent={<SaveOptions />}>
|
|
15
|
+
Save
|
|
16
|
+
</SplitButton>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Props
|
|
20
|
+
|
|
21
|
+
| Prop | Type | Default | Description |
|
|
22
|
+
|------|------|---------|-------------|
|
|
23
|
+
| children | ReactNode | — | Primary action content (left side) |
|
|
24
|
+
| onClick | (e) => void | — | Primary click handler |
|
|
25
|
+
| dropdownContent | ReactNode | — | Content rendered inside floating dropdown |
|
|
26
|
+
| variant | 'solid' \| 'soft' \| 'outline' | 'solid' | Visual style |
|
|
27
|
+
| color | 'accent' \| 'error' \| 'success' \| 'warning' \| 'neutral' | 'accent' | Color scheme |
|
|
28
|
+
| size | 'xs' \| 'sm' \| 'md' \| 'icon-xs' \| 'icon-sm' \| 'icon-md' | 'md' | Size |
|
|
29
|
+
| triggerSide | 'left' \| 'right' | 'right' | Which side the dropdown chevron sits on |
|
|
30
|
+
| triggerWidth | number \| string | auto | Custom width for the trigger half |
|
|
31
|
+
| placement | Placement | 'top-end' | Floating UI placement for dropdown |
|
|
32
|
+
| disabled | boolean | false | Disable both halves |
|
|
33
|
+
| open | boolean | — | Controlled open state |
|
|
34
|
+
| onOpenChange | (open: boolean) => void | — | Open state callback |
|
|
35
|
+
| dropdownLabel | string | 'More options' | aria-label for trigger |
|
|
36
|
+
| dropdownIcon | ReactNode | chevron-down | Custom trigger icon |
|
|
37
|
+
|
|
38
|
+
## Changes
|
|
39
|
+
|
|
40
|
+
### v0.33.0
|
|
41
|
+
- **Added** Initial release
|