Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion apps/docs/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
<router-outlet />
} @else {
<docs-sidenav
class="kbq-scrollbar"
[class.docs-sidenav_closed]="!opened"
[class.docs-sidenav_opened]="opened"
[@openCloseSidenav]="opened ? 'open' : 'closed'"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { CdkScrollable } from '@angular/cdk/overlay';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Expand All @@ -15,6 +14,7 @@ import { KbqDividerModule } from '@koobiq/components/divider';
import { KbqIcon } from '@koobiq/components/icon';
import { KbqLinkModule } from '@koobiq/components/link';
import { KbqModalService } from '@koobiq/components/modal';
import { KbqScrollbarViewport } from '@koobiq/components/scrollbar';
import { KbqSidepanelService } from '@koobiq/components/sidepanel';
import { KbqTabsModule } from '@koobiq/components/tabs';
import { filter } from 'rxjs';
Expand Down Expand Up @@ -58,10 +58,10 @@ const GITHUB_REPO_TREE_URL = `https://github.com/koobiq/angular-components/tree/
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
class: 'docs-component-viewer kbq-scrollbar',
class: 'docs-component-viewer',
'[attr.data-docsearch-category]': 'structureCategoryId'
},
hostDirectives: [CdkScrollable]
hostDirectives: [KbqScrollbarViewport]
})
export class DocsComponentViewerComponent extends DocsLocaleState {
protected readonly structureItemTab = DocsStructureItemTab;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { DocsRegisterHeaderDirective } from '../register-header/register-header.
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
class: 'docs-component-viewer kbq-scrollbar',
class: 'docs-component-viewer',
'[attr.data-docsearch-category]': 'structureItem.id'
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { KbqFormFieldModule } from '@koobiq/components/form-field';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqInputModule } from '@koobiq/components/input';
import { KbqModalService } from '@koobiq/components/modal';
import { KbqScrollbarViewport } from '@koobiq/components/scrollbar';
import { KbqToolTipModule } from '@koobiq/components/tooltip';
import type { KbqIconsMetadata } from '@koobiq/icons/types/icons';
import { auditTime, BehaviorSubject, combineLatest, distinctUntilChanged, map, startWith } from 'rxjs';
Expand Down Expand Up @@ -52,8 +53,9 @@ const SEARCH_DEBOUNCE_TIME = 300;
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
class: 'docs-icons-viewer kbq-scrollbar'
}
class: 'docs-icons-viewer'
},
hostDirectives: [KbqScrollbarViewport]
})
export class DocsIconsViewerComponent extends DocsLocaleState {
private readonly http = inject(HttpClient);
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/src/app/components/sidenav/sidenav.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<a routerLink="/" class="docs-sidenav__header" [class.docs-top-overflown]="docStates.navbarTopOverflown.value">
<a routerLink="/" class="docs-sidenav__header" [class.docs-top-overflown]="docStates.navbarTopOverflown | async">
<!-- prettier-ignore -->
<svg fill="none" height="21" viewBox="0 0 18 19" width="18" xmlns="http://www.w3.org/2000/svg" class="docs-sidenav__header-logo"><path d="M17.5625 11.1001H11.4375C11.1959 11.1001 11 11.296 11 11.5376V17.6626C11 17.9043 11.1959 18.1001 11.4375 18.1001H17.5625C17.8042 18.1001 18 17.9043 18 17.6626V11.5376C18 11.296 17.8042 11.1001 17.5625 11.1001Z" fill="#FF0000"/><path clip-rule="evenodd" d="M6.5625 0.100098H0.4375C0.196875 0.100098 0 0.296973 0 0.537598V6.6626C0 6.90322 0.196875 7.1001 0.4375 7.1001H3.0625C3.30312 7.1001 3.5 6.90322 3.5 6.6626V4.0376C3.5 3.79697 3.69688 3.6001 3.9375 3.6001H6.5625C6.80312 3.6001 7 3.40322 7 3.1626V0.537598C7 0.296973 6.80312 0.100098 6.5625 0.100098Z" fill="#FF0000" fill-rule="evenodd"/><path clip-rule="evenodd" d="M6.5625 11.1001H0.4375C0.196875 11.1001 0 11.297 0 11.5376V14.1626C0 14.4032 0.196875 14.6001 0.4375 14.6001H3.0625C3.30312 14.6001 3.5 14.797 3.5 15.0376V17.6626C3.5 17.9032 3.69688 18.1001 3.9375 18.1001H6.5625C6.80312 18.1001 7 17.9032 7 17.6626V11.5376C7 11.297 6.80312 11.1001 6.5625 11.1001Z" fill="#FF0000" fill-rule="evenodd"/><path clip-rule="evenodd" d="M17.5625 0.100098H14.9375C14.6969 0.100098 14.5 0.296973 14.5 0.537598V3.1626C14.5 3.40322 14.3031 3.6001 14.0625 3.6001H11.4375C11.1969 3.6001 11 3.79697 11 4.0376V6.6626C11 6.90322 11.1969 7.1001 11.4375 7.1001H17.5625C17.8031 7.1001 18 6.90322 18 6.6626V0.537598C18 0.296973 17.8031 0.100098 17.5625 0.100098Z" fill="#FF0000" fill-rule="evenodd"/></svg>
<!-- prettier-ignore -->
<svg height="25" viewBox="0 0 78 25" width="78" xmlns="http://www.w3.org/2000/svg" class="docs-sidenav__header-text"><path d="M74.1362 24.2332V17.1036H74.0055C73.5087 18.0797 72.4715 19.4481 70.1705 19.4481C67.0153 19.4481 64.6533 16.9467 64.6533 12.5364C64.6533 8.0739 67.0851 5.65088 70.1792 5.65088C72.5412 5.65088 73.5261 7.07157 74.0055 8.03903H74.1972V5.8252H77.3001V24.2332H74.1362ZM71.0508 16.8595C73.0642 16.8595 74.1972 15.1163 74.1972 12.519C74.1972 9.92166 73.0816 8.2395 71.0508 8.2395C68.9503 8.2395 67.8695 10.0263 67.8695 12.519C67.8695 15.0292 68.9677 16.8595 71.0508 16.8595Z"/><path d="M58.8554 19.213V5.82541H62.0105V19.213H58.8554ZM60.4417 3.92535C59.4306 3.92535 58.6113 3.15835 58.6113 2.21703C58.6113 1.267 59.4306 0.5 60.4417 0.5C61.444 0.5 62.2633 1.267 62.2633 2.21703C62.2633 3.15835 61.444 3.92535 60.4417 3.92535Z"/><path d="M43.4824 19.2129V1.36279H46.6376V8.03917H46.7683C47.2477 7.0717 48.2326 5.65101 50.5946 5.65101C53.6887 5.65101 56.1205 8.07403 56.1205 12.5366C56.1205 16.9468 53.7585 19.4483 50.6033 19.4483C48.3023 19.4483 47.2651 18.0799 46.7683 17.1037H46.5853V19.2129H43.4824ZM46.5766 12.5191C46.5766 15.1165 47.7096 16.8596 49.723 16.8596C51.8061 16.8596 52.9043 15.0293 52.9043 12.5191C52.9043 10.0264 51.8235 8.23963 49.723 8.23963C47.6922 8.23963 46.5766 9.9218 46.5766 12.5191Z"/><path d="M34.2499 19.4743C30.3277 19.4743 27.835 16.7113 27.835 12.5713C27.835 8.42253 30.3277 5.65088 34.2499 5.65088C38.172 5.65088 40.6648 8.42253 40.6648 12.5713C40.6648 16.7113 38.172 19.4743 34.2499 19.4743ZM34.2673 16.9467C36.4027 16.9467 37.466 15.0117 37.466 12.5626C37.466 10.1134 36.4027 8.15234 34.2673 8.15234C32.097 8.15234 31.0337 10.1134 31.0337 12.5626C31.0337 15.0117 32.097 16.9467 34.2673 16.9467Z"/><path d="M19.3172 19.4743C15.3951 19.4743 12.9023 16.7113 12.9023 12.5713C12.9023 8.42253 15.3951 5.65088 19.3172 5.65088C23.2394 5.65088 25.7321 8.42253 25.7321 12.5713C25.7321 16.7113 23.2394 19.4743 19.3172 19.4743ZM19.3347 16.9467C21.4701 16.9467 22.5334 15.0117 22.5334 12.5626C22.5334 10.1134 21.4701 8.15234 19.3347 8.15234C17.1644 8.15234 16.1011 10.1134 16.1011 12.5626C16.1011 15.0117 17.1644 16.9467 19.3347 16.9467Z"/><path d="M0.0551758 19.2129V1.36279H3.21033V11.203H3.42823L8.2394 5.82533H11.9262L6.74026 11.604L12.2313 19.2129H8.4573L4.36083 13.4866L3.21033 14.7155V19.2129H0.0551758Z"/></svg>
</a>

<div kbq-scrollbar class="docs-sidenav__menu">
<div kbqScrollbarViewport class="docs-sidenav__menu">
<kbq-tree-selection
[autoSelect]="false"
[dataSource]="dataSource"
Expand Down
13 changes: 7 additions & 6 deletions apps/docs/src/app/components/sidenav/sidenav.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Location, ViewportScroller } from '@angular/common';
import { AsyncPipe, Location, ViewportScroller } from '@angular/common';
import {
afterNextRender,
AfterViewInit,
Expand All @@ -16,7 +16,7 @@ import { NavigationEnd, Router, RouterLink } from '@angular/router';
import { KbqBadgeModule } from '@koobiq/components/badge';
import { KbqDividerModule } from '@koobiq/components/divider';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqScrollbar, KbqScrollbarModule } from '@koobiq/components/scrollbar';
import { KbqScrollbarViewport } from '@koobiq/components/scrollbar';
import {
FlatTreeControl,
KbqTreeFlatDataSource,
Expand Down Expand Up @@ -87,9 +87,10 @@ function buildTree(categories: DocsStructureCategory[]): TreeNode[] {
KbqTreeModule,
KbqDividerModule,
DocsFooterComponent,
KbqScrollbarModule,
KbqScrollbarViewport,
RouterLink,
KbqBadgeModule
KbqBadgeModule,
AsyncPipe
],
templateUrl: './sidenav.html',
styleUrl: './sidenav.scss',
Expand All @@ -100,7 +101,7 @@ function buildTree(categories: DocsStructureCategory[]): TreeNode[] {
}
})
export class DocsSidenav extends DocsLocaleState implements AfterViewInit {
private readonly scrollbar = viewChild.required(KbqScrollbar);
private readonly scrollbar = viewChild.required(KbqScrollbarViewport);
private readonly tree = viewChild.required(KbqTreeSelection);
private readonly viewportScroller = inject(ViewportScroller);
private readonly router = inject(Router);
Expand Down Expand Up @@ -145,7 +146,7 @@ export class DocsSidenav extends DocsLocaleState implements AfterViewInit {

ngAfterViewInit() {
this.treeControl.expandAll();
this.docStates.registerNavbarScrollContainer(this.scrollbar().contentElement().nativeElement);
this.docStates.registerNavbarScrollContainer(this.scrollbar().getNativeElement());
this.highlightSelectedOption();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ const OPTIONAL_PACKAGE_JSON_DEPENDENCIES = {
// `writeFile`, whose API is unchanged between the two, so the sandbox still works.
xlsx: {
xlsx: '^0.18'
},
'@koobiq/components/scrollbar/deprecated': {
overlayscrollbars: '2.7.3'
}
} as const;

Expand Down Expand Up @@ -250,7 +253,6 @@ export class DocsStackblitzWriter {
'@koobiq/icons': '^11.2.0',
'@messageformat/core': '^3.4.0',
luxon: '^3.7.2',
overlayscrollbars: '2.7.3',
rxjs: '^7.8.2',
tslib: '^2.8.1',
'zone.js': '~0.15.0'
Expand Down
52 changes: 27 additions & 25 deletions apps/docs/src/app/components/welcome/welcome.component.html
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
<header docsRegisterHeader class="docs-welcome__header">
{{ t('welcomeTitle') }}
</header>
<div class="docs-welcome__content">
<header docsRegisterHeader class="docs-welcome__header">
{{ t('welcomeTitle') }}
</header>

<div class="docs-welcome__description">
{{ t('welcomeDescription') }}
</div>
<div class="docs-welcome__description">
{{ t('welcomeDescription') }}
</div>

@for (category of structureCategories; track category) {
<div class="docs-welcome__category">
<div class="docs-welcome__category-title">{{ category.name[locale()] }}</div>
<div class="docs-welcome__category-items layout-row layout-margin-top-l">
@let theme = currentTheme();
@for (category of structureCategories; track category) {
<div class="docs-welcome__category">
<div class="docs-welcome__category-title">{{ category.name[locale()] }}</div>
<div class="docs-welcome__category-items layout-row layout-margin-top-l">
@let theme = currentTheme();

@for (item of category.items; track item) {
<a class="docs-welcome__category-item" [routerLink]="[category.id, item.id]">
<img
class="docs-welcome__category-item-preview"
width="200"
height="140"
[ngSrc]="`/assets/images/welcome/${item.svgPreview || 'generic'}-${theme}.png`"
[alt]="item.id"
/>
<div class="docs-welcome__category-item-title">{{ item.name[locale()] }}</div>
</a>
}
@for (item of category.items; track item) {
<a class="docs-welcome__category-item" [routerLink]="[category.id, item.id]">
<img
class="docs-welcome__category-item-preview"
width="200"
height="140"
[ngSrc]="`/assets/images/welcome/${item.svgPreview || 'generic'}-${theme}.png`"
[alt]="item.id"
/>
<div class="docs-welcome__category-item-title">{{ item.name[locale()] }}</div>
</a>
}
</div>
</div>
</div>
}
}
</div>
13 changes: 10 additions & 3 deletions apps/docs/src/app/components/welcome/welcome.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
scroll-behavior: smooth;

min-width: 0;
}

// Padding lives on the inner wrapper, not on the scroll host, so the custom scrollbar track hugs the
// right edge instead of being pushed inward by the host's horizontal padding.
.docs-welcome__content {
display: flex;
flex-direction: column;

padding-bottom: 160px;
padding-left: 160px;
Expand Down Expand Up @@ -50,7 +57,7 @@
}

@media (width < 768px) {
.docs-welcome {
.docs-welcome__content {
padding: var(--kbq-size-l) var(--kbq-size-l) 160px;
}

Expand All @@ -64,13 +71,13 @@
}

@media (768px <= width < 1200px) {
.docs-welcome {
.docs-welcome__content {
padding: 0 var(--kbq-size-xxl) 160px var(--kbq-size-xxl);
}
}

@media (1200px <= width < 1920px) {
.docs-welcome {
.docs-welcome__content {
padding: 0 var(--kbq-size-7xl) 160px var(--kbq-size-7xl);
}
}
6 changes: 4 additions & 2 deletions apps/docs/src/app/components/welcome/welcome.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { RouterLink } from '@angular/router';
import { ThemeService } from '@koobiq/components/core';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqLinkModule } from '@koobiq/components/link';
import { KbqScrollbarViewport } from '@koobiq/components/scrollbar';
import { fromEvent } from 'rxjs';
import { debounceTime, map } from 'rxjs/operators';
import { DocsDocStates } from 'src/app/services/doc-states';
Expand All @@ -26,8 +27,9 @@ import { DocsRegisterHeaderDirective } from '../register-header/register-header.
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
class: 'docs-welcome kbq-scrollbar'
}
class: 'docs-welcome'
},
hostDirectives: [KbqScrollbarViewport]
})
export class DocsWelcomeComponent extends DocsLocaleState implements OnInit {
private readonly themeService = inject(ThemeService);
Expand Down
45 changes: 45 additions & 0 deletions docs/guides/migration.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ New versions include improvements but also contain **breaking changes**; they mu
10. **20.3.0**: button supported colors — a default color of its own per style.
11. **20.3.0**: the button-toggle review — ARIA semantics, keyboard navigation and signal inputs.
12. **20.3.0**: the form-field review — signals, accessibility and the removal of `mixinColor`.
13. **20.3.0**: deprecation of the overlayscrollbars-based Scrollbar implementation.

### 1. Upgrade to 18.5.3

Expand Down Expand Up @@ -741,6 +742,50 @@ A receiver is matched by its explicit type annotation (`KbqFormField`, `KbqHint`

**Stylesheets that fought `!important`.** `.kbq-form-field_no-borders` and `.kbq-form-field_in-overlay` used `!important` to beat the state theme; they now override the `--kbq-form-field-*` tokens instead. The computed result is the same, but an override written specifically to outrank the old `!important` can be simplified.

### 13. Scrollbar overlayscrollbars implementation deprecation (20.3.0)

Until 20.3.0, `@koobiq/components/scrollbar` wrapped the third-party `overlayscrollbars` library: the `KbqScrollbar` component (`kbq-scrollbar` / `[kbq-scrollbar]`) and the low-level `KbqScrollbarDirective` (`[kbqScrollbar]`), with `options`, `events`, `defer` inputs and raw access to `scrollbarInstance`.

As of 20.3.0, `@koobiq/components/scrollbar` provides a new dependency-free `KbqScrollbar` component with the `<kbq-scrollbar>` selector and a different public API. The previous implementation has not gone away — it moved, unchanged, to `@koobiq/components/scrollbar/deprecated` and will be removed in a future major version.

#### Running the migration

The `scrollbar-deprecated-path` schematic runs automatically:

```bash
ng update @koobiq/components@20
```

Or manually:

```bash
ng g @koobiq/components:scrollbar-deprecated-path --project <your project>
```

#### What is fixed automatically

**The `@koobiq/components/scrollbar` import path is rewritten to `@koobiq/components/scrollbar/deprecated`** — in every `.ts` file, in both single- and double-quoted specifiers. The implementation itself and its public API (`options` / `events` / `defer` / `scrollbarInstance`, the `kbq-scrollbar` / `[kbq-scrollbar]` / `[kbqScrollbar]` selectors) are unchanged — only where you import them from changes.

```ts
// Before
import { KbqScrollbarModule } from '@koobiq/components/scrollbar';

// After
import { KbqScrollbarModule } from '@koobiq/components/scrollbar/deprecated';
```

#### What you need to fix manually

**Moving to the new implementation** is a separate, manual migration, not just an import path change: the new component uses the `<kbq-scrollbar>` selector and does not support the `[kbq-scrollbar]` or `[kbqScrollbar]` attribute selectors. Its public API differs from the previous implementation — see the [Scrollbar component documentation](/en/components/scrollbar) for details.

**Do not import both the old and the new implementation into the same standalone component.** Both use the `kbq-scrollbar` element selector, so Angular cannot choose a component unambiguously. During a gradual manual migration, keep old and new usage in separate components.

### After the migration

After fully moving to the new component and removing imports from `@koobiq/components/scrollbar/deprecated`, the `overlayscrollbars` dependency is no longer needed and can be removed:

```bash
npm uninstall overlayscrollbars
```

The migration is regex-based and does not rewrite aliased imports, local variables, or re-exports — **review the diff before committing**, rebuild the project and run your tests. The full list of breaking changes is on the [Angular 20 breaking changes](https://github.com/koobiq/angular-components/blob/main/docs/guides/angular-20-breaking-changes.en.md) page.
Loading