@nqlib/nqui 0.4.7 → 0.5.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.
Files changed (63) hide show
  1. package/README.md +22 -18
  2. package/dist/{button-CJHdCq9I.js → button-BrroJ39H.js} +35 -34
  3. package/dist/button-CrLihxcE.cjs +1 -0
  4. package/dist/calendar.cjs.js +1 -1
  5. package/dist/calendar.es.js +1 -1
  6. package/dist/{carousel-U7RZhYZj.js → carousel-C976t5jo.js} +1 -1
  7. package/dist/{carousel-D1FMVglR.cjs → carousel-VldrniuT.cjs} +1 -1
  8. package/dist/carousel.cjs.js +1 -1
  9. package/dist/carousel.es.js +1 -1
  10. package/dist/{command-palette-D_SFxXyQ.js → command-palette-2V1VSlOM.js} +1 -1
  11. package/dist/{command-palette-DSQYbRiH.cjs → command-palette-4Sv4QjZ2.cjs} +1 -1
  12. package/dist/command.cjs.js +1 -1
  13. package/dist/command.es.js +1 -1
  14. package/dist/components/custom/enhanced-tabs.d.ts +1 -0
  15. package/dist/components/custom/enhanced-tabs.d.ts.map +1 -1
  16. package/dist/components/ui/button.d.ts +4 -0
  17. package/dist/components/ui/button.d.ts.map +1 -1
  18. package/dist/components/ui/card.d.ts +1 -0
  19. package/dist/components/ui/card.d.ts.map +1 -1
  20. package/dist/components/ui/sonner.d.ts.map +1 -1
  21. package/dist/components/ui/tabs.d.ts +6 -4
  22. package/dist/components/ui/tabs.d.ts.map +1 -1
  23. package/dist/{debug-panel-BtOvhfpR.js → debug-panel-BnZDhlaR.js} +1621 -1749
  24. package/dist/{debug-panel-DLfH4sdK.cjs → debug-panel-R2ZLkucO.cjs} +10 -10
  25. package/dist/debug.cjs.js +1 -1
  26. package/dist/debug.es.js +1 -1
  27. package/dist/{enhanced-calendar-C7EQIr6i.cjs → enhanced-calendar-BEIfybRx.cjs} +1 -1
  28. package/dist/{enhanced-calendar-BGlsSYJd.js → enhanced-calendar-Cj-4xhqf.js} +1 -1
  29. package/dist/hooks/use-resolved-theme.d.ts +3 -4
  30. package/dist/hooks/use-resolved-theme.d.ts.map +1 -1
  31. package/dist/nqui.cjs.js +3 -23
  32. package/dist/nqui.es.js +607 -629
  33. package/dist/{sonner-nE9hIalJ.cjs → sonner-CEx2-yKh.cjs} +2 -2
  34. package/dist/{sonner-CpmECDBk.js → sonner-FXwPWWq8.js} +24 -24
  35. package/dist/sonner.cjs.js +1 -1
  36. package/dist/sonner.es.js +1 -1
  37. package/dist/styles.css +40 -80
  38. package/docs/components/README.md +11 -2
  39. package/docs/components/nqui-scroll-area.md +74 -0
  40. package/docs/components/nqui-tooltip.md +17 -2
  41. package/docs/nqui-skills/COMPONENTS_INDEX.md +48 -0
  42. package/docs/nqui-skills/HUMAN_GUIDE.md +21 -0
  43. package/docs/nqui-skills/README.md +20 -0
  44. package/docs/nqui-skills/SKILL.md +36 -89
  45. package/docs/nqui-skills/nqui-bundle-size-best-practices/SKILL.md +78 -0
  46. package/docs/nqui-skills/nqui-components/SKILL.md +101 -0
  47. package/docs/nqui-skills/{design-system.md → nqui-design-system/SKILL.md} +55 -25
  48. package/docs/nqui-skills/nqui-install/SKILL.md +65 -0
  49. package/docs/nqui-skills/nqui-local-published-toggle/SKILL.md +132 -0
  50. package/docs/nqui-skills/nqui-local-published-toggle/scripts/toggle-nqui.js +203 -0
  51. package/docs/nqui-skills/nqui-shadcn/SKILL.md +164 -0
  52. package/docs/nqui-skills/{rules → nqui-shadcn/rules}/forms.md +3 -3
  53. package/docs/nqui-skills/{rules → nqui-shadcn/rules}/styling.md +1 -1
  54. package/package.json +1 -1
  55. package/scripts/download-skills.js +28 -8
  56. package/scripts/examples/nextjs-layout-sidebar.tsx +3 -2
  57. package/scripts/examples/nextjs-layout.tsx +3 -2
  58. package/scripts/examples/vite-main.tsx +7 -1
  59. package/scripts/init-cursor.js +4 -3
  60. package/scripts/skill-templates.js +16 -6
  61. package/dist/button-R304rhsj.cjs +0 -1
  62. /package/docs/nqui-skills/{rules → nqui-shadcn/rules}/composition.md +0 -0
  63. /package/docs/nqui-skills/{rules → nqui-shadcn/rules}/icons.md +0 -0
@@ -1,106 +1,53 @@
1
1
  ---
2
- name: nqui Components
3
- description: Component implementation guide for nqui. Use when building UI, designing app layouts, or implementing components with @nqlib/nqui.
2
+ name: nqui
3
+ description: Hub for nqui skills — @nqlib/nqui components, design system, shadcn patterns, bundle size, local/published toggle, and install. Load sub-skills by task.
4
4
  ---
5
5
 
6
- # nqui Components Guide
6
+ # nqui skills (hub)
7
7
 
8
- Reference `packages/nqui/docs/components/README.md` for the full component index and implementation rules.
8
+ Use this file as the entry point when working inside **`docs/nqui-skills/`** (package) or **`.cursor/nqui-skills/`** (after `npx @nqlib/nqui init-skills`).
9
9
 
10
- ## Quick Reference
10
+ ## Per-component docs (token-efficient)
11
11
 
12
- 1. **Main index:** `packages/nqui/docs/components/README.md` - all components, use cases, prerequisites
13
- 2. **Per-component:** `packages/nqui/docs/components/nqui-<name>.md` - import, examples, variants
14
- 3. **Design system:** this folder - sizing, grouped controls
12
+ 1. Read **[COMPONENTS_INDEX.md](./COMPONENTS_INDEX.md)** first — which single `nqui-*.md` to open.
13
+ 2. **Designers / task-based:** **[HUMAN_GUIDE.md](./HUMAN_GUIDE.md)** forms, dashboards, navigation, empty/loading/error, without reading all of `README.md`.
14
+ 3. **Source repo:** `docs/components/nqui-<name>.md`
15
+ 4. **After `init-skills`:** `.cursor/nqui-skills/components/nqui-<name>.md` (same files as npm `docs/components/`)
15
16
 
16
- ## App Design Rule: Inline Selection ToggleGroup
17
+ Avoid loading every component doc or the full `README.md` unless you need broad “when to use” tables.
17
18
 
18
- When designing app UI (toolbars, headers, inline controls):
19
+ ## Where to read docs (pick by context)
19
20
 
20
- | Context | Use | NOT |
21
- |---------|-----|-----|
22
- | View mode (List/Grid/Table), scale (Linear/Log), size (S/M/L) | **ToggleGroup** `type="single"` | RadioGroup |
23
- | Format toolbar (Bold/Italic/Underline), multi-toggle | **ToggleGroup** `type="multiple"` | Multiple Checkboxes |
24
- | Toolbar actions (Undo/Redo, align) | **ButtonGroup** | - |
25
- | Single on/off (Bold, Mute) | **Toggle** | - |
21
+ | Context | Path |
22
+ |---------|------|
23
+ | **This package** (nqui repo or monorepo `packages/nqui`) | `docs/components/README.md`, `docs/components/nqui-<name>.md` |
24
+ | **Consumer after init-skills** | `.cursor/nqui-skills/components/README.md` and `nqui-<name>.md` |
25
+ | **npm only** | `node_modules/@nqlib/nqui/docs/components/` |
26
26
 
27
- **Rule:** Inline/toolbar selection = ToggleGroup. Use RadioGroup only for form context (settings page, modal form, stacked list).
27
+ Per-component files: `nqui-<kebab-case>.md` (e.g. `nqui-combobox.md`).
28
28
 
29
- ## App Design Rule: Context-First (Toolbar in Real Environment)
29
+ ## Skill index (load by task)
30
30
 
31
- **Rule:** Never show Toggle/ToggleGroup/ButtonGroup in isolation. Always place them in realistic app context.
31
+ | Task | Open |
32
+ |------|------|
33
+ | UI, layouts, ToggleGroup vs Radio, Card + ScrollArea | [nqui-components/SKILL.md](./nqui-components/SKILL.md) |
34
+ | Sizing, spacing, density, grouped controls, flex scroll | [nqui-design-system/SKILL.md](./nqui-design-system/SKILL.md) |
35
+ | Imports, FieldGroup, forms, composition, icons, styling | [nqui-shadcn/SKILL.md](./nqui-shadcn/SKILL.md) |
36
+ | Peers, externals, subpath imports | [nqui-bundle-size-best-practices/SKILL.md](./nqui-bundle-size-best-practices/SKILL.md) |
37
+ | `npm link` local nqui vs registry | [nqui-local-published-toggle/SKILL.md](./nqui-local-published-toggle/SKILL.md) |
38
+ | `init-css`, `install-peers`, CLI | [nqui-install/SKILL.md](./nqui-install/SKILL.md) |
32
39
 
33
- | Context | Layout | Reference |
34
- |---------|--------|-----------|
35
- | Document editor | Toolbar above content; `bg-muted/30` container; `Separator` between groups | ComponentShowcase → Toggle & ToggleGroup |
36
- | Chart/settings | Label + inline controls; `rounded-lg border bg-muted/30 p-3` | ComponentShowcase → Chart settings |
37
- | Standalone | Inline with related UI | ComponentShowcase → Standalone toggle |
40
+ ## UX principles (cross-cutting)
38
41
 
39
- **Canonical implementation:** `packages/nqui/src/pages/ComponentShowcase.tsx` Toggle & ToggleGroup section.
42
+ - **Accessibility:** Use semantic components; **don’t** hide required instructions in **Tooltip** only (see `docs/components/nqui-tooltip.md`). Forms: `data-invalid` / `aria-invalid` per `nqui-shadcn/rules/forms.md`. Dialogs need titles (`nqui-shadcn` composition rules).
43
+ - **Touch / pointer:** Hover-only content is **supplemental**; **Tooltip** / **HoverCard** are poor for primary info on touch. Use **default/lg** size and optional **hit-area** on small targets in padded rows (`nqui-components/SKILL.md`).
44
+ - **States:** **Loading** → Skeleton / Spinner; **empty** → Empty; **error** → Field + Alert + validation patterns.
45
+ - **Focus:** After closing overlays, preserve sensible focus (Radix defaults — don’t override with stray `tabIndex`).
40
46
 
41
- ## Design System Conventions
47
+ ## Quick rules
42
48
 
43
- See **`design-system.md`** in this folder for sizing, grouped controls (including pill **ButtonGroup** / **ToggleGroup** shells), and file paths under `packages/nqui/src/components/ui/`.
49
+ - **Inline/toolbar selection** `ToggleGroup` (see **RadioGroup** when form semantics matter `nqui-components/SKILL.md`).
50
+ - **Card + scroll** → thread `min-h-0` through flex to `ScrollArea`; see design-system skill.
51
+ - **Forms** → `FieldGroup` + `Field`; see `nqui-shadcn` rules.
44
52
 
45
- ### Control Sizing
46
- - sm = h-6
47
- - default = h-7
48
- - lg = h-8
49
-
50
- ### Z-Index
51
- Always use CSS variables from elevation.css:
52
- - `--z-content` (10) - standard content
53
- - `--z-sticky-content` (15) - sticky within containers
54
- - `--z-sticky-page` (20) - page-level sticky
55
- - `--z-floating` (30) - floating panels
56
- - `--z-modal-backdrop` (40)
57
- - `--z-modal` (50)
58
- - `--z-popover` (60)
59
- - `--z-tooltip` (70)
60
-
61
- ### FrostedGlass (sticky glass headers)
62
-
63
- `FrostedGlass` is only the blur layer. Implementations need a **second row** with `bg-background/40`, `relative z-[var(--z-content)]`, and content that **scrolls behind** the sticky header. Full checklist, props, and troubleshooting: **`packages/nqui/docs/components/nqui-frosted-glass.md`**. Canonical page header: `AppLayout`; card: **Card** `stickyHeader`.
64
-
65
- ### Component Naming
66
- - Default exports are the enhanced/polished variants; use **Core\*** for plain primitives
67
- - Implementations are consolidated under **`ui/`** (not separate `custom/enhanced-*` per component for Button, Badge, Checkbox, Select, Combobox, Sonner)
68
- - File names: kebab-case
69
- - Component names: PascalCase
70
-
71
- ### Hit area (optional)
72
-
73
- Library CSS includes [Bazza hit-area](https://bazza.dev/craft/2026/hit-area) utilities. For **Checkbox** / **Switch** in padded tables or lists, pass **`className="hit-area-6"`** (or `hit-area-4`, axis variants) on the **component root**, not on a wrapper-only parent. Opt-in only; use **`hit-area-debug`** while tuning. Details: `packages/nqui/docs/components/nqui-checkbox.md`, `nqui-switch.md`; examples: `ComponentShowcase` Checkbox + Switch sections.
74
-
75
- ## Key Dependencies
76
-
77
- Required peer dependencies:
78
- - `@hugeicons/react`
79
- - `@hugeicons/core-free-icons`
80
-
81
- Optional:
82
- - `next-themes` - for theme toggle
83
- - `tw-animate-css` - for animations
84
-
85
- ## Installation & Setup
86
-
87
- ```bash
88
- # Quick setup
89
- npx @nqlib/nqui init-css
90
-
91
- # App setup with sidebar
92
- npx @nqlib/nqui init-css --sidebar
93
-
94
- # Install peer dependencies
95
- npx @nqlib/nqui install-peers
96
- ```
97
-
98
- ## CSS Variables
99
-
100
- All components use CSS variables. Key ones:
101
- - `--background`, `--foreground`
102
- - `--muted`, `--muted-foreground`
103
- - `--accent`, `--accent-foreground`
104
- - `--border`, `--ring`
105
- - `--primary`, `--primary-foreground`
106
- - `--destructive`, `--destructive-foreground`
53
+ Full table: [README.md](./README.md).
@@ -0,0 +1,78 @@
1
+ ---
2
+ name: nqui-bundle-size-best-practices
3
+ description: Bundle size best practices for @nqlib/nqui. Use when adding dependencies, creating packages that depend on nqui, or optimizing build output.
4
+ ---
5
+
6
+ # nqui Bundle Size Best Practices
7
+
8
+ Guidelines for keeping **@nqlib/nqui** bundles small and maintainable.
9
+
10
+ ## Principle
11
+
12
+ Keep the main bundle small. Externalize heavy optional dependencies so consumers install only what they use.
13
+
14
+ ## When Adding a Dependency
15
+
16
+ Before adding a dependency, ask:
17
+
18
+ 1. **Is it heavy (>50KB)?** Large libs (motion, @dnd-kit, embla-carousel, etc.) bloat the bundle.
19
+ 2. **Is it optional?** Only some components use it (e.g. Sortable uses @dnd-kit). If yes, add as optional peer + external in Vite.
20
+
21
+ If both answers are yes, externalize it.
22
+
23
+ ## Externalization Checklist
24
+
25
+ 1. Add to `vite.config.ts` (package root) → `rollupOptions.external`:
26
+ ```ts
27
+ "package-name",
28
+ ```
29
+ 2. Add to `package.json`:
30
+ - `peerDependencies`: `"package-name": "^x.y.0"`
31
+ - `peerDependenciesMeta`: `"package-name": { "optional": true }`
32
+ 3. Keep in `dependencies` if the nqui dev app (showcase, Storybook) needs it.
33
+ 4. Document in `internal-notes/PEER_DEPENDENCIES.md` which component(s) require it.
34
+
35
+ ## Avoid Bundling
36
+
37
+ Do not add large dependencies as regular dependencies when they are feature-specific:
38
+
39
+ - **Animations**: motion, framer-motion
40
+ - **Drag and drop**: @dnd-kit/*
41
+ - **Carousels**: embla-carousel-react
42
+ - **Tables**: @tanstack/react-table
43
+ - **Resizable panels**: react-resizable-panels
44
+ - **Combobox**: `cmdk` (optional peer, shared with Command)
45
+ - **Syntax highlighting**: shiki, @shikijs/transformers
46
+ - **Sandboxes**: @codesandbox/sandpack-react
47
+ - **Command palettes**: cmdk
48
+ - **Date pickers**: react-day-picker, date-fns
49
+ - **Toasts**: sonner
50
+ - **Drawers**: vaul
51
+ - **Icons**: @hugeicons/react, @hugeicons/core-free-icons
52
+
53
+ ## Subpath Exports
54
+
55
+ Consumers can import from subpaths for smaller bundles when using only specific component groups:
56
+
57
+ - `@nqlib/nqui/code` — CodeBlock
58
+ - `@nqlib/nqui/carousel` — Carousel
59
+ - `@nqlib/nqui/command` — Command, CommandPalette
60
+ - `@nqlib/nqui/sortable` — Sortable
61
+ - `@nqlib/nqui/calendar` — Calendar
62
+ - `@nqlib/nqui/sonner` — Toaster, Sonner
63
+ - `@nqlib/nqui/drawer` — Drawer
64
+
65
+ See `internal-notes/PEER_DEPENDENCIES.md` for peer requirements per subpath.
66
+
67
+ ## Reference
68
+
69
+ - **Component-to-peer mapping:** `internal-notes/PEER_DEPENDENCIES.md`
70
+ - **Installation notes:** `internal-notes/INSTALLATION.md` (Optional components section)
71
+
72
+ ## Other libraries in a monorepo
73
+
74
+ Packages that wrap or extend nqui should follow the same pattern:
75
+
76
+ - `peerDependencies`: `react`, `react-dom`, `@nqlib/nqui` (or workspace version)
77
+ - In Vite library build: externalize `react`, `react-dom`, `@nqlib/nqui`
78
+ - Keep heavy optional deps as peers when consumers may not need them
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: nqui-components
3
+ description: Component implementation guide for nqui. Use when building UI, designing app layouts, or implementing components with @nqlib/nqui. ToggleGroup for inline/toolbar selection; RadioGroup when form semantics matter. Card + ScrollArea + flex min-h-0 scroll patterns.
4
+ ---
5
+
6
+ # nqui Components
7
+
8
+ ## Where to read docs (pick by context)
9
+
10
+ | Context | Path |
11
+ |---------|------|
12
+ | **This package** (nqui as its own repo, or `packages/nqui` in a monorepo) | `docs/components/README.md` and `docs/components/nqui-<name>.md` |
13
+ | **Consumer app** (npm install; see `files` in `@nqlib/nqui` `package.json`) | `node_modules/@nqlib/nqui/docs/components/README.md` and `node_modules/@nqlib/nqui/docs/components/nqui-<name>.md` |
14
+ | **Task-based entry (designers)** | `docs/nqui-skills/HUMAN_GUIDE.md` |
15
+
16
+ Per-component files: `nqui-<kebab-case>.md` (e.g. `nqui-combobox.md`).
17
+
18
+ ## When to Load
19
+
20
+ - Implementing UI with nqui components
21
+ - Adding or modifying a component in this package
22
+ - Choosing the right component for a use case
23
+ - Debugging component behavior
24
+
25
+ ## App Design Rule: Inline Selection → ToggleGroup
26
+
27
+ When designing **toolbars, headers, and inline controls** (not traditional stacked forms):
28
+
29
+ | Context | Use | NOT |
30
+ |---------|-----|-----|
31
+ | View mode (List/Grid/Table), scale (Linear/Log), size (S/M/L) | **ToggleGroup** `type="single"` | RadioGroup |
32
+ | Format toolbar (Bold/Italic/Underline), multi-toggle | **ToggleGroup** `type="multiple"` | Multiple Checkboxes |
33
+ | Toolbar actions (Undo/Redo, align) | **ButtonGroup** | — |
34
+ | Single on/off (Bold, Mute) | **Toggle** | — |
35
+
36
+ **Default rule:** Inline/toolbar selection = **ToggleGroup**.
37
+
38
+ ## ToggleGroup vs RadioGroup (semantics & a11y)
39
+
40
+ | Situation | Prefer |
41
+ |-----------|--------|
42
+ | Toolbar, chart controls, editor chrome, **spatially inline** options | **ToggleGroup** — correct visual language; Radix exposes `role="group"` / toggle semantics as implemented |
43
+ | **Stacked or labeled form** “choose one” (settings page, wizard, survey), users expect **radiogroup** behavior | **RadioGroup** — screen readers get **radiogroup / radio** semantics (“1 of N”) |
44
+ | Unsure | If it reads like a **form field**, use **RadioGroup**. If it reads like a **toolbar or segmented control**, use **ToggleGroup**. |
45
+
46
+ Do not use RadioGroup inside dense toolbars for purely visual reasons if ToggleGroup fits the interaction — but do not force ToggleGroup for **form questionnaires** where radio semantics matter.
47
+
48
+ ## App Design Rule: Context-First (Toolbar in Real Environment)
49
+
50
+ **Rule:** Never show Toggle/ToggleGroup/ButtonGroup in isolation. Always place them in realistic app context.
51
+
52
+ | Context | Layout | Reference |
53
+ |---------|--------|-----------|
54
+ | Document editor | Toolbar above content; `bg-muted/30` container; `Separator` between groups | ComponentShowcase → Toggle & ToggleGroup |
55
+ | Chart/settings | Label + inline controls; `rounded-lg border bg-muted/30 p-3` | ComponentShowcase → Chart settings |
56
+ | Standalone | Inline with related UI | ComponentShowcase → Standalone toggle |
57
+
58
+ **Canonical implementation:** `src/pages/ComponentShowcase.tsx` — Toggle & ToggleGroup section.
59
+
60
+ ## Quick Reference
61
+
62
+ 1. **Human task → component:** `docs/nqui-skills/HUMAN_GUIDE.md`
63
+ 2. **Main index:** `README.md` under `docs/components/` — full tables, prerequisites, layout patterns
64
+ 3. **Per-component:** `nqui-<name>.md` — import, examples, variants
65
+ 4. **Design system:** `docs/nqui-skills/nqui-design-system/SKILL.md` — sizing, **Card + ScrollArea flex scroll contract**
66
+
67
+ **Cursor:** `npx @nqlib/nqui init-cursor` syncs from `docs/nqui-skills/`.
68
+
69
+ ## Accessibility & touch (summary)
70
+
71
+ - **Focus:** After closing **Dialog** / **Sheet**, return focus to the trigger; don’t leave focus in the void (Radix helps — don’t fight it with extra `tabIndex`).
72
+ - **Keyboard:** Interactive components must be focusable and activatable without a mouse; see per-component docs and `nqui-shadcn` rules.
73
+ - **Touch:** Default control heights (h-6 / h-7 / h-8) align with dense desktop UI; for **touch-primary** surfaces, prefer **default/lg** and optional **`hit-area-*`** on small controls in padded rows (`nqui-checkbox.md`, `nqui-switch.md`).
74
+ - **Hover-only:** **Tooltip** / **HoverCard** are poor places for **required** information — no hover on touch. See `docs/components/nqui-tooltip.md`.
75
+
76
+ ## Card + ScrollArea (do not overflow the card)
77
+
78
+ When building **Card** + **ScrollArea** (or any **scroll inside flex**):
79
+
80
+ - Read **`docs/nqui-skills/nqui-design-system/SKILL.md`** → section **Card + ScrollArea (flex scroll contract)**.
81
+ - **Always** thread **`min-h-0`** on flex children from the height constraint down to **ScrollArea**.
82
+ - Do **not** rely on **`overflow-hidden`** on the outer **Card** alone without a proper **flex** + **`min-h-0`** chain (Card defaults **`overflow-visible`** for popovers).
83
+
84
+ ## Key Conventions
85
+
86
+ - React 18+ and 19 supported
87
+ - Control sizes: sm=h-6, default=h-7, lg=h-8
88
+ - Enhanced vs Core: default is enhanced; use Core* for plain
89
+ - Z-index: CSS vars from `src/styles/elevation.css` only
90
+
91
+ ## FrostedGlass sticky headers
92
+
93
+ `FrostedGlass` is only the blur layer. Pair it with a **second row** (`bg-background/40`, `relative z-[var(--z-content)]`) and ensure **content scrolls behind** the sticky header. Full detail: `docs/components/nqui-frosted-glass.md`. References: `AppLayout`, **Card** `stickyHeader`.
94
+
95
+ ## Hit area (optional pointer targets)
96
+
97
+ nqui ships [Bazza hit-area](https://bazza.dev/craft/2026/hit-area) utilities (`hit-area-4`, `hit-area-6`, axis variants, `hit-area-debug`). Use when a **small control sits in a padded cell or row** and you want taps in the padding to hit the control.
98
+
99
+ - Put utilities on the **same element** as **Checkbox** or **Switch** — not on a wrapper-only parent.
100
+ - **Opt-in** — dense toolbars can get overlapping targets if every control uses a large hit area.
101
+ - **Docs:** `docs/components/nqui-checkbox.md`, `nqui-switch.md`; examples: `src/pages/ComponentShowcase.tsx`.
@@ -1,21 +1,21 @@
1
1
  ---
2
2
  name: nqui-design-system
3
- description: Design system conventions for nqui component library. Use when creating or modifying nqui UI components to ensure sizing, spacing, and styling consistency.
3
+ description: Design system conventions for nqui component library. Use when creating or modifying nqui UI components (sizing, spacing, Card + ScrollArea flex scroll / min-h-0, grouped controls, density).
4
4
  ---
5
5
 
6
6
  # nqui Design System
7
7
 
8
- Guidelines for AI agents implementing or modifying nqui components. Follow these rules to maintain visual consistency.
8
+ Guidelines for AI agents and developers implementing or modifying nqui components. Follow these rules to maintain visual consistency.
9
9
 
10
10
  ## Control Size Scale
11
11
 
12
12
  All interactive controls (buttons, toggles, inputs, selects) use a unified scale:
13
13
 
14
- | Size | Height | Min Width | Use Case |
15
- |----------|--------|-----------|-----------------------------------|
16
- | `sm` | h-6 (24px) | min-w-6 | Compact UIs, dense tables, toolbars |
17
- | `default`| h-7 (28px) | min-w-7 | Standard forms, primary actions |
18
- | `lg` | h-8 (32px) | min-w-8 | Emphasis, secondary actions |
14
+ | Size | Height | Min Width | Use Case |
15
+ |------|--------|-----------|----------|
16
+ | `sm` | h-6 (24px) | min-w-6 | Compact UIs, dense tables, toolbars |
17
+ | `default` | h-7 (28px) | min-w-7 | Standard forms, primary actions |
18
+ | `lg` | h-8 (32px) | min-w-8 | Emphasis, secondary actions |
19
19
 
20
20
  ### Semantic Rule
21
21
 
@@ -85,7 +85,7 @@ Font: `--font-sans` (Inter Variable). Leading: `leading-normal` or `text-xs/rela
85
85
  - **Child borders** – Items: `border-0` (container provides the border)
86
86
  - **Dividers** – ToggleGroup: item borders (`border-foreground/20`) between items. Or `ToggleGroupSeparator` when `separator={false}`.
87
87
  - **Corners** – First item: rounded-l (or rounded-t vertical), last: rounded-r (or rounded-b)
88
- - **Several groups on one horizontal row** – `ButtonGroup`’s container is **`inline-flex`**, so multiple sibling groups in normal flow behave like **inline boxes** and align to **baseline**. Mixed content (labels vs icons vs `ButtonGroupText`) then produces inconsistent vertical alignment. Prefer an explicit row container: **`flex flex-wrap items-center gap-*`**, or **grid** columns—so you choose **cross-axis alignment** (`items-center`, `items-end`, etc.) instead of inheriting baseline alignment from inline layout.
88
+ - **Several groups on one horizontal row** – `ButtonGroup`’s container is `inline-flex`, so multiple sibling groups behave like inline boxes and align to **baseline**. Mixed content (labels vs icons vs `ButtonGroupText`) then looks vertically inconsistent. Prefer **`flex flex-wrap items-center gap-*`** or **grid** so you control cross-axis alignment (`items-center`, `items-end`) instead of baseline alignment.
89
89
 
90
90
  ## Toggle & ToggleGroup Visual Treatment (Visibility on Any Background)
91
91
 
@@ -94,28 +94,58 @@ Toggles and ToggleGroup items must remain visible on card, sidebar, and varied b
94
94
  | State | Default/Outline | Segmented (single select) |
95
95
  |-------|-----------------|---------------------------|
96
96
  | **Off** | `border border-input/60` (or `border-input`), `shadow-sm`, `bg-background/50` (or transparent) | Transparent |
97
- | **On** | `bg-secondary` + `nqui-button-gradient` + `nqui-button-shadow` (secondary-like layering) | `bg-primary` + gradient + shadow |
97
+ | **On** | `bg-secondary` + `nqui-button-gradient` + `nqui-button-shadow` | `bg-primary` + gradient + shadow |
98
98
  | **Active (pressed)** | `active:shadow-[inset_0_3px_5px_rgba(0,0,0,0.125)]` | Same |
99
99
 
100
100
  Never use flat `bg-muted` only for selected state; always add gradient + shadow for depth and visibility.
101
101
 
102
+ **Active label weight:** Toggle / ToggleGroup use `font-medium` when off and **`font-bold` when on** (`data-[state=on]`). TabsTrigger uses **`font-bold` when active** (`data-[state=active]`). **ButtonGroup** forces direct **`button` / `a` / select-trigger children to `font-normal`** (overrides Button’s `font-medium`); use **`font-bold` only** on the selected control via `aria-current="true"`, `aria-pressed="true"`, or `data-active`.
103
+
102
104
  ## Toolbar & In-Context Design
103
105
 
104
- **Rule:** Show controls in realistic app context, not isolated. Reference: `packages/nqui/src/pages/ComponentShowcase.tsx` (Toggle & ToggleGroup section).
106
+ **Rule:** Show controls in realistic app context, not isolated. Reference: `src/pages/ComponentShowcase.tsx` (Toggle & ToggleGroup section).
105
107
 
106
108
  | Context | Layout | Example |
107
109
  |---------|--------|---------|
108
- | Document editor | Toolbar above content area, `bg-muted/30` container, `Separator` between control groups | Bold/Italic/Underline \| Align Left/Center/Right |
109
- | Chart/settings panel | Label + inline controls, `rounded-lg border bg-muted/30 p-3` | Y-axis: Linear/Log; Size: S/M/L |
110
- | Standalone | Inline with related UI, not floating alone | Pin, Mute, single Toggle |
110
+ | Document editor | Toolbar above content, `bg-muted/30`, `Separator` between groups | Bold / Italic / Underline; align left / center / right |
111
+ | Chart/settings panel | Label + inline controls, `rounded-lg border bg-muted/30 p-3` | Y-axis Linear/Log; size S/M/L |
112
+ | Standalone | Inline with related UI | Pin, Mute, single Toggle |
111
113
 
112
114
  ## Bounded content (default UX)
113
115
 
114
- - **Rule:** Interactive surfaces should not **visually bleed** outside their box: prefer **ellipsis** (`truncate`), **line-clamp**, **controlled scroll**, or **wrapping** (`break-words` / `whitespace-normal`) instead of letting text or icons paint past padding in narrow layouts.
115
- - **Not universal:** Portals (dropdowns, popovers), **tooltips**, and **drag overlays** intentionally escape bounds. **Data tables** may use horizontal scroll. Choose per component.
116
- - **Flex gotcha:** `inline-flex` + icon + `whitespace-nowrap` + raw **string** children keeps an implicit **min-width: min-content**; parents need **`min-w-0`** (and often **`max-w-full`**) on the control and a truncating inner wrapper for long labels.
117
- - **Built-in helpers in nqui:** Shared `wrapInlineLabelTextNodes` + `min-w-0 max-w-full` on **Button**, **Toggle**, **TabsTrigger**, **Badge**, **ComboboxChip**; **SelectTrigger** uses **`min-w-0 max-w-full`** and **`min-w-0`** on the value slot with **`line-clamp-1`**. **Carousel** prev/next sit **inside** the carousel box so they don’t spill out of **Card** (override via `className` if you want outside arrows).
118
- - **Card:** **Card** uses **`min-w-0`** on shell + header/content/footer for flex/grid safety but keeps **`overflow-visible`** so overlays aren’t clipped; don’t rely on **`overflow-hidden`** on Card as a global catch-all unless you accept clipping dropdowns/focus.
116
+ - **Rule:** Interactive surfaces should not **visually bleed** outside their box: prefer **ellipsis** (`truncate`), **line-clamp**, **controlled scroll**, or **wrapping** instead of letting text or icons paint past padding in narrow layouts.
117
+ - **Not universal:** Portals (dropdowns, popovers), **tooltips**, and **drag overlays** intentionally escape bounds. **Data tables** may use horizontal scroll.
118
+ - **Flex gotcha:** `inline-flex` + icon + `whitespace-nowrap` + raw string children keeps implicit **min-width: min-content**; parents need **`min-w-0`** (and often **`max-w-full`**) on the control and a truncating inner wrapper for long labels.
119
+ - **Built-in helpers in nqui:** Shared `wrapInlineLabelTextNodes` + `min-w-0 max-w-full` on **Button**, **Toggle**, **TabsTrigger**, **Badge**, **ComboboxChip**; **SelectTrigger** uses `min-w-0 max-w-full` and `min-w-0` on the value slot with `line-clamp-1`. **Carousel** prev/next sit **inside** the carousel box so they don’t spill out of **Card** (override via `className` if you want outside arrows).
120
+ - **Card:** **Card** uses **`min-w-0`** on shell + header/content/footer for flex/grid safety but keeps **`overflow-visible`** so overlays aren’t clipped; don’t rely on **`overflow-hidden`** on Card as a global catch-all unless you accept clipping dropdowns/focus.
121
+
122
+ ## Card + ScrollArea (flex scroll contract)
123
+
124
+ **Symptom:** Content inside **Card** + **ScrollArea** overflows the card, ignores rounded corners, or **does not scroll** until someone adds `min-h-0` up the tree.
125
+
126
+ **Cause:** Flex items default to **`min-height: auto`**: they won’t shrink below content height, so the scroll region never gets a bounded height → **no scrollport**. Normal CSS, not a ScrollArea bug.
127
+
128
+ **Rules (every time you nest scrollable content in flex):**
129
+
130
+ 1. **Height chain:** From the page shell down to **ScrollArea**, every flex child that must shrink needs **`min-h-0`** (often with **`flex-1`** or **`flex-shrink`**).
131
+ 2. **Card root:** Keeps **`overflow-visible`** on purpose (dropdowns, popovers, focus rings). Do **not** use **`overflow-hidden`** on the outer **Card** alone as your only scroll fix — establish a **nested** scroll box.
132
+ 3. **Scrollable body:** Prefer **`CardContent`** (or a wrapper) with **`min-h-0 flex-1 overflow-hidden`**, then **ScrollArea** with **`className="min-h-0 h-full"`** or **`min-h-0 flex-1`** inside a **`flex flex-col min-h-0`** card.
133
+ 4. **Parent must constrain height:** e.g. `h-full`, `min-h-0`, or explicit `max-h-*` / `h-[...]`; otherwise “100%” has no reference.
134
+
135
+ **Reference implementations:** `Card` + **`stickyHeader`** in `src/components/ui/card.tsx`; `src/pages/ComponentShowcase.tsx` where ScrollArea sits in a bounded layout.
136
+
137
+ **Checklist before merging a scrollable card:**
138
+
139
+ - [ ] Flex column from page → card includes **`min-h-0`** where the tree shrinks.
140
+ - [ ] Card column is **`flex flex-col min-h-0`** (and **`h-full`** if filling a panel).
141
+ - [ ] Scroll wrapper: **`flex-1 min-h-0 overflow-hidden`**.
142
+ - [ ] **ScrollArea** has **`min-h-0`** and fills the wrapper (**`h-full`** / **`flex-1`**).
143
+
144
+ ## Density & visual hierarchy (product feel)
145
+
146
+ - **Density:** `size="sm"` and compact patterns (tables, sidebars) read as **dense**; default/lg and generous spacing read as **comfortable**. Don’t mix ad-hoc heights — use the **size scale** so density stays intentional.
147
+ - **Task priority:** One **primary** action per surface (full-color / high contrast). Secondary actions use **outline** / **secondary**; **tertiary** use **ghost** / muted text. Avoid multiple competing primaries.
148
+ - **Muted vs foreground:** Use **`text-muted-foreground`** for supporting labels, **`text-foreground`** for primary reading. Don’t gray out text that must be understood to complete a task.
119
149
 
120
150
  ## Customization
121
151
 
@@ -125,16 +155,16 @@ Never use flat `bg-muted` only for selected state; always add gradient + shadow
125
155
 
126
156
  ## Hit area utilities
127
157
 
128
- **Hit area** expands the pointer target; it does **not** replace control **size** (sm / default / lg). Use **opt-in** on **Checkbox** / **Switch** for padded rows or cells—not as a global default. Avoid large overlapping hit areas in dense toolbars. See **`SKILL.md`** (Hit area) in this folder and `packages/nqui/docs/components/nqui-checkbox.md` / `nqui-switch.md`.
158
+ **Hit area** expands the pointer target; it does **not** replace the **size** scale. Use **opt-in** on **Checkbox** / **Switch** in padded rows—not globally. See `docs/nqui-skills/nqui-components/SKILL.md` and `docs/components/nqui-checkbox.md` / `nqui-switch.md`.
129
159
 
130
160
  ## Files to Check for Consistency
131
161
 
132
- - `packages/nqui/src/components/ui/button.tsx`
133
- - `packages/nqui/src/components/ui/toggle.tsx`
134
- - `packages/nqui/src/components/ui/toggle-group.tsx`
135
- - `packages/nqui/src/components/ui/input.tsx`
136
- - `packages/nqui/src/components/ui/select.tsx`
137
- - `packages/nqui/src/components/ui/combobox.tsx`
162
+ - `src/components/ui/button.tsx`
163
+ - `src/components/ui/toggle.tsx`
164
+ - `src/components/ui/toggle-group.tsx`
165
+ - `src/components/ui/input.tsx`
166
+ - `src/components/ui/select.tsx`
167
+ - `src/components/ui/combobox.tsx`
138
168
 
139
169
  ## Anti-Patterns
140
170
 
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: nqui-install
3
+ description: Install and setup @nqlib/nqui. Use when the user wants to install nqui, set up a project, fix missing peers, or run setup commands. Execute these commands in the consumer project root.
4
+ ---
5
+
6
+ # nqui Install & Setup
7
+
8
+ **When to load:** User asks to install nqui, set up a new project, fix "module not found" or missing peer deps, or run setup.
9
+
10
+ **Action:** Run the relevant command(s) below in the **consumer project root**, in order when doing full setup.
11
+
12
+ ## 1. Install nqui + peers
13
+
14
+ **Minimal (icons only):**
15
+
16
+ ```bash
17
+ pnpm add @nqlib/nqui @hugeicons/react @hugeicons/core-free-icons
18
+ ```
19
+
20
+ (npm: `npm install @nqlib/nqui @hugeicons/react @hugeicons/core-free-icons`)
21
+
22
+ **Full (all optional components):**
23
+
24
+ ```bash
25
+ npx @nqlib/nqui install-peers
26
+ ```
27
+
28
+ Or manually:
29
+
30
+ ```bash
31
+ pnpm add @nqlib/nqui @hugeicons/react @hugeicons/core-free-icons cmdk @dnd-kit/core @dnd-kit/modifiers @dnd-kit/sortable @dnd-kit/utilities embla-carousel-react @tanstack/react-table react-day-picker date-fns sonner vaul react-resizable-panels
32
+ ```
33
+
34
+ ## 2. Setup CSS (required)
35
+
36
+ ```bash
37
+ npx @nqlib/nqui init-css
38
+ ```
39
+
40
+ Then add to main CSS (`app/globals.css` or `src/index.css`): `@import "@nqlib/nqui/styles";`
41
+
42
+ Or copy contents of `nqui/nqui-setup.css` to the top of main CSS.
43
+
44
+ ## 3. Cursor skills (optional)
45
+
46
+ ```bash
47
+ npx @nqlib/nqui init-cursor
48
+ ```
49
+
50
+ Copies `docs/nqui-skills` to `.cursor/nqui-skills/`, copies **`docs/components`** to **`.cursor/nqui-skills/components/`**, and may add rules. For skills only:
51
+
52
+ ```bash
53
+ npx @nqlib/nqui init-skills
54
+ ```
55
+
56
+ Use **`HUMAN_GUIDE.md`** for task-based wayfinding; **`COMPONENTS_INDEX.md`** to pick **one** `nqui-*.md` at a time (saves tokens).
57
+
58
+ ## File locations (after install)
59
+
60
+ - Task → docs: `node_modules/@nqlib/nqui/docs/nqui-skills/HUMAN_GUIDE.md`
61
+ - Docs index: `node_modules/@nqlib/nqui/docs/components/README.md`
62
+ - Per component: `node_modules/@nqlib/nqui/docs/components/nqui-<name>.md`
63
+ - Skills (source in repo): `docs/nqui-skills/` inside the package
64
+ - Check setup: `npx nqui-setup` (or `npx @nqlib/nqui setup`)
65
+