@fanvue/ui 3.7.2 → 3.9.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/cjs/components/Alert/Alert.cjs +28 -5
- package/dist/cjs/components/Alert/Alert.cjs.map +1 -1
- package/dist/cjs/components/Badge/Badge.cjs +17 -5
- package/dist/cjs/components/Badge/Badge.cjs.map +1 -1
- package/dist/cjs/components/Breadcrumb/Breadcrumb.cjs +46 -23
- package/dist/cjs/components/Breadcrumb/Breadcrumb.cjs.map +1 -1
- package/dist/cjs/components/Checkbox/Checkbox.cjs +1 -1
- package/dist/cjs/components/Checkbox/Checkbox.cjs.map +1 -1
- package/dist/cjs/components/Dialog/Dialog.cjs +21 -8
- package/dist/cjs/components/Dialog/Dialog.cjs.map +1 -1
- package/dist/cjs/components/FanFollowerCount/FanFollowerCount.cjs +64 -0
- package/dist/cjs/components/FanFollowerCount/FanFollowerCount.cjs.map +1 -0
- package/dist/cjs/components/IconButton/IconButton.cjs +1 -1
- package/dist/cjs/components/IconButton/IconButton.cjs.map +1 -1
- package/dist/cjs/components/Icons/GifIcon.cjs +101 -0
- package/dist/cjs/components/Icons/GifIcon.cjs.map +1 -0
- package/dist/cjs/components/Icons/VerifiedIcon.cjs +82 -0
- package/dist/cjs/components/Icons/VerifiedIcon.cjs.map +1 -0
- package/dist/cjs/components/Link/Link.cjs +85 -0
- package/dist/cjs/components/Link/Link.cjs.map +1 -0
- package/dist/cjs/components/Pagination/Pagination.cjs +7 -7
- package/dist/cjs/components/Pagination/Pagination.cjs.map +1 -1
- package/dist/cjs/components/Pill/Pill.cjs +3 -1
- package/dist/cjs/components/Pill/Pill.cjs.map +1 -1
- package/dist/cjs/components/ProfileOnlineStatus/ProfileOnlineStatus.cjs +44 -0
- package/dist/cjs/components/ProfileOnlineStatus/ProfileOnlineStatus.cjs.map +1 -0
- package/dist/cjs/components/ProfileStatus/ProfileStatus.cjs +51 -0
- package/dist/cjs/components/ProfileStatus/ProfileStatus.cjs.map +1 -0
- package/dist/cjs/components/Radio/Radio.cjs +65 -34
- package/dist/cjs/components/Radio/Radio.cjs.map +1 -1
- package/dist/cjs/components/RatingSummary/RatingSummary.cjs +103 -0
- package/dist/cjs/components/RatingSummary/RatingSummary.cjs.map +1 -0
- package/dist/cjs/components/ReviewCard/ReviewCard.cjs +51 -0
- package/dist/cjs/components/ReviewCard/ReviewCard.cjs.map +1 -0
- package/dist/cjs/components/Select/Select.cjs +4 -4
- package/dist/cjs/components/Select/Select.cjs.map +1 -1
- package/dist/cjs/components/TextField/TextField.cjs +4 -4
- package/dist/cjs/components/TextField/TextField.cjs.map +1 -1
- package/dist/cjs/components/Toast/Toast.cjs +18 -32
- package/dist/cjs/components/Toast/Toast.cjs.map +1 -1
- package/dist/cjs/components/UserDisplayName/UserDisplayName.cjs +67 -0
- package/dist/cjs/components/UserDisplayName/UserDisplayName.cjs.map +1 -0
- package/dist/cjs/components/UserHandle/UserHandle.cjs +46 -0
- package/dist/cjs/components/UserHandle/UserHandle.cjs.map +1 -0
- package/dist/cjs/components/UserItem/UserItem.cjs +74 -0
- package/dist/cjs/components/UserItem/UserItem.cjs.map +1 -0
- package/dist/cjs/index.cjs +24 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/utils/getInitials.cjs +10 -0
- package/dist/cjs/utils/getInitials.cjs.map +1 -0
- package/dist/components/Alert/Alert.mjs +28 -5
- package/dist/components/Alert/Alert.mjs.map +1 -1
- package/dist/components/Badge/Badge.mjs +17 -5
- package/dist/components/Badge/Badge.mjs.map +1 -1
- package/dist/components/Breadcrumb/Breadcrumb.mjs +46 -23
- package/dist/components/Breadcrumb/Breadcrumb.mjs.map +1 -1
- package/dist/components/Checkbox/Checkbox.mjs +1 -1
- package/dist/components/Checkbox/Checkbox.mjs.map +1 -1
- package/dist/components/Dialog/Dialog.mjs +21 -8
- package/dist/components/Dialog/Dialog.mjs.map +1 -1
- package/dist/components/FanFollowerCount/FanFollowerCount.mjs +47 -0
- package/dist/components/FanFollowerCount/FanFollowerCount.mjs.map +1 -0
- package/dist/components/IconButton/IconButton.mjs +1 -1
- package/dist/components/IconButton/IconButton.mjs.map +1 -1
- package/dist/components/Icons/GifIcon.mjs +84 -0
- package/dist/components/Icons/GifIcon.mjs.map +1 -0
- package/dist/components/Icons/VerifiedIcon.mjs +65 -0
- package/dist/components/Icons/VerifiedIcon.mjs.map +1 -0
- package/dist/components/Link/Link.mjs +68 -0
- package/dist/components/Link/Link.mjs.map +1 -0
- package/dist/components/Pagination/Pagination.mjs +7 -7
- package/dist/components/Pagination/Pagination.mjs.map +1 -1
- package/dist/components/Pill/Pill.mjs +3 -1
- package/dist/components/Pill/Pill.mjs.map +1 -1
- package/dist/components/ProfileOnlineStatus/ProfileOnlineStatus.mjs +27 -0
- package/dist/components/ProfileOnlineStatus/ProfileOnlineStatus.mjs.map +1 -0
- package/dist/components/ProfileStatus/ProfileStatus.mjs +34 -0
- package/dist/components/ProfileStatus/ProfileStatus.mjs.map +1 -0
- package/dist/components/Radio/Radio.mjs +66 -35
- package/dist/components/Radio/Radio.mjs.map +1 -1
- package/dist/components/RatingSummary/RatingSummary.mjs +86 -0
- package/dist/components/RatingSummary/RatingSummary.mjs.map +1 -0
- package/dist/components/ReviewCard/ReviewCard.mjs +34 -0
- package/dist/components/ReviewCard/ReviewCard.mjs.map +1 -0
- package/dist/components/Select/Select.mjs +4 -4
- package/dist/components/Select/Select.mjs.map +1 -1
- package/dist/components/TextField/TextField.mjs +4 -4
- package/dist/components/TextField/TextField.mjs.map +1 -1
- package/dist/components/Toast/Toast.mjs +18 -32
- package/dist/components/Toast/Toast.mjs.map +1 -1
- package/dist/components/UserDisplayName/UserDisplayName.mjs +50 -0
- package/dist/components/UserDisplayName/UserDisplayName.mjs.map +1 -0
- package/dist/components/UserHandle/UserHandle.mjs +29 -0
- package/dist/components/UserHandle/UserHandle.mjs.map +1 -0
- package/dist/components/UserItem/UserItem.mjs +57 -0
- package/dist/components/UserItem/UserItem.mjs.map +1 -0
- package/dist/index.d.ts +404 -15
- package/dist/index.mjs +24 -0
- package/dist/index.mjs.map +1 -1
- package/dist/utils/getInitials.mjs +10 -0
- package/dist/utils/getInitials.mjs.map +1 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextField.cjs","sources":["../../../../src/components/TextField/TextField.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CheckOutlineIcon } from \"@/index\";\nimport { cn } from \"../../utils/cn\";\n\n/** Text field height in pixels. */\nexport type TextFieldSize = \"48\" | \"40\" | \"32\";\n\nexport interface TextFieldProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\" | \"prefix\"> {\n /** Label text displayed above the input. Also used as the accessible name. */\n label?: string;\n /** Helper text displayed below the input. Replaced by `errorMessage` when `error` is `true`. */\n helperText?: string;\n /** Height of the text field in pixels. @default \"48\" */\n size?: TextFieldSize;\n /** Whether the text field is in an error state. @default false */\n error?: boolean;\n /** Error message displayed below the input. Shown instead of `helperText` when `error` is `true`. */\n errorMessage?: string;\n /** Whether the text field is validated. @default false */\n validated?: boolean;\n /** Icon element displayed at the left side of the input. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed at the right side of the input. */\n rightIcon?: React.ReactNode;\n /** Whether the text field stretches to fill its container width. @default false */\n fullWidth?: boolean;\n}\n\nconst CONTAINER_HEIGHT: Record<TextFieldSize, string> = {\n \"48\": \"h-12\",\n \"40\": \"h-10\",\n \"32\": \"h-8\",\n};\n\nconst INPUT_SIZE_CLASSES: Record<TextFieldSize, string> = {\n \"48\": \"py-3 typography-body-default-16px-regular autofill-body-lg\",\n \"40\": \"py-2 typography-body-default-16px-regular autofill-body-lg\",\n \"32\": \"py-2 typography-body-small-14px-regular autofill-body-md\",\n};\n\nconst INPUT_PL: Record<TextFieldSize, { default: string; withIcon: string }> = {\n \"48\": { default: \"pl-4\", withIcon: \"pl-10\" },\n \"40\": { default: \"pl-4\", withIcon: \"pl-10\" },\n \"32\": { default: \"pl-3\", withIcon: \"pl-9\" },\n};\n\nconst INPUT_PR: Record<TextFieldSize, { default: string; withIcon: string }> = {\n \"48\": { default: \"pr-4\", withIcon: \"pr-10\" },\n \"40\": { default: \"pr-4\", withIcon: \"pr-10\" },\n \"32\": { default: \"pr-3\", withIcon: \"pr-9\" },\n};\n\nconst ICON_INSET: Record<TextFieldSize, string> = {\n \"48\": \"px-4\",\n \"40\": \"px-4\",\n \"32\": \"px-3\",\n};\n\nfunction getContainerClassName(size: TextFieldSize, error: boolean, disabled?: boolean) {\n return cn(\n \"relative overflow-hidden rounded-sm border bg-neutral-alphas-50 has-focus-visible:shadow-focus-ring has-focus-visible:outline-none motion-safe:transition-colors\",\n error ? \"border-error-content\" : \"border-transparent\",\n !disabled && !error && \"hover:border-neutral-alphas-400\",\n CONTAINER_HEIGHT[size],\n disabled && \"opacity-50\",\n );\n}\n\nfunction getInputClassName(size: TextFieldSize, hasLeftIcon: boolean, hasRightIcon: boolean) {\n return cn(\n \"h-full w-full rounded-sm bg-transparent text-content-primary no-underline placeholder:text-content-secondary focus:outline-none disabled:cursor-not-allowed\",\n INPUT_SIZE_CLASSES[size],\n hasLeftIcon ? INPUT_PL[size].withIcon : INPUT_PL[size].default,\n hasRightIcon ? INPUT_PR[size].withIcon : INPUT_PR[size].default,\n );\n}\n\nfunction TextFieldHelperText({\n id,\n error,\n children,\n}: {\n id: string;\n error: boolean;\n children: React.ReactNode;\n}) {\n return (\n <p\n id={id}\n className={cn(\n \"typography-description-12px-regular px-2 pt-2 pb-0.5\",\n error ? \"text-error-content\" : \"text-content-secondary\",\n )}\n >\n {children}\n </p>\n );\n}\n\nfunction warnMissingAccessibleName(label?: string, ariaLabel?: string, ariaLabelledBy?: string) {\n if (process.env.NODE_ENV !== \"production\") {\n if (!label && !ariaLabel && !ariaLabelledBy) {\n console.warn(\n \"TextField: no accessible name provided. Pass a `label`, `aria-label`, or `aria-labelledby` prop.\",\n );\n }\n }\n}\n\n/**\n * A text input field with optional label, helper/error text, and icon slots.\n *\n * Provide at least one of `label`, `aria-label`, or `aria-labelledby` for\n * accessibility — a console warning is emitted in development if none are set.\n *\n * @example\n * ```tsx\n * <TextField\n * label=\"Email\"\n * placeholder=\"you@example.com\"\n * error={!!emailError}\n * errorMessage={emailError}\n * />\n * ```\n */\nexport const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(\n (\n {\n label,\n helperText,\n size = \"48\",\n error = false,\n errorMessage,\n validated = false,\n leftIcon,\n rightIcon,\n className,\n id,\n disabled,\n fullWidth = false,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const inputId = id || generatedId;\n const helperTextId = `${inputId}-helper`;\n const bottomText = error && errorMessage ? errorMessage : helperText;\n\n warnMissingAccessibleName(label, props[\"aria-label\"], props[\"aria-labelledby\"]);\n\n return (\n <div\n className={cn(\"flex flex-col\", fullWidth && \"w-full\", className)}\n data-disabled={disabled ? \"\" : undefined}\n data-error={error ? \"\" : undefined}\n >\n {label && (\n <label\n htmlFor={inputId}\n className=\"typography-description-12px-semibold px-1 pt-1 pb-2 text-content-primary\"\n >\n {label}\n </label>\n )}\n\n <div className={getContainerClassName(size, error, disabled)}>\n <input\n ref={ref}\n id={inputId}\n disabled={disabled}\n aria-describedby={bottomText ? helperTextId : undefined}\n aria-invalid={error || undefined}\n className={cn(\n getInputClassName(size, !!leftIcon, !!(rightIcon || validated)),\n \"[&[type='search']::-webkit-search-cancel-button]:hidden [&[type='search']::-webkit-search-cancel-button]:appearance-none\",\n )}\n {...props}\n />\n\n {leftIcon && (\n <div\n className={cn(\n \"pointer-events-none absolute inset-y-0 left-0 flex items-center text-content-secondary\",\n ICON_INSET[size],\n )}\n >\n <div className=\"flex size-4 shrink-0 items-center justify-center\">{leftIcon}</div>\n </div>\n )}\n\n {(rightIcon || validated) && (\n <div\n className={cn(\n \"absolute inset-y-0 right-0 flex items-center gap-2 text-content-secondary\",\n ICON_INSET[size],\n )}\n >\n {rightIcon && (\n <div className=\"flex size-4 shrink-0 items-center justify-center\">{rightIcon}</div>\n )}\n {validated && (\n <div className=\"pointer-events-none flex size-4 shrink-0 items-center justify-center\">\n <CheckOutlineIcon className=\"text-success-content\" />\n </div>\n )}\n </div>\n )}\n </div>\n\n {bottomText && (\n <TextFieldHelperText id={helperTextId} error={error}>\n {bottomText}\n </TextFieldHelperText>\n )}\n </div>\n );\n },\n);\n\nTextField.displayName = \"TextField\";\n"],"names":["cn","jsx","React","jsxs","CheckOutlineIcon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TextField.cjs","sources":["../../../../src/components/TextField/TextField.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CheckOutlineIcon } from \"@/index\";\nimport { cn } from \"../../utils/cn\";\n\n/** Text field height in pixels. */\nexport type TextFieldSize = \"48\" | \"40\" | \"32\";\n\nexport interface TextFieldProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\" | \"prefix\"> {\n /** Label text displayed above the input. Also used as the accessible name. */\n label?: string;\n /** Helper text displayed below the input. Replaced by `errorMessage` when `error` is `true`. */\n helperText?: string;\n /** Height of the text field in pixels. @default \"48\" */\n size?: TextFieldSize;\n /** Whether the text field is in an error state. @default false */\n error?: boolean;\n /** Error message displayed below the input. Shown instead of `helperText` when `error` is `true`. */\n errorMessage?: string;\n /** Whether the text field is validated. @default false */\n validated?: boolean;\n /** Icon element displayed at the left side of the input. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed at the right side of the input. */\n rightIcon?: React.ReactNode;\n /** Whether the text field stretches to fill its container width. @default false */\n fullWidth?: boolean;\n}\n\nconst CONTAINER_HEIGHT: Record<TextFieldSize, string> = {\n \"48\": \"h-12\",\n \"40\": \"h-10\",\n \"32\": \"h-8\",\n};\n\nconst INPUT_SIZE_CLASSES: Record<TextFieldSize, string> = {\n \"48\": \"py-3 typography-body-default-16px-regular autofill-body-lg\",\n \"40\": \"py-2 typography-body-default-16px-regular autofill-body-lg\",\n \"32\": \"py-2 typography-body-small-14px-regular autofill-body-md\",\n};\n\nconst INPUT_PL: Record<TextFieldSize, { default: string; withIcon: string }> = {\n \"48\": { default: \"pl-4\", withIcon: \"pl-10\" },\n \"40\": { default: \"pl-4\", withIcon: \"pl-10\" },\n \"32\": { default: \"pl-3\", withIcon: \"pl-9\" },\n};\n\nconst INPUT_PR: Record<TextFieldSize, { default: string; withIcon: string }> = {\n \"48\": { default: \"pr-4\", withIcon: \"pr-10\" },\n \"40\": { default: \"pr-4\", withIcon: \"pr-10\" },\n \"32\": { default: \"pr-3\", withIcon: \"pr-9\" },\n};\n\nconst ICON_INSET: Record<TextFieldSize, string> = {\n \"48\": \"px-4\",\n \"40\": \"px-4\",\n \"32\": \"px-3\",\n};\n\nfunction getContainerClassName(size: TextFieldSize, error: boolean, disabled?: boolean) {\n return cn(\n \"relative overflow-hidden rounded-sm border bg-inputs-inputs-primary has-focus-visible:shadow-focus-ring has-focus-visible:outline-none motion-safe:transition-colors\",\n error ? \"border-error-content\" : \"border-border-primary\",\n !disabled && !error && \"hover:border-neutral-alphas-400\",\n CONTAINER_HEIGHT[size],\n disabled && \"opacity-50\",\n );\n}\n\nfunction getInputClassName(size: TextFieldSize, hasLeftIcon: boolean, hasRightIcon: boolean) {\n return cn(\n \"h-full w-full rounded-sm bg-transparent text-content-primary no-underline placeholder:text-content-tertiary focus:outline-none disabled:cursor-not-allowed\",\n INPUT_SIZE_CLASSES[size],\n hasLeftIcon ? INPUT_PL[size].withIcon : INPUT_PL[size].default,\n hasRightIcon ? INPUT_PR[size].withIcon : INPUT_PR[size].default,\n );\n}\n\nfunction TextFieldHelperText({\n id,\n error,\n children,\n}: {\n id: string;\n error: boolean;\n children: React.ReactNode;\n}) {\n return (\n <p\n id={id}\n className={cn(\n \"typography-description-12px-regular px-2 pt-2 pb-0.5\",\n error ? \"text-error-content\" : \"text-content-secondary\",\n )}\n >\n {children}\n </p>\n );\n}\n\nfunction warnMissingAccessibleName(label?: string, ariaLabel?: string, ariaLabelledBy?: string) {\n if (process.env.NODE_ENV !== \"production\") {\n if (!label && !ariaLabel && !ariaLabelledBy) {\n console.warn(\n \"TextField: no accessible name provided. Pass a `label`, `aria-label`, or `aria-labelledby` prop.\",\n );\n }\n }\n}\n\n/**\n * A text input field with optional label, helper/error text, and icon slots.\n *\n * Provide at least one of `label`, `aria-label`, or `aria-labelledby` for\n * accessibility — a console warning is emitted in development if none are set.\n *\n * @example\n * ```tsx\n * <TextField\n * label=\"Email\"\n * placeholder=\"you@example.com\"\n * error={!!emailError}\n * errorMessage={emailError}\n * />\n * ```\n */\nexport const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(\n (\n {\n label,\n helperText,\n size = \"48\",\n error = false,\n errorMessage,\n validated = false,\n leftIcon,\n rightIcon,\n className,\n id,\n disabled,\n fullWidth = false,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const inputId = id || generatedId;\n const helperTextId = `${inputId}-helper`;\n const bottomText = error && errorMessage ? errorMessage : helperText;\n\n warnMissingAccessibleName(label, props[\"aria-label\"], props[\"aria-labelledby\"]);\n\n return (\n <div\n className={cn(\"flex flex-col\", fullWidth && \"w-full\", className)}\n data-disabled={disabled ? \"\" : undefined}\n data-error={error ? \"\" : undefined}\n >\n {label && (\n <label\n htmlFor={inputId}\n className=\"typography-description-12px-semibold pb-2 text-content-primary\"\n >\n {label}\n </label>\n )}\n\n <div className={getContainerClassName(size, error, disabled)}>\n <input\n ref={ref}\n id={inputId}\n disabled={disabled}\n aria-describedby={bottomText ? helperTextId : undefined}\n aria-invalid={error || undefined}\n className={cn(\n getInputClassName(size, !!leftIcon, !!(rightIcon || validated)),\n \"[&[type='search']::-webkit-search-cancel-button]:hidden [&[type='search']::-webkit-search-cancel-button]:appearance-none\",\n )}\n {...props}\n />\n\n {leftIcon && (\n <div\n className={cn(\n \"pointer-events-none absolute inset-y-0 left-0 flex items-center text-content-secondary\",\n ICON_INSET[size],\n )}\n >\n <div className=\"flex size-4 shrink-0 items-center justify-center\">{leftIcon}</div>\n </div>\n )}\n\n {(rightIcon || validated) && (\n <div\n className={cn(\n \"absolute inset-y-0 right-0 flex items-center gap-2 text-content-secondary\",\n ICON_INSET[size],\n )}\n >\n {rightIcon && (\n <div className=\"flex size-4 shrink-0 items-center justify-center\">{rightIcon}</div>\n )}\n {validated && (\n <div className=\"pointer-events-none flex size-4 shrink-0 items-center justify-center\">\n <CheckOutlineIcon className=\"text-success-content\" />\n </div>\n )}\n </div>\n )}\n </div>\n\n {bottomText && (\n <TextFieldHelperText id={helperTextId} error={error}>\n {bottomText}\n </TextFieldHelperText>\n )}\n </div>\n );\n },\n);\n\nTextField.displayName = \"TextField\";\n"],"names":["cn","jsx","React","jsxs","CheckOutlineIcon"],"mappings":"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"}
|
|
@@ -7,7 +7,6 @@ const React = require("react");
|
|
|
7
7
|
const cn = require("../../utils/cn.cjs");
|
|
8
8
|
const Avatar = require("../Avatar/Avatar.cjs");
|
|
9
9
|
const Button = require("../Button/Button.cjs");
|
|
10
|
-
const IconButton = require("../IconButton/IconButton.cjs");
|
|
11
10
|
const CloseIcon = require("../Icons/CloseIcon.cjs");
|
|
12
11
|
const ErrorIcon = require("../Icons/ErrorIcon.cjs");
|
|
13
12
|
const InfoIcon = require("../Icons/InfoIcon.cjs");
|
|
@@ -47,13 +46,13 @@ ToastViewport.displayName = "ToastViewport";
|
|
|
47
46
|
const VariantIcon = ({ variant }) => {
|
|
48
47
|
switch (variant) {
|
|
49
48
|
case "info":
|
|
50
|
-
return /* @__PURE__ */ jsxRuntime.jsx(InfoIcon.InfoIcon, { className: "
|
|
49
|
+
return /* @__PURE__ */ jsxRuntime.jsx(InfoIcon.InfoIcon, { size: 16, filled: true, className: "text-alerts-toast-icon-info" });
|
|
51
50
|
case "warning":
|
|
52
|
-
return /* @__PURE__ */ jsxRuntime.jsx(WarningIcon.WarningIcon, { className: "
|
|
51
|
+
return /* @__PURE__ */ jsxRuntime.jsx(WarningIcon.WarningIcon, { size: 16, filled: true, className: "text-alerts-toast-icon-warning" });
|
|
53
52
|
case "success":
|
|
54
|
-
return /* @__PURE__ */ jsxRuntime.jsx(SuccessIcon.SuccessIcon, { className: "size-
|
|
53
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SuccessIcon.SuccessIcon, { className: "size-4 text-alerts-toast-icon-success" });
|
|
55
54
|
case "error":
|
|
56
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ErrorIcon.ErrorIcon, { className: "size-
|
|
55
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ErrorIcon.ErrorIcon, { className: "size-4 text-alerts-toast-icon-error" });
|
|
57
56
|
}
|
|
58
57
|
};
|
|
59
58
|
const Toast = React__namespace.forwardRef(
|
|
@@ -78,43 +77,30 @@ const Toast = React__namespace.forwardRef(
|
|
|
78
77
|
ref,
|
|
79
78
|
"data-testid": "toast",
|
|
80
79
|
className: cn.cn(
|
|
81
|
-
|
|
82
|
-
"group pointer-events-auto relative flex w-full flex-col items-start gap-3 overflow-hidden rounded-xs border-none bg-surface-primary-inverted p-4 text-content-primary-inverted shadow-lg transition-all",
|
|
83
|
-
// Dark mode
|
|
84
|
-
"dark:border-opacity-100",
|
|
85
|
-
// Animation
|
|
80
|
+
"group pointer-events-auto relative flex w-full items-start gap-6 overflow-hidden rounded-md border-none bg-surface-primary-inverted py-3 pr-3 pl-4 text-content-primary-inverted shadow-md transition-all",
|
|
86
81
|
"data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-bottom-full data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-(--radix-toast-swipe-end-x) data-[swipe=move]:translate-x-(--radix-toast-swipe-move-x) data-[state=closed]:animate-out data-[state=open]:animate-in data-[swipe=end]:animate-out data-[swipe=move]:transition-none",
|
|
87
|
-
// Manual CSS overrides
|
|
88
82
|
className
|
|
89
83
|
),
|
|
90
84
|
...props,
|
|
91
85
|
children: [
|
|
92
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-
|
|
93
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
94
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col items-start", children: [
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
variant: "secondary",
|
|
102
|
-
className: "mt-4 border-content-primary-inverted text-content-primary-inverted",
|
|
103
|
-
size: "32",
|
|
104
|
-
onClick: onActionClick,
|
|
105
|
-
children: actionLabel ?? "Action"
|
|
106
|
-
}
|
|
107
|
-
)
|
|
86
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-start gap-3 py-1 pr-1", children: [
|
|
87
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center pt-px", children: variant === "messageToast" ? avatarSrc && /* @__PURE__ */ jsxRuntime.jsx(Avatar.Avatar, { src: avatarSrc, alt: avatarAlt, fallback: avatarFallback }) : /* @__PURE__ */ jsxRuntime.jsx(VariantIcon, { variant }) }),
|
|
88
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col items-start gap-4", children: [
|
|
89
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full flex-col items-start gap-1", children: [
|
|
90
|
+
title && /* @__PURE__ */ jsxRuntime.jsx(ToastPrimitive__namespace.Title, { className: "typography-body-small-14px-semibold", children: title }),
|
|
91
|
+
description && /* @__PURE__ */ jsxRuntime.jsx(ToastPrimitive__namespace.Description, { className: "typography-body-small-14px-regular", children: description }),
|
|
92
|
+
children
|
|
93
|
+
] }),
|
|
94
|
+
onActionClick && /* @__PURE__ */ jsxRuntime.jsx(Button.Button, { variant: "outline", negative: true, size: "32", onClick: onActionClick, children: actionLabel ?? "Action" })
|
|
108
95
|
] })
|
|
109
96
|
] }),
|
|
110
97
|
showClose && /* @__PURE__ */ jsxRuntime.jsx(ToastPrimitive__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
111
|
-
|
|
98
|
+
"button",
|
|
112
99
|
{
|
|
113
|
-
|
|
100
|
+
type: "button",
|
|
114
101
|
"aria-label": closeLabel,
|
|
115
|
-
className: "
|
|
116
|
-
|
|
117
|
-
size: "24"
|
|
102
|
+
className: "flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-xs bg-buttons-secondary-negative-default text-content-primary-inverted transition-colors hover:bg-buttons-secondary-negative-hover focus-visible:shadow-focus-ring focus-visible:outline-none",
|
|
103
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon.CloseIcon, { size: 16, "aria-hidden": "true" })
|
|
118
104
|
}
|
|
119
105
|
) })
|
|
120
106
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toast.cjs","sources":["../../../../src/components/Toast/Toast.tsx"],"sourcesContent":["import * as ToastPrimitive from \"@radix-ui/react-toast\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Avatar } from \"../Avatar/Avatar\";\nimport { Button } from \"../Button/Button\";\nimport {
|
|
1
|
+
{"version":3,"file":"Toast.cjs","sources":["../../../../src/components/Toast/Toast.tsx"],"sourcesContent":["import * as ToastPrimitive from \"@radix-ui/react-toast\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Avatar } from \"../Avatar/Avatar\";\nimport { Button } from \"../Button/Button\";\nimport { CloseIcon } from \"../Icons/CloseIcon\";\nimport { ErrorIcon } from \"../Icons/ErrorIcon\";\nimport { InfoIcon } from \"../Icons/InfoIcon\";\nimport { SuccessIcon } from \"../Icons/SuccessIcon\";\nimport { WarningIcon } from \"../Icons/WarningIcon\";\n\n/** Visual/semantic variant of the toast notification. */\nexport type ToastVariant = \"info\" | \"warning\" | \"success\" | \"error\" | \"messageToast\";\n\nexport interface ToastProps\n extends Omit<Omit<React.ComponentPropsWithoutRef<typeof ToastPrimitive.Root>, \"type\">, \"title\"> {\n /** Visual/semantic variant of the toast. @default \"info\" */\n variant?: ToastVariant;\n /** Title text displayed in bold at the top of the toast. */\n title?: string;\n /** Description or body content displayed below the title. */\n description?: React.ReactNode;\n /** Label for the optional action button. @default \"Action\" */\n actionLabel?: string;\n /** Click handler for the action button. When provided, the action button is rendered. */\n onActionClick?: () => void;\n /** Whether to show the close button. @default true */\n showClose?: boolean;\n /** Accessible label for the close button. @default \"Close notification\" */\n closeLabel?: string;\n /** Avatar image URL (used by the `messageToast` variant). */\n avatarSrc?: string;\n /** Alt text for the avatar image. */\n avatarAlt?: string;\n /** Fallback content for the avatar (e.g. initials). */\n avatarFallback?: string;\n}\n\n/** Props for the {@link ToastProvider}. Wraps Radix `Toast.Provider`. */\nexport interface ToastProviderProps extends ToastPrimitive.ToastProviderProps {}\n/** Props for the {@link ToastViewport}. Controls where toasts are rendered on screen. */\nexport interface ToastViewportProps\n extends React.ComponentPropsWithoutRef<typeof ToastPrimitive.Viewport> {}\n\n/** Provides toast context. Wrap your application (or a subtree) with this provider. */\nexport const ToastProvider: React.FC<ToastProviderProps> = ToastPrimitive.Provider;\n\n/** Fixed-position container that renders active toasts. Place once at the root of your app. */\nexport const ToastViewport = React.forwardRef<\n React.ElementRef<typeof ToastPrimitive.Viewport>,\n ToastViewportProps\n>(({ className, ...props }, ref) => (\n <ToastPrimitive.Viewport\n ref={ref}\n className={cn(\n \"pointer-events-none fixed right-0 bottom-0 z-100 flex max-h-screen w-full flex-col-reverse gap-3 p-4 md:max-w-[420px]\",\n className,\n )}\n {...props}\n />\n));\n\nToastViewport.displayName = \"ToastViewport\";\n\nconst VariantIcon = ({ variant }: { variant: ToastVariant }) => {\n switch (variant) {\n case \"info\":\n return <InfoIcon size={16} filled className=\"text-alerts-toast-icon-info\" />;\n case \"warning\":\n return <WarningIcon size={16} filled className=\"text-alerts-toast-icon-warning\" />;\n case \"success\":\n return <SuccessIcon className=\"size-4 text-alerts-toast-icon-success\" />;\n case \"error\":\n return <ErrorIcon className=\"size-4 text-alerts-toast-icon-error\" />;\n }\n};\n\n/**\n * A dismissible notification that appears temporarily. Supports `info`,\n * `warning`, `success`, `error`, and `messageToast` variants with optional\n * action button, close control, and avatar.\n *\n * Use inside a {@link ToastProvider} with a {@link ToastViewport}.\n *\n * @example\n * ```tsx\n * <Toast variant=\"success\" title=\"Saved\" description=\"Your changes are live.\" />\n * ```\n */\nexport const Toast = React.forwardRef<React.ComponentRef<typeof ToastPrimitive.Root>, ToastProps>(\n (\n {\n className,\n variant = \"info\",\n title,\n description,\n actionLabel,\n onActionClick,\n showClose = true,\n closeLabel = \"Close notification\",\n avatarSrc,\n avatarAlt,\n avatarFallback,\n children,\n ...props\n },\n ref,\n ) => {\n return (\n <ToastPrimitive.Root\n ref={ref}\n data-testid=\"toast\"\n className={cn(\n \"group pointer-events-auto relative flex w-full items-start gap-6 overflow-hidden rounded-md border-none bg-surface-primary-inverted py-3 pr-3 pl-4 text-content-primary-inverted shadow-md transition-all\",\n \"data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-bottom-full data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-(--radix-toast-swipe-end-x) data-[swipe=move]:translate-x-(--radix-toast-swipe-move-x) data-[state=closed]:animate-out data-[state=open]:animate-in data-[swipe=end]:animate-out data-[swipe=move]:transition-none\",\n className,\n )}\n {...props}\n >\n <div className=\"flex min-w-0 flex-1 items-start gap-3 py-1 pr-1\">\n <div className=\"flex shrink-0 items-center pt-px\">\n {variant === \"messageToast\" ? (\n avatarSrc && <Avatar src={avatarSrc} alt={avatarAlt} fallback={avatarFallback} />\n ) : (\n <VariantIcon variant={variant} />\n )}\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col items-start gap-4\">\n <div className=\"flex w-full flex-col items-start gap-1\">\n {title && (\n <ToastPrimitive.Title className=\"typography-body-small-14px-semibold\">\n {title}\n </ToastPrimitive.Title>\n )}\n {description && (\n <ToastPrimitive.Description className=\"typography-body-small-14px-regular\">\n {description}\n </ToastPrimitive.Description>\n )}\n {children}\n </div>\n {onActionClick && (\n <Button variant=\"outline\" negative size=\"32\" onClick={onActionClick}>\n {actionLabel ?? \"Action\"}\n </Button>\n )}\n </div>\n </div>\n {showClose && (\n <ToastPrimitive.Close asChild>\n <button\n type=\"button\"\n aria-label={closeLabel}\n className=\"flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-xs bg-buttons-secondary-negative-default text-content-primary-inverted transition-colors hover:bg-buttons-secondary-negative-hover focus-visible:shadow-focus-ring focus-visible:outline-none\"\n >\n <CloseIcon size={16} aria-hidden=\"true\" />\n </button>\n </ToastPrimitive.Close>\n )}\n </ToastPrimitive.Root>\n );\n },\n);\n\nToast.displayName = \"Toast\";\n"],"names":["ToastPrimitive","React","jsx","cn","InfoIcon","WarningIcon","SuccessIcon","ErrorIcon","jsxs","Avatar","Button","CloseIcon"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CO,MAAM,gBAA8CA,0BAAe;AAGnE,MAAM,gBAAgBC,iBAAM,WAGjC,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QAC1BC,2BAAAA;AAAAA,EAACF,0BAAe;AAAA,EAAf;AAAA,IACC;AAAA,IACA,WAAWG,GAAAA;AAAAA,MACT;AAAA,MACA;AAAA,IAAA;AAAA,IAED,GAAG;AAAA,EAAA;AACN,CACD;AAED,cAAc,cAAc;AAE5B,MAAM,cAAc,CAAC,EAAE,cAAyC;AAC9D,UAAQ,SAAA;AAAA,IACN,KAAK;AACH,4CAAQC,mBAAA,EAAS,MAAM,IAAI,QAAM,MAAC,WAAU,+BAA8B;AAAA,IAC5E,KAAK;AACH,4CAAQC,yBAAA,EAAY,MAAM,IAAI,QAAM,MAAC,WAAU,kCAAiC;AAAA,IAClF,KAAK;AACH,aAAOH,2BAAAA,IAACI,YAAAA,aAAA,EAAY,WAAU,wCAAA,CAAwC;AAAA,IACxE,KAAK;AACH,aAAOJ,2BAAAA,IAACK,UAAAA,WAAA,EAAU,WAAU,sCAAA,CAAsC;AAAA,EAAA;AAExE;AAcO,MAAM,QAAQN,iBAAM;AAAA,EACzB,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,WACEO,2BAAAA;AAAAA,MAACR,0BAAe;AAAA,MAAf;AAAA,QACC;AAAA,QACA,eAAY;AAAA,QACZ,WAAWG,GAAAA;AAAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,QAEJ,UAAA;AAAA,UAAAK,2BAAAA,KAAC,OAAA,EAAI,WAAU,mDACb,UAAA;AAAA,YAAAN,2BAAAA,IAAC,SAAI,WAAU,oCACZ,sBAAY,iBACX,4CAAcO,eAAA,EAAO,KAAK,WAAW,KAAK,WAAW,UAAU,eAAA,CAAgB,IAE/EP,2BAAAA,IAAC,aAAA,EAAY,SAAkB,EAAA,CAEnC;AAAA,YACAM,2BAAAA,KAAC,OAAA,EAAI,WAAU,kDACb,UAAA;AAAA,cAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,0CACZ,UAAA;AAAA,gBAAA,wCACER,0BAAe,OAAf,EAAqB,WAAU,uCAC7B,UAAA,OACH;AAAA,gBAED,eACCE,2BAAAA,IAACF,0BAAe,aAAf,EAA2B,WAAU,sCACnC,UAAA,aACH;AAAA,gBAED;AAAA,cAAA,GACH;AAAA,cACC,iBACCE,2BAAAA,IAACQ,OAAAA,QAAA,EAAO,SAAQ,WAAU,UAAQ,MAAC,MAAK,MAAK,SAAS,eACnD,UAAA,eAAe,SAAA,CAClB;AAAA,YAAA,EAAA,CAEJ;AAAA,UAAA,GACF;AAAA,UACC,aACCR,2BAAAA,IAACF,0BAAe,OAAf,EAAqB,SAAO,MAC3B,UAAAE,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAY;AAAA,cACZ,WAAU;AAAA,cAEV,UAAAA,2BAAAA,IAACS,qBAAA,EAAU,MAAM,IAAI,eAAY,OAAA,CAAO;AAAA,YAAA;AAAA,UAAA,EAC1C,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,MAAM,cAAc;;;;"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
5
|
+
const React = require("react");
|
|
6
|
+
const cn = require("../../utils/cn.cjs");
|
|
7
|
+
const VerifiedIcon = require("../Icons/VerifiedIcon.cjs");
|
|
8
|
+
const ProfileOnlineStatus = require("../ProfileOnlineStatus/ProfileOnlineStatus.cjs");
|
|
9
|
+
function _interopNamespaceDefault(e) {
|
|
10
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
11
|
+
if (e) {
|
|
12
|
+
for (const k in e) {
|
|
13
|
+
if (k !== "default") {
|
|
14
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
15
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: () => e[k]
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
n.default = e;
|
|
23
|
+
return Object.freeze(n);
|
|
24
|
+
}
|
|
25
|
+
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
26
|
+
const UserDisplayName = React__namespace.forwardRef(
|
|
27
|
+
({
|
|
28
|
+
ambassador,
|
|
29
|
+
ambassadorLabel = "Ambassador",
|
|
30
|
+
children,
|
|
31
|
+
className,
|
|
32
|
+
component = "span",
|
|
33
|
+
noWrap = true,
|
|
34
|
+
onlineLabel = "Online",
|
|
35
|
+
showOnlineStatus,
|
|
36
|
+
verified,
|
|
37
|
+
verifiedLabel = "Verified",
|
|
38
|
+
...props
|
|
39
|
+
}, ref) => {
|
|
40
|
+
const Component = component;
|
|
41
|
+
const badge = ambassador ? { label: ambassadorLabel, tint: "text-success-content" } : verified ? { label: verifiedLabel, tint: "text-content-primary" } : null;
|
|
42
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
43
|
+
Component,
|
|
44
|
+
{
|
|
45
|
+
ref,
|
|
46
|
+
className: cn.cn("inline-flex max-w-full items-center", className),
|
|
47
|
+
...props,
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn.cn("min-w-0", noWrap && "truncate"), children }),
|
|
50
|
+
badge && /* @__PURE__ */ jsxRuntime.jsx(
|
|
51
|
+
"span",
|
|
52
|
+
{
|
|
53
|
+
role: "img",
|
|
54
|
+
"aria-label": badge.label,
|
|
55
|
+
className: cn.cn("ml-2 inline-flex shrink-0 items-center", badge.tint),
|
|
56
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(VerifiedIcon.VerifiedIcon, { size: 16 })
|
|
57
|
+
}
|
|
58
|
+
),
|
|
59
|
+
showOnlineStatus && /* @__PURE__ */ jsxRuntime.jsx(ProfileOnlineStatus.ProfileOnlineStatus, { label: onlineLabel, className: "shrink-0 ml-2" })
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
UserDisplayName.displayName = "UserDisplayName";
|
|
66
|
+
exports.UserDisplayName = UserDisplayName;
|
|
67
|
+
//# sourceMappingURL=UserDisplayName.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserDisplayName.cjs","sources":["../../../../src/components/UserDisplayName/UserDisplayName.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { VerifiedIcon } from \"../Icons/VerifiedIcon\";\nimport { ProfileOnlineStatus } from \"../ProfileOnlineStatus/ProfileOnlineStatus\";\n\nexport interface UserDisplayNameProps extends React.HTMLAttributes<HTMLElement> {\n /** Render an ambassador badge after the name. */\n ambassador?: boolean;\n /** Accessible label for the ambassador badge. @default \"Ambassador\" */\n ambassadorLabel?: string;\n /** HTML element used for the root wrapper. @default \"span\" */\n component?: \"span\" | \"h1\" | \"h2\" | \"h3\" | \"p\" | \"div\";\n /** Truncate the display name on a single line. @default true */\n noWrap?: boolean;\n /** Accessible label for the online-status indicator. @default \"Online\" */\n onlineLabel?: string;\n /** Render the inline online-status indicator after the name. @default false */\n showOnlineStatus?: boolean;\n /** Render a verified badge after the name (ignored when `ambassador` is set). */\n verified?: boolean;\n /** Accessible label for the verified badge. @default \"Verified\" */\n verifiedLabel?: string;\n}\n\n/**\n * Renders a user's display name with optional ambassador/verified badges and an\n * online-status indicator. Only the name shrinks and truncates; trailing badges\n * and the online-status indicator stay visible on the same line.\n *\n * Typography is not baked in: pass a `typography-*` utility via `className` on\n * the root and the name inherits it. Use `typography-body-small-14px-semibold`\n * for the standard display-name scale.\n *\n * When both `ambassador` and `verified` are set, the ambassador badge takes\n * precedence. Its tint uses `text-success-content` (not `text-icons-brand-green`)\n * so the green darkens in light mode and lightens in dark mode, matching\n * {@link ProfileOnlineStatus}; `text-icons-brand-green` is fixed across modes.\n *\n * @example\n * ```tsx\n * <UserDisplayName className=\"typography-body-small-14px-semibold\">Jane Doe</UserDisplayName>\n * ```\n */\nexport const UserDisplayName = React.forwardRef<HTMLElement, UserDisplayNameProps>(\n (\n {\n ambassador,\n ambassadorLabel = \"Ambassador\",\n children,\n className,\n component = \"span\",\n noWrap = true,\n onlineLabel = \"Online\",\n showOnlineStatus,\n verified,\n verifiedLabel = \"Verified\",\n ...props\n },\n ref,\n ) => {\n const Component = component as React.ElementType;\n\n const badge = ambassador\n ? { label: ambassadorLabel, tint: \"text-success-content\" }\n : verified\n ? { label: verifiedLabel, tint: \"text-content-primary\" }\n : null;\n\n return (\n <Component\n ref={ref}\n className={cn(\"inline-flex max-w-full items-center\", className)}\n {...props}\n >\n <span className={cn(\"min-w-0\", noWrap && \"truncate\")}>{children}</span>\n {badge && (\n <span\n role=\"img\"\n aria-label={badge.label}\n className={cn(\"ml-2 inline-flex shrink-0 items-center\", badge.tint)}\n >\n <VerifiedIcon size={16} />\n </span>\n )}\n {showOnlineStatus && <ProfileOnlineStatus label={onlineLabel} className=\"shrink-0 ml-2\" />}\n </Component>\n );\n },\n);\n\nUserDisplayName.displayName = \"UserDisplayName\";\n"],"names":["React","jsxs","cn","jsx","VerifiedIcon","ProfileOnlineStatus"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA2CO,MAAM,kBAAkBA,iBAAM;AAAA,EACnC,CACE;AAAA,IACE;AAAA,IACA,kBAAkB;AAAA,IAClB;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,YAAY;AAElB,UAAM,QAAQ,aACV,EAAE,OAAO,iBAAiB,MAAM,uBAAA,IAChC,WACE,EAAE,OAAO,eAAe,MAAM,2BAC9B;AAEN,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAWC,GAAAA,GAAG,uCAAuC,SAAS;AAAA,QAC7D,GAAG;AAAA,QAEJ,UAAA;AAAA,UAAAC,+BAAC,UAAK,WAAWD,GAAAA,GAAG,WAAW,UAAU,UAAU,GAAI,UAAS;AAAA,UAC/D,SACCC,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAY,MAAM;AAAA,cAClB,WAAWD,GAAAA,GAAG,0CAA0C,MAAM,IAAI;AAAA,cAElE,UAAAC,2BAAAA,IAACC,aAAAA,cAAA,EAAa,MAAM,GAAA,CAAI;AAAA,YAAA;AAAA,UAAA;AAAA,UAG3B,oBAAoBD,2BAAAA,IAACE,yCAAA,EAAoB,OAAO,aAAa,WAAU,gBAAA,CAAgB;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAG9F;AACF;AAEA,gBAAgB,cAAc;;"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
5
|
+
const React = require("react");
|
|
6
|
+
const cn = require("../../utils/cn.cjs");
|
|
7
|
+
function _interopNamespaceDefault(e) {
|
|
8
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
9
|
+
if (e) {
|
|
10
|
+
for (const k in e) {
|
|
11
|
+
if (k !== "default") {
|
|
12
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: () => e[k]
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
24
|
+
const HANDLE_SYMBOL = "@";
|
|
25
|
+
const UserHandle = React__namespace.forwardRef(
|
|
26
|
+
({ children, className, ...props }, ref) => {
|
|
27
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28
|
+
"span",
|
|
29
|
+
{
|
|
30
|
+
ref,
|
|
31
|
+
className: cn.cn(
|
|
32
|
+
"typography-body-small-14px-regular block max-w-full truncate text-content-secondary",
|
|
33
|
+
className
|
|
34
|
+
),
|
|
35
|
+
...props,
|
|
36
|
+
children: [
|
|
37
|
+
HANDLE_SYMBOL,
|
|
38
|
+
children
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
UserHandle.displayName = "UserHandle";
|
|
45
|
+
exports.UserHandle = UserHandle;
|
|
46
|
+
//# sourceMappingURL=UserHandle.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserHandle.cjs","sources":["../../../../src/components/UserHandle/UserHandle.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nconst HANDLE_SYMBOL = \"@\";\n\nexport interface UserHandleProps extends React.HTMLAttributes<HTMLSpanElement> {}\n\n/**\n * Renders a user handle prefixed with the `@` symbol as muted, truncated\n * secondary text.\n *\n * @example\n * ```tsx\n * <UserHandle>jane_doe</UserHandle>\n * ```\n */\nexport const UserHandle = React.forwardRef<HTMLSpanElement, UserHandleProps>(\n ({ children, className, ...props }, ref) => {\n return (\n <span\n ref={ref}\n className={cn(\n \"typography-body-small-14px-regular block max-w-full truncate text-content-secondary\",\n className,\n )}\n {...props}\n >\n {HANDLE_SYMBOL}\n {children}\n </span>\n );\n },\n);\n\nUserHandle.displayName = \"UserHandle\";\n"],"names":["React","jsxs","cn"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAGA,MAAM,gBAAgB;AAaf,MAAM,aAAaA,iBAAM;AAAA,EAC9B,CAAC,EAAE,UAAU,WAAW,GAAG,MAAA,GAAS,QAAQ;AAC1C,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAWC,GAAAA;AAAAA,UACT;AAAA,UACA;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA;AAAA,UACA;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEA,WAAW,cAAc;;"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
5
|
+
const React = require("react");
|
|
6
|
+
const cn = require("../../utils/cn.cjs");
|
|
7
|
+
const getInitials = require("../../utils/getInitials.cjs");
|
|
8
|
+
const Avatar = require("../Avatar/Avatar.cjs");
|
|
9
|
+
const BellOffIcon = require("../Icons/BellOffIcon.cjs");
|
|
10
|
+
const UserDisplayName = require("../UserDisplayName/UserDisplayName.cjs");
|
|
11
|
+
const UserHandle = require("../UserHandle/UserHandle.cjs");
|
|
12
|
+
function _interopNamespaceDefault(e) {
|
|
13
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
14
|
+
if (e) {
|
|
15
|
+
for (const k in e) {
|
|
16
|
+
if (k !== "default") {
|
|
17
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
18
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: () => e[k]
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
n.default = e;
|
|
26
|
+
return Object.freeze(n);
|
|
27
|
+
}
|
|
28
|
+
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
29
|
+
const AVATAR_SIZES = [16, 24, 32, 40, 48, 64, 88, 148];
|
|
30
|
+
const getNearestAvatarSize = (size) => AVATAR_SIZES.reduce(
|
|
31
|
+
(prev, curr) => Math.abs(curr - size) < Math.abs(prev - size) ? curr : prev
|
|
32
|
+
);
|
|
33
|
+
const UserItem = React__namespace.forwardRef(
|
|
34
|
+
({
|
|
35
|
+
user,
|
|
36
|
+
avatarSize,
|
|
37
|
+
isOnline = false,
|
|
38
|
+
isMuted = false,
|
|
39
|
+
showOnlineStatus,
|
|
40
|
+
showHandle = true,
|
|
41
|
+
showAvatar = true,
|
|
42
|
+
className,
|
|
43
|
+
...props
|
|
44
|
+
}, ref) => {
|
|
45
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
46
|
+
"div",
|
|
47
|
+
{
|
|
48
|
+
ref,
|
|
49
|
+
className: cn.cn("relative flex w-full items-center justify-start px-2 py-1", className),
|
|
50
|
+
...props,
|
|
51
|
+
children: [
|
|
52
|
+
isMuted && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 z-1 flex rounded-xs bg-surface-primary p-1", children: /* @__PURE__ */ jsxRuntime.jsx(BellOffIcon.BellOffIcon, { size: 16 }) }),
|
|
53
|
+
showAvatar && /* @__PURE__ */ jsxRuntime.jsx(
|
|
54
|
+
Avatar.Avatar,
|
|
55
|
+
{
|
|
56
|
+
size: getNearestAvatarSize(avatarSize || 48),
|
|
57
|
+
src: user.avatarUri?.url,
|
|
58
|
+
alt: user.displayName,
|
|
59
|
+
fallback: getInitials.getInitials(user.displayName),
|
|
60
|
+
onlineIndicator: Boolean(showOnlineStatus && isOnline)
|
|
61
|
+
}
|
|
62
|
+
),
|
|
63
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-hidden pl-2", children: [
|
|
64
|
+
/* @__PURE__ */ jsxRuntime.jsx(UserDisplayName.UserDisplayName, { className: "typography-body-small-14px-semibold", children: user.nickname || user.displayName }),
|
|
65
|
+
showHandle && /* @__PURE__ */ jsxRuntime.jsx(UserHandle.UserHandle, { children: user.handle })
|
|
66
|
+
] })
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
UserItem.displayName = "UserItem";
|
|
73
|
+
exports.UserItem = UserItem;
|
|
74
|
+
//# sourceMappingURL=UserItem.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserItem.cjs","sources":["../../../../src/components/UserItem/UserItem.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { getInitials } from \"../../utils/getInitials\";\nimport { Avatar } from \"../Avatar/Avatar\";\nimport { BellOffIcon } from \"../Icons/BellOffIcon\";\nimport { UserDisplayName } from \"../UserDisplayName/UserDisplayName\";\nimport { UserHandle } from \"../UserHandle/UserHandle\";\n\nconst AVATAR_SIZES = [16, 24, 32, 40, 48, 64, 88, 148] as const;\ntype AvatarSizeToken = (typeof AVATAR_SIZES)[number];\n\n/** Snap an arbitrary pixel size to the nearest supported {@link Avatar} size token. */\nconst getNearestAvatarSize = (size: number): AvatarSizeToken =>\n AVATAR_SIZES.reduce((prev, curr) =>\n Math.abs(curr - size) < Math.abs(prev - size) ? curr : prev,\n );\n\n/** Minimal user shape consumed by {@link UserItem}. */\nexport type UserItemUser = {\n avatarUri?: { url: string; url2x?: string };\n displayName: string;\n handle: string;\n nickname?: string;\n};\n\nexport interface UserItemProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The user to display. */\n user: UserItemUser;\n /** Desired avatar size in px; snapped to the nearest supported token. @default 48 */\n avatarSize?: number;\n /** Show the muted indicator in the bottom-left corner. @default false */\n isMuted?: boolean;\n /** Whether the user is online (only shown when `showOnlineStatus` is also set). @default false */\n isOnline?: boolean;\n /** Render the avatar. @default true */\n showAvatar?: boolean;\n /** Render the handle line under the display name. @default true */\n showHandle?: boolean;\n /** Enable the avatar online indicator (combined with `isOnline`). */\n showOnlineStatus?: boolean;\n}\n\n/**\n * A compact user row showing an avatar, display name (or nickname) and handle,\n * with optional online and muted indicators.\n *\n * @example\n * ```tsx\n * <UserItem user={{ displayName: \"Jane Doe\", handle: \"jane_doe\" }} />\n * ```\n */\nexport const UserItem = React.forwardRef<HTMLDivElement, UserItemProps>(\n (\n {\n user,\n avatarSize,\n isOnline = false,\n isMuted = false,\n showOnlineStatus,\n showHandle = true,\n showAvatar = true,\n className,\n ...props\n },\n ref,\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\"relative flex w-full items-center justify-start px-2 py-1\", className)}\n {...props}\n >\n {isMuted && (\n <div className=\"absolute bottom-0 left-0 z-1 flex rounded-xs bg-surface-primary p-1\">\n <BellOffIcon size={16} />\n </div>\n )}\n {showAvatar && (\n <Avatar\n size={getNearestAvatarSize(avatarSize || 48)}\n src={user.avatarUri?.url}\n alt={user.displayName}\n fallback={getInitials(user.displayName)}\n onlineIndicator={Boolean(showOnlineStatus && isOnline)}\n />\n )}\n <div className=\"flex-1 overflow-hidden pl-2\">\n <UserDisplayName className=\"typography-body-small-14px-semibold\">\n {user.nickname || user.displayName}\n </UserDisplayName>\n {showHandle && <UserHandle>{user.handle}</UserHandle>}\n </div>\n </div>\n );\n },\n);\n\nUserItem.displayName = \"UserItem\";\n"],"names":["React","jsxs","cn","jsx","BellOffIcon","Avatar","getInitials","UserDisplayName","UserHandle"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,MAAM,eAAe,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG;AAIrD,MAAM,uBAAuB,CAAC,SAC5B,aAAa;AAAA,EAAO,CAAC,MAAM,SACzB,KAAK,IAAI,OAAO,IAAI,IAAI,KAAK,IAAI,OAAO,IAAI,IAAI,OAAO;AACzD;AAoCK,MAAM,WAAWA,iBAAM;AAAA,EAC5B,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,UAAU;AAAA,IACV;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAWC,GAAAA,GAAG,6DAA6D,SAAS;AAAA,QACnF,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,WACCC,2BAAAA,IAAC,SAAI,WAAU,uEACb,yCAACC,YAAAA,aAAA,EAAY,MAAM,IAAI,EAAA,CACzB;AAAA,UAED,cACCD,2BAAAA;AAAAA,YAACE,OAAAA;AAAAA,YAAA;AAAA,cACC,MAAM,qBAAqB,cAAc,EAAE;AAAA,cAC3C,KAAK,KAAK,WAAW;AAAA,cACrB,KAAK,KAAK;AAAA,cACV,UAAUC,YAAAA,YAAY,KAAK,WAAW;AAAA,cACtC,iBAAiB,QAAQ,oBAAoB,QAAQ;AAAA,YAAA;AAAA,UAAA;AAAA,UAGzDL,2BAAAA,KAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,YAAAE,+BAACI,gBAAAA,mBAAgB,WAAU,uCACxB,UAAA,KAAK,YAAY,KAAK,aACzB;AAAA,YACC,cAAcJ,2BAAAA,IAACK,WAAAA,YAAA,EAAY,UAAA,KAAK,OAAA,CAAO;AAAA,UAAA,EAAA,CAC1C;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,SAAS,cAAc;;"}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -31,6 +31,7 @@ const Divider = require("./components/Divider/Divider.cjs");
|
|
|
31
31
|
const Drawer = require("./components/Drawer/Drawer.cjs");
|
|
32
32
|
const DropdownMenu = require("./components/DropdownMenu/DropdownMenu.cjs");
|
|
33
33
|
const EmptyState = require("./components/EmptyState/EmptyState.cjs");
|
|
34
|
+
const FanFollowerCount = require("./components/FanFollowerCount/FanFollowerCount.cjs");
|
|
34
35
|
const IconButton = require("./components/IconButton/IconButton.cjs");
|
|
35
36
|
const AddIcon = require("./components/Icons/AddIcon.cjs");
|
|
36
37
|
const AffiliatesIcon = require("./components/Icons/AffiliatesIcon.cjs");
|
|
@@ -100,6 +101,7 @@ const ForwardIcon = require("./components/Icons/ForwardIcon.cjs");
|
|
|
100
101
|
const GalleryIcon = require("./components/Icons/GalleryIcon.cjs");
|
|
101
102
|
const GameIcon = require("./components/Icons/GameIcon.cjs");
|
|
102
103
|
const GenderIcon = require("./components/Icons/GenderIcon.cjs");
|
|
104
|
+
const GifIcon = require("./components/Icons/GifIcon.cjs");
|
|
103
105
|
const GiftIcon = require("./components/Icons/GiftIcon.cjs");
|
|
104
106
|
const GoogleIcon = require("./components/Icons/GoogleIcon.cjs");
|
|
105
107
|
const HealthIcon = require("./components/Icons/HealthIcon.cjs");
|
|
@@ -184,6 +186,7 @@ const UserIcon = require("./components/Icons/UserIcon.cjs");
|
|
|
184
186
|
const UserMenuIcon = require("./components/Icons/UserMenuIcon.cjs");
|
|
185
187
|
const UsersIcon = require("./components/Icons/UsersIcon.cjs");
|
|
186
188
|
const VaultIcon = require("./components/Icons/VaultIcon.cjs");
|
|
189
|
+
const VerifiedIcon = require("./components/Icons/VerifiedIcon.cjs");
|
|
187
190
|
const VideoIcon = require("./components/Icons/VideoIcon.cjs");
|
|
188
191
|
const VipBadgeIcon = require("./components/Icons/VipBadgeIcon.cjs");
|
|
189
192
|
const WalletIcon = require("./components/Icons/WalletIcon.cjs");
|
|
@@ -195,6 +198,7 @@ const WifiOnIcon = require("./components/Icons/WifiOnIcon.cjs");
|
|
|
195
198
|
const WrenchIcon = require("./components/Icons/WrenchIcon.cjs");
|
|
196
199
|
const InfoBox = require("./components/InfoBox/InfoBox.cjs");
|
|
197
200
|
const InlineEdit = require("./components/InlineEdit/InlineEdit.cjs");
|
|
201
|
+
const Link = require("./components/Link/Link.cjs");
|
|
198
202
|
const Loader = require("./components/Loader/Loader.cjs");
|
|
199
203
|
const Logo = require("./components/Logo/Logo.cjs");
|
|
200
204
|
const MobileStepper = require("./components/MobileStepper/MobileStepper.cjs");
|
|
@@ -202,9 +206,13 @@ const OnlineBlinkingIcon = require("./components/OnlineBlinkingIcon/OnlineBlinki
|
|
|
202
206
|
const Pagination = require("./components/Pagination/Pagination.cjs");
|
|
203
207
|
const PasswordField = require("./components/PasswordField/PasswordField.cjs");
|
|
204
208
|
const Pill = require("./components/Pill/Pill.cjs");
|
|
209
|
+
const ProfileOnlineStatus = require("./components/ProfileOnlineStatus/ProfileOnlineStatus.cjs");
|
|
210
|
+
const ProfileStatus = require("./components/ProfileStatus/ProfileStatus.cjs");
|
|
205
211
|
const ProgressBar = require("./components/ProgressBar/ProgressBar.cjs");
|
|
206
212
|
const Radio = require("./components/Radio/Radio.cjs");
|
|
207
213
|
const RadioGroup = require("./components/RadioGroup/RadioGroup.cjs");
|
|
214
|
+
const RatingSummary = require("./components/RatingSummary/RatingSummary.cjs");
|
|
215
|
+
const ReviewCard = require("./components/ReviewCard/ReviewCard.cjs");
|
|
208
216
|
const SearchField = require("./components/SearchField/SearchField.cjs");
|
|
209
217
|
const Select = require("./components/Select/Select.cjs");
|
|
210
218
|
const Skeleton = require("./components/Skeleton/Skeleton.cjs");
|
|
@@ -225,7 +233,11 @@ const TextArea = require("./components/TextArea/TextArea.cjs");
|
|
|
225
233
|
const TextField = require("./components/TextField/TextField.cjs");
|
|
226
234
|
const Toast = require("./components/Toast/Toast.cjs");
|
|
227
235
|
const Tooltip = require("./components/Tooltip/Tooltip.cjs");
|
|
236
|
+
const UserDisplayName = require("./components/UserDisplayName/UserDisplayName.cjs");
|
|
237
|
+
const UserHandle = require("./components/UserHandle/UserHandle.cjs");
|
|
238
|
+
const UserItem = require("./components/UserItem/UserItem.cjs");
|
|
228
239
|
const cn = require("./utils/cn.cjs");
|
|
240
|
+
const getInitials = require("./utils/getInitials.cjs");
|
|
229
241
|
const useSuppressClickAfterDrag = require("./utils/useSuppressClickAfterDrag.cjs");
|
|
230
242
|
Object.defineProperty(exports, "Slot", {
|
|
231
243
|
enumerable: true,
|
|
@@ -303,6 +315,7 @@ exports.DropdownMenuRadioItem = DropdownMenu.DropdownMenuRadioItem;
|
|
|
303
315
|
exports.DropdownMenuSeparator = DropdownMenu.DropdownMenuSeparator;
|
|
304
316
|
exports.DropdownMenuTrigger = DropdownMenu.DropdownMenuTrigger;
|
|
305
317
|
exports.EmptyState = EmptyState.EmptyState;
|
|
318
|
+
exports.FanFollowerCount = FanFollowerCount.FanFollowerCount;
|
|
306
319
|
exports.IconButton = IconButton.IconButton;
|
|
307
320
|
exports.AddIcon = AddIcon.AddIcon;
|
|
308
321
|
exports.AffiliatesIcon = AffiliatesIcon.AffiliatesIcon;
|
|
@@ -372,6 +385,7 @@ exports.ForwardIcon = ForwardIcon.ForwardIcon;
|
|
|
372
385
|
exports.GalleryIcon = GalleryIcon.GalleryIcon;
|
|
373
386
|
exports.GameIcon = GameIcon.GameIcon;
|
|
374
387
|
exports.GenderIcon = GenderIcon.GenderIcon;
|
|
388
|
+
exports.GifIcon = GifIcon.GifIcon;
|
|
375
389
|
exports.GiftIcon = GiftIcon.GiftIcon;
|
|
376
390
|
exports.GoogleIcon = GoogleIcon.GoogleIcon;
|
|
377
391
|
exports.HealthIcon = HealthIcon.HealthIcon;
|
|
@@ -456,6 +470,7 @@ exports.UserIcon = UserIcon.UserIcon;
|
|
|
456
470
|
exports.UserMenuIcon = UserMenuIcon.UserMenuIcon;
|
|
457
471
|
exports.UsersIcon = UsersIcon.UsersIcon;
|
|
458
472
|
exports.VaultIcon = VaultIcon.VaultIcon;
|
|
473
|
+
exports.VerifiedIcon = VerifiedIcon.VerifiedIcon;
|
|
459
474
|
exports.VideoIcon = VideoIcon.VideoIcon;
|
|
460
475
|
exports.VipBadgeIcon = VipBadgeIcon.VipBadgeIcon;
|
|
461
476
|
exports.WalletIcon = WalletIcon.WalletIcon;
|
|
@@ -469,6 +484,7 @@ exports.InfoBox = InfoBox.InfoBox;
|
|
|
469
484
|
exports.InfoBoxContent = InfoBox.InfoBoxContent;
|
|
470
485
|
exports.InfoBoxTrigger = InfoBox.InfoBoxTrigger;
|
|
471
486
|
exports.InlineEdit = InlineEdit.InlineEdit;
|
|
487
|
+
exports.Link = Link.Link;
|
|
472
488
|
exports.Loader = Loader.Loader;
|
|
473
489
|
exports.Logo = Logo.Logo;
|
|
474
490
|
exports.MobileStepper = MobileStepper.MobileStepper;
|
|
@@ -476,9 +492,13 @@ exports.OnlineBlinkingIcon = OnlineBlinkingIcon.OnlineBlinkingIcon;
|
|
|
476
492
|
exports.Pagination = Pagination.Pagination;
|
|
477
493
|
exports.PasswordField = PasswordField.PasswordField;
|
|
478
494
|
exports.Pill = Pill.Pill;
|
|
495
|
+
exports.ProfileOnlineStatus = ProfileOnlineStatus.ProfileOnlineStatus;
|
|
496
|
+
exports.ProfileStatus = ProfileStatus.ProfileStatus;
|
|
479
497
|
exports.ProgressBar = ProgressBar.ProgressBar;
|
|
480
498
|
exports.Radio = Radio.Radio;
|
|
481
499
|
exports.RadioGroup = RadioGroup.RadioGroup;
|
|
500
|
+
exports.RatingSummary = RatingSummary.RatingSummary;
|
|
501
|
+
exports.ReviewCard = ReviewCard.ReviewCard;
|
|
482
502
|
exports.SearchField = SearchField.SearchField;
|
|
483
503
|
exports.Select = Select.Select;
|
|
484
504
|
exports.SelectContent = Select.SelectContent;
|
|
@@ -528,6 +548,10 @@ exports.Tooltip = Tooltip.Tooltip;
|
|
|
528
548
|
exports.TooltipContent = Tooltip.TooltipContent;
|
|
529
549
|
exports.TooltipProvider = Tooltip.TooltipProvider;
|
|
530
550
|
exports.TooltipTrigger = Tooltip.TooltipTrigger;
|
|
551
|
+
exports.UserDisplayName = UserDisplayName.UserDisplayName;
|
|
552
|
+
exports.UserHandle = UserHandle.UserHandle;
|
|
553
|
+
exports.UserItem = UserItem.UserItem;
|
|
531
554
|
exports.cn = cn.cn;
|
|
555
|
+
exports.getInitials = getInitials.getInitials;
|
|
532
556
|
exports.useSuppressClickAfterDrag = useSuppressClickAfterDrag.useSuppressClickAfterDrag;
|
|
533
557
|
//# sourceMappingURL=index.cjs.map
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
+
const cleanSpaces = (str) => str.trim().replace(/\s+/g, " ");
|
|
5
|
+
const getInitials = (str) => {
|
|
6
|
+
if (!str) return "";
|
|
7
|
+
return cleanSpaces(str).split(" ").map((word) => word.length ? ([...word][0] ?? "").toUpperCase() : "").slice(0, 2).join("");
|
|
8
|
+
};
|
|
9
|
+
exports.getInitials = getInitials;
|
|
10
|
+
//# sourceMappingURL=getInitials.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getInitials.cjs","sources":["../../../src/utils/getInitials.ts"],"sourcesContent":["/** Trim leading/trailing whitespace and collapse internal runs of whitespace to a single space. */\nconst cleanSpaces = (str: string): string => str.trim().replace(/\\s+/g, \" \");\n\n/**\n * Returns the first letters of the first one or two words in a given string, capitalized.\n * @example\n * getInitials(\"Ciao Bello\"); // \"CB\"\n * getInitials(\"JavaScript\"); // \"J\"\n * getInitials(undefined); // \"\"\n */\nexport const getInitials = (str?: string | null): string => {\n if (!str) return \"\";\n return cleanSpaces(str)\n .split(\" \")\n .map((word) => (word.length ? ([...word][0] ?? \"\").toUpperCase() : \"\"))\n .slice(0, 2)\n .join(\"\");\n};\n"],"names":[],"mappings":";;;AACA,MAAM,cAAc,CAAC,QAAwB,IAAI,OAAO,QAAQ,QAAQ,GAAG;AASpE,MAAM,cAAc,CAAC,QAAgC;AAC1D,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO,YAAY,GAAG,EACnB,MAAM,GAAG,EACT,IAAI,CAAC,SAAU,KAAK,UAAU,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,YAAA,IAAgB,EAAG,EACrE,MAAM,GAAG,CAAC,EACV,KAAK,EAAE;AACZ;;"}
|