@borisj74/bv-ds 0.1.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/LICENSE +21 -0
- package/README.md +94 -0
- package/dist/index.cjs +33885 -0
- package/dist/index.d.cts +2715 -0
- package/dist/index.d.ts +2715 -0
- package/dist/index.js +33717 -0
- package/package.json +67 -0
- package/src/components/ActivityFeed/ActivityFeed.tsx +48 -0
- package/src/components/ActivityFeed/index.ts +2 -0
- package/src/components/ActivityGauge/ActivityGauge.tsx +155 -0
- package/src/components/ActivityGauge/index.ts +7 -0
- package/src/components/AdvancedFilterBar/AdvancedFilterBar.tsx +80 -0
- package/src/components/AdvancedFilterBar/index.ts +2 -0
- package/src/components/Alert/Alert.tsx +210 -0
- package/src/components/Alert/index.ts +2 -0
- package/src/components/Avatar/Avatar.tsx +111 -0
- package/src/components/Avatar/index.ts +2 -0
- package/src/components/AvatarAddButton/AvatarAddButton.tsx +65 -0
- package/src/components/AvatarAddButton/index.ts +5 -0
- package/src/components/AvatarGroup/AvatarGroup.tsx +79 -0
- package/src/components/AvatarGroup/index.ts +6 -0
- package/src/components/AvatarLabelGroup/AvatarLabelGroup.tsx +62 -0
- package/src/components/AvatarLabelGroup/index.ts +5 -0
- package/src/components/AvatarProfilePhoto/AvatarProfilePhoto.tsx +117 -0
- package/src/components/AvatarProfilePhoto/index.ts +5 -0
- package/src/components/Badge/ColorBadge.tsx +36 -0
- package/src/components/Badge/ModernBadge.tsx +38 -0
- package/src/components/Badge/PillBadge.tsx +36 -0
- package/src/components/Badge/badgeShared.tsx +139 -0
- package/src/components/Badge/index.ts +7 -0
- package/src/components/BadgeCloseX/BadgeCloseX.tsx +64 -0
- package/src/components/BadgeCloseX/index.ts +2 -0
- package/src/components/BadgeGroup/BadgeGroup.tsx +61 -0
- package/src/components/BadgeGroup/index.ts +7 -0
- package/src/components/BreadcrumbButtonBase/BreadcrumbButtonBase.tsx +75 -0
- package/src/components/BreadcrumbButtonBase/index.ts +5 -0
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +62 -0
- package/src/components/Breadcrumbs/index.ts +2 -0
- package/src/components/Button/Button.tsx +71 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/ButtonCloseX/ButtonCloseX.tsx +54 -0
- package/src/components/ButtonCloseX/index.ts +2 -0
- package/src/components/ButtonDestructive/ButtonDestructive.tsx +67 -0
- package/src/components/ButtonDestructive/index.ts +6 -0
- package/src/components/ButtonGroup/ButtonGroup.tsx +28 -0
- package/src/components/ButtonGroup/index.ts +2 -0
- package/src/components/ButtonGroupSegment/ButtonGroupSegment.tsx +54 -0
- package/src/components/ButtonGroupSegment/index.ts +5 -0
- package/src/components/ButtonUtility/ButtonUtility.tsx +67 -0
- package/src/components/ButtonUtility/index.ts +6 -0
- package/src/components/CalendarCell/CalendarCell.tsx +82 -0
- package/src/components/CalendarCell/index.ts +2 -0
- package/src/components/CalendarCellDayWeekView/CalendarCellDayWeekView.tsx +56 -0
- package/src/components/CalendarCellDayWeekView/index.ts +2 -0
- package/src/components/CalendarColumnHeader/CalendarColumnHeader.tsx +45 -0
- package/src/components/CalendarColumnHeader/index.ts +5 -0
- package/src/components/CalendarDateIcon/CalendarDateIcon.tsx +25 -0
- package/src/components/CalendarDateIcon/index.ts +2 -0
- package/src/components/CalendarEvent/CalendarEvent.tsx +76 -0
- package/src/components/CalendarEvent/index.ts +2 -0
- package/src/components/CalendarEventDayWeekView/CalendarEventDayWeekView.tsx +76 -0
- package/src/components/CalendarEventDayWeekView/index.ts +2 -0
- package/src/components/CalendarHeader/CalendarHeader.tsx +47 -0
- package/src/components/CalendarHeader/index.ts +2 -0
- package/src/components/CalendarRowLabel/CalendarRowLabel.tsx +21 -0
- package/src/components/CalendarRowLabel/index.ts +2 -0
- package/src/components/CalendarTimemarker/CalendarTimemarker.tsx +46 -0
- package/src/components/CalendarTimemarker/index.ts +5 -0
- package/src/components/CalendarViewDropdown/CalendarViewDropdown.tsx +101 -0
- package/src/components/CalendarViewDropdown/index.ts +6 -0
- package/src/components/CardHeader/CardHeader.tsx +57 -0
- package/src/components/CardHeader/index.ts +2 -0
- package/src/components/CarouselArrow/CarouselArrow.tsx +47 -0
- package/src/components/CarouselArrow/index.ts +6 -0
- package/src/components/CarouselImage/CarouselImage.tsx +60 -0
- package/src/components/CarouselImage/index.ts +2 -0
- package/src/components/Change/Change.tsx +73 -0
- package/src/components/Change/index.ts +2 -0
- package/src/components/ChartLegend/ChartLegend.tsx +38 -0
- package/src/components/ChartLegend/index.ts +2 -0
- package/src/components/ChartMarker/ChartMarker.tsx +54 -0
- package/src/components/ChartMarker/index.ts +2 -0
- package/src/components/ChartMini/ChartMini.tsx +86 -0
- package/src/components/ChartMini/index.ts +2 -0
- package/src/components/ChartTooltip/ChartTooltip.tsx +44 -0
- package/src/components/ChartTooltip/index.ts +2 -0
- package/src/components/Checkbox/Checkbox.tsx +65 -0
- package/src/components/Checkbox/checkboxBase.tsx +81 -0
- package/src/components/Checkbox/index.ts +3 -0
- package/src/components/CodeSnippet/CodeSnippet.tsx +94 -0
- package/src/components/CodeSnippet/index.ts +2 -0
- package/src/components/CodeSnippetTabs/CodeSnippetTabs.tsx +44 -0
- package/src/components/CodeSnippetTabs/index.ts +2 -0
- package/src/components/CommandBar/CommandBar.tsx +80 -0
- package/src/components/CommandBar/index.ts +2 -0
- package/src/components/CommandBarFooter/CommandBarFooter.tsx +125 -0
- package/src/components/CommandBarFooter/index.ts +5 -0
- package/src/components/CommandBarMenuSection/CommandBarMenuSection.tsx +28 -0
- package/src/components/CommandBarMenuSection/index.ts +2 -0
- package/src/components/CommandBarNavigationIcon/CommandBarNavigationIcon.tsx +47 -0
- package/src/components/CommandBarNavigationIcon/index.ts +2 -0
- package/src/components/CommandDropdownMenuItem/CommandDropdownMenuItem.tsx +51 -0
- package/src/components/CommandDropdownMenuItem/index.ts +2 -0
- package/src/components/CommandInput/CommandInput.tsx +74 -0
- package/src/components/CommandInput/index.ts +2 -0
- package/src/components/CommandShortcut/CommandShortcut.tsx +26 -0
- package/src/components/CommandShortcut/index.ts +2 -0
- package/src/components/ContentDivider/ContentDivider.tsx +80 -0
- package/src/components/ContentDivider/index.ts +6 -0
- package/src/components/ContentFeatureText/ContentFeatureText.tsx +60 -0
- package/src/components/ContentFeatureText/index.ts +5 -0
- package/src/components/ContentHeading/ContentHeading.tsx +43 -0
- package/src/components/ContentHeading/index.ts +5 -0
- package/src/components/ContentParagraph/ContentParagraph.tsx +39 -0
- package/src/components/ContentParagraph/index.ts +5 -0
- package/src/components/ContentQuote/ContentQuote.tsx +114 -0
- package/src/components/ContentQuote/index.ts +6 -0
- package/src/components/ContentRule/ContentRule.tsx +31 -0
- package/src/components/ContentRule/index.ts +2 -0
- package/src/components/ContextMenu/ContextMenu.tsx +67 -0
- package/src/components/ContextMenu/index.ts +7 -0
- package/src/components/ContextMenu/useContextMenu.ts +41 -0
- package/src/components/DatePickerCell/DatePickerCell.tsx +77 -0
- package/src/components/DatePickerCell/index.ts +2 -0
- package/src/components/DatePickerListItem/DatePickerListItem.tsx +39 -0
- package/src/components/DatePickerListItem/index.ts +2 -0
- package/src/components/DatePickerMenu/DatePickerMenu.tsx +131 -0
- package/src/components/DatePickerMenu/index.ts +2 -0
- package/src/components/DropdownAccountListItem/DropdownAccountListItem.tsx +69 -0
- package/src/components/DropdownAccountListItem/index.ts +2 -0
- package/src/components/DropdownMenuFooter/DropdownMenuFooter.tsx +50 -0
- package/src/components/DropdownMenuFooter/index.ts +5 -0
- package/src/components/DropdownMenuHeader/DropdownMenuHeader.tsx +93 -0
- package/src/components/DropdownMenuHeader/index.ts +5 -0
- package/src/components/DropdownMenuItemInsetIcon/DropdownMenuItemInsetIcon.tsx +89 -0
- package/src/components/DropdownMenuItemInsetIcon/index.ts +5 -0
- package/src/components/DropdownMenuListItem/DropdownMenuListItem.tsx +84 -0
- package/src/components/DropdownMenuListItem/index.ts +2 -0
- package/src/components/EmptyState/EmptyState.tsx +65 -0
- package/src/components/EmptyState/index.ts +2 -0
- package/src/components/FeedItemBase/FeedItemBase.tsx +135 -0
- package/src/components/FeedItemBase/index.ts +2 -0
- package/src/components/FileUpload/FileUpload.tsx +112 -0
- package/src/components/FileUpload/index.ts +2 -0
- package/src/components/FileUploadBase/FileUploadBase.tsx +69 -0
- package/src/components/FileUploadBase/index.ts +2 -0
- package/src/components/FileUploadItemBase/FileUploadItemBase.tsx +190 -0
- package/src/components/FileUploadItemBase/index.ts +7 -0
- package/src/components/FilterBar/FilterBar.tsx +62 -0
- package/src/components/FilterBar/index.ts +2 -0
- package/src/components/FilterTabs/FilterTabs.tsx +41 -0
- package/src/components/FilterTabs/index.ts +2 -0
- package/src/components/FiltersDropdownMenu/FiltersDropdownMenu.tsx +104 -0
- package/src/components/FiltersDropdownMenu/index.ts +2 -0
- package/src/components/FiltersSlideoutMenu/FiltersSlideoutMenu.tsx +71 -0
- package/src/components/FiltersSlideoutMenu/index.ts +2 -0
- package/src/components/HeaderNavigation/HeaderNavigation.tsx +178 -0
- package/src/components/HeaderNavigation/index.ts +6 -0
- package/src/components/HelpIcon/HelpIcon.tsx +49 -0
- package/src/components/HelpIcon/index.ts +2 -0
- package/src/components/InputField/InputField.tsx +108 -0
- package/src/components/InputField/index.ts +3 -0
- package/src/components/InputField/inputFieldShared.tsx +68 -0
- package/src/components/LeadingInputField/LeadingInputField.tsx +60 -0
- package/src/components/LeadingInputField/index.ts +2 -0
- package/src/components/LineAndBarChart/LineAndBarChart.tsx +96 -0
- package/src/components/LineAndBarChart/index.ts +2 -0
- package/src/components/LinkMessage/LinkMessage.tsx +52 -0
- package/src/components/LinkMessage/index.ts +2 -0
- package/src/components/LoadingIndicator/LoadingIndicator.tsx +108 -0
- package/src/components/LoadingIndicator/index.ts +6 -0
- package/src/components/MediaMessage/MediaMessage.tsx +109 -0
- package/src/components/MediaMessage/index.ts +2 -0
- package/src/components/MegaInputFieldBase/MegaInputFieldBase.tsx +49 -0
- package/src/components/MegaInputFieldBase/index.ts +5 -0
- package/src/components/Message/Message.tsx +85 -0
- package/src/components/Message/index.ts +3 -0
- package/src/components/Message/messageShared.tsx +73 -0
- package/src/components/MessageAction/MessageAction.tsx +221 -0
- package/src/components/MessageAction/index.ts +2 -0
- package/src/components/MessageActionButton/MessageActionButton.tsx +36 -0
- package/src/components/MessageActionButton/index.ts +2 -0
- package/src/components/MessageActionPanel/MessageActionPanel.tsx +36 -0
- package/src/components/MessageActionPanel/index.ts +2 -0
- package/src/components/MessageReaction/MessageReaction.tsx +37 -0
- package/src/components/MessageReaction/index.ts +2 -0
- package/src/components/MessageStatusIcon/MessageStatusIcon.tsx +54 -0
- package/src/components/MessageStatusIcon/index.ts +2 -0
- package/src/components/MetricItem/MetricItem.tsx +147 -0
- package/src/components/MetricItem/index.ts +2 -0
- package/src/components/ModalActions/ModalActions.tsx +57 -0
- package/src/components/ModalActions/index.ts +2 -0
- package/src/components/ModalHeader/ModalHeader.tsx +99 -0
- package/src/components/ModalHeader/index.ts +2 -0
- package/src/components/MultiSelect/MultiSelect.tsx +118 -0
- package/src/components/MultiSelect/index.ts +2 -0
- package/src/components/NavAccountCard/NavAccountCard.tsx +124 -0
- package/src/components/NavAccountCard/index.ts +2 -0
- package/src/components/NavAccountCardMenuItem/NavAccountCardMenuItem.tsx +101 -0
- package/src/components/NavAccountCardMenuItem/index.ts +5 -0
- package/src/components/NavButton/NavButton.tsx +50 -0
- package/src/components/NavButton/index.ts +2 -0
- package/src/components/NavFeaturedCard/NavFeaturedCard.tsx +82 -0
- package/src/components/NavFeaturedCard/index.ts +2 -0
- package/src/components/NavItemBase/NavItemBase.tsx +79 -0
- package/src/components/NavItemBase/index.ts +2 -0
- package/src/components/NavItemDropdownBase/NavItemDropdownBase.tsx +74 -0
- package/src/components/NavItemDropdownBase/index.ts +2 -0
- package/src/components/NavMenuButton/NavMenuButton.tsx +47 -0
- package/src/components/NavMenuButton/index.ts +2 -0
- package/src/components/Notification/Notification.tsx +102 -0
- package/src/components/Notification/index.ts +2 -0
- package/src/components/NumberInput/NumberInput.tsx +114 -0
- package/src/components/NumberInput/index.ts +2 -0
- package/src/components/PageHeader/PageHeader.tsx +88 -0
- package/src/components/PageHeader/index.ts +2 -0
- package/src/components/Pagination/Pagination.tsx +124 -0
- package/src/components/Pagination/index.ts +2 -0
- package/src/components/PaginationButtonGroupBase/PaginationButtonGroupBase.tsx +69 -0
- package/src/components/PaginationButtonGroupBase/index.ts +5 -0
- package/src/components/PaginationCards/PaginationCards.tsx +72 -0
- package/src/components/PaginationCards/index.ts +2 -0
- package/src/components/PaginationDotGroup/PaginationDotGroup.tsx +66 -0
- package/src/components/PaginationDotGroup/index.ts +2 -0
- package/src/components/PaginationDotIndicator/PaginationDotIndicator.tsx +39 -0
- package/src/components/PaginationDotIndicator/index.ts +6 -0
- package/src/components/PaginationNumberBase/PaginationNumberBase.tsx +42 -0
- package/src/components/PaginationNumberBase/index.ts +5 -0
- package/src/components/PieChart/PieChart.tsx +73 -0
- package/src/components/PieChart/index.ts +2 -0
- package/src/components/ProgressBar/ProgressBar.tsx +75 -0
- package/src/components/ProgressBar/index.ts +2 -0
- package/src/components/ProgressCircle/ProgressCircle.tsx +89 -0
- package/src/components/ProgressCircle/index.ts +6 -0
- package/src/components/RadarChart/RadarChart.tsx +62 -0
- package/src/components/RadarChart/index.ts +2 -0
- package/src/components/Radio/Radio.tsx +55 -0
- package/src/components/Radio/index.ts +2 -0
- package/src/components/RadioGroup/RadioGroup.tsx +54 -0
- package/src/components/RadioGroup/index.ts +2 -0
- package/src/components/RadioGroupItem/RadioGroupItem.tsx +118 -0
- package/src/components/RadioGroupItem/index.ts +6 -0
- package/src/components/SectionFooter/SectionFooter.tsx +40 -0
- package/src/components/SectionFooter/index.ts +2 -0
- package/src/components/SectionHeader/SectionHeader.tsx +44 -0
- package/src/components/SectionHeader/index.ts +2 -0
- package/src/components/SectionLabel/SectionLabel.tsx +51 -0
- package/src/components/SectionLabel/index.ts +2 -0
- package/src/components/Select/Select.tsx +121 -0
- package/src/components/Select/index.ts +2 -0
- package/src/components/SelectMenuItem/SelectMenuItem.tsx +85 -0
- package/src/components/SelectMenuItem/index.ts +2 -0
- package/src/components/SidebarNavigation/SidebarNavigation.tsx +100 -0
- package/src/components/SidebarNavigation/index.ts +2 -0
- package/src/components/SlideOutMenuHeader/SlideOutMenuHeader.tsx +56 -0
- package/src/components/SlideOutMenuHeader/index.ts +2 -0
- package/src/components/Slider/Slider.tsx +125 -0
- package/src/components/Slider/index.ts +2 -0
- package/src/components/SocialButton/SocialButton.tsx +88 -0
- package/src/components/SocialButton/index.ts +2 -0
- package/src/components/StatusIcon/StatusIcon.tsx +75 -0
- package/src/components/StatusIcon/index.ts +2 -0
- package/src/components/StepBase/StepBase.tsx +90 -0
- package/src/components/StepBase/index.ts +2 -0
- package/src/components/StepIconBase/StepIconBase.tsx +65 -0
- package/src/components/StepIconBase/index.ts +7 -0
- package/src/components/TabButtonBase/TabButtonBase.tsx +88 -0
- package/src/components/TabButtonBase/index.ts +2 -0
- package/src/components/TableCell/TableCell.tsx +44 -0
- package/src/components/TableCell/index.ts +2 -0
- package/src/components/TableHeaderCell/TableHeaderCell.tsx +34 -0
- package/src/components/TableHeaderCell/index.ts +2 -0
- package/src/components/TableHeaderLabel/TableHeaderLabel.tsx +37 -0
- package/src/components/TableHeaderLabel/index.ts +2 -0
- package/src/components/Tabs/Tabs.tsx +80 -0
- package/src/components/Tabs/index.ts +2 -0
- package/src/components/Tag/Tag.tsx +91 -0
- package/src/components/Tag/index.ts +2 -0
- package/src/components/TagsInputField/TagsInputField.tsx +90 -0
- package/src/components/TagsInputField/index.ts +2 -0
- package/src/components/TextEditorToolbar/TextEditorToolbar.tsx +33 -0
- package/src/components/TextEditorToolbar/index.ts +2 -0
- package/src/components/TextEditorTooltip/TextEditorTooltip.tsx +28 -0
- package/src/components/TextEditorTooltip/index.ts +2 -0
- package/src/components/TextareaInputField/TextareaInputField.tsx +45 -0
- package/src/components/TextareaInputField/index.ts +2 -0
- package/src/components/Toggle/Toggle.tsx +87 -0
- package/src/components/Toggle/index.ts +2 -0
- package/src/components/Tooltip/Tooltip.tsx +59 -0
- package/src/components/Tooltip/index.ts +2 -0
- package/src/components/TrailingInputField/TrailingInputField.tsx +62 -0
- package/src/components/TrailingInputField/index.ts +2 -0
- package/src/components/TreeView/TreeView.tsx +86 -0
- package/src/components/TreeView/index.ts +2 -0
- package/src/components/TreeViewConnector/TreeViewConnector.tsx +36 -0
- package/src/components/TreeViewConnector/index.ts +2 -0
- package/src/components/TreeViewItem/TreeViewItem.tsx +111 -0
- package/src/components/TreeViewItem/index.ts +2 -0
- package/src/components/VerificationCodeInput/VerificationCodeInput.tsx +114 -0
- package/src/components/VerificationCodeInput/index.ts +2 -0
- package/src/illustrations/BoxIllustration.tsx +13 -0
- package/src/illustrations/CloudIllustration.tsx +18 -0
- package/src/illustrations/CreditCardIllustration.tsx +13 -0
- package/src/illustrations/DocumentsIllustration.tsx +13 -0
- package/src/illustrations/index.ts +4 -0
- package/src/index.ts +147 -0
- package/src/internal/chartTheme.ts +30 -0
- package/src/internal/ringBase.tsx +82 -0
- package/src/styles.css +3 -0
- package/tailwind-preset.js +295 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { ButtonHTMLAttributes } from "react";
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
|
|
4
|
+
export type AvatarAddButtonSize = "xs" | "sm" | "md";
|
|
5
|
+
|
|
6
|
+
export interface AvatarAddButtonProps
|
|
7
|
+
extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "size"> {
|
|
8
|
+
size?: AvatarAddButtonSize;
|
|
9
|
+
/** Tooltip text + accessible label (Figma hover shows "Add user"). */
|
|
10
|
+
label?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const sizeClass: Record<AvatarAddButtonSize, string> = {
|
|
14
|
+
xs: "size-6", // 24px
|
|
15
|
+
sm: "size-8", // 32px
|
|
16
|
+
md: "size-10", // 40px
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function PlusIcon() {
|
|
20
|
+
return (
|
|
21
|
+
<svg viewBox="0 0 20 20" fill="none" className="h-1/2 w-1/2" aria-hidden>
|
|
22
|
+
<path
|
|
23
|
+
d="M10 4.167v11.666M4.167 10h11.666"
|
|
24
|
+
stroke="currentColor"
|
|
25
|
+
strokeWidth="1.667"
|
|
26
|
+
strokeLinecap="round"
|
|
27
|
+
strokeLinejoin="round"
|
|
28
|
+
/>
|
|
29
|
+
</svg>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function AvatarAddButton({
|
|
34
|
+
size = "md",
|
|
35
|
+
label,
|
|
36
|
+
className,
|
|
37
|
+
...rest
|
|
38
|
+
}: AvatarAddButtonProps) {
|
|
39
|
+
return (
|
|
40
|
+
<span className="group relative inline-flex">
|
|
41
|
+
<button
|
|
42
|
+
type="button"
|
|
43
|
+
aria-label={label ?? "Add"}
|
|
44
|
+
className={clsx(
|
|
45
|
+
"flex items-center justify-center rounded-full border border-dashed border-border-primary text-fg-quaternary transition-colors",
|
|
46
|
+
"hover:border-border-brand hover:text-fg-quaternary-hover",
|
|
47
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-brand focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
|
|
48
|
+
sizeClass[size],
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
{...rest}
|
|
52
|
+
>
|
|
53
|
+
<PlusIcon />
|
|
54
|
+
</button>
|
|
55
|
+
{label ? (
|
|
56
|
+
<span
|
|
57
|
+
role="tooltip"
|
|
58
|
+
className="pointer-events-none absolute bottom-full left-1/2 mb-xs -translate-x-1/2 whitespace-nowrap rounded-md bg-bg-primary-solid px-md py-xs text-xs font-semibold text-text-white opacity-0 shadow-lg transition-opacity group-hover:opacity-100 group-focus-within:opacity-100"
|
|
59
|
+
>
|
|
60
|
+
{label}
|
|
61
|
+
</span>
|
|
62
|
+
) : null}
|
|
63
|
+
</span>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import { Avatar } from "../Avatar";
|
|
3
|
+
import { AvatarAddButton } from "../AvatarAddButton";
|
|
4
|
+
|
|
5
|
+
export type AvatarGroupSize = "xs" | "sm" | "md";
|
|
6
|
+
|
|
7
|
+
export interface AvatarGroupItem {
|
|
8
|
+
src?: string;
|
|
9
|
+
alt?: string;
|
|
10
|
+
initials?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AvatarGroupProps {
|
|
14
|
+
size?: AvatarGroupSize;
|
|
15
|
+
avatars: AvatarGroupItem[];
|
|
16
|
+
/** Max avatars shown before collapsing the rest into a "+N" chip. */
|
|
17
|
+
max?: number;
|
|
18
|
+
/** Renders a trailing dashed add button when provided. */
|
|
19
|
+
onAdd?: () => void;
|
|
20
|
+
/** Tooltip/label for the add button. */
|
|
21
|
+
addLabel?: string;
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const chipSizeClass: Record<AvatarGroupSize, string> = {
|
|
26
|
+
xs: "size-6", // 24px
|
|
27
|
+
sm: "size-8", // 32px
|
|
28
|
+
md: "size-10", // 40px
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const chipTextClass: Record<AvatarGroupSize, string> = {
|
|
32
|
+
xs: "text-xs",
|
|
33
|
+
sm: "text-xs",
|
|
34
|
+
md: "text-sm",
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export function AvatarGroup({
|
|
38
|
+
size = "md",
|
|
39
|
+
avatars,
|
|
40
|
+
max,
|
|
41
|
+
onAdd,
|
|
42
|
+
addLabel,
|
|
43
|
+
className,
|
|
44
|
+
}: AvatarGroupProps) {
|
|
45
|
+
const shown = max ? avatars.slice(0, max) : avatars;
|
|
46
|
+
const surplus = avatars.length - shown.length;
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div className={clsx("flex items-center", className)}>
|
|
50
|
+
{shown.map((a, i) => (
|
|
51
|
+
<span
|
|
52
|
+
key={i}
|
|
53
|
+
className={clsx(
|
|
54
|
+
"rounded-full ring-2 ring-bg-primary",
|
|
55
|
+
i > 0 && "-ml-md",
|
|
56
|
+
)}
|
|
57
|
+
>
|
|
58
|
+
<Avatar size={size} src={a.src} alt={a.alt} initials={a.initials} />
|
|
59
|
+
</span>
|
|
60
|
+
))}
|
|
61
|
+
{surplus > 0 ? (
|
|
62
|
+
<span
|
|
63
|
+
className={clsx(
|
|
64
|
+
"-ml-md flex items-center justify-center rounded-full border border-border-secondary bg-bg-tertiary font-semibold text-text-quaternary ring-2 ring-bg-primary",
|
|
65
|
+
chipSizeClass[size],
|
|
66
|
+
chipTextClass[size],
|
|
67
|
+
)}
|
|
68
|
+
>
|
|
69
|
+
+{surplus}
|
|
70
|
+
</span>
|
|
71
|
+
) : null}
|
|
72
|
+
{onAdd ? (
|
|
73
|
+
<span className="ml-md">
|
|
74
|
+
<AvatarAddButton size={size} label={addLabel} onClick={onAdd} />
|
|
75
|
+
</span>
|
|
76
|
+
) : null}
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import { Avatar, type AvatarSize } from "../Avatar";
|
|
3
|
+
|
|
4
|
+
export type AvatarLabelGroupSize = "sm" | "md" | "lg";
|
|
5
|
+
|
|
6
|
+
export interface AvatarLabelGroupProps {
|
|
7
|
+
size?: AvatarLabelGroupSize;
|
|
8
|
+
/** Primary line (name). */
|
|
9
|
+
name: string;
|
|
10
|
+
/** Secondary line (email / handle / role). */
|
|
11
|
+
subtitle?: string;
|
|
12
|
+
src?: string;
|
|
13
|
+
alt?: string;
|
|
14
|
+
initials?: string;
|
|
15
|
+
hasStatus?: boolean;
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const avatarSize: Record<AvatarLabelGroupSize, AvatarSize> = {
|
|
20
|
+
sm: "sm",
|
|
21
|
+
md: "md",
|
|
22
|
+
lg: "lg",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const textClass: Record<AvatarLabelGroupSize, string> = {
|
|
26
|
+
sm: "text-sm",
|
|
27
|
+
md: "text-sm",
|
|
28
|
+
lg: "text-md",
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export function AvatarLabelGroup({
|
|
32
|
+
size = "md",
|
|
33
|
+
name,
|
|
34
|
+
subtitle,
|
|
35
|
+
src,
|
|
36
|
+
alt,
|
|
37
|
+
initials,
|
|
38
|
+
hasStatus = false,
|
|
39
|
+
className,
|
|
40
|
+
}: AvatarLabelGroupProps) {
|
|
41
|
+
return (
|
|
42
|
+
<div className={clsx("flex items-center gap-md font-body", className)}>
|
|
43
|
+
<Avatar
|
|
44
|
+
size={avatarSize[size]}
|
|
45
|
+
src={src}
|
|
46
|
+
alt={alt ?? name}
|
|
47
|
+
initials={initials}
|
|
48
|
+
hasStatus={hasStatus}
|
|
49
|
+
/>
|
|
50
|
+
<div className="flex min-w-0 flex-col">
|
|
51
|
+
<span className={clsx("truncate font-semibold text-text-primary", textClass[size])}>
|
|
52
|
+
{name}
|
|
53
|
+
</span>
|
|
54
|
+
{subtitle ? (
|
|
55
|
+
<span className={clsx("truncate font-normal text-text-tertiary", textClass[size])}>
|
|
56
|
+
{subtitle}
|
|
57
|
+
</span>
|
|
58
|
+
) : null}
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
|
|
3
|
+
export type AvatarProfilePhotoSize = "sm" | "md" | "lg";
|
|
4
|
+
|
|
5
|
+
export interface AvatarProfilePhotoProps {
|
|
6
|
+
size?: AvatarProfilePhotoSize;
|
|
7
|
+
src?: string;
|
|
8
|
+
alt?: string;
|
|
9
|
+
/** Placeholder initials when no image is supplied. */
|
|
10
|
+
initials?: string;
|
|
11
|
+
/** Show the verified (blue tick) badge bottom-right. */
|
|
12
|
+
verified?: boolean;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const sizeClass: Record<AvatarProfilePhotoSize, string> = {
|
|
17
|
+
sm: "size-16", // 64px
|
|
18
|
+
md: "size-24", // 96px
|
|
19
|
+
lg: "size-40", // 160px
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Initials typography (display-sm / display-md / display-xl, Semibold).
|
|
23
|
+
const initialsClass: Record<AvatarProfilePhotoSize, string> = {
|
|
24
|
+
sm: "text-display-sm",
|
|
25
|
+
md: "text-display-md",
|
|
26
|
+
lg: "text-display-xl",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const shadowClass: Record<AvatarProfilePhotoSize, string> = {
|
|
30
|
+
sm: "shadow-xl",
|
|
31
|
+
md: "shadow-xl",
|
|
32
|
+
lg: "shadow-2xl",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const badgeClass: Record<AvatarProfilePhotoSize, string> = {
|
|
36
|
+
sm: "size-4", // 16px
|
|
37
|
+
md: "size-6", // 24px
|
|
38
|
+
lg: "size-9", // 36px
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function UserIcon() {
|
|
42
|
+
return (
|
|
43
|
+
<svg viewBox="0 0 24 24" fill="none" className="h-1/2 w-1/2" aria-hidden>
|
|
44
|
+
<path
|
|
45
|
+
d="M20 21a8 8 0 0 0-16 0M12 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z"
|
|
46
|
+
stroke="currentColor"
|
|
47
|
+
strokeWidth="2"
|
|
48
|
+
strokeLinecap="round"
|
|
49
|
+
strokeLinejoin="round"
|
|
50
|
+
/>
|
|
51
|
+
</svg>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function VerifiedBadge({ className }: { className?: string }) {
|
|
56
|
+
// Approximated as a filled disc + white check (the source uses a scalloped
|
|
57
|
+
// seal outline); colour is utility-blue-500.
|
|
58
|
+
return (
|
|
59
|
+
<span
|
|
60
|
+
className={clsx(
|
|
61
|
+
"absolute bottom-0 right-0 flex items-center justify-center rounded-full border-2 border-bg-primary bg-utility-blue-500 text-text-white",
|
|
62
|
+
className,
|
|
63
|
+
)}
|
|
64
|
+
aria-label="Verified"
|
|
65
|
+
>
|
|
66
|
+
<svg viewBox="0 0 20 20" fill="none" className="h-1/2 w-1/2" aria-hidden>
|
|
67
|
+
<path
|
|
68
|
+
d="m6 10 2.5 2.5L14 7"
|
|
69
|
+
stroke="currentColor"
|
|
70
|
+
strokeWidth="2"
|
|
71
|
+
strokeLinecap="round"
|
|
72
|
+
strokeLinejoin="round"
|
|
73
|
+
/>
|
|
74
|
+
</svg>
|
|
75
|
+
</span>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function AvatarProfilePhoto({
|
|
80
|
+
size = "md",
|
|
81
|
+
src,
|
|
82
|
+
alt = "",
|
|
83
|
+
initials,
|
|
84
|
+
verified = false,
|
|
85
|
+
className,
|
|
86
|
+
}: AvatarProfilePhotoProps) {
|
|
87
|
+
return (
|
|
88
|
+
<span className={clsx("relative inline-flex shrink-0", className)}>
|
|
89
|
+
<span
|
|
90
|
+
className={clsx(
|
|
91
|
+
"flex items-center justify-center overflow-hidden rounded-full bg-bg-tertiary",
|
|
92
|
+
src
|
|
93
|
+
? "border-[0.5px] border-border-secondary-alt"
|
|
94
|
+
: "text-fg-quaternary",
|
|
95
|
+
shadowClass[size],
|
|
96
|
+
sizeClass[size],
|
|
97
|
+
)}
|
|
98
|
+
>
|
|
99
|
+
{src ? (
|
|
100
|
+
<img src={src} alt={alt} className="size-full object-cover" />
|
|
101
|
+
) : initials ? (
|
|
102
|
+
<span
|
|
103
|
+
className={clsx(
|
|
104
|
+
"font-display font-semibold text-text-quaternary",
|
|
105
|
+
initialsClass[size],
|
|
106
|
+
)}
|
|
107
|
+
>
|
|
108
|
+
{initials}
|
|
109
|
+
</span>
|
|
110
|
+
) : (
|
|
111
|
+
<UserIcon />
|
|
112
|
+
)}
|
|
113
|
+
</span>
|
|
114
|
+
{verified ? <VerifiedBadge className={badgeClass[size]} /> : null}
|
|
115
|
+
</span>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import {
|
|
3
|
+
BadgeBase,
|
|
4
|
+
colorFillClasses,
|
|
5
|
+
dotColorClasses,
|
|
6
|
+
type BadgeCommonProps,
|
|
7
|
+
} from "./badgeShared";
|
|
8
|
+
|
|
9
|
+
export type ColorBadgeProps = BadgeCommonProps;
|
|
10
|
+
|
|
11
|
+
/** Rounded-rectangle coloured badge (Figma Badge `Type=Badge color`). */
|
|
12
|
+
export function ColorBadge({
|
|
13
|
+
color = "gray",
|
|
14
|
+
size = "md",
|
|
15
|
+
dot,
|
|
16
|
+
children,
|
|
17
|
+
iconLeading,
|
|
18
|
+
iconTrailing,
|
|
19
|
+
onClose,
|
|
20
|
+
className,
|
|
21
|
+
}: ColorBadgeProps) {
|
|
22
|
+
return (
|
|
23
|
+
<BadgeBase
|
|
24
|
+
size={size}
|
|
25
|
+
dot={dot}
|
|
26
|
+
dotClass={dotColorClasses[color]}
|
|
27
|
+
iconLeading={iconLeading}
|
|
28
|
+
iconTrailing={iconTrailing}
|
|
29
|
+
onClose={onClose}
|
|
30
|
+
shapeClass={clsx("rounded-md", colorFillClasses[color])}
|
|
31
|
+
className={className}
|
|
32
|
+
>
|
|
33
|
+
{children}
|
|
34
|
+
</BadgeBase>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BadgeBase,
|
|
3
|
+
dotColorClasses,
|
|
4
|
+
type BadgeCommonProps,
|
|
5
|
+
} from "./badgeShared";
|
|
6
|
+
|
|
7
|
+
export type ModernBadgeProps = BadgeCommonProps;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Neutral white badge with a coloured leading dot (Figma Badge
|
|
11
|
+
* `Type=Badge modern`). Here `color` drives only the dot — the chrome stays
|
|
12
|
+
* neutral. The dot defaults on (it's the defining trait of this style).
|
|
13
|
+
*/
|
|
14
|
+
export function ModernBadge({
|
|
15
|
+
color = "gray",
|
|
16
|
+
size = "md",
|
|
17
|
+
dot = true,
|
|
18
|
+
children,
|
|
19
|
+
iconLeading,
|
|
20
|
+
iconTrailing,
|
|
21
|
+
onClose,
|
|
22
|
+
className,
|
|
23
|
+
}: ModernBadgeProps) {
|
|
24
|
+
return (
|
|
25
|
+
<BadgeBase
|
|
26
|
+
size={size}
|
|
27
|
+
dot={dot}
|
|
28
|
+
dotClass={dotColorClasses[color]}
|
|
29
|
+
iconLeading={iconLeading}
|
|
30
|
+
iconTrailing={iconTrailing}
|
|
31
|
+
onClose={onClose}
|
|
32
|
+
shapeClass="rounded-md bg-bg-primary border-border-primary text-text-secondary shadow-xs"
|
|
33
|
+
className={className}
|
|
34
|
+
>
|
|
35
|
+
{children}
|
|
36
|
+
</BadgeBase>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import {
|
|
3
|
+
BadgeBase,
|
|
4
|
+
colorFillClasses,
|
|
5
|
+
dotColorClasses,
|
|
6
|
+
type BadgeCommonProps,
|
|
7
|
+
} from "./badgeShared";
|
|
8
|
+
|
|
9
|
+
export type PillBadgeProps = BadgeCommonProps;
|
|
10
|
+
|
|
11
|
+
/** Fully-rounded coloured badge (Figma Badge `Type=Pill color`). */
|
|
12
|
+
export function PillBadge({
|
|
13
|
+
color = "gray",
|
|
14
|
+
size = "md",
|
|
15
|
+
dot,
|
|
16
|
+
children,
|
|
17
|
+
iconLeading,
|
|
18
|
+
iconTrailing,
|
|
19
|
+
onClose,
|
|
20
|
+
className,
|
|
21
|
+
}: PillBadgeProps) {
|
|
22
|
+
return (
|
|
23
|
+
<BadgeBase
|
|
24
|
+
size={size}
|
|
25
|
+
dot={dot}
|
|
26
|
+
dotClass={dotColorClasses[color]}
|
|
27
|
+
iconLeading={iconLeading}
|
|
28
|
+
iconTrailing={iconTrailing}
|
|
29
|
+
onClose={onClose}
|
|
30
|
+
shapeClass={clsx("rounded-full", colorFillClasses[color])}
|
|
31
|
+
className={className}
|
|
32
|
+
>
|
|
33
|
+
{children}
|
|
34
|
+
</BadgeBase>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
|
|
4
|
+
// 12 Badge colours. Family names match the Figma utility-* palette; `gray`
|
|
5
|
+
// maps to the `neutral` family.
|
|
6
|
+
export type BadgeColor =
|
|
7
|
+
| "brand"
|
|
8
|
+
| "gray"
|
|
9
|
+
| "red"
|
|
10
|
+
| "yellow"
|
|
11
|
+
| "green"
|
|
12
|
+
| "slate"
|
|
13
|
+
| "sky"
|
|
14
|
+
| "blue"
|
|
15
|
+
| "indigo"
|
|
16
|
+
| "purple"
|
|
17
|
+
| "pink"
|
|
18
|
+
| "orange";
|
|
19
|
+
|
|
20
|
+
export type BadgeSize = "sm" | "md" | "lg";
|
|
21
|
+
|
|
22
|
+
// Static class strings (not constructed) so Tailwind's content scanner keeps
|
|
23
|
+
// them. bg = utility-<c>-50, text = -700, border = -200.
|
|
24
|
+
export const colorFillClasses: Record<BadgeColor, string> = {
|
|
25
|
+
brand: "bg-utility-brand-50 text-utility-brand-700 border-utility-brand-200",
|
|
26
|
+
gray: "bg-utility-neutral-50 text-utility-neutral-700 border-utility-neutral-200",
|
|
27
|
+
red: "bg-utility-red-50 text-utility-red-700 border-utility-red-200",
|
|
28
|
+
yellow: "bg-utility-yellow-50 text-utility-yellow-700 border-utility-yellow-200",
|
|
29
|
+
green: "bg-utility-green-50 text-utility-green-700 border-utility-green-200",
|
|
30
|
+
slate: "bg-utility-slate-50 text-utility-slate-700 border-utility-slate-200",
|
|
31
|
+
sky: "bg-utility-sky-50 text-utility-sky-700 border-utility-sky-200",
|
|
32
|
+
blue: "bg-utility-blue-50 text-utility-blue-700 border-utility-blue-200",
|
|
33
|
+
indigo: "bg-utility-indigo-50 text-utility-indigo-700 border-utility-indigo-200",
|
|
34
|
+
purple: "bg-utility-purple-50 text-utility-purple-700 border-utility-purple-200",
|
|
35
|
+
pink: "bg-utility-pink-50 text-utility-pink-700 border-utility-pink-200",
|
|
36
|
+
orange: "bg-utility-orange-50 text-utility-orange-700 border-utility-orange-200",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Leading-dot colour (utility-<c>-500).
|
|
40
|
+
export const dotColorClasses: Record<BadgeColor, string> = {
|
|
41
|
+
brand: "bg-utility-brand-500",
|
|
42
|
+
gray: "bg-utility-neutral-500",
|
|
43
|
+
red: "bg-utility-red-500",
|
|
44
|
+
yellow: "bg-utility-yellow-500",
|
|
45
|
+
green: "bg-utility-green-500",
|
|
46
|
+
slate: "bg-utility-slate-500",
|
|
47
|
+
sky: "bg-utility-sky-500",
|
|
48
|
+
blue: "bg-utility-blue-500",
|
|
49
|
+
indigo: "bg-utility-indigo-500",
|
|
50
|
+
purple: "bg-utility-purple-500",
|
|
51
|
+
pink: "bg-utility-pink-500",
|
|
52
|
+
orange: "bg-utility-orange-500",
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const sizeClasses: Record<BadgeSize, string> = {
|
|
56
|
+
sm: "px-md py-xxs text-xs gap-xs",
|
|
57
|
+
md: "px-lg py-xxs text-sm gap-xs",
|
|
58
|
+
lg: "px-lg py-xs text-sm gap-md",
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/** Props shared by all three Badge types. */
|
|
62
|
+
export interface BadgeCommonProps {
|
|
63
|
+
children: ReactNode;
|
|
64
|
+
color?: BadgeColor;
|
|
65
|
+
size?: BadgeSize;
|
|
66
|
+
/** Leading coloured dot. */
|
|
67
|
+
dot?: boolean;
|
|
68
|
+
iconLeading?: ReactNode;
|
|
69
|
+
iconTrailing?: ReactNode;
|
|
70
|
+
/** Renders a trailing X-close button when provided. */
|
|
71
|
+
onClose?: () => void;
|
|
72
|
+
className?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function CloseX() {
|
|
76
|
+
return (
|
|
77
|
+
<svg viewBox="0 0 12 12" fill="none" className="size-3" aria-hidden>
|
|
78
|
+
<path
|
|
79
|
+
d="m9 3-6 6m0-6 6 6"
|
|
80
|
+
stroke="currentColor"
|
|
81
|
+
strokeWidth="1.5"
|
|
82
|
+
strokeLinecap="round"
|
|
83
|
+
strokeLinejoin="round"
|
|
84
|
+
/>
|
|
85
|
+
</svg>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Internal layout shell used by PillBadge / ColorBadge / ModernBadge. */
|
|
90
|
+
export function BadgeBase({
|
|
91
|
+
children,
|
|
92
|
+
size = "md",
|
|
93
|
+
dot,
|
|
94
|
+
dotClass,
|
|
95
|
+
iconLeading,
|
|
96
|
+
iconTrailing,
|
|
97
|
+
onClose,
|
|
98
|
+
shapeClass,
|
|
99
|
+
className,
|
|
100
|
+
}: {
|
|
101
|
+
children: ReactNode;
|
|
102
|
+
size?: BadgeSize;
|
|
103
|
+
dot?: boolean;
|
|
104
|
+
dotClass?: string;
|
|
105
|
+
iconLeading?: ReactNode;
|
|
106
|
+
iconTrailing?: ReactNode;
|
|
107
|
+
onClose?: () => void;
|
|
108
|
+
/** Type-specific shape + colour classes (rounded + bg/text/border). */
|
|
109
|
+
shapeClass: string;
|
|
110
|
+
className?: string;
|
|
111
|
+
}) {
|
|
112
|
+
return (
|
|
113
|
+
<span
|
|
114
|
+
className={clsx(
|
|
115
|
+
"inline-flex items-center whitespace-nowrap border font-medium font-body",
|
|
116
|
+
sizeClasses[size],
|
|
117
|
+
shapeClass,
|
|
118
|
+
className,
|
|
119
|
+
)}
|
|
120
|
+
>
|
|
121
|
+
{dot ? (
|
|
122
|
+
<span className={clsx("size-2 shrink-0 rounded-full", dotClass)} aria-hidden />
|
|
123
|
+
) : null}
|
|
124
|
+
{iconLeading ? <span className="shrink-0">{iconLeading}</span> : null}
|
|
125
|
+
{children}
|
|
126
|
+
{iconTrailing ? <span className="shrink-0">{iconTrailing}</span> : null}
|
|
127
|
+
{onClose ? (
|
|
128
|
+
<button
|
|
129
|
+
type="button"
|
|
130
|
+
onClick={onClose}
|
|
131
|
+
aria-label="Remove"
|
|
132
|
+
className="-mr-xxs shrink-0 rounded-xs opacity-70 transition-opacity hover:opacity-100"
|
|
133
|
+
>
|
|
134
|
+
<CloseX />
|
|
135
|
+
</button>
|
|
136
|
+
) : null}
|
|
137
|
+
</span>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { PillBadge } from "./PillBadge";
|
|
2
|
+
export { ColorBadge } from "./ColorBadge";
|
|
3
|
+
export { ModernBadge } from "./ModernBadge";
|
|
4
|
+
export type { PillBadgeProps } from "./PillBadge";
|
|
5
|
+
export type { ColorBadgeProps } from "./ColorBadge";
|
|
6
|
+
export type { ModernBadgeProps } from "./ModernBadge";
|
|
7
|
+
export type { BadgeColor, BadgeSize, BadgeCommonProps } from "./badgeShared";
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ButtonHTMLAttributes } from "react";
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
import type { BadgeColor } from "../Badge";
|
|
4
|
+
|
|
5
|
+
export type BadgeCloseXShape = "square" | "rounded";
|
|
6
|
+
|
|
7
|
+
export interface BadgeCloseXProps
|
|
8
|
+
extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "color"> {
|
|
9
|
+
/**
|
|
10
|
+
* Tint for the X. Omit to inherit the parent badge's text colour
|
|
11
|
+
* (currentColor) — the usual case when composed inside a Badge.
|
|
12
|
+
*/
|
|
13
|
+
color?: BadgeColor;
|
|
14
|
+
shape?: BadgeCloseXShape;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Standalone tint map (utility-<c>-500). Static strings for Tailwind.
|
|
18
|
+
const textColorClasses: Record<BadgeColor, string> = {
|
|
19
|
+
brand: "text-utility-brand-500",
|
|
20
|
+
gray: "text-utility-neutral-500",
|
|
21
|
+
red: "text-utility-red-500",
|
|
22
|
+
yellow: "text-utility-yellow-500",
|
|
23
|
+
green: "text-utility-green-500",
|
|
24
|
+
slate: "text-utility-slate-500",
|
|
25
|
+
sky: "text-utility-sky-500",
|
|
26
|
+
blue: "text-utility-blue-500",
|
|
27
|
+
indigo: "text-utility-indigo-500",
|
|
28
|
+
purple: "text-utility-purple-500",
|
|
29
|
+
pink: "text-utility-pink-500",
|
|
30
|
+
orange: "text-utility-orange-500",
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export function BadgeCloseX({
|
|
34
|
+
color,
|
|
35
|
+
shape = "rounded",
|
|
36
|
+
className,
|
|
37
|
+
...rest
|
|
38
|
+
}: BadgeCloseXProps) {
|
|
39
|
+
return (
|
|
40
|
+
<button
|
|
41
|
+
type="button"
|
|
42
|
+
aria-label="Remove"
|
|
43
|
+
className={clsx(
|
|
44
|
+
"inline-flex size-4 items-center justify-center transition-colors",
|
|
45
|
+
shape === "square" ? "rounded-xs" : "rounded-full",
|
|
46
|
+
color ? textColorClasses[color] : undefined,
|
|
47
|
+
"hover:bg-black/10",
|
|
48
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-brand focus-visible:ring-offset-1 focus-visible:ring-offset-bg-primary",
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
{...rest}
|
|
52
|
+
>
|
|
53
|
+
<svg viewBox="0 0 12 12" fill="none" className="size-3" aria-hidden>
|
|
54
|
+
<path
|
|
55
|
+
d="m9 3-6 6m0-6 6 6"
|
|
56
|
+
stroke="currentColor"
|
|
57
|
+
strokeWidth="1.5"
|
|
58
|
+
strokeLinecap="round"
|
|
59
|
+
strokeLinejoin="round"
|
|
60
|
+
/>
|
|
61
|
+
</svg>
|
|
62
|
+
</button>
|
|
63
|
+
);
|
|
64
|
+
}
|