@nqlib/nqui 0.4.3 → 0.4.4
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/INSTALLATION.md +215 -0
- package/README.md +104 -151
- package/dist/button-CJHdCq9I.js +155 -0
- package/dist/button-R304rhsj.cjs +1 -0
- package/dist/calendar.cjs.js +1 -1
- package/dist/calendar.es.js +1 -1
- package/dist/carousel-D1FMVglR.cjs +1 -0
- package/dist/carousel-U7RZhYZj.js +179 -0
- package/dist/carousel.cjs.js +1 -1
- package/dist/carousel.es.js +1 -1
- package/dist/command-palette-DCtLpM3Q.js +694 -0
- package/dist/command-palette-MHc03bBf.cjs +5 -0
- package/dist/command.cjs.js +1 -1
- package/dist/command.es.js +1 -1
- package/dist/components/custom/color-picker.d.ts +1 -1
- package/dist/components/custom/color-picker.d.ts.map +1 -1
- package/dist/components/custom/color-slider.d.ts +4 -10
- package/dist/components/custom/color-slider.d.ts.map +1 -1
- package/dist/components/custom/enhanced-radio-group.d.ts +13 -4
- package/dist/components/custom/enhanced-radio-group.d.ts.map +1 -1
- package/dist/components/custom/enhanced-tabs.d.ts.map +1 -1
- package/dist/components/debug/debug-features.d.ts +29 -0
- package/dist/components/debug/debug-features.d.ts.map +1 -0
- package/dist/components/debug/debug-panel.d.ts.map +1 -1
- package/dist/components/error-boundary.d.ts +20 -0
- package/dist/components/error-boundary.d.ts.map +1 -0
- package/dist/components/index.d.ts +103 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/ui/badge.d.ts +16 -5
- package/dist/components/ui/badge.d.ts.map +1 -1
- package/dist/components/ui/button.d.ts +38 -4
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/checkbox.d.ts +16 -2
- package/dist/components/ui/checkbox.d.ts.map +1 -1
- package/dist/components/ui/combobox.d.ts +2 -1
- package/dist/components/ui/combobox.d.ts.map +1 -1
- package/dist/components/ui/input-group.d.ts +1 -1
- package/dist/components/ui/input-group.d.ts.map +1 -1
- package/dist/components/ui/pagination.d.ts +3 -2
- package/dist/components/ui/pagination.d.ts.map +1 -1
- package/dist/components/ui/radio-group.d.ts +3 -1
- package/dist/components/ui/radio-group.d.ts.map +1 -1
- package/dist/components/ui/select.d.ts +6 -1
- package/dist/components/ui/select.d.ts.map +1 -1
- package/dist/components/ui/sidebar.d.ts +1 -1
- package/dist/components/ui/sidebar.d.ts.map +1 -1
- package/dist/components/ui/slider.d.ts +10 -2
- package/dist/components/ui/slider.d.ts.map +1 -1
- package/dist/components/ui/sonner.d.ts +18 -2
- package/dist/components/ui/sonner.d.ts.map +1 -1
- package/dist/components/ui/spinner.d.ts +2 -1
- package/dist/components/ui/spinner.d.ts.map +1 -1
- package/dist/components/ui/switch.d.ts +15 -2
- package/dist/components/ui/switch.d.ts.map +1 -1
- package/dist/components/ui/tabs.d.ts +1 -1
- package/dist/components/ui/tabs.d.ts.map +1 -1
- package/dist/components/ui/toggle.d.ts +1 -1
- package/dist/components/ui/toggle.d.ts.map +1 -1
- package/dist/debug-panel-CG-vAN0L.js +9016 -0
- package/dist/debug-panel-DHBfAc1V.cjs +75 -0
- package/dist/debug.cjs.js +1 -0
- package/dist/debug.es.js +7 -0
- package/dist/{drawer-CU4lkcz7.js → drawer-DO26uhym.js} +31 -31
- package/dist/drawer-DVarEy65.cjs +1 -0
- package/dist/drawer.cjs.js +1 -1
- package/dist/drawer.es.js +1 -1
- package/dist/{enhanced-calendar-BENbxw7_.js → enhanced-calendar-BGlsSYJd.js} +1 -1
- package/dist/{enhanced-calendar-5PA8CeF7.cjs → enhanced-calendar-C7EQIr6i.cjs} +1 -1
- package/dist/entries/debug.d.ts +14 -0
- package/dist/entries/debug.d.ts.map +1 -0
- package/dist/entries/sonner.d.ts +1 -2
- package/dist/entries/sonner.d.ts.map +1 -1
- package/dist/hooks/use-mobile.d.ts.map +1 -1
- package/dist/hooks/use-scroll-spy.d.ts.map +1 -1
- package/dist/index-CI756mSv.cjs +41 -0
- package/dist/index-CgfzsUO6.js +1069 -0
- package/dist/index.d.ts +2 -98
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/index.d.ts +9 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/wrap-inline-label-text.d.ts +7 -0
- package/dist/lib/wrap-inline-label-text.d.ts.map +1 -0
- package/dist/nqui.cjs.js +49 -245
- package/dist/nqui.es.js +7399 -16735
- package/dist/sonner-CpmECDBk.js +179 -0
- package/dist/sonner-nE9hIalJ.cjs +48 -0
- package/dist/sonner.cjs.js +1 -1
- package/dist/sonner.es.js +3 -2
- package/dist/styles.css +186 -1
- package/docs/components/README.md +107 -8
- package/docs/components/nqui-badge.md +1 -0
- package/docs/components/nqui-button.md +3 -1
- package/docs/components/nqui-card.md +8 -0
- package/docs/components/nqui-carousel.md +6 -0
- package/docs/components/nqui-checkbox.md +38 -1
- package/docs/components/nqui-color-slider.md +5 -3
- package/docs/components/nqui-combobox.md +58 -37
- package/docs/components/nqui-drawer.md +1 -1
- package/docs/components/nqui-radio-group.md +45 -2
- package/docs/components/nqui-scroll-area.md +1 -1
- package/docs/components/nqui-select.md +2 -2
- package/docs/components/nqui-sheet.md +1 -1
- package/docs/components/nqui-slider.md +13 -0
- package/docs/components/nqui-spinner.md +6 -1
- package/docs/components/nqui-switch.md +23 -1
- package/docs/components/nqui-tabs.md +11 -1
- package/docs/components/nqui-toaster.md +5 -1
- package/docs/internal-notes/PUBLISHING.md +46 -4
- package/docs/nqui-skills/SKILL.md +102 -0
- package/docs/nqui-skills/design-system.md +143 -0
- package/docs/nqui-skills/rules/composition.md +183 -0
- package/docs/nqui-skills/rules/forms.md +190 -0
- package/docs/nqui-skills/rules/icons.md +158 -0
- package/docs/nqui-skills/rules/styling.md +192 -0
- package/package.json +23 -12
- package/scripts/build-styles.js +16 -0
- package/scripts/cli.js +1 -0
- package/scripts/download-skills.js +91 -0
- package/scripts/examples/nextjs-layout-sidebar.tsx +100 -0
- package/scripts/examples/nextjs-page-sidebar.tsx +81 -0
- package/scripts/examples/vite-app.tsx +135 -0
- package/scripts/examples/vite-main.tsx +17 -0
- package/scripts/examples.js +92 -6
- package/scripts/generate-docs.js +169 -0
- package/scripts/init-css.js +34 -14
- package/scripts/init-cursor.js +8 -0
- package/scripts/init-debug-css.js +4 -2
- package/scripts/post-install.js +41 -9
- package/scripts/publish-npmjs.js +17 -3
- package/scripts/resolve-target-dir.js +20 -1
- package/scripts/verify-build.js +1 -1
- package/scripts/wizard.js +12 -7
- package/dist/button-CYFTFDKe.cjs +0 -1
- package/dist/button-nJvDl3w8.js +0 -44
- package/dist/carousel-DEyyJi49.js +0 -179
- package/dist/carousel-Dhhz8m5V.cjs +0 -1
- package/dist/command-palette-UHk8zZOg.cjs +0 -45
- package/dist/command-palette-d-TrdBsM.js +0 -1778
- package/dist/components/custom/enhanced-badge.d.ts +0 -33
- package/dist/components/custom/enhanced-badge.d.ts.map +0 -1
- package/dist/components/custom/enhanced-button.d.ts +0 -34
- package/dist/components/custom/enhanced-button.d.ts.map +0 -1
- package/dist/components/custom/enhanced-checkbox.d.ts +0 -28
- package/dist/components/custom/enhanced-checkbox.d.ts.map +0 -1
- package/dist/components/custom/enhanced-combobox.d.ts +0 -35
- package/dist/components/custom/enhanced-combobox.d.ts.map +0 -1
- package/dist/components/custom/enhanced-select.d.ts +0 -30
- package/dist/components/custom/enhanced-select.d.ts.map +0 -1
- package/dist/components/custom/enhanced-sonner.d.ts +0 -16
- package/dist/components/custom/enhanced-sonner.d.ts.map +0 -1
- package/dist/drawer-BcIxWRN8.cjs +0 -1
- package/dist/sonner-Co6YpYVs.js +0 -546
- package/dist/sonner-DbQhVp8m.cjs +0 -330
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { jsx as a } from "react/jsx-runtime";
|
|
2
|
+
import * as i from "react";
|
|
3
|
+
import { Toaster as T } from "sonner";
|
|
4
|
+
import { HugeiconsIcon as s } from "@hugeicons/react";
|
|
5
|
+
import { Loading03Icon as S, MultiplicationSignCircleIcon as I, Alert02Icon as E, InformationCircleIcon as C, CheckmarkCircle02Icon as N } from "@hugeicons/core-free-icons";
|
|
6
|
+
var z = (t, n, p, c, l, r, u, f) => {
|
|
7
|
+
let e = document.documentElement, g = ["light", "dark"];
|
|
8
|
+
function d(o) {
|
|
9
|
+
(Array.isArray(t) ? t : [t]).forEach((m) => {
|
|
10
|
+
let v = m === "class", k = v && r ? l.map((x) => r[x] || x) : l;
|
|
11
|
+
v ? (e.classList.remove(...k), e.classList.add(r && r[o] ? r[o] : o)) : e.setAttribute(m, o);
|
|
12
|
+
}), w(o);
|
|
13
|
+
}
|
|
14
|
+
function w(o) {
|
|
15
|
+
f && g.includes(o) && (e.style.colorScheme = o);
|
|
16
|
+
}
|
|
17
|
+
function y() {
|
|
18
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
19
|
+
}
|
|
20
|
+
if (c) d(c);
|
|
21
|
+
else try {
|
|
22
|
+
let o = localStorage.getItem(n) || p, m = u && o === "system" ? y() : o;
|
|
23
|
+
d(m);
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
26
|
+
}, W = i.createContext(void 0), A = { setTheme: (t) => {
|
|
27
|
+
}, themes: [] }, L = () => {
|
|
28
|
+
var t;
|
|
29
|
+
return (t = i.useContext(W)) != null ? t : A;
|
|
30
|
+
};
|
|
31
|
+
i.memo(({ forcedTheme: t, storageKey: n, attribute: p, enableSystem: c, enableColorScheme: l, defaultTheme: r, value: u, themes: f, nonce: e, scriptProps: g }) => {
|
|
32
|
+
let d = JSON.stringify([p, n, r, t, f, u, c, l]).slice(1, -1);
|
|
33
|
+
return i.createElement("script", { ...g, suppressHydrationWarning: !0, nonce: typeof window > "u" ? e : "", dangerouslySetInnerHTML: { __html: `(${z.toString()})(${d})` } });
|
|
34
|
+
});
|
|
35
|
+
const b = "nqui-toast-styles-v2";
|
|
36
|
+
function M() {
|
|
37
|
+
if (typeof document > "u" || document.getElementById(b)) return;
|
|
38
|
+
const t = document.createElement("style");
|
|
39
|
+
t.id = b, t.textContent = `
|
|
40
|
+
/* Pill toast — inverted surface: dark-on-light app, light-on-dark app */
|
|
41
|
+
[data-sonner-toast] .cn-toast {
|
|
42
|
+
border: 1px solid color-mix(in oklch, var(--normal-text) 18%, transparent) !important;
|
|
43
|
+
border-radius: 9999px !important;
|
|
44
|
+
box-shadow:
|
|
45
|
+
0 1px 0 0 color-mix(in oklch, var(--normal-text) 12%, transparent),
|
|
46
|
+
0 1px 2px 0 oklch(0.15 0 0 / 0.08);
|
|
47
|
+
transition: all 200ms ease-in-out !important;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.dark [data-sonner-toast] .cn-toast {
|
|
51
|
+
box-shadow:
|
|
52
|
+
0 1px 0 0 color-mix(in oklch, var(--normal-text) 14%, transparent),
|
|
53
|
+
0 1px 2px 0 oklch(0.15 0 0 / 0.12);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
[data-sonner-toast] .cn-toast.toast-success {
|
|
57
|
+
border-left-width: 3px !important;
|
|
58
|
+
border-left-color: var(--success-500) !important;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
[data-sonner-toast] .cn-toast.toast-error {
|
|
62
|
+
border-left-width: 3px !important;
|
|
63
|
+
border-left-color: var(--danger-500) !important;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
[data-sonner-toast] .cn-toast.toast-warning {
|
|
67
|
+
border-left-width: 3px !important;
|
|
68
|
+
border-left-color: var(--warning-500) !important;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
[data-sonner-toast] .cn-toast.toast-info {
|
|
72
|
+
border-left-width: 3px !important;
|
|
73
|
+
border-left-color: var(--info-500) !important;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
[data-sonner-toast] .cn-toast.toast-loading {
|
|
77
|
+
border-left-width: 3px !important;
|
|
78
|
+
border-left-color: var(--primary-500) !important;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.cn-toast .toast-icon-success { color: var(--success); }
|
|
82
|
+
.cn-toast .toast-icon-error { color: var(--destructive); }
|
|
83
|
+
.cn-toast .toast-icon-warning { color: var(--warning); }
|
|
84
|
+
.cn-toast .toast-icon-info { color: var(--info); }
|
|
85
|
+
.cn-toast .toast-icon-loading { color: var(--primary); }
|
|
86
|
+
`, document.head.appendChild(t);
|
|
87
|
+
}
|
|
88
|
+
const h = ({ ...t }) => {
|
|
89
|
+
const { theme: n = "system" } = L();
|
|
90
|
+
return i.useEffect(() => {
|
|
91
|
+
M();
|
|
92
|
+
}, []), /* @__PURE__ */ a(
|
|
93
|
+
T,
|
|
94
|
+
{
|
|
95
|
+
theme: n,
|
|
96
|
+
className: "toaster group",
|
|
97
|
+
icons: {
|
|
98
|
+
success: /* @__PURE__ */ a(
|
|
99
|
+
s,
|
|
100
|
+
{
|
|
101
|
+
icon: N,
|
|
102
|
+
strokeWidth: 2,
|
|
103
|
+
className: "size-4 text-success toast-icon-success"
|
|
104
|
+
}
|
|
105
|
+
),
|
|
106
|
+
info: /* @__PURE__ */ a(
|
|
107
|
+
s,
|
|
108
|
+
{
|
|
109
|
+
icon: C,
|
|
110
|
+
strokeWidth: 2,
|
|
111
|
+
className: "size-4 text-info toast-icon-info"
|
|
112
|
+
}
|
|
113
|
+
),
|
|
114
|
+
warning: /* @__PURE__ */ a(
|
|
115
|
+
s,
|
|
116
|
+
{
|
|
117
|
+
icon: E,
|
|
118
|
+
strokeWidth: 2,
|
|
119
|
+
className: "size-4 text-warning toast-icon-warning"
|
|
120
|
+
}
|
|
121
|
+
),
|
|
122
|
+
error: /* @__PURE__ */ a(
|
|
123
|
+
s,
|
|
124
|
+
{
|
|
125
|
+
icon: I,
|
|
126
|
+
strokeWidth: 2,
|
|
127
|
+
className: "size-4 text-destructive toast-icon-error"
|
|
128
|
+
}
|
|
129
|
+
),
|
|
130
|
+
loading: /* @__PURE__ */ a(
|
|
131
|
+
s,
|
|
132
|
+
{
|
|
133
|
+
icon: S,
|
|
134
|
+
strokeWidth: 2,
|
|
135
|
+
className: "size-4 text-primary toast-icon-loading animate-spin"
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
},
|
|
139
|
+
style: {
|
|
140
|
+
/* Invert page chrome: light UI → dark toast; dark UI → light toast */
|
|
141
|
+
"--normal-bg": "var(--foreground)",
|
|
142
|
+
"--normal-text": "var(--background)",
|
|
143
|
+
"--normal-border": "color-mix(in oklch, var(--background) 25%, transparent)",
|
|
144
|
+
"--border-radius": "9999px",
|
|
145
|
+
"--success-bg": "var(--success)",
|
|
146
|
+
"--success-text": "var(--success-foreground)",
|
|
147
|
+
"--success-border": "var(--success-400)",
|
|
148
|
+
"--error-bg": "var(--destructive)",
|
|
149
|
+
"--error-text": "var(--destructive-foreground)",
|
|
150
|
+
"--error-border": "var(--danger-400)",
|
|
151
|
+
"--warning-bg": "var(--warning)",
|
|
152
|
+
"--warning-text": "var(--warning-foreground)",
|
|
153
|
+
"--warning-border": "var(--warning-400)",
|
|
154
|
+
"--info-bg": "var(--info)",
|
|
155
|
+
"--info-text": "var(--info-foreground)",
|
|
156
|
+
"--info-border": "var(--info-400)"
|
|
157
|
+
},
|
|
158
|
+
toastOptions: {
|
|
159
|
+
classNames: {
|
|
160
|
+
toast: "cn-toast",
|
|
161
|
+
success: "toast-success",
|
|
162
|
+
error: "toast-error",
|
|
163
|
+
warning: "toast-warning",
|
|
164
|
+
info: "toast-info",
|
|
165
|
+
loading: "toast-loading"
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
...t
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
};
|
|
172
|
+
h.displayName = "Toaster";
|
|
173
|
+
const j = h, P = h;
|
|
174
|
+
export {
|
|
175
|
+
P as E,
|
|
176
|
+
h as T,
|
|
177
|
+
j as a,
|
|
178
|
+
L as z
|
|
179
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";const c=require("react/jsx-runtime"),T=require("react"),j=require("sonner"),i=require("@hugeicons/react"),l=require("@hugeicons/core-free-icons");function E(t){const o=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const r in t)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(o,r,n.get?n:{enumerable:!0,get:()=>t[r]})}}return o.default=t,Object.freeze(o)}const d=E(T);var N=(t,o,r,n,u,a,f,x)=>{let s=document.documentElement,h=["light","dark"];function m(e){(Array.isArray(t)?t:[t]).forEach(p=>{let v=p==="class",S=v&&a?u.map(b=>a[b]||b):u;v?(s.classList.remove(...S),s.classList.add(a&&a[e]?a[e]:e)):s.setAttribute(p,e)}),k(e)}function k(e){x&&h.includes(e)&&(s.style.colorScheme=e)}function I(){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}if(n)m(n);else try{let e=localStorage.getItem(o)||r,p=f&&e==="system"?I():e;m(p)}catch{}},C=d.createContext(void 0),O={setTheme:t=>{},themes:[]},y=()=>{var t;return(t=d.useContext(C))!=null?t:O};d.memo(({forcedTheme:t,storageKey:o,attribute:r,enableSystem:n,enableColorScheme:u,defaultTheme:a,value:f,themes:x,nonce:s,scriptProps:h})=>{let m=JSON.stringify([r,o,a,t,x,f,n,u]).slice(1,-1);return d.createElement("script",{...h,suppressHydrationWarning:!0,nonce:typeof window>"u"?s:"",dangerouslySetInnerHTML:{__html:`(${N.toString()})(${m})`}})});const w="nqui-toast-styles-v2";function z(){if(typeof document>"u"||document.getElementById(w))return;const t=document.createElement("style");t.id=w,t.textContent=`
|
|
2
|
+
/* Pill toast — inverted surface: dark-on-light app, light-on-dark app */
|
|
3
|
+
[data-sonner-toast] .cn-toast {
|
|
4
|
+
border: 1px solid color-mix(in oklch, var(--normal-text) 18%, transparent) !important;
|
|
5
|
+
border-radius: 9999px !important;
|
|
6
|
+
box-shadow:
|
|
7
|
+
0 1px 0 0 color-mix(in oklch, var(--normal-text) 12%, transparent),
|
|
8
|
+
0 1px 2px 0 oklch(0.15 0 0 / 0.08);
|
|
9
|
+
transition: all 200ms ease-in-out !important;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.dark [data-sonner-toast] .cn-toast {
|
|
13
|
+
box-shadow:
|
|
14
|
+
0 1px 0 0 color-mix(in oklch, var(--normal-text) 14%, transparent),
|
|
15
|
+
0 1px 2px 0 oklch(0.15 0 0 / 0.12);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
[data-sonner-toast] .cn-toast.toast-success {
|
|
19
|
+
border-left-width: 3px !important;
|
|
20
|
+
border-left-color: var(--success-500) !important;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
[data-sonner-toast] .cn-toast.toast-error {
|
|
24
|
+
border-left-width: 3px !important;
|
|
25
|
+
border-left-color: var(--danger-500) !important;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
[data-sonner-toast] .cn-toast.toast-warning {
|
|
29
|
+
border-left-width: 3px !important;
|
|
30
|
+
border-left-color: var(--warning-500) !important;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
[data-sonner-toast] .cn-toast.toast-info {
|
|
34
|
+
border-left-width: 3px !important;
|
|
35
|
+
border-left-color: var(--info-500) !important;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
[data-sonner-toast] .cn-toast.toast-loading {
|
|
39
|
+
border-left-width: 3px !important;
|
|
40
|
+
border-left-color: var(--primary-500) !important;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.cn-toast .toast-icon-success { color: var(--success); }
|
|
44
|
+
.cn-toast .toast-icon-error { color: var(--destructive); }
|
|
45
|
+
.cn-toast .toast-icon-warning { color: var(--warning); }
|
|
46
|
+
.cn-toast .toast-icon-info { color: var(--info); }
|
|
47
|
+
.cn-toast .toast-icon-loading { color: var(--primary); }
|
|
48
|
+
`,document.head.appendChild(t)}const g=({...t})=>{const{theme:o="system"}=y();return d.useEffect(()=>{z()},[]),c.jsx(j.Toaster,{theme:o,className:"toaster group",icons:{success:c.jsx(i.HugeiconsIcon,{icon:l.CheckmarkCircle02Icon,strokeWidth:2,className:"size-4 text-success toast-icon-success"}),info:c.jsx(i.HugeiconsIcon,{icon:l.InformationCircleIcon,strokeWidth:2,className:"size-4 text-info toast-icon-info"}),warning:c.jsx(i.HugeiconsIcon,{icon:l.Alert02Icon,strokeWidth:2,className:"size-4 text-warning toast-icon-warning"}),error:c.jsx(i.HugeiconsIcon,{icon:l.MultiplicationSignCircleIcon,strokeWidth:2,className:"size-4 text-destructive toast-icon-error"}),loading:c.jsx(i.HugeiconsIcon,{icon:l.Loading03Icon,strokeWidth:2,className:"size-4 text-primary toast-icon-loading animate-spin"})},style:{"--normal-bg":"var(--foreground)","--normal-text":"var(--background)","--normal-border":"color-mix(in oklch, var(--background) 25%, transparent)","--border-radius":"9999px","--success-bg":"var(--success)","--success-text":"var(--success-foreground)","--success-border":"var(--success-400)","--error-bg":"var(--destructive)","--error-text":"var(--destructive-foreground)","--error-border":"var(--danger-400)","--warning-bg":"var(--warning)","--warning-text":"var(--warning-foreground)","--warning-border":"var(--warning-400)","--info-bg":"var(--info)","--info-text":"var(--info-foreground)","--info-border":"var(--info-400)"},toastOptions:{classNames:{toast:"cn-toast",success:"toast-success",error:"toast-error",warning:"toast-warning",info:"toast-info",loading:"toast-loading"}},...t})};g.displayName="Toaster";const H=g,_=g;exports.EnhancedSonner=_;exports.EnhancedToaster=H;exports.Toaster=g;exports.z=y;
|
package/dist/sonner.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./sonner-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./sonner-nE9hIalJ.cjs");exports.CoreToaster=e.Toaster;exports.EnhancedSonner=e.EnhancedSonner;exports.EnhancedToaster=e.EnhancedToaster;exports.Toaster=e.Toaster;
|
package/dist/sonner.es.js
CHANGED
package/dist/styles.css
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* - Light and dark mode support
|
|
13
13
|
* - Base layer styles
|
|
14
14
|
* - Utility animations
|
|
15
|
+
* - Hit-area @utility blocks (inlined from src/styles/hit-area.css)
|
|
15
16
|
* - @source inline() directives for zero-config Tailwind utility generation
|
|
16
17
|
*
|
|
17
18
|
* Generated by: npm run build:lib
|
|
@@ -68,9 +69,148 @@
|
|
|
68
69
|
/* Z-index elevation utilities */
|
|
69
70
|
@source inline("z-[var(--z-debug)] z-[var(--z-sticky-page)] z-[var(--z-background)] z-[var(--z-content)] z-[var(--z-popover)] z-[var(--z-modal-backdrop)] z-[var(--z-modal)] z-[var(--z-tooltip)] z-[var(--z-sticky-content)] z-[var(--z-floating)]");
|
|
70
71
|
|
|
72
|
+
/* Hit-area utilities (referenced from TSX / docs; @utility defines behavior) */
|
|
73
|
+
@source inline("hit-area-4 hit-area-6 hit-area-debug");
|
|
74
|
+
|
|
71
75
|
|
|
72
76
|
|
|
73
77
|
/* Custom dark mode variant - matches when .dark class is on element or ancestor */
|
|
78
|
+
/* Hit-area — https://bazza.dev/craft/2026/hit-area */
|
|
79
|
+
/* Bazza hit-area utilities — https://bazza.dev/craft/2026/hit-area */
|
|
80
|
+
|
|
81
|
+
@utility hit-area-debug {
|
|
82
|
+
position: relative;
|
|
83
|
+
&::before {
|
|
84
|
+
content: "";
|
|
85
|
+
position: absolute;
|
|
86
|
+
top: var(--hit-area-t, 0px);
|
|
87
|
+
right: var(--hit-area-r, 0px);
|
|
88
|
+
bottom: var(--hit-area-b, 0px);
|
|
89
|
+
left: var(--hit-area-l, 0px);
|
|
90
|
+
pointer-events: inherit;
|
|
91
|
+
@apply border border-dashed border-blue-500 bg-blue-500/10;
|
|
92
|
+
}
|
|
93
|
+
&:hover::before {
|
|
94
|
+
@apply border border-dashed border-green-500 bg-green-500/10;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@utility hit-area {
|
|
99
|
+
position: relative;
|
|
100
|
+
&::before {
|
|
101
|
+
content: "";
|
|
102
|
+
position: absolute;
|
|
103
|
+
top: var(--hit-area-t, 0px);
|
|
104
|
+
right: var(--hit-area-r, 0px);
|
|
105
|
+
bottom: var(--hit-area-b, 0px);
|
|
106
|
+
left: var(--hit-area-l, 0px);
|
|
107
|
+
pointer-events: inherit;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@utility hit-area-* {
|
|
112
|
+
position: relative;
|
|
113
|
+
--hit-area-t: --spacing(--value(number) * -1); --hit-area-t: calc(--value([*]) * -1);
|
|
114
|
+
--hit-area-b: --spacing(--value(number) * -1); --hit-area-b: calc(--value([*]) * -1);
|
|
115
|
+
--hit-area-l: --spacing(--value(number) * -1); --hit-area-l: calc(--value([*]) * -1);
|
|
116
|
+
--hit-area-r: --spacing(--value(number) * -1); --hit-area-r: calc(--value([*]) * -1);
|
|
117
|
+
&::before {
|
|
118
|
+
content: "";
|
|
119
|
+
position: absolute;
|
|
120
|
+
top: var(--hit-area-t, 0px);
|
|
121
|
+
right: var(--hit-area-r, 0px);
|
|
122
|
+
bottom: var(--hit-area-b, 0px);
|
|
123
|
+
left: var(--hit-area-l, 0px);
|
|
124
|
+
pointer-events: inherit;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@utility hit-area-l-* {
|
|
129
|
+
position: relative;
|
|
130
|
+
--hit-area-l: --spacing(--value(number) * -1); --hit-area-l: calc(--value([*]) * -1);
|
|
131
|
+
&::before {
|
|
132
|
+
content: "";
|
|
133
|
+
position: absolute;
|
|
134
|
+
top: var(--hit-area-t, 0px);
|
|
135
|
+
right: var(--hit-area-r, 0px);
|
|
136
|
+
bottom: var(--hit-area-b, 0px);
|
|
137
|
+
left: var(--hit-area-l, 0px);
|
|
138
|
+
pointer-events: inherit;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
@utility hit-area-r-* {
|
|
143
|
+
position: relative;
|
|
144
|
+
--hit-area-r: --spacing(--value(number) * -1); --hit-area-r: calc(--value([*]) * -1);
|
|
145
|
+
&::before {
|
|
146
|
+
content: "";
|
|
147
|
+
position: absolute;
|
|
148
|
+
top: var(--hit-area-t, 0px);
|
|
149
|
+
right: var(--hit-area-r, 0px);
|
|
150
|
+
bottom: var(--hit-area-b, 0px);
|
|
151
|
+
left: var(--hit-area-l, 0px);
|
|
152
|
+
pointer-events: inherit;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@utility hit-area-t-* {
|
|
157
|
+
position: relative;
|
|
158
|
+
--hit-area-t: --spacing(--value(number) * -1); --hit-area-t: calc(--value([*]) * -1);
|
|
159
|
+
&::before {
|
|
160
|
+
content: "";
|
|
161
|
+
position: absolute;
|
|
162
|
+
top: var(--hit-area-t, 0px);
|
|
163
|
+
right: var(--hit-area-r, 0px);
|
|
164
|
+
bottom: var(--hit-area-b, 0px);
|
|
165
|
+
left: var(--hit-area-l, 0px);
|
|
166
|
+
pointer-events: inherit;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@utility hit-area-b-* {
|
|
171
|
+
position: relative;
|
|
172
|
+
--hit-area-b: --spacing(--value(number) * -1); --hit-area-b: calc(--value([*]) * -1);
|
|
173
|
+
&::before {
|
|
174
|
+
content: "";
|
|
175
|
+
position: absolute;
|
|
176
|
+
top: var(--hit-area-t, 0px);
|
|
177
|
+
right: var(--hit-area-r, 0px);
|
|
178
|
+
bottom: var(--hit-area-b, 0px);
|
|
179
|
+
left: var(--hit-area-l, 0px);
|
|
180
|
+
pointer-events: inherit;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
@utility hit-area-x-* {
|
|
185
|
+
position: relative;
|
|
186
|
+
--hit-area-l: --spacing(--value(number) * -1); --hit-area-l: calc(--value([*]) * -1);
|
|
187
|
+
--hit-area-r: --spacing(--value(number) * -1); --hit-area-r: calc(--value([*]) * -1);
|
|
188
|
+
&::before {
|
|
189
|
+
content: "";
|
|
190
|
+
position: absolute;
|
|
191
|
+
top: var(--hit-area-t, 0px);
|
|
192
|
+
right: var(--hit-area-r, 0px);
|
|
193
|
+
bottom: var(--hit-area-b, 0px);
|
|
194
|
+
left: var(--hit-area-l, 0px);
|
|
195
|
+
pointer-events: inherit;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@utility hit-area-y-* {
|
|
200
|
+
position: relative;
|
|
201
|
+
--hit-area-t: --spacing(--value(number) * -1); --hit-area-t: calc(--value([*]) * -1);
|
|
202
|
+
--hit-area-b: --spacing(--value(number) * -1); --hit-area-b: calc(--value([*]) * -1);
|
|
203
|
+
&::before {
|
|
204
|
+
content: "";
|
|
205
|
+
position: absolute;
|
|
206
|
+
top: var(--hit-area-t, 0px);
|
|
207
|
+
right: var(--hit-area-r, 0px);
|
|
208
|
+
bottom: var(--hit-area-b, 0px);
|
|
209
|
+
left: var(--hit-area-l, 0px);
|
|
210
|
+
pointer-events: inherit;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
74
214
|
@theme inline {
|
|
75
215
|
--font-sans: 'Inter Variable', sans-serif;
|
|
76
216
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
@@ -455,6 +595,48 @@
|
|
|
455
595
|
}
|
|
456
596
|
}
|
|
457
597
|
|
|
598
|
+
/* Spinner — dual arc (Uiverse-style), primary gradient */
|
|
599
|
+
@keyframes nqui-spinner-rotate {
|
|
600
|
+
from {
|
|
601
|
+
transform: rotate(0deg);
|
|
602
|
+
}
|
|
603
|
+
to {
|
|
604
|
+
transform: rotate(360deg);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
@keyframes nqui-spinner-dash-first {
|
|
609
|
+
0%,
|
|
610
|
+
100% {
|
|
611
|
+
stroke-dashoffset: 50;
|
|
612
|
+
}
|
|
613
|
+
50% {
|
|
614
|
+
stroke-dashoffset: 625;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
@keyframes nqui-spinner-dash-second {
|
|
619
|
+
0%,
|
|
620
|
+
100% {
|
|
621
|
+
stroke-dashoffset: -625;
|
|
622
|
+
}
|
|
623
|
+
50% {
|
|
624
|
+
stroke-dashoffset: -50;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
.nqui-spinner-rotate {
|
|
629
|
+
animation: nqui-spinner-rotate 2s linear infinite;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
.nqui-spinner-arc-first circle {
|
|
633
|
+
animation: nqui-spinner-dash-first 3s ease-in-out infinite;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
.nqui-spinner-arc-second circle {
|
|
637
|
+
animation: nqui-spinner-dash-second 3s ease-in-out infinite;
|
|
638
|
+
}
|
|
639
|
+
|
|
458
640
|
/* Toast Icon Animations */
|
|
459
641
|
.toast-icon-success {
|
|
460
642
|
animation: toast-checkmark 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
|
@@ -541,6 +723,7 @@
|
|
|
541
723
|
position: absolute;
|
|
542
724
|
z-index: 0;
|
|
543
725
|
pointer-events: none;
|
|
726
|
+
overflow: visible;
|
|
544
727
|
transition:
|
|
545
728
|
left 0.3s ease-in-out,
|
|
546
729
|
top 0.3s ease-in-out,
|
|
@@ -550,6 +733,8 @@
|
|
|
550
733
|
|
|
551
734
|
.sliding-indicator-container {
|
|
552
735
|
position: relative;
|
|
736
|
+
overflow: hidden;
|
|
737
|
+
min-width: 0;
|
|
553
738
|
}
|
|
554
739
|
|
|
555
740
|
.sliding-indicator-target {
|
|
@@ -979,4 +1164,4 @@
|
|
|
979
1164
|
--sidebar-accent-foreground: oklch(0.92 0 0);
|
|
980
1165
|
--sidebar-border: oklch(1 0 0 / 10%);
|
|
981
1166
|
--sidebar-ring: oklch(0.556 0 0);
|
|
982
|
-
}
|
|
1167
|
+
}
|
|
@@ -17,7 +17,7 @@ Implementation guides for each component. **AI Skill:** Optimized for AI/LLM con
|
|
|
17
17
|
| Dependency | Version | Notes |
|
|
18
18
|
|------------|---------|-------|
|
|
19
19
|
| **React** | 18+ or 19 | nqui supports React 18 and 19 via `^18.0.0 \|\| ^19.0.0` peer. |
|
|
20
|
-
| **Tailwind CSS** | ^4.x | Required. Vite: `@tailwindcss/vite`. Next.js
|
|
20
|
+
| **Tailwind CSS** | ^4.x | Required. Vite: `@tailwindcss/vite`. Both Vite and Next.js need `@source` for `node_modules/@nqlib/nqui/dist` (Tailwind does not scan node_modules). |
|
|
21
21
|
| **tw-animate-css** | — | `@import "tw-animate-css"` in your CSS (added by init-css). |
|
|
22
22
|
| **Radix UI** | — | Bundled (Dialog, Select, etc.). |
|
|
23
23
|
| **Hugeicons** | @hugeicons/react, @hugeicons/core-free-icons | Required for icon display in components. |
|
|
@@ -28,16 +28,115 @@ Implementation guides for each component. **AI Skill:** Optimized for AI/LLM con
|
|
|
28
28
|
|
|
29
29
|
## Shared Conventions (AI Implementation Rules)
|
|
30
30
|
|
|
31
|
-
- **Control sizes:** `sm`=h-6, `default`=h-7, `lg`=h-8. Button, Toggle, ToggleGroup, Input, Select use this scale. See `.cursor/skills/nqui-design-system/SKILL.md`.
|
|
31
|
+
- **Control sizes:** `sm`=h-6, `default`=h-7, `lg`=h-8. Button, Toggle, ToggleGroup, Input, Select, Switch, Slider use this scale. See `packages/nqui/docs/nqui-skills/design-system.md` or `.cursor/skills/nqui-design-system/SKILL.md`.
|
|
32
32
|
- **CSS vars required:** nqui uses `--primary`, `--background`, `--foreground`, etc. Run `npx @nqlib/nqui init-css`.
|
|
33
|
-
- **Enhanced vs Core:** Button
|
|
34
|
-
- **Grouped controls:** ButtonGroup, ToggleGroup share border; ToggleGroup uses item dividers (`border-foreground/20`) or `ToggleGroupSeparator`.
|
|
33
|
+
- **Enhanced vs Core:** Default exports (`Button`, `Badge`, `Checkbox`, `Select`, etc.) are the polished/3D variants. Implementations live in **`packages/nqui/src/components/ui/*.tsx`** (single file per concern). Use `CoreButton`, `CoreBadge`, `CoreCheckbox`, etc. for base Radix/shadcn-style behavior. Separator: single component with `variant` prop (no CoreSeparator).
|
|
34
|
+
- **Grouped controls:** ButtonGroup, ToggleGroup share border; outer container uses **pill** radius (`rounded-full`). ToggleGroup uses item dividers (`border-foreground/20`) or `ToggleGroupSeparator`.
|
|
35
35
|
- **Toolbar context:** Always show Toggle/ToggleGroup in realistic context (document toolbar, chart settings, etc.). Reference: `src/pages/ComponentShowcase.tsx`.
|
|
36
|
-
- **Style injection:**
|
|
36
|
+
- **Style injection:** Some components inject `<style>` once at mount (e.g. **Combobox** input chrome in `ui/combobox.tsx`) → safe for SSR if the component is client-only (`"use client"`).
|
|
37
37
|
- **OKLCH:** ColorPicker expects OKLCH strings (`oklch(0.5 0.15 240)`), not hex.
|
|
38
38
|
- **SidebarProvider:** Must wrap entire layout (sidebar + content).
|
|
39
39
|
- **Z-index:** Use CSS vars from `styles/elevation.css` (e.g. `z-[var(--z-modal)]`). Never hardcode `z-10`, `z-50`, etc.
|
|
40
40
|
- **Keyboard:** Use `Keys`, `isMod`, `shouldIgnoreKeyboardShortcut` from `@/lib/keyboard` for custom shortcuts.
|
|
41
|
+
- **Bounded content:** Chips, pills, and inline controls should stay inside their box (ellipsis / line-clamp / scroll-by-design). See **Bounded content** in `packages/nqui/docs/nqui-skills/design-system.md`. Portals and tooltips are explicit exceptions.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Layout & Scroll Patterns
|
|
46
|
+
|
|
47
|
+
This section documents the CSS patterns used in the showcase app to ensure proper scroll behavior and prevent sticky element issues.
|
|
48
|
+
|
|
49
|
+
### Sticky Elements & Momentum Scroll
|
|
50
|
+
|
|
51
|
+
**The problem:** When using default body scroll, sticky elements can exhibit "momentum push" behavior during fast scrolling - they appear to float or lag before snapping back. This happens because sticky positioning is relative to the viewport, not the scroll container.
|
|
52
|
+
|
|
53
|
+
**The solution:** Use a custom scroll container instead of body/html scroll.
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
// App layout structure - prevents momentum push on sticky elements
|
|
57
|
+
<div className="h-screen overflow-hidden">
|
|
58
|
+
<header className="sticky top-0 z-[var(--z-sticky-page)]">
|
|
59
|
+
{/* Page header */}
|
|
60
|
+
</header>
|
|
61
|
+
<main className="flex-1 min-h-0 overflow-y-auto">
|
|
62
|
+
{/* Scrollable content */}
|
|
63
|
+
</main>
|
|
64
|
+
</div>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Z-Index Layering for Sticky Elements
|
|
68
|
+
|
|
69
|
+
Use the correct z-index variables to prevent sticky element conflicts:
|
|
70
|
+
|
|
71
|
+
| Element | CSS Variable | Value |
|
|
72
|
+
|---------|-------------|-------|
|
|
73
|
+
| Page headers, navigation bars | `z-[var(--z-sticky-page)]` | 20 |
|
|
74
|
+
| Card headers, table headers | `z-[var(--z-sticky-content)]` | 15 |
|
|
75
|
+
|
|
76
|
+
**Rule:** Page-level sticky elements (20) must be above container-level sticky elements (15) to prevent scroll conflicts.
|
|
77
|
+
|
|
78
|
+
### Flex Scroll Pattern
|
|
79
|
+
|
|
80
|
+
For nested scrolling to work correctly, flex children must have `min-height: 0` (or `min-h-0` in Tailwind):
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
// Correct - flex child can shrink and scroll
|
|
84
|
+
<div className="flex flex-col h-screen">
|
|
85
|
+
<header className="flex-shrink-0">...</header>
|
|
86
|
+
<main className="flex-1 min-h-0 overflow-y-auto">
|
|
87
|
+
{/* This will scroll */}
|
|
88
|
+
</main>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
// Wrong - flex child cannot shrink below content height
|
|
92
|
+
<div className="flex flex-col h-screen">
|
|
93
|
+
<header>...</header>
|
|
94
|
+
<main className="flex-1 overflow-y-auto">
|
|
95
|
+
{/* May not scroll - overflows instead */}
|
|
96
|
+
</main>
|
|
97
|
+
</div>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Body Scroll Prevention
|
|
101
|
+
|
|
102
|
+
For app-like experiences, disable body/html scroll:
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
// Disable browser scroll restoration
|
|
107
|
+
if ('scrollRestoration' in history) {
|
|
108
|
+
history.scrollRestoration = 'manual'
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Prevent body/html from scrolling
|
|
112
|
+
document.body.style.overflow = 'hidden'
|
|
113
|
+
document.documentElement.style.overflow = 'hidden'
|
|
114
|
+
|
|
115
|
+
return () => {
|
|
116
|
+
document.body.style.overflow = ''
|
|
117
|
+
document.documentElement.style.overflow = ''
|
|
118
|
+
}
|
|
119
|
+
}, [])
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Sliding Indicator Containers
|
|
123
|
+
|
|
124
|
+
Components with sliding indicators (Tabs, RadioGroup `sliding` variant) need specific container styling:
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
// Required CSS for sliding indicator containers
|
|
128
|
+
.sliding-indicator-container {
|
|
129
|
+
position: relative;
|
|
130
|
+
overflow: hidden;
|
|
131
|
+
min-width: 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.sliding-indicator {
|
|
135
|
+
position: absolute;
|
|
136
|
+
overflow: visible;
|
|
137
|
+
/* transitions for smooth sliding */
|
|
138
|
+
}
|
|
139
|
+
```
|
|
41
140
|
|
|
42
141
|
---
|
|
43
142
|
|
|
@@ -67,7 +166,7 @@ Use these rules to choose the right component. **Selection** = user picks from o
|
|
|
67
166
|
|-------|-----|
|
|
68
167
|
| 2–5 options, inline (e.g. bold/italic/underline) | **ToggleGroup** `type="multiple"` |
|
|
69
168
|
| Form context, list of options | **Checkbox** (each option) |
|
|
70
|
-
| Many options, need search | **Combobox** `
|
|
169
|
+
| Many options, need search | **Combobox** with `multiple` (see `nqui-combobox.md`) |
|
|
71
170
|
|
|
72
171
|
### Actions (trigger, not select)
|
|
73
172
|
|
|
@@ -108,7 +207,7 @@ Use these rules to choose the right component. **Selection** = user picks from o
|
|
|
108
207
|
| Single choice, 5+ options or no space | **Select** |
|
|
109
208
|
| Single choice, need search | **Combobox** (single) |
|
|
110
209
|
| Single choice, form, small option set | **RadioGroup** |
|
|
111
|
-
| Multiple choice, need search | **Combobox** `
|
|
210
|
+
| Multiple choice, need search | **Combobox** with `multiple` (see `nqui-combobox.md`) |
|
|
112
211
|
| One boolean (agree, subscribe) | **Checkbox** |
|
|
113
212
|
| On/off setting (dark mode, notifications) | **Switch** |
|
|
114
213
|
| Numeric range (volume, opacity) | **Slider** |
|
|
@@ -135,7 +234,7 @@ Use these rules to choose the right component. **Selection** = user picks from o
|
|
|
135
234
|
| Rating | [nqui-rating.md](./nqui-rating.md) | Star/score (1–5). |
|
|
136
235
|
| InputOTP | [nqui-input-otp.md](./nqui-input-otp.md) | OTP/verification. |
|
|
137
236
|
| Field | [nqui-field.md](./nqui-field.md) | Label + description + error wrapper. |
|
|
138
|
-
| Combobox | [nqui-combobox.md](./nqui-combobox.md) | **Searchable** select. Single or `
|
|
237
|
+
| Combobox | [nqui-combobox.md](./nqui-combobox.md) | **Searchable** select. Single or `multiple`. Use when user types to filter. |
|
|
139
238
|
| ColorPicker | [nqui-color-picker.md](./nqui-color-picker.md) | Color selection. OKLCH. |
|
|
140
239
|
| ColorSlider | [nqui-color-slider.md](./nqui-color-slider.md) | Hue/saturation (used in ColorPicker). |
|
|
141
240
|
| Label | [nqui-label.md](./nqui-label.md) | Form label. |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nqui Button
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Default **Button** is the enhanced variant (gradients, depth, active scale). Implemented in **`ui/button.tsx`** with **`CoreButton`** for the plain primitive.
|
|
4
4
|
|
|
5
5
|
## Import
|
|
6
6
|
|
|
@@ -52,5 +52,7 @@ Render as `<a>` or custom element:
|
|
|
52
52
|
|
|
53
53
|
## Notes
|
|
54
54
|
|
|
55
|
+
- **Shape:** full pill (`rounded-full`) for all sizes.
|
|
56
|
+
- **Bounded label:** string/number children are wrapped so **`truncate`** + **`min-w-0`** apply in narrow layouts. Same pattern is used across **Toggle**, **Tabs**, **Badge**, **Combobox** chips; **Select** value uses **line-clamp**. Custom markup with one long inner node may still need its own `min-w-0 truncate` or a **`title`**.
|
|
55
57
|
- Active state uses `scale-95`; avoid parent `transform` overrides.
|
|
56
58
|
- Use `CoreButton` from `@nqlib/nqui` for base shadcn style.
|
|
@@ -29,3 +29,11 @@ import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter }
|
|
|
29
29
|
<CardContent>Scrollable content</CardContent>
|
|
30
30
|
</Card>
|
|
31
31
|
```
|
|
32
|
+
|
|
33
|
+
## Notes
|
|
34
|
+
|
|
35
|
+
- **Layout / bounds:** Root **Card**, **CardHeader**, **CardContent**, and **CardFooter** include **`min-w-0`** so nested flex/grid layouts can shrink and children are less likely to spill horizontally. **Card** stays **`overflow-visible`** on purpose so popovers, menus, and focus rings are not clipped—pair with bounded components (buttons, carousel insets, `truncate`, etc.) instead of `overflow-hidden` on the card by default.
|
|
36
|
+
- **stickyHeader:** Use `stickyHeader` prop on Card for scrollable content with sticky header. The header uses `--z-sticky-content` (z-index: 15).
|
|
37
|
+
- **Z-index layering:** Card sticky headers (15) are below page headers (20). If using in a page with sticky header, ensure proper z-index layering.
|
|
38
|
+
- **Height required:** Card needs a defined height (e.g., `h-[400px]` or `h-full`) for sticky behavior to work.
|
|
39
|
+
- **Content scroll:** The CardContent becomes scrollable when Card has `stickyHeader` and a defined height.
|
|
@@ -20,3 +20,9 @@ import { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext
|
|
|
20
20
|
<CarouselNext />
|
|
21
21
|
</Carousel>
|
|
22
22
|
```
|
|
23
|
+
|
|
24
|
+
## Notes
|
|
25
|
+
|
|
26
|
+
- **Prev/Next** are positioned **inside** the carousel region (`left-2` / `right-2`, or `top-2` / `bottom-2` when vertical) so arrows stay within parents like **Card** instead of using negative offsets that sat outside the viewport (`-left-12` / `-right-12` previously).
|
|
27
|
+
- **Visibility:** Arrows are **dim by default** (`opacity-35`), ramp up on **carousel hover** (`group-hover/carousel`), and go **full opacity** on **button** `:hover`, `:focus-visible`, and `:active` (tap). Disabled controls stay faint.
|
|
28
|
+
- Override with `className` on `CarouselPrevious` / `CarouselNext` if you need edge-aligned or external controls.
|