plainframe-ui 0.1.6 → 0.1.7

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.js CHANGED
@@ -10978,13 +10978,250 @@ var Stepper = ({
10978
10978
  );
10979
10979
  };
10980
10980
 
10981
+ // src/components/Swap.tsx
10982
+ import React44, {
10983
+ useState as useState20,
10984
+ useCallback as useCallback13,
10985
+ useEffect as useEffect14,
10986
+ useRef as useRef14,
10987
+ Children as Children6,
10988
+ isValidElement as isValidElement15,
10989
+ createContext as createContext6,
10990
+ useContext as useContext9
10991
+ } from "react";
10992
+ import { css as css42, keyframes as keyframes3 } from "@emotion/react";
10993
+ import { jsx as jsx50 } from "@emotion/react/jsx-runtime";
10994
+ var SwapContext = createContext6(null);
10995
+ var useSwapContext = () => {
10996
+ const ctx = useContext9(SwapContext);
10997
+ if (!ctx) {
10998
+ throw new Error("SwapItem must be used within Swap");
10999
+ }
11000
+ return ctx;
11001
+ };
11002
+ var ANIMATION_MS = 220;
11003
+ var scaleAnim = keyframes3`
11004
+ 0% { transform: scale(1); }
11005
+ 45% { transform: scale(0.85); }
11006
+ 55% { transform: scale(0.85); }
11007
+ 100% { transform: scale(1); }
11008
+ `;
11009
+ var rotateAnim = keyframes3`
11010
+ 0% { transform: rotate(0deg); }
11011
+ 49% { transform: rotate(179deg); }
11012
+ 51% { transform: rotate(181deg); }
11013
+ 100% { transform: rotate(360deg); }
11014
+ `;
11015
+ var scaleRotateAnim = keyframes3`
11016
+ 0% { transform: scale(1) rotate(0deg); }
11017
+ 40% { transform: scale(0.9) rotate(140deg); }
11018
+ 50% { transform: scale(0.85) rotate(180deg); }
11019
+ 60% { transform: scale(0.9) rotate(220deg); }
11020
+ 100% { transform: scale(1) rotate(360deg); }
11021
+ `;
11022
+ var SwapItem = React44.forwardRef(
11023
+ ({ value, children, className = "", css: customCss }, ref) => {
11024
+ const {
11025
+ activeValue,
11026
+ animationEffect,
11027
+ isAnimating,
11028
+ transitionFrom,
11029
+ transitionTo,
11030
+ transitionPhase
11031
+ } = useSwapContext();
11032
+ const isOverlayEffect = animationEffect === "rotate" || animationEffect === "scale-rotate" || animationEffect === "scale";
11033
+ let shouldShow = false;
11034
+ let opacity = 0;
11035
+ if (!isAnimating || !isOverlayEffect) {
11036
+ shouldShow = value === activeValue;
11037
+ opacity = shouldShow ? 1 : 0;
11038
+ } else {
11039
+ const isFrom = value === transitionFrom;
11040
+ const isTo = value === transitionTo;
11041
+ if (isFrom || isTo) {
11042
+ shouldShow = true;
11043
+ if (transitionPhase === "first") {
11044
+ opacity = isFrom ? 1 : 0;
11045
+ } else {
11046
+ opacity = isTo ? 1 : 0;
11047
+ }
11048
+ } else {
11049
+ shouldShow = false;
11050
+ opacity = 0;
11051
+ }
11052
+ }
11053
+ const itemCss = css42({
11054
+ gridArea: "1 / 1 / 2 / 2",
11055
+ transition: `opacity ${ANIMATION_MS / 2}ms ease-out`,
11056
+ opacity,
11057
+ display: shouldShow ? "block" : "none"
11058
+ });
11059
+ return /* @__PURE__ */ jsx50(
11060
+ "div",
11061
+ {
11062
+ ref,
11063
+ className: `pfui-swap-item ${className}`,
11064
+ css: [itemCss, customCss],
11065
+ "aria-hidden": opacity === 0,
11066
+ children
11067
+ }
11068
+ );
11069
+ }
11070
+ );
11071
+ SwapItem.displayName = "SwapItem";
11072
+ var Swap = React44.forwardRef(
11073
+ ({
11074
+ variant = "toggle",
11075
+ animationEffect = "scale",
11076
+ flashDuration = 750,
11077
+ value: controlledValue,
11078
+ defaultValue,
11079
+ onChange,
11080
+ disabled = false,
11081
+ children,
11082
+ className = "",
11083
+ css: customCss
11084
+ }, ref) => {
11085
+ const childArray = Children6.toArray(children).filter(isValidElement15);
11086
+ const values = childArray.filter((child) => child.type === SwapItem).map((child) => child.props.value);
11087
+ const initial = defaultValue ?? values[0] ?? "";
11088
+ const [internalValue, setInternalValue] = useState20(initial);
11089
+ const [isAnimating, setIsAnimating] = useState20(false);
11090
+ const [isFlashing, setIsFlashing] = useState20(false);
11091
+ const [transitionFrom, setTransitionFrom] = useState20(null);
11092
+ const [transitionTo, setTransitionTo] = useState20(null);
11093
+ const [transitionPhase, setTransitionPhase] = useState20("idle");
11094
+ const isControlled = controlledValue !== void 0;
11095
+ const activeValue = isControlled ? controlledValue : internalValue;
11096
+ const flashMs = flashDuration ?? 200;
11097
+ const timeoutsRef = useRef14([]);
11098
+ const clearAllTimeouts = () => {
11099
+ timeoutsRef.current.forEach((id) => window.clearTimeout(id));
11100
+ timeoutsRef.current = [];
11101
+ };
11102
+ useEffect14(() => {
11103
+ return () => {
11104
+ clearAllTimeouts();
11105
+ };
11106
+ }, []);
11107
+ const commitValue = (next) => {
11108
+ if (isControlled) {
11109
+ onChange?.(next);
11110
+ } else {
11111
+ setInternalValue(next);
11112
+ }
11113
+ };
11114
+ const runSwap = useCallback13(
11115
+ (from, to, after) => {
11116
+ clearAllTimeouts();
11117
+ setIsAnimating(true);
11118
+ setTransitionFrom(from);
11119
+ setTransitionTo(to);
11120
+ setTransitionPhase("first");
11121
+ const mid = window.setTimeout(() => {
11122
+ commitValue(to);
11123
+ setTransitionPhase("second");
11124
+ }, ANIMATION_MS / 2);
11125
+ const end = window.setTimeout(() => {
11126
+ setIsAnimating(false);
11127
+ setTransitionFrom(null);
11128
+ setTransitionTo(null);
11129
+ setTransitionPhase("idle");
11130
+ after?.();
11131
+ }, ANIMATION_MS);
11132
+ timeoutsRef.current.push(mid, end);
11133
+ },
11134
+ [isControlled, onChange]
11135
+ );
11136
+ const handleSwap = useCallback13(() => {
11137
+ if (disabled || isAnimating || isFlashing || values.length <= 1) return;
11138
+ const base = initial;
11139
+ const baseIndex = values.indexOf(base);
11140
+ const nextIndexFromBase = baseIndex === -1 ? 0 : (baseIndex + 1) % values.length;
11141
+ const nextFromBase = values[nextIndexFromBase];
11142
+ if (variant === "toggle") {
11143
+ const currentIndex = values.indexOf(activeValue);
11144
+ const nextIndex = (currentIndex + 1) % values.length;
11145
+ const nextValue = values[nextIndex];
11146
+ runSwap(activeValue, nextValue);
11147
+ } else {
11148
+ setIsFlashing(true);
11149
+ const flashValue = nextFromBase === base ? values[(nextIndexFromBase + 1) % values.length] : nextFromBase;
11150
+ runSwap(base, flashValue, () => {
11151
+ const pause = window.setTimeout(() => {
11152
+ runSwap(flashValue, base, () => {
11153
+ setIsFlashing(false);
11154
+ });
11155
+ }, flashMs);
11156
+ timeoutsRef.current.push(pause);
11157
+ });
11158
+ }
11159
+ }, [
11160
+ disabled,
11161
+ isAnimating,
11162
+ isFlashing,
11163
+ values,
11164
+ activeValue,
11165
+ variant,
11166
+ flashMs,
11167
+ runSwap,
11168
+ initial
11169
+ ]);
11170
+ const animationKeyframes = animationEffect === "rotate" ? rotateAnim : animationEffect === "scale-rotate" ? scaleRotateAnim : scaleAnim;
11171
+ const swapCss = css42({
11172
+ position: "relative",
11173
+ display: "inline-grid",
11174
+ cursor: disabled ? "not-allowed" : "pointer",
11175
+ opacity: disabled ? 0.55 : 1,
11176
+ transformOrigin: "center",
11177
+ backfaceVisibility: "hidden",
11178
+ ...isAnimating && {
11179
+ animation: `${animationKeyframes} ${ANIMATION_MS}ms cubic-bezier(0.4, 0, 0.2, 1)`
11180
+ }
11181
+ });
11182
+ const contextValue = {
11183
+ activeValue,
11184
+ variant,
11185
+ animationEffect,
11186
+ flashDuration: flashMs,
11187
+ isAnimating,
11188
+ handleSwap,
11189
+ disabled,
11190
+ transitionFrom,
11191
+ transitionTo,
11192
+ transitionPhase
11193
+ };
11194
+ return /* @__PURE__ */ jsx50(SwapContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx50(
11195
+ "div",
11196
+ {
11197
+ ref,
11198
+ className: `pfui-swap ${className}`,
11199
+ css: [swapCss, customCss],
11200
+ onClick: handleSwap,
11201
+ role: "button",
11202
+ tabIndex: disabled ? -1 : 0,
11203
+ onKeyDown: (e) => {
11204
+ if (disabled) return;
11205
+ if (e.key === "Enter" || e.key === " ") {
11206
+ e.preventDefault();
11207
+ handleSwap();
11208
+ }
11209
+ },
11210
+ "aria-disabled": disabled,
11211
+ children
11212
+ }
11213
+ ) });
11214
+ }
11215
+ );
11216
+ Swap.displayName = "Swap";
11217
+
10981
11218
  // src/components/Tabs.tsx
10982
- import React44 from "react";
10983
- import { css as css42 } from "@emotion/react";
10984
- import { Fragment as Fragment8, jsx as jsx50, jsxs as jsxs29 } from "@emotion/react/jsx-runtime";
11219
+ import React45 from "react";
11220
+ import { css as css43 } from "@emotion/react";
11221
+ import { Fragment as Fragment8, jsx as jsx51, jsxs as jsxs29 } from "@emotion/react/jsx-runtime";
10985
11222
  var Tab = () => null;
10986
11223
  Tab.displayName = "PF.Tab";
10987
- var TabContent = ({ children }) => /* @__PURE__ */ jsx50(Fragment8, { children });
11224
+ var TabContent = ({ children }) => /* @__PURE__ */ jsx51(Fragment8, { children });
10988
11225
  TabContent.displayName = "PF.TabContent";
10989
11226
  function unwrapEmotion2(child) {
10990
11227
  const propsAny = child.props;
@@ -11017,11 +11254,11 @@ var Tabs = ({
11017
11254
  const stretch = fullWidth || width != null;
11018
11255
  const effAlign = align ?? (isV ? "left" : "center");
11019
11256
  const justifyMap = { left: "flex-start", center: "center", right: "flex-end" };
11020
- const { tabs, contents } = React44.useMemo(() => {
11257
+ const { tabs, contents } = React45.useMemo(() => {
11021
11258
  const t = [];
11022
11259
  const c = [];
11023
- React44.Children.forEach(children, (child) => {
11024
- if (!React44.isValidElement(child)) return;
11260
+ React45.Children.forEach(children, (child) => {
11261
+ if (!React45.isValidElement(child)) return;
11025
11262
  const { type: origType, props } = unwrapEmotion2(child);
11026
11263
  const isTab = origType === Tab || origType?.displayName === Tab.displayName;
11027
11264
  const isContent = origType === TabContent || origType?.displayName === TabContent.displayName;
@@ -11037,20 +11274,20 @@ var Tabs = ({
11037
11274
  });
11038
11275
  return { tabs: t, contents: c };
11039
11276
  }, [children]);
11040
- const firstEnabled = React44.useMemo(() => tabs.find((t) => !t.disabled)?.value, [tabs]);
11041
- const [internal, setInternal] = React44.useState(() => {
11277
+ const firstEnabled = React45.useMemo(() => tabs.find((t) => !t.disabled)?.value, [tabs]);
11278
+ const [internal, setInternal] = React45.useState(() => {
11042
11279
  const ok = defaultValue !== void 0 && tabs.some((t) => t.value === defaultValue && !t.disabled);
11043
11280
  return ok ? defaultValue : firstEnabled;
11044
11281
  });
11045
11282
  const isControlled = value !== void 0;
11046
11283
  const currentValue = isControlled ? value : internal;
11047
- const listRef = React44.useRef(null);
11048
- const btnRefs = React44.useRef([]);
11284
+ const listRef = React45.useRef(null);
11285
+ const btnRefs = React45.useRef([]);
11049
11286
  const activeIndex = Math.max(0, tabs.findIndex((t) => t.value === currentValue));
11050
- const [indicator, setIndicator] = React44.useState({ left: 0, top: 0, width: 0, height: 0 });
11051
- const [ready, setReady] = React44.useState(false);
11052
- const [animate, setAnimate] = React44.useState(false);
11053
- const measure = React44.useCallback(() => {
11287
+ const [indicator, setIndicator] = React45.useState({ left: 0, top: 0, width: 0, height: 0 });
11288
+ const [ready, setReady] = React45.useState(false);
11289
+ const [animate, setAnimate] = React45.useState(false);
11290
+ const measure = React45.useCallback(() => {
11054
11291
  const list = listRef.current;
11055
11292
  const btn = btnRefs.current[activeIndex];
11056
11293
  if (!list || !btn) return;
@@ -11058,14 +11295,14 @@ var Tabs = ({
11058
11295
  const r = btn.getBoundingClientRect();
11059
11296
  setIndicator({ left: r.left - listRect.left, top: r.top - listRect.top, width: r.width, height: r.height });
11060
11297
  }, [activeIndex]);
11061
- React44.useLayoutEffect(() => {
11298
+ React45.useLayoutEffect(() => {
11062
11299
  measure();
11063
11300
  if (!ready) {
11064
11301
  setReady(true);
11065
11302
  requestAnimationFrame(() => setAnimate(true));
11066
11303
  }
11067
11304
  }, [measure, ready]);
11068
- React44.useEffect(() => {
11305
+ React45.useEffect(() => {
11069
11306
  const ro = new ResizeObserver(() => measure());
11070
11307
  if (listRef.current) ro.observe(listRef.current);
11071
11308
  const btn = btnRefs.current[activeIndex];
@@ -11112,14 +11349,14 @@ var Tabs = ({
11112
11349
  const thumbBg = variant === "subtle" ? theme.surface.panelBg ?? theme.surface.panelBg : variant === "ghost" ? theme.surface.subtleBg : "transparent";
11113
11350
  const underlineColor = theme.text.primary;
11114
11351
  const showThumb = variant === "subtle" || variant === "ghost" || variant === "underlined";
11115
- const rootCss2 = css42({
11352
+ const rootCss2 = css43({
11116
11353
  "--pf-ease": "cubic-bezier(.4,0,.2,1)",
11117
11354
  display: "flex",
11118
11355
  flexDirection: "column",
11119
11356
  width: fullWidth ? "100%" : width == null ? "auto" : typeof width === "number" ? `${width}px` : width
11120
11357
  });
11121
11358
  const needsPad = variant === "subtle";
11122
- const trackBaseCss = css42({
11359
+ const trackBaseCss = css43({
11123
11360
  position: "relative",
11124
11361
  display: stretch ? "flex" : "inline-flex",
11125
11362
  width: stretch ? "100%" : "auto",
@@ -11131,7 +11368,7 @@ var Tabs = ({
11131
11368
  background: trackBg,
11132
11369
  borderRadius: variant === "subtle" ? rounded ? isV ? theme.radius.lg : theme.radius.full : theme.radius.lg : "none"
11133
11370
  });
11134
- const thumbBaseCss = css42({
11371
+ const thumbBaseCss = css43({
11135
11372
  position: "absolute",
11136
11373
  zIndex: 0,
11137
11374
  pointerEvents: "none",
@@ -11143,10 +11380,10 @@ var Tabs = ({
11143
11380
  ...isV ? { top: `${indicator.top}px`, height: `${indicator.height}px`, left: theme.spacing.xs, right: theme.spacing.xs } : { left: `${indicator.left}px`, width: `${indicator.width}px`, top: theme.spacing.xs, bottom: theme.spacing.xs },
11144
11381
  boxShadow: shadow && variant === "subtle" ? "0 1px 3px rgba(0,0,0,0.04), 0 6px 16px rgba(0,0,0,0.04)" : "none"
11145
11382
  });
11146
- const underlineCss = css42(
11383
+ const underlineCss = css43(
11147
11384
  variant !== "underlined" ? {} : isV ? { background: "transparent", top: `${indicator.top}px`, height: `${indicator.height}px`, left: 0, width: 0, borderLeft: `2px solid ${underlineColor}`, borderBottom: "none", borderRadius: 2 } : { background: "transparent", left: `${indicator.left}px`, width: `${indicator.width}px`, bottom: 0, top: "auto", height: 0, borderBottom: `2px solid ${underlineColor}`, borderLeft: "none", borderRadius: 2 }
11148
11385
  );
11149
- const baseTabCss = css42({
11386
+ const baseTabCss = css43({
11150
11387
  position: "relative",
11151
11388
  zIndex: 1,
11152
11389
  border: "none",
@@ -11170,7 +11407,7 @@ var Tabs = ({
11170
11407
  "&:hover": { color: textPrimary },
11171
11408
  "&[aria-disabled='true'], &:disabled": { opacity: 0.55, cursor: "not-allowed", color: disabledText }
11172
11409
  });
11173
- const contentWrapCss = css42({
11410
+ const contentWrapCss = css43({
11174
11411
  display: "inline-flex",
11175
11412
  alignItems: "center",
11176
11413
  justifyContent: isV ? justifyMap[effAlign] : "center",
@@ -11178,8 +11415,8 @@ var Tabs = ({
11178
11415
  width: "100%",
11179
11416
  flexDirection: titlePosition === "top" ? "column-reverse" : titlePosition === "bottom" ? "column" : titlePosition === "left" ? "row-reverse" : "row"
11180
11417
  });
11181
- const panelCss = css42({ marginTop: theme.spacing.sm, width: "100%" });
11182
- const idBase = React44.useId();
11418
+ const panelCss = css43({ marginTop: theme.spacing.sm, width: "100%" });
11419
+ const idBase = React45.useId();
11183
11420
  const panelIdByValue = /* @__PURE__ */ new Map();
11184
11421
  contents.forEach((c, i) => panelIdByValue.set(c.value, `${idBase}-panel-${i}`));
11185
11422
  const tabIdForIndex = (i) => `${idBase}-tab-${i}`;
@@ -11194,10 +11431,10 @@ var Tabs = ({
11194
11431
  onKeyDown,
11195
11432
  css: [trackBaseCss, userTrackCss],
11196
11433
  children: [
11197
- showThumb && /* @__PURE__ */ jsx50("div", { className: "plainframe-ui-tabs-thumb", css: [thumbBaseCss, underlineCss, userThumbCss, activeIndicatorCss] }),
11434
+ showThumb && /* @__PURE__ */ jsx51("div", { className: "plainframe-ui-tabs-thumb", css: [thumbBaseCss, underlineCss, userThumbCss, activeIndicatorCss] }),
11198
11435
  tabs.map((t, i) => {
11199
11436
  const isActive = currentValue === t.value;
11200
- return /* @__PURE__ */ jsx50(
11437
+ return /* @__PURE__ */ jsx51(
11201
11438
  "button",
11202
11439
  {
11203
11440
  ref: (el) => {
@@ -11215,7 +11452,7 @@ var Tabs = ({
11215
11452
  if (!t.disabled) setSelected(t.value);
11216
11453
  },
11217
11454
  css: [baseTabCss, !t.disabled && focusRing(), t.css, isActive ? t.activeCss ?? activeTabCss : void 0],
11218
- children: /* @__PURE__ */ jsx50("span", { className: "plainframe-ui-tab-content", css: contentWrapCss, children: t.node })
11455
+ children: /* @__PURE__ */ jsx51("span", { className: "plainframe-ui-tab-content", css: contentWrapCss, children: t.node })
11219
11456
  },
11220
11457
  String(t.value ?? i)
11221
11458
  );
@@ -11227,7 +11464,7 @@ var Tabs = ({
11227
11464
  const isActive = c.value === currentValue;
11228
11465
  const labelledByIndex = tabs.findIndex((t) => t.value === c.value);
11229
11466
  const labelledBy = labelledByIndex >= 0 ? tabIdForIndex(labelledByIndex) : void 0;
11230
- return /* @__PURE__ */ jsx50(
11467
+ return /* @__PURE__ */ jsx51(
11231
11468
  "div",
11232
11469
  {
11233
11470
  role: "tabpanel",
@@ -11247,17 +11484,17 @@ var Tabs = ({
11247
11484
  // src/components/TextArea.tsx
11248
11485
  import {
11249
11486
  useLayoutEffect as useLayoutEffect3,
11250
- useRef as useRef14,
11251
- useState as useState20,
11487
+ useRef as useRef15,
11488
+ useState as useState21,
11252
11489
  useId as useId4,
11253
11490
  useMemo as useMemo20,
11254
- useCallback as useCallback13
11491
+ useCallback as useCallback14
11255
11492
  } from "react";
11256
- import { css as css43 } from "@emotion/react";
11257
- import { jsx as jsx51, jsxs as jsxs30 } from "@emotion/react/jsx-runtime";
11493
+ import { css as css44 } from "@emotion/react";
11494
+ import { jsx as jsx52, jsxs as jsxs30 } from "@emotion/react/jsx-runtime";
11258
11495
  var u4 = (v) => v == null ? void 0 : typeof v === "number" ? `${v}px` : v;
11259
11496
  var asArr = (v) => v == null ? [] : Array.isArray(v) ? v : [v];
11260
- var mergeCss2 = (...parts) => css43(parts.filter(Boolean));
11497
+ var mergeCss2 = (...parts) => css44(parts.filter(Boolean));
11261
11498
  var TextArea = ({
11262
11499
  label,
11263
11500
  value,
@@ -11337,9 +11574,9 @@ var TextArea = ({
11337
11574
  const N = theme.neutral;
11338
11575
  const T = theme.text;
11339
11576
  const isControlled = value !== void 0;
11340
- const [internal, setInternal] = useState20(defaultValue);
11577
+ const [internal, setInternal] = useState21(defaultValue);
11341
11578
  const curr = isControlled ? value : internal;
11342
- const setValue = useCallback13(
11579
+ const setValue = useCallback14(
11343
11580
  (next) => {
11344
11581
  if (!isControlled) setInternal(next);
11345
11582
  onChange?.(next);
@@ -11356,7 +11593,7 @@ var TextArea = ({
11356
11593
  [variant, borderW, error, theme.palette.danger, theme.surface.border]
11357
11594
  );
11358
11595
  const rootCss2 = useMemo20(
11359
- () => css43({
11596
+ () => css44({
11360
11597
  boxSizing: "border-box",
11361
11598
  display: "block",
11362
11599
  minWidth: 0,
@@ -11472,7 +11709,7 @@ var TextArea = ({
11472
11709
  ),
11473
11710
  [s.helperFont, maxLength, curr.length, theme.palette.danger, T, userCharCountCss]
11474
11711
  );
11475
- const ref = useRef14(null);
11712
+ const ref = useRef15(null);
11476
11713
  useLayoutEffect3(() => {
11477
11714
  if (typeof window === "undefined") return;
11478
11715
  const el = ref.current;
@@ -11500,8 +11737,8 @@ var TextArea = ({
11500
11737
  const helperId = helperText != null || showCharCount ? `${id ?? reactId}-help` : void 0;
11501
11738
  const inputId = id ?? reactId;
11502
11739
  return /* @__PURE__ */ jsxs30("div", { className: ["plainframe-ui-textarea", className || ""].join(" ").trim(), css: rootCss2, children: [
11503
- label && /* @__PURE__ */ jsx51("label", { htmlFor: inputId, className: "plainframe-ui-textarea-label", css: labelCss2, children: label }),
11504
- /* @__PURE__ */ jsx51(
11740
+ label && /* @__PURE__ */ jsx52("label", { htmlFor: inputId, className: "plainframe-ui-textarea-label", css: labelCss2, children: label }),
11741
+ /* @__PURE__ */ jsx52(
11505
11742
  "div",
11506
11743
  {
11507
11744
  className: "plainframe-ui-textarea-surface",
@@ -11509,7 +11746,7 @@ var TextArea = ({
11509
11746
  "aria-invalid": !!error || void 0,
11510
11747
  "aria-disabled": disabled || void 0,
11511
11748
  onClick: () => !disabled && ref.current?.focus(),
11512
- children: /* @__PURE__ */ jsx51(
11749
+ children: /* @__PURE__ */ jsx52(
11513
11750
  "textarea",
11514
11751
  {
11515
11752
  ref,
@@ -11541,7 +11778,7 @@ var TextArea = ({
11541
11778
  }
11542
11779
  ),
11543
11780
  (helperText != null || showCharCount && maxLength != null) && /* @__PURE__ */ jsxs30("div", { className: "plainframe-ui-textarea-helper-row", css: helperRowCss, children: [
11544
- /* @__PURE__ */ jsx51("span", { id: helperId, className: "plainframe-ui-textarea-helper-text", css: helperTextCss, children: helperText }),
11781
+ /* @__PURE__ */ jsx52("span", { id: helperId, className: "plainframe-ui-textarea-helper-text", css: helperTextCss, children: helperText }),
11545
11782
  showCharCount && maxLength != null && /* @__PURE__ */ jsxs30("span", { className: "plainframe-ui-textarea-char-count", css: charCountCss, children: [
11546
11783
  curr.length,
11547
11784
  "/",
@@ -11552,18 +11789,18 @@ var TextArea = ({
11552
11789
  };
11553
11790
 
11554
11791
  // src/components/Toast.tsx
11555
- import React46, { useEffect as useEffect14, useSyncExternalStore } from "react";
11556
- import { css as css44 } from "@emotion/react";
11792
+ import React47, { useEffect as useEffect15, useSyncExternalStore } from "react";
11793
+ import { css as css45 } from "@emotion/react";
11557
11794
  import { AnimatePresence as AnimatePresence5, motion as motion5, useAnimationControls } from "framer-motion";
11558
11795
  import { X as X4 } from "lucide-react";
11559
11796
  import { createPortal } from "react-dom";
11560
- import { Fragment as Fragment9, jsx as jsx52, jsxs as jsxs31 } from "@emotion/react/jsx-runtime";
11797
+ import { Fragment as Fragment9, jsx as jsx53, jsxs as jsxs31 } from "@emotion/react/jsx-runtime";
11561
11798
  var isIterable = (obj) => obj != null && typeof obj[Symbol.iterator] === "function";
11562
11799
  var isPromise = (obj) => !!obj && (typeof obj === "object" || typeof obj === "function") && typeof obj.then === "function";
11563
11800
  function isOptionsInput(x) {
11564
11801
  if (x == null) return false;
11565
11802
  if (typeof x !== "object") return false;
11566
- if (React46.isValidElement(x)) return false;
11803
+ if (React47.isValidElement(x)) return false;
11567
11804
  if (isPromise(x)) return false;
11568
11805
  if (isIterable(x)) return false;
11569
11806
  const keys = Object.keys(x);
@@ -11746,7 +11983,7 @@ var toast = Object.assign(
11746
11983
  }
11747
11984
  if (o.content == null && (o.title != null || o.description != null)) {
11748
11985
  o.content = /* @__PURE__ */ jsxs31("div", { children: [
11749
- o.title && /* @__PURE__ */ jsx52("strong", { style: { display: "block", marginBottom: 2 }, children: o.title }),
11986
+ o.title && /* @__PURE__ */ jsx53("strong", { style: { display: "block", marginBottom: 2 }, children: o.title }),
11750
11987
  o.description
11751
11988
  ] });
11752
11989
  }
@@ -11910,16 +12147,16 @@ function positionCss(pos) {
11910
12147
  };
11911
12148
  return map[pos];
11912
12149
  }
11913
- var rowCss = css44({ display: "flex", alignItems: "flex-start", gap: 10 });
11914
- var iconWrapCss = css44({
12150
+ var rowCss = css45({ display: "flex", alignItems: "flex-start", gap: 10 });
12151
+ var iconWrapCss = css45({
11915
12152
  flex: "0 0 auto",
11916
12153
  paddingTop: 1,
11917
12154
  lineHeight: 0,
11918
12155
  marginLeft: -3,
11919
12156
  "& svg, & img, & canvas, & video": { display: "block" }
11920
12157
  });
11921
- var textCss = css44({ fontSize: 14, lineHeight: 1.4, fontWeight: 500, flex: 1, minWidth: 0 });
11922
- var actionRowCss = css44({ display: "flex", alignItems: "center", gap: 6, marginRight: -2 });
12158
+ var textCss = css45({ fontSize: 14, lineHeight: 1.4, fontWeight: 500, flex: 1, minWidth: 0 });
12159
+ var actionRowCss = css45({ display: "flex", alignItems: "center", gap: 6, marginRight: -2 });
11923
12160
  function ToastHost() {
11924
12161
  const snap = useSyncExternalStore(store.subscribe.bind(store), () => store.snapshot, () => store.snapshot);
11925
12162
  const theme = usePlainframeUITheme();
@@ -11936,7 +12173,7 @@ function ToastHost() {
11936
12173
  ...positionCss(cfg.position),
11937
12174
  ...cfg.styles.stack ?? {}
11938
12175
  };
11939
- return /* @__PURE__ */ jsx52("div", { className: "plainframe-ui-toast-stack", css: css44(stackStyle), children: /* @__PURE__ */ jsx52(AnimatePresence5, { initial: false, children: list.map((t, index) => {
12176
+ return /* @__PURE__ */ jsx53("div", { className: "plainframe-ui-toast-stack", css: css45(stackStyle), children: /* @__PURE__ */ jsx53(AnimatePresence5, { initial: false, children: list.map((t, index) => {
11940
12177
  const from = snap.enterFrom[t.id] || "tail";
11941
12178
  const enterY = isBottom ? from === "head" ? -16 : 16 : from === "head" ? 16 : -16;
11942
12179
  const mt = index > 0 ? cfg.gutter : 0;
@@ -11974,8 +12211,8 @@ function ToastHost() {
11974
12211
  } else if (dismissMode === "never") {
11975
12212
  modeStyles[closeSel] = { display: "none" };
11976
12213
  }
11977
- const wrapCss = css44({ ...baseSurface, ...extraSurface, ...modeStyles });
11978
- const closeCss = css44({
12214
+ const wrapCss = css45({ ...baseSurface, ...extraSurface, ...modeStyles });
12215
+ const closeCss = css45({
11979
12216
  position: "absolute",
11980
12217
  top: 8,
11981
12218
  right: 8,
@@ -11996,10 +12233,10 @@ function ToastHost() {
11996
12233
  let content;
11997
12234
  if (t.bare && t.render) {
11998
12235
  const inner = typeof t.render === "function" ? t.render(ctx) : t.render;
11999
- content = /* @__PURE__ */ jsx52("div", { style: { pointerEvents: "auto" }, onClick: (e) => t.onClick?.(t.id, e), children: inner });
12236
+ content = /* @__PURE__ */ jsx53("div", { style: { pointerEvents: "auto" }, onClick: (e) => t.onClick?.(t.id, e), children: inner });
12000
12237
  } else if (cfg.bareRenderer && cfg.renderer) {
12001
12238
  const inner = typeof cfg.renderer === "function" ? cfg.renderer(ctx) : cfg.renderer;
12002
- content = /* @__PURE__ */ jsx52("div", { style: { pointerEvents: "auto" }, onClick: (e) => t.onClick?.(t.id, e), children: inner });
12239
+ content = /* @__PURE__ */ jsx53("div", { style: { pointerEvents: "auto" }, onClick: (e) => t.onClick?.(t.id, e), children: inner });
12003
12240
  } else {
12004
12241
  let innerBlock;
12005
12242
  if (cfg.renderer) {
@@ -12009,16 +12246,16 @@ function ToastHost() {
12009
12246
  } else {
12010
12247
  innerBlock = /* @__PURE__ */ jsxs31(Fragment9, { children: [
12011
12248
  /* @__PURE__ */ jsxs31("div", { css: rowCss, children: [
12012
- t.startIcon && /* @__PURE__ */ jsx52("div", { css: iconWrapCss, children: t.startIcon }),
12013
- /* @__PURE__ */ jsx52("div", { css: textCss, children: t.content }),
12014
- t.endIcon && /* @__PURE__ */ jsx52("div", { css: iconWrapCss, children: t.endIcon })
12249
+ t.startIcon && /* @__PURE__ */ jsx53("div", { css: iconWrapCss, children: t.startIcon }),
12250
+ /* @__PURE__ */ jsx53("div", { css: textCss, children: t.content }),
12251
+ t.endIcon && /* @__PURE__ */ jsx53("div", { css: iconWrapCss, children: t.endIcon })
12015
12252
  ] }),
12016
- t.action && /* @__PURE__ */ jsx52("div", { css: actionRowCss, children: t.action })
12253
+ t.action && /* @__PURE__ */ jsx53("div", { css: actionRowCss, children: t.action })
12017
12254
  ] });
12018
12255
  }
12019
12256
  content = /* @__PURE__ */ jsxs31("div", { css: wrapCss, onClick: (e) => t.onClick?.(t.id, e), children: [
12020
12257
  innerBlock,
12021
- /* @__PURE__ */ jsx52(
12258
+ /* @__PURE__ */ jsx53(
12022
12259
  "button",
12023
12260
  {
12024
12261
  className: "plainframe-ui-toast-close",
@@ -12028,12 +12265,12 @@ function ToastHost() {
12028
12265
  e.stopPropagation();
12029
12266
  toast.dismiss(t.id);
12030
12267
  },
12031
- children: /* @__PURE__ */ jsx52(X4, { strokeWidth: 2.5, size: 14 })
12268
+ children: /* @__PURE__ */ jsx53(X4, { strokeWidth: 2.5, size: 14 })
12032
12269
  }
12033
12270
  )
12034
12271
  ] });
12035
12272
  }
12036
- return /* @__PURE__ */ jsx52(
12273
+ return /* @__PURE__ */ jsx53(
12037
12274
  SwipeItem,
12038
12275
  {
12039
12276
  id: t.id,
@@ -12051,7 +12288,7 @@ function ToastHost() {
12051
12288
  function SwipeItem(props) {
12052
12289
  const { id, isBottom, mt, enterY, width, pauseOnHover, children } = props;
12053
12290
  const controls = useAnimationControls();
12054
- useEffect14(() => {
12291
+ useEffect15(() => {
12055
12292
  controls.start({ opacity: 1, y: 0, height: "auto", x: 0, transition: ENTER_SPRING });
12056
12293
  }, [controls]);
12057
12294
  const itemStyle = {
@@ -12062,12 +12299,12 @@ function SwipeItem(props) {
12062
12299
  maxWidth: width != null ? typeof width === "number" ? `${width}px` : width : "none",
12063
12300
  ...cfg.styles.item ?? {}
12064
12301
  };
12065
- return /* @__PURE__ */ jsx52(
12302
+ return /* @__PURE__ */ jsx53(
12066
12303
  motion5.div,
12067
12304
  {
12068
12305
  layout: true,
12069
12306
  className: "plainframe-ui-toast-item",
12070
- css: css44(itemStyle),
12307
+ css: css45(itemStyle),
12071
12308
  initial: { opacity: 0, y: enterY, height: "auto", x: 0 },
12072
12309
  animate: controls,
12073
12310
  exit: {
@@ -12105,19 +12342,19 @@ function SwipeItem(props) {
12105
12342
  }
12106
12343
  function ToastViewport() {
12107
12344
  ensureHost();
12108
- return hostEl ? createPortal(/* @__PURE__ */ jsx52(ToastHost, {}), hostEl) : null;
12345
+ return hostEl ? createPortal(/* @__PURE__ */ jsx53(ToastHost, {}), hostEl) : null;
12109
12346
  }
12110
12347
 
12111
12348
  // src/components/Tooltip.tsx
12112
- import React47, {
12113
- createContext as createContext6,
12114
- useContext as useContext9,
12349
+ import React48, {
12350
+ createContext as createContext7,
12351
+ useContext as useContext10,
12115
12352
  useId as useId5,
12116
12353
  useMemo as useMemo21,
12117
- useRef as useRef15,
12118
- useState as useState21
12354
+ useRef as useRef16,
12355
+ useState as useState22
12119
12356
  } from "react";
12120
- import { css as css45 } from "@emotion/react";
12357
+ import { css as css46 } from "@emotion/react";
12121
12358
  import {
12122
12359
  useFloating as useFloating3,
12123
12360
  offset,
@@ -12134,7 +12371,7 @@ import {
12134
12371
  FloatingPortal as FloatingPortal3
12135
12372
  } from "@floating-ui/react";
12136
12373
  import { AnimatePresence as AnimatePresence6, motion as motion6 } from "framer-motion";
12137
- import { jsx as jsx53, jsxs as jsxs32 } from "@emotion/react/jsx-runtime";
12374
+ import { jsx as jsx54, jsxs as jsxs32 } from "@emotion/react/jsx-runtime";
12138
12375
  var mergeRefs4 = (...refs) => (node) => {
12139
12376
  for (const r of refs) {
12140
12377
  if (!r) continue;
@@ -12145,9 +12382,9 @@ var mergeRefs4 = (...refs) => (node) => {
12145
12382
  }
12146
12383
  }
12147
12384
  };
12148
- var TooltipCtx = createContext6(null);
12385
+ var TooltipCtx = createContext7(null);
12149
12386
  var useTooltipCtx = () => {
12150
- const v = useContext9(TooltipCtx);
12387
+ const v = useContext10(TooltipCtx);
12151
12388
  if (!v) throw new Error("TooltipTrigger/TooltipContent must be inside <Tooltip>.");
12152
12389
  return v;
12153
12390
  };
@@ -12162,13 +12399,13 @@ var Tooltip = ({
12162
12399
  autoWidth = false,
12163
12400
  disableHoverListener = false
12164
12401
  }) => {
12165
- const [uc, setUc] = useState21(!!defaultOpen);
12402
+ const [uc, setUc] = useState22(!!defaultOpen);
12166
12403
  const open = controlled ?? uc;
12167
12404
  const setOpen = (o) => {
12168
12405
  if (controlled === void 0) setUc(o);
12169
12406
  onOpenChange?.(o);
12170
12407
  };
12171
- const arrowRef = useRef15(null);
12408
+ const arrowRef = useRef16(null);
12172
12409
  const floating = useFloating3({
12173
12410
  placement,
12174
12411
  open,
@@ -12226,7 +12463,7 @@ var Tooltip = ({
12226
12463
  getFloatingProps
12227
12464
  ]
12228
12465
  );
12229
- return /* @__PURE__ */ jsx53(TooltipCtx.Provider, { value: ctx, children });
12466
+ return /* @__PURE__ */ jsx54(TooltipCtx.Provider, { value: ctx, children });
12230
12467
  };
12231
12468
  var TooltipTrigger = ({
12232
12469
  asChild = true,
@@ -12235,7 +12472,7 @@ var TooltipTrigger = ({
12235
12472
  css: userCss
12236
12473
  }) => {
12237
12474
  const { refs, getReferenceProps, id } = useTooltipCtx();
12238
- const isElement = React47.isValidElement(children);
12475
+ const isElement = React48.isValidElement(children);
12239
12476
  const isDomChild = isElement && typeof children.type === "string";
12240
12477
  if (asChild && isElement && isDomChild) {
12241
12478
  const child = children;
@@ -12249,9 +12486,9 @@ var TooltipTrigger = ({
12249
12486
  child.props?.css || void 0,
12250
12487
  userCss
12251
12488
  ].filter(Boolean);
12252
- return React47.cloneElement(child, { ...merged, css: mergedCss });
12489
+ return React48.cloneElement(child, { ...merged, css: mergedCss });
12253
12490
  }
12254
- return /* @__PURE__ */ jsx53(
12491
+ return /* @__PURE__ */ jsx54(
12255
12492
  "span",
12256
12493
  {
12257
12494
  ref: refs.setReference,
@@ -12287,7 +12524,7 @@ var TooltipContent = ({
12287
12524
  const initial = side === "bottom" ? { opacity: 0, y: -delta, scale: 0.98 } : side === "top" ? { opacity: 0, y: +delta, scale: 0.98 } : side === "left" ? { opacity: 0, x: +delta, scale: 0.98 } : { opacity: 0, x: -delta, scale: 0.98 };
12288
12525
  const exit = initial;
12289
12526
  const transformOrigin = side === "bottom" ? "center top" : side === "top" ? "center bottom" : side === "left" ? "right center" : "left center";
12290
- const tooltipBase = css45({
12527
+ const tooltipBase = css46({
12291
12528
  zIndex: 1300,
12292
12529
  backgroundColor: theme.neutral[900],
12293
12530
  color: theme.neutral[0],
@@ -12302,7 +12539,7 @@ var TooltipContent = ({
12302
12539
  pointerEvents: "auto",
12303
12540
  transformOrigin
12304
12541
  });
12305
- const arrowBase = css45({
12542
+ const arrowBase = css46({
12306
12543
  position: "absolute",
12307
12544
  width: 10,
12308
12545
  height: 10,
@@ -12313,7 +12550,7 @@ var TooltipContent = ({
12313
12550
  });
12314
12551
  const arrowData = middlewareData.arrow;
12315
12552
  const staticSide = { top: "bottom", bottom: "top", left: "right", right: "left" }[side];
12316
- return /* @__PURE__ */ jsx53(FloatingPortal3, { children: /* @__PURE__ */ jsx53(AnimatePresence6, { children: open && /* @__PURE__ */ jsxs32(
12553
+ return /* @__PURE__ */ jsx54(FloatingPortal3, { children: /* @__PURE__ */ jsx54(AnimatePresence6, { children: open && /* @__PURE__ */ jsxs32(
12317
12554
  motion6.div,
12318
12555
  {
12319
12556
  id,
@@ -12335,7 +12572,7 @@ var TooltipContent = ({
12335
12572
  ...getFloatingProps(),
12336
12573
  children: [
12337
12574
  children,
12338
- allowArrow && /* @__PURE__ */ jsx53(
12575
+ allowArrow && /* @__PURE__ */ jsx54(
12339
12576
  "div",
12340
12577
  {
12341
12578
  ref: arrowRef,
@@ -12354,14 +12591,14 @@ var TooltipContent = ({
12354
12591
  };
12355
12592
 
12356
12593
  // src/theme/CssBaseline.tsx
12357
- import { Global, css as css46 } from "@emotion/react";
12358
- import { jsx as jsx54 } from "@emotion/react/jsx-runtime";
12594
+ import { Global, css as css47 } from "@emotion/react";
12595
+ import { jsx as jsx55 } from "@emotion/react/jsx-runtime";
12359
12596
  function CssBaseline() {
12360
12597
  const t = usePlainframeUITheme();
12361
- return /* @__PURE__ */ jsx54(
12598
+ return /* @__PURE__ */ jsx55(
12362
12599
  Global,
12363
12600
  {
12364
- styles: css46`
12601
+ styles: css47`
12365
12602
  *,*::before,*::after{box-sizing:border-box}
12366
12603
  :where(html){-webkit-text-size-adjust:100%;text-size-adjust:100%;scroll-behavior:smooth}
12367
12604
  html,body,#root{height:100%}
@@ -12489,6 +12726,8 @@ export {
12489
12726
  SubMenu,
12490
12727
  SubMenuContent,
12491
12728
  SubMenuTrigger,
12729
+ Swap,
12730
+ SwapItem,
12492
12731
  Switch,
12493
12732
  Tab,
12494
12733
  TabContent,