@navecss/base-ui 0.2.0 → 0.4.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.
- package/README.md +70 -8
- package/dist/accordion/index.js +0 -1
- package/dist/alert-dialog/index.js +0 -1
- package/dist/autocomplete/index.js +0 -1
- package/dist/avatar/index.js +0 -1
- package/dist/button/index.js +0 -1
- package/dist/checkbox/index.js +0 -1
- package/dist/checkbox-group/index.js +0 -1
- package/dist/collapsible/index.js +0 -1
- package/dist/combobox/index.js +0 -1
- package/dist/combobox/parts.generated.d.ts +0 -2
- package/dist/combobox/parts.generated.js +0 -1
- package/dist/context-menu/index.js +0 -1
- package/dist/css.d.ts +1 -0
- package/dist/dialog/index.js +0 -1
- package/dist/field/index.js +0 -1
- package/dist/fieldset/index.js +0 -1
- package/dist/form/index.js +0 -1
- package/dist/index.js +0 -1
- package/dist/input/index.js +0 -1
- package/dist/menu/index.js +0 -1
- package/dist/menubar/index.js +0 -1
- package/dist/meter/index.js +0 -1
- package/dist/navigation-menu/index.js +0 -1
- package/dist/number-field/index.js +0 -1
- package/dist/part.d.ts +0 -5
- package/dist/popover/index.js +0 -1
- package/dist/preview-card/index.js +0 -1
- package/dist/progress/index.js +0 -1
- package/dist/radio/index.js +0 -1
- package/dist/radio-group/index.js +0 -1
- package/dist/registry/base-ui-accordion.json +55 -0
- package/dist/registry/base-ui-alert-dialog.json +55 -0
- package/dist/registry/base-ui-autocomplete.json +55 -0
- package/dist/registry/base-ui-avatar.json +55 -0
- package/dist/registry/base-ui-button.json +55 -0
- package/dist/registry/base-ui-checkbox-group.json +55 -0
- package/dist/registry/base-ui-checkbox.json +55 -0
- package/dist/registry/base-ui-collapsible.json +55 -0
- package/dist/registry/base-ui-combobox.json +55 -0
- package/dist/registry/base-ui-context-menu.json +55 -0
- package/dist/registry/base-ui-dialog.json +55 -0
- package/dist/registry/base-ui-field.json +55 -0
- package/dist/registry/base-ui-fieldset.json +55 -0
- package/dist/registry/base-ui-input.json +55 -0
- package/dist/registry/base-ui-menu.json +55 -0
- package/dist/registry/base-ui-menubar.json +55 -0
- package/dist/registry/base-ui-meter.json +55 -0
- package/dist/registry/base-ui-navigation-menu.json +55 -0
- package/dist/registry/base-ui-number-field.json +55 -0
- package/dist/registry/base-ui-popover.json +55 -0
- package/dist/registry/base-ui-preview-card.json +55 -0
- package/dist/registry/base-ui-progress.json +55 -0
- package/dist/registry/base-ui-radio-group.json +55 -0
- package/dist/registry/base-ui-radio.json +55 -0
- package/dist/registry/base-ui-scroll-area.json +55 -0
- package/dist/registry/base-ui-select.json +55 -0
- package/dist/registry/base-ui-separator.json +55 -0
- package/dist/registry/base-ui-slider.json +55 -0
- package/dist/registry/base-ui-switch.json +55 -0
- package/dist/registry/base-ui-tabs.json +55 -0
- package/dist/registry/base-ui-toast.json +55 -0
- package/dist/registry/base-ui-toggle-group.json +55 -0
- package/dist/registry/base-ui-toggle.json +55 -0
- package/dist/registry/base-ui-toolbar.json +55 -0
- package/dist/registry/base-ui-tooltip.json +55 -0
- package/dist/registry/registry.json +1757 -0
- package/dist/scroll-area/index.js +0 -1
- package/dist/select/index.js +0 -1
- package/dist/separator/index.js +0 -1
- package/dist/slider/index.js +0 -1
- package/dist/styles.css +33 -15
- package/dist/switch/index.js +0 -1
- package/dist/tabs/index.js +0 -1
- package/dist/toast/index.js +0 -1
- package/dist/toggle/index.js +0 -1
- package/dist/toggle-group/index.js +0 -1
- package/dist/toolbar/index.js +0 -1
- package/dist/tooltip/index.js +0 -1
- package/package.json +31 -20
|
@@ -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 Avatar, 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 { Avatar } from the nave-avatar file just written, not from @navecss/base-ui/avatar.\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.5.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.4.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 Avatar from './nave-avatar.parts'\nexport type * from '@base-ui/react/avatar'\n",
|
|
14
|
+
"path": "registry/nave/nave-avatar.ts",
|
|
15
|
+
"target": "components/nave/nave-avatar.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 { Avatar as Base } from '@base-ui/react/avatar'\nimport styles from './nave-avatar.module.css'\n\nimport { wrapAvatarPart, wrapPart, type AvatarProps } from './nave-avatar.wrap'\n\nexport const Root: (props: Omit<Base.Root.Props, 'ref'> & RefAttributes<HTMLSpanElement> & AvatarProps) => ReactElement = /*#__PURE__*/ (() => wrapAvatarPart(Base.Root, styles.avatar))()\nexport declare namespace Root {\n export type State = Base.Root.State\n export type Props = Base.Root.Props & AvatarProps\n}\nexport const Image: typeof Base.Image = /*#__PURE__*/ (() => wrapPart(Base.Image, styles.avatarImage))()\nexport declare namespace Image {\n export type State = Base.Image.State\n export type Props = Base.Image.Props\n}\nexport const Fallback: typeof Base.Fallback = /*#__PURE__*/ (() => wrapPart(Base.Fallback, styles.avatarFallback))()\nexport declare namespace Fallback {\n export type State = Base.Fallback.State\n export type Props = Base.Fallback.Props\n}\n",
|
|
20
|
+
"path": "registry/nave/nave-avatar.parts.ts",
|
|
21
|
+
"target": "components/nave/nave-avatar.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-avatar.wrap.ts",
|
|
27
|
+
"target": "components/nave/nave-avatar.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 .avatar {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n vertical-align: middle;\n border: var(--nave-border-width-sm) solid var(--nave-color-border-default);\n border-radius: var(--nave-radius-full);\n inline-size: var(--nave-size-avatar-md);\n block-size: var(--nave-size-avatar-md);\n font-size: var(--nave-font-size-sm);\n font-weight: var(--nave-font-weight-medium);\n line-height: var(--nave-line-height-none);\n &[data-nave-size=\"sm\"] {\n inline-size: var(--nave-size-avatar-sm);\n block-size: var(--nave-size-avatar-sm);\n font-size: var(--nave-font-size-xs);\n }\n &[data-nave-size=\"lg\"] {\n inline-size: var(--nave-size-avatar-lg);\n block-size: var(--nave-size-avatar-lg);\n font-size: var(--nave-font-size-xl);\n }\n }\n .avatarImage {\n inline-size: 100%;\n block-size: 100%;\n object-fit: cover;\n border-radius: inherit;\n }\n .avatarFallback {\n display: flex;\n align-items: center;\n justify-content: center;\n inline-size: 100%;\n block-size: 100%;\n border-radius: inherit;\n background-color: var(--nave-color-surface-sunken);\n color: var(--nave-color-content-primary);\n }\n}\n",
|
|
32
|
+
"path": "registry/nave/nave-avatar.module.css",
|
|
33
|
+
"target": "components/nave/nave-avatar.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.5.0 <1.0.0",
|
|
47
|
+
"react": "^18 || ^19",
|
|
48
|
+
"react-dom": "^18 || ^19"
|
|
49
|
+
},
|
|
50
|
+
"version": "0.4.0"
|
|
51
|
+
},
|
|
52
|
+
"name": "base-ui-avatar",
|
|
53
|
+
"title": "NaveCSS styling of Base UI Avatar",
|
|
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 Button, 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 { Button } from the nave-button file just written, not from @navecss/base-ui/button.\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.5.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.4.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 { Button } from './nave-button.parts'\nexport type * from '@base-ui/react/button'\n",
|
|
14
|
+
"path": "registry/nave/nave-button.ts",
|
|
15
|
+
"target": "components/nave/nave-button.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 { Button as Base } from '@base-ui/react/button'\nimport styles from './nave-button.module.css'\n\nimport { wrapVariantPart, type VariantProps } from './nave-button.wrap'\n\nexport const Button: (props: Omit<Base.Props, 'ref'> & RefAttributes<HTMLElement> & VariantProps) => ReactElement = /*#__PURE__*/ (() => wrapVariantPart(Base, styles.button))()\nexport declare namespace Button {\n export type State = Base.State\n export type Props = Base.Props & VariantProps\n}\n",
|
|
20
|
+
"path": "registry/nave/nave-button.parts.ts",
|
|
21
|
+
"target": "components/nave/nave-button.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-button.wrap.ts",
|
|
27
|
+
"target": "components/nave/nave-button.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 .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\"]:is(\n [aria-haspopup=\"menu\"],\n [aria-haspopup=\"true\"],\n [aria-haspopup=\"dialog\"]\n ):not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--nave-color-action-highlight);\n }\n &:not([data-nave-variant=\"primary\"], [data-nave-variant=\"ghost\"]):hover:not(\n :disabled,\n [aria-disabled=\"true\"]\n ) {\n background-color: var(--nave-color-action-secondary-hover);\n }\n &:not(\n [data-nave-variant=\"primary\"],\n [data-nave-variant=\"ghost\"]\n ):active:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--nave-color-action-secondary-active);\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}\n",
|
|
32
|
+
"path": "registry/nave/nave-button.module.css",
|
|
33
|
+
"target": "components/nave/nave-button.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.5.0 <1.0.0",
|
|
47
|
+
"react": "^18 || ^19",
|
|
48
|
+
"react-dom": "^18 || ^19"
|
|
49
|
+
},
|
|
50
|
+
"version": "0.4.0"
|
|
51
|
+
},
|
|
52
|
+
"name": "base-ui-button",
|
|
53
|
+
"title": "NaveCSS styling of Base UI Button",
|
|
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 Checkbox Group, 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 { CheckboxGroup } from the nave-checkbox-group file just written, not from @navecss/base-ui/checkbox-group.\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.5.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.4.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 { CheckboxGroup } from './nave-checkbox-group.parts'\nexport type * from '@base-ui/react/checkbox-group'\n",
|
|
14
|
+
"path": "registry/nave/nave-checkbox-group.ts",
|
|
15
|
+
"target": "components/nave/nave-checkbox-group.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 { CheckboxGroup as Base } from '@base-ui/react/checkbox-group'\nimport styles from './nave-checkbox-group.module.css'\n\nimport { wrapPart } from './nave-checkbox-group.wrap'\n\nexport const CheckboxGroup: typeof Base = /*#__PURE__*/ (() => wrapPart(Base, styles.choiceGroup))()\nexport declare namespace CheckboxGroup {\n export type State = Base.State\n export type Props = Base.Props\n export type ChangeEventReason = Base.ChangeEventReason\n export type ChangeEventDetails = Base.ChangeEventDetails\n}\n",
|
|
20
|
+
"path": "registry/nave/nave-checkbox-group.parts.ts",
|
|
21
|
+
"target": "components/nave/nave-checkbox-group.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-checkbox-group.wrap.ts",
|
|
27
|
+
"target": "components/nave/nave-checkbox-group.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 .choiceGroup {\n display: flex;\n flex-direction: column;\n gap: var(--nave-spacing-control-sm);\n }\n}\n",
|
|
32
|
+
"path": "registry/nave/nave-checkbox-group.module.css",
|
|
33
|
+
"target": "components/nave/nave-checkbox-group.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.5.0 <1.0.0",
|
|
47
|
+
"react": "^18 || ^19",
|
|
48
|
+
"react-dom": "^18 || ^19"
|
|
49
|
+
},
|
|
50
|
+
"version": "0.4.0"
|
|
51
|
+
},
|
|
52
|
+
"name": "base-ui-checkbox-group",
|
|
53
|
+
"title": "NaveCSS styling of Base UI Checkbox Group",
|
|
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 Checkbox, 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 { Checkbox } from the nave-checkbox file just written, not from @navecss/base-ui/checkbox.\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.5.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.4.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 Checkbox from './nave-checkbox.parts'\nexport type * from '@base-ui/react/checkbox'\n",
|
|
14
|
+
"path": "registry/nave/nave-checkbox.ts",
|
|
15
|
+
"target": "components/nave/nave-checkbox.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 { Checkbox as Base } from '@base-ui/react/checkbox'\nimport styles from './nave-checkbox.module.css'\n\nimport { wrapPart } from './nave-checkbox.wrap'\n\nexport const Root: typeof Base.Root = /*#__PURE__*/ (() => wrapPart(Base.Root, styles.checkbox))()\nexport declare namespace Root {\n export type State = Base.Root.State\n export type Props = Base.Root.Props\n export type ChangeEventReason = Base.Root.ChangeEventReason\n export type ChangeEventDetails = Base.Root.ChangeEventDetails\n}\nexport const Indicator: typeof Base.Indicator = /*#__PURE__*/ (() => wrapPart(Base.Indicator, styles.checkboxIndicator))()\nexport declare namespace Indicator {\n export type State = Base.Indicator.State\n export type Props = Base.Indicator.Props\n}\n",
|
|
20
|
+
"path": "registry/nave/nave-checkbox.parts.ts",
|
|
21
|
+
"target": "components/nave/nave-checkbox.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-checkbox.wrap.ts",
|
|
27
|
+
"target": "components/nave/nave-checkbox.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 .checkbox {\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-icon-sm);\n block-size: var(--nave-size-icon-sm);\n border: var(--nave-border-width-sm) solid var(--nave-color-border-control);\n border-radius: var(--nave-radius-sm);\n background-color: transparent;\n color: var(--nave-color-content-primary);\n cursor: pointer;\n position: relative;\n &[aria-invalid=\"true\"] {\n border-color: var(--nave-color-feedback-danger);\n border-width: var(--nave-border-width-mark);\n }\n &[aria-disabled=\"true\"] {\n border-color: var(--nave-color-border-disabled);\n color: var(--nave-color-content-disabled);\n cursor: not-allowed;\n }\n &::before {\n content: \"\";\n position: absolute;\n inset-block-start: 50%;\n inset-inline-start: 50%;\n inline-size: var(--nave-size-control-xs);\n block-size: var(--nave-size-control-xs);\n margin-block-start: calc(var(--nave-size-control-xs) / -2);\n margin-inline-start: calc(var(--nave-size-control-xs) / -2);\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 .checkboxIndicator {\n box-sizing: border-box;\n display: block;\n inline-size: 0.3125rem;\n block-size: 0.5625rem;\n margin-block-start: -0.125rem;\n border-right: var(--nave-border-width-mark) solid currentColor;\n border-bottom: var(--nave-border-width-mark) solid currentColor;\n rotate: 45deg;\n [aria-checked=\"mixed\"] > & {\n inline-size: 0.5rem;\n block-size: 0;\n margin-block-start: 0;\n border-right-style: none;\n rotate: 0deg;\n }\n }\n}\n",
|
|
32
|
+
"path": "registry/nave/nave-checkbox.module.css",
|
|
33
|
+
"target": "components/nave/nave-checkbox.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.5.0 <1.0.0",
|
|
47
|
+
"react": "^18 || ^19",
|
|
48
|
+
"react-dom": "^18 || ^19"
|
|
49
|
+
},
|
|
50
|
+
"version": "0.4.0"
|
|
51
|
+
},
|
|
52
|
+
"name": "base-ui-checkbox",
|
|
53
|
+
"title": "NaveCSS styling of Base UI Checkbox",
|
|
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 Collapsible, 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 { Collapsible } from the nave-collapsible file just written, not from @navecss/base-ui/collapsible.\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.5.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.4.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 Collapsible from './nave-collapsible.parts'\nexport type * from '@base-ui/react/collapsible'\n",
|
|
14
|
+
"path": "registry/nave/nave-collapsible.ts",
|
|
15
|
+
"target": "components/nave/nave-collapsible.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 { Collapsible as Base } from '@base-ui/react/collapsible'\nimport styles from './nave-collapsible.module.css'\n\nimport { wrapPart } from './nave-collapsible.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 = Base.Root.Props\n export type ChangeEventReason = Base.Root.ChangeEventReason\n export type ChangeEventDetails = Base.Root.ChangeEventDetails\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.collapsiblePanel))()\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-collapsible.parts.ts",
|
|
21
|
+
"target": "components/nave/nave-collapsible.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-collapsible.wrap.ts",
|
|
27
|
+
"target": "components/nave/nave-collapsible.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 .collapsiblePanel {\n box-sizing: border-box;\n overflow: hidden;\n padding-inline: var(--nave-spacing-control-xs);\n height: var(--collapsible-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-collapsible.module.css",
|
|
33
|
+
"target": "components/nave/nave-collapsible.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.5.0 <1.0.0",
|
|
47
|
+
"react": "^18 || ^19",
|
|
48
|
+
"react-dom": "^18 || ^19"
|
|
49
|
+
},
|
|
50
|
+
"version": "0.4.0"
|
|
51
|
+
},
|
|
52
|
+
"name": "base-ui-collapsible",
|
|
53
|
+
"title": "NaveCSS styling of Base UI Collapsible",
|
|
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 Combobox, 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 { Combobox } from the nave-combobox file just written, not from @navecss/base-ui/combobox.\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.5.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.4.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 Combobox from './nave-combobox.parts'\nexport type * from '@base-ui/react/combobox'\n",
|
|
14
|
+
"path": "registry/nave/nave-combobox.ts",
|
|
15
|
+
"target": "components/nave/nave-combobox.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 { Combobox as Base } from '@base-ui/react/combobox'\nimport styles from './nave-combobox.module.css'\n\nimport { wrapPart } from './nave-combobox.wrap'\n\nexport const Root: typeof Base.Root = /*#__PURE__*/ (() => Base.Root)()\nexport declare namespace Root {\n export type Props<Value, Multiple extends boolean | undefined = false> = Base.Root.Props<Value, Multiple>\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 Label: typeof Base.Label = /*#__PURE__*/ (() => wrapPart(Base.Label, styles.label))()\nexport declare namespace Label {\n export type State = Base.Label.State\n export type Props = Base.Label.Props\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 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 declare namespace InputGroup {\n export type State = Base.InputGroup.State\n export type Props = Base.InputGroup.Props\n}\nexport const Trigger: typeof Base.Trigger = /*#__PURE__*/ (() => wrapPart(Base.Trigger, styles.comboboxTrigger))()\nexport declare namespace Trigger {\n export type State = Base.Trigger.State\n export type Props = Base.Trigger.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 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 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 declare namespace Item {\n export type State = Base.Item.State\n export type Props = Base.Item.Props\n}\nexport const ItemIndicator: typeof Base.ItemIndicator = /*#__PURE__*/ (() => Base.ItemIndicator)()\nexport declare namespace ItemIndicator {\n export type Props = Base.ItemIndicator.Props\n export type State = Base.ItemIndicator.State\n}\nexport const Chips: typeof Base.Chips = /*#__PURE__*/ (() => wrapPart(Base.Chips, styles.chips))()\nexport declare namespace Chips {\n export type State = Base.Chips.State\n export type Props = Base.Chips.Props\n}\nexport const Chip: typeof Base.Chip = /*#__PURE__*/ (() => wrapPart(Base.Chip, styles.chip))()\nexport declare namespace Chip {\n export type State = Base.Chip.State\n export type Props = Base.Chip.Props\n}\nexport const ChipRemove: typeof Base.ChipRemove = /*#__PURE__*/ (() => wrapPart(Base.ChipRemove, styles.chipRemove))()\nexport declare namespace ChipRemove {\n export type State = Base.ChipRemove.State\n export type Props = Base.ChipRemove.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 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 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-combobox.parts.ts",
|
|
21
|
+
"target": "components/nave/nave-combobox.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-combobox.wrap.ts",
|
|
27
|
+
"target": "components/nave/nave-combobox.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 .label {\n font-size: var(--nave-font-size-sm);\n font-weight: var(--nave-font-weight-medium);\n color: var(--nave-color-content-primary);\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 .chips {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n flex: 1;\n min-inline-size: 0;\n gap: var(--nave-spacing-control-sm);\n padding: var(--nave-spacing-control-sm);\n }\n .chip {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n gap: var(--nave-spacing-control-xs);\n min-block-size: calc(\n var(--nave-size-control-xs) + 2 * var(--nave-border-width-sm)\n );\n padding-inline: var(--nave-spacing-control-sm)\n var(--nave-spacing-control-xs);\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 font-size: var(--nave-font-size-sm);\n line-height: var(--nave-line-height-tight);\n cursor: default;\n &[aria-disabled=\"true\"] {\n border-color: var(--nave-color-border-disabled);\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 .chipRemove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n align-self: stretch;\n inline-size: var(--nave-size-control-xs);\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 .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-combobox.module.css",
|
|
33
|
+
"target": "components/nave/nave-combobox.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.5.0 <1.0.0",
|
|
47
|
+
"react": "^18 || ^19",
|
|
48
|
+
"react-dom": "^18 || ^19"
|
|
49
|
+
},
|
|
50
|
+
"version": "0.4.0"
|
|
51
|
+
},
|
|
52
|
+
"name": "base-ui-combobox",
|
|
53
|
+
"title": "NaveCSS styling of Base UI Combobox",
|
|
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 Context Menu, 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 { ContextMenu } from the nave-context-menu file just written, not from @navecss/base-ui/context-menu.\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.5.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.4.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 ContextMenu from './nave-context-menu.parts'\nexport type * from '@base-ui/react/context-menu'\n",
|
|
14
|
+
"path": "registry/nave/nave-context-menu.ts",
|
|
15
|
+
"target": "components/nave/nave-context-menu.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 { ContextMenu as Base } from '@base-ui/react/context-menu'\nimport styles from './nave-context-menu.module.css'\n\nimport { wrapPart } from './nave-context-menu.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 = Base.Root.Props\n export type ChangeEventReason = Base.Root.ChangeEventReason\n export type ChangeEventDetails = Base.Root.ChangeEventDetails\n}\nexport const Trigger: typeof Base.Trigger = /*#__PURE__*/ (() => Base.Trigger)()\nexport declare namespace Trigger {\n export type State = Base.Trigger.State\n export type Props = Base.Trigger.Props\n}\nexport const Backdrop: typeof Base.Backdrop = /*#__PURE__*/ (() => Base.Backdrop)()\nexport declare namespace Backdrop {\n export type State = Base.Backdrop.State\n export type Props = Base.Backdrop.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 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.popupMotion}`))()\nexport declare namespace Popup {\n export type Props = Base.Popup.Props\n export type State = Base.Popup.State\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 Props = Base.Group.Props\n export type State = Base.Group.State\n}\nexport const GroupLabel: typeof Base.GroupLabel = /*#__PURE__*/ (() => wrapPart(Base.GroupLabel, styles.groupLabel))()\nexport declare namespace GroupLabel {\n export type Props = Base.GroupLabel.Props\n export type State = Base.GroupLabel.State\n}\nexport const Item: typeof Base.Item = /*#__PURE__*/ (() => wrapPart(Base.Item, `${styles.item} ${styles.itemHighlight}`))()\nexport declare namespace Item {\n export type State = Base.Item.State\n export type Props = Base.Item.Props\n}\nexport const CheckboxItem: typeof Base.CheckboxItem = /*#__PURE__*/ (() => wrapPart(Base.CheckboxItem, `${styles.item} ${styles.itemHighlight}`))()\nexport declare namespace CheckboxItem {\n export type State = Base.CheckboxItem.State\n export type Props = Base.CheckboxItem.Props\n export type ChangeEventReason = Base.CheckboxItem.ChangeEventReason\n export type ChangeEventDetails = Base.CheckboxItem.ChangeEventDetails\n}\nexport const CheckboxItemIndicator: typeof Base.CheckboxItemIndicator = /*#__PURE__*/ (() => Base.CheckboxItemIndicator)()\nexport declare namespace CheckboxItemIndicator {\n export type Props = Base.CheckboxItemIndicator.Props\n export type State = Base.CheckboxItemIndicator.State\n}\nexport const LinkItem: typeof Base.LinkItem = /*#__PURE__*/ (() => wrapPart(Base.LinkItem, `${styles.item} ${styles.itemHighlight}`))()\nexport declare namespace LinkItem {\n export type State = Base.LinkItem.State\n export type Props = Base.LinkItem.Props\n}\nexport const RadioGroup: typeof Base.RadioGroup = /*#__PURE__*/ (() => Base.RadioGroup)()\nexport declare namespace RadioGroup {\n export type Props = Base.RadioGroup.Props\n export type State = Base.RadioGroup.State\n export type ChangeEventReason = Base.RadioGroup.ChangeEventReason\n export type ChangeEventDetails = Base.RadioGroup.ChangeEventDetails\n}\nexport const RadioItem: typeof Base.RadioItem = /*#__PURE__*/ (() => wrapPart(Base.RadioItem, `${styles.item} ${styles.itemHighlight}`))()\nexport declare namespace RadioItem {\n export type State = Base.RadioItem.State\n export type Props = Base.RadioItem.Props\n}\nexport const RadioItemIndicator: typeof Base.RadioItemIndicator = /*#__PURE__*/ (() => Base.RadioItemIndicator)()\nexport declare namespace RadioItemIndicator {\n export type Props = Base.RadioItemIndicator.Props\n export type State = Base.RadioItemIndicator.State\n}\nexport const SubmenuRoot: typeof Base.SubmenuRoot = /*#__PURE__*/ (() => Base.SubmenuRoot)()\nexport declare namespace SubmenuRoot {\n export type Props = Base.SubmenuRoot.Props\n export type State = Base.SubmenuRoot.State\n export type ChangeEventReason = Base.SubmenuRoot.ChangeEventReason\n export type ChangeEventDetails = Base.SubmenuRoot.ChangeEventDetails\n}\nexport const SubmenuTrigger: typeof Base.SubmenuTrigger = /*#__PURE__*/ (() => wrapPart(Base.SubmenuTrigger, `${styles.item} ${styles.itemHighlight}`))()\nexport declare namespace SubmenuTrigger {\n export type Props = Base.SubmenuTrigger.Props\n export type State = Base.SubmenuTrigger.State\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}\n",
|
|
20
|
+
"path": "registry/nave/nave-context-menu.parts.ts",
|
|
21
|
+
"target": "components/nave/nave-context-menu.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-context-menu.wrap.ts",
|
|
27
|
+
"target": "components/nave/nave-context-menu.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 .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 .popupMotion {\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 &[data-instant] {\n transition-duration: var(--nave-motion-duration-instant);\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}\n",
|
|
32
|
+
"path": "registry/nave/nave-context-menu.module.css",
|
|
33
|
+
"target": "components/nave/nave-context-menu.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.5.0 <1.0.0",
|
|
47
|
+
"react": "^18 || ^19",
|
|
48
|
+
"react-dom": "^18 || ^19"
|
|
49
|
+
},
|
|
50
|
+
"version": "0.4.0"
|
|
51
|
+
},
|
|
52
|
+
"name": "base-ui-context-menu",
|
|
53
|
+
"title": "NaveCSS styling of Base UI Context Menu",
|
|
54
|
+
"type": "registry:item"
|
|
55
|
+
}
|