@ixfx/components 0.15.1 → 0.15.3

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.
package/dist/index.d.ts CHANGED
@@ -2664,6 +2664,11 @@ declare class PanelGroupElement extends LitElement {
2664
2664
  collapsible: boolean;
2665
2665
  accordion: boolean;
2666
2666
  allowReorder: boolean;
2667
+ /**
2668
+ * Pin each panel's titlebar to the top (or left, for vertical titlebars) of the scroll area
2669
+ * while its content is in view. On by default; set `sticky-headers="false"` to disable.
2670
+ */
2671
+ stickyHeaders: boolean;
2667
2672
  /** Explicit gap between panels. When unset, `--group-gap` (falling back to `--space-l`) controls the gap. */
2668
2673
  gap?: string;
2669
2674
  private _panels;
package/dist/index.js CHANGED
@@ -75,6 +75,7 @@ import { createCommandRegistry } from "@clinth/ui-commands";
75
75
  import { repeat } from "lit/directives/repeat.js";
76
76
  import { Trees } from "@ixfx/collections";
77
77
  import { clamp, clamper, scaler } from "@ixfx/numbers";
78
+ import { live } from "lit/directives/live.js";
78
79
  //#region src/bottom-drawer/bottom-drawer.ts
79
80
  /** Builds the command id for a named drawer's command, e.g. `inspector.expand`. */
80
81
  function bottomDrawerCommandId(name, command) {
@@ -5255,7 +5256,7 @@ let DockHostElement = class DockHostElement extends LitElement {
5255
5256
  <ixfx-split-layout
5256
5257
  class="split"
5257
5258
  direction=${node.direction}
5258
- size=${size === void 0 ? nothing : String(size)}
5259
+ size=${size === void 0 ? nothing : live(String(size))}
5259
5260
  style=${`--split-gutter-size: var(--dock-split-bar-size, 2px); --split-collapsed-size: var(--dock-collapsed-size, 40px)`}
5260
5261
  data-dock-path=${pathStr}
5261
5262
  data-dock-gen=${this._loadGeneration}
@@ -5278,7 +5279,7 @@ let DockHostElement = class DockHostElement extends LitElement {
5278
5279
  class="leaf"
5279
5280
  data-dock-path=${pathStr}
5280
5281
  data-dock-name=${stack.name ?? nothing}
5281
- size=${size === void 0 ? nothing : String(size)}
5282
+ size=${size === void 0 ? nothing : live(String(size))}
5282
5283
  min=${collapsible ? `1px` : nothing}
5283
5284
  when-small=${collapsible ? `collapse` : nothing}
5284
5285
  ?collapsed=${stack.collapsed === true}
@@ -11050,6 +11051,7 @@ let PanelGroupElement = class PanelGroupElement extends LitElement {
11050
11051
  this.collapsible = true;
11051
11052
  this.accordion = false;
11052
11053
  this.allowReorder = false;
11054
+ this.stickyHeaders = true;
11053
11055
  this._dragState = null;
11054
11056
  this._suppressNextClick = false;
11055
11057
  this._onClickCapture = (event) => {
@@ -11147,7 +11149,7 @@ let PanelGroupElement = class PanelGroupElement extends LitElement {
11147
11149
  if (this.gap !== void 0) this.style.setProperty(`--group-gap`, this.gap);
11148
11150
  else this.style.removeProperty(`--group-gap`);
11149
11151
  }
11150
- if (changed.has(`variant`) || changed.has(`toggleInteraction`) || changed.has(`orientation`) || changed.has(`collapsible`)) this.updateComplete.then(() => {
11152
+ if (changed.has(`variant`) || changed.has(`toggleInteraction`) || changed.has(`orientation`) || changed.has(`collapsible`) || changed.has(`stickyHeaders`)) this.updateComplete.then(() => {
11151
11153
  this._propagateAll();
11152
11154
  });
11153
11155
  }
@@ -11157,6 +11159,7 @@ let PanelGroupElement = class PanelGroupElement extends LitElement {
11157
11159
  panel.setAttribute(`variant`, this.variant);
11158
11160
  panel.setAttribute(`toggle-interaction`, this.toggleInteraction);
11159
11161
  panel.setAttribute(`orientation`, invertedOrientation);
11162
+ panel.toggleAttribute(`sticky-header`, this.stickyHeaders);
11160
11163
  if (this.collapsible) panel.setAttribute(`collapsible`, ``);
11161
11164
  else panel.removeAttribute(`collapsible`);
11162
11165
  }
@@ -11395,6 +11398,14 @@ __decorate([property({
11395
11398
  attribute: `allow-reorder`,
11396
11399
  reflect: true
11397
11400
  })], PanelGroupElement.prototype, "allowReorder", void 0);
11401
+ __decorate([property({
11402
+ attribute: `sticky-headers`,
11403
+ reflect: true,
11404
+ converter: {
11405
+ fromAttribute: (value) => value !== `false`,
11406
+ toAttribute: (value) => value ? `true` : `false`
11407
+ }
11408
+ })], PanelGroupElement.prototype, "stickyHeaders", void 0);
11398
11409
  __decorate([property()], PanelGroupElement.prototype, "gap", void 0);
11399
11410
  __decorate([queryAssignedElements({ slot: `` })], PanelGroupElement.prototype, "_panels", void 0);
11400
11411
  PanelGroupElement = __decorate([safeCustomElement(`ixfx-panel-group`)], PanelGroupElement);
package/dist/panel.d.ts CHANGED
@@ -26,6 +26,11 @@ declare class PanelElement extends LitElement {
26
26
  hideTitlebar: boolean;
27
27
  /** Keep the toolbar visible even when the panel is collapsed. */
28
28
  keepToolbar: boolean;
29
+ /**
30
+ * Keep the titlebar pinned to the edge of the nearest scrolling ancestor while this panel
31
+ * is in view (top for horizontal titlebars, left for vertical). Normally set by `ixfx-panel-group`.
32
+ */
33
+ stickyHeader: boolean;
29
34
  private _onTitlebarToggle;
30
35
  private _onCloseClick;
31
36
  protected render(): import("lit").TemplateResult<1>;
package/dist/panel.js CHANGED
@@ -17,6 +17,7 @@ let PanelElement = class PanelElement extends LitElement {
17
17
  this.variant = `titlebar`;
18
18
  this.hideTitlebar = false;
19
19
  this.keepToolbar = false;
20
+ this.stickyHeader = false;
20
21
  }
21
22
  _onTitlebarToggle(event) {
22
23
  event.stopPropagation();
@@ -85,6 +86,23 @@ let PanelElement = class PanelElement extends LitElement {
85
86
  flex-shrink: 0;
86
87
  }
87
88
 
89
+ /* \`overflow: clip\` (unlike \`hidden\`) does not create a scroll container, so the
90
+ titlebar can stick to the outer scroll area. Sticking is bounded by the panel itself. */
91
+ :host([sticky-header]) {
92
+ overflow: clip;
93
+ }
94
+
95
+ :host([sticky-header]) ixfx-titlebar {
96
+ position: sticky;
97
+ top: 0;
98
+ z-index: 2;
99
+ }
100
+
101
+ :host([sticky-header][orientation="vertical"]) ixfx-titlebar {
102
+ top: auto;
103
+ left: 0;
104
+ }
105
+
88
106
  .content-wrapper {
89
107
  interpolate-size: allow-keywords;
90
108
  overflow: hidden;
@@ -108,7 +126,8 @@ let PanelElement = class PanelElement extends LitElement {
108
126
  }
109
127
 
110
128
  .content-inner {
111
- box-shadow: var(--deboss-3);
129
+ box-shadow: var(--panel-content-shadow, var(--deboss-3));
130
+ border: var(--panel-content-border, none);
112
131
  min-height: 0;
113
132
  min-width: 0;
114
133
  overflow: hidden;
@@ -214,6 +233,11 @@ __decorate([property({
214
233
  type: Boolean,
215
234
  attribute: `keep-toolbar`
216
235
  })], PanelElement.prototype, "keepToolbar", void 0);
236
+ __decorate([property({
237
+ type: Boolean,
238
+ attribute: `sticky-header`,
239
+ reflect: true
240
+ })], PanelElement.prototype, "stickyHeader", void 0);
217
241
  PanelElement = __decorate([safeCustomElement(`ixfx-panel`)], PanelElement);
218
242
  //#endregion
219
243
  export { PanelElement };
package/dist/titlebar.js CHANGED
@@ -157,7 +157,6 @@ let TitlebarElement = class TitlebarElement extends LitElement {
157
157
 
158
158
  .title-text {
159
159
  flex: 1;
160
- padding-left: 1ch;
161
160
  font-family: var(--font-family);
162
161
  font-size: var(--text-m);
163
162
  font-weight: var(--font-weight-bold, 600);
@@ -175,7 +174,6 @@ let TitlebarElement = class TitlebarElement extends LitElement {
175
174
 
176
175
  :host([orientation="vertical"]) .title-text {
177
176
  writing-mode: vertical-rl;
178
- padding-left: 0;
179
177
  padding-bottom: 1ch;
180
178
  text-orientation: mixed;
181
179
  transform: rotate(180deg);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ixfx/components",
3
- "version": "0.15.1",
4
- "generated": "2026-10-18T18:06:38.222Z",
3
+ "version": "0.15.3",
4
+ "generated": "2026-10-18T19:35:32.045Z",
5
5
  "components": [
6
6
  {
7
7
  "name": "ac-text",
@@ -189,6 +189,8 @@ Use the `collapsed` attribute to start the panel in collapsed state:
189
189
  | `--transition` | `0.15s ease-out` | Animation transition duration |
190
190
  | `--panel-width` | `auto` | Width for vertical panels |
191
191
  | `--panel-height` | `auto` | Height for horizontal panels |
192
+ | `--panel-content-shadow`| `var(--deboss-3)` | `box-shadow` of the content area (the inset 3D effect). `none` removes it |
193
+ | `--panel-content-border`| `none` | `border` of the content area |
192
194
  | `--prominence-idle-opacity` | `0.6` | Opacity of caret when idle |
193
195
  | `--prominence-tickled-opacity` | `1.0` | Opacity of caret on hover |
194
196
 
@@ -215,6 +217,7 @@ A container component that manages multiple panels with flexible open behavior.
215
217
  | `collapsible` | boolean | `true` | Collapse behaviour propagated to child panels |
216
218
  | `gap` | string | (unset) | Explicit gap between panels; sets `--group-gap` when provided |
217
219
  | `orientation` | `'horizontal'` \| `'vertical'` | `'horizontal'` | Layout direction of the group |
220
+ | `sticky-headers` | boolean (`"false"` disables) | `true` | Pin each panel's titlebar to the scroll area edge (top, or left for vertical titlebars) |
218
221
  | `toggle-interaction` | `'implicit'` \| `'explicit'` \| `'disabled'` | `'implicit'` | Toggle behavior applied to all child panels |
219
222
  | `variant` | `'titlebar'` \| `'midline'` \| `'tree'` | `'titlebar'` | Visual style applied to all child panels |
220
223
 
@@ -255,6 +258,12 @@ By default, multiple panels can be open at the same time. Add `accordion` to res
255
258
  </ixfx-panel-group>
256
259
  ```
257
260
 
261
+ ### Sticky headers
262
+
263
+ Panels in a group keep their titlebar pinned to the nearest scrolling ancestor while the panel is in view, so you don't lose track of which panel you're in. The titlebar stops sticking when the panel ends. Horizontal titlebars stick to the top, vertical titlebars to the left. Disable with `sticky-headers="false"`. A standalone `ixfx-panel` can opt in with `sticky-header`.
264
+
265
+ Sticking activates `overflow: clip` on the panel instead of `overflow: hidden`.
266
+
258
267
  ### Reordering
259
268
 
260
269
  Set `allow-reorder` to let users rearrange panels by dragging their titlebars (pointer-only in v1; keyboard reorder is not included):
@@ -294,6 +303,18 @@ ixfx-panel-group {
294
303
 
295
304
  Alternatively set the `gap` property/attribute for the same effect (it mirrors its value into `--group-gap`).
296
305
 
306
+ ### Content area styling
307
+
308
+ Inherited custom properties, so setting them on a group styles all its panels. To remove the inset effect or use your own:
309
+
310
+ ```css
311
+ ixfx-panel-group {
312
+ --panel-content-shadow: none;
313
+ --panel-content-border: 1px solid var(--surface-4);
314
+ }
315
+ ```
316
+
317
+
297
318
  ### Group-propagated properties
298
319
 
299
320
  When you set `variant`, `toggle-interaction` or `collapsible` on the group, those values are automatically applied to all child panels that don't have an explicit value set. This simplifies declaration when all panels in a group share the same styling:
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ixfx/components",
3
3
  "type": "module",
4
- "version": "0.15.1",
4
+ "version": "0.15.3",
5
5
  "packageManager": "pnpm@10.0.0",
6
6
  "description": "Web components for ixfx — Lit-based UI toolkit",
7
7
  "author": "Clint Heyer",