@devalok/shilp-sutra 0.39.0 → 0.40.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/AGENTS.md +151 -0
- package/MIGRATION.md +137 -0
- package/README.md +3 -0
- package/dist/_chunks/badge-group.js +75 -74
- package/dist/_chunks/badge-group.js.map +1 -1
- package/dist/_chunks/chart-container.js +50 -0
- package/dist/_chunks/chart-container.js.map +1 -0
- package/dist/_chunks/chat.js +231 -223
- package/dist/_chunks/chat.js.map +1 -1
- package/dist/_chunks/colors.js +30 -0
- package/dist/_chunks/colors.js.map +1 -0
- package/dist/_chunks/emoji-data.js +45 -0
- package/dist/_chunks/emoji-data.js.map +1 -0
- package/dist/_chunks/grid-lines.js +72 -0
- package/dist/_chunks/grid-lines.js.map +1 -0
- package/dist/_chunks/mention-suggestion.js +31 -259
- package/dist/_chunks/mention-suggestion.js.map +1 -1
- package/dist/_chunks/normalize-icon.js +18 -0
- package/dist/_chunks/normalize-icon.js.map +1 -0
- package/dist/_chunks/oauth-button.js +227 -0
- package/dist/_chunks/oauth-button.js.map +1 -0
- package/dist/_chunks/primitives.js +107 -107
- package/dist/_chunks/primitives.js.map +1 -1
- package/dist/_chunks/{text.js → success.js} +24 -61
- package/dist/_chunks/success.js.map +1 -0
- package/dist/_chunks/tiptap.js +1952 -1949
- package/dist/_chunks/tiptap.js.map +1 -1
- package/dist/_chunks/tooltip.js +58 -0
- package/dist/_chunks/tooltip.js.map +1 -0
- package/dist/_chunks/tree-view.js +101 -96
- package/dist/_chunks/tree-view.js.map +1 -1
- package/dist/ai/ai-command-provider.d.ts +3 -2
- package/dist/ai/ai-command-provider.d.ts.map +1 -1
- package/dist/ai/ai-command-provider.js.map +1 -1
- package/dist/ai/block-renderer.js +11 -9
- package/dist/ai/block-renderer.js.map +1 -1
- package/dist/ai/blocks/error.js +31 -0
- package/dist/ai/blocks/error.js.map +1 -0
- package/dist/ai/blocks/index.d.ts +0 -2
- package/dist/ai/blocks/index.d.ts.map +1 -1
- package/dist/ai/blocks/index.js +2 -2
- package/dist/ai/blocks/text.js +19 -0
- package/dist/ai/blocks/text.js.map +1 -0
- package/dist/ai/command-bar.d.ts.map +1 -1
- package/dist/ai/command-bar.js +192 -187
- package/dist/ai/command-bar.js.map +1 -1
- package/dist/ai/conversation.d.ts +2 -1
- package/dist/ai/conversation.d.ts.map +1 -1
- package/dist/ai/conversation.js +88 -83
- package/dist/ai/conversation.js.map +1 -1
- package/dist/ai/index.d.ts +0 -4
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +45 -46
- package/dist/ai/index.js.map +1 -1
- package/dist/composed/activity-feed.d.ts +2 -1
- package/dist/composed/activity-feed.d.ts.map +1 -1
- package/dist/composed/activity-feed.js.map +1 -1
- package/dist/composed/bulk-action-bar.d.ts +2 -2
- package/dist/composed/bulk-action-bar.d.ts.map +1 -1
- package/dist/composed/bulk-action-bar.js +11 -11
- package/dist/composed/bulk-action-bar.js.map +1 -1
- package/dist/composed/command-palette.d.ts +2 -1
- package/dist/composed/command-palette.d.ts.map +1 -1
- package/dist/composed/command-palette.js +103 -98
- package/dist/composed/command-palette.js.map +1 -1
- package/dist/composed/date-picker/index.js +747 -3
- package/dist/composed/date-picker/index.js.map +1 -0
- package/dist/composed/empty-state.d.ts +3 -3
- package/dist/composed/empty-state.d.ts.map +1 -1
- package/dist/composed/empty-state.js +40 -31
- package/dist/composed/empty-state.js.map +1 -1
- package/dist/composed/extensions/emoji-node.js +81 -0
- package/dist/composed/extensions/emoji-node.js.map +1 -0
- package/dist/composed/extensions/emoji-suggestion.js +117 -0
- package/dist/composed/extensions/emoji-suggestion.js.map +1 -0
- package/dist/composed/file-preview.js +498 -2
- package/dist/{_chunks → composed}/file-preview.js.map +1 -1
- package/dist/composed/index.d.ts +0 -15
- package/dist/composed/index.d.ts.map +1 -1
- package/dist/composed/index.js +16 -24
- package/dist/composed/rich-chat-input.js +2073 -2
- package/dist/{_chunks → composed}/rich-chat-input.js.map +1 -1
- package/dist/composed/rich-text-editor.js +64 -61
- package/dist/composed/rich-text-editor.js.map +1 -1
- package/dist/composed/status-badge.d.ts +3 -2
- package/dist/composed/status-badge.d.ts.map +1 -1
- package/dist/composed/status-badge.js +58 -53
- package/dist/composed/status-badge.js.map +1 -1
- package/dist/shell/app-command-palette.d.ts +2 -1
- package/dist/shell/app-command-palette.d.ts.map +1 -1
- package/dist/shell/app-command-palette.js.map +1 -1
- package/dist/shell/bottom-navbar.d.ts +3 -1
- package/dist/shell/bottom-navbar.d.ts.map +1 -1
- package/dist/shell/bottom-navbar.js +90 -82
- package/dist/shell/bottom-navbar.js.map +1 -1
- package/dist/shell/command-registry.d.ts +2 -1
- package/dist/shell/command-registry.d.ts.map +1 -1
- package/dist/shell/command-registry.js.map +1 -1
- package/dist/shell/sidebar.d.ts +7 -4
- package/dist/shell/sidebar.d.ts.map +1 -1
- package/dist/shell/sidebar.js +143 -129
- package/dist/shell/sidebar.js.map +1 -1
- package/dist/shell/top-bar.d.ts +4 -3
- package/dist/shell/top-bar.d.ts.map +1 -1
- package/dist/shell/top-bar.js +114 -106
- package/dist/shell/top-bar.js.map +1 -1
- package/dist/ui/badge.d.ts +3 -2
- package/dist/ui/badge.d.ts.map +1 -1
- package/dist/ui/button.d.ts +3 -2
- package/dist/ui/button.d.ts.map +1 -1
- package/dist/ui/button.js +54 -53
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/charts/area-chart.js +177 -0
- package/dist/ui/charts/area-chart.js.map +1 -0
- package/dist/ui/charts/bar-chart.js +127 -0
- package/dist/ui/charts/bar-chart.js.map +1 -0
- package/dist/ui/charts/chart-container.js +3 -0
- package/dist/ui/charts/gauge-chart.js +72 -0
- package/dist/ui/charts/gauge-chart.js.map +1 -0
- package/dist/ui/charts/index.js +10 -1035
- package/dist/ui/charts/line-chart.js +135 -0
- package/dist/ui/charts/line-chart.js.map +1 -0
- package/dist/ui/charts/pie-chart.js +111 -0
- package/dist/ui/charts/pie-chart.js.map +1 -0
- package/dist/ui/charts/radar-chart.js +170 -0
- package/dist/ui/charts/radar-chart.js.map +1 -0
- package/dist/ui/charts/sparkline.js +119 -0
- package/dist/ui/charts/sparkline.js.map +1 -0
- package/dist/ui/chat/message.d.ts +3 -3
- package/dist/ui/chat/message.d.ts.map +1 -1
- package/dist/ui/chat/system-message.d.ts +2 -1
- package/dist/ui/chat/system-message.d.ts.map +1 -1
- package/dist/ui/combobox.d.ts +2 -1
- package/dist/ui/combobox.d.ts.map +1 -1
- package/dist/ui/combobox.js +97 -92
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/container.d.ts +6 -1
- package/dist/ui/container.d.ts.map +1 -1
- package/dist/ui/container.js +2 -1
- package/dist/ui/container.js.map +1 -1
- package/dist/ui/icon-button.d.ts +9 -2
- package/dist/ui/icon-button.d.ts.map +1 -1
- package/dist/ui/icon-button.js +14 -13
- package/dist/ui/icon-button.js.map +1 -1
- package/dist/ui/index.d.ts +1 -3
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +31 -33
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/lib/icon-input.d.ts +42 -0
- package/dist/ui/lib/icon-input.d.ts.map +1 -0
- package/dist/ui/lib/normalize-icon.d.ts +39 -0
- package/dist/ui/lib/normalize-icon.d.ts.map +1 -0
- package/dist/ui/oauth-button/index.d.ts +3 -0
- package/dist/ui/oauth-button/index.d.ts.map +1 -0
- package/dist/ui/oauth-button/index.js +3 -0
- package/dist/ui/oauth-button/oauth-button.d.ts +208 -0
- package/dist/ui/oauth-button/oauth-button.d.ts.map +1 -0
- package/dist/ui/progress.js +1 -1
- package/dist/ui/segmented-control.d.ts +3 -4
- package/dist/ui/segmented-control.d.ts.map +1 -1
- package/dist/ui/segmented-control.js +53 -45
- package/dist/ui/segmented-control.js.map +1 -1
- package/dist/ui/stack.d.ts +6 -1
- package/dist/ui/stack.d.ts.map +1 -1
- package/dist/ui/stack.js +2 -1
- package/dist/ui/stack.js.map +1 -1
- package/dist/ui/stat-card.d.ts +2 -3
- package/dist/ui/stat-card.d.ts.map +1 -1
- package/dist/ui/stat-card.js +117 -115
- package/dist/ui/stat-card.js.map +1 -1
- package/dist/ui/stepper.d.ts +2 -1
- package/dist/ui/stepper.d.ts.map +1 -1
- package/dist/ui/stepper.js +74 -69
- package/dist/ui/stepper.js.map +1 -1
- package/dist/ui/text.d.ts +7 -2
- package/dist/ui/text.d.ts.map +1 -1
- package/dist/ui/text.js +2 -1
- package/dist/ui/text.js.map +1 -1
- package/dist/ui/toaster.d.ts +11 -2
- package/dist/ui/toaster.d.ts.map +1 -1
- package/dist/ui/toaster.js.map +1 -1
- package/dist/ui/tooltip.js +12 -12
- package/dist/ui/tree-view/tree-item.d.ts +3 -2
- package/dist/ui/tree-view/tree-item.d.ts.map +1 -1
- package/dist/ui/tree-view/use-tree.d.ts +2 -1
- package/dist/ui/tree-view/use-tree.d.ts.map +1 -1
- package/docs/components/ui/oauth-button.md +86 -0
- package/docs/recipes/customize-brand.md +15 -0
- package/docs/recipes/index.md +5 -1
- package/docs/recipes/install-astro.md +15 -0
- package/docs/recipes/install-next-app-router.md +21 -5
- package/docs/recipes/install-next-pages.md +2 -0
- package/docs/recipes/install-remix.md +15 -0
- package/docs/recipes/install-tanstack-start.md +15 -0
- package/docs/recipes/install-vite.md +15 -0
- package/docs/recipes/troubleshoot.md +22 -0
- package/llms-full.txt +87 -1
- package/llms-quick.txt +247 -0
- package/llms.txt +107 -2
- package/package.json +79 -2
- package/scripts/welcome.mjs +219 -0
- package/skill/SKILL.md +22 -3
- package/skill/references/components-full.md +87 -1
- package/skill/references/components.md +107 -2
- package/skill/references/customize-brand.md +15 -0
- package/skill/references/setup-astro.md +15 -0
- package/skill/references/setup-next-app-router.md +21 -5
- package/skill/references/setup-next-pages.md +2 -0
- package/skill/references/setup-remix.md +15 -0
- package/skill/references/setup-tanstack-start.md +15 -0
- package/skill/references/setup-vite.md +15 -0
- package/skill/references/troubleshoot.md +22 -0
- package/dist/_chunks/date-picker.js +0 -748
- package/dist/_chunks/date-picker.js.map +0 -1
- package/dist/_chunks/file-preview.js +0 -499
- package/dist/_chunks/rich-chat-input.js +0 -2071
- package/dist/_chunks/text.js.map +0 -1
- package/dist/ui/charts/index.js.map +0 -1
package/dist/ui/stepper.js
CHANGED
|
@@ -1,47 +1,52 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
2
|
+
import { IconProvider as e } from "./icon-context.js";
|
|
3
|
+
import { springs as t } from "./lib/motion.js";
|
|
4
|
+
import { cn as n } from "./lib/utils.js";
|
|
5
|
+
import { t as r } from "../_chunks/normalize-icon.js";
|
|
6
|
+
import * as i from "react";
|
|
7
|
+
import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
8
|
+
import { AnimatePresence as c, motion as l } from "framer-motion";
|
|
7
9
|
//#region src/ui/stepper.tsx
|
|
8
|
-
var
|
|
10
|
+
var u = i.createContext({
|
|
9
11
|
activeStep: 0,
|
|
10
12
|
orientation: "horizontal",
|
|
11
13
|
stepperId: ""
|
|
12
|
-
}),
|
|
13
|
-
let f =
|
|
14
|
+
}), d = i.forwardRef(({ activeStep: e, orientation: t = "horizontal", onStepClick: r, className: a, children: c, ...l }, d) => {
|
|
15
|
+
let f = i.Children.toArray(c), p = i.useId(), m = i.useMemo(() => ({
|
|
14
16
|
activeStep: e,
|
|
15
|
-
orientation:
|
|
17
|
+
orientation: t,
|
|
16
18
|
stepperId: p,
|
|
17
|
-
onStepClick:
|
|
19
|
+
onStepClick: r
|
|
18
20
|
}), [
|
|
19
21
|
e,
|
|
20
|
-
|
|
22
|
+
t,
|
|
21
23
|
p,
|
|
22
|
-
|
|
24
|
+
r
|
|
23
25
|
]);
|
|
24
|
-
return /* @__PURE__ */
|
|
26
|
+
return /* @__PURE__ */ o(u.Provider, {
|
|
25
27
|
value: m,
|
|
26
|
-
children: /* @__PURE__ */
|
|
28
|
+
children: /* @__PURE__ */ o("div", {
|
|
27
29
|
ref: d,
|
|
28
|
-
className:
|
|
30
|
+
className: n("flex gap-ds-02", t === "vertical" ? "flex-col" : "flex-row items-center", a),
|
|
29
31
|
role: "list",
|
|
30
|
-
...
|
|
31
|
-
children: f.map((
|
|
32
|
-
className:
|
|
32
|
+
...l,
|
|
33
|
+
children: f.map((r, a) => /* @__PURE__ */ s(i.Fragment, { children: [i.isValidElement(r) ? i.cloneElement(r, { _index: a }) : r, a < f.length - 1 && /* @__PURE__ */ o("div", {
|
|
34
|
+
className: n("relative flex-1 overflow-hidden", t === "vertical" ? "ml-ds-04 w-ds-01 min-h-ds-05" : "h-ds-01 min-w-ds-05", "bg-surface-border"),
|
|
33
35
|
"aria-hidden": "true",
|
|
34
|
-
children: /* @__PURE__ */
|
|
35
|
-
className:
|
|
36
|
-
style: { transform: `${
|
|
36
|
+
children: /* @__PURE__ */ o("div", {
|
|
37
|
+
className: n("absolute inset-0 bg-accent-9 transition-transform duration-moderate-02 ease-productive-standard", t === "vertical" ? "origin-top" : "origin-left"),
|
|
38
|
+
style: { transform: `${t === "vertical" ? "scaleY" : "scaleX"}(${+(a < e)})` }
|
|
37
39
|
})
|
|
38
|
-
})] },
|
|
40
|
+
})] }, a))
|
|
39
41
|
})
|
|
40
42
|
});
|
|
41
|
-
}),
|
|
42
|
-
let { _index:
|
|
43
|
-
className:
|
|
44
|
-
children:
|
|
43
|
+
}), f = i.forwardRef(({ label: t, description: c, icon: l, className: d, ...f }, p) => {
|
|
44
|
+
let { _index: m = 0, ...h } = f, { activeStep: g, orientation: _, stepperId: v, onStepClick: y } = i.useContext(u), b = m < g ? "completed" : m === g ? "active" : "pending", x = b === "completed" && !!y, S = /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o("div", {
|
|
45
|
+
className: n("relative shrink-0 flex items-center justify-center w-ds-sm h-ds-sm rounded-pill text-ds-sm font-semibold", "transition-[background-color,border-color,color] duration-moderate-01 ease-productive-standard", b === "completed" && "bg-accent-9 text-accent-fg", b === "active" && "bg-accent-9 text-accent-fg", b === "pending" && "bg-surface-raised text-surface-fg-subtle border border-surface-border-strong"),
|
|
46
|
+
children: l ? /* @__PURE__ */ o(e, {
|
|
47
|
+
size: "sm",
|
|
48
|
+
children: r(l)
|
|
49
|
+
}) : b === "completed" ? /* @__PURE__ */ o("svg", {
|
|
45
50
|
className: "w-ico-sm h-ico-sm",
|
|
46
51
|
viewBox: "0 0 24 24",
|
|
47
52
|
fill: "none",
|
|
@@ -49,48 +54,48 @@ var c = n.createContext({
|
|
|
49
54
|
strokeWidth: 2.5,
|
|
50
55
|
strokeLinecap: "round",
|
|
51
56
|
strokeLinejoin: "round",
|
|
52
|
-
children: /* @__PURE__ */
|
|
53
|
-
}) :
|
|
54
|
-
}), /* @__PURE__ */
|
|
57
|
+
children: /* @__PURE__ */ o("polyline", { points: "20 6 9 17 4 12" })
|
|
58
|
+
}) : m + 1
|
|
59
|
+
}), /* @__PURE__ */ s("div", {
|
|
55
60
|
className: "flex flex-col",
|
|
56
|
-
children: [/* @__PURE__ */
|
|
57
|
-
className:
|
|
58
|
-
children:
|
|
59
|
-
}),
|
|
61
|
+
children: [/* @__PURE__ */ o("span", {
|
|
62
|
+
className: n("text-ds-md font-medium leading-ds-snug", b === "pending" ? "text-surface-fg-subtle" : "text-surface-fg"),
|
|
63
|
+
children: t
|
|
64
|
+
}), c && /* @__PURE__ */ o("span", {
|
|
60
65
|
className: "text-ds-sm text-surface-fg-muted leading-ds-relaxed",
|
|
61
|
-
children:
|
|
66
|
+
children: c
|
|
62
67
|
})]
|
|
63
68
|
})] });
|
|
64
|
-
return
|
|
65
|
-
ref:
|
|
69
|
+
return x ? /* @__PURE__ */ o("div", {
|
|
70
|
+
ref: p,
|
|
66
71
|
"data-step": "",
|
|
67
|
-
"data-state":
|
|
72
|
+
"data-state": b,
|
|
68
73
|
role: "listitem",
|
|
69
|
-
className:
|
|
70
|
-
...
|
|
71
|
-
children: /* @__PURE__ */
|
|
74
|
+
className: n(_ === "vertical" && "py-ds-02", d),
|
|
75
|
+
...h,
|
|
76
|
+
children: /* @__PURE__ */ o("button", {
|
|
72
77
|
type: "button",
|
|
73
78
|
tabIndex: 0,
|
|
74
|
-
"aria-label": `Go to step ${
|
|
75
|
-
onClick: () =>
|
|
76
|
-
className:
|
|
77
|
-
children:
|
|
79
|
+
"aria-label": `Go to step ${m + 1}: ${t}`,
|
|
80
|
+
onClick: () => y(m),
|
|
81
|
+
className: n("flex items-center gap-ds-03 cursor-pointer select-none", "rounded-control px-ds-02 py-ds-01 -mx-ds-02 -my-ds-01", "bg-transparent border-0", "hover:bg-surface-raised-hover active:bg-surface-raised-active", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-8 focus-visible:ring-offset-2", "transition-colors duration-fast-01 ease-productive-standard"),
|
|
82
|
+
children: S
|
|
78
83
|
})
|
|
79
|
-
}) : /* @__PURE__ */
|
|
80
|
-
ref:
|
|
84
|
+
}) : /* @__PURE__ */ o("div", {
|
|
85
|
+
ref: p,
|
|
81
86
|
"data-step": "",
|
|
82
|
-
"data-state":
|
|
87
|
+
"data-state": b,
|
|
83
88
|
role: "listitem",
|
|
84
|
-
"aria-current":
|
|
85
|
-
"aria-label": `Step ${
|
|
86
|
-
className:
|
|
87
|
-
...
|
|
88
|
-
children:
|
|
89
|
+
"aria-current": b === "active" ? "step" : void 0,
|
|
90
|
+
"aria-label": `Step ${m + 1}: ${t}, ${b === "completed" ? "completed" : b === "active" ? "current" : "upcoming"}`,
|
|
91
|
+
className: n("flex items-center gap-ds-03", _ === "vertical" && "py-ds-02", d),
|
|
92
|
+
...h,
|
|
93
|
+
children: S
|
|
89
94
|
});
|
|
90
|
-
}),
|
|
95
|
+
}), p = 40, m = {
|
|
91
96
|
enter: (e) => ({
|
|
92
97
|
opacity: 0,
|
|
93
|
-
x: e *
|
|
98
|
+
x: e * p
|
|
94
99
|
}),
|
|
95
100
|
center: {
|
|
96
101
|
opacity: 1,
|
|
@@ -98,30 +103,30 @@ var c = n.createContext({
|
|
|
98
103
|
},
|
|
99
104
|
exit: (e) => ({
|
|
100
105
|
opacity: 0,
|
|
101
|
-
x: e * -
|
|
106
|
+
x: e * -p
|
|
102
107
|
})
|
|
103
108
|
};
|
|
104
|
-
function
|
|
105
|
-
let
|
|
106
|
-
return
|
|
107
|
-
|
|
108
|
-
}, [
|
|
109
|
-
className:
|
|
110
|
-
children: /* @__PURE__ */
|
|
109
|
+
function h({ activeStep: e, children: r, className: a }) {
|
|
110
|
+
let s = i.useRef(e), u = e >= s.current ? 1 : -1;
|
|
111
|
+
return i.useEffect(() => {
|
|
112
|
+
s.current = e;
|
|
113
|
+
}, [e]), /* @__PURE__ */ o("div", {
|
|
114
|
+
className: n("relative overflow-hidden", a),
|
|
115
|
+
children: /* @__PURE__ */ o(c, {
|
|
111
116
|
mode: "wait",
|
|
112
117
|
custom: u,
|
|
113
|
-
children: /* @__PURE__ */
|
|
118
|
+
children: /* @__PURE__ */ o(l.div, {
|
|
114
119
|
custom: u,
|
|
115
|
-
variants:
|
|
120
|
+
variants: m,
|
|
116
121
|
initial: "enter",
|
|
117
122
|
animate: "center",
|
|
118
123
|
exit: "exit",
|
|
119
|
-
transition:
|
|
120
|
-
children:
|
|
121
|
-
},
|
|
124
|
+
transition: t.smooth,
|
|
125
|
+
children: r
|
|
126
|
+
}, e)
|
|
122
127
|
})
|
|
123
128
|
});
|
|
124
129
|
}
|
|
125
|
-
|
|
130
|
+
d.displayName = "Stepper", f.displayName = "Step", h.displayName = "StepperContent";
|
|
126
131
|
//#endregion
|
|
127
|
-
export {
|
|
132
|
+
export { f as Step, d as Stepper, h as StepperContent };
|
package/dist/ui/stepper.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stepper.js","names":[],"sources":["../../src/ui/stepper.tsx"],"sourcesContent":["'use client'\n\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { springs } from './lib/motion'\nimport { cn } from './lib/utils'\n\ntype StepState = 'completed' | 'active' | 'pending'\n\ntype StepperContextValue = {\n activeStep: number\n orientation: 'horizontal' | 'vertical'\n stepperId: string\n onStepClick?: (stepIndex: number) => void\n}\n\nconst StepperContext = React.createContext<StepperContextValue>({\n activeStep: 0,\n orientation: 'horizontal',\n stepperId: '',\n})\n\n/**\n * Props for Stepper — a multi-step progress indicator that renders a connected series of `<Step>`\n * children with connector lines, showing completed/active/pending states automatically.\n *\n * **`activeStep`:** 0-indexed. Step at `activeStep` is \"active\", steps before it are \"completed\",\n * steps after it are \"pending\". Update this value to advance the stepper.\n *\n * **Orientation:** `'horizontal'` (default, left-to-right) | `'vertical'` (top-to-bottom, for sidebars).\n *\n * **Children:** Must be `<Step>` components. The Stepper injects `_index` into each child automatically.\n *\n * @example\n * // Horizontal 3-step form wizard:\n * <Stepper activeStep={currentStep}>\n * <Step label=\"Account\" description=\"Create your credentials\" />\n * <Step label=\"Profile\" description=\"Add your details\" />\n * <Step label=\"Review\" description=\"Confirm and submit\" />\n * </Stepper>\n *\n * @example\n * // Vertical onboarding checklist in a sidebar:\n * <Stepper activeStep={completedSteps} orientation=\"vertical\">\n * <Step label=\"Connect workspace\" />\n * <Step label=\"Invite teammates\" />\n * <Step label=\"Set up billing\" />\n * </Stepper>\n *\n * @example\n * // Clickable completed steps — user can navigate back:\n * <Stepper activeStep={step} onStepClick={(i) => setStep(i)}>\n * <Step label=\"Account\" />\n * <Step label=\"Profile\" />\n * <Step label=\"Review\" />\n * </Stepper>\n * // These are just a few ways — feel free to combine props creatively!\n */\ninterface StepperProps extends React.HTMLAttributes<HTMLDivElement> {\n activeStep: number\n orientation?: 'horizontal' | 'vertical'\n /** Called when a completed step is clicked. Receives the 0-based step index. */\n onStepClick?: (stepIndex: number) => void\n children: React.ReactNode\n}\n\nconst Stepper = React.forwardRef<HTMLDivElement, StepperProps>(\n ({ activeStep, orientation = 'horizontal', onStepClick, className, children, ...props }, ref) => {\n const steps = React.Children.toArray(children)\n const stepperId = React.useId()\n const contextValue = React.useMemo(\n () => ({ activeStep, orientation, stepperId, onStepClick }),\n [activeStep, orientation, stepperId, onStepClick],\n )\n return (\n <StepperContext.Provider value={contextValue}>\n <div\n ref={ref}\n className={cn(\n 'flex gap-ds-02',\n orientation === 'vertical' ? 'flex-col' : 'flex-row items-center',\n className,\n )}\n role=\"list\"\n {...props}\n >\n {steps.map((child, index) => (\n <React.Fragment key={index}>\n {React.isValidElement<StepInternalProps>(child)\n ? React.cloneElement(child, { _index: index })\n : child}\n {index < steps.length - 1 && (\n <div\n className={cn(\n 'relative flex-1 overflow-hidden',\n orientation === 'vertical'\n ? 'ml-ds-04 w-ds-01 min-h-ds-05'\n : 'h-ds-01 min-w-ds-05',\n 'bg-surface-border',\n )}\n aria-hidden=\"true\"\n >\n {/* Filled portion — smooth CSS transition */}\n <div\n className={cn(\n 'absolute inset-0 bg-accent-9 transition-transform duration-moderate-02 ease-productive-standard',\n orientation === 'vertical' ? 'origin-top' : 'origin-left',\n )}\n style={{\n transform: `${orientation === 'vertical' ? 'scaleY' : 'scaleX'}(${index < activeStep ? 1 : 0})`,\n }}\n />\n </div>\n )}\n </React.Fragment>\n ))}\n </div>\n </StepperContext.Provider>\n )\n },\n)\n\n/**\n * Props for Step — a single step within a `<Stepper>`. The visual state (completed/active/pending)\n * is derived from the parent Stepper's `activeStep` and this step's position — you don't set it manually.\n *\n * @example\n * // Basic step with label and description:\n * <Step label=\"Payment\" description=\"Enter your card details\" />\n *\n * @example\n * // Step with a custom icon (overrides the default number/checkmark):\n * <Step label=\"Verified\" icon={<IconShieldCheck className=\"h-ico-sm w-ico-sm\" />} />\n */\ninterface StepProps extends React.HTMLAttributes<HTMLDivElement> {\n label: string\n description?: string\n icon?: React.ReactNode\n}\n\ntype StepInternalProps = StepProps & { _index?: number }\n\nconst Step = React.forwardRef<HTMLDivElement, StepProps>(\n ({ label, description, icon, className, ...props }, ref) => {\n const { _index = 0, ...restProps } = props as StepInternalProps\n const { activeStep, orientation, stepperId, onStepClick } = React.useContext(StepperContext)\n const state: StepState = _index < activeStep ? 'completed' : _index === activeStep ? 'active' : 'pending'\n const isClickable = state === 'completed' && !!onStepClick\n\n const stepContent = (\n <>\n <div\n className={cn(\n 'relative shrink-0 flex items-center justify-center w-ds-sm h-ds-sm rounded-pill text-ds-sm font-semibold',\n 'transition-[background-color,border-color,color] duration-moderate-01 ease-productive-standard',\n state === 'completed' && 'bg-accent-9 text-accent-fg',\n state === 'active' && 'bg-accent-9 text-accent-fg',\n state === 'pending' && 'bg-surface-raised text-surface-fg-subtle border border-surface-border-strong',\n )}\n >\n {icon || (state === 'completed' ? (\n <svg\n className=\"w-ico-sm h-ico-sm\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n ) : (\n _index + 1\n ))}\n </div>\n <div className=\"flex flex-col\">\n <span\n className={cn(\n 'text-ds-md font-medium leading-ds-snug',\n state === 'pending'\n ? 'text-surface-fg-subtle'\n : 'text-surface-fg',\n )}\n >\n {label}\n </span>\n {description && (\n <span className=\"text-ds-sm text-surface-fg-muted leading-ds-relaxed\">\n {description}\n </span>\n )}\n </div>\n </>\n )\n\n if (isClickable) {\n return (\n <div\n ref={ref}\n data-step=\"\"\n data-state={state}\n role=\"listitem\"\n className={cn(\n orientation === 'vertical' && 'py-ds-02',\n className,\n )}\n {...restProps}\n >\n <button\n type=\"button\"\n tabIndex={0}\n aria-label={`Go to step ${_index + 1}: ${label}`}\n onClick={() => onStepClick(_index)}\n className={cn(\n 'flex items-center gap-ds-03 cursor-pointer select-none',\n 'rounded-control px-ds-02 py-ds-01 -mx-ds-02 -my-ds-01',\n 'bg-transparent border-0',\n 'hover:bg-surface-raised-hover active:bg-surface-raised-active',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-8 focus-visible:ring-offset-2',\n 'transition-colors duration-fast-01 ease-productive-standard',\n )}\n >\n {stepContent}\n </button>\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n data-step=\"\"\n data-state={state}\n role=\"listitem\"\n aria-current={state === 'active' ? 'step' : undefined}\n aria-label={`Step ${_index + 1}: ${label}, ${state === 'completed' ? 'completed' : state === 'active' ? 'current' : 'upcoming'}`}\n className={cn(\n 'flex items-center gap-ds-03',\n orientation === 'vertical' && 'py-ds-02',\n className,\n )}\n {...restProps}\n >\n {stepContent}\n </div>\n )\n },\n)\n\n/**\n * Props for StepperContent — wraps the content panel for the active step, animating\n * slide transitions when `activeStep` changes. Detects forward vs backward navigation\n * and slides content accordingly.\n *\n * @example\n * <StepperContent activeStep={currentStep}>\n * {currentStep === 0 && <AccountForm />}\n * {currentStep === 1 && <ProfileForm />}\n * {currentStep === 2 && <ReviewPanel />}\n * </StepperContent>\n */\ninterface StepperContentProps {\n activeStep: number\n children: React.ReactNode\n className?: string\n}\n\nconst SLIDE_OFFSET = 40\n\nconst stepContentVariants = {\n enter: (direction: number) => ({\n opacity: 0,\n x: direction * SLIDE_OFFSET,\n }),\n center: {\n opacity: 1,\n x: 0,\n },\n exit: (direction: number) => ({\n opacity: 0,\n x: direction * -SLIDE_OFFSET,\n }),\n}\n\nfunction StepperContent({ activeStep, children, className }: StepperContentProps) {\n const prevStepRef = React.useRef(activeStep)\n const direction = activeStep >= prevStepRef.current ? 1 : -1\n\n React.useEffect(() => {\n prevStepRef.current = activeStep\n }, [activeStep])\n\n return (\n <div className={cn('relative overflow-hidden', className)}>\n <AnimatePresence mode=\"wait\" custom={direction}>\n <motion.div\n key={activeStep}\n custom={direction}\n variants={stepContentVariants}\n initial=\"enter\"\n animate=\"center\"\n exit=\"exit\"\n transition={springs.smooth}\n >\n {children}\n </motion.div>\n </AnimatePresence>\n </div>\n )\n}\n\nStepper.displayName = 'Stepper'\nStep.displayName = 'Step'\nStepperContent.displayName = 'StepperContent'\n\nexport { Step, Stepper, StepperContent, type StepperContentProps,type StepperProps, type StepProps }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stepper.js","names":[],"sources":["../../src/ui/stepper.tsx"],"sourcesContent":["'use client'\n\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { IconProvider } from './icon-context'\nimport type { IconInput } from './lib/icon-input'\nimport { springs } from './lib/motion'\nimport { normalizeIcon } from './lib/normalize-icon'\nimport { cn } from './lib/utils'\n\ntype StepState = 'completed' | 'active' | 'pending'\n\ntype StepperContextValue = {\n activeStep: number\n orientation: 'horizontal' | 'vertical'\n stepperId: string\n onStepClick?: (stepIndex: number) => void\n}\n\nconst StepperContext = React.createContext<StepperContextValue>({\n activeStep: 0,\n orientation: 'horizontal',\n stepperId: '',\n})\n\n/**\n * Props for Stepper — a multi-step progress indicator that renders a connected series of `<Step>`\n * children with connector lines, showing completed/active/pending states automatically.\n *\n * **`activeStep`:** 0-indexed. Step at `activeStep` is \"active\", steps before it are \"completed\",\n * steps after it are \"pending\". Update this value to advance the stepper.\n *\n * **Orientation:** `'horizontal'` (default, left-to-right) | `'vertical'` (top-to-bottom, for sidebars).\n *\n * **Children:** Must be `<Step>` components. The Stepper injects `_index` into each child automatically.\n *\n * @example\n * // Horizontal 3-step form wizard:\n * <Stepper activeStep={currentStep}>\n * <Step label=\"Account\" description=\"Create your credentials\" />\n * <Step label=\"Profile\" description=\"Add your details\" />\n * <Step label=\"Review\" description=\"Confirm and submit\" />\n * </Stepper>\n *\n * @example\n * // Vertical onboarding checklist in a sidebar:\n * <Stepper activeStep={completedSteps} orientation=\"vertical\">\n * <Step label=\"Connect workspace\" />\n * <Step label=\"Invite teammates\" />\n * <Step label=\"Set up billing\" />\n * </Stepper>\n *\n * @example\n * // Clickable completed steps — user can navigate back:\n * <Stepper activeStep={step} onStepClick={(i) => setStep(i)}>\n * <Step label=\"Account\" />\n * <Step label=\"Profile\" />\n * <Step label=\"Review\" />\n * </Stepper>\n * // These are just a few ways — feel free to combine props creatively!\n */\ninterface StepperProps extends React.HTMLAttributes<HTMLDivElement> {\n activeStep: number\n orientation?: 'horizontal' | 'vertical'\n /** Called when a completed step is clicked. Receives the 0-based step index. */\n onStepClick?: (stepIndex: number) => void\n children: React.ReactNode\n}\n\nconst Stepper = React.forwardRef<HTMLDivElement, StepperProps>(\n ({ activeStep, orientation = 'horizontal', onStepClick, className, children, ...props }, ref) => {\n const steps = React.Children.toArray(children)\n const stepperId = React.useId()\n const contextValue = React.useMemo(\n () => ({ activeStep, orientation, stepperId, onStepClick }),\n [activeStep, orientation, stepperId, onStepClick],\n )\n return (\n <StepperContext.Provider value={contextValue}>\n <div\n ref={ref}\n className={cn(\n 'flex gap-ds-02',\n orientation === 'vertical' ? 'flex-col' : 'flex-row items-center',\n className,\n )}\n role=\"list\"\n {...props}\n >\n {steps.map((child, index) => (\n <React.Fragment key={index}>\n {React.isValidElement<StepInternalProps>(child)\n ? React.cloneElement(child, { _index: index })\n : child}\n {index < steps.length - 1 && (\n <div\n className={cn(\n 'relative flex-1 overflow-hidden',\n orientation === 'vertical'\n ? 'ml-ds-04 w-ds-01 min-h-ds-05'\n : 'h-ds-01 min-w-ds-05',\n 'bg-surface-border',\n )}\n aria-hidden=\"true\"\n >\n {/* Filled portion — smooth CSS transition */}\n <div\n className={cn(\n 'absolute inset-0 bg-accent-9 transition-transform duration-moderate-02 ease-productive-standard',\n orientation === 'vertical' ? 'origin-top' : 'origin-left',\n )}\n style={{\n transform: `${orientation === 'vertical' ? 'scaleY' : 'scaleX'}(${index < activeStep ? 1 : 0})`,\n }}\n />\n </div>\n )}\n </React.Fragment>\n ))}\n </div>\n </StepperContext.Provider>\n )\n },\n)\n\n/**\n * Props for Step — a single step within a `<Stepper>`. The visual state (completed/active/pending)\n * is derived from the parent Stepper's `activeStep` and this step's position — you don't set it manually.\n *\n * @example\n * // Basic step with label and description:\n * <Step label=\"Payment\" description=\"Enter your card details\" />\n *\n * @example\n * // Step with a custom icon (overrides the default number/checkmark):\n * <Step label=\"Verified\" icon={<IconShieldCheck className=\"h-ico-sm w-ico-sm\" />} />\n */\ninterface StepProps extends React.HTMLAttributes<HTMLDivElement> {\n label: string\n description?: string\n icon?: IconInput\n}\n\ntype StepInternalProps = StepProps & { _index?: number }\n\nconst Step = React.forwardRef<HTMLDivElement, StepProps>(\n ({ label, description, icon, className, ...props }, ref) => {\n const { _index = 0, ...restProps } = props as StepInternalProps\n const { activeStep, orientation, stepperId, onStepClick } = React.useContext(StepperContext)\n const state: StepState = _index < activeStep ? 'completed' : _index === activeStep ? 'active' : 'pending'\n const isClickable = state === 'completed' && !!onStepClick\n\n const stepContent = (\n <>\n <div\n className={cn(\n 'relative shrink-0 flex items-center justify-center w-ds-sm h-ds-sm rounded-pill text-ds-sm font-semibold',\n 'transition-[background-color,border-color,color] duration-moderate-01 ease-productive-standard',\n state === 'completed' && 'bg-accent-9 text-accent-fg',\n state === 'active' && 'bg-accent-9 text-accent-fg',\n state === 'pending' && 'bg-surface-raised text-surface-fg-subtle border border-surface-border-strong',\n )}\n >\n {icon ? <IconProvider size=\"sm\">{normalizeIcon(icon)}</IconProvider> : (state === 'completed' ? (\n <svg\n className=\"w-ico-sm h-ico-sm\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n ) : (\n _index + 1\n ))}\n </div>\n <div className=\"flex flex-col\">\n <span\n className={cn(\n 'text-ds-md font-medium leading-ds-snug',\n state === 'pending'\n ? 'text-surface-fg-subtle'\n : 'text-surface-fg',\n )}\n >\n {label}\n </span>\n {description && (\n <span className=\"text-ds-sm text-surface-fg-muted leading-ds-relaxed\">\n {description}\n </span>\n )}\n </div>\n </>\n )\n\n if (isClickable) {\n return (\n <div\n ref={ref}\n data-step=\"\"\n data-state={state}\n role=\"listitem\"\n className={cn(\n orientation === 'vertical' && 'py-ds-02',\n className,\n )}\n {...restProps}\n >\n <button\n type=\"button\"\n tabIndex={0}\n aria-label={`Go to step ${_index + 1}: ${label}`}\n onClick={() => onStepClick(_index)}\n className={cn(\n 'flex items-center gap-ds-03 cursor-pointer select-none',\n 'rounded-control px-ds-02 py-ds-01 -mx-ds-02 -my-ds-01',\n 'bg-transparent border-0',\n 'hover:bg-surface-raised-hover active:bg-surface-raised-active',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-8 focus-visible:ring-offset-2',\n 'transition-colors duration-fast-01 ease-productive-standard',\n )}\n >\n {stepContent}\n </button>\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n data-step=\"\"\n data-state={state}\n role=\"listitem\"\n aria-current={state === 'active' ? 'step' : undefined}\n aria-label={`Step ${_index + 1}: ${label}, ${state === 'completed' ? 'completed' : state === 'active' ? 'current' : 'upcoming'}`}\n className={cn(\n 'flex items-center gap-ds-03',\n orientation === 'vertical' && 'py-ds-02',\n className,\n )}\n {...restProps}\n >\n {stepContent}\n </div>\n )\n },\n)\n\n/**\n * Props for StepperContent — wraps the content panel for the active step, animating\n * slide transitions when `activeStep` changes. Detects forward vs backward navigation\n * and slides content accordingly.\n *\n * @example\n * <StepperContent activeStep={currentStep}>\n * {currentStep === 0 && <AccountForm />}\n * {currentStep === 1 && <ProfileForm />}\n * {currentStep === 2 && <ReviewPanel />}\n * </StepperContent>\n */\ninterface StepperContentProps {\n activeStep: number\n children: React.ReactNode\n className?: string\n}\n\nconst SLIDE_OFFSET = 40\n\nconst stepContentVariants = {\n enter: (direction: number) => ({\n opacity: 0,\n x: direction * SLIDE_OFFSET,\n }),\n center: {\n opacity: 1,\n x: 0,\n },\n exit: (direction: number) => ({\n opacity: 0,\n x: direction * -SLIDE_OFFSET,\n }),\n}\n\nfunction StepperContent({ activeStep, children, className }: StepperContentProps) {\n const prevStepRef = React.useRef(activeStep)\n const direction = activeStep >= prevStepRef.current ? 1 : -1\n\n React.useEffect(() => {\n prevStepRef.current = activeStep\n }, [activeStep])\n\n return (\n <div className={cn('relative overflow-hidden', className)}>\n <AnimatePresence mode=\"wait\" custom={direction}>\n <motion.div\n key={activeStep}\n custom={direction}\n variants={stepContentVariants}\n initial=\"enter\"\n animate=\"center\"\n exit=\"exit\"\n transition={springs.smooth}\n >\n {children}\n </motion.div>\n </AnimatePresence>\n </div>\n )\n}\n\nStepper.displayName = 'Stepper'\nStep.displayName = 'Step'\nStepperContent.displayName = 'StepperContent'\n\nexport { Step, Stepper, StepperContent, type StepperContentProps,type StepperProps, type StepProps }\n"],"mappings":"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"}
|
package/dist/ui/text.d.ts
CHANGED
|
@@ -38,10 +38,15 @@ type TextVariant = NonNullable<VariantProps<typeof textVariants>['variant']>;
|
|
|
38
38
|
*/
|
|
39
39
|
type TextProps<T extends React.ElementType = 'p'> = {
|
|
40
40
|
variant?: TextVariant;
|
|
41
|
-
as?:
|
|
41
|
+
as?: T;
|
|
42
42
|
className?: string;
|
|
43
43
|
children?: React.ReactNode;
|
|
44
44
|
} & Omit<React.ComponentPropsWithRef<T>, 'as' | 'variant' | 'className' | 'children'>;
|
|
45
|
-
|
|
45
|
+
type TextComponent = (<T extends React.ElementType = 'p'>(props: TextProps<T> & {
|
|
46
|
+
ref?: React.ComponentPropsWithRef<T>['ref'];
|
|
47
|
+
}) => React.ReactElement | null) & {
|
|
48
|
+
displayName?: string;
|
|
49
|
+
};
|
|
50
|
+
declare const Text: TextComponent;
|
|
46
51
|
export { Text, type TextProps, type TextVariant, textVariants };
|
|
47
52
|
//# sourceMappingURL=text.d.ts.map
|
package/dist/ui/text.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/ui/text.tsx"],"names":[],"mappings":"AACA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,QAAA,MAAM,YAAY;;8EA4BhB,CAAA;AAEF,KAAK,WAAW,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;AAyB5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,KAAK,SAAS,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,GAAG,GAAG,IAAI;IAClD,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,EAAE,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/ui/text.tsx"],"names":[],"mappings":"AACA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,QAAA,MAAM,YAAY;;8EA4BhB,CAAA;AAEF,KAAK,WAAW,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;AAyB5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,KAAK,SAAS,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,GAAG,GAAG,IAAI;IAClD,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,EAAE,CAAC,EAAE,CAAC,CAAA;IACN,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC,CAAA;AAOrF,KAAK,aAAa,GAAG,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,GAAG,GAAG,EACtD,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;CAAE,KAClE,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAc1D,QAAA,MAAM,IAAI,EAA0B,aAAa,CAAA;AAEjD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAC,YAAY,EAAE,CAAA"}
|
package/dist/ui/text.js
CHANGED
package/dist/ui/text.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","names":[],"sources":["../../src/ui/text.tsx"],"sourcesContent":["// @server-safe\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from './lib/utils'\n\nconst textVariants = cva('font-sans', {\n variants: {\n variant: {\n 'heading-2xl': 'text-[length:var(--typo-heading-2xl-size)] font-[number:var(--typo-heading-2xl-weight)] leading-[var(--typo-heading-2xl-leading)] tracking-[var(--typo-heading-2xl-tracking)]',\n 'heading-xl': 'text-[length:var(--typo-heading-xl-size)] font-[number:var(--typo-heading-xl-weight)] leading-[var(--typo-heading-xl-leading)] tracking-[var(--typo-heading-xl-tracking)]',\n 'heading-lg': 'text-[length:var(--typo-heading-lg-size)] font-[number:var(--typo-heading-lg-weight)] leading-[var(--typo-heading-lg-leading)] tracking-[var(--typo-heading-lg-tracking)]',\n 'heading-md': 'text-[length:var(--typo-heading-md-size)] font-[number:var(--typo-heading-md-weight)] leading-[var(--typo-heading-md-leading)] tracking-[var(--typo-heading-md-tracking)]',\n 'heading-sm': 'text-[length:var(--typo-heading-sm-size)] font-[number:var(--typo-heading-sm-weight)] leading-[var(--typo-heading-sm-leading)] tracking-[var(--typo-heading-sm-tracking)]',\n 'heading-xs': 'text-[length:var(--typo-heading-xs-size)] font-[number:var(--typo-heading-xs-weight)] leading-[var(--typo-heading-xs-leading)] tracking-[var(--typo-heading-xs-tracking)]',\n 'body-lg': 'text-[length:var(--typo-body-lg-size)] font-[number:var(--typo-body-lg-weight)] leading-[var(--typo-body-lg-leading)] tracking-[var(--typo-body-lg-tracking)]',\n 'body-md': 'text-[length:var(--typo-body-md-size)] font-[number:var(--typo-body-md-weight)] leading-[var(--typo-body-md-leading)] tracking-[var(--typo-body-md-tracking)]',\n 'body-sm': 'text-[length:var(--typo-body-sm-size)] font-[number:var(--typo-body-sm-weight)] leading-[var(--typo-body-sm-leading)] tracking-[var(--typo-body-sm-tracking)]',\n 'body-xs': 'text-[length:var(--typo-body-xs-size)] font-[number:var(--typo-body-xs-weight)] leading-[var(--typo-body-xs-leading)] tracking-[var(--typo-body-xs-tracking)]',\n 'label-lg': 'text-[length:var(--typo-label-lg-size)] font-[number:var(--typo-label-lg-weight)] leading-[var(--typo-label-lg-leading)] tracking-[var(--typo-label-lg-tracking)] uppercase',\n 'label-md': 'text-[length:var(--typo-label-md-size)] font-[number:var(--typo-label-md-weight)] leading-[var(--typo-label-md-leading)] tracking-[var(--typo-label-md-tracking)] uppercase',\n 'label-sm': 'text-[length:var(--typo-label-sm-size)] font-[number:var(--typo-label-sm-weight)] leading-[var(--typo-label-sm-leading)] tracking-[var(--typo-label-sm-tracking)] uppercase',\n 'label-xs': 'text-[length:var(--typo-label-xs-size)] font-[number:var(--typo-label-xs-weight)] leading-[var(--typo-label-xs-leading)] tracking-[var(--typo-label-xs-tracking)] uppercase',\n caption: 'text-[length:var(--typo-caption-size)] font-[number:var(--typo-caption-weight)] leading-[var(--typo-caption-leading)] tracking-[var(--typo-caption-tracking)]',\n overline: 'text-[length:var(--typo-overline-size)] font-[number:var(--typo-overline-weight)] leading-[var(--typo-overline-leading)] tracking-[var(--typo-overline-tracking)] uppercase',\n code: 'text-[length:var(--typo-code-size)] font-[number:var(--typo-code-weight)] leading-[var(--typo-code-leading)] tracking-[var(--typo-code-tracking)] font-mono',\n 'label-plain-lg': 'text-[length:var(--typo-label-plain-lg-size)] font-[number:var(--typo-label-plain-lg-weight)] leading-[var(--typo-label-plain-lg-leading)] tracking-[var(--typo-label-plain-lg-tracking)]',\n 'label-plain-md': 'text-[length:var(--typo-label-plain-md-size)] font-[number:var(--typo-label-plain-md-weight)] leading-[var(--typo-label-plain-md-leading)] tracking-[var(--typo-label-plain-md-tracking)]',\n 'label-plain-sm': 'text-[length:var(--typo-label-plain-sm-size)] font-[number:var(--typo-label-plain-sm-weight)] leading-[var(--typo-label-plain-sm-leading)] tracking-[var(--typo-label-plain-sm-tracking)]',\n },\n },\n defaultVariants: {\n variant: 'body-md',\n },\n})\n\ntype TextVariant = NonNullable<VariantProps<typeof textVariants>['variant']>\n\nconst defaultElementMap: Record<TextVariant, keyof React.JSX.IntrinsicElements> = {\n 'heading-2xl': 'h1',\n 'heading-xl': 'h2',\n 'heading-lg': 'h3',\n 'heading-md': 'h4',\n 'heading-sm': 'h5',\n 'heading-xs': 'h6',\n 'body-lg': 'p',\n 'body-md': 'p',\n 'body-sm': 'p',\n 'body-xs': 'p',\n 'label-lg': 'span',\n 'label-md': 'span',\n 'label-sm': 'span',\n 'label-xs': 'span',\n caption: 'span',\n overline: 'span',\n code: 'code',\n 'label-plain-lg': 'span',\n 'label-plain-md': 'span',\n 'label-plain-sm': 'span',\n}\n\n/**\n * Props for Text — a polymorphic typography component covering the full type scale:\n * headings, body, labels, captions, and overlines — with automatic semantic HTML element selection.\n *\n * **Variants (grouped):**\n * - Headings: `heading-2xl` → `h1`, `heading-xl` → `h2`, `heading-lg` → `h3`, etc.\n * - Body: `body-lg` | `body-md` (default) | `body-sm` | `body-xs` → `<p>`\n * - Labels: `label-lg` | `label-md` | `label-sm` | `label-xs` → `<span>` (uppercase)\n * - Misc: `caption` | `overline` → `<span>` (overline is uppercase)\n *\n * **`as` prop:** Override the rendered element. E.g. `<Text variant=\"heading-lg\" as=\"div\">` renders\n * `<div class=\"text-heading-lg ...\">` — useful when you need heading styles on a non-heading element.\n *\n * @example\n * // Page heading:\n * <Text variant=\"heading-2xl\">Welcome to Shilp Sutra</Text>\n *\n * @example\n * // Section label (uppercase, small):\n * <Text variant=\"label-sm\" className=\"text-surface-fg-muted\">Recent activity</Text>\n *\n * @example\n * // Body copy with custom element (renders as <span> for inline use):\n * <Text variant=\"body-sm\" as=\"span\" className=\"text-surface-fg-muted\">\n * Last updated 3 hours ago\n * </Text>\n *\n * @example\n * // Caption under an image or figure:\n * <Text variant=\"caption\" className=\"text-surface-fg-subtle\">Figure 1: System architecture</Text>\n * // These are just a few ways — feel free to combine props creatively!\n */\ntype TextProps<T extends React.ElementType = 'p'> = {\n variant?: TextVariant\n as?:
|
|
1
|
+
{"version":3,"file":"text.js","names":[],"sources":["../../src/ui/text.tsx"],"sourcesContent":["// @server-safe\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from './lib/utils'\n\nconst textVariants = cva('font-sans', {\n variants: {\n variant: {\n 'heading-2xl': 'text-[length:var(--typo-heading-2xl-size)] font-[number:var(--typo-heading-2xl-weight)] leading-[var(--typo-heading-2xl-leading)] tracking-[var(--typo-heading-2xl-tracking)]',\n 'heading-xl': 'text-[length:var(--typo-heading-xl-size)] font-[number:var(--typo-heading-xl-weight)] leading-[var(--typo-heading-xl-leading)] tracking-[var(--typo-heading-xl-tracking)]',\n 'heading-lg': 'text-[length:var(--typo-heading-lg-size)] font-[number:var(--typo-heading-lg-weight)] leading-[var(--typo-heading-lg-leading)] tracking-[var(--typo-heading-lg-tracking)]',\n 'heading-md': 'text-[length:var(--typo-heading-md-size)] font-[number:var(--typo-heading-md-weight)] leading-[var(--typo-heading-md-leading)] tracking-[var(--typo-heading-md-tracking)]',\n 'heading-sm': 'text-[length:var(--typo-heading-sm-size)] font-[number:var(--typo-heading-sm-weight)] leading-[var(--typo-heading-sm-leading)] tracking-[var(--typo-heading-sm-tracking)]',\n 'heading-xs': 'text-[length:var(--typo-heading-xs-size)] font-[number:var(--typo-heading-xs-weight)] leading-[var(--typo-heading-xs-leading)] tracking-[var(--typo-heading-xs-tracking)]',\n 'body-lg': 'text-[length:var(--typo-body-lg-size)] font-[number:var(--typo-body-lg-weight)] leading-[var(--typo-body-lg-leading)] tracking-[var(--typo-body-lg-tracking)]',\n 'body-md': 'text-[length:var(--typo-body-md-size)] font-[number:var(--typo-body-md-weight)] leading-[var(--typo-body-md-leading)] tracking-[var(--typo-body-md-tracking)]',\n 'body-sm': 'text-[length:var(--typo-body-sm-size)] font-[number:var(--typo-body-sm-weight)] leading-[var(--typo-body-sm-leading)] tracking-[var(--typo-body-sm-tracking)]',\n 'body-xs': 'text-[length:var(--typo-body-xs-size)] font-[number:var(--typo-body-xs-weight)] leading-[var(--typo-body-xs-leading)] tracking-[var(--typo-body-xs-tracking)]',\n 'label-lg': 'text-[length:var(--typo-label-lg-size)] font-[number:var(--typo-label-lg-weight)] leading-[var(--typo-label-lg-leading)] tracking-[var(--typo-label-lg-tracking)] uppercase',\n 'label-md': 'text-[length:var(--typo-label-md-size)] font-[number:var(--typo-label-md-weight)] leading-[var(--typo-label-md-leading)] tracking-[var(--typo-label-md-tracking)] uppercase',\n 'label-sm': 'text-[length:var(--typo-label-sm-size)] font-[number:var(--typo-label-sm-weight)] leading-[var(--typo-label-sm-leading)] tracking-[var(--typo-label-sm-tracking)] uppercase',\n 'label-xs': 'text-[length:var(--typo-label-xs-size)] font-[number:var(--typo-label-xs-weight)] leading-[var(--typo-label-xs-leading)] tracking-[var(--typo-label-xs-tracking)] uppercase',\n caption: 'text-[length:var(--typo-caption-size)] font-[number:var(--typo-caption-weight)] leading-[var(--typo-caption-leading)] tracking-[var(--typo-caption-tracking)]',\n overline: 'text-[length:var(--typo-overline-size)] font-[number:var(--typo-overline-weight)] leading-[var(--typo-overline-leading)] tracking-[var(--typo-overline-tracking)] uppercase',\n code: 'text-[length:var(--typo-code-size)] font-[number:var(--typo-code-weight)] leading-[var(--typo-code-leading)] tracking-[var(--typo-code-tracking)] font-mono',\n 'label-plain-lg': 'text-[length:var(--typo-label-plain-lg-size)] font-[number:var(--typo-label-plain-lg-weight)] leading-[var(--typo-label-plain-lg-leading)] tracking-[var(--typo-label-plain-lg-tracking)]',\n 'label-plain-md': 'text-[length:var(--typo-label-plain-md-size)] font-[number:var(--typo-label-plain-md-weight)] leading-[var(--typo-label-plain-md-leading)] tracking-[var(--typo-label-plain-md-tracking)]',\n 'label-plain-sm': 'text-[length:var(--typo-label-plain-sm-size)] font-[number:var(--typo-label-plain-sm-weight)] leading-[var(--typo-label-plain-sm-leading)] tracking-[var(--typo-label-plain-sm-tracking)]',\n },\n },\n defaultVariants: {\n variant: 'body-md',\n },\n})\n\ntype TextVariant = NonNullable<VariantProps<typeof textVariants>['variant']>\n\nconst defaultElementMap: Record<TextVariant, keyof React.JSX.IntrinsicElements> = {\n 'heading-2xl': 'h1',\n 'heading-xl': 'h2',\n 'heading-lg': 'h3',\n 'heading-md': 'h4',\n 'heading-sm': 'h5',\n 'heading-xs': 'h6',\n 'body-lg': 'p',\n 'body-md': 'p',\n 'body-sm': 'p',\n 'body-xs': 'p',\n 'label-lg': 'span',\n 'label-md': 'span',\n 'label-sm': 'span',\n 'label-xs': 'span',\n caption: 'span',\n overline: 'span',\n code: 'code',\n 'label-plain-lg': 'span',\n 'label-plain-md': 'span',\n 'label-plain-sm': 'span',\n}\n\n/**\n * Props for Text — a polymorphic typography component covering the full type scale:\n * headings, body, labels, captions, and overlines — with automatic semantic HTML element selection.\n *\n * **Variants (grouped):**\n * - Headings: `heading-2xl` → `h1`, `heading-xl` → `h2`, `heading-lg` → `h3`, etc.\n * - Body: `body-lg` | `body-md` (default) | `body-sm` | `body-xs` → `<p>`\n * - Labels: `label-lg` | `label-md` | `label-sm` | `label-xs` → `<span>` (uppercase)\n * - Misc: `caption` | `overline` → `<span>` (overline is uppercase)\n *\n * **`as` prop:** Override the rendered element. E.g. `<Text variant=\"heading-lg\" as=\"div\">` renders\n * `<div class=\"text-heading-lg ...\">` — useful when you need heading styles on a non-heading element.\n *\n * @example\n * // Page heading:\n * <Text variant=\"heading-2xl\">Welcome to Shilp Sutra</Text>\n *\n * @example\n * // Section label (uppercase, small):\n * <Text variant=\"label-sm\" className=\"text-surface-fg-muted\">Recent activity</Text>\n *\n * @example\n * // Body copy with custom element (renders as <span> for inline use):\n * <Text variant=\"body-sm\" as=\"span\" className=\"text-surface-fg-muted\">\n * Last updated 3 hours ago\n * </Text>\n *\n * @example\n * // Caption under an image or figure:\n * <Text variant=\"caption\" className=\"text-surface-fg-subtle\">Figure 1: System architecture</Text>\n * // These are just a few ways — feel free to combine props creatively!\n */\ntype TextProps<T extends React.ElementType = 'p'> = {\n variant?: TextVariant\n as?: T\n className?: string\n children?: React.ReactNode\n} & Omit<React.ComponentPropsWithRef<T>, 'as' | 'variant' | 'className' | 'children'>\n\n// Polymorphic component type — preserves T across the call site so element-\n// specific props (e.g. `htmlFor` on `as=\"label\"`, `href` on `as=\"a\"`) typecheck.\n// React.forwardRef can't keep a generic parameter live at its export, so we\n// type the implementation loosely and cast the public export to a generic\n// callable. Standard polymorphic-component pattern (same shape as Radix).\ntype TextComponent = (<T extends React.ElementType = 'p'>(\n props: TextProps<T> & { ref?: React.ComponentPropsWithRef<T>['ref'] },\n) => React.ReactElement | null) & { displayName?: string }\n\nconst TextImpl = React.forwardRef<HTMLElement, TextProps>(\n ({ variant = 'body-md', as, className, children, ...props }, ref) => {\n const Component = as || defaultElementMap[variant] || 'p'\n return React.createElement(\n Component,\n { ref, className: cn(textVariants({ variant }), className), ...props },\n children,\n )\n },\n)\nTextImpl.displayName = 'Text'\n\nconst Text = TextImpl as unknown as TextComponent\n\nexport { Text, type TextProps, type TextVariant,textVariants }\n"],"mappings":";;;;AAMA,IAAM,IAAe,EAAI,aAAa;CACpC,UAAU,EACR,SAAS;EACP,eAAe;EACf,cAAe;EACf,cAAe;EACf,cAAe;EACf,cAAe;EACf,cAAe;EACf,WAAe;EACf,WAAe;EACf,WAAe;EACf,WAAe;EACf,YAAe;EACf,YAAe;EACf,YAAe;EACf,YAAe;EACf,SAAe;EACf,UAAe;EACf,MAAmB;EACnB,kBAAmB;EACnB,kBAAmB;EACnB,kBAAmB;EACpB,EACF;CACD,iBAAiB,EACf,SAAS,WACV;CACF,CAAC,EAII,IAA4E;CAChF,eAAe;CACf,cAAe;CACf,cAAe;CACf,cAAe;CACf,cAAe;CACf,cAAe;CACf,WAAe;CACf,WAAe;CACf,WAAe;CACf,WAAe;CACf,YAAe;CACf,YAAe;CACf,YAAe;CACf,YAAe;CACf,SAAe;CACf,UAAe;CACf,MAAmB;CACnB,kBAAmB;CACnB,kBAAmB;CACnB,kBAAmB;CACpB,EAkDK,IAAW,EAAM,YACpB,EAAE,aAAU,WAAW,OAAI,cAAW,aAAU,GAAG,KAAS,MAAQ;CACnE,IAAM,IAAY,KAAM,EAAkB,MAAY;AACtD,QAAO,EAAM,cACX,GACA;EAAE;EAAK,WAAW,EAAG,EAAa,EAAE,YAAS,CAAC,EAAE,EAAU;EAAE,GAAG;EAAO,EACtE,EACD;EAEJ;AACD,EAAS,cAAc;AAEvB,IAAM,IAAO"}
|
package/dist/ui/toaster.d.ts
CHANGED
|
@@ -3,8 +3,17 @@ import * as React from 'react';
|
|
|
3
3
|
/**
|
|
4
4
|
* Toaster — mount once at your root layout to enable toast notifications.
|
|
5
5
|
*
|
|
6
|
+
* **⚠ Peer dependency required:** `sonner`. Without it your build fails with
|
|
7
|
+
* `Cannot find module 'sonner'`. Install:
|
|
8
|
+
* ```bash
|
|
9
|
+
* pnpm add sonner # or: npm i sonner / yarn add sonner / bun add sonner
|
|
10
|
+
* ```
|
|
11
|
+
* `sonner` is listed as an optional peer because consumers who never render
|
|
12
|
+
* `<Toaster />` shouldn't pay the install cost — but once you import this
|
|
13
|
+
* component, it becomes effectively required.
|
|
14
|
+
*
|
|
6
15
|
* @example
|
|
7
|
-
* import { Toaster } from '@devalok/shilp-sutra'
|
|
16
|
+
* import { Toaster } from '@devalok/shilp-sutra/ui/toaster'
|
|
8
17
|
*
|
|
9
18
|
* export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
10
19
|
* return (
|
|
@@ -18,7 +27,7 @@ import * as React from 'react';
|
|
|
18
27
|
* }
|
|
19
28
|
*
|
|
20
29
|
* // Then from any component:
|
|
21
|
-
* import { toast } from '@devalok/shilp-sutra'
|
|
30
|
+
* import { toast } from '@devalok/shilp-sutra/ui/toast'
|
|
22
31
|
* toast.success('Saved!')
|
|
23
32
|
*/
|
|
24
33
|
export interface ToasterProps {
|
package/dist/ui/toaster.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toaster.d.ts","sourceRoot":"","sources":["../../src/ui/toaster.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B
|
|
1
|
+
{"version":3,"file":"toaster.d.ts","sourceRoot":"","sources":["../../src/ui/toaster.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,QAAQ,CAAC,EACL,UAAU,GACV,YAAY,GACZ,WAAW,GACX,aAAa,GACb,eAAe,GACf,cAAc,CAAA;IAClB,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,OAAO,qFA+BnB,CAAA"}
|
package/dist/ui/toaster.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toaster.js","names":[],"sources":["../../src/ui/toaster.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { Toaster as SonnerToaster } from 'sonner'\n\nimport { cn } from './lib/utils'\nimport { registerToaster } from './toast-registry'\n\n/**\n * Toaster — mount once at your root layout to enable toast notifications.\n *\n * @example\n * import { Toaster } from '@devalok/shilp-sutra'\n *\n * export default function RootLayout({ children }: { children: React.ReactNode }) {\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <Toaster />\n * </body>\n * </html>\n * )\n * }\n *\n * // Then from any component:\n * import { toast } from '@devalok/shilp-sutra'\n * toast.success('Saved!')\n */\nexport interface ToasterProps {\n /** Toast position on screen. Default: 'bottom-right' */\n position?:\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right'\n /** Show close button on all toasts. Default: false */\n closeButton?: boolean\n /** Default auto-dismiss duration in ms. Default: 5000 */\n duration?: number\n /** Keyboard shortcut to focus toast region. Default: ['altKey', 'KeyT'] */\n hotkey?: string[]\n /** Max visible toasts before stacking. Default: 3 */\n visibleToasts?: number\n /** Additional CSS class */\n className?: string\n}\n\nexport const Toaster = React.forwardRef<HTMLDivElement, ToasterProps>(\n (\n {\n position = 'bottom-right',\n closeButton = false,\n duration = 5000,\n hotkey = ['altKey', 'KeyT'],\n visibleToasts = 3,\n className,\n },\n ref,\n ) => {\n React.useEffect(() => registerToaster(), [])\n return (\n <div ref={ref} className={cn('z-toast', className)}>\n <SonnerToaster\n position={position}\n closeButton={closeButton}\n duration={duration}\n hotkey={hotkey}\n visibleToasts={visibleToasts}\n toastOptions={{\n unstyled: true,\n classNames: {\n toast: 'w-full',\n },\n }}\n />\n </div>\n )\n },\n)\nToaster.displayName = 'Toaster'\n"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"toaster.js","names":[],"sources":["../../src/ui/toaster.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { Toaster as SonnerToaster } from 'sonner'\n\nimport { cn } from './lib/utils'\nimport { registerToaster } from './toast-registry'\n\n/**\n * Toaster — mount once at your root layout to enable toast notifications.\n *\n * **⚠ Peer dependency required:** `sonner`. Without it your build fails with\n * `Cannot find module 'sonner'`. Install:\n * ```bash\n * pnpm add sonner # or: npm i sonner / yarn add sonner / bun add sonner\n * ```\n * `sonner` is listed as an optional peer because consumers who never render\n * `<Toaster />` shouldn't pay the install cost — but once you import this\n * component, it becomes effectively required.\n *\n * @example\n * import { Toaster } from '@devalok/shilp-sutra/ui/toaster'\n *\n * export default function RootLayout({ children }: { children: React.ReactNode }) {\n * return (\n * <html lang=\"en\">\n * <body>\n * {children}\n * <Toaster />\n * </body>\n * </html>\n * )\n * }\n *\n * // Then from any component:\n * import { toast } from '@devalok/shilp-sutra/ui/toast'\n * toast.success('Saved!')\n */\nexport interface ToasterProps {\n /** Toast position on screen. Default: 'bottom-right' */\n position?:\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right'\n /** Show close button on all toasts. Default: false */\n closeButton?: boolean\n /** Default auto-dismiss duration in ms. Default: 5000 */\n duration?: number\n /** Keyboard shortcut to focus toast region. Default: ['altKey', 'KeyT'] */\n hotkey?: string[]\n /** Max visible toasts before stacking. Default: 3 */\n visibleToasts?: number\n /** Additional CSS class */\n className?: string\n}\n\nexport const Toaster = React.forwardRef<HTMLDivElement, ToasterProps>(\n (\n {\n position = 'bottom-right',\n closeButton = false,\n duration = 5000,\n hotkey = ['altKey', 'KeyT'],\n visibleToasts = 3,\n className,\n },\n ref,\n ) => {\n React.useEffect(() => registerToaster(), [])\n return (\n <div ref={ref} className={cn('z-toast', className)}>\n <SonnerToaster\n position={position}\n closeButton={closeButton}\n duration={duration}\n hotkey={hotkey}\n visibleToasts={visibleToasts}\n toastOptions={{\n unstyled: true,\n classNames: {\n toast: 'w-full',\n },\n }}\n />\n </div>\n )\n },\n)\nToaster.displayName = 'Toaster'\n"],"mappings":";;;;;;;AA2DA,IAAa,IAAU,EAAM,YAEzB,EACE,cAAW,gBACX,iBAAc,IACd,cAAW,KACX,YAAS,CAAC,UAAU,OAAO,EAC3B,mBAAgB,GAChB,gBAEF,OAEA,EAAM,gBAAgB,GAAiB,EAAE,EAAE,CAAC,EAE1C,kBAAC,OAAD;CAAU;CAAK,WAAW,EAAG,WAAW,EAAU;WAChD,kBAAC,GAAD;EACY;EACG;EACH;EACF;EACO;EACf,cAAc;GACZ,UAAU;GACV,YAAY,EACV,OAAO,UACR;GACF;EACD,CAAA;CACE,CAAA,EAGX;AACD,EAAQ,cAAc"}
|
package/dist/ui/tooltip.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { F as e, M as t, N as n, P as r, j as i } from "../_chunks/primitives.js";
|
|
3
3
|
import { springs as a, tweens as o } from "./lib/motion.js";
|
|
4
4
|
import { cn as s } from "./lib/utils.js";
|
|
5
5
|
import * as c from "react";
|
|
@@ -8,7 +8,7 @@ import { AnimatePresence as d, motion as f } from "framer-motion";
|
|
|
8
8
|
//#region src/ui/tooltip.tsx
|
|
9
9
|
var p = c.createContext(!1), m = ({ children: e, ...t }) => /* @__PURE__ */ u(p.Provider, {
|
|
10
10
|
value: !0,
|
|
11
|
-
children: /* @__PURE__ */ u(
|
|
11
|
+
children: /* @__PURE__ */ u(n, {
|
|
12
12
|
...t,
|
|
13
13
|
children: e
|
|
14
14
|
})
|
|
@@ -16,19 +16,19 @@ var p = c.createContext(!1), m = ({ children: e, ...t }) => /* @__PURE__ */ u(p.
|
|
|
16
16
|
function h({ children: e }) {
|
|
17
17
|
return c.useContext(p) ? /* @__PURE__ */ u(l, { children: e }) : /* @__PURE__ */ u(p.Provider, {
|
|
18
18
|
value: !0,
|
|
19
|
-
children: /* @__PURE__ */ u(
|
|
19
|
+
children: /* @__PURE__ */ u(n, {
|
|
20
20
|
delayDuration: 300,
|
|
21
21
|
children: e
|
|
22
22
|
})
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
-
var g = c.createContext({ open: !1 }), _ = ({ open: e, defaultOpen:
|
|
26
|
-
let [a, o] = c.useState(
|
|
27
|
-
s || o(e),
|
|
28
|
-
}, [s,
|
|
25
|
+
var g = c.createContext({ open: !1 }), _ = ({ open: e, defaultOpen: t, onOpenChange: n, ...i }) => {
|
|
26
|
+
let [a, o] = c.useState(t ?? !1), s = e !== void 0, l = s ? e : a, d = c.useCallback((e) => {
|
|
27
|
+
s || o(e), n?.(e);
|
|
28
|
+
}, [s, n]), f = c.useMemo(() => ({ open: l }), [l]);
|
|
29
29
|
return /* @__PURE__ */ u(h, { children: /* @__PURE__ */ u(g.Provider, {
|
|
30
30
|
value: f,
|
|
31
|
-
children: /* @__PURE__ */ u(
|
|
31
|
+
children: /* @__PURE__ */ u(r, {
|
|
32
32
|
open: l,
|
|
33
33
|
onOpenChange: d,
|
|
34
34
|
...i
|
|
@@ -36,14 +36,14 @@ var g = c.createContext({ open: !1 }), _ = ({ open: e, defaultOpen: n, onOpenCha
|
|
|
36
36
|
}) });
|
|
37
37
|
};
|
|
38
38
|
_.displayName = "Tooltip";
|
|
39
|
-
var v =
|
|
39
|
+
var v = e, y = {
|
|
40
40
|
top: { y: 4 },
|
|
41
41
|
bottom: { y: -4 },
|
|
42
42
|
left: { x: 4 },
|
|
43
43
|
right: { x: -4 }
|
|
44
|
-
}, b = c.forwardRef(({ className:
|
|
44
|
+
}, b = c.forwardRef(({ className: e, sideOffset: n = 4, side: r = "top", children: l, ...p }, m) => {
|
|
45
45
|
let { open: h } = c.useContext(g), _ = y[r] ?? {};
|
|
46
|
-
return /* @__PURE__ */ u(d, { children: h && /* @__PURE__ */ u(
|
|
46
|
+
return /* @__PURE__ */ u(d, { children: h && /* @__PURE__ */ u(t, {
|
|
47
47
|
forceMount: !0,
|
|
48
48
|
children: /* @__PURE__ */ u(i, {
|
|
49
49
|
ref: m,
|
|
@@ -73,7 +73,7 @@ var v = n, y = {
|
|
|
73
73
|
...a.snappy,
|
|
74
74
|
opacity: o.fade
|
|
75
75
|
},
|
|
76
|
-
className: s("z-tooltip overflow-hidden rounded-overlay-sm bg-surface-inverted px-ds-04 py-ds-02b text-ds-sm text-surface-inverted-fg shadow-floating",
|
|
76
|
+
className: s("z-tooltip overflow-hidden rounded-overlay-sm bg-surface-inverted px-ds-04 py-ds-02b text-ds-sm text-surface-inverted-fg shadow-floating", e),
|
|
77
77
|
children: l
|
|
78
78
|
})
|
|
79
79
|
})
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { IconInput } from '../lib/icon-input';
|
|
2
3
|
import * as React from 'react';
|
|
3
4
|
export interface TreeItemProps {
|
|
4
5
|
/** Unique identifier for this tree item */
|
|
5
6
|
itemId: string;
|
|
6
7
|
/** Primary label content */
|
|
7
8
|
label: React.ReactNode;
|
|
8
|
-
/** Optional icon rendered before the label */
|
|
9
|
-
icon?:
|
|
9
|
+
/** Optional icon rendered before the label. Accepts any `IconInput`. */
|
|
10
|
+
icon?: IconInput;
|
|
10
11
|
/** Secondary label rendered after the primary label */
|
|
11
12
|
secondaryLabel?: React.ReactNode;
|
|
12
13
|
/** Action buttons rendered at the end of the row */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-item.d.ts","sourceRoot":"","sources":["../../../src/ui/tree-view/tree-item.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"tree-item.d.ts","sourceRoot":"","sources":["../../../src/ui/tree-view/tree-item.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAKlD,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAA;IACd,4BAA4B;IAC5B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,wEAAwE;IACxE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,uDAAuD;IACvD,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAChC,oDAAoD;IACpD,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,QAAA,MAAM,QAAQ,qFAqMb,CAAA;AAGD,OAAO,EAAE,QAAQ,EAAE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tree.d.ts","sourceRoot":"","sources":["../../../src/ui/tree-view/use-tree.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"use-tree.d.ts","sourceRoot":"","sources":["../../../src/ui/tree-view/use-tree.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAElD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,UAAU,cAAc;IACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IAC1C,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;CAC3C;AAED,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB;;;iBAW3C,MAAM;iBAaN,MAAM,UAAU,KAAK,CAAC,UAAU;qBAsBpB,MAAM;qBACN,MAAM;qBACN,MAAM,EAAE;;EAG5B"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# OAuthButton
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra/ui/oauth-button
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: ui
|
|
6
|
+
|
|
7
|
+
## Exports
|
|
8
|
+
- `OAuthButton` — primary brand-aware sign-in button
|
|
9
|
+
- `OAuthGroup` — stacked layout wrapper with consistent spacing
|
|
10
|
+
- `OAuthDivider` — `or`-style horizontal rule between OAuth row and email form
|
|
11
|
+
- `OAuthConnectionRow` — settings-page row for a linked provider (Disconnect / Connect action)
|
|
12
|
+
|
|
13
|
+
## OAuthButton props
|
|
14
|
+
provider: "google" | "apple" | "github" | "microsoft" | "x" | "linkedin" | "facebook" | "discord" | "slack" | "gitlab" | "sso" | "email" | "passkey" (required)
|
|
15
|
+
intent: "continue" | "signin" | "signup" (default "continue") — drives the verb in the label
|
|
16
|
+
appearance: "brand" | "outline" | "dark" (default "brand") — visual treatment
|
|
17
|
+
icon: ReactNode — override the default Tabler glyph with a brand-multicolour SVG
|
|
18
|
+
iconOnly: boolean — compact icon-only button; provider name preserved in aria-label
|
|
19
|
+
compact: boolean — short label ("Google" not "Continue with Google"); aria-label keeps long form
|
|
20
|
+
lastUsed: boolean — inline right-edge pill inside the button (a stronger pattern is reorder, below)
|
|
21
|
+
helperText: ReactNode — reassurance copy rendered below the button
|
|
22
|
+
children: ReactNode — override the default label entirely (i18n / custom copy)
|
|
23
|
+
size: inherited from Button ("xs" | "sm" | "md" | "lg" | compact + icon variants)
|
|
24
|
+
fullWidth, loading, onClick, onClickAsync, asyncFeedbackDuration, disabled — inherited from Button
|
|
25
|
+
|
|
26
|
+
## Data attributes
|
|
27
|
+
- `data-provider="<provider>"` — useful for analytics filtering
|
|
28
|
+
- `data-oauth-appearance="<appearance>"`
|
|
29
|
+
|
|
30
|
+
## OAuthGroup props
|
|
31
|
+
orientation: "vertical" | "horizontal" (default "vertical")
|
|
32
|
+
gap: "ds-02" | "ds-03" | "ds-04" (default "ds-03")
|
|
33
|
+
fullWidth: boolean (default true) — stretches children to fill width when vertical
|
|
34
|
+
reorderLastUsedFirst: boolean (default false) — pull the child with lastUsed to position 0
|
|
35
|
+
(Stripe-style — a stronger conversion lever than a visual badge alone)
|
|
36
|
+
|
|
37
|
+
## OAuthDivider props
|
|
38
|
+
label: ReactNode (default "or")
|
|
39
|
+
|
|
40
|
+
## OAuthConnectionRow props
|
|
41
|
+
provider: OAuthProvider (required)
|
|
42
|
+
connected: boolean (required)
|
|
43
|
+
accountLabel: ReactNode — account identifier shown next to the provider name (e.g. email)
|
|
44
|
+
onAction: (e) => void — synchronous click handler
|
|
45
|
+
onActionAsync: (e) => Promise<void> — uses Button's async state machine
|
|
46
|
+
actionLabel: ReactNode — override the "Disconnect" / "Connect <name>" copy
|
|
47
|
+
icon: ReactNode — override the default glyph
|
|
48
|
+
disabled: boolean
|
|
49
|
+
|
|
50
|
+
## Defaults
|
|
51
|
+
intent="continue", appearance="brand", iconOnly=false, lastUsed=false
|
|
52
|
+
|
|
53
|
+
## Example
|
|
54
|
+
```jsx
|
|
55
|
+
// Typical signup flow
|
|
56
|
+
<OAuthGroup>
|
|
57
|
+
<OAuthButton provider="google" lastUsed />
|
|
58
|
+
<OAuthButton provider="apple" />
|
|
59
|
+
<OAuthButton provider="github" />
|
|
60
|
+
</OAuthGroup>
|
|
61
|
+
<OAuthDivider />
|
|
62
|
+
<OAuthGroup>
|
|
63
|
+
<OAuthButton provider="passkey" appearance="outline" />
|
|
64
|
+
<OAuthButton provider="email" appearance="outline" />
|
|
65
|
+
</OAuthGroup>
|
|
66
|
+
|
|
67
|
+
// Async loading + success/error feedback
|
|
68
|
+
<OAuthButton provider="google" fullWidth onClickAsync={signInWithGoogle} />
|
|
69
|
+
|
|
70
|
+
// True brand-multicolour glyph from the provider's brand page
|
|
71
|
+
<OAuthButton provider="google" icon={<GoogleGSvg />} />
|
|
72
|
+
|
|
73
|
+
// Settings page — linked state
|
|
74
|
+
<OAuthConnectionRow
|
|
75
|
+
provider="google"
|
|
76
|
+
connected
|
|
77
|
+
accountLabel="namaskar@devalok.in"
|
|
78
|
+
onAction={disconnectGoogle}
|
|
79
|
+
/>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Composability
|
|
83
|
+
- **Built on Button.** Async state machine, loading/processing, sizes, and `fullWidth` are inherited. `variant` and `color` are managed internally — pass `appearance` instead.
|
|
84
|
+
- **Tabler peer dep.** Default glyphs come from `@tabler/icons-react`. To match a provider's official multicolour mark, pass `icon={<YourSvg />}`.
|
|
85
|
+
- **Brand-colour backgrounds.** `appearance="brand"` uses each provider's published button colour. `appearance="outline"` falls back to DS-neutral. `appearance="dark"` unifies every provider into an Apple-style black-on-white (light) / white-on-black (dark) treatment — useful when you want a row to feel visually consistent across providers.
|
|
86
|
+
- **Last-used hint.** Storage is the consumer's responsibility — pass `lastUsed={user.lastProvider === 'google'}`.
|