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
tsxexport function Menu() {}export function MenuButton() {}// ...
Object
tsxexport const Menu = {Root: function MenuRoot() {},Button: function MenuButton() {},// ...};
Note:
export default {}is also possible, but not ideal.
Overloaded
tsxexport function Menu() {}Menu.Button = function MenuButton() {};// ...
Note:
export default function ...is also possible, but not ideal.
Imports
Named
tsximport { Menu, MenuButton } from "ui-package";<Menu><MenuButton />{/* ... */}</Menu>;
Local "as"
tsximport * as Menu from "ui-package/menu";<Menu.Root><Menu.Button />{/* ... */}</Menu.Root>;
Global "as"
tsximport * 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>;