Skip to main content

Components

@modular/sdk/ui is the host's React component, icon, and UI hook surface. Use it inside the components mounted by views and widgets.

Start with the shared components

The generated @modular/sdk/ui reference contains every export from the live SDK. It is generated from the same TypeDoc artifact as the rest of the reference, so new components appear without a hand-maintained list.

import { function Button({ block, children, className, componentProps, disabled, endIcon, icon, iconPosition, loading, nativeButton, ref, render, shape, size, type, variant, withoutHoverStyle, ...otherProps }: ButtonProps): import("react").JSX.ElementButton, const Container: ContainerComponentContainer } from '@modular/sdk/ui';

export function function Outline(): JSX.ElementOutline() {
  return (
    <const Container: ContainerComponentContainer
      ContainerProps.title?: ReactNodetitle="Outline"
      ContainerProps.description?: ReactNodedescription="No sections yet."
      ContainerProps.actions?: ReactNodeactions={<function Button({ block, children, className, componentProps, disabled, endIcon, icon, iconPosition, loading, nativeButton, ref, render, shape, size, type, variant, withoutHoverStyle, ...otherProps }: ButtonProps): import("react").JSX.ElementButton ButtonProps.variant?: ButtonVariant | undefinedvariant="primary">Create section</function Button({ block, children, className, componentProps, disabled, endIcon, icon, iconPosition, loading, nativeButton, ref, render, shape, size, type, variant, withoutHoverStyle, ...otherProps }: ButtonProps): import("react").JSX.ElementButton>}
    />
  );
}

These are the same live components the host uses. They follow the active theme, material, type scale, focus treatment, and accessibility behavior without a mod copying that policy into its own CSS.

Read host state from React

useMod() returns the host context for the current UI contribution. useModState(state) subscribes a component to a state handle and re-renders it after a committed write.

import type { interface State<TValue>
A read-only handle to one state value. Returned by `ctx.state('editor.selection')` and the other built-in state names. Reading `.value` gives you the current data, and it tracks: inside an `effect` or a condition predicate, reading it registers a dependency. Use `getSnapshot()` when you want the data without that tracking, and `subscribe()` when you are outside a reactive body and need a callback. Built-in state is never writable from a mod. To change host state, dispatch the matching action with `ctx.action(id, input)`.
@categoryState
State
} from '@modular/sdk/state';
import { function Text({ as: Element, font, color, weight, align, truncate, className, style, children, ref, ...rest }: TextProps): import("react").JSX.ElementText, function useMod(): HostContextuseMod, function useModState<TValue>(state: State<TValue>): StateSnapshot<TValue>useModState } from '@modular/sdk/ui'; interface SectionCountProps { readonly SectionCountProps.count: State<number>count: interface State<TValue>
A read-only handle to one state value. Returned by `ctx.state('editor.selection')` and the other built-in state names. Reading `.value` gives you the current data, and it tracks: inside an `effect` or a condition predicate, reading it registers a dependency. Use `getSnapshot()` when you want the data without that tracking, and `subscribe()` when you are outside a reactive body and need a callback. Built-in state is never writable from a mod. To change host state, dispatch the matching action with `ctx.action(id, input)`.
@categoryState
State
<number>;
} export function function SectionCount({ count }: SectionCountProps): JSX.ElementSectionCount({ count: State<number>count }: SectionCountProps) { const const mod: HostContextmod = function useMod(): HostContextuseMod(); const const snapshot: StateSnapshot<number>snapshot = useModState<number>(state: State<number>): StateSnapshot<number>useModState(count: State<number>count); return ( <function Text({ as: Element, font, color, weight, align, truncate, className, style, children, ref, ...rest }: TextProps): import("react").JSX.ElementText TextProps.as?: TextElement | undefinedas="p" TextProps.font?: TextFont | undefinedfont="body" TextProps.color?: TextColor | undefinedcolor="secondary"> {const mod: HostContextmod.ContextBase.modId: `${string}.${string}` & $brand<"ModId">
The id of the mod this handler belongs to.
modId
}: {const snapshot: StateSnapshot<number>snapshot.StateVersion<number>.value: numbervalue} sections
</function Text({ as: Element, font, color, weight, align, truncate, className, style, children, ref, ...rest }: TextProps): import("react").JSX.ElementText> ); }

Read snapshot.value during render. Reading state.value directly does not subscribe React to later writes. The host already supplies ModHostProvider at the contribution boundary, so a view does not add another provider.

Pick a container variant

Container takes one visual role: default, subtle, elevated, or plain. Ordinary cards and panels use default. Floating panels use elevated. Use plain when the surrounding surface already owns the frame.

import { const Container: ContainerComponentContainer, function Text({ as: Element, font, color, weight, align, truncate, className, style, children, ref, ...rest }: TextProps): import("react").JSX.ElementText } from '@modular/sdk/ui';

export function function Inspector(): JSX.ElementInspector() {
  return (
    <const Container: ContainerComponentContainer ContainerProps.variant?: ContainerVariant | undefinedvariant="default">
      <function Text({ as: Element, font, color, weight, align, truncate, className, style, children, ref, ...rest }: TextProps): import("react").JSX.ElementText TextProps.as?: TextElement | undefinedas="h2" TextProps.font?: TextFont | undefinedfont="h3">Inspector</function Text({ as: Element, font, color, weight, align, truncate, className, style, children, ref, ...rest }: TextProps): import("react").JSX.ElementText>
    </const Container: ContainerComponentContainer>
  );
}

Do not import @tvx/design-system/components directly and do not bundle a separate copy of @modular/sdk/ui. The host injects the live module alongside React. A second copy breaks shared context, hooks, theming, and hot replacement.

Find the exact API

Browse the complete generated reference by kind or filter its sidebar by name. Editor autocomplete remains the fastest discovery path, and hover shows the exact props at the call site.

modular mod docs <mod-id> --symbol Button answers by name from the same TypeDoc artifact. modular mod language <mod-id> --hover answers at a position from the SDK installed with the host.