@nextlyhq/ui 0.0.2-alpha.35 → 0.0.2-alpha.39

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/README.md CHANGED
@@ -31,7 +31,7 @@ pnpm add react react-dom lucide-react
31
31
 
32
32
  ## Setup
33
33
 
34
- The package ships two CSS entry points. Pick one:
34
+ The package ships three CSS entry points. Pick one:
35
35
 
36
36
  **Zero config — pre-compiled bundle**
37
37
 
@@ -58,10 +58,10 @@ utilities the components use:
58
58
  @source "../node_modules/@nextlyhq/ui/dist";
59
59
  ```
60
60
 
61
- `theme.css` defines the tokens as complete OKLCH color values (`--background`, `--primary`,
62
- `--border`, …) with `@theme inline` mappings and the dark-mode overrides. Reference tokens
63
- directly (`var(--primary)`) — never wrap them in `hsl()`. The exported `uiPreset` remains
64
- available as a Tailwind v3 preset.
61
+ `theme.css` defines the tokens as complete OKLCH color values (`--nx-background`, `--nx-primary`,
62
+ `--nx-border`, …) with `@theme inline` mappings and the dark-mode overrides. Reference tokens
63
+ directly (`var(--nx-primary)`) — never wrap them in `hsl()`. `uiPreset` remains available
64
+ as a Tailwind v3 preset from `@nextlyhq/ui/tailwind-preset`.
65
65
 
66
66
  > Inside a Nextly admin plugin you need neither import — the admin already provides the
67
67
  > tokens. See the [**Plugin UI authoring guide**](./docs/plugin-ui-authoring.md).
@@ -77,15 +77,81 @@ available as a Tailwind v3 preset.
77
77
  **Feedback:** `Spinner`, `Toaster` (with `toast()` helper)
78
78
  **Tables:** `Table` primitives, `ResponsiveTable`, `TableSearch`, `TablePagination`, `TableSkeleton`, `TableEmpty`, `TableError`, `TableLoading`
79
79
  **Providers:** `PortalProvider`, `usePortalContainer`
80
- **Utilities:** `cn`, `uiPreset`
80
+
81
+ > Which of these carry a stability guarantee is recorded in
82
+ > [STABILITY.md](https://github.com/nextlyhq/nextly/blob/main/packages/ui/STABILITY.md). A component becomes `@public` once a first-party
83
+ > plugin depends on it; everything else is `@experimental` and may change in any
84
+ > release.
85
+
86
+ **Utilities:** `cn` (from `@nextlyhq/ui/utils`), `uiPreset` (from `@nextlyhq/ui/tailwind-preset`)
87
+
88
+ > Both ship from their own subpaths rather than the root: the root bundle is
89
+ > published with `"use client"`, and neither of these contains a React runtime,
90
+ > so a server component or a Tailwind config can import them safely.
91
+
92
+ ## Stylesheets
93
+
94
+ | Import | Use when |
95
+ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
96
+ | `@nextlyhq/ui/styles.css` | The app is yours end to end. Styles the whole document, Tailwind preflight included. |
97
+ | `@nextlyhq/ui/styles.scoped.css` | Dropping a few components into an existing app. Every rule is confined to `.nextly-ui`, so the rest of the page keeps its own styles. |
98
+ | `@nextlyhq/ui/theme.css` | You compile Tailwind yourself and want the token contract only. |
99
+
100
+ The scoped sheet needs a wrapper element, and dark mode goes on the same element:
101
+
102
+ ```tsx
103
+ import "@nextlyhq/ui/styles.scoped.css";
104
+
105
+ <div className="nextly-ui">
106
+ <Button>Save</Button>
107
+ </div>;
108
+ ```
109
+
110
+ It keeps preflight rather than dropping it — these components are designed against a
111
+ normalised baseline — but confines it to the wrapper, so your headings, lists and form
112
+ controls outside it are untouched. Three things CSS resolves globally are namespaced
113
+ along with the selectors, so the sheet cannot reach outside the wrapper through them
114
+ either: animation names (it will not displace a `spin` or `fade-in` you define),
115
+ Tailwind's internal `--tw-*` registrations, and the ancestor classes `dark:` and
116
+ `group-*:` variants look for. Dark mode is therefore driven by the wrapper, not by a
117
+ `dark` class higher up your page.
118
+
119
+ ### Overlays need a portal container
120
+
121
+ AlertDialog, Command, Dialog, DropdownMenu, Popover, Select, Sheet and Tooltip render
122
+ their overlay through a portal, which defaults to `document.body` — outside the wrapper,
123
+ where the scoped rules and tokens do not reach. Triggers would look right and the menus
124
+ they open would not. Point them back inside with `PortalProvider`:
125
+
126
+ ```tsx
127
+ import { useState } from "react";
128
+ import { PortalProvider } from "@nextlyhq/ui";
129
+ import "@nextlyhq/ui/styles.scoped.css";
130
+
131
+ function Kit({ children }: { children: React.ReactNode }) {
132
+ const [container, setContainer] = useState<HTMLElement | null>(null);
133
+
134
+ return (
135
+ <div className="nextly-ui" ref={setContainer}>
136
+ <PortalProvider container={container}>{children}</PortalProvider>
137
+ </div>
138
+ );
139
+ }
140
+ ```
141
+
142
+ A callback ref rather than `useRef` because the container has to be a state value: on the
143
+ first render it is still `null`, and the overlays need a re-render once the element exists.
144
+
145
+ This does not apply to `styles.css`, where the rules are document-wide and
146
+ `document.body` is already covered.
81
147
 
82
148
  ## Compatibility
83
149
 
84
- | Tool | Version |
85
- | -------------- | ---------------------------------------------------------------- |
86
- | React | 18 or 19 |
87
- | Tailwind CSS | 4+ (the `uiPreset` JS export also works as a Tailwind v3 preset) |
88
- | `lucide-react` | 0.400+ |
150
+ | Tool | Version |
151
+ | -------------- | ---------------------------------------------------------------------- |
152
+ | React | 18 or 19 |
153
+ | Tailwind CSS | 4+ (`@nextlyhq/ui/tailwind-preset` also works as a Tailwind v3 preset) |
154
+ | `lucide-react` | 0.400+ |
89
155
 
90
156
  ## Documentation
91
157