@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
|
@@ -11,9 +11,31 @@ import { Checkbox } from "@nqlib/nqui"
|
|
|
11
11
|
## Basic
|
|
12
12
|
|
|
13
13
|
```tsx
|
|
14
|
-
|
|
14
|
+
const [checked, setChecked] = useState(false)
|
|
15
|
+
|
|
16
|
+
<Checkbox checked={checked} onCheckedChange={setChecked}>Accept terms</Checkbox>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## With Label
|
|
20
|
+
|
|
21
|
+
Checkbox automatically wraps in a label when children are provided:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
<Checkbox>Accept terms</Checkbox>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Gap
|
|
28
|
+
|
|
29
|
+
Control the gap between checkbox and label:
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
<Checkbox gap={2}>Compact gap (8px)</Checkbox>
|
|
33
|
+
<Checkbox gap={3}>Default gap (12px)</Checkbox>
|
|
34
|
+
<Checkbox gap={4}>Loose gap (16px)</Checkbox>
|
|
15
35
|
```
|
|
16
36
|
|
|
37
|
+
Options: `0`, `1`, `2`, `3`, `4` (maps to Tailwind gap-0 through gap-4).
|
|
38
|
+
|
|
17
39
|
## Variants
|
|
18
40
|
|
|
19
41
|
```tsx
|
|
@@ -27,8 +49,23 @@ import { Checkbox } from "@nqlib/nqui"
|
|
|
27
49
|
<Checkbox checked="indeterminate" onCheckedChange={...} />
|
|
28
50
|
```
|
|
29
51
|
|
|
52
|
+
## Hit area (expanded pointer target)
|
|
53
|
+
|
|
54
|
+
nqui ships [Bazza **hit-area** utilities](https://bazza.dev/craft/2026/hit-area) in library CSS (`hit-area-*`, `hit-area-x-*`, `hit-area-debug`, etc.). They extend the clickable region with a `::before` layer without changing layout.
|
|
55
|
+
|
|
56
|
+
**Enhanced checkbox:** The checkmark is drawn with `::after` on the control root so `::before` stays free for `hit-area-*` on the **same** element. Add a class when you want a larger target (e.g. padded table cells):
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
<Checkbox className="hit-area-6" checked={rowSelected} onCheckedChange={...} aria-label="Select row" />
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Label hover pill:** `.checkbox-animated-label::before` is on the **label** wrapper only; it does not conflict with `hit-area-*` on the checkbox button.
|
|
63
|
+
|
|
64
|
+
**Without hit-area:** You can still wrap the control in `<span className="relative hit-area-6">` if you prefer the expanded area on a wrapper.
|
|
65
|
+
|
|
30
66
|
## Notes
|
|
31
67
|
|
|
68
|
+
- Implementation: **`packages/nqui/src/components/ui/checkbox.tsx`** (enhanced + core in one module).
|
|
32
69
|
- Injects `<style>` at mount. Use client-only guard for SSR.
|
|
33
70
|
- Square and round share the same animation (pulse + checkmark scale); round has no SVG filters.
|
|
34
71
|
- Use `CoreCheckbox` for plain Radix checkbox.
|
|
@@ -10,10 +10,12 @@ import { ColorSlider } from "@nqlib/nqui"
|
|
|
10
10
|
|
|
11
11
|
## Types
|
|
12
12
|
|
|
13
|
+
Built on **`Slider`** from `ui/slider` (white thumb + shadow). For **non-controlled** demos, prefer **`defaultValue`** so the thumb stays draggable.
|
|
14
|
+
|
|
13
15
|
```tsx
|
|
14
|
-
<ColorSlider sliderType="hue"
|
|
15
|
-
<ColorSlider sliderType="saturation"
|
|
16
|
-
<ColorSlider sliderType="lightness"
|
|
16
|
+
<ColorSlider sliderType="hue" defaultValue={[240]} onValueChange={setVal} min={0} max={360} />
|
|
17
|
+
<ColorSlider sliderType="saturation" defaultValue={[0.5]} onValueChange={setVal} min={0} max={1} step={0.01} />
|
|
18
|
+
<ColorSlider sliderType="lightness" defaultValue={[0.6]} onValueChange={setVal} min={0} max={1} step={0.01} />
|
|
17
19
|
```
|
|
18
20
|
|
|
19
21
|
## Custom
|
|
@@ -1,73 +1,94 @@
|
|
|
1
1
|
# nqui Combobox
|
|
2
2
|
|
|
3
|
-
> **Searchable** select
|
|
3
|
+
> **Searchable** select (Base UI). User types to filter options. Single or multiple selection.
|
|
4
4
|
|
|
5
5
|
## When to Use
|
|
6
6
|
|
|
7
|
-
- **Selection:** Single or multiple
|
|
8
|
-
- **Key feature:**
|
|
9
|
-
- **Options:** Many
|
|
7
|
+
- **Selection:** Single (default) or multiple (`multiple` on root)
|
|
8
|
+
- **Key feature:** Filter list by typing in the input
|
|
9
|
+
- **Options:** Many rows; use **`items`** on `Combobox` + render prop on `ComboboxList` for built-in filtering
|
|
10
10
|
|
|
11
|
-
**Choose Combobox when:**
|
|
11
|
+
**Choose Combobox when:** Users need search. Use **Select** when a plain dropdown is enough.
|
|
12
12
|
|
|
13
13
|
## Import
|
|
14
14
|
|
|
15
15
|
```tsx
|
|
16
16
|
import {
|
|
17
|
-
Combobox,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
Combobox,
|
|
18
|
+
ComboboxInput,
|
|
19
|
+
ComboboxContent,
|
|
20
|
+
ComboboxList,
|
|
21
|
+
ComboboxItem,
|
|
22
|
+
ComboboxEmpty,
|
|
23
|
+
ComboboxGroup,
|
|
24
|
+
ComboboxLabel,
|
|
25
|
+
ComboboxSeparator,
|
|
26
|
+
ComboboxCollection,
|
|
27
|
+
ComboboxChips,
|
|
28
|
+
ComboboxChip,
|
|
29
|
+
ComboboxChipsInput,
|
|
30
|
+
ComboboxTrigger,
|
|
31
|
+
ComboboxValue,
|
|
32
|
+
ComboboxClear,
|
|
33
|
+
useComboboxAnchor,
|
|
21
34
|
} from "@nqlib/nqui"
|
|
22
35
|
```
|
|
23
36
|
|
|
24
|
-
##
|
|
37
|
+
## Single selection + type-to-filter (recommended)
|
|
38
|
+
|
|
39
|
+
Pass **`items`** to `Combobox` and use a **render function** as the only child of `ComboboxList`. Place **`ComboboxEmpty`** next to `ComboboxList` (both under `ComboboxContent`), not inside `ComboboxList` alongside the function.
|
|
25
40
|
|
|
26
41
|
```tsx
|
|
27
|
-
|
|
42
|
+
const fruits = ["Apple", "Banana", "Cherry", "Date", "Elderberry"]
|
|
43
|
+
|
|
44
|
+
<Combobox items={fruits}>
|
|
28
45
|
<ComboboxInput placeholder="Search..." />
|
|
29
46
|
<ComboboxContent>
|
|
47
|
+
<ComboboxEmpty>No results found.</ComboboxEmpty>
|
|
30
48
|
<ComboboxList>
|
|
31
|
-
{
|
|
32
|
-
<ComboboxItem key={item
|
|
33
|
-
|
|
49
|
+
{(item) => (
|
|
50
|
+
<ComboboxItem key={item} value={item}>
|
|
51
|
+
{item}
|
|
52
|
+
</ComboboxItem>
|
|
53
|
+
)}
|
|
34
54
|
</ComboboxList>
|
|
35
|
-
<ComboboxEmpty>No results</ComboboxEmpty>
|
|
36
55
|
</ComboboxContent>
|
|
37
56
|
</Combobox>
|
|
38
57
|
```
|
|
39
58
|
|
|
40
|
-
##
|
|
59
|
+
## Static list (no `items` filter)
|
|
41
60
|
|
|
42
|
-
|
|
43
|
-
<Combobox showClear ... />
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Multi-select chips
|
|
61
|
+
You can still render `ComboboxItem` children manually when you control filtering yourself.
|
|
47
62
|
|
|
48
63
|
```tsx
|
|
49
|
-
<Combobox
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
64
|
+
<Combobox>
|
|
65
|
+
<ComboboxInput placeholder="Search..." />
|
|
66
|
+
<ComboboxContent>
|
|
67
|
+
<ComboboxList>
|
|
68
|
+
<ComboboxItem value="a">A</ComboboxItem>
|
|
69
|
+
<ComboboxItem value="b">B</ComboboxItem>
|
|
70
|
+
</ComboboxList>
|
|
71
|
+
</ComboboxContent>
|
|
54
72
|
</Combobox>
|
|
55
73
|
```
|
|
56
74
|
|
|
57
|
-
##
|
|
75
|
+
## Clear button
|
|
58
76
|
|
|
59
77
|
```tsx
|
|
60
|
-
<
|
|
61
|
-
<ComboboxGroup>
|
|
62
|
-
<ComboboxLabel>Group A</ComboboxLabel>
|
|
63
|
-
<ComboboxItem value="a">A</ComboboxItem>
|
|
64
|
-
</ComboboxGroup>
|
|
65
|
-
<ComboboxSeparator />
|
|
66
|
-
...
|
|
67
|
-
</ComboboxCollection>
|
|
78
|
+
<ComboboxInput showClear placeholder="Search..." />
|
|
68
79
|
```
|
|
69
80
|
|
|
81
|
+
## Multiple selection
|
|
82
|
+
|
|
83
|
+
Use **`multiple`** on `Combobox` (see [Base UI Combobox](https://base-ui.com/react/components/combobox)). Combine with **`ComboboxChips`**, **`ComboboxChip`**, **`ComboboxChipsInput`** as needed for chip UI.
|
|
84
|
+
|
|
85
|
+
## Implementation
|
|
86
|
+
|
|
87
|
+
- **Source:** `packages/nqui/src/components/ui/combobox.tsx`
|
|
88
|
+
- **Public API:** exported from `@nqlib/nqui` (same as `CoreCombobox*` aliases in the barrel if you need the unprefixed base re-exports)
|
|
89
|
+
- **Styling:** Input group uses injected CSS once per page (`nqui-combobox-styles-v1`) for trigger depth/shadow; component is `"use client"`.
|
|
90
|
+
|
|
70
91
|
## Notes
|
|
71
92
|
|
|
72
|
-
-
|
|
73
|
-
-
|
|
93
|
+
- **`useComboboxAnchor`:** ref for anchoring `ComboboxContent` when using chips / custom layout.
|
|
94
|
+
- **Dropdown items:** spacing/hover treatment aligns with **Select** (`SelectItem`-style density).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nqui Drawer
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> **Vaul** drawer. **DrawerContent** keeps an **inset rounded card** (`before:bg-card`, `before:inset-2`, `before:rounded-xl`) so the panel does not read as a full-bleed slab—surface follows **`card`** tokens in both themes.
|
|
4
4
|
|
|
5
5
|
## Import
|
|
6
6
|
|
|
@@ -18,13 +18,56 @@ import { RadioGroup, RadioGroupItem } from "@nqlib/nqui"
|
|
|
18
18
|
|
|
19
19
|
## Basic
|
|
20
20
|
|
|
21
|
+
RadioGroupItem now automatically wraps the radio button with a label when children are provided:
|
|
22
|
+
|
|
21
23
|
```tsx
|
|
24
|
+
const [value, setValue] = useState("a")
|
|
25
|
+
|
|
22
26
|
<RadioGroup value={value} onValueChange={setValue}>
|
|
23
|
-
<RadioGroupItem value="a"
|
|
24
|
-
<RadioGroupItem value="b"
|
|
27
|
+
<RadioGroupItem value="a">Option A</RadioGroupItem>
|
|
28
|
+
<RadioGroupItem value="b">Option B</RadioGroupItem>
|
|
25
29
|
</RadioGroup>
|
|
26
30
|
```
|
|
27
31
|
|
|
32
|
+
## With Complex Content
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
<RadioGroup value={value} onValueChange={setValue}>
|
|
36
|
+
<RadioGroupItem value="email">
|
|
37
|
+
<div>
|
|
38
|
+
<div className="font-medium">Email</div>
|
|
39
|
+
<div className="text-sm text-muted-foreground">Receive notifications via email</div>
|
|
40
|
+
</div>
|
|
41
|
+
</RadioGroupItem>
|
|
42
|
+
<RadioGroupItem value="sms">
|
|
43
|
+
<div>
|
|
44
|
+
<div className="font-medium">SMS</div>
|
|
45
|
+
<div className="text-sm text-muted-foreground">Receive notifications via SMS</div>
|
|
46
|
+
</div>
|
|
47
|
+
</RadioGroupItem>
|
|
48
|
+
</RadioGroup>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Spacing
|
|
52
|
+
|
|
53
|
+
Control the gap between radio items with the `gap` prop on RadioGroup:
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
<RadioGroup gap={0}>No gap</RadioGroup>
|
|
57
|
+
<RadioGroup gap={1}>4px gap</RadioGroup>
|
|
58
|
+
<RadioGroup gap={2}>Compact (8px)</RadioGroup>
|
|
59
|
+
<RadioGroup gap={3}>Default (12px)</RadioGroup>
|
|
60
|
+
<RadioGroup gap={4}>Loose (16px)</RadioGroup>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Control the gap between radio button and label with the `spacing` prop on RadioGroupItem:
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
<RadioGroupItem value="a" spacing="compact">Tight spacing (8px)</RadioGroupItem>
|
|
67
|
+
<RadioGroupItem value="b" spacing="default">Default spacing (12px)</RadioGroupItem>
|
|
68
|
+
<RadioGroupItem value="c" spacing="comfortable">Loose spacing (16px)</RadioGroupItem>
|
|
69
|
+
```
|
|
70
|
+
|
|
28
71
|
## Variants
|
|
29
72
|
|
|
30
73
|
```tsx
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nqui ScrollArea
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Default export is **EnhancedScrollArea** (fade mask, orientation). Underlying primitive: **`CoreScrollArea`** / `ScrollBar` from **`ui/scroll-area`**. Core scrollbar uses a **thinner** track/thumb (drawer-like).
|
|
4
4
|
|
|
5
5
|
## Import
|
|
6
6
|
|
|
@@ -48,6 +48,6 @@ import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGr
|
|
|
48
48
|
|
|
49
49
|
## Notes
|
|
50
50
|
|
|
51
|
-
-
|
|
51
|
+
- **Content:** FrostedGlass + popover surface; **items** use relaxed row spacing (hover `accent`, margins) for dropdown parity with **Combobox** list items.
|
|
52
52
|
- Use `SelectScrollUpButton` / `SelectScrollDownButton` for long lists.
|
|
53
|
-
-
|
|
53
|
+
- **`CoreSelect*`** for the same primitives without the enhanced trigger chrome (re-exported from the same `ui/select` module).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nqui Sheet
|
|
2
2
|
|
|
3
|
-
> Side panel.
|
|
3
|
+
> Side panel (Radix **Dialog** pattern). **SheetContent** uses an **inset card** panel: transparent outer shell + `before:bg-card` block inset with **rounded corners** (matches drawer-style “card floating in the viewport”). **No edge borders** on the sheet shell (divider lines removed in favor of the card shape).
|
|
4
4
|
|
|
5
5
|
## Import
|
|
6
6
|
|
|
@@ -14,3 +14,16 @@ import { Slider } from "@nqlib/nqui"
|
|
|
14
14
|
<Slider value={[50]} onValueChange={([v]) => setVal(v)} />
|
|
15
15
|
<Slider value={[20, 80]} onValueChange={setRange} />
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## Sizes
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
<Slider size="sm" defaultValue={[40]} />
|
|
22
|
+
<Slider size="default" defaultValue={[40]} />
|
|
23
|
+
<Slider size="lg" defaultValue={[40]} />
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Notes
|
|
27
|
+
|
|
28
|
+
- **Thumb:** white, rounded-full, subtle shadow (aligned with **Switch** thumb language).
|
|
29
|
+
- **`size`:** `sm` | `default` | `lg` (control scale heights).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nqui Spinner
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Dual-arc loader (primary **`linearGradient`** strokes, rotating shell). Keyframes live in **`packages/nqui/src/index.css`** (`.nqui-spinner-*`).
|
|
4
4
|
|
|
5
5
|
## Import
|
|
6
6
|
|
|
@@ -14,3 +14,8 @@ import { Spinner } from "@nqlib/nqui"
|
|
|
14
14
|
<Spinner />
|
|
15
15
|
<Spinner className="size-6" />
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## Notes
|
|
19
|
+
|
|
20
|
+
- Root is a `div` with `role="status"` and `aria-label="Loading"`.
|
|
21
|
+
- Strokes use `var(--primary)` and `color-mix(in oklch, var(--primary) …, white)` so light/dark themes stay on-brand.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nqui Switch
|
|
2
2
|
|
|
3
|
-
> Toggle switch.
|
|
3
|
+
> Toggle switch. **Radix** primitive with **size** variants and **capsule thumb** (white, shadow). Sizes align with control scale: `sm` / `default` / `lg`.
|
|
4
4
|
|
|
5
5
|
## Import
|
|
6
6
|
|
|
@@ -13,3 +13,25 @@ import { Switch } from "@nqlib/nqui"
|
|
|
13
13
|
```tsx
|
|
14
14
|
<Switch checked={checked} onCheckedChange={setChecked} />
|
|
15
15
|
```
|
|
16
|
+
|
|
17
|
+
## Sizes
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
<Switch size="sm" />
|
|
21
|
+
<Switch size="default" />
|
|
22
|
+
<Switch size="lg" />
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Hit area
|
|
26
|
+
|
|
27
|
+
The switch root has no `::before` styling, so you can add [hit-area utilities](https://bazza.dev/craft/2026/hit-area) on the same element:
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
<Switch className="hit-area-4" id="notifications" />
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Use sparingly in dense toolbars so expanded targets do not overlap.
|
|
34
|
+
|
|
35
|
+
## Notes
|
|
36
|
+
|
|
37
|
+
- Thumb travel and track sizes are fixed per `size`; overriding height on the root without matching thumb classes may look off.
|
|
@@ -31,5 +31,15 @@ import { Tabs, TabsList, TabsTrigger, TabsContent } from "@nqlib/nqui"
|
|
|
31
31
|
|
|
32
32
|
## Notes
|
|
33
33
|
|
|
34
|
-
- Sliding indicator
|
|
34
|
+
- **Sliding indicator:** Requires `position: relative` on TabsList container (handled automatically by the component).
|
|
35
|
+
- **Responsive behavior:** On small screens, TabsList can overflow horizontally. Use `overflow-x-auto` on parent if needed.
|
|
36
|
+
- **Container requirements:** For the sliding indicator to work correctly, the TabsList container needs:
|
|
37
|
+
```css
|
|
38
|
+
.sliding-indicator-container {
|
|
39
|
+
position: relative;
|
|
40
|
+
overflow: hidden;
|
|
41
|
+
min-width: 0;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
- **Resize handling:** The indicator recalculates position on window resize (built-in).
|
|
35
45
|
- Use `EnhancedTabsList` props for additional customization.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nqui Toaster
|
|
2
2
|
|
|
3
|
-
> Toast notifications (sonner).
|
|
3
|
+
> Toast notifications via **Sonner**. Default toast is **pill-shaped**; default **normal** toast uses **inverted** surface (dark fill in light theme, light fill in dark theme) using `--foreground` / `--background`. Implemented in **`packages/nqui/src/components/ui/sonner.tsx`** (`Toaster`). Compatibility aliases: `EnhancedSonner`, `CoreToaster` → same component.
|
|
4
4
|
|
|
5
5
|
## Import
|
|
6
6
|
|
|
@@ -42,3 +42,7 @@ toast.promise(fetchData(), {
|
|
|
42
42
|
toast.success("Msg", { duration: 5000 })
|
|
43
43
|
// Toaster: position, richColors, etc.
|
|
44
44
|
```
|
|
45
|
+
|
|
46
|
+
## Notes
|
|
47
|
+
|
|
48
|
+
- **Subpath import:** `@nqlib/nqui/sonner` re-exports the same `Toaster`.
|
|
@@ -230,15 +230,57 @@ If a version had bugs (e.g. init-cursor routed to wrong script, skills not worki
|
|
|
230
230
|
npm deprecate @nqlib/nqui@0.4.1 "Use 0.4.2 instead. See changelog."
|
|
231
231
|
```
|
|
232
232
|
|
|
233
|
-
4. **Unpublish** (rare, npm restrictions apply):
|
|
234
|
-
- Must be within 72 hours of publish
|
|
235
|
-
- No other packages can depend on it
|
|
236
|
-
- `npm unpublish @nqlib/nqui@0.4.1 --force`
|
|
233
|
+
4. **Unpublish** (rare, npm restrictions apply): See [Unpublishing](#unpublishing) below.
|
|
237
234
|
|
|
238
235
|
**Recommendation:** Usually deprecate + publish patch. Unpublish only for security issues.
|
|
239
236
|
|
|
240
237
|
---
|
|
241
238
|
|
|
239
|
+
## Unpublishing
|
|
240
|
+
|
|
241
|
+
### npmjs.com
|
|
242
|
+
|
|
243
|
+
**Rules:**
|
|
244
|
+
- **Within 72 hours of publish**: You can unpublish. The version is then available for re-publish.
|
|
245
|
+
- **After 72 hours**: Unpublish is disallowed. Versions are permanently locked. Use deprecation instead.
|
|
246
|
+
|
|
247
|
+
**Unpublish a specific version** (within 72 hours):
|
|
248
|
+
```bash
|
|
249
|
+
cd packages/nqui
|
|
250
|
+
npm unpublish @nqlib/nqui@0.4.1 --force --registry=https://registry.npmjs.com
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Unpublish entire package** (within 72 hours, removes all versions):
|
|
254
|
+
```bash
|
|
255
|
+
npm unpublish @nqlib/nqui --force --registry=https://registry.npmjs.com
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**After 72 hours – deprecate instead:**
|
|
259
|
+
```bash
|
|
260
|
+
npm deprecate @nqlib/nqui@0.4.1 "Superseded by 0.4.2. Use npm install @nqlib/nqui@0.4.2"
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### GitHub Packages
|
|
264
|
+
|
|
265
|
+
**Rules:**
|
|
266
|
+
- You can delete any version at any time.
|
|
267
|
+
- Deleted versions can be re-published (unlike npm).
|
|
268
|
+
|
|
269
|
+
**Delete via GitHub UI:**
|
|
270
|
+
1. Go to your repo → **Packages** (right sidebar) or `https://github.com/ORG/REPO/packages`
|
|
271
|
+
2. Click the package `nqui`
|
|
272
|
+
3. **Manage package** → **Delete package** (entire package) or **Manage versions** → delete specific versions
|
|
273
|
+
|
|
274
|
+
**Delete via GitHub API** (for automation):
|
|
275
|
+
```bash
|
|
276
|
+
# Requires GITHUB_TOKEN with delete:packages
|
|
277
|
+
curl -X DELETE -H "Authorization: token $GITHUB_TOKEN" \
|
|
278
|
+
"https://api.github.com/orgs/nqlib/packages/npm/nqui/versions/VERSION_ID"
|
|
279
|
+
```
|
|
280
|
+
(Get `VERSION_ID` from the package page or API.)
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
242
284
|
## Version Management
|
|
243
285
|
|
|
244
286
|
The `npm version` command automatically:
|
|
@@ -0,0 +1,102 @@
|
|
|
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.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# nqui Components Guide
|
|
7
|
+
|
|
8
|
+
Reference `packages/nqui/docs/components/README.md` for the full component index and implementation rules.
|
|
9
|
+
|
|
10
|
+
## Quick Reference
|
|
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
|
|
15
|
+
|
|
16
|
+
## App Design Rule: Inline Selection → ToggleGroup
|
|
17
|
+
|
|
18
|
+
When designing app UI (toolbars, headers, inline controls):
|
|
19
|
+
|
|
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** | - |
|
|
26
|
+
|
|
27
|
+
**Rule:** Inline/toolbar selection = ToggleGroup. Use RadioGroup only for form context (settings page, modal form, stacked list).
|
|
28
|
+
|
|
29
|
+
## App Design Rule: Context-First (Toolbar in Real Environment)
|
|
30
|
+
|
|
31
|
+
**Rule:** Never show Toggle/ToggleGroup/ButtonGroup in isolation. Always place them in realistic app context.
|
|
32
|
+
|
|
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 |
|
|
38
|
+
|
|
39
|
+
**Canonical implementation:** `packages/nqui/src/pages/ComponentShowcase.tsx` — Toggle & ToggleGroup section.
|
|
40
|
+
|
|
41
|
+
## Design System Conventions
|
|
42
|
+
|
|
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/`.
|
|
44
|
+
|
|
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
|
+
### Component Naming
|
|
62
|
+
- Default exports are the enhanced/polished variants; use **Core\*** for plain primitives
|
|
63
|
+
- Implementations are consolidated under **`ui/`** (not separate `custom/enhanced-*` per component for Button, Badge, Checkbox, Select, Combobox, Sonner)
|
|
64
|
+
- File names: kebab-case
|
|
65
|
+
- Component names: PascalCase
|
|
66
|
+
|
|
67
|
+
### Hit area (optional)
|
|
68
|
+
|
|
69
|
+
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.
|
|
70
|
+
|
|
71
|
+
## Key Dependencies
|
|
72
|
+
|
|
73
|
+
Required peer dependencies:
|
|
74
|
+
- `@hugeicons/react`
|
|
75
|
+
- `@hugeicons/core-free-icons`
|
|
76
|
+
|
|
77
|
+
Optional:
|
|
78
|
+
- `next-themes` - for theme toggle
|
|
79
|
+
- `tw-animate-css` - for animations
|
|
80
|
+
|
|
81
|
+
## Installation & Setup
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Quick setup
|
|
85
|
+
npx @nqlib/nqui init-css
|
|
86
|
+
|
|
87
|
+
# App setup with sidebar
|
|
88
|
+
npx @nqlib/nqui init-css --sidebar
|
|
89
|
+
|
|
90
|
+
# Install peer dependencies
|
|
91
|
+
npx @nqlib/nqui install-peers
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## CSS Variables
|
|
95
|
+
|
|
96
|
+
All components use CSS variables. Key ones:
|
|
97
|
+
- `--background`, `--foreground`
|
|
98
|
+
- `--muted`, `--muted-foreground`
|
|
99
|
+
- `--accent`, `--accent-foreground`
|
|
100
|
+
- `--border`, `--ring`
|
|
101
|
+
- `--primary`, `--primary-foreground`
|
|
102
|
+
- `--destructive`, `--destructive-foreground`
|