# @3dsource/source-ui > All local file paths in this document are relative to the package root (`@3dsource/source-ui/`). > Higher-level components built on top of Angular CDK and Angular Material. Provides custom styling for Angular Material form fields (input, select, autocomplete, checkbox, radio, toggle) and ngx-toastr toast notifications to match the Source UI design system. Requires `@3dsource/source-ui-native` (always installed together), `@angular/material`, `@angular/cdk`, and — optionally — `ngx-toastr`. Applications using swiper mode provide `swiper` themselves; it is not declared as a package dependency. See `package.json` for supported peer ranges. Components: breadcrumbs, color-picker, modal (CDK), popover, slider-group, tab-line, tooltip. Rules that apply to every task — the guides below explain each one: - Install and set up `@3dsource/source-ui-native` first ([its llms.txt](../source-ui-native/llms.txt)); this package adds `@use '../node_modules/@3dsource/source-ui/styles/source.ui.scss' as source-ui;` after the native stylesheet. - Importing `source.ui.scss` restyles Angular Material form fields app-wide: use stock Material markup with `
` above the field and `` below it, never ``, `` or ``. - Provide `MAT_FORM_FIELD_DEFAULT_OPTIONS` with `{ appearance: 'outline' }` in the app providers, or the form-field styling does not apply. - Wrap `` children of `` and `` in `
`, or the panel is unstyled. - `SourcePopoverService` is not provided in root: add it to the `providers` of the component that injects it. Popover content is a `TemplateRef`. - Use `` for tabs (`SourceTabsComponent`/`SourceTabComponent` are deprecated). For new modals prefer `SourceModalNativeService` from the native package; the CDK `SourceModalComponent` stays supported. ## Source Element vs Source Component Two parallel ways to style markup: - **Source Component** — Angular component with signal inputs/outputs. Imported by class (e.g. `import { SourceButtonComponent } from '@3dsource/source-ui-native'`) and used as a tag: ``, ``, ``, ``. - **Source Element** — CSS-only BEM class on a native HTML tag. No import — styles come from the stylesheet. Example: ` ... ``` For several or changing anchors, pass the origin from the template instead of `viewChild`: each button opens the popover next to itself. ```html @for (item of items; track item.id) { } ... ``` ```ts open(origin: CdkOverlayOrigin, tpl: TemplateRef) { this.overlayRef = this.popover.show(origin, this.vcr, { srcPopoverTpl: tpl }); } ``` **Methods:** - `show(origin: CdkOverlayOrigin, vcr: ViewContainerRef, override: Partial): OverlayRef` - `closePopover(overlayRef: OverlayRef): void` **`override` fields** (`Partial`: every field is optional, the service fills in the defaults): - `srcPopoverTpl: TemplateRef` — the content; needed in practice (templates only; components are not supported) - `headerTitle: string` - `hasBackButton: boolean`, `hasCloseButton: boolean` - `popoverMaxHeight: string` - `panelCustomClass: string` - `breakpointDesktop: string` — a media query, default `'(min-width: 1024px)'`; while it does not match, the popover is a bottom drawer - `position: ConnectedPosition[]` — preferred placements, tried in order (from `@angular/cdk/overlay`) - `hasBackdrop: boolean` — the service does not close the popover on a backdrop click; subscribe to `backdropClick()`, as above - `closeOnBackdropClick: boolean` — not used by the service - `testID: string` `` opens the same popover from a wrapped trigger element ([SourcePopoverTriggerComponent API](./docs/components/popover-trigger.md)); both ways are equal. ### CDK Dialog for SourceModalComponent Open `SourceModalComponent` with CDK `Dialog` from `@angular/cdk/dialog`: inject it into a field (`private dialog = inject(Dialog)`), then call `this.dialog.open(SourceModalComponent, { data })`. Pass the result and data types explicitly, or `data` is not checked against `SourceModalData` and `ref.closed` emits `unknown`. Examples, all `SourceModalData` fields and the footer button types: [SourceModalComponent API](./docs/components/modal.md). - Never put `` in a template: the component works only when opened through `Dialog` or `SourceModalNativeService`. - Every footer button closes the modal with the value its `action()` returns. Return the result from `action`; do not call `ref.close()` inside it. - `ref.closed` emits that value, or `undefined` after Esc, a backdrop click or the header close button. - For a form or any custom layout, open your own component with `dialog.open(YourComponent)` and use the `src-modal` BEM markup inside it. ## Toastr styling `@3dsource/source-ui` styles [ngx-toastr](https://www.npmjs.com/package/ngx-toastr) to match the Source UI design system. ### Default (global) toasts Install `ngx-toastr`, import its stylesheet, register the provider, and use the standard `ToastrService` API. ngx-toastr 20 still declares an Angular 21 peer range: on Angular 22, install it with `npm install ngx-toastr --legacy-peer-deps` (pnpm only warns). The ngx-toastr stylesheet places the toast container and lays out the toasts. Import it before the source-ui stylesheet, so that the source-ui styles override the default `.toast-container` / `.toast-success` / `.toast-error` / `.toast-warning` / `.toast-info` / `.toast-message` / `.toast-close-button` selectors: ```scss @use '../node_modules/@3dsource/source-ui-native/styles/source.ui.native.scss' as source-ui-native; @use 'ngx-toastr/toastr'; @use '../node_modules/@3dsource/source-ui/styles/source.ui.scss' as source-ui; ``` ```ts import { provideToastr } from 'ngx-toastr'; providers: [provideToastr()] ``` To adjust a toast, override its custom properties. They are declared on `.toast-container .ngx-toastr`, so set them there in global styles, for example `.toast-container .ngx-toastr { --srcToastrMaxWidth: 480px; }`, or on `.toast-container .ngx-toastr.toast-error` for one type: `--srcToastrBg`, `--srcToastrMinWidth`, `--srcToastrMaxWidth`, `--srcToastrMessageFontSize`, `--srcToastrBorderRadius`, `--srcToastrShadow`. Each type (`.toast-error`, `.toast-info`, `.toast-warning`, `.toast-success`) sets its own `--srcToastrBg`. ### Inline toasts inside a custom container Use when toasts must render inside a specific DOM region (e.g. a panel or preview area) rather than the page overlay. `ToastrService` is provided in root, so all toasts share one container: once `overlayContainer` is set, every toast of the app renders in it. Put the container in a component that stays for the whole life of the app, usually the root component, as the ngx-toastr README advises. Two steps: 1. Register `provideToastr({ positionClass: 'inline' })`. 2. In the hosting component, render a container element with the `toastContainer` directive and wire it to `ToastrService.overlayContainer`: ```ts import { afterNextRender, Component, inject, viewChild } from '@angular/core'; import { ToastContainerDirective, ToastrService } from 'ngx-toastr'; import { SourceButtonComponent } from '@3dsource/source-ui-native'; @Component({ selector: 'my-panel', imports: [ToastContainerDirective, SourceButtonComponent], template: `
Notify `, styles: `:host { position: relative; }`, }) export class MyPanel { readonly toast = viewChild(ToastContainerDirective); private toastrService = inject(ToastrService); _initToastr = afterNextRender(() => { const toast = this.toast(); if (toast) this.toastrService.overlayContainer = toast; }); showToastr() { this.toastrService.show('Hello'); } } ``` The host element must have `position: relative` so the inline container can anchor absolutely positioned toasts. The library also exposes a `.toast-container.inline` selector variant picked up automatically. ## Shared documentation - [@3dsource/source-ui-native llms.txt](../source-ui-native/llms.txt): Key concepts, setup, theming, Source Elements, icons, design tokens, design rules - [Design tokens](../source-ui-native/guides/design-tokens.md): The native guide on which token to pick: the priority order, semantic color layers, gaps, padding, border radius, the spacing scale - [Native full documentation](../source-ui-native/docs/llms-full.txt): Self-contained comprehensive reference for the native library ## Component API reference (inline) > Full API for every component inlined below. No external links needed. ### SourceBreadcrumbItemDirective (@3dsource/source-ui) **Selector:** `[srcBreadcrumbItem]` · **Kind:** Directive **Usage:** ```html {{ item.label }} ``` ### SourceBreadcrumbSeparatorDirective (@3dsource/source-ui) **Selector:** `[srcBreadcrumbSeparator]` · **Kind:** Directive **Usage:** ```html @for (item of items; track item.label; let last = $last) { @if (last) { {{ item.label }} } @else { {{ item.label }} } } ``` ### SourceBreadcrumbsComponent (@3dsource/source-ui) **Selector:** `src-breadcrumbs` · **Kind:** Component **Usage:** ```html @for (item of items; track item.label; let last = $last) { @if (last) { {{ item.label }} } @else { {{ item.label }} } } ``` **Inputs:** | Input | Type | Default | Values | Required | Description | |-------|------|---------|--------|----------|-------------| | ariaLabel | string | "Breadcrumb" | — | no | Accessible label for the