@seed-design/react 1.2.6 → 1.2.8

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.
Files changed (44) hide show
  1. package/lib/components/ContentPlaceholder/ContentPlaceholder.cjs +58 -0
  2. package/lib/components/ContentPlaceholder/ContentPlaceholder.d.ts +10 -0
  3. package/lib/components/ContentPlaceholder/ContentPlaceholder.d.ts.map +1 -0
  4. package/lib/components/ContentPlaceholder/ContentPlaceholder.js +35 -0
  5. package/lib/components/ContentPlaceholder/ContentPlaceholder.namespace.cjs +10 -0
  6. package/lib/components/ContentPlaceholder/ContentPlaceholder.namespace.d.ts +2 -0
  7. package/lib/components/ContentPlaceholder/ContentPlaceholder.namespace.d.ts.map +1 -0
  8. package/lib/components/ContentPlaceholder/ContentPlaceholder.namespace.js +1 -0
  9. package/lib/components/ContentPlaceholder/index.cjs +12 -0
  10. package/lib/components/ContentPlaceholder/index.d.ts +3 -0
  11. package/lib/components/ContentPlaceholder/index.d.ts.map +1 -0
  12. package/lib/components/ContentPlaceholder/index.js +3 -0
  13. package/lib/components/ContentPlaceholder/presets.cjs +78 -0
  14. package/lib/components/ContentPlaceholder/presets.d.ts +3 -0
  15. package/lib/components/ContentPlaceholder/presets.d.ts.map +1 -0
  16. package/lib/components/ContentPlaceholder/presets.js +74 -0
  17. package/lib/components/ImageFrame/ImageFrame.cjs +65 -36
  18. package/lib/components/ImageFrame/ImageFrame.d.ts +0 -4
  19. package/lib/components/ImageFrame/ImageFrame.d.ts.map +1 -1
  20. package/lib/components/ImageFrame/ImageFrame.js +66 -37
  21. package/lib/components/ImageFrame/ImageFrame.test.d.ts +2 -0
  22. package/lib/components/ImageFrame/ImageFrame.test.d.ts.map +1 -0
  23. package/lib/components/TagGroup/TagGroup.cjs +1 -1
  24. package/lib/components/TagGroup/TagGroup.d.ts.map +1 -1
  25. package/lib/components/TagGroup/TagGroup.js +1 -1
  26. package/lib/components/index.cjs +5 -0
  27. package/lib/components/index.d.ts +1 -0
  28. package/lib/components/index.d.ts.map +1 -1
  29. package/lib/components/index.js +3 -0
  30. package/lib/index.cjs +5 -0
  31. package/lib/index.js +3 -0
  32. package/lib/utils/styled.cjs +5 -1
  33. package/lib/utils/styled.d.ts.map +1 -1
  34. package/lib/utils/styled.js +5 -1
  35. package/package.json +2 -2
  36. package/src/components/ContentPlaceholder/ContentPlaceholder.namespace.ts +6 -0
  37. package/src/components/ContentPlaceholder/ContentPlaceholder.tsx +59 -0
  38. package/src/components/ContentPlaceholder/index.ts +8 -0
  39. package/src/components/ContentPlaceholder/presets.tsx +96 -0
  40. package/src/components/ImageFrame/ImageFrame.test.tsx +57 -0
  41. package/src/components/ImageFrame/ImageFrame.tsx +63 -28
  42. package/src/components/TagGroup/TagGroup.tsx +4 -1
  43. package/src/components/index.ts +1 -0
  44. package/src/utils/styled.tsx +6 -1
@@ -12,14 +12,19 @@ import {
12
12
  } from "@seed-design/css/recipes/image-frame-indicator";
13
13
  import { imageFrameReactionButton } from "@seed-design/css/recipes/image-frame-reaction-button";
14
14
  import { imageFrameFloater as floaterVars } from "@seed-design/css/vars/component";
15
+ import { mergeProps } from "@seed-design/dom-utils";
15
16
  import { Image } from "@seed-design/react-image";
16
- import { Toggle as TogglePrimitive } from "@seed-design/react-toggle";
17
+ import { Toggle as TogglePrimitive, useToggleContext } from "@seed-design/react-toggle";
17
18
  import clsx from "clsx";
18
19
  import * as React from "react";
20
+ import { createSlotRecipeContext } from "../../utils/createSlotRecipeContext";
19
21
  import { AspectRatio, type AspectRatioProps } from "../AspectRatio/AspectRatio";
20
22
  import { Badge, type BadgeProps } from "../Badge/Badge";
21
23
  import { Float, type FloatProps } from "../Float/Float";
22
24
  import { Icon } from "../Icon/Icon";
25
+ import { InternalIcon } from "../private/Icon";
26
+
27
+ ////////////////////////////////////////////////////////////////////////////////////
23
28
 
24
29
  export interface ImageFrameProps
25
30
  extends Omit<AspectRatioProps, "children">,
@@ -41,10 +46,6 @@ export interface ImageFrameProps
41
46
  srcSet?: string;
42
47
  onLoad?: React.ReactEventHandler<HTMLImageElement>;
43
48
  onError?: React.ReactEventHandler<HTMLImageElement>;
44
- /**
45
- * Overlay elements to be rendered on top of the image.
46
- * Use ImageFrameFloater to position them.
47
- */
48
49
  children?: React.ReactNode;
49
50
  }
50
51
 
@@ -52,8 +53,6 @@ export const ImageFrame = React.forwardRef<HTMLDivElement, ImageFrameProps>(
52
53
  (
53
54
  {
54
55
  ratio = 4 / 3,
55
- stroke,
56
- rounded,
57
56
  src,
58
57
  alt,
59
58
  fallback,
@@ -71,10 +70,14 @@ export const ImageFrame = React.forwardRef<HTMLDivElement, ImageFrameProps>(
71
70
  },
72
71
  ref,
73
72
  ) => {
73
+ const [variantProps, restProps] = imageFrameRecipe.splitVariantProps(rest);
74
+ const classNames = imageFrameRecipe(variantProps);
75
+
74
76
  return (
75
- <AspectRatio ref={ref} ratio={ratio} className={className} {...rest}>
76
- <Image.Root className={imageFrameRecipe({ stroke, rounded })}>
77
+ <AspectRatio ref={ref} ratio={ratio} className={className} {...restProps}>
78
+ <Image.Root className={classNames.root}>
77
79
  <Image.Content
80
+ className={classNames.content}
78
81
  src={src}
79
82
  alt={alt}
80
83
  loading={loading}
@@ -86,7 +89,7 @@ export const ImageFrame = React.forwardRef<HTMLDivElement, ImageFrameProps>(
86
89
  onLoad={onLoad}
87
90
  onError={onError}
88
91
  />
89
- {fallback && <Image.Fallback>{fallback}</Image.Fallback>}
92
+ {fallback && <Image.Fallback className={classNames.fallback}>{fallback}</Image.Fallback>}
90
93
  {children}
91
94
  </Image.Root>
92
95
  </AspectRatio>
@@ -175,24 +178,33 @@ ImageFrameIndicator.displayName = "ImageFrameIndicator";
175
178
 
176
179
  ////////////////////////////////////////////////////////////////////////////////////
177
180
 
181
+ const {
182
+ ClassNamesProvider: ImageFrameReactionButtonClassNamesProvider,
183
+ useClassNames: useImageFrameReactionButtonClassNames,
184
+ } = createSlotRecipeContext(imageFrameReactionButton);
185
+
186
+ ////////////////////////////////////////////////////////////////////////////////////
187
+
178
188
  const HeartFillPath =
179
189
  "M15.5452 10C11.7873 10 9.25 12.9484 9.25 16.6267C9.25 19.8754 11.1219 22.0952 13.1877 23.969C13.7807 24.5069 14.4438 25.0617 15.095 25.6066C15.5434 25.9817 15.9862 26.3522 16.3967 26.7093C17.4501 27.6257 18.4191 28.557 19.1995 29.5994C19.3886 29.8518 19.6856 30.0003 20.001 30C20.3163 29.9997 20.6131 29.8507 20.8016 29.5979C21.5785 28.5562 22.5453 27.6253 23.598 26.7091C24.0105 26.35 24.4568 25.9766 24.9089 25.5984C25.5573 25.0559 26.2176 24.5035 26.807 23.9693C28.8739 22.096 30.75 19.8761 30.75 16.6267C30.75 12.9484 28.2127 10 24.4548 10C22.6365 10 21.1002 11.0545 20 12.4906C18.8998 11.0545 17.3635 10 15.5452 10Z";
180
190
 
181
191
  const HeartOutlineStrokePath =
182
192
  "M15.5452 12C13.0342 12 11.25 13.905 11.25 16.6267C11.25 18.9912 12.5659 20.7048 14.5314 22.4876C15.1157 23.0176 15.7038 23.5087 16.3148 24.019C16.7646 24.3946 17.2269 24.7807 17.7093 25.2003C18.4947 25.8835 19.2814 26.6141 19.9988 27.4215C20.7144 26.614 21.5001 25.8836 22.2849 25.2005C22.7714 24.7771 23.2368 24.3885 23.6895 24.0105C24.2967 23.5035 24.8813 23.0154 25.4639 22.4874C27.4317 20.704 28.75 18.9906 28.75 16.6267C28.75 13.905 26.9658 12 24.4548 12C23.069 12 21.747 12.8325 20.8919 14.5189C20.7215 14.8549 20.3768 15.0667 20 15.0667C19.6233 15.0667 19.2785 14.8549 19.1081 14.5189C18.2531 12.8325 16.931 12 15.5452 12ZM9.25 16.6267C9.25 12.9484 11.7873 10 15.5452 10C17.3146 10 18.8683 10.8364 20 12.2306C21.1317 10.8364 22.6854 10 24.4548 10C28.2127 10 30.75 12.9484 30.75 16.6267C30.75 19.8761 28.8739 22.096 26.807 23.9693C26.2176 24.5035 25.5573 25.0559 24.9089 25.5984C24.4568 25.9766 24.0105 26.35 23.598 26.7091C22.5453 27.6253 21.5785 28.5562 20.8016 29.5979C20.6131 29.8507 20.3163 29.9997 20.001 30C19.6856 30.0003 19.3886 29.8518 19.1995 29.5994C18.4191 28.557 17.4501 27.6257 16.3967 26.7093C15.9862 26.3522 15.5434 25.9817 15.095 25.6066C14.4438 25.0617 13.7807 24.5069 13.1877 23.969C11.1219 22.0952 9.25 19.8754 9.25 16.6267Z";
183
193
 
184
- const UnselectedHeartIcon = () => (
185
- <svg viewBox="8 9 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
186
- <path d={HeartFillPath} fill="black" fillOpacity="0.063" />
187
- <path fillRule="evenodd" clipRule="evenodd" d={HeartOutlineStrokePath} fill="white" />
188
- </svg>
189
- );
190
-
191
- const SelectedHeartIcon = () => {
194
+ const HeartFillSvg = (props: React.SVGAttributes<SVGSVGElement>) => {
192
195
  const id = React.useId();
193
196
  const gradientId = `seed-heart-gradient${id.replace(/:/g, "")}`;
197
+
194
198
  return (
195
- <svg viewBox="8 9 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
199
+ <svg
200
+ width="100%"
201
+ height="100%"
202
+ viewBox="8 9 24 24"
203
+ fill="none"
204
+ xmlns="http://www.w3.org/2000/svg"
205
+ aria-hidden="true"
206
+ {...props}
207
+ >
196
208
  <path d={HeartFillPath} fill={`url(#${gradientId})`} />
197
209
  <defs>
198
210
  <linearGradient
@@ -211,22 +223,45 @@ const SelectedHeartIcon = () => {
211
223
  );
212
224
  };
213
225
 
226
+ const HeartLineSvg = (props: React.SVGAttributes<SVGSVGElement>) => (
227
+ <svg
228
+ width="100%"
229
+ height="100%"
230
+ viewBox="8 9 24 24"
231
+ fill="none"
232
+ xmlns="http://www.w3.org/2000/svg"
233
+ aria-hidden="true"
234
+ {...props}
235
+ >
236
+ <path fillRule="evenodd" clipRule="evenodd" d={HeartOutlineStrokePath} fill="currentColor" />
237
+ </svg>
238
+ );
239
+
214
240
  export interface ImageFrameReactionButtonProps
215
241
  extends Omit<TogglePrimitive.RootProps, "children"> {}
216
242
 
243
+ const ReactionButtonIcon = () => {
244
+ const { pressed, stateProps } = useToggleContext();
245
+ const classNames = useImageFrameReactionButtonClassNames();
246
+ const iconProps = mergeProps(stateProps, {
247
+ className: pressed ? classNames.fillIcon : classNames.lineIcon,
248
+ } as React.HTMLAttributes<HTMLElement>);
249
+
250
+ return <InternalIcon svg={pressed ? <HeartFillSvg /> : <HeartLineSvg />} {...iconProps} />;
251
+ };
252
+
217
253
  export const ImageFrameReactionButton = React.forwardRef<
218
254
  HTMLButtonElement,
219
255
  ImageFrameReactionButtonProps
220
- >(({ className, pressed, ...rest }, ref) => {
256
+ >(({ className, ...rest }, ref) => {
257
+ const classNames = imageFrameReactionButton();
258
+
221
259
  return (
222
- <TogglePrimitive.Root
223
- ref={ref}
224
- className={clsx(imageFrameReactionButton(), className)}
225
- pressed={pressed}
226
- {...rest}
227
- >
228
- <Icon svg={pressed ? <SelectedHeartIcon /> : <UnselectedHeartIcon />} />
229
- </TogglePrimitive.Root>
260
+ <ImageFrameReactionButtonClassNamesProvider value={classNames}>
261
+ <TogglePrimitive.Root ref={ref} className={clsx(classNames.root, className)} {...rest}>
262
+ <ReactionButtonIcon />
263
+ </TogglePrimitive.Root>
264
+ </ImageFrameReactionButtonClassNamesProvider>
230
265
  );
231
266
  });
232
267
 
@@ -31,7 +31,10 @@ export const TagGroupRoot = forwardRef<HTMLSpanElement, TagGroupRootProps>(
31
31
  <PropsProvider value={tagGroupItemVariantProps}>
32
32
  <Primitive.span ref={ref} className={clsx(classNames.root, className)} {...otherProps}>
33
33
  {Children.toArray(children)
34
- .filter((child) => child !== null && child !== undefined)
34
+ // putting something other than TagGroupItem in TagGroupRoot is not a good idea,
35
+ // but we shouldn't throw an error for it either
36
+ // thus .filter(React.isValidElement) is too strict here
37
+ .filter(Boolean)
35
38
  .map((child, index) => (
36
39
  // biome-ignore lint/suspicious/noArrayIndexKey: those fragments won't change order
37
40
  <Fragment key={index}>
@@ -14,6 +14,7 @@ export * from "./Chip";
14
14
  export * from "./ChipTabs";
15
15
  export * from "./Columns";
16
16
  export * from "./ConsistentWidth";
17
+ export * from "./ContentPlaceholder";
17
18
  export * from "./ContextualFloatingButton";
18
19
  export * from "./ControlChip";
19
20
  export * from "./Count";
@@ -671,7 +671,12 @@ export function useStyleProps<T extends UseStyleProps>(
671
671
  "--seed-box-background--active": handleColor(_active?.bg ?? _active?.background),
672
672
  ...style,
673
673
  } as React.CSSProperties,
674
- restProps,
674
+ restProps: {
675
+ ...restProps,
676
+
677
+ // see global.ts to understand why we need this
678
+ ...((_active?.bg != null || _active?.background != null) && { "data-has-active-bg": "" }),
679
+ },
675
680
  };
676
681
  }
677
682