@frame-kit/ui-ng 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -16,6 +16,12 @@ class FkContentSplitComponent {
|
|
|
16
16
|
railWidth = input('64px', ...(ngDevMode ? [{ debugName: "railWidth" }] : /* istanbul ignore next */ []));
|
|
17
17
|
/** Host element pixel width below which the layout switches to narrow mode. */
|
|
18
18
|
breakpoint = input(700, ...(ngDevMode ? [{ debugName: "breakpoint" }] : /* istanbul ignore next */ []));
|
|
19
|
+
/**
|
|
20
|
+
* Optional CSS max-width for the layout. When set, the split is capped at
|
|
21
|
+
* this width and centered in its container (via auto inline margins);
|
|
22
|
+
* unset (default), it fills the full available width as before.
|
|
23
|
+
*/
|
|
24
|
+
maxWidth = input(null, ...(ngDevMode ? [{ debugName: "maxWidth" }] : /* istanbul ignore next */ []));
|
|
19
25
|
/** Two-way binding for the collapsed state of the left panel. */
|
|
20
26
|
collapsed = model(false, ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
|
|
21
27
|
// ===== INTERNAL STATE =====
|
|
@@ -46,6 +52,9 @@ class FkContentSplitComponent {
|
|
|
46
52
|
get hostRailWidth() {
|
|
47
53
|
return this.railWidth();
|
|
48
54
|
}
|
|
55
|
+
get hostMaxWidth() {
|
|
56
|
+
return this.maxWidth();
|
|
57
|
+
}
|
|
49
58
|
// ===== CONSTRUCTOR =====
|
|
50
59
|
constructor() {
|
|
51
60
|
// ResizeObserver is browser-only — the SSR pass has no live
|
|
@@ -108,12 +117,12 @@ class FkContentSplitComponent {
|
|
|
108
117
|
this.close();
|
|
109
118
|
}
|
|
110
119
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkContentSplitComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
111
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: FkContentSplitComponent, isStandalone: true, selector: "fk-content-split", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, leftWidth: { classPropertyName: "leftWidth", publicName: "leftWidth", isSignal: true, isRequired: false, transformFunction: null }, railWidth: { classPropertyName: "railWidth", publicName: "railWidth", isSignal: true, isRequired: false, transformFunction: null }, breakpoint: { classPropertyName: "breakpoint", publicName: "breakpoint", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange" }, host: { properties: { "class": "this.hostClass", "style.--fk-content-split-left-width": "this.hostLeftWidth", "style.--fk-content-split-rail-width": "this.hostRailWidth" } }, ngImport: i0, template: "@if (showOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-content-split__overlay\" (click)=\"dismiss()\"></div>\n}\n\n<div\n class=\"fk-content-split__left\"\n [class.fk-content-split__left--open]=\"!collapsed()\"\n>\n <div class=\"fk-content-split__left-content\">\n <ng-content select=\"[contentSplitLeft]\" />\n </div>\n</div>\n\n<div class=\"fk-content-split__rail\">\n <button\n class=\"fk-content-split__rail-toggle\"\n type=\"button\"\n [attr.aria-label]=\"collapsed() ? 'Open panel' : 'Close panel'\"\n (click)=\"toggle()\"\n >\n <span\n class=\"fk-content-split__rail-toggle-icon\"\n [class.fk-content-split__rail-toggle-icon--open]=\"!collapsed()\"\n aria-hidden=\"true\"\n >\n <span class=\"fk-content-split__rail-toggle-projected\">\n <ng-content select=\"[contentSplitToggleIcon]\" />\n </span>\n <svg\n class=\"fk-content-split__rail-toggle-fallback\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M15.25 9H2.75\" />\n <path d=\"M11 4.75L15.25 9L11 13.25\" />\n </svg>\n </span>\n </button>\n</div>\n\n<div class=\"fk-content-split__right\">\n <ng-content select=\"[contentSplitRight]\" />\n</div>\n", styles: [":host{display:flex;position:relative;height:100%;overflow:hidden}.fk-content-split__left{width:var(--fk-content-split-left-width, 280px);flex-shrink:0;overflow:hidden;background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0))}.fk-content-split__left-content{height:100%;overflow-y:auto;overscroll-behavior:contain}.fk-content-split__overlay,.fk-content-split__rail{display:none}.fk-content-split__right{flex:1;min-width:0;overflow-y:auto}:host(.fk-content-split--narrow) .fk-content-split__left{position:absolute;top:0;left:0;bottom:0;z-index:var(--fk-content-split-panel-z-index, 11);width:min(var(--fk-content-split-left-width, 280px),100% - var(--fk-content-split-rail-width, 64px));transform:translate(-100%);visibility:hidden;pointer-events:none;background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0))}:host(.fk-content-split--narrow) .fk-content-split__left--open{transform:translate(var(--fk-content-split-rail-width, 64px));visibility:visible;pointer-events:auto}:host(.fk-content-split--narrow) .fk-content-split__overlay{display:block;position:absolute;inset:0;left:var(--fk-content-split-rail-width, 64px);z-index:var(--fk-content-split-overlay-z-index, 10);background:var(--fk-content-split-overlay-bg, var(--fk-black-50, rgba(0, 0, 0, .5)))}:host(.fk-content-split--narrow) .fk-content-split__rail{display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:var(--fk-content-split-rail-width, 64px);background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0));overflow-y:auto;overscroll-behavior:contain}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle{display:flex;align-items:center;justify-content:center;width:100%;padding:var(--fk-content-split-rail-toggle-padding, var(--fk-rhythm-3, .75rem)) 0;border:none;background:transparent;color:var(--fk-content-split-rail-toggle-color, var(--fk-color-muted, #64748b));cursor:pointer;flex-shrink:0}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle:hover{color:var(--fk-content-split-rail-toggle-color-hover, var(--fk-color-text, #1f2d3d));background:var(--fk-content-split-rail-toggle-bg-hover, var(--fk-color-surface-muted, #f1f5f9))}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle:focus-visible{outline:var(--fk-focus-ring, 0 0 0 3px rgba(59, 130, 246, .5));outline-offset:-2px}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-icon{display:flex;align-items:center;justify-content:center;transition:transform .15s ease}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-icon--open{transform:rotate(180deg)}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-projected{display:contents}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-projected:empty+.fk-content-split__rail-toggle-fallback{display:block}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-fallback{display:none}:host(.fk-content-split--narrow) .fk-content-split__right{flex:1;min-width:0}:host(.fk-content-split--animate) .fk-content-split__left{transition:transform .25s cubic-bezier(.4,0,.2,1),visibility 0s .25s}:host(.fk-content-split--animate.fk-content-split--open) .fk-content-split__left{transition:transform .25s cubic-bezier(.4,0,.2,1),visibility 0s 0s}@media(prefers-reduced-motion:reduce){:host(.fk-content-split--animate) .fk-content-split__left{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
120
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: FkContentSplitComponent, isStandalone: true, selector: "fk-content-split", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, leftWidth: { classPropertyName: "leftWidth", publicName: "leftWidth", isSignal: true, isRequired: false, transformFunction: null }, railWidth: { classPropertyName: "railWidth", publicName: "railWidth", isSignal: true, isRequired: false, transformFunction: null }, breakpoint: { classPropertyName: "breakpoint", publicName: "breakpoint", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange" }, host: { properties: { "class": "this.hostClass", "style.--fk-content-split-left-width": "this.hostLeftWidth", "style.--fk-content-split-rail-width": "this.hostRailWidth", "style.--fk-content-split-max-width": "this.hostMaxWidth" } }, ngImport: i0, template: "@if (showOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-content-split__overlay\" (click)=\"dismiss()\"></div>\n}\n\n<div\n class=\"fk-content-split__left\"\n [class.fk-content-split__left--open]=\"!collapsed()\"\n>\n <div class=\"fk-content-split__left-content\">\n <ng-content select=\"[contentSplitLeft]\" />\n </div>\n</div>\n\n<div class=\"fk-content-split__rail\">\n <button\n class=\"fk-content-split__rail-toggle\"\n type=\"button\"\n [attr.aria-label]=\"collapsed() ? 'Open panel' : 'Close panel'\"\n (click)=\"toggle()\"\n >\n <span\n class=\"fk-content-split__rail-toggle-icon\"\n [class.fk-content-split__rail-toggle-icon--open]=\"!collapsed()\"\n aria-hidden=\"true\"\n >\n <span class=\"fk-content-split__rail-toggle-projected\">\n <ng-content select=\"[contentSplitToggleIcon]\" />\n </span>\n <svg\n class=\"fk-content-split__rail-toggle-fallback\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M15.25 9H2.75\" />\n <path d=\"M11 4.75L15.25 9L11 13.25\" />\n </svg>\n </span>\n </button>\n</div>\n\n<div class=\"fk-content-split__right\">\n <ng-content select=\"[contentSplitRight]\" />\n</div>\n", styles: [":host{display:flex;position:relative;height:100%;overflow:hidden;max-width:var(--fk-content-split-max-width, none);margin-inline:auto}.fk-content-split__left{width:var(--fk-content-split-left-width, 280px);flex-shrink:0;overflow:hidden;background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0))}.fk-content-split__left-content{height:100%;overflow-y:auto;overscroll-behavior:contain}.fk-content-split__overlay,.fk-content-split__rail{display:none}.fk-content-split__right{flex:1;min-width:0;overflow-y:auto}:host(.fk-content-split--narrow) .fk-content-split__left{position:absolute;top:0;left:0;bottom:0;z-index:var(--fk-content-split-panel-z-index, 11);width:min(var(--fk-content-split-left-width, 280px),100% - var(--fk-content-split-rail-width, 64px));transform:translate(-100%);visibility:hidden;pointer-events:none;background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0))}:host(.fk-content-split--narrow) .fk-content-split__left--open{transform:translate(var(--fk-content-split-rail-width, 64px));visibility:visible;pointer-events:auto}:host(.fk-content-split--narrow) .fk-content-split__overlay{display:block;position:absolute;inset:0;left:var(--fk-content-split-rail-width, 64px);z-index:var(--fk-content-split-overlay-z-index, 10);background:var(--fk-content-split-overlay-bg, var(--fk-black-50, rgba(0, 0, 0, .5)))}:host(.fk-content-split--narrow) .fk-content-split__rail{display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:var(--fk-content-split-rail-width, 64px);background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0));overflow-y:auto;overscroll-behavior:contain}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle{display:flex;align-items:center;justify-content:center;width:100%;padding:var(--fk-content-split-rail-toggle-padding, var(--fk-rhythm-3, .75rem)) 0;border:none;background:transparent;color:var(--fk-content-split-rail-toggle-color, var(--fk-color-muted, #64748b));cursor:pointer;flex-shrink:0}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle:hover{color:var(--fk-content-split-rail-toggle-color-hover, var(--fk-color-text, #1f2d3d));background:var(--fk-content-split-rail-toggle-bg-hover, var(--fk-color-surface-muted, #f1f5f9))}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle:focus-visible{outline:var(--fk-focus-ring, 0 0 0 3px rgba(59, 130, 246, .5));outline-offset:-2px}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-icon{display:flex;align-items:center;justify-content:center;transition:transform .15s ease}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-icon--open{transform:rotate(180deg)}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-projected{display:contents}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-projected:empty+.fk-content-split__rail-toggle-fallback{display:block}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-fallback{display:none}:host(.fk-content-split--narrow) .fk-content-split__right{flex:1;min-width:0}:host(.fk-content-split--animate) .fk-content-split__left{transition:transform .25s cubic-bezier(.4,0,.2,1),visibility 0s .25s}:host(.fk-content-split--animate.fk-content-split--open) .fk-content-split__left{transition:transform .25s cubic-bezier(.4,0,.2,1),visibility 0s 0s}@media(prefers-reduced-motion:reduce){:host(.fk-content-split--animate) .fk-content-split__left{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
112
121
|
}
|
|
113
122
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkContentSplitComponent, decorators: [{
|
|
114
123
|
type: Component,
|
|
115
|
-
args: [{ selector: 'fk-content-split', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (showOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-content-split__overlay\" (click)=\"dismiss()\"></div>\n}\n\n<div\n class=\"fk-content-split__left\"\n [class.fk-content-split__left--open]=\"!collapsed()\"\n>\n <div class=\"fk-content-split__left-content\">\n <ng-content select=\"[contentSplitLeft]\" />\n </div>\n</div>\n\n<div class=\"fk-content-split__rail\">\n <button\n class=\"fk-content-split__rail-toggle\"\n type=\"button\"\n [attr.aria-label]=\"collapsed() ? 'Open panel' : 'Close panel'\"\n (click)=\"toggle()\"\n >\n <span\n class=\"fk-content-split__rail-toggle-icon\"\n [class.fk-content-split__rail-toggle-icon--open]=\"!collapsed()\"\n aria-hidden=\"true\"\n >\n <span class=\"fk-content-split__rail-toggle-projected\">\n <ng-content select=\"[contentSplitToggleIcon]\" />\n </span>\n <svg\n class=\"fk-content-split__rail-toggle-fallback\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M15.25 9H2.75\" />\n <path d=\"M11 4.75L15.25 9L11 13.25\" />\n </svg>\n </span>\n </button>\n</div>\n\n<div class=\"fk-content-split__right\">\n <ng-content select=\"[contentSplitRight]\" />\n</div>\n", styles: [":host{display:flex;position:relative;height:100%;overflow:hidden}.fk-content-split__left{width:var(--fk-content-split-left-width, 280px);flex-shrink:0;overflow:hidden;background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0))}.fk-content-split__left-content{height:100%;overflow-y:auto;overscroll-behavior:contain}.fk-content-split__overlay,.fk-content-split__rail{display:none}.fk-content-split__right{flex:1;min-width:0;overflow-y:auto}:host(.fk-content-split--narrow) .fk-content-split__left{position:absolute;top:0;left:0;bottom:0;z-index:var(--fk-content-split-panel-z-index, 11);width:min(var(--fk-content-split-left-width, 280px),100% - var(--fk-content-split-rail-width, 64px));transform:translate(-100%);visibility:hidden;pointer-events:none;background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0))}:host(.fk-content-split--narrow) .fk-content-split__left--open{transform:translate(var(--fk-content-split-rail-width, 64px));visibility:visible;pointer-events:auto}:host(.fk-content-split--narrow) .fk-content-split__overlay{display:block;position:absolute;inset:0;left:var(--fk-content-split-rail-width, 64px);z-index:var(--fk-content-split-overlay-z-index, 10);background:var(--fk-content-split-overlay-bg, var(--fk-black-50, rgba(0, 0, 0, .5)))}:host(.fk-content-split--narrow) .fk-content-split__rail{display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:var(--fk-content-split-rail-width, 64px);background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0));overflow-y:auto;overscroll-behavior:contain}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle{display:flex;align-items:center;justify-content:center;width:100%;padding:var(--fk-content-split-rail-toggle-padding, var(--fk-rhythm-3, .75rem)) 0;border:none;background:transparent;color:var(--fk-content-split-rail-toggle-color, var(--fk-color-muted, #64748b));cursor:pointer;flex-shrink:0}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle:hover{color:var(--fk-content-split-rail-toggle-color-hover, var(--fk-color-text, #1f2d3d));background:var(--fk-content-split-rail-toggle-bg-hover, var(--fk-color-surface-muted, #f1f5f9))}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle:focus-visible{outline:var(--fk-focus-ring, 0 0 0 3px rgba(59, 130, 246, .5));outline-offset:-2px}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-icon{display:flex;align-items:center;justify-content:center;transition:transform .15s ease}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-icon--open{transform:rotate(180deg)}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-projected{display:contents}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-projected:empty+.fk-content-split__rail-toggle-fallback{display:block}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-fallback{display:none}:host(.fk-content-split--narrow) .fk-content-split__right{flex:1;min-width:0}:host(.fk-content-split--animate) .fk-content-split__left{transition:transform .25s cubic-bezier(.4,0,.2,1),visibility 0s .25s}:host(.fk-content-split--animate.fk-content-split--open) .fk-content-split__left{transition:transform .25s cubic-bezier(.4,0,.2,1),visibility 0s 0s}@media(prefers-reduced-motion:reduce){:host(.fk-content-split--animate) .fk-content-split__left{transition:none}}\n"] }]
|
|
116
|
-
}], ctorParameters: () => [], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], leftWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "leftWidth", required: false }] }], railWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "railWidth", required: false }] }], breakpoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "breakpoint", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }, { type: i0.Output, args: ["collapsedChange"] }], hostClass: [{
|
|
124
|
+
args: [{ selector: 'fk-content-split', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (showOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-content-split__overlay\" (click)=\"dismiss()\"></div>\n}\n\n<div\n class=\"fk-content-split__left\"\n [class.fk-content-split__left--open]=\"!collapsed()\"\n>\n <div class=\"fk-content-split__left-content\">\n <ng-content select=\"[contentSplitLeft]\" />\n </div>\n</div>\n\n<div class=\"fk-content-split__rail\">\n <button\n class=\"fk-content-split__rail-toggle\"\n type=\"button\"\n [attr.aria-label]=\"collapsed() ? 'Open panel' : 'Close panel'\"\n (click)=\"toggle()\"\n >\n <span\n class=\"fk-content-split__rail-toggle-icon\"\n [class.fk-content-split__rail-toggle-icon--open]=\"!collapsed()\"\n aria-hidden=\"true\"\n >\n <span class=\"fk-content-split__rail-toggle-projected\">\n <ng-content select=\"[contentSplitToggleIcon]\" />\n </span>\n <svg\n class=\"fk-content-split__rail-toggle-fallback\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M15.25 9H2.75\" />\n <path d=\"M11 4.75L15.25 9L11 13.25\" />\n </svg>\n </span>\n </button>\n</div>\n\n<div class=\"fk-content-split__right\">\n <ng-content select=\"[contentSplitRight]\" />\n</div>\n", styles: [":host{display:flex;position:relative;height:100%;overflow:hidden;max-width:var(--fk-content-split-max-width, none);margin-inline:auto}.fk-content-split__left{width:var(--fk-content-split-left-width, 280px);flex-shrink:0;overflow:hidden;background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0))}.fk-content-split__left-content{height:100%;overflow-y:auto;overscroll-behavior:contain}.fk-content-split__overlay,.fk-content-split__rail{display:none}.fk-content-split__right{flex:1;min-width:0;overflow-y:auto}:host(.fk-content-split--narrow) .fk-content-split__left{position:absolute;top:0;left:0;bottom:0;z-index:var(--fk-content-split-panel-z-index, 11);width:min(var(--fk-content-split-left-width, 280px),100% - var(--fk-content-split-rail-width, 64px));transform:translate(-100%);visibility:hidden;pointer-events:none;background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0))}:host(.fk-content-split--narrow) .fk-content-split__left--open{transform:translate(var(--fk-content-split-rail-width, 64px));visibility:visible;pointer-events:auto}:host(.fk-content-split--narrow) .fk-content-split__overlay{display:block;position:absolute;inset:0;left:var(--fk-content-split-rail-width, 64px);z-index:var(--fk-content-split-overlay-z-index, 10);background:var(--fk-content-split-overlay-bg, var(--fk-black-50, rgba(0, 0, 0, .5)))}:host(.fk-content-split--narrow) .fk-content-split__rail{display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:var(--fk-content-split-rail-width, 64px);background:var(--fk-content-split-left-bg, var(--fk-color-surface, #ffffff));border-right:var(--fk-content-split-left-border, 1px solid var(--fk-color-border, #e2e8f0));overflow-y:auto;overscroll-behavior:contain}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle{display:flex;align-items:center;justify-content:center;width:100%;padding:var(--fk-content-split-rail-toggle-padding, var(--fk-rhythm-3, .75rem)) 0;border:none;background:transparent;color:var(--fk-content-split-rail-toggle-color, var(--fk-color-muted, #64748b));cursor:pointer;flex-shrink:0}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle:hover{color:var(--fk-content-split-rail-toggle-color-hover, var(--fk-color-text, #1f2d3d));background:var(--fk-content-split-rail-toggle-bg-hover, var(--fk-color-surface-muted, #f1f5f9))}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle:focus-visible{outline:var(--fk-focus-ring, 0 0 0 3px rgba(59, 130, 246, .5));outline-offset:-2px}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-icon{display:flex;align-items:center;justify-content:center;transition:transform .15s ease}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-icon--open{transform:rotate(180deg)}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-projected{display:contents}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-projected:empty+.fk-content-split__rail-toggle-fallback{display:block}:host(.fk-content-split--narrow) .fk-content-split__rail-toggle-fallback{display:none}:host(.fk-content-split--narrow) .fk-content-split__right{flex:1;min-width:0}:host(.fk-content-split--animate) .fk-content-split__left{transition:transform .25s cubic-bezier(.4,0,.2,1),visibility 0s .25s}:host(.fk-content-split--animate.fk-content-split--open) .fk-content-split__left{transition:transform .25s cubic-bezier(.4,0,.2,1),visibility 0s 0s}@media(prefers-reduced-motion:reduce){:host(.fk-content-split--animate) .fk-content-split__left{transition:none}}\n"] }]
|
|
125
|
+
}], ctorParameters: () => [], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], leftWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "leftWidth", required: false }] }], railWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "railWidth", required: false }] }], breakpoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "breakpoint", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }, { type: i0.Output, args: ["collapsedChange"] }], hostClass: [{
|
|
117
126
|
type: HostBinding,
|
|
118
127
|
args: ['class']
|
|
119
128
|
}], hostLeftWidth: [{
|
|
@@ -122,6 +131,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
122
131
|
}], hostRailWidth: [{
|
|
123
132
|
type: HostBinding,
|
|
124
133
|
args: ['style.--fk-content-split-rail-width']
|
|
134
|
+
}], hostMaxWidth: [{
|
|
135
|
+
type: HostBinding,
|
|
136
|
+
args: ['style.--fk-content-split-max-width']
|
|
125
137
|
}] } });
|
|
126
138
|
|
|
127
139
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame-kit-ui-ng-layouts-content-split.mjs","sources":["../../../../packages/ui-ng/layouts/content-split/content-split.component.ts","../../../../packages/ui-ng/layouts/content-split/content-split.component.html","../../../../packages/ui-ng/layouts/content-split/frame-kit-ui-ng-layouts-content-split.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n HostBinding,\n inject,\n input,\n model,\n NgZone,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\n\nimport type { ContentSplitLayout } from './content-split.types';\n\n@Component({\n selector: 'fk-content-split',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './content-split.component.html',\n styleUrl: './content-split.component.scss',\n})\nexport class FkContentSplitComponent {\n private readonly el = inject(ElementRef<HTMLElement>);\n private readonly ngZone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n private readonly platformId = inject(PLATFORM_ID);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n\n // ===== INPUTS =====\n /** Width of the left panel when the layout is in wide mode. */\n readonly leftWidth = input<string>('280px');\n /** Width of the left panel when collapsed to a narrow icon rail. */\n readonly railWidth = input<string>('64px');\n /** Host element pixel width below which the layout switches to narrow mode. */\n readonly breakpoint = input<number>(700);\n /** Two-way binding for the collapsed state of the left panel. */\n readonly collapsed = model<boolean>(false);\n\n // ===== INTERNAL STATE =====\n readonly layout = signal<ContentSplitLayout>('wide');\n readonly animate = signal(false);\n\n private observer: ResizeObserver | null = null;\n\n // ===== COMPUTED =====\n readonly isNarrow = computed(() => this.layout() === 'narrow');\n readonly isWide = computed(() => this.layout() === 'wide');\n readonly showOverlay = computed(() => this.isNarrow() && !this.collapsed());\n\n readonly classes = computed(() =>\n [\n 'fk-content-split',\n this.isNarrow() ? 'fk-content-split--narrow' : 'fk-content-split--wide',\n this.isNarrow() && !this.collapsed() ? 'fk-content-split--open' : '',\n this.isNarrow() && this.collapsed() ? 'fk-content-split--closed' : '',\n this.animate() ? 'fk-content-split--animate' : '',\n this.className(),\n ]\n .filter(Boolean)\n .join(' '),\n );\n\n // ===== HOST BINDINGS =====\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('style.--fk-content-split-left-width')\n get hostLeftWidth() {\n return this.leftWidth();\n }\n\n @HostBinding('style.--fk-content-split-rail-width')\n get hostRailWidth() {\n return this.railWidth();\n }\n\n // ===== CONSTRUCTOR =====\n\n constructor() {\n // ResizeObserver is browser-only — the SSR pass has no live\n // layout to observe, so the initial layout signal stays at its\n // default (\"wide\") and the browser pass wires the observer once\n // hydration mounts the element.\n if (isPlatformBrowser(this.platformId)) {\n this.ngZone.runOutsideAngular(() => {\n this.observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n\n if (!entry) {\n return;\n }\n\n const hostWidth = entry.contentRect.width;\n const bp = this.breakpoint();\n\n if (hostWidth < bp && this.layout() !== 'narrow') {\n this.ngZone.run(() => {\n this.layout.set('narrow');\n this.animate.set(false);\n this.collapsed.set(true);\n });\n } else if (hostWidth >= bp && this.layout() !== 'wide') {\n this.ngZone.run(() => {\n this.layout.set('wide');\n this.animate.set(false);\n this.collapsed.set(true);\n });\n }\n });\n\n this.observer.observe(this.el.nativeElement);\n });\n }\n\n this.destroyRef.onDestroy(() => {\n this.observer?.disconnect();\n });\n }\n\n // ===== PUBLIC METHODS =====\n\n /** Expand the left panel. */\n open(): void {\n this.animate.set(true);\n this.collapsed.set(false);\n }\n\n /** Collapse the left panel. */\n close(): void {\n this.animate.set(true);\n this.collapsed.set(true);\n }\n\n /** Toggle the left panel between expanded and collapsed. */\n toggle(): void {\n if (this.collapsed()) {\n this.open();\n } else {\n this.close();\n }\n }\n\n /** Dismiss the left panel overlay on narrow viewports (alias for `close`). */\n dismiss(): void {\n this.close();\n }\n}\n","@if (showOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-content-split__overlay\" (click)=\"dismiss()\"></div>\n}\n\n<div\n class=\"fk-content-split__left\"\n [class.fk-content-split__left--open]=\"!collapsed()\"\n>\n <div class=\"fk-content-split__left-content\">\n <ng-content select=\"[contentSplitLeft]\" />\n </div>\n</div>\n\n<div class=\"fk-content-split__rail\">\n <button\n class=\"fk-content-split__rail-toggle\"\n type=\"button\"\n [attr.aria-label]=\"collapsed() ? 'Open panel' : 'Close panel'\"\n (click)=\"toggle()\"\n >\n <span\n class=\"fk-content-split__rail-toggle-icon\"\n [class.fk-content-split__rail-toggle-icon--open]=\"!collapsed()\"\n aria-hidden=\"true\"\n >\n <span class=\"fk-content-split__rail-toggle-projected\">\n <ng-content select=\"[contentSplitToggleIcon]\" />\n </span>\n <svg\n class=\"fk-content-split__rail-toggle-fallback\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M15.25 9H2.75\" />\n <path d=\"M11 4.75L15.25 9L11 13.25\" />\n </svg>\n </span>\n </button>\n</div>\n\n<div class=\"fk-content-split__right\">\n <ng-content select=\"[contentSplitRight]\" />\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"frame-kit-ui-ng-layouts-content-split.mjs","sources":["../../../../packages/ui-ng/layouts/content-split/content-split.component.ts","../../../../packages/ui-ng/layouts/content-split/content-split.component.html","../../../../packages/ui-ng/layouts/content-split/frame-kit-ui-ng-layouts-content-split.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n HostBinding,\n inject,\n input,\n model,\n NgZone,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\n\nimport type { ContentSplitLayout } from './content-split.types';\n\n@Component({\n selector: 'fk-content-split',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './content-split.component.html',\n styleUrl: './content-split.component.scss',\n})\nexport class FkContentSplitComponent {\n private readonly el = inject(ElementRef<HTMLElement>);\n private readonly ngZone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n private readonly platformId = inject(PLATFORM_ID);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n\n // ===== INPUTS =====\n /** Width of the left panel when the layout is in wide mode. */\n readonly leftWidth = input<string>('280px');\n /** Width of the left panel when collapsed to a narrow icon rail. */\n readonly railWidth = input<string>('64px');\n /** Host element pixel width below which the layout switches to narrow mode. */\n readonly breakpoint = input<number>(700);\n /**\n * Optional CSS max-width for the layout. When set, the split is capped at\n * this width and centered in its container (via auto inline margins);\n * unset (default), it fills the full available width as before.\n */\n readonly maxWidth = input<string | null>(null);\n /** Two-way binding for the collapsed state of the left panel. */\n readonly collapsed = model<boolean>(false);\n\n // ===== INTERNAL STATE =====\n readonly layout = signal<ContentSplitLayout>('wide');\n readonly animate = signal(false);\n\n private observer: ResizeObserver | null = null;\n\n // ===== COMPUTED =====\n readonly isNarrow = computed(() => this.layout() === 'narrow');\n readonly isWide = computed(() => this.layout() === 'wide');\n readonly showOverlay = computed(() => this.isNarrow() && !this.collapsed());\n\n readonly classes = computed(() =>\n [\n 'fk-content-split',\n this.isNarrow() ? 'fk-content-split--narrow' : 'fk-content-split--wide',\n this.isNarrow() && !this.collapsed() ? 'fk-content-split--open' : '',\n this.isNarrow() && this.collapsed() ? 'fk-content-split--closed' : '',\n this.animate() ? 'fk-content-split--animate' : '',\n this.className(),\n ]\n .filter(Boolean)\n .join(' '),\n );\n\n // ===== HOST BINDINGS =====\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('style.--fk-content-split-left-width')\n get hostLeftWidth() {\n return this.leftWidth();\n }\n\n @HostBinding('style.--fk-content-split-rail-width')\n get hostRailWidth() {\n return this.railWidth();\n }\n\n @HostBinding('style.--fk-content-split-max-width')\n get hostMaxWidth() {\n return this.maxWidth();\n }\n\n // ===== CONSTRUCTOR =====\n\n constructor() {\n // ResizeObserver is browser-only — the SSR pass has no live\n // layout to observe, so the initial layout signal stays at its\n // default (\"wide\") and the browser pass wires the observer once\n // hydration mounts the element.\n if (isPlatformBrowser(this.platformId)) {\n this.ngZone.runOutsideAngular(() => {\n this.observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n\n if (!entry) {\n return;\n }\n\n const hostWidth = entry.contentRect.width;\n const bp = this.breakpoint();\n\n if (hostWidth < bp && this.layout() !== 'narrow') {\n this.ngZone.run(() => {\n this.layout.set('narrow');\n this.animate.set(false);\n this.collapsed.set(true);\n });\n } else if (hostWidth >= bp && this.layout() !== 'wide') {\n this.ngZone.run(() => {\n this.layout.set('wide');\n this.animate.set(false);\n this.collapsed.set(true);\n });\n }\n });\n\n this.observer.observe(this.el.nativeElement);\n });\n }\n\n this.destroyRef.onDestroy(() => {\n this.observer?.disconnect();\n });\n }\n\n // ===== PUBLIC METHODS =====\n\n /** Expand the left panel. */\n open(): void {\n this.animate.set(true);\n this.collapsed.set(false);\n }\n\n /** Collapse the left panel. */\n close(): void {\n this.animate.set(true);\n this.collapsed.set(true);\n }\n\n /** Toggle the left panel between expanded and collapsed. */\n toggle(): void {\n if (this.collapsed()) {\n this.open();\n } else {\n this.close();\n }\n }\n\n /** Dismiss the left panel overlay on narrow viewports (alias for `close`). */\n dismiss(): void {\n this.close();\n }\n}\n","@if (showOverlay()) {\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"fk-content-split__overlay\" (click)=\"dismiss()\"></div>\n}\n\n<div\n class=\"fk-content-split__left\"\n [class.fk-content-split__left--open]=\"!collapsed()\"\n>\n <div class=\"fk-content-split__left-content\">\n <ng-content select=\"[contentSplitLeft]\" />\n </div>\n</div>\n\n<div class=\"fk-content-split__rail\">\n <button\n class=\"fk-content-split__rail-toggle\"\n type=\"button\"\n [attr.aria-label]=\"collapsed() ? 'Open panel' : 'Close panel'\"\n (click)=\"toggle()\"\n >\n <span\n class=\"fk-content-split__rail-toggle-icon\"\n [class.fk-content-split__rail-toggle-icon--open]=\"!collapsed()\"\n aria-hidden=\"true\"\n >\n <span class=\"fk-content-split__rail-toggle-projected\">\n <ng-content select=\"[contentSplitToggleIcon]\" />\n </span>\n <svg\n class=\"fk-content-split__rail-toggle-fallback\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M15.25 9H2.75\" />\n <path d=\"M11 4.75L15.25 9L11 13.25\" />\n </svg>\n </span>\n </button>\n</div>\n\n<div class=\"fk-content-split__right\">\n <ng-content select=\"[contentSplitRight]\" />\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -8,13 +8,14 @@ A container-aware split-pane layout component for Angular. In wide containers, r
|
|
|
8
8
|
|
|
9
9
|
### Inputs
|
|
10
10
|
|
|
11
|
-
| Input | Type | Default | Description
|
|
12
|
-
| ------------ | ---------------- | --------- |
|
|
13
|
-
| `leftWidth` | `string` | `'280px'` | CSS width of the left panel
|
|
14
|
-
| `railWidth` | `string` | `'64px'` | Width of the rail strip in narrow mode
|
|
15
|
-
| `breakpoint` | `number` | `700` | Host width (px) below which drawer mode activates
|
|
16
|
-
| `
|
|
17
|
-
| `
|
|
11
|
+
| Input | Type | Default | Description |
|
|
12
|
+
| ------------ | ---------------- | --------- | -------------------------------------------------------------------- |
|
|
13
|
+
| `leftWidth` | `string` | `'280px'` | CSS width of the left panel |
|
|
14
|
+
| `railWidth` | `string` | `'64px'` | Width of the rail strip in narrow mode |
|
|
15
|
+
| `breakpoint` | `number` | `700` | Host width (px) below which drawer mode activates |
|
|
16
|
+
| `maxWidth` | `string \| null` | `null` | Caps the layout at this width and centers it; unset fills full width |
|
|
17
|
+
| `collapsed` | `model<boolean>` | `false` | Two-way binding for drawer open/closed state |
|
|
18
|
+
| `className` | `string` | `''` | Additional CSS classes for the host |
|
|
18
19
|
|
|
19
20
|
### Methods
|
|
20
21
|
|
|
@@ -139,6 +140,7 @@ export class ExampleComponent {}
|
|
|
139
140
|
| -------------------------------------------- | ---------------------------------- | ---------------------------------------- |
|
|
140
141
|
| `--fk-content-split-left-width` | `280px` | Left panel width (capped in narrow mode) |
|
|
141
142
|
| `--fk-content-split-rail-width` | `64px` | Rail strip width in narrow mode |
|
|
143
|
+
| `--fk-content-split-max-width` | `none` | Caps + centers the whole layout |
|
|
142
144
|
| `--fk-content-split-left-bg` | `var(--fk-color-surface)` | Left panel / rail background |
|
|
143
145
|
| `--fk-content-split-left-border` | `1px solid var(--fk-color-border)` | Left panel / rail border |
|
|
144
146
|
| `--fk-content-split-overlay-bg` | `rgba(0, 0, 0, 0.5)` | Overlay backdrop color |
|
package/package.json
CHANGED
|
@@ -14,6 +14,12 @@ declare class FkContentSplitComponent {
|
|
|
14
14
|
readonly railWidth: _angular_core.InputSignal<string>;
|
|
15
15
|
/** Host element pixel width below which the layout switches to narrow mode. */
|
|
16
16
|
readonly breakpoint: _angular_core.InputSignal<number>;
|
|
17
|
+
/**
|
|
18
|
+
* Optional CSS max-width for the layout. When set, the split is capped at
|
|
19
|
+
* this width and centered in its container (via auto inline margins);
|
|
20
|
+
* unset (default), it fills the full available width as before.
|
|
21
|
+
*/
|
|
22
|
+
readonly maxWidth: _angular_core.InputSignal<string | null>;
|
|
17
23
|
/** Two-way binding for the collapsed state of the left panel. */
|
|
18
24
|
readonly collapsed: _angular_core.ModelSignal<boolean>;
|
|
19
25
|
readonly layout: _angular_core.WritableSignal<ContentSplitLayout>;
|
|
@@ -26,6 +32,7 @@ declare class FkContentSplitComponent {
|
|
|
26
32
|
get hostClass(): string;
|
|
27
33
|
get hostLeftWidth(): string;
|
|
28
34
|
get hostRailWidth(): string;
|
|
35
|
+
get hostMaxWidth(): string | null;
|
|
29
36
|
constructor();
|
|
30
37
|
/** Expand the left panel. */
|
|
31
38
|
open(): void;
|
|
@@ -36,7 +43,7 @@ declare class FkContentSplitComponent {
|
|
|
36
43
|
/** Dismiss the left panel overlay on narrow viewports (alias for `close`). */
|
|
37
44
|
dismiss(): void;
|
|
38
45
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FkContentSplitComponent, never>;
|
|
39
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FkContentSplitComponent, "fk-content-split", never, { "className": { "alias": "className"; "required": false; "isSignal": true; }; "leftWidth": { "alias": "leftWidth"; "required": false; "isSignal": true; }; "railWidth": { "alias": "railWidth"; "required": false; "isSignal": true; }; "breakpoint": { "alias": "breakpoint"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; }, never, ["[contentSplitLeft]", "[contentSplitToggleIcon]", "[contentSplitRight]"], true, never>;
|
|
46
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FkContentSplitComponent, "fk-content-split", never, { "className": { "alias": "className"; "required": false; "isSignal": true; }; "leftWidth": { "alias": "leftWidth"; "required": false; "isSignal": true; }; "railWidth": { "alias": "railWidth"; "required": false; "isSignal": true; }; "breakpoint": { "alias": "breakpoint"; "required": false; "isSignal": true; }; "maxWidth": { "alias": "maxWidth"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; }, never, ["[contentSplitLeft]", "[contentSplitToggleIcon]", "[contentSplitRight]"], true, never>;
|
|
40
47
|
}
|
|
41
48
|
|
|
42
49
|
export { FkContentSplitComponent };
|