plainframe-ui 0.1.0 → 0.1.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/index.d.ts CHANGED
@@ -303,22 +303,6 @@ type LoadingPosition = "start" | "end" | "center";
303
303
  type WithCssProp$5 = {
304
304
  css?: Interpolation<Theme>;
305
305
  };
306
- type ButtonBase = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "color" | "style"> & WithCssProp$5 & {
307
- size?: ButtonSize;
308
- startIcon?: ReactNode;
309
- endIcon?: ReactNode;
310
- rounded?: boolean;
311
- fullWidth?: boolean;
312
- loading?: boolean;
313
- loadingIndicator?: ReactNode;
314
- loadingPosition?: LoadingPosition;
315
- className?: string;
316
- hoverEffect?: boolean;
317
- children?: ReactNode;
318
- };
319
- type ButtonProps = ButtonBase & {
320
- variant?: ButtonVariant;
321
- };
322
306
  declare const Button: React.MemoExoticComponent<React.ForwardRefExoticComponent<Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "style" | "color"> & WithCssProp$5 & {
323
307
  size?: ButtonSize;
324
308
  startIcon?: ReactNode;
@@ -389,6 +373,12 @@ type WithCssProp$3 = {
389
373
  css?: Interpolation<Theme>;
390
374
  };
391
375
  type CardDirection = "horizontal" | "vertical";
376
+ type Align$3 = "start" | "center" | "end";
377
+ type SectionPadding = {
378
+ padding?: ContainerProps["padding"];
379
+ paddingX?: ContainerProps["padding"];
380
+ paddingY?: ContainerProps["padding"];
381
+ };
392
382
  type CardProps = WithCssProp$3 & Omit<React.HTMLAttributes<HTMLDivElement>, "onChange" | "className"> & {
393
383
  variant?: ContainerProps["variant"];
394
384
  padding?: ContainerProps["padding"];
@@ -404,7 +394,22 @@ type CardProps = WithCssProp$3 & Omit<React.HTMLAttributes<HTMLDivElement>, "onC
404
394
  direction?: CardDirection;
405
395
  className?: string;
406
396
  };
397
+ type CardSectionBaseProps = WithCssProp$3 & SectionPadding & Omit<React.HTMLAttributes<HTMLDivElement>, "className"> & {
398
+ className?: string;
399
+ align?: Align$3;
400
+ };
401
+ type CardSideProps = CardSectionBaseProps;
407
402
  declare const Card: React.ForwardRefExoticComponent<React.PropsWithoutRef<CardProps> & React.RefAttributes<HTMLDivElement>>;
403
+ declare const CardContent: React.FC<CardSectionBaseProps>;
404
+ declare const CardStart: React.FC<CardSideProps>;
405
+ declare const CardEnd: React.FC<CardSideProps>;
406
+ type TextTune = {
407
+ weight?: number | string;
408
+ size?: number | string;
409
+ color?: string | "primary" | "secondary";
410
+ };
411
+ declare const CardTitle: React.FC<CardSectionBaseProps & TextTune>;
412
+ declare const CardDescription: React.FC<CardSectionBaseProps & TextTune>;
408
413
 
409
414
  /** @jsxImportSource @emotion/react */
410
415
 
@@ -1407,6 +1412,7 @@ declare const toast: {
1407
1412
  bareRenderer: boolean;
1408
1413
  }>) => void;
1409
1414
  };
1415
+ declare function ToastViewport(): JSX.Element | null;
1410
1416
 
1411
1417
  /** @jsxImportSource @emotion/react */
1412
1418
 
@@ -1588,4 +1594,4 @@ declare const ThemeProvider: React.FC<ThemeProviderProps>;
1588
1594
 
1589
1595
  declare function CssBaseline(): _emotion_react_jsx_runtime.JSX.Element;
1590
1596
 
1591
- export { Accordion, AccordionDetails, AccordionGroup, AccordionSummary, ActionBar, Alert, AlertDescription, AlertTitle, Autocomplete, Avatar, AvatarGroup, Backdrop, Badge, BreadCrumbItem, BreadCrumbs, Button, ButtonGroup, type ButtonProps, Card, CardGroup, Checkbox, Chip, CodeField, ColorPatches, Container, ContextZone, CssBaseline, Divider, Drawer, DropdownMenu, DropdownMenuContent, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Fade, Flex, Grow, Image, type ImageProps, ImageStack, Kbd, Menu, MenuCheckboxGroup, MenuCheckboxItem, MenuItem, MenuLabel, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSwitchItem, MenuVariantCtx, Modal, ModalContent, type ModalProps, ModalTrigger, type Mode, Pagination, type PlainframeUITheme, Popover, PopoverAnchor, type PopoverAnchorProps, PopoverContent, type PopoverContentProps, type PopoverRootProps, PopoverTrigger, type PopoverTriggerProps, Progress, Quote, RadioGroup, type RadioGroupProps, RadioItem, type RadioItemProps, Rotate, type Scale, Select, Skeleton, Slide, Slider, Step, Stepper, SubMenu, SubMenuContent, SubMenuTrigger, Switch, Tab, TabContent, Tabs, TextArea, TextField, type TextFieldProps, type ThemeProp, ThemeProvider, type ThemeProviderProps, Tooltip, TooltipContent, TooltipTrigger, Typography, defaultDarkTheme, defaultLightTheme, surfaceFromNeutral, textDark, textLight, toast, useColorMode, useColorModeValue, useDropdownMenuActiveIndex, usePlainframeUITheme, usePopoverContext, usePrimary, usePrimitives };
1597
+ export { Accordion, AccordionDetails, AccordionGroup, AccordionSummary, ActionBar, Alert, AlertDescription, AlertTitle, Autocomplete, Avatar, AvatarGroup, Backdrop, Badge, BreadCrumbItem, BreadCrumbs, Button, ButtonGroup, Card, CardContent, CardDescription, CardEnd, CardGroup, CardStart, CardTitle, Checkbox, Chip, CodeField, ColorPatches, Container, ContextZone, CssBaseline, Divider, Drawer, DropdownMenu, DropdownMenuContent, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Fade, Flex, Grow, Image, ImageStack, Kbd, Menu, MenuCheckboxGroup, MenuCheckboxItem, MenuItem, MenuLabel, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSwitchItem, MenuVariantCtx, Modal, ModalContent, ModalTrigger, type Mode, Pagination, type PlainframeUITheme, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, Quote, RadioGroup, RadioItem, Rotate, type Scale, Select, Skeleton, Slide, Slider, Step, Stepper, SubMenu, SubMenuContent, SubMenuTrigger, Switch, Tab, TabContent, Tabs, TextArea, TextField, type ThemeProp, ThemeProvider, type ThemeProviderProps, ToastViewport, Tooltip, TooltipContent, TooltipTrigger, Typography, defaultDarkTheme, defaultLightTheme, surfaceFromNeutral, textDark, textLight, toast, useColorMode, useColorModeValue, useDropdownMenuActiveIndex, usePlainframeUITheme, usePopoverContext, usePrimary, usePrimitives };
package/dist/index.js CHANGED
@@ -1691,14 +1691,14 @@ import { jsx as jsx8, jsxs as jsxs4 } from "@emotion/react/jsx-runtime";
1691
1691
  var u = (v) => v == null ? void 0 : typeof v === "number" ? `${v}px` : v;
1692
1692
  var asArray = (v) => v == null ? [] : Array.isArray(v) ? v : [v];
1693
1693
  var mergeCss = (...parts) => css8(parts.filter(Boolean));
1694
- function cloneIcon(icon, px4, color = "currentColor") {
1694
+ function cloneIcon(icon, px5, color = "currentColor") {
1695
1695
  if (!isValidElement3(icon)) return icon;
1696
1696
  const props = icon.props || {};
1697
1697
  const next = {};
1698
- if (props.size == null) next.size = px4;
1698
+ if (props.size == null) next.size = px5;
1699
1699
  if (props.color == null) next.color = color;
1700
1700
  if (props.style?.fontSize == null)
1701
- next.style = { ...props.style || {}, fontSize: px4 };
1701
+ next.style = { ...props.style || {}, fontSize: px5 };
1702
1702
  return cloneElement3(icon, { ...props, ...next });
1703
1703
  }
1704
1704
  var TextField = forwardRef3(function TextField2({
@@ -2955,7 +2955,7 @@ var DropdownMenuContent = React9.forwardRef(
2955
2955
  y: { type: "spring", stiffness: 420, damping: 30, mass: 0.6 },
2956
2956
  opacity: { duration: 0.12, ease: "linear" }
2957
2957
  };
2958
- const positionCss = emCss2({
2958
+ const positionCss2 = emCss2({
2959
2959
  position: strategy,
2960
2960
  top: y ?? 0,
2961
2961
  left: x ?? 0,
@@ -2971,7 +2971,7 @@ var DropdownMenuContent = React9.forwardRef(
2971
2971
  ref: mergeRefs(ref, refs.setFloating)
2972
2972
  }),
2973
2973
  className,
2974
- css: [baseCss, positionCss, userCss],
2974
+ css: [baseCss, positionCss2, userCss],
2975
2975
  initial,
2976
2976
  animate: { opacity: 1, x: 0, y: 0, scale: 1 },
2977
2977
  exit,
@@ -4305,15 +4305,15 @@ function resolveGap(gap, theme) {
4305
4305
  }
4306
4306
  function sectionPaddingStyles(theme, padding, paddingX, paddingY) {
4307
4307
  const p = resolveTokenPadding(padding, theme);
4308
- const px4 = resolveTokenPadding(paddingX, theme);
4308
+ const px5 = resolveTokenPadding(paddingX, theme);
4309
4309
  const py = resolveTokenPadding(paddingY, theme);
4310
4310
  const styles = {};
4311
- if (p && !px4 && !py) {
4311
+ if (p && !px5 && !py) {
4312
4312
  styles.padding = p;
4313
4313
  }
4314
- if (px4) {
4315
- styles.paddingLeft = px4;
4316
- styles.paddingRight = px4;
4314
+ if (px5) {
4315
+ styles.paddingLeft = px5;
4316
+ styles.paddingRight = px5;
4317
4317
  }
4318
4318
  if (py) {
4319
4319
  styles.paddingTop = py;
@@ -4750,10 +4750,10 @@ var Autocomplete = ({
4750
4750
  if (typeof document === "undefined") return;
4751
4751
  const menu = document.querySelector(`.${cls("menu")}`);
4752
4752
  if (!menu) return;
4753
- const first = menu.querySelector(
4753
+ const first2 = menu.querySelector(
4754
4754
  '[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"]'
4755
4755
  );
4756
- first?.focus();
4756
+ first2?.focus();
4757
4757
  };
4758
4758
  const handleKeyDown = (e) => {
4759
4759
  if (e.key === " " || e.code === "Space" || e.key === "Spacebar") {
@@ -4773,12 +4773,12 @@ var Autocomplete = ({
4773
4773
  if (e.key === "Tab" && !e.shiftKey && open) {
4774
4774
  const menu = typeof document !== "undefined" ? document.querySelector(`.${cls("menu")}`) : null;
4775
4775
  if (menu) {
4776
- const first = menu.querySelector(
4776
+ const first2 = menu.querySelector(
4777
4777
  '[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"]'
4778
4778
  );
4779
- if (first) {
4779
+ if (first2) {
4780
4780
  e.preventDefault();
4781
- first.focus();
4781
+ first2.focus();
4782
4782
  return;
4783
4783
  }
4784
4784
  }
@@ -5000,16 +5000,16 @@ var Avatar = forwardRef10(
5000
5000
  useEffect7(() => {
5001
5001
  setShowImg(!!src);
5002
5002
  }, [src]);
5003
- const px4 = getSize2(size, theme);
5004
- const numeric = typeof px4 === "number" ? px4 : Number.parseFloat(String(px4)) || 0;
5003
+ const px5 = getSize2(size, theme);
5004
+ const numeric = typeof px5 === "number" ? px5 : Number.parseFloat(String(px5)) || 0;
5005
5005
  const fontSize = numeric ? Math.round(numeric * (numeric <= 28 ? 0.55 : 0.52)) : void 0;
5006
5006
  const radius2 = rounded ? theme.radius.full : theme.radius.md;
5007
5007
  const bg = getPaletteColor(theme, color);
5008
5008
  const fg = getForegroundColor(theme, color);
5009
5009
  const fallbackText = getFallbackText(children, alt);
5010
5010
  const baseCss = css14({
5011
- width: px4,
5012
- height: px4,
5011
+ width: px5,
5012
+ height: px5,
5013
5013
  borderRadius: radius2,
5014
5014
  display: "inline-flex",
5015
5015
  alignItems: "center",
@@ -6285,17 +6285,17 @@ var toPx2 = (v, fallback = 1) => {
6285
6285
  return /^\d+(\.\d+)?$/.test(v) ? `${v}px` : v;
6286
6286
  };
6287
6287
  var isOutlinedVariant = (v) => typeof v === "string" && /^(outlined|outlined-soft|outline-soft)$/i.test(v);
6288
- var visualLeaf = (node, first) => {
6288
+ var visualLeaf = (node, first2) => {
6289
6289
  if (!isEl2(node)) return null;
6290
6290
  if (isGroup(node)) {
6291
6291
  const kids = Children3.toArray(node.props.children).filter(isValidElement8);
6292
6292
  if (!kids.length) return null;
6293
- return visualLeaf(first ? kids[0] : kids[kids.length - 1], first);
6293
+ return visualLeaf(first2 ? kids[0] : kids[kids.length - 1], first2);
6294
6294
  }
6295
6295
  if (isMenu(node)) {
6296
6296
  const kids = Children3.toArray(node.props.children).filter(isValidElement8);
6297
6297
  const trig = kids.find(isTrigger);
6298
- return trig ? visualLeaf(trig, first) : null;
6298
+ return trig ? visualLeaf(trig, first2) : null;
6299
6299
  }
6300
6300
  if (isTrigger(node)) {
6301
6301
  const kids = Children3.toArray(node.props.children ?? []).filter(isValidElement8);
@@ -11678,7 +11678,24 @@ function isOptionsInput(x) {
11678
11678
  "id"
11679
11679
  ].some((k) => k in x);
11680
11680
  }
11681
+ var ENTER_SPRING = { type: "spring", stiffness: 920, damping: 100 };
11681
11682
  var ROOT_ID = "toast-host";
11683
+ var getIn = (obj, path) => path.split(".").reduce((o, k) => o == null ? o : o[k], obj);
11684
+ var first = (theme, paths) => {
11685
+ for (const p of paths) {
11686
+ const v = getIn(theme, p);
11687
+ if (v != null && v !== "") return v;
11688
+ }
11689
+ return void 0;
11690
+ };
11691
+ var px4 = (v, fb) => v == null ? `${fb}px` : typeof v === "number" ? `${v}px` : String(v);
11692
+ function resolveToastTokens(theme) {
11693
+ const radius2 = first(theme, ["radius.md", "shape.borderRadius", "radii.md"]);
11694
+ const padX = first(theme, ["spacing.lg", "space.4", "spacing.4"]);
11695
+ const padY = first(theme, ["spacing.md", "space.3", "spacing.3"]);
11696
+ const shadow = first(theme, ["shadows.lg", "elevation.lg"]) ?? "0 8px 24px rgba(0,0,0,.03), 0 2px 8px rgba(0,0,0,.05)";
11697
+ return { radius: px4(radius2, 16), padX: px4(padX, 14), padY: px4(padY, 12), shadow: String(shadow) };
11698
+ }
11682
11699
  var hostEl = null;
11683
11700
  function ensureHost() {
11684
11701
  if (typeof document === "undefined") return;
@@ -11787,6 +11804,28 @@ function pushOutOldestIntoQueue() {
11787
11804
  store.queue.push(oldest);
11788
11805
  syncAndNotify();
11789
11806
  }
11807
+ var normalizeStatus = (s) => {
11808
+ if (s === "danger") return "error";
11809
+ const allowed = ["default", "success", "error", "warning", "info"];
11810
+ return allowed.includes(s) ? s : "default";
11811
+ };
11812
+ function statusColors(theme, s) {
11813
+ const st = normalizeStatus(s);
11814
+ const panelBg = theme.surface?.panelBg ?? "#fff";
11815
+ const panelFg = theme.text?.primary ?? "#111";
11816
+ const border = theme.surface?.border;
11817
+ if (st === "default" || st === "info") return { bg: panelBg, fg: panelFg, border };
11818
+ const on = theme.text?.onColors ?? {};
11819
+ const pick = (k, fallbackBg, fallbackFg) => ({
11820
+ bg: theme.colors?.[k] ?? theme.palette?.[k]?.[700] ?? fallbackBg,
11821
+ fg: on?.[k] ?? fallbackFg,
11822
+ border: "transparent"
11823
+ });
11824
+ if (st === "success") return pick("success", "#22C55E", "#fff");
11825
+ if (st === "warning") return pick("warning", "#F59E0B", "#fff");
11826
+ if (st === "error") return pick("error", "#EF4444", "#fff");
11827
+ return { bg: panelBg, fg: panelFg, border };
11828
+ }
11790
11829
  var toast = Object.assign(
11791
11830
  (contentOrOptions, opts) => {
11792
11831
  ensureHost();
@@ -11873,8 +11912,8 @@ var toast = Object.assign(
11873
11912
  update: (id, o) => toast({ id, ...o }),
11874
11913
  dismiss: (id) => {
11875
11914
  if (!id) {
11876
- const first = store.displayed.find((d) => !store.exiting[d.id])?.id;
11877
- if (first) toast.dismiss(first);
11915
+ const first2 = store.displayed.find((d) => !store.exiting[d.id])?.id;
11916
+ if (first2) toast.dismiss(first2);
11878
11917
  return;
11879
11918
  }
11880
11919
  clearTimer(id);
@@ -11945,6 +11984,23 @@ var toast = Object.assign(
11945
11984
  }
11946
11985
  }
11947
11986
  );
11987
+ function normalizeDismiss(show) {
11988
+ if (typeof show === "string") return show;
11989
+ if (show === true) return "always";
11990
+ if (show === false) return "never";
11991
+ return cfg.showDismiss;
11992
+ }
11993
+ function positionCss(pos) {
11994
+ const map = {
11995
+ "top-left": { top: 16, left: 16, alignItems: "flex-start" },
11996
+ "top-center": { top: 16, left: "50%", transform: "translateX(-50%)", alignItems: "center" },
11997
+ "top-right": { top: 16, right: 16, alignItems: "flex-end" },
11998
+ "bottom-left": { bottom: 16, left: 16, alignItems: "flex-start" },
11999
+ "bottom-center": { bottom: 16, left: "50%", transform: "translateX(-50%)", alignItems: "center" },
12000
+ "bottom-right": { bottom: 16, right: 16, alignItems: "flex-end" }
12001
+ };
12002
+ return map[pos];
12003
+ }
11948
12004
  var rowCss = css44({ display: "flex", alignItems: "flex-start", gap: 10 });
11949
12005
  var iconWrapCss = css44({
11950
12006
  flex: "0 0 auto",
@@ -11955,6 +12011,193 @@ var iconWrapCss = css44({
11955
12011
  });
11956
12012
  var textCss = css44({ fontSize: 14, lineHeight: 1.4, fontWeight: 500, flex: 1, minWidth: 0 });
11957
12013
  var actionRowCss = css44({ display: "flex", alignItems: "center", gap: 6, marginRight: -2 });
12014
+ function ToastHost() {
12015
+ const snap = useSyncExternalStore(store.subscribe.bind(store), () => store.snapshot, () => store.snapshot);
12016
+ const theme = usePlainframeUITheme();
12017
+ const TOK = resolveToastTokens(theme);
12018
+ const isBottom = cfg.position.startsWith("bottom");
12019
+ const list = isBottom ? snap.displayed : [...snap.displayed].reverse();
12020
+ const stackStyle = {
12021
+ position: "fixed",
12022
+ zIndex: cfg.zIndex,
12023
+ pointerEvents: "none",
12024
+ width: "100%",
12025
+ display: "flex",
12026
+ flexDirection: "column",
12027
+ ...positionCss(cfg.position),
12028
+ ...cfg.styles.stack ?? {}
12029
+ };
12030
+ return /* @__PURE__ */ jsx52("div", { className: "plainframe-ui-toast-stack", css: css44(stackStyle), children: /* @__PURE__ */ jsx52(AnimatePresence5, { initial: false, children: list.map((t, index) => {
12031
+ const from = snap.enterFrom[t.id] || "tail";
12032
+ const enterY = isBottom ? from === "head" ? -16 : 16 : from === "head" ? 16 : -16;
12033
+ const mt = index > 0 ? cfg.gutter : 0;
12034
+ const ctx = {
12035
+ toast: t,
12036
+ close: toast.dismiss,
12037
+ pause: toast.pause,
12038
+ resume: toast.resume
12039
+ };
12040
+ const { bg, fg, border } = statusColors(theme, t.status);
12041
+ const baseSurface = {
12042
+ position: "relative",
12043
+ overflow: "hidden",
12044
+ borderRadius: TOK.radius,
12045
+ boxShadow: TOK.shadow,
12046
+ padding: `${TOK.padY} calc(${TOK.padX} + 30px) ${TOK.padY} ${TOK.padX}`,
12047
+ display: "grid",
12048
+ gridTemplateColumns: "1fr auto",
12049
+ gap: 10,
12050
+ background: bg,
12051
+ color: fg,
12052
+ cursor: t.onClick ? "pointer" : "default",
12053
+ border: border ? `1px solid ${border}` : "1px solid transparent"
12054
+ };
12055
+ const extraSurface = typeof cfg.styles.surface === "function" ? cfg.styles.surface(t) : cfg.styles.surface ?? {};
12056
+ const dismissMode = normalizeDismiss(t.showDismiss);
12057
+ const modeStyles = {};
12058
+ const closeSel = "& .plainframe-ui-toast-close";
12059
+ const hoverSel = "&:hover .plainframe-ui-toast-close";
12060
+ if (dismissMode === "hover") {
12061
+ modeStyles[closeSel] = { opacity: 0, pointerEvents: "none" };
12062
+ modeStyles[hoverSel] = { opacity: 1, pointerEvents: "auto" };
12063
+ } else if (dismissMode === "always") {
12064
+ modeStyles[closeSel] = { opacity: 1, pointerEvents: "auto" };
12065
+ } else if (dismissMode === "never") {
12066
+ modeStyles[closeSel] = { display: "none" };
12067
+ }
12068
+ const wrapCss = css44({ ...baseSurface, ...extraSurface, ...modeStyles });
12069
+ const closeCss = css44({
12070
+ position: "absolute",
12071
+ top: 8,
12072
+ right: 8,
12073
+ appearance: "none",
12074
+ border: 0,
12075
+ background: "transparent",
12076
+ color: fg,
12077
+ width: 28,
12078
+ height: 28,
12079
+ borderRadius: 8,
12080
+ cursor: "pointer",
12081
+ lineHeight: 1,
12082
+ transition: "opacity .12s ease",
12083
+ display: "grid",
12084
+ placeItems: "center",
12085
+ ...cfg.styles.close ?? {}
12086
+ });
12087
+ let content;
12088
+ if (t.bare && t.render) {
12089
+ const inner = typeof t.render === "function" ? t.render(ctx) : t.render;
12090
+ content = /* @__PURE__ */ jsx52("div", { style: { pointerEvents: "auto" }, onClick: (e) => t.onClick?.(t.id, e), children: inner });
12091
+ } else if (cfg.bareRenderer && cfg.renderer) {
12092
+ const inner = typeof cfg.renderer === "function" ? cfg.renderer(ctx) : cfg.renderer;
12093
+ content = /* @__PURE__ */ jsx52("div", { style: { pointerEvents: "auto" }, onClick: (e) => t.onClick?.(t.id, e), children: inner });
12094
+ } else {
12095
+ let innerBlock;
12096
+ if (cfg.renderer) {
12097
+ innerBlock = typeof cfg.renderer === "function" ? cfg.renderer(ctx) : cfg.renderer;
12098
+ } else if (t.render && !t.bare) {
12099
+ innerBlock = typeof t.render === "function" ? t.render(ctx) : t.render;
12100
+ } else {
12101
+ innerBlock = /* @__PURE__ */ jsxs31(Fragment9, { children: [
12102
+ /* @__PURE__ */ jsxs31("div", { css: rowCss, children: [
12103
+ t.startIcon && /* @__PURE__ */ jsx52("div", { css: iconWrapCss, children: t.startIcon }),
12104
+ /* @__PURE__ */ jsx52("div", { css: textCss, children: t.content }),
12105
+ t.endIcon && /* @__PURE__ */ jsx52("div", { css: iconWrapCss, children: t.endIcon })
12106
+ ] }),
12107
+ t.action && /* @__PURE__ */ jsx52("div", { css: actionRowCss, children: t.action })
12108
+ ] });
12109
+ }
12110
+ content = /* @__PURE__ */ jsxs31("div", { css: wrapCss, onClick: (e) => t.onClick?.(t.id, e), children: [
12111
+ innerBlock,
12112
+ /* @__PURE__ */ jsx52(
12113
+ "button",
12114
+ {
12115
+ className: "plainframe-ui-toast-close",
12116
+ "aria-label": "Close",
12117
+ css: closeCss,
12118
+ onClick: (e) => {
12119
+ e.stopPropagation();
12120
+ toast.dismiss(t.id);
12121
+ },
12122
+ children: /* @__PURE__ */ jsx52(X4, { strokeWidth: 2.5, size: 14 })
12123
+ }
12124
+ )
12125
+ ] });
12126
+ }
12127
+ return /* @__PURE__ */ jsx52(
12128
+ SwipeItem,
12129
+ {
12130
+ id: t.id,
12131
+ isBottom,
12132
+ mt,
12133
+ enterY,
12134
+ width: t.width,
12135
+ pauseOnHover: t.pauseOnHover !== false,
12136
+ children: content
12137
+ },
12138
+ t.id
12139
+ );
12140
+ }) }) });
12141
+ }
12142
+ function SwipeItem(props) {
12143
+ const { id, isBottom, mt, enterY, width, pauseOnHover, children } = props;
12144
+ const controls = useAnimationControls();
12145
+ useEffect14(() => {
12146
+ controls.start({ opacity: 1, y: 0, height: "auto", x: 0, transition: ENTER_SPRING });
12147
+ }, [controls]);
12148
+ const itemStyle = {
12149
+ pointerEvents: "auto",
12150
+ willChange: "transform, opacity, height, margin, scale, width, max-width",
12151
+ marginTop: mt,
12152
+ width: "100%",
12153
+ maxWidth: width != null ? typeof width === "number" ? `${width}px` : width : "none",
12154
+ ...cfg.styles.item ?? {}
12155
+ };
12156
+ return /* @__PURE__ */ jsx52(
12157
+ motion5.div,
12158
+ {
12159
+ layout: true,
12160
+ className: "plainframe-ui-toast-item",
12161
+ css: css44(itemStyle),
12162
+ initial: { opacity: 0, y: enterY, height: "auto", x: 0 },
12163
+ animate: controls,
12164
+ exit: {
12165
+ opacity: 0,
12166
+ y: isBottom ? 6 : -6,
12167
+ height: 0,
12168
+ marginTop: 0,
12169
+ transition: { type: "tween", ease: "easeInOut", duration: 0.14 }
12170
+ },
12171
+ drag: "x",
12172
+ dragElastic: 0.2,
12173
+ dragMomentum: true,
12174
+ whileDrag: { scale: 0.98, opacity: 0.95 },
12175
+ onDragEnd: (_, info) => {
12176
+ const dist = Math.abs(info.offset.x);
12177
+ const velo = Math.abs(info.velocity.x);
12178
+ const shouldFling = dist > 60 || velo > 600;
12179
+ if (!shouldFling) {
12180
+ controls.start({ x: 0, opacity: 1, transition: { type: "spring", stiffness: 700, damping: 40 } });
12181
+ return;
12182
+ }
12183
+ const dir = info.offset.x !== 0 ? Math.sign(info.offset.x) : Math.sign(info.velocity.x || 1);
12184
+ const targetX = dir * (window.innerWidth + 160);
12185
+ controls.start({
12186
+ x: targetX,
12187
+ opacity: 0.9,
12188
+ transition: { type: "spring", stiffness: 280, damping: 24, velocity: info.velocity.x / 10 }
12189
+ }).then(() => toast.dismiss(id));
12190
+ },
12191
+ onMouseEnter: pauseOnHover ? () => toast.pause(id) : void 0,
12192
+ onMouseLeave: pauseOnHover ? () => toast.resume(id) : void 0,
12193
+ children
12194
+ }
12195
+ );
12196
+ }
12197
+ function ToastViewport() {
12198
+ ensureHost();
12199
+ return hostEl ? createPortal(/* @__PURE__ */ jsx52(ToastHost, {}), hostEl) : null;
12200
+ }
11958
12201
 
11959
12202
  // src/components/Tooltip.tsx
11960
12203
  import React47, {
@@ -12278,7 +12521,12 @@ export {
12278
12521
  Button,
12279
12522
  ButtonGroup,
12280
12523
  Card,
12524
+ CardContent,
12525
+ CardDescription,
12526
+ CardEnd,
12281
12527
  CardGroup,
12528
+ CardStart,
12529
+ CardTitle,
12282
12530
  Checkbox,
12283
12531
  Chip,
12284
12532
  CodeField,
@@ -12339,6 +12587,7 @@ export {
12339
12587
  TextArea,
12340
12588
  TextField,
12341
12589
  ThemeProvider,
12590
+ ToastViewport,
12342
12591
  Tooltip,
12343
12592
  TooltipContent,
12344
12593
  TooltipTrigger,