@navecss/base-ui 0.2.0 → 0.3.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 (80) hide show
  1. package/README.md +69 -7
  2. package/dist/accordion/index.js +0 -1
  3. package/dist/alert-dialog/index.js +0 -1
  4. package/dist/autocomplete/index.js +0 -1
  5. package/dist/avatar/index.js +0 -1
  6. package/dist/button/index.js +0 -1
  7. package/dist/checkbox/index.js +0 -1
  8. package/dist/checkbox-group/index.js +0 -1
  9. package/dist/collapsible/index.js +0 -1
  10. package/dist/combobox/index.js +0 -1
  11. package/dist/combobox/parts.generated.d.ts +0 -2
  12. package/dist/combobox/parts.generated.js +0 -1
  13. package/dist/context-menu/index.js +0 -1
  14. package/dist/css.d.ts +1 -0
  15. package/dist/dialog/index.js +0 -1
  16. package/dist/field/index.js +0 -1
  17. package/dist/fieldset/index.js +0 -1
  18. package/dist/form/index.js +0 -1
  19. package/dist/index.js +0 -1
  20. package/dist/input/index.js +0 -1
  21. package/dist/menu/index.js +0 -1
  22. package/dist/menubar/index.js +0 -1
  23. package/dist/meter/index.js +0 -1
  24. package/dist/navigation-menu/index.js +0 -1
  25. package/dist/number-field/index.js +0 -1
  26. package/dist/part.d.ts +0 -5
  27. package/dist/popover/index.js +0 -1
  28. package/dist/preview-card/index.js +0 -1
  29. package/dist/progress/index.js +0 -1
  30. package/dist/radio/index.js +0 -1
  31. package/dist/radio-group/index.js +0 -1
  32. package/dist/registry/base-ui-accordion.json +55 -0
  33. package/dist/registry/base-ui-alert-dialog.json +55 -0
  34. package/dist/registry/base-ui-autocomplete.json +55 -0
  35. package/dist/registry/base-ui-avatar.json +55 -0
  36. package/dist/registry/base-ui-button.json +55 -0
  37. package/dist/registry/base-ui-checkbox-group.json +55 -0
  38. package/dist/registry/base-ui-checkbox.json +55 -0
  39. package/dist/registry/base-ui-collapsible.json +55 -0
  40. package/dist/registry/base-ui-combobox.json +55 -0
  41. package/dist/registry/base-ui-context-menu.json +55 -0
  42. package/dist/registry/base-ui-dialog.json +55 -0
  43. package/dist/registry/base-ui-field.json +55 -0
  44. package/dist/registry/base-ui-fieldset.json +55 -0
  45. package/dist/registry/base-ui-input.json +55 -0
  46. package/dist/registry/base-ui-menu.json +55 -0
  47. package/dist/registry/base-ui-menubar.json +55 -0
  48. package/dist/registry/base-ui-meter.json +55 -0
  49. package/dist/registry/base-ui-navigation-menu.json +55 -0
  50. package/dist/registry/base-ui-number-field.json +55 -0
  51. package/dist/registry/base-ui-popover.json +55 -0
  52. package/dist/registry/base-ui-preview-card.json +55 -0
  53. package/dist/registry/base-ui-progress.json +55 -0
  54. package/dist/registry/base-ui-radio-group.json +55 -0
  55. package/dist/registry/base-ui-radio.json +55 -0
  56. package/dist/registry/base-ui-scroll-area.json +55 -0
  57. package/dist/registry/base-ui-select.json +55 -0
  58. package/dist/registry/base-ui-separator.json +55 -0
  59. package/dist/registry/base-ui-slider.json +55 -0
  60. package/dist/registry/base-ui-switch.json +55 -0
  61. package/dist/registry/base-ui-tabs.json +55 -0
  62. package/dist/registry/base-ui-toast.json +55 -0
  63. package/dist/registry/base-ui-toggle-group.json +55 -0
  64. package/dist/registry/base-ui-toggle.json +55 -0
  65. package/dist/registry/base-ui-toolbar.json +55 -0
  66. package/dist/registry/base-ui-tooltip.json +55 -0
  67. package/dist/registry/registry.json +1757 -0
  68. package/dist/scroll-area/index.js +0 -1
  69. package/dist/select/index.js +0 -1
  70. package/dist/separator/index.js +0 -1
  71. package/dist/slider/index.js +0 -1
  72. package/dist/styles.css +28 -14
  73. package/dist/switch/index.js +0 -1
  74. package/dist/tabs/index.js +0 -1
  75. package/dist/toast/index.js +0 -1
  76. package/dist/toggle/index.js +0 -1
  77. package/dist/toggle-group/index.js +0 -1
  78. package/dist/toolbar/index.js +0 -1
  79. package/dist/tooltip/index.js +0 -1
  80. package/package.json +29 -19
package/README.md CHANGED
@@ -6,7 +6,7 @@ This package is not affiliated with, endorsed by or sponsored by MUI or the Base
6
6
 
7
7
  `@base-ui/react` is a separately installed peer, built and maintained by its own maintainers; this package does not include it. You change `@base-ui/react/<component>` to `@navecss/base-ui/<component>` in your imports, add one stylesheet, and every part keeps Base UI's props, refs and behaviour while gaining Nave's styling. The styling is zero-runtime styling: static classes and one static stylesheet, with all behaviour still Base UI's.
8
8
 
9
- On this page: [Install](#install) · [Use it](#use-it) · [The stylesheet](#the-stylesheet) · [Variants](#variants) · [Overriding](#overriding) · [What is styled](#what-is-styled) · [Feedback and navigation](#feedback-and-navigation) · [Things to know](#things-to-know) · [License](#license)
9
+ On this page: [Install](#install) · [Use it](#use-it) · [The stylesheet](#the-stylesheet) · [Variants](#variants) · [Overriding](#overriding) · [Copy a component](#copy-a-component-into-your-project) · [What is styled](#what-is-styled) · [Feedback and navigation](#feedback-and-navigation) · [Things to know](#things-to-know) · [License](#license)
10
10
 
11
11
  ## Install
12
12
 
@@ -50,6 +50,8 @@ export default function RenameDialog() {
50
50
 
51
51
  Every subpath of Base UI that this package wraps is listed under [What is styled](#what-is-styled). Each one also re-exports every flat type name Base UI exports there, such as `DialogRootProps`, so those imports change the same way. Base UI's dotted type names, such as `Dialog.Root.Props`, come through as well, but not all of them: where one does not compile through this package, import Base UI's flat name for the same type from the same subpath. The end of [What is styled](#what-is-styled) names the ones left out by design. The package root, `@navecss/base-ui`, re-exports the same components.
52
52
 
53
+ A Server Component can import a namespace such as `Dialog` from a subpath and render its parts, `Dialog.Root` among them, without a `'use client'` directive of its own.
54
+
53
55
  ## The stylesheet
54
56
 
55
57
  Import Nave's tokens, then this package's stylesheet, before any stylesheet of yours that declares a `@layer`:
@@ -99,11 +101,12 @@ export default function SaveButton() {
99
101
 
100
102
  ## Overriding
101
103
 
102
- There are three steps, from the lightest:
104
+ There are four steps, from the lightest:
103
105
 
104
106
  1. **Tokens.** Re-theme with Nave's tokens and every part follows. Nothing else is needed for a different palette, radius or spacing.
105
107
  2. **`className`.** Pass a class to any part, as a string or as Base UI's function of the part's state. Put its rules in `@layer components.consumer`: that layer comes after Nave's, so your class wins in every state, whatever the specificity of Nave's rule. It also means that restyling a property restyles it in every state: set `background-color` on a Button and your colour replaces the `primary` variant's hover and active colours and a disabled button's too, so write the states you want yourself.
106
- 3. **The raw Base UI part.** Import the part from `@base-ui/react/<component>` and style it from scratch. It mixes freely with wrapped parts.
108
+ 3. **A copy of the component.** To change Nave's rules for a component rather than override them, copy its files into your project with shadcn's CLI and change the copy: see [Copy a component into your project](#copy-a-component-into-your-project).
109
+ 4. **The raw Base UI part.** Import the part from `@base-ui/react/<component>` and style it from scratch. It mixes freely with wrapped parts.
107
110
 
108
111
  ```css
109
112
  /* menu.module.css */
@@ -136,6 +139,51 @@ export default function ActionsMenu() {
136
139
 
137
140
  Behaviour is Base UI's. Parts Nave does not style, such as `Portal`, `Positioner`, `Provider` and `Form`, are Base UI's own parts, passed through unchanged.
138
141
 
142
+ ## Copy a component into your project
143
+
144
+ Every component this package styles is also in Nave's shadcn registry: one command copies the component's files into your project, and you then change its rules in the copy instead of overriding them.
145
+
146
+ With `@navecss/base-ui` installed, add a component from the files of the version you have:
147
+
148
+ ```bash
149
+ npx shadcn@latest add ./node_modules/@navecss/base-ui/dist/registry/base-ui-dialog.json
150
+ ```
151
+
152
+ Replace `dialog` with the subpath of the component you want, from [What is styled](#what-is-styled), and list several paths to add several components. The copy then comes from the same release as the components you still import from the package, with no version to type: `add` reads the files it copies from `node_modules` instead of downloading them. The command needs no Tailwind, no `components.json` and no `shadcn init`: every file in the registry says where it goes, so `add` installs it into a project that has none of them. Run `add` for Nave's components alone, with no item from another registry in the same command: shadcn's CLI decides from the first item it is given whether the project needs that setup.
153
+
154
+ The registry is also served at an exact version of `@navecss/base-ui`. Use that address in a project without the package installed, or with Yarn Plug'n'Play, which has no `node_modules`:
155
+
156
+ ```bash
157
+ npx shadcn@latest add https://cdn.jsdelivr.net/npm/@navecss/base-ui@<version>/dist/registry/base-ui-dialog.json
158
+ ```
159
+
160
+ Replace `<version>` with the version of `@navecss/base-ui` your project has, if it has one (`npm ls @navecss/base-ui` or `pnpm list @navecss/base-ui` prints it), so the copy matches the components you still import from the package; if not, use the latest version.
161
+
162
+ For shadcn's MCP server, which agents use, and for `shadcn search`, map the `@navecss` namespace to that address once. shadcn's CLI writes the mapping into your `package.json`, under `registries`, with the version in the address, so change the version there when you upgrade:
163
+
164
+ ```bash
165
+ npx shadcn@latest registry add '@navecss=https://cdn.jsdelivr.net/npm/@navecss/base-ui@<version>/dist/registry/{name}.json'
166
+ npx shadcn@latest add @navecss/base-ui-dialog
167
+ ```
168
+
169
+ `add` writes the files to `components/nave/`, or to `src/components/nave/` in a project with a `src` folder; `--path <folder>` writes them to that folder instead. For Dialog, in the order `add` writes them:
170
+
171
+ - `nave-dialog.ts`, the module you import;
172
+ - `nave-dialog.parts.ts`, its parts;
173
+ - `nave-dialog.wrap.ts`, the code that adds the classes to those parts;
174
+ - `nave-dialog.module.css`, the rules for those parts;
175
+ - `NAVECSS-LICENSE`.
176
+
177
+ Then import the component from the copy instead of from the package, with a path relative to the importing file, for example `import { Dialog } from './components/nave/nave-dialog'`. The copy's parts take the same props as the package's, `variant` and `size` included.
178
+
179
+ The copied rules read Nave's tokens, so keep `@navecss/tokens/css` imported as [The stylesheet](#the-stylesheet) shows. The copy imports neither `@navecss/base-ui` nor its `styles.css`: keep those while you still import any component from the package; a copy and the package's components work side by side. The first rule of each `.module.css` is Nave's `@layer` order statement, as in `styles.css`, and your build has to support CSS Modules, as Vite and Next.js do without setup. A change to one copy reaches no other copy and no component from the package.
180
+
181
+ A component added this way keeps its rules in `@layer components.consumer`, the layer your classes use, so a class you pass to one of its parts no longer wins in every state as it does on the package's components: the copied rules for hover, focus, disabled and the other states are more specific than one class, and still apply. A change to those states takes effect in the copied rules.
182
+
183
+ No later release of `@navecss/base-ui` changes the copied files. To take a later release's version of a component, upgrade the package and run `add` again, or use that release's address. `add` asks before it replaces a copied file whose content differs from the new one, whether you changed it or the release did, and `--overwrite` replaces them without asking. In a run with no terminal to answer, such as an agent or a CI job, it stops at the first such file and still exits with success, so that file and the ones after it stay as they were. The exit status does not show that it stopped, but the output does: it ends with the question about that file.
184
+
185
+ The registry names no versions for the packages a copy depends on, so `add` leaves the versions in your `package.json` as they are, and installs the latest version of any that is missing. A copy needs `@base-ui/react` 1.3 or later in the 1.x line, `@navecss/tokens` 0.4.0 or later before 1.0, and React 18 or 19.
186
+
139
187
  ## What is styled
140
188
 
141
189
  | Group | Subpaths |
@@ -219,9 +267,23 @@ A right-to-left app needs both `dir="rtl"` on `<html>` (or on the element you pa
219
267
 
220
268
  Context Menu's trigger area is your own element, and Nave paints nothing on it.
221
269
 
222
- Parts that Base UI added after 1.3 are exported as whatever your installed version provides. In this release the only such part is Combobox's `createItems`, added in Base UI 1.8.0. On 1.3 to 1.7 it is `undefined`, as it is in Base UI itself, and building an app that imports `@navecss/base-ui` or `@navecss/base-ui/combobox` may print a bundler warning that `createItems` has no matching export in Base UI's combobox module, even if the app never uses it. Vite prints it as `IMPORT_IS_UNDEFINED`. The warning is harmless and stops on Base UI 1.8.0. The package keeps it because avoiding it would make every app that uses `createItems` bundle all of Combobox.
270
+ Combobox's `createItems` is not exported here: Base UI added it in 1.8.0, and this package supports Base UI from 1.3. On 1.8.0 or later, import it from Base UI and pass what it returns to `items` on this package's `Combobox.Root`:
271
+
272
+ ```ts
273
+ import { Combobox as BaseCombobox } from '@base-ui/react/combobox'
274
+
275
+ const fruits = BaseCombobox.createItems(
276
+ [
277
+ { id: 1, name: 'Apple' },
278
+ { id: 2, name: 'Banana' },
279
+ ],
280
+ { getValue: (fruit) => fruit.id, getLabel: (fruit) => fruit.name },
281
+ )
282
+ ```
283
+
284
+ The types under a part, such as `Menu.Item.Props`, take their names and type parameters from Base UI 1.3, so nine that Base UI added up to 1.9.0 do not come through: `ContextMenu.Root.Actions`, the third type parameter of `Combobox.Root.Props` (`Item`), the type parameter of `NavigationMenu.Root.Props`, `NavigationMenu.Root.Value`, `OpenChangeEventDetails` under the roots of Select, Combobox and Autocomplete, and `Menu.Root.HighlightEventDetails` and `Menu.Root.HighlightEventReason`. Import `ContextMenuRootActions` from `@navecss/base-ui/context-menu`, `ComboboxRootProps<Value, Multiple, Item>` from `@navecss/base-ui/combobox`, `NavigationMenuRootProps<Value>` and `NavigationMenuRoot.Value<Value>` from `@navecss/base-ui/navigation-menu`, `SelectRootOpenChangeEventDetails`, `ComboboxRootOpenChangeEventDetails` and `AutocompleteRootOpenChangeEventDetails` from their own subpaths, and `MenuRootHighlightEventDetails` and `MenuRootHighlightEventReason` from `@navecss/base-ui/menu` instead.
223
285
 
224
- The types under a part, such as `Menu.Item.Props`, take their names and type parameters from Base UI 1.3, so four that Base UI added up to 1.8.0 do not come through: `ContextMenu.Root.Actions`, the third type parameter of `Combobox.Root.Props` (`Item`), the type parameter of `NavigationMenu.Root.Props`, and `NavigationMenu.Root.Value`. Import `ContextMenuRootActions` from `@navecss/base-ui/context-menu`, `ComboboxRootProps<Value, Multiple, Item>` from `@navecss/base-ui/combobox`, and `NavigationMenuRootProps<Value>` and `NavigationMenuRoot.Value<Value>` from `@navecss/base-ui/navigation-menu` instead.
286
+ Two more things Base UI 1.9.0 added are not exported here, because this package supports Base UI from 1.3. The Menu's filtering parts (`Menu.FilterProvider`, `Menu.Input`, `Menu.List`, `Menu.Empty`, `Menu.Clear` and `Menu.useFilter`), which Base UI marks as a preview, are left out, and Nave does not style them; import them from `@base-ui/react/menu` if you use them. Their flat type names, such as `MenuInputProps` and `MenuFilter`, still come through. The objects that name each part's data attributes and CSS variables, such as `DialogPopupDataAttributes`, come through as types only: to read their values, import them from Base UI's subpath.
225
287
 
226
288
  ## Feedback and navigation
227
289
 
@@ -269,7 +331,7 @@ export default function ToastArea({ children }: { children: ReactNode }) {
269
331
 
270
332
  `toastManager.add({ title: 'Saved', description: 'Your changes were saved.' })` then raises a toast from anywhere in your app.
271
333
 
272
- Call `Toast.createToastManager()` in a module that starts with `'use client'`, as in the example, and import the manager from that module: every subpath of this package is a client module.
334
+ Call `Toast.createToastManager()` in a module that starts with `'use client'`, as in the example, and import the manager from that module.
273
335
 
274
336
  `Toast.Title` renders an `<h2>`. Pass `render` to use another element.
275
337
 
@@ -409,7 +471,7 @@ A Preview Card opens when its link is hovered or focused, but its contents are n
409
471
 
410
472
  In a Menubar, moving to the next menu with the arrow keys puts focus on that menu's panel before any item, so the browser's ring around the panel shows where you are until the next arrow key reaches an item.
411
473
 
412
- In Base UI 1.8.0, `Menu.LinkItem` has no disabled state: a `disabled` prop reaches the `<a>` as a plain attribute, the link still activates, and it does not take the disabled colour Nave gives the other menu items.
474
+ In Base UI 1.8.0 and 1.9.0, `Menu.LinkItem` has no disabled state: a `disabled` prop reaches the `<a>` as a plain attribute, the link still activates, and it does not take the disabled colour Nave gives the other menu items.
413
475
 
414
476
  When the reader's system asks for reduced motion, this package turns off the popups' fade, the tooltip's fade, the backdrop's fade, the toasts' fade, the turn of the icon in Navigation Menu triggers, the tab indicator's slide, the motion of Accordion and Collapsible panels opening and closing, the turn of the icon in their triggers and the switch's slide, even if you have changed Nave's motion tokens. Motion you add or restyle yourself is yours to switch off.
415
477
 
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Accordion from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as AlertDialog from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Autocomplete from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Avatar from "./parts.generated.js";
@@ -1,3 +1,2 @@
1
- 'use client';
2
1
  /* eslint-disable import-x/export -- the named export wins over the star re-export, as TypeScript has it */
3
2
  export { Button } from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Checkbox from "./parts.generated.js";
@@ -1,3 +1,2 @@
1
- 'use client';
2
1
  /* eslint-disable import-x/export -- the named export wins over the star re-export, as TypeScript has it */
3
2
  export { CheckboxGroup } from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Collapsible from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Combobox from "./parts.generated.js";
@@ -1,5 +1,4 @@
1
1
  import { Combobox as Base } from '@base-ui/react/combobox';
2
- import { type PartOf } from '../part.ts';
3
2
  export declare const Root: typeof Base.Root;
4
3
  export declare namespace Root {
5
4
  type Props<Value, Multiple extends boolean | undefined = false> = Base.Root.Props<Value, Multiple>;
@@ -137,4 +136,3 @@ export declare namespace Separator {
137
136
  }
138
137
  export declare const useFilter: typeof Base.useFilter;
139
138
  export declare const useFilteredItems: typeof Base.useFilteredItems;
140
- export declare const createItems: PartOf<typeof Base, 'createItems'>;
@@ -30,4 +30,3 @@ export const Clear = /*#__PURE__*/ (() => wrapPart(Base.Clear, 'nave-base-ui-num
30
30
  export const Separator = /*#__PURE__*/ (() => wrapPart(Base.Separator, 'nave-base-ui-separator'))();
31
31
  export const useFilter = /*#__PURE__*/ (() => Base.useFilter)();
32
32
  export const useFilteredItems = /*#__PURE__*/ (() => Base.useFilteredItems)();
33
- export const createItems = /*#__PURE__*/ (() => Base.createItems)();
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as ContextMenu from "./parts.generated.js";
package/dist/css.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {}
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Dialog from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Field from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Fieldset from "./parts.generated.js";
@@ -1,3 +1,2 @@
1
- 'use client';
2
1
  /* eslint-disable import-x/export -- the named export wins over the star re-export, as TypeScript has it */
3
2
  export { Form } from "./parts.generated.js";
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
- 'use client';
2
1
  export * from "./accordion/index.js";
3
2
  export * from "./alert-dialog/index.js";
4
3
  export * from "./autocomplete/index.js";
@@ -1,3 +1,2 @@
1
- 'use client';
2
1
  /* eslint-disable import-x/export -- the named export wins over the star re-export, as TypeScript has it */
3
2
  export { Input } from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Menu from "./parts.generated.js";
@@ -1,3 +1,2 @@
1
- 'use client';
2
1
  /* eslint-disable import-x/export -- the named export wins over the star re-export, as TypeScript has it */
3
2
  export { Menubar } from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Meter from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as NavigationMenu from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as NumberField from "./parts.generated.js";
package/dist/part.d.ts CHANGED
@@ -8,11 +8,6 @@ export interface VariantProps {
8
8
  size?: 'md' | 'sm';
9
9
  variant?: 'ghost' | 'primary' | 'secondary';
10
10
  }
11
- /**
12
- * A part of a Base UI component, or `never` where the installed Base UI has no such part (one
13
- * younger than the peer floor).
14
- */
15
- export type PartOf<Namespace, Key extends string> = Key extends keyof Namespace ? Namespace[Key] : never;
16
11
  export interface SizeProps {
17
12
  size?: 'md' | 'sm';
18
13
  }
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Popover from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as PreviewCard from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Progress from "./parts.generated.js";
@@ -1,2 +1 @@
1
- 'use client';
2
1
  export * as Radio from "./parts.generated.js";
@@ -1,3 +1,2 @@
1
- 'use client';
2
1
  /* eslint-disable import-x/export -- the named export wins over the star re-export, as TypeScript has it */
3
2
  export { RadioGroup } from "./parts.generated.js";
@@ -0,0 +1,55 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
+ "dependencies": [
4
+ "@base-ui/react",
5
+ "@navecss/tokens",
6
+ "react",
7
+ "react-dom"
8
+ ],
9
+ "description": "NaveCSS's styling of the Base UI Accordion, as files copied into your project: Base UI's parts from @base-ui/react, which Base UI's maintainers publish, with Nave's classes from a CSS Module that reads Nave's tokens.",
10
+ "docs": "Import { Accordion } from the nave-accordion file just written, not from @navecss/base-ui/accordion.\nKeep @navecss/tokens/css imported: the copied rules read Nave's tokens. They sit in a CSS Module, so your build needs CSS Modules.\nThe copy needs @base-ui/react 1.3 or later in the 1.x line, @navecss/tokens 0.4.0 or later before 1.0, and React 18 or 19. A version already in your package.json is kept; a missing package is installed at its latest version.\nGenerated from @navecss/base-ui 0.3.0. No later release changes these files.",
11
+ "files": [
12
+ {
13
+ "content": "// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE.\n\nexport * as Accordion from './nave-accordion.parts'\nexport type * from '@base-ui/react/accordion'\n",
14
+ "path": "registry/nave/nave-accordion.ts",
15
+ "target": "components/nave/nave-accordion.ts",
16
+ "type": "registry:file"
17
+ },
18
+ {
19
+ "content": "// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE.\n'use client'\n/* eslint-disable @typescript-eslint/no-namespace, @typescript-eslint/no-explicit-any -- the types keep the names and generic defaults @navecss/base-ui exports, so code typed against the package compiles here unchanged */\nimport { Accordion as Base } from '@base-ui/react/accordion'\nimport styles from './nave-accordion.module.css'\n\nimport { wrapPart } from './nave-accordion.wrap'\n\nexport const Root: typeof Base.Root = /*#__PURE__*/ (() => Base.Root)()\nexport declare namespace Root {\n export type Value<TValue = any> = Base.Root.Value<TValue>\n export type State<TValue = any> = Base.Root.State<TValue>\n export type Props<TValue = any> = Base.Root.Props<TValue>\n export type ChangeEventReason = Base.Root.ChangeEventReason\n export type ChangeEventDetails = Base.Root.ChangeEventDetails\n}\nexport const Item: typeof Base.Item = /*#__PURE__*/ (() => wrapPart(Base.Item, styles.accordionItem))()\nexport declare namespace Item {\n export type State = Base.Item.State\n export type Props = Base.Item.Props\n export type ChangeEventReason = Base.Item.ChangeEventReason\n export type ChangeEventDetails = Base.Item.ChangeEventDetails\n}\nexport const Header: typeof Base.Header = /*#__PURE__*/ (() => wrapPart(Base.Header, styles.accordionHeader))()\nexport declare namespace Header {\n export type State = Base.Header.State\n export type Props = Base.Header.Props\n}\nexport const Trigger: typeof Base.Trigger = /*#__PURE__*/ (() => wrapPart(Base.Trigger, `${styles.disclosureTrigger} ${styles.disclosureIcon}`))()\nexport declare namespace Trigger {\n export type State = Base.Trigger.State\n export type Props = Base.Trigger.Props\n}\nexport const Panel: typeof Base.Panel = /*#__PURE__*/ (() => wrapPart(Base.Panel, styles.accordionPanel))()\nexport declare namespace Panel {\n export type State = Base.Panel.State\n export type Props = Base.Panel.Props\n}\n",
20
+ "path": "registry/nave/nave-accordion.parts.ts",
21
+ "target": "components/nave/nave-accordion.parts.ts",
22
+ "type": "registry:file"
23
+ },
24
+ {
25
+ "content": "// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE.\n'use client'\n\n/**\n * The one helper every wrapped part is built with. A wrapped part is Base UI's part with Nave's\n * class added to its `className` (a string is joined after Nave's class, a function of state is\n * wrapped, never stringified) and, for the Button family, the typed `variant` and `size` props\n * turned into `data-nave-*` attributes (as `size` is for an Avatar). Everything else (every other\n * prop, the ref, `render`) goes to Base UI's part untouched, and nothing here reads state, layout\n * or style: what the wrapper adds is chosen by the props the consumer passed.\n */\nimport {\n createElement,\n type ElementType,\n forwardRef,\n type ForwardRefExoticComponent,\n type RefAttributes,\n useMemo,\n} from 'react'\n\n/**\n * The size an Avatar takes. It is not a Base UI prop of any Avatar part, so nothing is shadowed.\n */\nexport interface AvatarProps {\n size?: 'lg' | 'md' | 'sm'\n}\n\nexport interface VariantProps {\n size?: 'md' | 'sm'\n variant?: 'ghost' | 'primary' | 'secondary'\n}\n\nexport interface SizeProps {\n size?: 'md' | 'sm'\n}\n\ntype Variants = 'avatar' | 'size' | 'variant'\n\nconst isOffDefault = (size: unknown, variants: Variants): boolean =>\n size === 'sm' || (variants === 'avatar' && size === 'lg')\n\ntype ClassNameFunction = (state: unknown) => string | undefined\ntype ClassName = ClassNameFunction | string | undefined\ntype Props = Record<string, unknown>\n\nconst join = (own: string, consumer: string | undefined): string =>\n consumer === undefined || consumer === '' ? own : `${own} ${consumer}`\n\n/**\n * Nave's class composed with the consumer's. The result is memoized on the consumer's own value,\n * so a consumer that passes the same function gets the same function through and a memoized part\n * does not re-render for it.\n */\nconst useClassName = (own: string, consumer: ClassName): ClassName =>\n useMemo(\n () =>\n typeof consumer === 'function'\n ? (state: unknown) => join(own, consumer(state))\n : join(own, consumer),\n [own, consumer],\n )\n\n/**\n * The attributes a non-default variant or size renders as, and the props left over. `variant` and\n * `size` are consumed here and never reach Base UI's part, which has no such props.\n */\nconst variantAttributes = (props: Props, variants: Variants): Props => {\n const { size, variant, ...rest } = props\n return {\n ...rest,\n ...(variants === 'variant' &&\n (variant === 'primary' || variant === 'ghost') && { 'data-nave-variant': variant }),\n ...(isOffDefault(size, variants) && { 'data-nave-size': size }),\n }\n}\n\nconst build = (\n part: ElementType,\n own: string,\n variants: Variants | undefined,\n): ForwardRefExoticComponent<Props & RefAttributes<unknown>> =>\n forwardRef<unknown, Props>(function NaveBaseUiPart(props, ref) {\n const forwarded = variants === undefined ? props : variantAttributes(props, variants)\n const className = useClassName(own, forwarded.className as ClassName)\n return createElement(part, { ...forwarded, className, ref })\n })\n\n/**\n * The wrapped part, or nothing where the installed Base UI has no such part (one younger than the\n * peer floor): the export stays absent instead of becoming a component that throws when rendered.\n */\nconst wrap = <T>(part: unknown, className: string, variants: Variants | undefined): T =>\n part === undefined\n ? (part as T)\n : (build(part as ElementType, className, variants) as unknown as T)\n\n/**\n * A part that is Base UI's own, with `className` composed. Typed as the part it wraps. A part the\n * installed Base UI does not have stays absent.\n */\nexport const wrapPart = <P>(part: P, className: string): P => wrap<P>(part, className, undefined)\n\n/**\n * A part of the Button family: as `wrapPart`, and its props gain `variant` and `size`. The type it\n * is given is the type the generated module declares for it, written from Base UI's own public\n * `Props` so that a generic part (a trigger's `Payload`) stays generic.\n */\nexport const wrapVariantPart = <T>(part: unknown, className: string): T =>\n wrap<T>(part, className, 'variant')\n\n/**\n * A part that gains `size` alone, as the Toggle does. A part the installed Base UI does not have\n * stays absent, as for `wrapPart`.\n */\nexport const wrapSizePart = <T>(part: unknown, className: string): T =>\n wrap<T>(part, className, 'size')\n\n/**\n * A part that gains `size` with the Avatar's three values. A part the installed Base UI does not\n * have stays absent, as for `wrapPart`.\n */\nexport const wrapAvatarPart = <T>(part: unknown, className: string): T =>\n wrap<T>(part, className, 'avatar')\n",
26
+ "path": "registry/nave/nave-accordion.wrap.ts",
27
+ "target": "components/nave/nave-accordion.wrap.ts",
28
+ "type": "registry:file"
29
+ },
30
+ {
31
+ "content": "/* SPDX-License-Identifier: MIT */\n/* Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE. */\n@layer tokens.defaults, tokens.presets, reset, atomic, components.nave, components.consumer, overrides;\n\n@layer components.consumer {\n .disclosureTrigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n inline-size: 100%;\n padding: var(--nave-spacing-control-md) var(--nave-spacing-control-xs);\n border: 0;\n background-color: transparent;\n color: var(--nave-color-content-primary);\n font-family: inherit;\n font-size: var(--nave-font-size-md);\n font-weight: var(--nave-font-weight-medium);\n text-align: start;\n cursor: pointer;\n &:disabled,\n &[aria-disabled=\"true\"] {\n color: var(--nave-color-content-disabled);\n cursor: not-allowed;\n }\n & {\n /* stylelint-disable-next-line declaration-property-value-disallowed-list -- the outline the &:focus-visible rule for this class draws replaces the browser's default focus indicator; keep that rule while this declaration stays. */\n outline: none;\n }\n &:focus-visible {\n outline-style: solid;\n outline-width: var(--nave-border-width-focus, 2px);\n outline-color: var(--nave-color-border-focus, currentColor);\n outline-offset: 2px;\n }\n }\n .disclosureIcon {\n & > svg:last-child {\n flex: none;\n transition-property: rotate;\n transition-duration: var(--nave-motion-duration-fast);\n transition-timing-function: var(--nave-motion-easing-standard);\n }\n\n &[aria-expanded=\"true\"] > svg:last-child {\n rotate: 180deg;\n }\n\n @media (prefers-reduced-motion: reduce) {\n & > svg:last-child {\n transition-duration: calc(0 * var(--nave-motion-duration-fast));\n }\n }\n }\n .accordionHeader {\n margin: 0;\n }\n .accordionItem {\n border-block-end: var(--nave-border-width-sm) solid\n var(--nave-color-border-default);\n }\n .accordionPanel {\n box-sizing: border-box;\n overflow: hidden;\n padding-inline: var(--nave-spacing-control-xs);\n height: var(--accordion-panel-height);\n transition-property: height;\n transition-duration: var(--nave-motion-duration-base);\n transition-timing-function: var(--nave-motion-easing-standard);\n &[data-starting-style],\n &[data-ending-style] {\n height: 0;\n }\n & > :first-child {\n margin-block-start: var(--nave-spacing-control-xs);\n }\n & > :last-child {\n margin-block-end: var(--nave-spacing-content-md);\n }\n @media (prefers-reduced-motion: reduce) {\n & {\n transition-duration: calc(0 * var(--nave-motion-duration-fast));\n }\n }\n }\n}\n",
32
+ "path": "registry/nave/nave-accordion.module.css",
33
+ "target": "components/nave/nave-accordion.module.css",
34
+ "type": "registry:file"
35
+ },
36
+ {
37
+ "content": "MIT License\n\nCopyright (c) 2026 Nave Contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n",
38
+ "path": "registry/nave/NAVECSS-LICENSE",
39
+ "target": "components/nave/NAVECSS-LICENSE",
40
+ "type": "registry:file"
41
+ }
42
+ ],
43
+ "meta": {
44
+ "peerDependencies": {
45
+ "@base-ui/react": "^1.3.0",
46
+ "@navecss/tokens": ">=0.4.0 <1.0.0",
47
+ "react": "^18 || ^19",
48
+ "react-dom": "^18 || ^19"
49
+ },
50
+ "version": "0.3.0"
51
+ },
52
+ "name": "base-ui-accordion",
53
+ "title": "NaveCSS styling of Base UI Accordion",
54
+ "type": "registry:item"
55
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
+ "dependencies": [
4
+ "@base-ui/react",
5
+ "@navecss/tokens",
6
+ "react",
7
+ "react-dom"
8
+ ],
9
+ "description": "NaveCSS's styling of the Base UI Alert Dialog, as files copied into your project: Base UI's parts from @base-ui/react, which Base UI's maintainers publish, with Nave's classes from a CSS Module that reads Nave's tokens.",
10
+ "docs": "Import { AlertDialog } from the nave-alert-dialog file just written, not from @navecss/base-ui/alert-dialog.\nKeep @navecss/tokens/css imported: the copied rules read Nave's tokens. They sit in a CSS Module, so your build needs CSS Modules.\nThe copy needs @base-ui/react 1.3 or later in the 1.x line, @navecss/tokens 0.4.0 or later before 1.0, and React 18 or 19. A version already in your package.json is kept; a missing package is installed at its latest version.\nGenerated from @navecss/base-ui 0.3.0. No later release changes these files.",
11
+ "files": [
12
+ {
13
+ "content": "// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE.\n\nexport * as AlertDialog from './nave-alert-dialog.parts'\nexport type * from '@base-ui/react/alert-dialog'\n",
14
+ "path": "registry/nave/nave-alert-dialog.ts",
15
+ "target": "components/nave/nave-alert-dialog.ts",
16
+ "type": "registry:file"
17
+ },
18
+ {
19
+ "content": "// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE.\n'use client'\n/* eslint-disable @typescript-eslint/no-namespace -- the types keep the names and generic defaults @navecss/base-ui exports, so code typed against the package compiles here unchanged */\nimport type { ReactElement, RefAttributes } from 'react'\nimport { AlertDialog as Base } from '@base-ui/react/alert-dialog'\nimport styles from './nave-alert-dialog.module.css'\n\nimport { wrapPart, wrapVariantPart, type VariantProps } from './nave-alert-dialog.wrap'\n\nexport const Root: typeof Base.Root = /*#__PURE__*/ (() => Base.Root)()\nexport declare namespace Root {\n export type State = Base.Root.State\n export type Props<Payload = unknown> = Base.Root.Props<Payload>\n export type Actions = Base.Root.Actions\n export type ChangeEventReason = Base.Root.ChangeEventReason\n export type ChangeEventDetails = Base.Root.ChangeEventDetails\n}\nexport const Backdrop: typeof Base.Backdrop = /*#__PURE__*/ (() => wrapPart(Base.Backdrop, styles.backdrop))()\nexport declare namespace Backdrop {\n export type Props = Base.Backdrop.Props\n export type State = Base.Backdrop.State\n}\nexport const Close: (props: Omit<Base.Close.Props, 'ref'> & RefAttributes<HTMLButtonElement> & VariantProps) => ReactElement = /*#__PURE__*/ (() => wrapVariantPart(Base.Close, styles.button))()\nexport declare namespace Close {\n export type Props = Base.Close.Props & VariantProps\n export type State = Base.Close.State\n}\nexport const Description: typeof Base.Description = /*#__PURE__*/ (() => wrapPart(Base.Description, styles.description))()\nexport declare namespace Description {\n export type Props = Base.Description.Props\n export type State = Base.Description.State\n}\nexport const Popup: typeof Base.Popup = /*#__PURE__*/ (() => wrapPart(Base.Popup, `${styles.dialogPopup} ${styles.popupFade}`))()\nexport declare namespace Popup {\n export type Props = Base.Popup.Props\n export type State = Base.Popup.State\n}\nexport const Portal: typeof Base.Portal = /*#__PURE__*/ (() => Base.Portal)()\nexport declare namespace Portal {\n export type State = Base.Portal.State\n export type Props = Base.Portal.Props\n}\nexport const Title: typeof Base.Title = /*#__PURE__*/ (() => wrapPart(Base.Title, styles.title))()\nexport declare namespace Title {\n export type Props = Base.Title.Props\n export type State = Base.Title.State\n}\nexport const Trigger: <Payload>(props: Omit<Base.Trigger.Props<Payload>, 'ref'> & RefAttributes<HTMLElement> & VariantProps) => ReactElement = /*#__PURE__*/ (() => wrapVariantPart(Base.Trigger, styles.button))()\nexport type Trigger = typeof Trigger\nexport declare namespace Trigger {\n export type Props<Payload = unknown> = Base.Trigger.Props<Payload> & VariantProps\n export type State = Base.Trigger.State\n}\nexport const Viewport: typeof Base.Viewport = /*#__PURE__*/ (() => Base.Viewport)()\nexport declare namespace Viewport {\n export type State = Base.Viewport.State\n export type Props = Base.Viewport.Props\n}\nexport const Handle: typeof Base.Handle = /*#__PURE__*/ (() => Base.Handle)()\nexport type Handle<Payload> = Base.Handle<Payload>\nexport const createHandle: typeof Base.createHandle = /*#__PURE__*/ (() => Base.createHandle)()\n",
20
+ "path": "registry/nave/nave-alert-dialog.parts.ts",
21
+ "target": "components/nave/nave-alert-dialog.parts.ts",
22
+ "type": "registry:file"
23
+ },
24
+ {
25
+ "content": "// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE.\n'use client'\n\n/**\n * The one helper every wrapped part is built with. A wrapped part is Base UI's part with Nave's\n * class added to its `className` (a string is joined after Nave's class, a function of state is\n * wrapped, never stringified) and, for the Button family, the typed `variant` and `size` props\n * turned into `data-nave-*` attributes (as `size` is for an Avatar). Everything else (every other\n * prop, the ref, `render`) goes to Base UI's part untouched, and nothing here reads state, layout\n * or style: what the wrapper adds is chosen by the props the consumer passed.\n */\nimport {\n createElement,\n type ElementType,\n forwardRef,\n type ForwardRefExoticComponent,\n type RefAttributes,\n useMemo,\n} from 'react'\n\n/**\n * The size an Avatar takes. It is not a Base UI prop of any Avatar part, so nothing is shadowed.\n */\nexport interface AvatarProps {\n size?: 'lg' | 'md' | 'sm'\n}\n\nexport interface VariantProps {\n size?: 'md' | 'sm'\n variant?: 'ghost' | 'primary' | 'secondary'\n}\n\nexport interface SizeProps {\n size?: 'md' | 'sm'\n}\n\ntype Variants = 'avatar' | 'size' | 'variant'\n\nconst isOffDefault = (size: unknown, variants: Variants): boolean =>\n size === 'sm' || (variants === 'avatar' && size === 'lg')\n\ntype ClassNameFunction = (state: unknown) => string | undefined\ntype ClassName = ClassNameFunction | string | undefined\ntype Props = Record<string, unknown>\n\nconst join = (own: string, consumer: string | undefined): string =>\n consumer === undefined || consumer === '' ? own : `${own} ${consumer}`\n\n/**\n * Nave's class composed with the consumer's. The result is memoized on the consumer's own value,\n * so a consumer that passes the same function gets the same function through and a memoized part\n * does not re-render for it.\n */\nconst useClassName = (own: string, consumer: ClassName): ClassName =>\n useMemo(\n () =>\n typeof consumer === 'function'\n ? (state: unknown) => join(own, consumer(state))\n : join(own, consumer),\n [own, consumer],\n )\n\n/**\n * The attributes a non-default variant or size renders as, and the props left over. `variant` and\n * `size` are consumed here and never reach Base UI's part, which has no such props.\n */\nconst variantAttributes = (props: Props, variants: Variants): Props => {\n const { size, variant, ...rest } = props\n return {\n ...rest,\n ...(variants === 'variant' &&\n (variant === 'primary' || variant === 'ghost') && { 'data-nave-variant': variant }),\n ...(isOffDefault(size, variants) && { 'data-nave-size': size }),\n }\n}\n\nconst build = (\n part: ElementType,\n own: string,\n variants: Variants | undefined,\n): ForwardRefExoticComponent<Props & RefAttributes<unknown>> =>\n forwardRef<unknown, Props>(function NaveBaseUiPart(props, ref) {\n const forwarded = variants === undefined ? props : variantAttributes(props, variants)\n const className = useClassName(own, forwarded.className as ClassName)\n return createElement(part, { ...forwarded, className, ref })\n })\n\n/**\n * The wrapped part, or nothing where the installed Base UI has no such part (one younger than the\n * peer floor): the export stays absent instead of becoming a component that throws when rendered.\n */\nconst wrap = <T>(part: unknown, className: string, variants: Variants | undefined): T =>\n part === undefined\n ? (part as T)\n : (build(part as ElementType, className, variants) as unknown as T)\n\n/**\n * A part that is Base UI's own, with `className` composed. Typed as the part it wraps. A part the\n * installed Base UI does not have stays absent.\n */\nexport const wrapPart = <P>(part: P, className: string): P => wrap<P>(part, className, undefined)\n\n/**\n * A part of the Button family: as `wrapPart`, and its props gain `variant` and `size`. The type it\n * is given is the type the generated module declares for it, written from Base UI's own public\n * `Props` so that a generic part (a trigger's `Payload`) stays generic.\n */\nexport const wrapVariantPart = <T>(part: unknown, className: string): T =>\n wrap<T>(part, className, 'variant')\n\n/**\n * A part that gains `size` alone, as the Toggle does. A part the installed Base UI does not have\n * stays absent, as for `wrapPart`.\n */\nexport const wrapSizePart = <T>(part: unknown, className: string): T =>\n wrap<T>(part, className, 'size')\n\n/**\n * A part that gains `size` with the Avatar's three values. A part the installed Base UI does not\n * have stays absent, as for `wrapPart`.\n */\nexport const wrapAvatarPart = <T>(part: unknown, className: string): T =>\n wrap<T>(part, className, 'avatar')\n",
26
+ "path": "registry/nave/nave-alert-dialog.wrap.ts",
27
+ "target": "components/nave/nave-alert-dialog.wrap.ts",
28
+ "type": "registry:file"
29
+ },
30
+ {
31
+ "content": "/* SPDX-License-Identifier: MIT */\n/* Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE. */\n@layer tokens.defaults, tokens.presets, reset, atomic, components.nave, components.consumer, overrides;\n\n@layer components.consumer {\n .dialogPopup {\n box-sizing: border-box;\n position: fixed;\n inset: 0;\n margin: auto;\n block-size: fit-content;\n inline-size: 32rem;\n max-inline-size: calc(100% - 2 * var(--nave-spacing-content-lg));\n max-block-size: calc(100% - 2 * var(--nave-spacing-content-lg));\n overflow-y: auto;\n scroll-padding: var(--nave-spacing-content-lg);\n background-color: var(--nave-color-surface-overlay);\n color: var(--nave-color-content-primary);\n border: var(--nave-border-width-sm) solid var(--nave-color-border-default);\n border-radius: var(--nave-radius-overlay);\n box-shadow: var(--nave-shadow-modal);\n padding: var(--nave-spacing-content-lg);\n }\n .title {\n margin: 0;\n font-size: var(--nave-font-size-lg);\n font-weight: var(--nave-font-weight-semibold);\n line-height: var(--nave-line-height-tight);\n }\n .description {\n margin: 0;\n font-size: var(--nave-font-size-sm);\n line-height: var(--nave-line-height-base);\n color: var(--nave-color-content-secondary);\n }\n .button {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--nave-spacing-control-sm);\n min-block-size: var(--nave-size-control-md);\n padding-block: 0;\n padding-inline: var(--nave-spacing-control-lg);\n border: var(--nave-border-width-sm) solid var(--nave-color-border-control);\n border-radius: var(--nave-radius-control);\n background-color: var(--nave-color-action-secondary);\n color: var(--nave-color-content-primary);\n font-family: inherit;\n font-size: var(--nave-font-size-sm);\n font-weight: var(--nave-font-weight-medium);\n line-height: var(--nave-line-height-tight);\n white-space: nowrap;\n cursor: pointer;\n user-select: none;\n &[data-nave-size=\"sm\"] {\n min-block-size: var(--nave-size-control-sm);\n padding-inline: var(--nave-spacing-control-md);\n }\n &[data-nave-variant=\"primary\"] {\n background-color: var(--nave-color-action-primary);\n border-color: transparent;\n color: var(--nave-color-on-action-primary);\n }\n &[data-nave-variant=\"primary\"]:hover:not(\n :disabled,\n [aria-disabled=\"true\"]\n ) {\n background-color: var(--nave-color-action-primary-hover);\n }\n &[data-nave-variant=\"primary\"]:active:not(\n :disabled,\n [aria-disabled=\"true\"]\n ) {\n background-color: var(--nave-color-action-primary-active);\n }\n &:disabled,\n &[aria-disabled=\"true\"] {\n background-color: transparent;\n border-color: var(--nave-color-border-disabled);\n color: var(--nave-color-content-disabled);\n cursor: not-allowed;\n }\n &[data-nave-variant=\"ghost\"] {\n background-color: transparent;\n border-color: transparent;\n }\n &[data-nave-variant=\"ghost\"]:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--nave-color-action-highlight);\n }\n &[data-nave-variant=\"ghost\"]:active:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--nave-color-action-highlight);\n }\n &[data-nave-variant=\"ghost\"][aria-expanded=\"true\"]:not(\n :disabled,\n [aria-disabled=\"true\"]\n ) {\n background-color: var(--nave-color-action-highlight);\n }\n & {\n /* stylelint-disable-next-line declaration-property-value-disallowed-list -- the outline the &:focus-visible rule for this class draws replaces the browser's default focus indicator; keep that rule while this declaration stays. */\n outline: none;\n }\n &:focus-visible {\n outline-style: solid;\n outline-width: var(--nave-border-width-focus, 2px);\n outline-color: var(--nave-color-border-focus, currentColor);\n outline-offset: 2px;\n }\n }\n .backdrop {\n position: fixed;\n inset: 0;\n background-color: var(--nave-color-backdrop-modal);\n transition-property: opacity;\n transition-duration: var(--nave-motion-duration-fast);\n transition-timing-function: var(--nave-motion-easing-decelerate);\n &[data-starting-style],\n &[data-ending-style] {\n opacity: 0;\n }\n &[data-ending-style] {\n transition-timing-function: var(--nave-motion-easing-accelerate);\n }\n @media (prefers-reduced-motion: reduce) {\n &,\n &[data-instant] {\n transition-duration: calc(0 * var(--nave-motion-duration-fast));\n }\n }\n }\n .popupFade {\n transition-property: opacity;\n transition-duration: var(--nave-motion-duration-fast);\n transition-timing-function: var(--nave-motion-easing-decelerate);\n &[data-starting-style],\n &[data-ending-style] {\n opacity: 0;\n }\n &[data-ending-style] {\n transition-timing-function: var(--nave-motion-easing-accelerate);\n }\n @media (prefers-reduced-motion: reduce) {\n &,\n &[data-instant] {\n transition-duration: calc(0 * var(--nave-motion-duration-fast));\n }\n }\n }\n}\n",
32
+ "path": "registry/nave/nave-alert-dialog.module.css",
33
+ "target": "components/nave/nave-alert-dialog.module.css",
34
+ "type": "registry:file"
35
+ },
36
+ {
37
+ "content": "MIT License\n\nCopyright (c) 2026 Nave Contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n",
38
+ "path": "registry/nave/NAVECSS-LICENSE",
39
+ "target": "components/nave/NAVECSS-LICENSE",
40
+ "type": "registry:file"
41
+ }
42
+ ],
43
+ "meta": {
44
+ "peerDependencies": {
45
+ "@base-ui/react": "^1.3.0",
46
+ "@navecss/tokens": ">=0.4.0 <1.0.0",
47
+ "react": "^18 || ^19",
48
+ "react-dom": "^18 || ^19"
49
+ },
50
+ "version": "0.3.0"
51
+ },
52
+ "name": "base-ui-alert-dialog",
53
+ "title": "NaveCSS styling of Base UI Alert Dialog",
54
+ "type": "registry:item"
55
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
+ "dependencies": [
4
+ "@base-ui/react",
5
+ "@navecss/tokens",
6
+ "react",
7
+ "react-dom"
8
+ ],
9
+ "description": "NaveCSS's styling of the Base UI Autocomplete, as files copied into your project: Base UI's parts from @base-ui/react, which Base UI's maintainers publish, with Nave's classes from a CSS Module that reads Nave's tokens.",
10
+ "docs": "Import { Autocomplete } from the nave-autocomplete file just written, not from @navecss/base-ui/autocomplete.\nKeep @navecss/tokens/css imported: the copied rules read Nave's tokens. They sit in a CSS Module, so your build needs CSS Modules.\nThe copy needs @base-ui/react 1.3 or later in the 1.x line, @navecss/tokens 0.4.0 or later before 1.0, and React 18 or 19. A version already in your package.json is kept; a missing package is installed at its latest version.\nGenerated from @navecss/base-ui 0.3.0. No later release changes these files.",
11
+ "files": [
12
+ {
13
+ "content": "// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE.\n\nexport * as Autocomplete from './nave-autocomplete.parts'\nexport type * from '@base-ui/react/autocomplete'\n",
14
+ "path": "registry/nave/nave-autocomplete.ts",
15
+ "target": "components/nave/nave-autocomplete.ts",
16
+ "type": "registry:file"
17
+ },
18
+ {
19
+ "content": "// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE.\n'use client'\n/* eslint-disable @typescript-eslint/no-namespace -- the types keep the names and generic defaults @navecss/base-ui exports, so code typed against the package compiles here unchanged */\nimport { Autocomplete as Base } from '@base-ui/react/autocomplete'\nimport styles from './nave-autocomplete.module.css'\n\nimport { wrapPart } from './nave-autocomplete.wrap'\n\nexport const Root: typeof Base.Root = /*#__PURE__*/ (() => Base.Root)()\nexport declare namespace Root {\n export type Props<ItemValue> = Base.Root.Props<ItemValue>\n export type State = Base.Root.State\n export type Actions = Base.Root.Actions\n export type ChangeEventReason = Base.Root.ChangeEventReason\n export type ChangeEventDetails = Base.Root.ChangeEventDetails\n export type HighlightEventReason = Base.Root.HighlightEventReason\n export type HighlightEventDetails = Base.Root.HighlightEventDetails\n}\nexport const Value: typeof Base.Value = /*#__PURE__*/ (() => Base.Value)()\nexport declare namespace Value {\n export type State = Base.Value.State\n export type Props = Base.Value.Props\n}\nexport const Trigger: typeof Base.Trigger = /*#__PURE__*/ (() => wrapPart(Base.Trigger, styles.comboboxTrigger))()\nexport type Trigger = typeof Trigger\nexport declare namespace Trigger {\n export type State = Base.Trigger.State\n export type Props = Base.Trigger.Props\n}\nexport const Input: typeof Base.Input = /*#__PURE__*/ (() => wrapPart(Base.Input, styles.numberFieldInput))()\nexport declare namespace Input {\n export type State = Base.Input.State\n export type Props = Base.Input.Props\n}\nexport const InputGroup: typeof Base.InputGroup = /*#__PURE__*/ (() => wrapPart(Base.InputGroup, styles.inputGroup))()\nexport type InputGroup = typeof InputGroup\nexport declare namespace InputGroup {\n export type State = Base.InputGroup.State\n export type Props = Base.InputGroup.Props\n}\nexport const Icon: typeof Base.Icon = /*#__PURE__*/ (() => wrapPart(Base.Icon, styles.selectIcon))()\nexport declare namespace Icon {\n export type State = Base.Icon.State\n export type Props = Base.Icon.Props\n}\nexport const Clear: typeof Base.Clear = /*#__PURE__*/ (() => wrapPart(Base.Clear, styles.numberFieldStepper))()\nexport declare namespace Clear {\n export type State = Base.Clear.State\n export type Props = Base.Clear.Props\n}\nexport const List: typeof Base.List = /*#__PURE__*/ (() => Base.List)()\nexport declare namespace List {\n export type State = Base.List.State\n export type Props = Base.List.Props\n}\nexport const Status: typeof Base.Status = /*#__PURE__*/ (() => Base.Status)()\nexport declare namespace Status {\n export type State = Base.Status.State\n export type Props = Base.Status.Props\n}\nexport const Portal: typeof Base.Portal = /*#__PURE__*/ (() => Base.Portal)()\nexport declare namespace Portal {\n export type State = Base.Portal.State\n export type Props = Base.Portal.Props\n}\nexport const Backdrop: typeof Base.Backdrop = /*#__PURE__*/ (() => Base.Backdrop)()\nexport declare namespace Backdrop {\n export type Props = Base.Backdrop.Props\n export type State = Base.Backdrop.State\n}\nexport const Positioner: typeof Base.Positioner = /*#__PURE__*/ (() => Base.Positioner)()\nexport declare namespace Positioner {\n export type State = Base.Positioner.State\n export type Props = Base.Positioner.Props\n}\nexport const Popup: typeof Base.Popup = /*#__PURE__*/ (() => wrapPart(Base.Popup, `${styles.listPopup} ${styles.popupFade}`))()\nexport declare namespace Popup {\n export type State = Base.Popup.State\n export type Props = Base.Popup.Props\n}\nexport const Arrow: typeof Base.Arrow = /*#__PURE__*/ (() => wrapPart(Base.Arrow, `${styles.arrow} ${styles.arrowInline}`))()\nexport declare namespace Arrow {\n export type State = Base.Arrow.State\n export type Props = Base.Arrow.Props\n}\nexport const Group: typeof Base.Group = /*#__PURE__*/ (() => Base.Group)()\nexport declare namespace Group {\n export type State = Base.Group.State\n export type Props = Base.Group.Props\n}\nexport const GroupLabel: typeof Base.GroupLabel = /*#__PURE__*/ (() => wrapPart(Base.GroupLabel, styles.groupLabel))()\nexport declare namespace GroupLabel {\n export type State = Base.GroupLabel.State\n export type Props = Base.GroupLabel.Props\n}\nexport const Item: typeof Base.Item = /*#__PURE__*/ (() => wrapPart(Base.Item, `${styles.item} ${styles.itemHighlight} ${styles.activeOption}`))()\nexport type Item = typeof Item\nexport declare namespace Item {\n export type State = Base.Item.State\n export type Props = Base.Item.Props\n}\nexport const Row: typeof Base.Row = /*#__PURE__*/ (() => Base.Row)()\nexport declare namespace Row {\n export type State = Base.Row.State\n export type Props = Base.Row.Props\n}\nexport const Collection: typeof Base.Collection = /*#__PURE__*/ (() => Base.Collection)()\nexport declare namespace Collection {\n export type State = Base.Collection.State\n export type Props = Base.Collection.Props\n}\nexport const Empty: typeof Base.Empty = /*#__PURE__*/ (() => wrapPart(Base.Empty, styles.listEmpty))()\nexport declare namespace Empty {\n export type State = Base.Empty.State\n export type Props = Base.Empty.Props\n}\nexport const Separator: typeof Base.Separator = /*#__PURE__*/ (() => wrapPart(Base.Separator, styles.separator))()\nexport declare namespace Separator {\n export type Props = Base.Separator.Props\n export type State = Base.Separator.State\n}\nexport const useFilter: typeof Base.useFilter = /*#__PURE__*/ (() => Base.useFilter)()\nexport const useFilteredItems: typeof Base.useFilteredItems = /*#__PURE__*/ (() => Base.useFilteredItems)()\n",
20
+ "path": "registry/nave/nave-autocomplete.parts.ts",
21
+ "target": "components/nave/nave-autocomplete.parts.ts",
22
+ "type": "registry:file"
23
+ },
24
+ {
25
+ "content": "// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE.\n'use client'\n\n/**\n * The one helper every wrapped part is built with. A wrapped part is Base UI's part with Nave's\n * class added to its `className` (a string is joined after Nave's class, a function of state is\n * wrapped, never stringified) and, for the Button family, the typed `variant` and `size` props\n * turned into `data-nave-*` attributes (as `size` is for an Avatar). Everything else (every other\n * prop, the ref, `render`) goes to Base UI's part untouched, and nothing here reads state, layout\n * or style: what the wrapper adds is chosen by the props the consumer passed.\n */\nimport {\n createElement,\n type ElementType,\n forwardRef,\n type ForwardRefExoticComponent,\n type RefAttributes,\n useMemo,\n} from 'react'\n\n/**\n * The size an Avatar takes. It is not a Base UI prop of any Avatar part, so nothing is shadowed.\n */\nexport interface AvatarProps {\n size?: 'lg' | 'md' | 'sm'\n}\n\nexport interface VariantProps {\n size?: 'md' | 'sm'\n variant?: 'ghost' | 'primary' | 'secondary'\n}\n\nexport interface SizeProps {\n size?: 'md' | 'sm'\n}\n\ntype Variants = 'avatar' | 'size' | 'variant'\n\nconst isOffDefault = (size: unknown, variants: Variants): boolean =>\n size === 'sm' || (variants === 'avatar' && size === 'lg')\n\ntype ClassNameFunction = (state: unknown) => string | undefined\ntype ClassName = ClassNameFunction | string | undefined\ntype Props = Record<string, unknown>\n\nconst join = (own: string, consumer: string | undefined): string =>\n consumer === undefined || consumer === '' ? own : `${own} ${consumer}`\n\n/**\n * Nave's class composed with the consumer's. The result is memoized on the consumer's own value,\n * so a consumer that passes the same function gets the same function through and a memoized part\n * does not re-render for it.\n */\nconst useClassName = (own: string, consumer: ClassName): ClassName =>\n useMemo(\n () =>\n typeof consumer === 'function'\n ? (state: unknown) => join(own, consumer(state))\n : join(own, consumer),\n [own, consumer],\n )\n\n/**\n * The attributes a non-default variant or size renders as, and the props left over. `variant` and\n * `size` are consumed here and never reach Base UI's part, which has no such props.\n */\nconst variantAttributes = (props: Props, variants: Variants): Props => {\n const { size, variant, ...rest } = props\n return {\n ...rest,\n ...(variants === 'variant' &&\n (variant === 'primary' || variant === 'ghost') && { 'data-nave-variant': variant }),\n ...(isOffDefault(size, variants) && { 'data-nave-size': size }),\n }\n}\n\nconst build = (\n part: ElementType,\n own: string,\n variants: Variants | undefined,\n): ForwardRefExoticComponent<Props & RefAttributes<unknown>> =>\n forwardRef<unknown, Props>(function NaveBaseUiPart(props, ref) {\n const forwarded = variants === undefined ? props : variantAttributes(props, variants)\n const className = useClassName(own, forwarded.className as ClassName)\n return createElement(part, { ...forwarded, className, ref })\n })\n\n/**\n * The wrapped part, or nothing where the installed Base UI has no such part (one younger than the\n * peer floor): the export stays absent instead of becoming a component that throws when rendered.\n */\nconst wrap = <T>(part: unknown, className: string, variants: Variants | undefined): T =>\n part === undefined\n ? (part as T)\n : (build(part as ElementType, className, variants) as unknown as T)\n\n/**\n * A part that is Base UI's own, with `className` composed. Typed as the part it wraps. A part the\n * installed Base UI does not have stays absent.\n */\nexport const wrapPart = <P>(part: P, className: string): P => wrap<P>(part, className, undefined)\n\n/**\n * A part of the Button family: as `wrapPart`, and its props gain `variant` and `size`. The type it\n * is given is the type the generated module declares for it, written from Base UI's own public\n * `Props` so that a generic part (a trigger's `Payload`) stays generic.\n */\nexport const wrapVariantPart = <T>(part: unknown, className: string): T =>\n wrap<T>(part, className, 'variant')\n\n/**\n * A part that gains `size` alone, as the Toggle does. A part the installed Base UI does not have\n * stays absent, as for `wrapPart`.\n */\nexport const wrapSizePart = <T>(part: unknown, className: string): T =>\n wrap<T>(part, className, 'size')\n\n/**\n * A part that gains `size` with the Avatar's three values. A part the installed Base UI does not\n * have stays absent, as for `wrapPart`.\n */\nexport const wrapAvatarPart = <T>(part: unknown, className: string): T =>\n wrap<T>(part, className, 'avatar')\n",
26
+ "path": "registry/nave/nave-autocomplete.wrap.ts",
27
+ "target": "components/nave/nave-autocomplete.wrap.ts",
28
+ "type": "registry:file"
29
+ },
30
+ {
31
+ "content": "/* SPDX-License-Identifier: MIT */\n/* Copyright (c) 2026 Nave Contributors. From NaveCSS (https://github.com/navecss/navecss), under the MIT License; the full text is in NAVECSS-LICENSE. */\n@layer tokens.defaults, tokens.presets, reset, atomic, components.nave, components.consumer, overrides;\n\n@layer components.consumer {\n .listPopup {\n box-sizing: border-box;\n background-color: var(--nave-color-surface-overlay);\n color: var(--nave-color-content-primary);\n border: var(--nave-border-width-sm) solid var(--nave-color-border-default);\n border-radius: var(--nave-radius-control);\n box-shadow: var(--nave-shadow-overlay);\n padding: var(--nave-spacing-control-sm);\n font-size: var(--nave-font-size-sm);\n min-inline-size: var(--anchor-width);\n max-block-size: var(--available-height);\n overflow-y: auto;\n scroll-padding: var(--nave-spacing-control-sm);\n }\n .arrow {\n &[data-side=\"top\"],\n &[data-side=\"bottom\"],\n &[data-side=\"left\"],\n &[data-side=\"right\"] {\n position: absolute;\n box-sizing: border-box;\n inline-size: 8px;\n block-size: 8px;\n background-color: inherit;\n border-style: inherit;\n border-width: inherit;\n border-color: inherit;\n border-top-style: none;\n border-left-style: none;\n }\n\n &[data-side=\"top\"] {\n bottom: -4px;\n rotate: 45deg;\n }\n\n &[data-side=\"bottom\"] {\n top: -4px;\n rotate: 225deg;\n }\n\n &[data-side=\"left\"] {\n right: -4px;\n rotate: -45deg;\n }\n\n &[data-side=\"right\"] {\n left: -4px;\n rotate: 135deg;\n }\n }\n .item {\n display: flex;\n align-items: center;\n gap: var(--nave-spacing-control-sm);\n padding: var(--nave-spacing-control-sm) var(--nave-spacing-control-md);\n cursor: default;\n user-select: none;\n &[aria-disabled=\"true\"] {\n color: var(--nave-color-content-disabled);\n }\n & {\n /* stylelint-disable-next-line declaration-property-value-disallowed-list -- the outline the &:focus-visible rule for this class draws replaces the browser's default focus indicator; keep that rule while this declaration stays. */\n outline: none;\n }\n &:focus-visible {\n outline-style: solid;\n outline-width: var(--nave-border-width-focus, 2px);\n outline-color: var(--nave-color-border-focus, currentColor);\n outline-offset: 2px;\n }\n }\n .separator {\n border: 0;\n block-size: var(--nave-border-width-sm);\n margin-block: var(--nave-spacing-control-xs);\n background-color: var(--nave-color-border-default);\n }\n .groupLabel {\n padding: var(--nave-spacing-control-sm) var(--nave-spacing-control-md);\n font-size: var(--nave-font-size-xs);\n font-weight: var(--nave-font-weight-medium);\n color: var(--nave-color-content-secondary);\n }\n .selectIcon {\n display: inline-flex;\n flex: none;\n }\n .numberFieldInput {\n flex: 1;\n min-inline-size: 0;\n padding-block: 0;\n padding-inline: var(--nave-spacing-control-md);\n border: 0;\n background-color: transparent;\n color: inherit;\n font-family: inherit;\n font-size: var(--nave-font-size-sm);\n &::placeholder {\n color: var(--nave-color-content-tertiary);\n opacity: 1;\n }\n & {\n /* stylelint-disable-next-line declaration-property-value-disallowed-list -- the outline the &:focus-visible rule for this class draws replaces the browser's default focus indicator; keep that rule while this declaration stays. */\n outline: none;\n }\n &:focus-visible {\n outline-style: solid;\n outline-width: var(--nave-border-width-focus, 2px);\n outline-color: var(--nave-color-border-focus, currentColor);\n outline-offset: 2px;\n }\n }\n .numberFieldStepper {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n inline-size: var(--nave-size-control-sm);\n padding: 0;\n border: 0;\n background-color: transparent;\n color: inherit;\n font-family: inherit;\n cursor: pointer;\n &:disabled,\n &[aria-disabled=\"true\"] {\n color: var(--nave-color-content-disabled);\n cursor: not-allowed;\n }\n }\n .itemHighlight {\n border-radius: var(--nave-radius-sm);\n &[data-highlighted]:not([aria-disabled=\"true\"]) {\n background-color: var(--nave-color-action-highlight);\n }\n }\n .activeOption {\n position: relative;\n &[data-highlighted]::before {\n content: \"\";\n position: absolute;\n inset: calc(-1 * (var(--nave-border-width-focus, 2px) + 2px));\n border-style: solid;\n border-width: var(--nave-border-width-focus, 2px);\n border-color: var(--nave-color-border-focus, currentColor);\n border-radius: calc(\n var(--nave-radius-sm) + var(--nave-border-width-focus, 2px) + 2px\n );\n pointer-events: none;\n }\n }\n .popupFade {\n transition-property: opacity;\n transition-duration: var(--nave-motion-duration-fast);\n transition-timing-function: var(--nave-motion-easing-decelerate);\n &[data-starting-style],\n &[data-ending-style] {\n opacity: 0;\n }\n &[data-ending-style] {\n transition-timing-function: var(--nave-motion-easing-accelerate);\n }\n @media (prefers-reduced-motion: reduce) {\n &,\n &[data-instant] {\n transition-duration: calc(0 * var(--nave-motion-duration-fast));\n }\n }\n }\n .arrowInline {\n &[data-side=\"inline-start\"],\n &[data-side=\"inline-end\"] {\n position: absolute;\n box-sizing: border-box;\n inline-size: 8px;\n block-size: 8px;\n background-color: inherit;\n border-style: inherit;\n border-width: inherit;\n border-color: inherit;\n border-top-style: none;\n border-left-style: none;\n }\n\n &[data-side=\"inline-start\"] {\n inset-inline-end: -4px;\n rotate: -45deg;\n }\n\n &[data-side=\"inline-end\"] {\n inset-inline-start: -4px;\n rotate: 135deg;\n }\n\n &[data-side=\"inline-start\"]:dir(rtl) {\n rotate: 135deg;\n }\n\n &[data-side=\"inline-end\"]:dir(rtl) {\n rotate: -45deg;\n }\n }\n .inputGroup {\n box-sizing: border-box;\n display: flex;\n align-items: stretch;\n min-block-size: var(--nave-size-control-md);\n border: var(--nave-border-width-sm) solid var(--nave-color-border-control);\n border-radius: var(--nave-radius-control);\n background-color: transparent;\n color: var(--nave-color-content-primary);\n &[data-invalid]:not([data-disabled]) {\n border-color: var(--nave-color-feedback-danger);\n border-width: var(--nave-border-width-mark);\n }\n &[data-disabled] {\n border-color: var(--nave-color-border-disabled);\n color: var(--nave-color-content-disabled);\n }\n }\n .comboboxTrigger {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n inline-size: var(--nave-size-control-sm);\n padding: 0;\n border: 0;\n background-color: transparent;\n color: inherit;\n font-family: inherit;\n cursor: pointer;\n &[aria-haspopup=\"dialog\"] {\n inline-size: auto;\n min-block-size: var(--nave-size-control-md);\n justify-content: space-between;\n gap: var(--nave-spacing-control-sm);\n padding-inline: var(--nave-spacing-control-md);\n border: var(--nave-border-width-sm) solid var(--nave-color-border-control);\n border-radius: var(--nave-radius-control);\n color: var(--nave-color-content-primary);\n font-size: var(--nave-font-size-sm);\n text-align: start;\n }\n &[aria-haspopup=\"dialog\"][aria-invalid=\"true\"] {\n border-color: var(--nave-color-feedback-danger);\n border-width: var(--nave-border-width-mark);\n padding-inline: calc(\n var(--nave-spacing-control-md) - var(--nave-border-width-mark) +\n var(--nave-border-width-sm)\n );\n }\n &:disabled,\n &[aria-disabled=\"true\"] {\n color: var(--nave-color-content-disabled);\n cursor: not-allowed;\n }\n &[aria-haspopup=\"dialog\"]:disabled,\n &[aria-haspopup=\"dialog\"][aria-disabled=\"true\"] {\n border-color: var(--nave-color-border-disabled);\n }\n & {\n /* stylelint-disable-next-line declaration-property-value-disallowed-list -- the outline the &:focus-visible rule for this class draws replaces the browser's default focus indicator; keep that rule while this declaration stays. */\n outline: none;\n }\n &:focus-visible {\n outline-style: solid;\n outline-width: var(--nave-border-width-focus, 2px);\n outline-color: var(--nave-color-border-focus, currentColor);\n outline-offset: 2px;\n }\n }\n .listEmpty {\n font-size: var(--nave-font-size-sm);\n color: var(--nave-color-content-secondary);\n [data-empty] > & {\n padding: var(--nave-spacing-control-sm) var(--nave-spacing-control-md);\n }\n }\n}\n",
32
+ "path": "registry/nave/nave-autocomplete.module.css",
33
+ "target": "components/nave/nave-autocomplete.module.css",
34
+ "type": "registry:file"
35
+ },
36
+ {
37
+ "content": "MIT License\n\nCopyright (c) 2026 Nave Contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n",
38
+ "path": "registry/nave/NAVECSS-LICENSE",
39
+ "target": "components/nave/NAVECSS-LICENSE",
40
+ "type": "registry:file"
41
+ }
42
+ ],
43
+ "meta": {
44
+ "peerDependencies": {
45
+ "@base-ui/react": "^1.3.0",
46
+ "@navecss/tokens": ">=0.4.0 <1.0.0",
47
+ "react": "^18 || ^19",
48
+ "react-dom": "^18 || ^19"
49
+ },
50
+ "version": "0.3.0"
51
+ },
52
+ "name": "base-ui-autocomplete",
53
+ "title": "NaveCSS styling of Base UI Autocomplete",
54
+ "type": "registry:item"
55
+ }