Namespaces
Flat
tsx
<Menu><MenuButton /><MenuPopover><MenuItem /><MenuItem /></MenuPopover></Menu>
Dot
tsx
<Menu.Root><Menu.Button /><Menu.Popover><Menu.Item /><Menu.Item /></Menu.Popover></Menu.Root>
Overloaded
tsx
<Menu><Menu.Button /><Menu.Popover><Menu.Item /><Menu.Item /></Menu.Popover></Menu>
Exports
Named
tsx
export function Menu() {}export function MenuButton() {}// ...
Object
tsx
export const Menu = {Root: function MenuRoot() {},Button: function MenuButton() {},// ...};
Note:
export default {}
is also possible, but not ideal.
Overloaded
tsx
export function Menu() {}Menu.Button = function MenuButton() {};// ...
Note:
export default function ...
is also possible, but not ideal.
Imports
Named
tsx
import { Menu, MenuButton } from "ui-package";<Menu><MenuButton />{/* ... */}</Menu>;
Local "as"
tsx
import * as Menu from "ui-package/menu";<Menu.Root><Menu.Button />{/* ... */}</Menu.Root>;
Global "as"
tsx
import * as UI from "ui-package";<UI.Menu><UI.MenuButton />{/* ... */}</UI.Menu>;
Options
Flat + named export
tsx
// Menu.tsxexport function Menu() {}export function MenuButton() {}
Pros and cons:
Score | Description | Notes |
---|---|---|
✅ | Tree-shakable | In all import styles, most bundler tools will tree-shake unused component parts. |
✅ | Auto-imports | IDEs will automatically import the components (or parts) you use. |
❌ | Component autocomplete | At most, you can start typing the name of the component (e.g. "Menu") to filter out other suggestions. |
🟠 | Library autocomplete | The library namespace contains all parts of all components, making it hard to see available components at a glance. |
Supports:
tsx
// named importimport { Menu, MenuButton } from "ui-package"; // or "ui-package/menu"<Menu><MenuButton /></Menu>;
tsx
// global "as" importimport * as UI from "ui-package";<UI.Menu><UI.MenuButton /></UI.Menu>;
Also this (but ew):
tsx
// local "as" importimport * as Menu from "ui-package/menu";<Menu.Menu><Menu.MenuButton /></Menu.Menu>;
Dot + named export
Score | Description | Notes |
---|---|---|
✅ | Tree-shakable | This is the only option for dot namespacing that is tree-shakable. |
❌ | Auto-imports | Users need to manually write the local "as" import every time. |
✅ | Component autocomplete | Suggestions for all parts (and only the parts) will show up after the dot. |
❌ | Library autocomplete | It's not possible to re-export at the top level since that'd cause conflicts (e.g. multiple Root parts of different components). |
tsx
// Menu.tsxexport function Root() {}export function Button() {}
Supports:
tsx
// local "as" importimport * as Menu from "ui-package/menu";<Menu.Root><Menu.Button /></Menu.Root>;
Dot + object export
tsx
// Menu.tsxexport const Menu = {Root: function MenuRoot() {},Button: function MenuButton() {},};
Score | Description | Notes |
---|---|---|
❌ | Tree-shakable | Since it's exported as a single object, it's not tree-shakable. |
✅ | Auto-imports | IDEs will automatically import the components you use. |
✅ | Component autocomplete | Suggestions for all parts (and only the parts) will show up after the dot. |
✅ | Library autocomplete | Only the components (objects) will show up in the library autocomplete (and not their parts). |
Supports:
tsx
// named importimport { Menu } from "ui-package"; // or "ui-package/menu"<Menu.Root><Menu.Button /></Menu.Root>;
tsx
// global "as" importimport * as UI from "ui-package";<UI.Menu.Root><UI.Menu.Button /></UI.Menu.Root>;
Also this (but ew):
tsx
// local "as" importimport * as Menu from "ui-package/menu";<Menu.Menu.Root><Menu.Menu.Button /></Menu.Menu.Root>;
Overloaded
tsx
// Menu.tsxexport function Menu() {}Menu.Button = function MenuButton() {};
Score | Description | Notes |
---|---|---|
❌ | Tree-shakable | Since it's exported as a single function with properties, it's not tree-shakable. |
✅ | Auto-imports | IDEs will automatically import the components you use. |
🟠 | Component autocomplete | Suggestions for all parts will show up after the dot. Unfortunately, so will the function prototype methods and properties (apply , call , etc). |
✅ | Library autocomplete | Only the root components will show up in the library autocomplete (and not their parts). |
Supports:
tsx
// named importimport { Menu } from "ui-package"; // or "ui-package/menu"<Menu><Menu.Button /></Menu>;
tsx
// global "as" importimport * as UI from "ui-package";<UI.Menu><UI.Menu.Button /></UI.Menu>;
Also this (but ew):
tsx
// local "as" importimport * as Menu from "ui-package/menu";<Menu.Menu><Menu.Menu.Button /></Menu.Menu>;