@discuss-ds/ui 0.8.2 → 0.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/CHANGELOG.md +12 -0
- package/dist/index.cjs +49 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +48 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -586,7 +586,7 @@ interface MediaInfoProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'tit
|
|
|
586
586
|
}
|
|
587
587
|
declare function MediaInfo({ name, details, onRemove, removeLabel, large, className, ...props }: MediaInfoProps): React.JSX.Element;
|
|
588
588
|
interface ImagePreviewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
589
|
-
/** The image (an `<img>`
|
|
589
|
+
/** The image (an `<img>`). The preview area is as tall as the image at full width, up to 336px. Leave empty for the fixed-height placeholder fill. */
|
|
590
590
|
children?: React.ReactNode;
|
|
591
591
|
name: string;
|
|
592
592
|
details?: string[];
|
|
@@ -803,6 +803,10 @@ interface StimulusCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, '
|
|
|
803
803
|
onCaptionChange?: (caption: string) => void;
|
|
804
804
|
/** Editor mode: placeholder for an empty caption. */
|
|
805
805
|
captionPlaceholder?: string;
|
|
806
|
+
/** Editor mode: caption length limit. Also what the counter counts against. */
|
|
807
|
+
maxLength?: number;
|
|
808
|
+
/** Editor mode: shows the "n/2000 characters" counter under the caption (it counts live while typing). Defaults to `true`; needs `maxLength`. */
|
|
809
|
+
showCounter?: boolean;
|
|
806
810
|
/** Shows the trash button. */
|
|
807
811
|
onRemove?: () => void;
|
|
808
812
|
/** Accessible name of the trash button. Defaults to "Remove stimulus". */
|
package/dist/index.d.ts
CHANGED
|
@@ -586,7 +586,7 @@ interface MediaInfoProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'tit
|
|
|
586
586
|
}
|
|
587
587
|
declare function MediaInfo({ name, details, onRemove, removeLabel, large, className, ...props }: MediaInfoProps): React.JSX.Element;
|
|
588
588
|
interface ImagePreviewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
589
|
-
/** The image (an `<img>`
|
|
589
|
+
/** The image (an `<img>`). The preview area is as tall as the image at full width, up to 336px. Leave empty for the fixed-height placeholder fill. */
|
|
590
590
|
children?: React.ReactNode;
|
|
591
591
|
name: string;
|
|
592
592
|
details?: string[];
|
|
@@ -803,6 +803,10 @@ interface StimulusCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, '
|
|
|
803
803
|
onCaptionChange?: (caption: string) => void;
|
|
804
804
|
/** Editor mode: placeholder for an empty caption. */
|
|
805
805
|
captionPlaceholder?: string;
|
|
806
|
+
/** Editor mode: caption length limit. Also what the counter counts against. */
|
|
807
|
+
maxLength?: number;
|
|
808
|
+
/** Editor mode: shows the "n/2000 characters" counter under the caption (it counts live while typing). Defaults to `true`; needs `maxLength`. */
|
|
809
|
+
showCounter?: boolean;
|
|
806
810
|
/** Shows the trash button. */
|
|
807
811
|
onRemove?: () => void;
|
|
808
812
|
/** Accessible name of the trash button. Defaults to "Remove stimulus". */
|
package/dist/index.js
CHANGED
|
@@ -2249,7 +2249,17 @@ function MediaInfo({ name, details, onRemove, removeLabel, large, className, ...
|
|
|
2249
2249
|
}
|
|
2250
2250
|
var ImagePreview = React37.forwardRef(
|
|
2251
2251
|
({ className, children, name, details, onRemove, ...props }, ref) => /* @__PURE__ */ jsxs27("div", { ref, className: cn("flex w-full flex-col overflow-hidden rounded-lg border border-border", className), ...props, children: [
|
|
2252
|
-
/* @__PURE__ */ jsx38(
|
|
2252
|
+
/* @__PURE__ */ jsx38(
|
|
2253
|
+
"div",
|
|
2254
|
+
{
|
|
2255
|
+
className: cn(
|
|
2256
|
+
"flex w-full items-center justify-center bg-accent-soft",
|
|
2257
|
+
// With an image the area hugs it (full width, its own height, at most 336px tall); the empty placeholder keeps the fixed height.
|
|
2258
|
+
children ? "[&>img]:block [&>img]:h-auto [&>img]:max-h-84 [&>img]:w-full [&>img]:object-contain" : "h-84"
|
|
2259
|
+
),
|
|
2260
|
+
children
|
|
2261
|
+
}
|
|
2262
|
+
),
|
|
2253
2263
|
/* @__PURE__ */ jsx38(MediaInfo, { name, details, onRemove, large: true })
|
|
2254
2264
|
] })
|
|
2255
2265
|
);
|
|
@@ -3052,6 +3062,8 @@ RatingScale.displayName = "RatingScale";
|
|
|
3052
3062
|
import * as React47 from "react";
|
|
3053
3063
|
import { Image as ImageIcon2, ImageBroken, Trash as Trash5 } from "@phosphor-icons/react";
|
|
3054
3064
|
import { jsx as jsx48, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
3065
|
+
var MIN_THUMBNAIL = 80;
|
|
3066
|
+
var MAX_THUMBNAIL = 240;
|
|
3055
3067
|
var StimulusCard = React47.forwardRef(
|
|
3056
3068
|
({
|
|
3057
3069
|
className,
|
|
@@ -3063,6 +3075,8 @@ var StimulusCard = React47.forwardRef(
|
|
|
3063
3075
|
caption,
|
|
3064
3076
|
onCaptionChange,
|
|
3065
3077
|
captionPlaceholder = "Click to write what the AI moderator says",
|
|
3078
|
+
maxLength,
|
|
3079
|
+
showCounter = true,
|
|
3066
3080
|
onRemove,
|
|
3067
3081
|
removeLabel = "Remove stimulus",
|
|
3068
3082
|
...props
|
|
@@ -3070,27 +3084,44 @@ var StimulusCard = React47.forwardRef(
|
|
|
3070
3084
|
const [failedSrc, setFailedSrc] = React47.useState();
|
|
3071
3085
|
const error = status === "error" || thumbnail !== void 0 && failedSrc === thumbnail;
|
|
3072
3086
|
const showImage = thumbnail !== void 0 && !error;
|
|
3087
|
+
const [draft, setDraft] = React47.useState(null);
|
|
3088
|
+
const count = (draft ?? caption ?? "").length;
|
|
3089
|
+
const textRef = React47.useRef(null);
|
|
3090
|
+
const [thumbnailSize, setThumbnailSize] = React47.useState(MIN_THUMBNAIL);
|
|
3091
|
+
React47.useEffect(() => {
|
|
3092
|
+
const el = textRef.current;
|
|
3093
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
3094
|
+
const observer = new ResizeObserver(() => {
|
|
3095
|
+
setThumbnailSize(Math.min(MAX_THUMBNAIL, Math.max(MIN_THUMBNAIL, Math.ceil(el.getBoundingClientRect().height))));
|
|
3096
|
+
});
|
|
3097
|
+
observer.observe(el);
|
|
3098
|
+
return () => observer.disconnect();
|
|
3099
|
+
}, []);
|
|
3073
3100
|
return /* @__PURE__ */ jsxs34(
|
|
3074
3101
|
"div",
|
|
3075
3102
|
{
|
|
3076
3103
|
ref,
|
|
3077
3104
|
"data-status": error ? "error" : "default",
|
|
3078
|
-
className: cn("flex w-full items-center gap-4 rounded-md border border-border p-0.5 pr-4", className),
|
|
3105
|
+
className: cn("flex min-h-21.5 w-full items-center gap-4 rounded-md border border-border p-0.5 pr-4", className),
|
|
3079
3106
|
...props,
|
|
3080
3107
|
children: [
|
|
3081
3108
|
/* @__PURE__ */ jsxs34("div", { className: "flex min-w-0 flex-1 items-center gap-4", children: [
|
|
3082
3109
|
/* @__PURE__ */ jsx48(
|
|
3083
3110
|
"span",
|
|
3084
3111
|
{
|
|
3112
|
+
style: { width: thumbnailSize, height: thumbnailSize },
|
|
3085
3113
|
className: cn(
|
|
3086
|
-
"flex
|
|
3114
|
+
"relative flex shrink-0 items-center justify-center overflow-hidden rounded-sm border",
|
|
3087
3115
|
error ? "border-destructive-soft-border bg-destructive-soft bg-linear-to-r from-overlay-dark-5 to-overlay-dark-5 text-destructive" : "border-border bg-background bg-linear-to-r from-overlay-dark-5 to-overlay-dark-5 text-surface-foreground",
|
|
3088
3116
|
showImage && "bg-none"
|
|
3089
3117
|
),
|
|
3090
|
-
children: showImage ?
|
|
3118
|
+
children: showImage ? (
|
|
3119
|
+
// Out of flow, so the image's own size never sets the thumbnail's size.
|
|
3120
|
+
/* @__PURE__ */ jsx48("img", { src: thumbnail, alt: thumbnailAlt, className: "absolute inset-0 size-full object-cover", onError: () => setFailedSrc(thumbnail) })
|
|
3121
|
+
) : error ? /* @__PURE__ */ jsx48(ImageBroken, { size: 24, "aria-hidden": true }) : icon ?? /* @__PURE__ */ jsx48(ImageIcon2, { size: 24, "aria-hidden": true })
|
|
3091
3122
|
}
|
|
3092
3123
|
),
|
|
3093
|
-
/* @__PURE__ */ jsxs34("div", { className: "flex min-w-0 flex-1 flex-col gap-2 text-surface-foreground", children: [
|
|
3124
|
+
/* @__PURE__ */ jsxs34("div", { ref: textRef, className: "flex min-w-0 flex-1 flex-col justify-center gap-2 py-2 text-surface-foreground", children: [
|
|
3094
3125
|
/* @__PURE__ */ jsx48("p", { className: "w-full text-ui-label", children: label }),
|
|
3095
3126
|
onCaptionChange ? /* @__PURE__ */ jsx48(
|
|
3096
3127
|
InlineEdit,
|
|
@@ -3101,10 +3132,21 @@ var StimulusCard = React47.forwardRef(
|
|
|
3101
3132
|
"aria-label": "Stimulus caption",
|
|
3102
3133
|
value: caption ?? "",
|
|
3103
3134
|
placeholder: captionPlaceholder,
|
|
3135
|
+
maxLength,
|
|
3104
3136
|
onValueChange: onCaptionChange,
|
|
3137
|
+
onDraftChange: setDraft,
|
|
3138
|
+
onEditingChange: (editing) => {
|
|
3139
|
+
if (!editing) setDraft(null);
|
|
3140
|
+
},
|
|
3105
3141
|
textClassName: "text-body-base"
|
|
3106
3142
|
}
|
|
3107
|
-
) : /* @__PURE__ */ jsx48("p", { className: "w-full text-body-base [word-break:break-word]", children: caption })
|
|
3143
|
+
) : /* @__PURE__ */ jsx48("p", { className: "w-full text-body-base [word-break:break-word]", children: caption }),
|
|
3144
|
+
onCaptionChange && showCounter && maxLength !== void 0 && /* @__PURE__ */ jsxs34("p", { className: "text-ui-caption text-secondary-muted-foreground", children: [
|
|
3145
|
+
count,
|
|
3146
|
+
"/",
|
|
3147
|
+
maxLength,
|
|
3148
|
+
" characters"
|
|
3149
|
+
] })
|
|
3108
3150
|
] })
|
|
3109
3151
|
] }),
|
|
3110
3152
|
onRemove && /* @__PURE__ */ jsx48(Button, { type: "button", variant: "destructive", size: "icon-sm", "aria-label": removeLabel, onClick: onRemove, children: /* @__PURE__ */ jsx48(Trash5, { size: 16, "aria-hidden": true }) })
|