@particle-academy/react-fancy 5.1.0 → 5.3.0

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.cts CHANGED
@@ -843,8 +843,18 @@ declare function Portal({ children, container }: PortalProps): react.ReactPortal
843
843
  interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
844
844
  /** Which heading element to render */
845
845
  as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
846
- /** Text size */
847
- size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
846
+ /**
847
+ * Text size, on a SEMANTIC ramp the names are steps on this scale, not
848
+ * Tailwind class names. `xl` is `text-2xl` and `2xl` is `text-4xl`, and that
849
+ * offset has been true since the component shipped, so the display steps
850
+ * below continue the same ramp rather than re-basing it and silently
851
+ * resizing every existing heading.
852
+ *
853
+ * `3xl`–`7xl` are DISPLAY sizes: hero type, "typography at maximum volume".
854
+ * They carry tighter tracking, because letter-spacing tuned for body-adjacent
855
+ * headings reads loose and unset once type gets big.
856
+ */
857
+ size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl" | "7xl";
848
858
  /** Font weight */
849
859
  weight?: "normal" | "medium" | "semibold" | "bold";
850
860
  }
@@ -1005,6 +1015,34 @@ declare const Profile: react.ForwardRefExoticComponent<ProfileProps & react.RefA
1005
1015
  interface CardProps extends HTMLAttributes<HTMLDivElement> {
1006
1016
  variant?: "outlined" | "elevated" | "flat";
1007
1017
  padding?: "none" | "sm" | "md" | "lg";
1018
+ /**
1019
+ * Card is a link or a grid tile: adds the hover lift + border/shadow
1020
+ * response, and clips children to the rounded corners so a `Card.Media`
1021
+ * sits flush.
1022
+ */
1023
+ interactive?: boolean;
1024
+ }
1025
+ interface CardMediaProps extends HTMLAttributes<HTMLDivElement> {
1026
+ /** Image URL. Omit for a pure colour/gradient tile. */
1027
+ src?: string;
1028
+ alt?: string;
1029
+ /** CSS `aspect-ratio`. Default `"16/9"`. Ignored when `height` is set. */
1030
+ ratio?: string;
1031
+ /** Fixed height instead of an aspect ratio. */
1032
+ height?: number | string;
1033
+ /**
1034
+ * Shown UNDER the image — while it loads, and permanently if it never
1035
+ * arrives. Any CSS background value, so a gradient works.
1036
+ */
1037
+ background?: string;
1038
+ /** `object-position` for the image. Default `"center"`. */
1039
+ objectPosition?: string;
1040
+ loading?: "lazy" | "eager";
1041
+ /** Slots pinned to the media's corners — a number chip, a status pill. */
1042
+ topLeft?: ReactNode;
1043
+ topRight?: ReactNode;
1044
+ bottomLeft?: ReactNode;
1045
+ bottomRight?: ReactNode;
1008
1046
  }
1009
1047
  interface CardHeaderProps extends HTMLAttributes<HTMLDivElement> {
1010
1048
  }
@@ -1014,6 +1052,7 @@ interface CardFooterProps extends HTMLAttributes<HTMLDivElement> {
1014
1052
  }
1015
1053
 
1016
1054
  declare const Card: react.ForwardRefExoticComponent<CardProps & react.RefAttributes<HTMLDivElement>> & {
1055
+ Media: react.ForwardRefExoticComponent<CardMediaProps & react.RefAttributes<HTMLDivElement>>;
1017
1056
  Header: react.ForwardRefExoticComponent<CardHeaderProps & react.RefAttributes<HTMLDivElement>>;
1018
1057
  Body: react.ForwardRefExoticComponent<CardBodyProps & react.RefAttributes<HTMLDivElement>>;
1019
1058
  Footer: react.ForwardRefExoticComponent<CardFooterProps & react.RefAttributes<HTMLDivElement>>;
package/dist/index.d.ts CHANGED
@@ -843,8 +843,18 @@ declare function Portal({ children, container }: PortalProps): react.ReactPortal
843
843
  interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
844
844
  /** Which heading element to render */
845
845
  as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
846
- /** Text size */
847
- size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
846
+ /**
847
+ * Text size, on a SEMANTIC ramp the names are steps on this scale, not
848
+ * Tailwind class names. `xl` is `text-2xl` and `2xl` is `text-4xl`, and that
849
+ * offset has been true since the component shipped, so the display steps
850
+ * below continue the same ramp rather than re-basing it and silently
851
+ * resizing every existing heading.
852
+ *
853
+ * `3xl`–`7xl` are DISPLAY sizes: hero type, "typography at maximum volume".
854
+ * They carry tighter tracking, because letter-spacing tuned for body-adjacent
855
+ * headings reads loose and unset once type gets big.
856
+ */
857
+ size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl" | "7xl";
848
858
  /** Font weight */
849
859
  weight?: "normal" | "medium" | "semibold" | "bold";
850
860
  }
@@ -1005,6 +1015,34 @@ declare const Profile: react.ForwardRefExoticComponent<ProfileProps & react.RefA
1005
1015
  interface CardProps extends HTMLAttributes<HTMLDivElement> {
1006
1016
  variant?: "outlined" | "elevated" | "flat";
1007
1017
  padding?: "none" | "sm" | "md" | "lg";
1018
+ /**
1019
+ * Card is a link or a grid tile: adds the hover lift + border/shadow
1020
+ * response, and clips children to the rounded corners so a `Card.Media`
1021
+ * sits flush.
1022
+ */
1023
+ interactive?: boolean;
1024
+ }
1025
+ interface CardMediaProps extends HTMLAttributes<HTMLDivElement> {
1026
+ /** Image URL. Omit for a pure colour/gradient tile. */
1027
+ src?: string;
1028
+ alt?: string;
1029
+ /** CSS `aspect-ratio`. Default `"16/9"`. Ignored when `height` is set. */
1030
+ ratio?: string;
1031
+ /** Fixed height instead of an aspect ratio. */
1032
+ height?: number | string;
1033
+ /**
1034
+ * Shown UNDER the image — while it loads, and permanently if it never
1035
+ * arrives. Any CSS background value, so a gradient works.
1036
+ */
1037
+ background?: string;
1038
+ /** `object-position` for the image. Default `"center"`. */
1039
+ objectPosition?: string;
1040
+ loading?: "lazy" | "eager";
1041
+ /** Slots pinned to the media's corners — a number chip, a status pill. */
1042
+ topLeft?: ReactNode;
1043
+ topRight?: ReactNode;
1044
+ bottomLeft?: ReactNode;
1045
+ bottomRight?: ReactNode;
1008
1046
  }
1009
1047
  interface CardHeaderProps extends HTMLAttributes<HTMLDivElement> {
1010
1048
  }
@@ -1014,6 +1052,7 @@ interface CardFooterProps extends HTMLAttributes<HTMLDivElement> {
1014
1052
  }
1015
1053
 
1016
1054
  declare const Card: react.ForwardRefExoticComponent<CardProps & react.RefAttributes<HTMLDivElement>> & {
1055
+ Media: react.ForwardRefExoticComponent<CardMediaProps & react.RefAttributes<HTMLDivElement>>;
1017
1056
  Header: react.ForwardRefExoticComponent<CardHeaderProps & react.RefAttributes<HTMLDivElement>>;
1018
1057
  Body: react.ForwardRefExoticComponent<CardBodyProps & react.RefAttributes<HTMLDivElement>>;
1019
1058
  Footer: react.ForwardRefExoticComponent<CardFooterProps & react.RefAttributes<HTMLDivElement>>;
package/dist/index.js CHANGED
@@ -6222,7 +6222,20 @@ var sizeClasses3 = {
6222
6222
  md: "text-base",
6223
6223
  lg: "text-lg",
6224
6224
  xl: "text-2xl",
6225
- "2xl": "text-4xl"
6225
+ "2xl": "text-4xl",
6226
+ // Display steps. Each is the next Tailwind size up, continuing the ramp.
6227
+ "3xl": "text-5xl",
6228
+ "4xl": "text-6xl",
6229
+ "5xl": "text-7xl",
6230
+ "6xl": "text-8xl",
6231
+ "7xl": "text-9xl"
6232
+ };
6233
+ var trackingClasses = {
6234
+ "3xl": "tracking-tight",
6235
+ "4xl": "tracking-tight",
6236
+ "5xl": "tracking-tighter",
6237
+ "6xl": "tracking-tighter",
6238
+ "7xl": "tracking-tighter"
6226
6239
  };
6227
6240
  var weightClasses = {
6228
6241
  normal: "font-normal",
@@ -6247,6 +6260,7 @@ var Heading = forwardRef(
6247
6260
  className: cn(
6248
6261
  "text-zinc-900 dark:text-zinc-100",
6249
6262
  sizeClasses3[size],
6263
+ trackingClasses[size],
6250
6264
  weightClasses[weight],
6251
6265
  className
6252
6266
  ),
@@ -7026,6 +7040,66 @@ var CardFooter = forwardRef(
7026
7040
  }
7027
7041
  );
7028
7042
  CardFooter.displayName = "CardFooter";
7043
+ var CardMedia = forwardRef(
7044
+ ({
7045
+ src,
7046
+ alt = "",
7047
+ ratio = "16/9",
7048
+ height,
7049
+ background,
7050
+ objectPosition = "center",
7051
+ loading = "lazy",
7052
+ topLeft,
7053
+ topRight,
7054
+ bottomLeft,
7055
+ bottomRight,
7056
+ className,
7057
+ style,
7058
+ children,
7059
+ ...props
7060
+ }, ref) => {
7061
+ return /* @__PURE__ */ jsxs(
7062
+ "div",
7063
+ {
7064
+ ref,
7065
+ "data-react-fancy-card-media": "",
7066
+ className: cn(
7067
+ "relative overflow-hidden rounded-t-lg",
7068
+ // Card's `padding` prop pads EVERY direct div child
7069
+ // (`[&>div]:px-4 …`), which would inset the media and break the
7070
+ // flush-to-the-edge look every caller wants. `!` wins regardless of
7071
+ // stylesheet order, which plain `p-0` would not.
7072
+ "!px-0 !py-0",
7073
+ className
7074
+ ),
7075
+ style: {
7076
+ ...height === void 0 ? { aspectRatio: ratio } : { height },
7077
+ ...background ? { background } : null,
7078
+ ...style
7079
+ },
7080
+ ...props,
7081
+ children: [
7082
+ src ? /* @__PURE__ */ jsx(
7083
+ "img",
7084
+ {
7085
+ src,
7086
+ alt,
7087
+ loading,
7088
+ className: "absolute inset-0 h-full w-full object-cover",
7089
+ style: { objectPosition }
7090
+ }
7091
+ ) : null,
7092
+ children,
7093
+ topLeft ? /* @__PURE__ */ jsx("span", { className: "absolute left-2 top-2 z-10", children: topLeft }) : null,
7094
+ topRight ? /* @__PURE__ */ jsx("span", { className: "absolute right-2 top-2 z-10", children: topRight }) : null,
7095
+ bottomLeft ? /* @__PURE__ */ jsx("span", { className: "absolute bottom-2 left-2 z-10", children: bottomLeft }) : null,
7096
+ bottomRight ? /* @__PURE__ */ jsx("span", { className: "absolute bottom-2 right-2 z-10", children: bottomRight }) : null
7097
+ ]
7098
+ }
7099
+ );
7100
+ }
7101
+ );
7102
+ CardMedia.displayName = "CardMedia";
7029
7103
  var variantClasses = {
7030
7104
  outlined: "border border-zinc-200 dark:border-zinc-700",
7031
7105
  elevated: "shadow-md border border-zinc-100 dark:border-zinc-800",
@@ -7041,6 +7115,7 @@ var CardRoot = forwardRef(
7041
7115
  ({
7042
7116
  variant = "outlined",
7043
7117
  padding = "md",
7118
+ interactive = false,
7044
7119
  className,
7045
7120
  children,
7046
7121
  ...props
@@ -7053,6 +7128,10 @@ var CardRoot = forwardRef(
7053
7128
  className: cn(
7054
7129
  "rounded-lg bg-white dark:bg-zinc-900",
7055
7130
  variantClasses[variant],
7131
+ // `overflow-hidden` is part of `interactive` rather than always-on:
7132
+ // clipping unconditionally would cut off popovers and dropdowns that
7133
+ // legitimately overflow a static card.
7134
+ interactive && "overflow-hidden transition hover:-translate-y-0.5 hover:shadow-lg hover:border-zinc-300 dark:hover:border-zinc-600",
7056
7135
  paddingClasses[padding],
7057
7136
  className
7058
7137
  ),
@@ -7064,6 +7143,7 @@ var CardRoot = forwardRef(
7064
7143
  );
7065
7144
  CardRoot.displayName = "Card";
7066
7145
  var Card = Object.assign(CardRoot, {
7146
+ Media: CardMedia,
7067
7147
  Header: CardHeader,
7068
7148
  Body: CardBody,
7069
7149
  Footer: CardFooter