+#### Селект без рамки
+
+При выборе открываем только выпадающее меню, но не показываем поле ввода, как у Select. Рамка поля ввода не требуется — достаточно выпадающего меню.
+
+
+
+После выбора опции поле возвращается в режим просмотра.
+
+#### Многострочное поле
+
+Иногда стоит делать опции в выпадающем списке многострочными. Рекомендуется выравнивать ширину выпадающего меню по ширине поля.
+
+
+
+#### Сброс
+
+Разместите элемент для очистки в выпадающем меню — ведь самого поля селекта не видно, поэтому другого подходящего места для кнопки сброса нет.
+
+Рекомендуем также добавить опцию, название которой явно даёт понять, что значение не установлено. Это будет логично перекликаться с формулировкой пустого поля в режиме просмотра.
+
+
+
+После выбора опции поле возвращается в режим просмотра.
+
### Рекомендации
Поле с инлайн-редактированием должны сохраняться сразу после изменения без общей для всего экрана кнопки «Сохранить».
diff --git a/packages/components/inline-edit/inline-edit.scss b/packages/components/inline-edit/inline-edit.scss
index bd423fbdaa..afc299b8f8 100644
--- a/packages/components/inline-edit/inline-edit.scss
+++ b/packages/components/inline-edit/inline-edit.scss
@@ -125,6 +125,12 @@
}
}
+ // Select-style editor: edit mode shows only the dropdown, not a bordered field, so the view
+ // text keeps showing through and just gets the "active" look instead.
+ &.kbq-inline-edit_select.kbq-inline-edit_edit {
+ --kbq-inline-edit-background: var(--kbq-states-background-transparent-active);
+ }
+
&:hover,
&.cdk-keyboard-focused,
&.kbq-inline-edit_anchor-focused {
@@ -187,6 +193,10 @@
padding: var(--kbq-size-xxs) var(--kbq-size-s) var(--kbq-size-s);
}
+ &.kbq-inline-edit__panel_select .kbq-inline-edit__control-container {
+ display: none;
+ }
+
.kbq-inline-edit__control-container,
.kbq-inline-edit__action-button {
box-shadow: var(--kbq-shadow-popup);
diff --git a/packages/components/inline-edit/inline-edit.spec.ts b/packages/components/inline-edit/inline-edit.spec.ts
index d1e7f88109..2b8e1cb743 100644
--- a/packages/components/inline-edit/inline-edit.spec.ts
+++ b/packages/components/inline-edit/inline-edit.spec.ts
@@ -16,7 +16,7 @@ import {
TAB
} from '@koobiq/components/core';
import { KbqDropdownModule } from '@koobiq/components/dropdown';
-import { KbqFormFieldModule } from '@koobiq/components/form-field';
+import { KbqFormField, KbqFormFieldModule } from '@koobiq/components/form-field';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqInputModule } from '@koobiq/components/input';
import { KbqSelectModule } from '@koobiq/components/select';
@@ -349,6 +349,42 @@ describe('KbqInlineEdit', () => {
expect(spyFn).not.toHaveBeenCalled();
});
+ it('should save and return to view mode when commit() is called directly', () => {
+ const fixture = setup(TestComponent);
+ const { componentInstance, debugElement } = fixture;
+ const inlineEditDebugElement: DebugElement = getInlineEditDebugElement(debugElement);
+ const spyFn = jest.spyOn(componentInstance, 'update');
+
+ inlineEditDebugElement.nativeElement.click();
+ fixture.detectChanges();
+
+ (inlineEditDebugElement.componentInstance as KbqInlineEdit).commit();
+ fixture.detectChanges();
+
+ expect(spyFn).toHaveBeenCalled();
+ expect(inlineEditDebugElement.classes['kbq-inline-edit_view']).toBe(true);
+ });
+
+ it('should not save when commit() is called while control is invalid', () => {
+ const fixture = setup(TestWithValidatedControl);
+ const { componentInstance, debugElement } = fixture;
+ const inlineEditDebugElement: DebugElement = getInlineEditDebugElement(debugElement);
+ const spyFn = jest.spyOn(componentInstance, 'update');
+
+ inlineEditDebugElement.nativeElement.click();
+ fixture.detectChanges();
+
+ componentInstance.control.markAsTouched();
+ componentInstance.control.updateValueAndValidity();
+ fixture.detectChanges();
+
+ (inlineEditDebugElement.componentInstance as KbqInlineEdit).commit();
+ fixture.detectChanges();
+
+ expect(spyFn).not.toHaveBeenCalled();
+ expect(inlineEditDebugElement.classes['kbq-inline-edit_edit']).toBe(true);
+ });
+
it('should reposition the edit mode overlay when the surrounding layout resizes', () => {
const resize$ = new Subject
();
const fixture = setup(TestComponent, [
@@ -517,6 +553,86 @@ describe('KbqInlineEdit', () => {
expect(document.querySelector(componentCssClasses.selectPanel)).toBeTruthy();
});
+ describe('select-style editor', () => {
+ it('should mark a single select as such and add the select-style panel class while editing', async () => {
+ const fixture = setup(TestWithSelect);
+ const { debugElement } = fixture;
+ const inlineEditDebugElement: DebugElement = getInlineEditDebugElement(debugElement);
+
+ expect(inlineEditDebugElement.classes['kbq-inline-edit_select']).toBe(true);
+
+ inlineEditDebugElement.nativeElement.click();
+ fixture.detectChanges();
+ await fixture.whenStable();
+
+ expect(document.querySelector(`${componentCssClasses.panel}.kbq-inline-edit__panel_select`)).toBeTruthy();
+ });
+
+ it('should connect the select panel to the inline-edit host', async () => {
+ const fixture = setup(TestWithSelect);
+ const { debugElement } = fixture;
+ const inlineEditDebugElement: DebugElement = getInlineEditDebugElement(debugElement);
+
+ inlineEditDebugElement.nativeElement.click();
+ fixture.detectChanges();
+ await fixture.whenStable();
+
+ const formField = fixture.debugElement.query(By.directive(KbqFormField)).componentInstance as KbqFormField;
+
+ expect(formField.getConnectedOverlayOrigin().nativeElement).toBe(inlineEditDebugElement.nativeElement);
+ });
+
+ it('should not treat a multi-select as a select-style editor', async () => {
+ const fixture = setup(TestWithMultiSelect);
+ const { debugElement } = fixture;
+ const inlineEditDebugElement: DebugElement = getInlineEditDebugElement(debugElement);
+
+ expect(inlineEditDebugElement.classes['kbq-inline-edit_select']).toBeFalsy();
+
+ inlineEditDebugElement.nativeElement.click();
+ fixture.detectChanges();
+ await fixture.whenStable();
+
+ expect(document.querySelector(`${componentCssClasses.panel}.kbq-inline-edit__panel_select`)).toBeNull();
+ });
+
+ it('should not override the overlay origin for a non-select control', async () => {
+ const fixture = setup(TestComponent);
+ const { debugElement } = fixture;
+ const inlineEditDebugElement: DebugElement = getInlineEditDebugElement(debugElement);
+
+ inlineEditDebugElement.nativeElement.click();
+ fixture.detectChanges();
+ await fixture.whenStable();
+
+ const formField = fixture.debugElement.query(By.directive(KbqFormField)).componentInstance as KbqFormField;
+
+ expect(formField.getConnectedOverlayOrigin().nativeElement).not.toBe(inlineEditDebugElement.nativeElement);
+ });
+ });
+
+ it('should stay in view mode when commit() is followed by a redundant outside-click save()', async () => {
+ // A control whose panel is a separate CDK overlay (e.g. kbq-select) makes the overlay's own
+ // outside-click detection see clicks on that panel as "outside" inline-edit's overlay, so both
+ // the control's own (selectionChange)-driven commit() and the overlay's outside-click handler
+ // can fire for the same interaction. Since save() used to be an unconditional toggle, the
+ // second (redundant) call would flip the mode straight back to 'edit'.
+ const fixture = setup(TestWithSelectAutoCommit);
+ const { debugElement } = fixture;
+ const inlineEditDebugElement: DebugElement = getInlineEditDebugElement(debugElement);
+ const inlineEdit = inlineEditDebugElement.componentInstance as KbqInlineEdit;
+
+ inlineEditDebugElement.nativeElement.click();
+ fixture.detectChanges();
+ await fixture.whenStable();
+
+ inlineEdit.commit();
+ (inlineEdit as any).save();
+ fixture.detectChanges();
+
+ expect(inlineEditDebugElement.classes['kbq-inline-edit_view']).toBe(true);
+ });
+
describe('with multiple form fields', () => {
it('should emit saved event when both form fields are valid', async () => {
const fixture = setup(TestWithMultipleFormFields);
@@ -1140,6 +1256,58 @@ export class TestWithSelect extends BaseTestComponent {
cancel = jest.fn();
}
+@Component({
+ selector: 'name',
+ imports: [
+ FormsModule,
+ KbqInlineEditModule,
+ KbqOptionModule,
+ KbqSelectModule
+ ],
+ template: `
+
+ {{ selected() }}
+
+
+ @for (option of options; track option) {
+ {{ option }}
+ }
+
+
+
+ `
+})
+export class TestWithSelectAutoCommit {
+ readonly options = Array.from({ length: 5 }).map((_, i) => `Option #${i}`);
+ readonly selected = model(this.options[0]);
+}
+
+@Component({
+ selector: 'name',
+ imports: [
+ FormsModule,
+ KbqInlineEditModule,
+ KbqOptionModule,
+ KbqSelectModule
+ ],
+ template: `
+
+ {{ selected().join(', ') }}
+
+
+ @for (option of options; track option) {
+ {{ option }}
+ }
+
+
+
+ `
+})
+export class TestWithMultiSelect {
+ readonly options = Array.from({ length: 5 }).map((_, i) => `Option #${i}`);
+ readonly selected = model([this.options[0]]);
+}
+
@Component({
selector: 'name',
imports: [ReactiveFormsModule, KbqFormFieldModule, KbqInlineEditModule, KbqTextareaModule],
diff --git a/packages/components/inline-edit/inline-edit.ts b/packages/components/inline-edit/inline-edit.ts
index 5237807afe..a5680f3fee 100644
--- a/packages/components/inline-edit/inline-edit.ts
+++ b/packages/components/inline-edit/inline-edit.ts
@@ -14,6 +14,7 @@ import {
Directive,
effect,
ElementRef,
+ forwardRef,
inject,
input,
numberAttribute,
@@ -29,15 +30,18 @@ import { AbstractControl, NgControl } from '@angular/forms';
import { KbqButtonModule } from '@koobiq/components/button';
import {
isElement,
+ KBQ_CONNECTED_OVERLAY_ORIGIN,
KbqAnimationCurves,
KbqAnimationDurations,
KbqComponentColors,
+ KbqConnectedOverlayOriginProvider,
kbqInjectA11yLocaleConfiguration,
PopUpPlacements
} from '@koobiq/components/core';
import { KbqDropdownTrigger } from '@koobiq/components/dropdown';
import { KbqFormField, KbqLabel } from '@koobiq/components/form-field';
import { KbqIcon } from '@koobiq/components/icon';
+import { KbqSelect } from '@koobiq/components/select';
import { KbqTooltipTrigger } from '@koobiq/components/tooltip';
import { merge, skip } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@@ -129,6 +133,7 @@ export class KbqInlineEditMenu {
],
templateUrl: './inline-edit.html',
styleUrls: ['./inline-edit.scss', './inline-edit-tokens.scss'],
+ providers: [{ provide: KBQ_CONNECTED_OVERLAY_ORIGIN, useExisting: forwardRef(() => KbqInlineEdit) }],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
@@ -139,17 +144,16 @@ export class KbqInlineEditMenu {
'[class.kbq-inline-edit_with-menu]': '!!menu()',
'[class.kbq-inline-edit_disabled]': 'disabled()',
'[class.kbq-inline-edit_anchor-focused]': 'anchorFocused()',
+ '[class.kbq-inline-edit_select]': 'isSingleSelect()',
'(click)': 'onClick($event)',
'(keydown.enter)': 'onClick($event)',
'(keydown.space)': 'onClick($event)'
},
- hostDirectives: [
- CdkMonitorFocus
- ],
+ hostDirectives: [CdkMonitorFocus],
animations: [KBQ_INLINE_EDIT_ACTION_BUTTONS_ANIMATION],
exportAs: 'kbqInlineEdit'
})
-export class KbqInlineEdit {
+export class KbqInlineEdit implements KbqConnectedOverlayOriginProvider {
/** Accessible names for the icon-only save/cancel buttons. */
protected readonly a11yLocaleConfiguration = kbqInjectA11yLocaleConfiguration();
@@ -217,6 +221,19 @@ export class KbqInlineEdit {
/** @docs-private */
protected readonly formFieldRefList = contentChildren(KbqFormField, { descendants: true });
+ /** @docs-private */
+ protected readonly selectRef = contentChild(KbqSelect, { descendants: true });
+ /**
+ * Whether edit mode contains a single-value select. When true, edit mode shows only the
+ * dropdown panel instead of a bordered field - see the "Select-style editor" example.
+ * @docs-private
+ */
+ protected readonly isSingleSelect = computed(() => {
+ const select = this.selectRef();
+
+ return !!select && !select.multiple && !select.multiline();
+ });
+
/** @docs-private */
protected overlayOrigin: HTMLElement = this.elementRef.nativeElement;
/** @docs-private */
@@ -283,6 +300,21 @@ export class KbqInlineEdit {
this.mode.update((mode) => (mode === 'view' ? 'edit' : 'view'));
}
+ /**
+ * Implements `KbqConnectedOverlayOriginProvider`, letting a nested `KbqFormField`'s control
+ * anchor its overlay to this element instead of the form-field's own container.
+ * When no override is needed, the form-field falls back to its default.
+ * @docs-private
+ */
+ getConnectedOverlayOrigin(): ElementRef | undefined {
+ return this.isSingleSelect() ? this.elementRef : undefined;
+ }
+
+ /** Saves the current value and returns to view mode, running the same validation as a normal save. */
+ commit(): void {
+ this.save();
+ }
+
/** @docs-private */
protected onClick(event: Event): void {
if (this.disabled() || this.isEditMode() || this.isInteractiveElement(event.target)) return;
@@ -331,6 +363,10 @@ export class KbqInlineEdit {
/** @docs-private */
protected save($event?: Event): void {
+ // Guards against a control triggering both its own commit() and the overlay's outside-click handler for the
+ // same interaction — without this, the second call would toggle back into edit mode.
+ if (!this.isEditMode()) return;
+
if (this.isInvalid()) {
$event?.stopPropagation();
diff --git a/packages/docs-examples/components/inline-edit/index.ts b/packages/docs-examples/components/inline-edit/index.ts
index cfe9fc7eca..72601bbfa3 100644
--- a/packages/docs-examples/components/inline-edit/index.ts
+++ b/packages/docs-examples/components/inline-edit/index.ts
@@ -10,6 +10,9 @@ import { InlineEditHorizontalListExample } from './inline-edit-horizontal-list/i
import { InlineEditMenuExample } from './inline-edit-menu/inline-edit-menu-example';
import { InlineEditOnCleanExample } from './inline-edit-on-clean/inline-edit-on-clean-example';
import { InlineEditOverviewExample } from './inline-edit-overview/inline-edit-overview-example';
+import { InlineEditSelectBasicExample } from './inline-edit-select-basic/inline-edit-select-basic-example';
+import { InlineEditSelectMultilineExample } from './inline-edit-select-multiline/inline-edit-select-multiline-example';
+import { InlineEditSelectExample } from './inline-edit-select/inline-edit-select-example';
import { InlineEditUnfilledExample } from './inline-edit-unfilled/inline-edit-unfilled-example';
import { InlineEditValidationExample } from './inline-edit-validation/inline-edit-validation-example';
import { InlineEditVerticalListExample } from './inline-edit-vertical-list/inline-edit-vertical-list-example';
@@ -27,6 +30,9 @@ export {
InlineEditMenuExample,
InlineEditOnCleanExample,
InlineEditOverviewExample,
+ InlineEditSelectBasicExample,
+ InlineEditSelectExample,
+ InlineEditSelectMultilineExample,
InlineEditUnfilledExample,
InlineEditValidationExample,
InlineEditVerticalListExample,
@@ -40,6 +46,9 @@ const EXAMPLES = [
InlineEditDisabledExample,
InlineEditHorizontalListExample,
InlineEditOnCleanExample,
+ InlineEditSelectBasicExample,
+ InlineEditSelectExample,
+ InlineEditSelectMultilineExample,
InlineEditValidationExample,
InlineEditCustomHandlerExample,
InlineEditVerticalListExample,
diff --git a/packages/docs-examples/components/inline-edit/inline-edit-select-basic/inline-edit-select-basic-example.ts b/packages/docs-examples/components/inline-edit/inline-edit-select-basic/inline-edit-select-basic-example.ts
new file mode 100644
index 0000000000..d1d4a44933
--- /dev/null
+++ b/packages/docs-examples/components/inline-edit/inline-edit-select-basic/inline-edit-select-basic-example.ts
@@ -0,0 +1,105 @@
+import { ChangeDetectionStrategy, Component } from '@angular/core';
+import { FormControl, ReactiveFormsModule } from '@angular/forms';
+import { KbqOptionModule } from '@koobiq/components/core';
+import { KbqDlModule } from '@koobiq/components/dl';
+import { KbqFormFieldModule, KbqLabel } from '@koobiq/components/form-field';
+import { KbqInlineEditModule } from '@koobiq/components/inline-edit';
+import { KbqSelectModule } from '@koobiq/components/select';
+
+const STATUSES: string[] = ['Open', 'In progress', 'Resolved', 'Closed'];
+const PRIORITIES: string[] = ['Low', 'Medium', 'High', 'Critical'];
+
+/**
+ * @title Inline edit select basic
+ */
+@Component({
+ selector: 'inline-edit-select-basic-example',
+ imports: [
+ ReactiveFormsModule,
+ KbqInlineEditModule,
+ KbqFormFieldModule,
+ KbqLabel,
+ KbqOptionModule,
+ KbqSelectModule,
+ KbqDlModule
+ ],
+ template: `
+
+
+ Status
+
+
+ @if (status.value) {
+ {{ status.value }}
+ } @else {
+ {{ notSetLabel }}
+ }
+
+
+
+
+ @for (item of statuses; track item) {
+ {{ item }}
+ }
+
+
+
+
+
+
+ Priority
+
+
+
+ @if (priority.value) {
+ {{ priority.value }}
+ } @else {
+ {{ notSetLabel }}
+ }
+
+
+
+
+ @for (item of priorities; track item) {
+ {{ item }}
+ }
+
+
+
+
+
+ `,
+ styles: `
+ .example__section {
+ width: 200px;
+ }
+
+ .kbq-dt {
+ display: inline-flex;
+ align-items: center;
+ }
+ `,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ host: {
+ class: 'layout-column layout-align-center-center layout-gap-l'
+ }
+})
+export class InlineEditSelectBasicExample {
+ protected readonly notSetLabel = 'Not specified';
+
+ protected readonly statuses = STATUSES;
+ protected readonly priorities = PRIORITIES;
+
+ protected readonly status = new FormControl(STATUSES[0]);
+ protected readonly priority = new FormControl(PRIORITIES[0]);
+}
diff --git a/packages/docs-examples/components/inline-edit/inline-edit-select-multiline/inline-edit-select-multiline-example.ts b/packages/docs-examples/components/inline-edit/inline-edit-select-multiline/inline-edit-select-multiline-example.ts
new file mode 100644
index 0000000000..4e31ef0fb2
--- /dev/null
+++ b/packages/docs-examples/components/inline-edit/inline-edit-select-multiline/inline-edit-select-multiline-example.ts
@@ -0,0 +1,77 @@
+import { ChangeDetectionStrategy, Component } from '@angular/core';
+import { FormControl, ReactiveFormsModule } from '@angular/forms';
+import { KbqOptionModule } from '@koobiq/components/core';
+import { KbqFormFieldModule, KbqLabel } from '@koobiq/components/form-field';
+import { KbqInlineEditModule } from '@koobiq/components/inline-edit';
+import { KbqSelectModule } from '@koobiq/components/select';
+
+const COMMENTS: string[] = [
+ 'Issue resolved after restarting the affected service. No further action required.',
+ 'Root cause identified as a misconfigured environment variable, fixed and redeployed.',
+ 'Duplicate of an existing issue, closing without further changes.',
+ 'Waiting on additional information from the reporter before further diagnosis.'
+];
+
+/**
+ * @title Inline edit select multiline
+ */
+@Component({
+ selector: 'inline-edit-select-multiline-example',
+ imports: [
+ ReactiveFormsModule,
+ KbqInlineEditModule,
+ KbqFormFieldModule,
+ KbqLabel,
+ KbqOptionModule,
+ KbqSelectModule
+ ],
+ template: `
+
+
+ Resolution comment
+
+
+ @if (control.value) {
+ {{ control.value }}
+ } @else {
+ {{ notSetLabel }}
+ }
+
+
+
+
+
+ {{ notSetLabel }}
+
+ @for (comment of comments; track comment) {
+ {{ comment }}
+ }
+
+
+
+
+ `,
+ styles: `
+ ::ng-deep .example-inline-select-multiline__options .kbq-option-text {
+ white-space: normal;
+ overflow-wrap: break-word;
+ }
+ `,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ host: {
+ class: 'layout-column layout-align-center-center'
+ }
+})
+export class InlineEditSelectMultilineExample {
+ protected readonly notSetLabel = 'Not specified';
+
+ protected readonly comments = COMMENTS;
+
+ protected readonly control = new FormControl(COMMENTS[0]);
+}
diff --git a/packages/docs-examples/components/inline-edit/inline-edit-select/inline-edit-select-example.ts b/packages/docs-examples/components/inline-edit/inline-edit-select/inline-edit-select-example.ts
new file mode 100644
index 0000000000..96d5c411cb
--- /dev/null
+++ b/packages/docs-examples/components/inline-edit/inline-edit-select/inline-edit-select-example.ts
@@ -0,0 +1,86 @@
+import { ChangeDetectionStrategy, Component } from '@angular/core';
+import { FormControl, ReactiveFormsModule } from '@angular/forms';
+import { KbqOptionModule } from '@koobiq/components/core';
+import { KbqFormFieldModule, KbqLabel } from '@koobiq/components/form-field';
+import { KbqInlineEditModule } from '@koobiq/components/inline-edit';
+import { KbqSelectModule } from '@koobiq/components/select';
+import { KbqUserInfo, KbqUsername } from '@koobiq/components/username';
+
+const USERS: KbqUserInfo[] = [
+ {
+ firstName: 'Ivan',
+ lastName: 'Petrov',
+ login: 'ipetrov',
+ site: 'Engineering'
+ },
+ { firstName: 'Maria', lastName: 'Sidorova', login: 'msidorova', site: 'Customer support' },
+ { firstName: 'Alexey', lastName: 'Smirnov', login: 'asmirnov', site: 'Information security' },
+ { firstName: 'Olga', lastName: 'Kuznetsova', login: 'okuznetsova', site: 'Marketing' }
+];
+
+/**
+ * @title Inline edit select
+ */
+@Component({
+ selector: 'inline-edit-select-example',
+ imports: [
+ ReactiveFormsModule,
+ KbqInlineEditModule,
+ KbqFormFieldModule,
+ KbqLabel,
+ KbqOptionModule,
+ KbqSelectModule,
+ KbqUsername
+ ],
+ template: `
+
+
+ Assignee
+
+
+ @if (control.value) {
+
+ } @else {
+ {{ notSetLabel }}
+ }
+
+
+
+
+ {{ notSetLabel }}
+
+ @for (user of users; track user) {
+
+
+
+ }
+
+
+
+
+ `,
+ styles: `
+ .example-inline-select__view {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ `,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ host: {
+ class: 'layout-column layout-align-center-center'
+ }
+})
+export class InlineEditSelectExample {
+ protected readonly notSetLabel = 'Not specified';
+
+ protected readonly users = USERS;
+
+ protected readonly control = new FormControl(this.users[0]);
+}
diff --git a/packages/docs-examples/example-module.ts b/packages/docs-examples/example-module.ts
index e6bf9535d5..75881b1667 100644
--- a/packages/docs-examples/example-module.ts
+++ b/packages/docs-examples/example-module.ts
@@ -3196,6 +3196,45 @@ export const EXAMPLE_COMPONENTS: {[id: string]: LiveExample} = {
"primaryFile": "inline-edit-overview-example.ts",
"importPath": "components/inline-edit"
},
+ "inline-edit-select-basic": {
+ "packagePath": "components/inline-edit/inline-edit-select-basic",
+ "title": "Inline edit select basic",
+ "componentName": "InlineEditSelectBasicExample",
+ "files": [
+ "inline-edit-select-basic-example.ts"
+ ],
+ "localImportFiles": [],
+ "selector": "inline-edit-select-basic-example",
+ "additionalComponents": [],
+ "primaryFile": "inline-edit-select-basic-example.ts",
+ "importPath": "components/inline-edit"
+ },
+ "inline-edit-select-multiline": {
+ "packagePath": "components/inline-edit/inline-edit-select-multiline",
+ "title": "Inline edit select multiline",
+ "componentName": "InlineEditSelectMultilineExample",
+ "files": [
+ "inline-edit-select-multiline-example.ts"
+ ],
+ "localImportFiles": [],
+ "selector": "inline-edit-select-multiline-example",
+ "additionalComponents": [],
+ "primaryFile": "inline-edit-select-multiline-example.ts",
+ "importPath": "components/inline-edit"
+ },
+ "inline-edit-select": {
+ "packagePath": "components/inline-edit/inline-edit-select",
+ "title": "Inline edit select",
+ "componentName": "InlineEditSelectExample",
+ "files": [
+ "inline-edit-select-example.ts"
+ ],
+ "localImportFiles": [],
+ "selector": "inline-edit-select-example",
+ "additionalComponents": [],
+ "primaryFile": "inline-edit-select-example.ts",
+ "importPath": "components/inline-edit"
+ },
"inline-edit-unfilled": {
"packagePath": "components/inline-edit/inline-edit-unfilled",
"title": "Inline edit unfilled",
@@ -7980,6 +8019,12 @@ return import('@koobiq/docs-examples/components/inline-edit');
case 'inline-edit-on-clean':
return import('@koobiq/docs-examples/components/inline-edit');
case 'inline-edit-overview':
+return import('@koobiq/docs-examples/components/inline-edit');
+ case 'inline-edit-select-basic':
+return import('@koobiq/docs-examples/components/inline-edit');
+ case 'inline-edit-select-multiline':
+return import('@koobiq/docs-examples/components/inline-edit');
+ case 'inline-edit-select':
return import('@koobiq/docs-examples/components/inline-edit');
case 'inline-edit-unfilled':
return import('@koobiq/docs-examples/components/inline-edit');
diff --git a/packages/e2e/routes.ts b/packages/e2e/routes.ts
index a67e1b5f34..36320faae6 100644
--- a/packages/e2e/routes.ts
+++ b/packages/e2e/routes.ts
@@ -46,6 +46,7 @@ import { E2eIconStateAndStyle, E2eIconSvg } from '../components/icon/e2e';
import {
E2eInlineEditActionButtons,
E2eInlineEditMenuButton,
+ E2eInlineEditSelectMultiline,
E2eInlineEditStates,
E2eInlineEditTruncation
} from '../components/inline-edit/e2e';
@@ -265,6 +266,7 @@ const components = [
E2eInlineEditMenuButton,
E2eInlineEditTruncation,
E2eInlineEditActionButtons,
+ E2eInlineEditSelectMultiline,
E2eFormHorizontal,
E2eTypographyStyles,
E2eTreeTwoLineNode,
diff --git a/tools/public_api_guard/components/core.api.md b/tools/public_api_guard/components/core.api.md
index 73cdfc6be8..399b25c669 100644
--- a/tools/public_api_guard/components/core.api.md
+++ b/tools/public_api_guard/components/core.api.md
@@ -1079,6 +1079,9 @@ export const KBQ_CONNECTED_OVERLAY_ABOVE_CLASS = "kbq-connected-overlay_above";
// @public
export const KBQ_CONNECTED_OVERLAY_BELOW_CLASS = "kbq-connected-overlay_below";
+// @public
+export const KBQ_CONNECTED_OVERLAY_ORIGIN: InjectionToken;
+
// @public (undocumented)
export const KBQ_CUSTOM_SCROLL_STRATEGY_PROVIDER: (token: InjectionToken, factory: (overlay: Overlay) => () => ScrollStrategy) => {
provide: InjectionToken;
@@ -2616,6 +2619,11 @@ export enum KbqComponentColors {
Warning = "warning"
}
+// @public
+export interface KbqConnectedOverlayOriginProvider {
+ getConnectedOverlayOrigin(): ElementRef | undefined;
+}
+
// @public (undocumented)
export class KbqDataSizePipe implements PipeTransform {
constructor();
diff --git a/tools/public_api_guard/components/inline-edit.api.md b/tools/public_api_guard/components/inline-edit.api.md
index ce4d6a46a7..3824f9fd0f 100644
--- a/tools/public_api_guard/components/inline-edit.api.md
+++ b/tools/public_api_guard/components/inline-edit.api.md
@@ -9,9 +9,11 @@ import { CdkConnectedOverlay } from '@angular/cdk/overlay';
import { ElementRef } from '@angular/core';
import * as i1 from '@angular/cdk/a11y';
import { KbqComponentColors } from '@koobiq/components/core';
+import { KbqConnectedOverlayOriginProvider } from '@koobiq/components/core';
import { KbqDropdownTrigger } from '@koobiq/components/dropdown';
import { KbqFormField } from '@koobiq/components/form-field';
import { KbqLabel } from '@koobiq/components/form-field';
+import { KbqSelect } from '@koobiq/components/select';
import { KbqTooltipTrigger } from '@koobiq/components/tooltip';
import * as _koobiq_components_core from '@koobiq/components/core';
import { PopUpPlacements } from '@koobiq/components/core';
@@ -33,7 +35,7 @@ export class KbqFocusRegionItem {
}
// @public
-export class KbqInlineEdit {
+export class KbqInlineEdit implements KbqConnectedOverlayOriginProvider {
constructor();
protected readonly a11yLocaleConfiguration: _angular_core.Signal<_koobiq_components_core.KbqA11yLocaleConfiguration>;
protected readonly anchorFocused: _angular_core.WritableSignal;
@@ -42,16 +44,19 @@ export class KbqInlineEdit {
readonly canSaveOnEnter: _angular_core.InputSignal<(event: KeyboardEvent) => boolean>;
protected readonly className: _angular_core.Signal;
protected readonly colors: typeof KbqComponentColors;
+ commit(): void;
readonly disabled: _angular_core.InputSignalWithTransform;
readonly editModeWidth: _angular_core.InputSignalWithTransform;
// (undocumented)
protected readonly elementRef: ElementRef;
protected readonly formFieldRef: _angular_core.Signal;
protected readonly formFieldRefList: _angular_core.Signal;
+ getConnectedOverlayOrigin(): ElementRef | undefined;
readonly getValueHandler: _angular_core.InputSignal<(() => unknown) | undefined>;
protected readonly hasInteractiveContent: _angular_core.WritableSignal;
readonly interactiveSelectors: _angular_core.InputSignal;
protected readonly isEditMode: _angular_core.Signal;
+ protected readonly isSingleSelect: _angular_core.Signal;
protected readonly label: _angular_core.Signal;
protected readonly menu: _angular_core.Signal;
protected readonly mode: _angular_core.WritableSignal;
@@ -70,6 +75,7 @@ export class KbqInlineEdit {
protected save($event?: Event): void;
protected readonly saved: _angular_core.OutputEmitterRef;
protected readonly scrollStrategy: _angular_core.WritableSignal;
+ protected readonly selectRef: _angular_core.Signal;
readonly setValueHandler: _angular_core.InputSignal<((value: any) => void) | undefined>;
readonly showActions: _angular_core.InputSignalWithTransform;
readonly showTooltipOnError: _angular_core.InputSignalWithTransform;
@@ -80,7 +86,7 @@ export class KbqInlineEdit {
readonly validationTooltip: _angular_core.InputSignal | undefined>;
protected readonly viewContainer: _angular_core.Signal>;
// (undocumented)
- static ɵcmp: _angular_core.ɵɵComponentDeclaration;
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration;
// (undocumented)
static ɵfac: _angular_core.ɵɵFactoryDeclaration;
}