fiboui 2.8.5 → 2.9.1

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/core.d.ts CHANGED
@@ -473,7 +473,27 @@ declare const FIBO_BREAKPOINTS: {
473
473
  readonly xl: 1280;
474
474
  };
475
475
  type BreakpointKey = keyof typeof FIBO_BREAKPOINTS;
476
+ type GestureMask = "all" | "gesture" | "subviews" | "none";
477
+ type TapLocation = {
478
+ x: number;
479
+ y: number;
480
+ };
476
481
  declare abstract class GestureBuilder {
482
+ protected _enabled: boolean;
483
+ protected _including: GestureMask;
484
+ /** When true, wrappers must not stopPropagation (simultaneous). */
485
+ protected _bubble: boolean;
486
+ /** @internal Fired when the gesture successfully recognizes (Sequence / Exclusive). */
487
+ protected _onRecognized?: () => void;
488
+ enabled(value?: boolean): this;
489
+ /** SwiftUI `gesture(_:including:)`. */
490
+ including(mask: GestureMask): this;
491
+ /** Internal — set by SimultaneousGesture / `.simultaneousGesture`. */
492
+ bubble(value?: boolean): this;
493
+ /** @internal Used by SequenceGesture / ExclusiveGesture. */
494
+ onRecognized(callback: () => void): this;
495
+ /** @internal */
496
+ protected notifyRecognized(): void;
477
497
  abstract wrap(children: React$1.ReactNode): React$1.ReactNode;
478
498
  }
479
499
  /**
@@ -704,6 +724,144 @@ declare const When: {
704
724
  };
705
725
  type When = (typeof When)[keyof typeof When];
706
726
  type WhenStyle = React$1.CSSProperties | string | ((builder: any) => void);
727
+ declare const Size: {
728
+ readonly full: "full";
729
+ readonly screen: "screen";
730
+ readonly fit: "fit";
731
+ readonly min: "min";
732
+ readonly max: "max";
733
+ /** SwiftUI `.infinity` — expand to the space the parent proposes (`100%`). */
734
+ readonly infinity: "infinity";
735
+ };
736
+ type Size = (typeof Size)[keyof typeof Size];
737
+ declare const StackAlign: {
738
+ readonly center: "center";
739
+ readonly top: "top";
740
+ readonly bottom: "bottom";
741
+ readonly left: "left";
742
+ readonly right: "right";
743
+ readonly topLeft: "topLeft";
744
+ readonly topRight: "topRight";
745
+ readonly bottomLeft: "bottomLeft";
746
+ readonly bottomRight: "bottomRight";
747
+ /** SwiftUI `leading` → `left` */
748
+ readonly leading: "left";
749
+ /** SwiftUI `trailing` → `right` */
750
+ readonly trailing: "right";
751
+ /** SwiftUI `topLeading` → `topLeft` */
752
+ readonly topLeading: "topLeft";
753
+ /** SwiftUI `topTrailing` → `topRight` */
754
+ readonly topTrailing: "topRight";
755
+ /** SwiftUI `bottomLeading` → `bottomLeft` */
756
+ readonly bottomLeading: "bottomLeft";
757
+ /** SwiftUI `bottomTrailing` → `bottomRight` */
758
+ readonly bottomTrailing: "bottomRight";
759
+ };
760
+ type StackAlign = (typeof StackAlign)[keyof typeof StackAlign];
761
+ type FrameSize = number | string | Size;
762
+ interface FrameSpec {
763
+ width?: FrameSize;
764
+ height?: FrameSize;
765
+ minWidth?: FrameSize;
766
+ idealWidth?: FrameSize;
767
+ maxWidth?: FrameSize;
768
+ minHeight?: FrameSize;
769
+ idealHeight?: FrameSize;
770
+ maxHeight?: FrameSize;
771
+ alignment?: StackAlign | keyof typeof StackAlign;
772
+ }
773
+ type ClipShapeName = "circle" | "rounded" | "square";
774
+ interface OffsetSpec {
775
+ x?: number;
776
+ y?: number;
777
+ }
778
+ interface FixedSizeSpec {
779
+ horizontal?: boolean;
780
+ vertical?: boolean;
781
+ }
782
+ interface LayerSpec {
783
+ kind: "overlay" | "background";
784
+ child: FiboChild | (() => FiboChild);
785
+ alignment: StackAlign | keyof typeof StackAlign;
786
+ }
787
+ type ContentShapeName = "rectangle" | ClipShapeName;
788
+ type GeometryRect = {
789
+ x: number;
790
+ y: number;
791
+ width: number;
792
+ height: number;
793
+ };
794
+ type ContainerRelativeFrameSpec = {
795
+ axis?: "horizontal" | "vertical" | "both";
796
+ /** Divisions of the container (SwiftUI `count`). Default 1. */
797
+ count?: number;
798
+ /** Spans claimed (SwiftUI `span`). Default 1. */
799
+ span?: number;
800
+ };
801
+ type AlignmentGuideName = "leading" | "trailing" | "top" | "bottom" | "centerX" | "centerY" | string;
802
+ type AlignmentGuideDims = {
803
+ width: number;
804
+ height: number;
805
+ };
806
+ type AlignmentGuideSpec = {
807
+ guide: AlignmentGuideName;
808
+ /** Absolute guide position, or compute from own size (SwiftUI `ViewDimensions`). */
809
+ compute: number | ((dims: AlignmentGuideDims) => number);
810
+ };
811
+ type MatchedGeometrySpec = {
812
+ id: string;
813
+ namespace?: string;
814
+ /** SwiftUI `isSource` — source owns the shared geometry. Default true. */
815
+ isSource?: boolean;
816
+ };
817
+ type PreferenceKeyDef<T> = {
818
+ readonly __preferenceKey: true;
819
+ readonly id: string | symbol;
820
+ readonly defaultValue: T;
821
+ reduce: (value: T, nextValue: T) => T;
822
+ };
823
+ type PreferenceWriteSpec = {
824
+ key: PreferenceKeyDef<any>;
825
+ value: unknown;
826
+ };
827
+ type PreferenceReadSpec = {
828
+ key: PreferenceKeyDef<any>;
829
+ onChange: (value: any) => void;
830
+ };
831
+ declare const Edge: {
832
+ readonly top: "top";
833
+ readonly bottom: "bottom";
834
+ readonly leading: "leading";
835
+ readonly trailing: "trailing";
836
+ };
837
+ type Edge = (typeof Edge)[keyof typeof Edge];
838
+ declare const EdgeSet: {
839
+ readonly top: "top";
840
+ readonly bottom: "bottom";
841
+ readonly leading: "leading";
842
+ readonly trailing: "trailing";
843
+ readonly horizontal: "horizontal";
844
+ readonly vertical: "vertical";
845
+ readonly all: "all";
846
+ };
847
+ type EdgeSet = (typeof EdgeSet)[keyof typeof EdgeSet];
848
+ type EdgeInsetsValue = {
849
+ top?: number | string;
850
+ bottom?: number | string;
851
+ leading?: number | string;
852
+ trailing?: number | string;
853
+ /** CSS left — alias of leading in LTR */
854
+ left?: number | string;
855
+ /** CSS right — alias of trailing in LTR */
856
+ right?: number | string;
857
+ };
858
+ type SafeAreaInsetEdge = Edge | "top" | "bottom" | "leading" | "trailing" | "left" | "right";
859
+ type SafeAreaInsetSpec = {
860
+ edge: SafeAreaInsetEdge;
861
+ content: FiboChild | (() => FiboChild);
862
+ /** Gap between inset bar and content. Default 0. */
863
+ spacing?: number;
864
+ };
707
865
  export interface SpringOptions {
708
866
  stiffness?: number;
709
867
  damping?: number;
@@ -895,7 +1053,29 @@ declare abstract class FiboBuilder {
895
1053
  /** @internal Direct `method(signal.value)` calls replayed when that signal changes. */
896
1054
  protected _replays: Array<() => void>;
897
1055
  protected _isObserver: boolean;
898
- protected _gesture?: GestureBuilder;
1056
+ /** Normal-priority gestures (SwiftUI `.gesture`). Last = outermost. */
1057
+ protected _gestures: GestureBuilder[];
1058
+ /** SwiftUI `.simultaneousGesture` — bubble / no stopPropagation. */
1059
+ protected _simultaneousGestures: GestureBuilder[];
1060
+ /** SwiftUI `.highPriorityGesture` — wrapped last (outermost / capture wins). */
1061
+ protected _highPriorityGestures: GestureBuilder[];
1062
+ protected _offset?: OffsetSpec;
1063
+ protected _clipped: boolean;
1064
+ protected _clipShape?: ClipShapeName | string;
1065
+ protected _contentShape?: ContentShapeName | string;
1066
+ protected _fixedSize?: FixedSizeSpec;
1067
+ protected _layoutPriority?: number;
1068
+ protected _layers: LayerSpec[];
1069
+ protected _onGeometryChange?: (rect: GeometryRect) => void;
1070
+ protected _compositingGroup: boolean;
1071
+ protected _viewMask?: string;
1072
+ protected _containerRelativeFrame?: ContainerRelativeFrameSpec;
1073
+ protected _alignmentGuide?: AlignmentGuideSpec;
1074
+ protected _matchedGeometry?: MatchedGeometrySpec;
1075
+ protected _preferences: PreferenceWriteSpec[];
1076
+ protected _preferenceReaders: PreferenceReadSpec[];
1077
+ protected _safeAreaInsets: SafeAreaInsetSpec[];
1078
+ protected _navigationTitle?: string;
899
1079
  protected _animationConfig?: Partial<AnimationOptions>;
900
1080
  protected _animatedProps: Map<string, Signal<any>>;
901
1081
  protected _transforms: string[];
@@ -924,6 +1104,11 @@ declare abstract class FiboBuilder {
924
1104
  protected _explicitScrollMargin: boolean;
925
1105
  /** Shrink-wrap: skip the default `w-full` / `self-stretch` on Row and Column. */
926
1106
  protected _hug: boolean;
1107
+ /**
1108
+ * SwiftUI `.frame(...)` wrappers (outer → inner order of application).
1109
+ * Applied in `assembleBuilder` so every widget gets the same DX.
1110
+ */
1111
+ protected _frames: FrameSpec[];
927
1112
  /**
928
1113
  * Unset every CSS property on this component and what it renders inside.
929
1114
  * Chain `.style()`, `.px()`, `.flex()` and the rest after this to put back only what you want.
@@ -935,6 +1120,109 @@ declare abstract class FiboBuilder {
935
1120
  protected isReset(): boolean;
936
1121
  hug(): this;
937
1122
  protected isHug(): boolean;
1123
+ /**
1124
+ * SwiftUI `View.frame` — invisible box around this view.
1125
+ *
1126
+ * ```ts
1127
+ * Image(url).frame({ width: 300, height: 400 })
1128
+ * Text('★★★★').frame({
1129
+ * maxWidth: Size.infinity,
1130
+ * maxHeight: Size.infinity,
1131
+ * alignment: StackAlign.topTrailing,
1132
+ * })
1133
+ * ```
1134
+ *
1135
+ * Chainable: each `.frame()` wraps the previous (same as SwiftUI).
1136
+ */
1137
+ frame(spec: FrameSpec): this;
1138
+ /**
1139
+ * SwiftUI `.offset(x:y:)` — visual translate; layout size stays.
1140
+ * `.offset(8)` ≡ `{ x: 8, y: 8 }`; `.offset({ x: 4 })` only horizontal.
1141
+ */
1142
+ offset(value: number | OffsetSpec): this;
1143
+ /** SwiftUI `.clipped()` — overflow hidden to bounds. */
1144
+ clipped(): this;
1145
+ /**
1146
+ * SwiftUI `.clipShape` — `'circle' | 'rounded' | 'square'` or any CSS radius
1147
+ * (`'8px'`, `'50%'`). Clips drawing; hit-testing still follows layout unless
1148
+ * you also set {@link contentShape}.
1149
+ */
1150
+ clipShape(shape: ClipShapeName | string): this;
1151
+ /**
1152
+ * SwiftUI `.contentShape` — region used for hit-testing (tap / long-press).
1153
+ * Default `'rectangle'` = full frame box, even over transparent pixels.
1154
+ *
1155
+ * ```ts
1156
+ * ZStack()…frame({ width: 300, height: 400 })
1157
+ * .clipShape('8px')
1158
+ * .contentShape('rectangle')
1159
+ * .onTapGesture(open)
1160
+ * ```
1161
+ */
1162
+ contentShape(shape?: ContentShapeName | string): this;
1163
+ /**
1164
+ * SwiftUI `.fixedSize(horizontal:vertical:)` — hug content on those axes.
1165
+ * Defaults both axes when called with no args.
1166
+ */
1167
+ fixedSize(spec?: FixedSizeSpec | boolean): this;
1168
+ /**
1169
+ * SwiftUI `.layoutPriority` — higher resists compression and claims free space.
1170
+ * Web: flex-grow / flex-shrink (not a full multi-axis proposal solver).
1171
+ */
1172
+ layoutPriority(value: number): this;
1173
+ /** SwiftUI `.compositingGroup()`. */
1174
+ compositingGroup(): this;
1175
+ /** SwiftUI `.mask` — shape name or CSS mask-image value. */
1176
+ mask(shapeOrCss: ClipShapeName | "rectangle" | string): this;
1177
+ /** SwiftUI `containerRelativeFrame`. */
1178
+ containerRelativeFrame(axis?: ContainerRelativeFrameSpec["axis"] | ContainerRelativeFrameSpec, count?: number, span?: number): this;
1179
+ /**
1180
+ * SwiftUI `alignmentGuide` — named guide + absolute value or compute from size.
1181
+ * ```ts
1182
+ * Text('Hi').alignmentGuide('leading', (d) => d.width / 2)
1183
+ * ```
1184
+ */
1185
+ alignmentGuide(guide: AlignmentGuideName, compute: number | ((dims: {
1186
+ width: number;
1187
+ height: number;
1188
+ }) => number)): this;
1189
+ /**
1190
+ * SwiftUI `matchedGeometryEffect` — shared view-transition id + measured rect.
1191
+ * ```ts
1192
+ * Image(url).matchedGeometryEffect('hero', { namespace: 'gallery', isSource: true })
1193
+ * ```
1194
+ */
1195
+ matchedGeometryEffect(id: string, namespaceOrOpts?: string | {
1196
+ namespace?: string;
1197
+ isSource?: boolean;
1198
+ }): this;
1199
+ /** SwiftUI `.preference(key:value:)` — contribute upward to `.onPreferenceChange`. */
1200
+ preference<T>(key: PreferenceKeyDef<T>, value: T): this;
1201
+ /** SwiftUI `.onPreferenceChange` — reduce descendant preferences. */
1202
+ onPreferenceChange<T>(key: PreferenceKeyDef<T>, onChange: (value: T) => void): this;
1203
+ /**
1204
+ * SwiftUI `.safeAreaInset(edge:)` — reserve a bar on one edge; content fills the rest.
1205
+ * Distinct from `SafeArea` (notch padding) and `proxy.safeAreaInsets` (read-only).
1206
+ */
1207
+ safeAreaInset(edge: SafeAreaInsetEdge, content: SafeAreaInsetSpec["content"], spacing?: number): this;
1208
+ /**
1209
+ * SwiftUI `.navigationTitle` — stores title for Scaffold (see `Scaffold.navigationTitle`).
1210
+ * On non-Scaffold builders, sets `aria-label` / data attribute only (no extra chrome bar).
1211
+ */
1212
+ navigationTitle(title: string): this;
1213
+ /**
1214
+ * SwiftUI `.overlay(alignment:) { }` — layer above this view.
1215
+ * ```ts
1216
+ * Image(url).overlay(Text('NEW'), StackAlign.topTrailing)
1217
+ * ```
1218
+ */
1219
+ overlay(child: FiboChild | (() => FiboChild), alignment?: StackAlign | keyof typeof StackAlign): this;
1220
+ /**
1221
+ * SwiftUI `.background(alignment:) { }` — layer behind this view.
1222
+ */
1223
+ background(child: FiboChild | (() => FiboChild), alignment?: StackAlign | keyof typeof StackAlign): this;
1224
+ /** SwiftUI `onGeometryChange` — fires on mount + resize. */
1225
+ onGeometryChange(handler: (rect: GeometryRect) => void): this;
938
1226
  id(value: string): this;
939
1227
  /**
940
1228
  * Scroll target. Same as `.id()`, plus `scroll-margin-top` so the section
@@ -958,7 +1246,18 @@ declare abstract class FiboBuilder {
958
1246
  private setBoxShorthand;
959
1247
  paddingHorizontal(value: string | number): this;
960
1248
  paddingVertical(value: string | number): this;
1249
+ /**
1250
+ * SwiftUI `.padding`:
1251
+ * - `.padding(8)` — all sides
1252
+ * - `.padding(EdgeSet.horizontal, 12)` — Edge.Set + value
1253
+ * - `.padding({ top: 8, leading: 12 })` — EdgeInsets
1254
+ */
961
1255
  padding(value: string | number): this;
1256
+ padding(edges: EdgeSet, value: string | number): this;
1257
+ padding(insets: EdgeInsetsValue): this;
1258
+ /** SwiftUI `.padding` with {@link EdgeSet} — alias clarity. */
1259
+ /** @deprecated Prefer `.padding(EdgeSet, n)` — same implementation. */
1260
+ paddingEdges(edges: EdgeSet, value: string | number): this;
962
1261
  marginHorizontal(value: string | number): this;
963
1262
  marginVertical(value: string | number): this;
964
1263
  margin(value: string | number): this;
@@ -1068,6 +1367,9 @@ declare abstract class FiboBuilder {
1068
1367
  * (the Scaffold body) cannot divide the viewport across these children.
1069
1368
  * `400`, `'320px'`, `Size.full`, and `Space.md` all count. `flex(1)` afterwards
1070
1369
  * opts back into sharing space.
1370
+ *
1371
+ * Percentages / `auto` do not lock `min-*` — `minWidth: 100%` on a flex
1372
+ * child fights clamping and lets long text blow past the ZStack box.
1071
1373
  */
1072
1374
  private lockAxis;
1073
1375
  width(value: string | number): this;
@@ -1098,8 +1400,58 @@ declare abstract class FiboBuilder {
1098
1400
  translateX(value: Signal<number> | number): this;
1099
1401
  translateY(value: Signal<number> | number): this;
1100
1402
  scale(value: Signal<number> | number): this;
1403
+ /** SwiftUI `scaleEffect` — alias of {@link scale}. */
1404
+ scaleEffect(value: Signal<number> | number): this;
1101
1405
  rotate(degrees: Signal<number> | number): this;
1406
+ /** SwiftUI `rotationEffect` — alias of {@link rotate} (degrees). */
1407
+ rotationEffect(degrees: Signal<number> | number): this;
1408
+ /**
1409
+ * SwiftUI `.allowsHitTesting` — when `false`, this view and descendants
1410
+ * ignore pointer hits (`pointer-events: none`).
1411
+ */
1412
+ allowsHitTesting(value?: boolean): this;
1413
+ /**
1414
+ * SwiftUI scroll target id — used by {@link ScrollViewReader} `.scrollTo(id)`.
1415
+ * Sets `data-scroll-id` on the host.
1416
+ */
1417
+ scrollTarget(id: string): this;
1418
+ /**
1419
+ * SwiftUI: taps on *containers* (ZStack / Column / …) only hit drawn content
1420
+ * unless `.contentShape(Rectangle())` is set. We default that shape when the
1421
+ * first gesture is attached and the caller did not set one — same as the
1422
+ * usual SwiftUI fix, without forcing it on chrome-only views.
1423
+ */
1424
+ protected ensureGestureContentShape(): void;
1425
+ /**
1426
+ * SwiftUI `.gesture` — attach Tap / LongPress / Drag / Magnify / Rotate / …
1427
+ * Chainable: each call wraps the previous (outermost = last).
1428
+ */
1102
1429
  gesture(gesture: GestureBuilder): this;
1430
+ /** SwiftUI `.simultaneousGesture` — runs alongside other gestures (no steal). */
1431
+ simultaneousGesture(gesture: GestureBuilder): this;
1432
+ /** SwiftUI `.highPriorityGesture` — recognized before the view's own gestures. */
1433
+ highPriorityGesture(gesture: GestureBuilder): this;
1434
+ /**
1435
+ * Sugar for {@link TapGesture}`.onEnd(handler)`.
1436
+ * Note: `Button` / `List` / `ListTile` keep domain-specific `.onPress`.
1437
+ */
1438
+ onPress(handler: () => void): this;
1439
+ /** Flutter-style alias of {@link onPress}. */
1440
+ onTap(handler: () => void): this;
1441
+ /**
1442
+ * SwiftUI `onTapGesture(count:perform:)` — default count 1.
1443
+ * Pass a location callback for SpatialTap behavior.
1444
+ */
1445
+ onTapGesture(countOrHandler: number | ((location?: TapLocation) => void) | (() => void), handler?: ((location?: TapLocation) => void) | (() => void)): this;
1446
+ /**
1447
+ * SwiftUI `onLongPressGesture(minimumDuration:perform:onPressingChanged:)`.
1448
+ */
1449
+ onLongPressGesture(handlerOrOpts: (() => void) | {
1450
+ minimumDuration?: number;
1451
+ maximumDistance?: number;
1452
+ perform: () => void;
1453
+ onPressingChanged?: (pressing: boolean) => void;
1454
+ }, onPressingChanged?: (pressing: boolean) => void): this;
1103
1455
  animation(config: Partial<AnimationOptions>): this;
1104
1456
  protected hasStateManagement(): boolean;
1105
1457
  className(className: string): this;
package/dist/core.js CHANGED
@@ -1,5 +1,5 @@
1
- import { C as e, E as t, X as r, a6 as i, a3 as o, a4 as n, _ as l, F as u, T as S, L as c, Q as p, Z as g, O as T, n as b, B as v, P as F, R as E, D as d, G as C, S as R, a8 as f, t as m, q as I, d as P, c as y, b as O, a as x, a2 as M, Y as N, e as _, f as w, a0 as A, g as B, $ as V, a1 as D, V as L, W as U, i as h, l as q, a5 as z, U as G, o as K, h as W, N as X, r as j, H as k, s as H, M as J, I as Q, K as Y, J as Z, a7 as $, m as ss, y as as, k as es, z as ts, p as rs, j as is, A as os, u as ns, w as ls, x as us, v as Ss } from "./client-BzMPiV64.js";
2
- import { F as ps, P as gs, T as Ts, U as bs, a as vs, c as Fs, p as Es, w as ds } from "./page-CHjFSSAF.js";
1
+ import { C as e, E as t, X as r, a6 as i, a3 as o, a4 as n, _ as l, F as u, T as S, L as c, Q as p, Z as g, O as T, n as b, B as v, P as F, R as E, D as d, G as C, S as R, a8 as f, t as m, q as I, d as P, c as y, b as O, a as x, a2 as M, Y as N, e as _, f as w, a0 as A, g as B, $ as V, a1 as D, V as L, W as U, i as h, l as q, a5 as z, U as G, o as K, h as W, N as X, r as j, H as k, s as H, M as J, I as Q, K as Y, J as Z, a7 as $, m as ss, y as as, k as es, z as ts, p as rs, j as is, A as os, u as ns, w as ls, x as us, v as Ss } from "./client-3NdKI2xE.js";
2
+ import { F as ps, P as gs, T as Ts, U as bs, a as vs, c as Fs, p as Es, w as ds } from "./page-xwU8SnoZ.js";
3
3
  export {
4
4
  e as ComputedSignal,
5
5
  t as Easing,