elements-kit 0.27.10 → 0.27.12

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.
@@ -7,6 +7,10 @@ type Axis = keyof ReadonlyBox;
7
7
  interface IDirection {
8
8
  readonly direction: "ltr" | "rtl";
9
9
  }
10
+ interface Point {
11
+ x: number;
12
+ y: number;
13
+ }
10
14
  interface ReadonlyBox {
11
15
  readonly x: number;
12
16
  readonly y: number;
@@ -27,6 +31,27 @@ declare class WindowBox implements ReadonlyBox, IDirection {
27
31
  get direction(): Direction;
28
32
  }
29
33
  declare const WINDOW_BOX: WindowBox;
34
+ /**
35
+ * A box grown by a margin per side — the offset off an anchor, as CSS spells
36
+ * it. The sides default like the `margin` shorthand: one value is every side,
37
+ * two is block then inline, three is top/inline/bottom.
38
+ *
39
+ * Every field is assignable and reactive, and each also takes a signal — so
40
+ * the box or a side can be swapped, or driven. Reads through, so it tracks
41
+ * whatever the wrapped box tracks.
42
+ */
43
+ declare class MarginBox implements ReadonlyBox {
44
+ box: MaybeReactive<ReadonlyBox>;
45
+ top: MaybeReactive<number>;
46
+ right: MaybeReactive<number>;
47
+ bottom: MaybeReactive<number>;
48
+ left: MaybeReactive<number>;
49
+ constructor(box: MaybeReactive<ReadonlyBox>, top?: MaybeReactive<number>, right?: MaybeReactive<number>, bottom?: MaybeReactive<number>, left?: MaybeReactive<number>);
50
+ get x(): number;
51
+ get y(): number;
52
+ get w(): number;
53
+ get h(): number;
54
+ }
30
55
  declare class ElementBox implements ReadonlyBox {
31
56
  #private;
32
57
  constructor(el: MaybeReactive<Element>);
@@ -78,28 +103,31 @@ type NoInline = {
78
103
  * both edges of one axis.
79
104
  */
80
105
  type Boundary = (BlockEdge & InlineEdge) | (BlockEdge & NoInline) | (NoBlock & InlineEdge);
81
- /** Where {@link Region.place} puts a box's top-left corner. */
82
- interface Placement {
83
- readonly x: number;
84
- readonly y: number;
106
+ /** Horizontal origin keyword, as CSS spells it. */
107
+ type OriginX = "left" | "center" | "right";
108
+ /** The vertical one. */
109
+ type OriginY = "top" | "center" | "bottom";
110
+ /** Which point of a box lands on its position. A `transform-origin`. */
111
+ interface Origin {
112
+ readonly x: OriginX;
113
+ readonly y: OriginY;
114
+ }
115
+ /** Has an origin. */
116
+ interface IOrigin {
117
+ readonly origin: Origin;
85
118
  }
86
119
  /**
87
- * Somewhere a box may go: a semi-bounded plane, each axis pinned or free.
88
- * `place` is the only operation: it never writes, so the caller picks which
89
- * channels to take `box.x = region.place(box).x` moves one axis and leaves
90
- * the rest. Size is never returned: the box is placed as given, so one larger
91
- * than its room overflows rather than shrinks, as CSS does.
120
+ * Somewhere a box may go: each axis pinned or free. `place` never writes, so
121
+ * the caller takes the channels it wants, and never returns a size, so a box
122
+ * larger than its room overflows rather than shrinks, as CSS does.
92
123
  *
93
- * The four insets read back as CSS would want them: the pinned edge's
94
- * coordinate, `null` for the other three (`auto`). A centred axis is not an
95
- * inset — both its edges are `null`.
124
+ * `x`/`y` are the pin lines, `origin` the box point landing on them the
125
+ * pair places a box without measuring it. A free axis has no pin (`null`).
96
126
  */
97
- interface Region {
98
- readonly left: number | null;
99
- readonly right: number | null;
100
- readonly top: number | null;
101
- readonly bottom: number | null;
102
- place(box: ReadonlyBox): Placement;
127
+ interface Region extends IOrigin {
128
+ readonly x: number | null;
129
+ readonly y: number | null;
130
+ place(box: ReadonlyBox): Point;
103
131
  }
104
132
  /**
105
133
  * A {@link Region} driven by writes — for gestures, where the box grows away
@@ -109,6 +137,11 @@ interface Region {
109
137
  declare class MutableRegion implements Region {
110
138
  #private;
111
139
  constructor(boundary: Boundary);
140
+ /** The pin line on each axis — `null` where the axis is free. */
141
+ get x(): number | null;
142
+ get y(): number | null;
143
+ /** The box point that lands on ({@link x}, {@link y}). */
144
+ get origin(): Origin;
112
145
  get left(): number | null;
113
146
  get right(): number | null;
114
147
  get top(): number | null;
@@ -117,7 +150,7 @@ declare class MutableRegion implements Region {
117
150
  set right(v: number | null);
118
151
  set top(v: number | null);
119
152
  set bottom(v: number | null);
120
- place(box: ReadonlyBox): Placement;
153
+ place(box: ReadonlyBox): Point;
121
154
  }
122
155
  //#endregion
123
156
  //#region src/ui/overlay/anchor.d.ts
@@ -162,39 +195,29 @@ type Unordered<A extends string, B extends string> = `${A} ${B}` | `${B} ${A}`;
162
195
  */
163
196
  type PositionAreaValue = AreaKeyword | Unordered<BlockKeyword, InlineKeyword> | Unordered<BlockKeyword, AmbiguousKeyword> | Unordered<InlineKeyword, AmbiguousKeyword> | `${AmbiguousKeyword} ${AmbiguousKeyword}`;
164
197
  /**
165
- * The reactive `position-area` property: the region of the viewport an
166
- * overlay anchored to `anchor` may occupy, with the region's default
167
- * self-alignment as {@link Region.place} outward regions hug the anchor,
168
- * spans go flush against its far edge, center is `anchor-center`. Nothing is
169
- * written; the caller takes what it wants from `place`:
198
+ * The reactive `position-area` property: which of the anchor's edges a box
199
+ * pins to, and the self-alignment that follows outward regions hug the
200
+ * anchor's near edge, spans its far edge, center is `anchor-center`. Not a
201
+ * box: a pin per axis, with no geometry of its own.
170
202
  *
171
- * const area = new PositionArea(a, "top span-left");
172
- * effect(() => { overlay.x = area.place(overlay).x; });
203
+ * Parsed once, at construction; the pins read the anchor on every access, so
204
+ * reading them in an `effect` tracks it.
173
205
  *
174
- * The value is parsed once, at construction; the geometry reads the anchor
175
- * and window on every access, so reading it inside an `effect` tracks both.
176
- *
177
- * Bounded by the window. A tighter bound (a `Constraint`, a scroll container)
178
- * is an intersection with the region, so it composes afterwards rather than
179
- * being a parameter here.
180
- *
181
- * There is no gap parameter, for the same reason CSS has none: the offset off
182
- * the anchor is the overlay's own `margin`.
206
+ * No gap parameter, for the same reason CSS has none: the offset off the
207
+ * anchor is the overlay's own `margin`.
183
208
  */
184
- declare class PositionArea implements Region, ReadonlyBox {
209
+ declare class PositionArea implements Region {
185
210
  #private;
186
211
  readonly anchor: ReadonlyBox;
187
212
  constructor(anchor: ReadonlyBox, area: PositionAreaValue);
213
+ /** The pin lines — the viewport point {@link origin} lands on. */
188
214
  get x(): number;
189
215
  get y(): number;
190
- get w(): number;
191
- get h(): number;
192
- get left(): number | null;
193
- get right(): number | null;
194
- get top(): number | null;
195
- get bottom(): number | null;
216
+ /** The box point landing on ({@link x}, {@link y}). Two axes, not one
217
+ * side: a corner area pins a corner. */
218
+ get origin(): Origin;
196
219
  /** Every axis is pinned, so only the box's size is read. */
197
- place(box: Pick<ReadonlyBox, "w" | "h">): Placement;
220
+ place(box: Pick<ReadonlyBox, "w" | "h">): Point;
198
221
  }
199
222
  //#endregion
200
223
  //#region src/ui/overlay/overlay.d.ts
@@ -224,10 +247,16 @@ declare class Displacement extends PartialBox {
224
247
  apply(): void;
225
248
  clear(): void;
226
249
  }
227
- declare class OverlayBox extends TransformableBox implements IDirection {
250
+ declare class OverlayBox extends TransformableBox implements IDirection, IOrigin {
228
251
  #private;
229
252
  readonly element: HTMLElement;
230
253
  constructor(element: HTMLElement);
254
+ /** The box point that lands on (x, y), and the scale's origin. */
255
+ get origin(): Origin;
256
+ set origin({
257
+ x,
258
+ y
259
+ }: Origin);
231
260
  get w(): number;
232
261
  set w(value: number);
233
262
  get h(): number;
@@ -283,4 +312,4 @@ declare class Motion implements IMotion {
283
312
  abort(initial?: number): void;
284
313
  }
285
314
  //#endregion
286
- export { type Align, type Axis, type BlockSide, type Boundary, ElementBox, gestures_d_exports as Gestures, type IDirection, type IMotion, type InlineSide, type Inset, Motion, MutableRegion, OverlayBox, type PhysicalInset, type Pin, type Placement, PositionArea, type PositionAreaValue, type ReadonlyBox, type Region, WINDOW_BOX, WindowBox, anchor_length };
315
+ export { type Align, type Axis, type BlockSide, type Boundary, ElementBox, gestures_d_exports as Gestures, type IDirection, type IMotion, type IOrigin, type InlineSide, type Inset, MarginBox, Motion, MutableRegion, type Origin, type OriginX, type OriginY, OverlayBox, type PhysicalInset, type Pin, PositionArea, type PositionAreaValue, type ReadonlyBox, type Region, WINDOW_BOX, WindowBox, anchor_length };
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "../../chunk-CfYAbeIz.mjs";
2
2
  import { c as batch, u as effect, x as signal } from "../../lib-Dw0g-vex.mjs";
3
- import { reactive } from "../../signals/index.mjs";
3
+ import { reactive, resolve } from "../../signals/index.mjs";
4
4
  import { t as scope } from "../../scope-B1kDu4YX.mjs";
5
5
  import { direction } from "../../utilities/direction.mjs";
6
6
  import { createElementRect } from "../../utilities/element-rect.mjs";
@@ -12,10 +12,20 @@ function placePinned(pin, n) {
12
12
  if (pin.align === "end") return pin.at - n;
13
13
  return pin.at - n / 2;
14
14
  }
15
- /** One axis of a {@link Region.place}: pinned, or `own` if the axis is free. */
15
+ /** One axis of {@link Region.place}: pinned, or `own` if free. */
16
16
  function placeAxis(pin, own, n) {
17
17
  return pin ? placePinned(pin, n) : own;
18
18
  }
19
+ /** The box point a pin lands. Physical: direction is resolved before a pin
20
+ * exists, so `left` is left in RTL. A free axis lands the near edge. */
21
+ function originX(pin) {
22
+ if (!pin) return "left";
23
+ return pin.align === "start" ? "left" : pin.align === "end" ? "right" : "center";
24
+ }
25
+ function originY(pin) {
26
+ if (!pin) return "top";
27
+ return pin.align === "start" ? "top" : pin.align === "end" ? "bottom" : "center";
28
+ }
19
29
  /** The inset a pin yields on one edge: its coordinate if it pins that edge. */
20
30
  function inset(pin, edge) {
21
31
  return pin?.align === edge ? pin.at : null;
@@ -35,6 +45,20 @@ var MutableRegion = class {
35
45
  if (top !== void 0) this.top = top;
36
46
  if (bottom !== void 0) this.bottom = bottom;
37
47
  }
48
+ /** The pin line on each axis — `null` where the axis is free. */
49
+ get x() {
50
+ return this.#x()?.at ?? null;
51
+ }
52
+ get y() {
53
+ return this.#y()?.at ?? null;
54
+ }
55
+ /** The box point that lands on ({@link x}, {@link y}). */
56
+ get origin() {
57
+ return {
58
+ x: originX(this.#x()),
59
+ y: originY(this.#y())
60
+ };
61
+ }
38
62
  get left() {
39
63
  return inset(this.#x(), "start");
40
64
  }
@@ -79,47 +103,6 @@ var MutableRegion = class {
79
103
  }
80
104
  };
81
105
  //#endregion
82
- //#region src/ui/overlay/box.ts
83
- var WindowBox = class {
84
- get x() {
85
- return 0;
86
- }
87
- get y() {
88
- return 0;
89
- }
90
- get w() {
91
- return windowSize.width();
92
- }
93
- get h() {
94
- return windowSize.height();
95
- }
96
- get direction() {
97
- return direction();
98
- }
99
- };
100
- const WINDOW_BOX = new WindowBox();
101
- var ElementBox = class {
102
- #rect;
103
- constructor(el) {
104
- this.#rect = createElementRect(el);
105
- }
106
- [Symbol.dispose]() {
107
- this.#rect[Symbol.dispose]();
108
- }
109
- get x() {
110
- return this.#rect().left;
111
- }
112
- get y() {
113
- return this.#rect().top;
114
- }
115
- get w() {
116
- return this.#rect().width;
117
- }
118
- get h() {
119
- return this.#rect().height;
120
- }
121
- };
122
- //#endregion
123
106
  //#region src/ui/overlay/anchor.ts
124
107
  /**
125
108
  * The reactive `anchor()` function: the viewport coordinate of an anchor line
@@ -280,37 +263,17 @@ function resolveArea(area, dir = "ltr", selfDir = dir) {
280
263
  inline: inline ? toPhysical(inline, "inline", dir, selfDir) : "center"
281
264
  };
282
265
  }
283
- /** One axis of the position-area containing block, as `[lo, hi]` viewport
284
- * coordinates. The anchor's two edges cut `[bLo, bHi]` into before/over/after. */
285
- function axisSpan(lo, hi, bLo, bHi, region) {
286
- switch (region) {
287
- case "start": return [bLo, lo];
288
- case "end": return [hi, bHi];
289
- case "center": return [lo, hi];
290
- case "span-start": return [bLo, hi];
291
- case "span-end": return [lo, bHi];
292
- default: return [bLo, bHi];
293
- }
294
- }
295
266
  /**
296
- * The reactive `position-area` property: the region of the viewport an
297
- * overlay anchored to `anchor` may occupy, with the region's default
298
- * self-alignment as {@link Region.place} outward regions hug the anchor,
299
- * spans go flush against its far edge, center is `anchor-center`. Nothing is
300
- * written; the caller takes what it wants from `place`:
301
- *
302
- * const area = new PositionArea(a, "top span-left");
303
- * effect(() => { overlay.x = area.place(overlay).x; });
304
- *
305
- * The value is parsed once, at construction; the geometry reads the anchor
306
- * and window on every access, so reading it inside an `effect` tracks both.
267
+ * The reactive `position-area` property: which of the anchor's edges a box
268
+ * pins to, and the self-alignment that follows outward regions hug the
269
+ * anchor's near edge, spans its far edge, center is `anchor-center`. Not a
270
+ * box: a pin per axis, with no geometry of its own.
307
271
  *
308
- * Bounded by the window. A tighter bound (a `Constraint`, a scroll container)
309
- * is an intersection with the region, so it composes afterwards rather than
310
- * being a parameter here.
272
+ * Parsed once, at construction; the pins read the anchor on every access, so
273
+ * reading them in an `effect` tracks it.
311
274
  *
312
- * There is no gap parameter, for the same reason CSS has none: the offset off
313
- * the anchor is the overlay's own `margin`.
275
+ * No gap parameter, for the same reason CSS has none: the offset off the
276
+ * anchor is the overlay's own `margin`.
314
277
  */
315
278
  var PositionArea = class {
316
279
  anchor;
@@ -319,18 +282,6 @@ var PositionArea = class {
319
282
  this.anchor = anchor;
320
283
  this.#area = resolveArea(area, rootDirection());
321
284
  }
322
- /** The inline axis as `[lo, hi]`, re-read from the anchor and window. */
323
- get #ix() {
324
- const a = this.anchor;
325
- const w = WINDOW_BOX;
326
- return axisSpan(a.x, a.x + a.w, w.x, w.x + w.w, this.#area.inline);
327
- }
328
- /** The block axis as `[lo, hi]`. */
329
- get #iy() {
330
- const a = this.anchor;
331
- const w = WINDOW_BOX;
332
- return axisSpan(a.y, a.y + a.h, w.y, w.y + w.h, this.#area.block);
333
- }
334
285
  get #px() {
335
286
  const a = this.anchor;
336
287
  return pinOf(this.#area.inline, a.x, a.x + a.w);
@@ -339,31 +290,20 @@ var PositionArea = class {
339
290
  const a = this.anchor;
340
291
  return pinOf(this.#area.block, a.y, a.y + a.h);
341
292
  }
293
+ /** The pin lines — the viewport point {@link origin} lands on. */
342
294
  get x() {
343
- return this.#ix[0];
295
+ return this.#px.at;
344
296
  }
345
297
  get y() {
346
- return this.#iy[0];
347
- }
348
- get w() {
349
- const [lo, hi] = this.#ix;
350
- return hi - lo;
351
- }
352
- get h() {
353
- const [lo, hi] = this.#iy;
354
- return hi - lo;
355
- }
356
- get left() {
357
- return inset(this.#px, "start");
358
- }
359
- get right() {
360
- return inset(this.#px, "end");
361
- }
362
- get top() {
363
- return inset(this.#py, "start");
298
+ return this.#py.at;
364
299
  }
365
- get bottom() {
366
- return inset(this.#py, "end");
300
+ /** The box point landing on ({@link x}, {@link y}). Two axes, not one
301
+ * side: a corner area pins a corner. */
302
+ get origin() {
303
+ return {
304
+ x: originX(this.#px),
305
+ y: originY(this.#py)
306
+ };
367
307
  }
368
308
  /** Every axis is pinned, so only the box's size is read. */
369
309
  place(box) {
@@ -401,6 +341,164 @@ function pinOf(region, lo, hi) {
401
341
  }
402
342
  }
403
343
  //#endregion
344
+ //#region src/ui/overlay/box.ts
345
+ var __create$1 = Object.create;
346
+ var __defProp$1 = Object.defineProperty;
347
+ var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
348
+ var __knownSymbol$1 = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
349
+ var __typeError$1 = (msg) => {
350
+ throw TypeError(msg);
351
+ };
352
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
353
+ enumerable: true,
354
+ configurable: true,
355
+ writable: true,
356
+ value
357
+ }) : obj[key] = value;
358
+ var __name$1 = (target, value) => __defProp$1(target, "name", {
359
+ value,
360
+ configurable: true
361
+ });
362
+ var __decoratorStart$1 = (base) => [
363
+ ,
364
+ ,
365
+ ,
366
+ __create$1(base?.[__knownSymbol$1("metadata")] ?? null)
367
+ ];
368
+ var __decoratorStrings$1 = [
369
+ "class",
370
+ "method",
371
+ "getter",
372
+ "setter",
373
+ "accessor",
374
+ "field",
375
+ "value",
376
+ "get",
377
+ "set"
378
+ ];
379
+ var __expectFn$1 = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError$1("Function expected") : fn;
380
+ var __decoratorContext$1 = (kind, name, done, metadata, fns) => ({
381
+ kind: __decoratorStrings$1[kind],
382
+ name,
383
+ metadata,
384
+ addInitializer: (fn) => done._ ? __typeError$1("Already initialized") : fns.push(__expectFn$1(fn || null))
385
+ });
386
+ var __decoratorMetadata$1 = (array, target) => __defNormalProp$1(target, __knownSymbol$1("metadata"), array[3]);
387
+ var __runInitializers$1 = (array, flags, self, value) => {
388
+ for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
389
+ return value;
390
+ };
391
+ var __decorateElement$1 = (array, flags, name, decorators, target, extra) => {
392
+ var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
393
+ var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings$1[k + 5];
394
+ var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
395
+ var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc$1(k < 4 ? target : {
396
+ get [name]() {
397
+ return __privateGet$1(this, extra);
398
+ },
399
+ set [name](x) {
400
+ return __privateSet$1(this, extra, x);
401
+ }
402
+ }, name));
403
+ k ? p && k < 4 && __name$1(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name$1(target, name);
404
+ for (var i = decorators.length - 1; i >= 0; i--) {
405
+ ctx = __decoratorContext$1(k, name, done = {}, array[3], extraInitializers);
406
+ if (k) {
407
+ ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn$1(target, x) : (x) => name in x };
408
+ if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet$1 : __privateMethod$1)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
409
+ if (k > 2) access.set = p ? (x, y) => __privateSet$1(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
410
+ }
411
+ it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : {
412
+ get: desc.get,
413
+ set: desc.set
414
+ } : target, ctx), done._ = 1;
415
+ if (k ^ 4 || it === void 0) __expectFn$1(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
416
+ else if (typeof it !== "object" || it === null) __typeError$1("Object expected");
417
+ else __expectFn$1(fn = it.get) && (desc.get = fn), __expectFn$1(fn = it.set) && (desc.set = fn), __expectFn$1(fn = it.init) && initializers.unshift(fn);
418
+ }
419
+ return k || __decoratorMetadata$1(array, target), desc && __defProp$1(target, name, desc), p ? k ^ 4 ? extra : desc : target;
420
+ };
421
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
422
+ var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
423
+ var __privateIn$1 = (member, obj) => Object(obj) !== obj ? __typeError$1("Cannot use the \"in\" operator on this value") : member.has(obj);
424
+ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
425
+ var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
426
+ var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
427
+ var _left_dec, _bottom_dec, _right_dec, _top_dec, _box_dec, _init$1;
428
+ var WindowBox = class {
429
+ get x() {
430
+ return 0;
431
+ }
432
+ get y() {
433
+ return 0;
434
+ }
435
+ get w() {
436
+ return windowSize.width();
437
+ }
438
+ get h() {
439
+ return windowSize.height();
440
+ }
441
+ get direction() {
442
+ return direction();
443
+ }
444
+ };
445
+ const WINDOW_BOX = new WindowBox();
446
+ _box_dec = [reactive()], _top_dec = [reactive()], _right_dec = [reactive()], _bottom_dec = [reactive()], _left_dec = [reactive()];
447
+ var MarginBox = class {
448
+ constructor(box, top = 0, right = top, bottom = top, left = right) {
449
+ __publicField$1(this, "box", __runInitializers$1(_init$1, 8, this)), __runInitializers$1(_init$1, 11, this);
450
+ __publicField$1(this, "top", __runInitializers$1(_init$1, 12, this)), __runInitializers$1(_init$1, 15, this);
451
+ __publicField$1(this, "right", __runInitializers$1(_init$1, 16, this)), __runInitializers$1(_init$1, 19, this);
452
+ __publicField$1(this, "bottom", __runInitializers$1(_init$1, 20, this)), __runInitializers$1(_init$1, 23, this);
453
+ __publicField$1(this, "left", __runInitializers$1(_init$1, 24, this)), __runInitializers$1(_init$1, 27, this);
454
+ this.box = box;
455
+ this.top = top;
456
+ this.right = right;
457
+ this.bottom = bottom;
458
+ this.left = left;
459
+ }
460
+ get x() {
461
+ return resolve(this.box).x - resolve(this.left);
462
+ }
463
+ get y() {
464
+ return resolve(this.box).y - resolve(this.top);
465
+ }
466
+ get w() {
467
+ return resolve(this.box).w + resolve(this.left) + resolve(this.right);
468
+ }
469
+ get h() {
470
+ return resolve(this.box).h + resolve(this.top) + resolve(this.bottom);
471
+ }
472
+ };
473
+ _init$1 = __decoratorStart$1(null);
474
+ __decorateElement$1(_init$1, 5, "box", _box_dec, MarginBox);
475
+ __decorateElement$1(_init$1, 5, "top", _top_dec, MarginBox);
476
+ __decorateElement$1(_init$1, 5, "right", _right_dec, MarginBox);
477
+ __decorateElement$1(_init$1, 5, "bottom", _bottom_dec, MarginBox);
478
+ __decorateElement$1(_init$1, 5, "left", _left_dec, MarginBox);
479
+ __decoratorMetadata$1(_init$1, MarginBox);
480
+ var ElementBox = class {
481
+ #rect;
482
+ constructor(el) {
483
+ this.#rect = createElementRect(el);
484
+ }
485
+ [Symbol.dispose]() {
486
+ this.#rect[Symbol.dispose]();
487
+ }
488
+ get x() {
489
+ return this.#rect().left;
490
+ }
491
+ get y() {
492
+ return this.#rect().top;
493
+ }
494
+ get w() {
495
+ return this.#rect().width;
496
+ }
497
+ get h() {
498
+ return this.#rect().height;
499
+ }
500
+ };
501
+ //#endregion
404
502
  //#region src/ui/overlay/overlay.ts
405
503
  var __create = Object.create;
406
504
  var __defProp = Object.defineProperty;
@@ -560,16 +658,27 @@ var Displacement = class extends PartialBox {
560
658
  });
561
659
  }
562
660
  };
661
+ const OFFSET = {
662
+ left: "0%",
663
+ top: "0%",
664
+ center: "50%",
665
+ right: "100%",
666
+ bottom: "100%"
667
+ };
563
668
  var OverlayBox = class extends TransformableBox {
564
669
  element;
565
670
  #rect;
671
+ #origin = {
672
+ x: "left",
673
+ y: "top"
674
+ };
566
675
  constructor(element) {
567
676
  super();
568
677
  this.element = element;
569
678
  this.#rect = createElementRect(element);
570
679
  element.style.setProperty("top", "0");
571
680
  element.style.setProperty("left", "0");
572
- element.style.setProperty("translate", "calc(var(--x, 0px) + var(--dx, 0px) + var(--_ex, 0px)) calc(var(--y, 0px) + var(--dy, 0px) + var(--_ey, 0px))");
681
+ element.style.setProperty("translate", "calc(var(--x, 0px) + var(--dx, 0px) + var(--_ex, 0px) - var(--_ox, 0%)) calc(var(--y, 0px) + var(--dy, 0px) + var(--_ey, 0px) - var(--_oy, 0%))");
573
682
  const [, stop] = scope(() => {
574
683
  effect(() => {
575
684
  this.#project("--x", this.transform.x);
@@ -595,6 +704,19 @@ var OverlayBox = class extends TransformableBox {
595
704
  this.#rect[Symbol.dispose]();
596
705
  };
597
706
  }
707
+ /** The box point that lands on (x, y), and the scale's origin. */
708
+ get origin() {
709
+ return this.#origin;
710
+ }
711
+ set origin({ x, y }) {
712
+ this.#origin = {
713
+ x,
714
+ y
715
+ };
716
+ this.element.style.setProperty("--_ox", OFFSET[x]);
717
+ this.element.style.setProperty("--_oy", OFFSET[y]);
718
+ this.element.style.transformOrigin = `${x} ${y}`;
719
+ }
598
720
  /** Write a size channel, or unset it when the axis is AUTO (NaN) so the
599
721
  * element falls back to content sizing (`var(--w, auto)`). */
600
722
  #project(name, ...value) {
@@ -721,4 +843,4 @@ var Motion = class {
721
843
  }
722
844
  };
723
845
  //#endregion
724
- export { ElementBox, gestures_exports as Gestures, Motion, MutableRegion, OverlayBox, PositionArea, WINDOW_BOX, WindowBox, anchor_length };
846
+ export { ElementBox, gestures_exports as Gestures, MarginBox, Motion, MutableRegion, OverlayBox, PositionArea, WINDOW_BOX, WindowBox, anchor_length };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "elements-kit",
3
3
  "type": "module",
4
- "version": "0.27.10",
4
+ "version": "0.27.12",
5
5
  "description": "A lightweight reactive UI library that transforms native HTMLElements into reactive components with signals. Ideal for framework-agnostic applications and web components.",
6
6
  "keywords": [
7
7
  "webcomponents",