-
-
-
- On:
-
-
-
- Off:
-
-
-
- Disabled On:
-
-
-
- Disabled Off:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ManaSwitch - Basic toggle switch without label.
-
-
- • checked: boolean - Current switch state
-
-
- • onChange?: (checked: boolean) => void - Called when toggled
-
-
- • disabled?: boolean - Disable interaction
-
-
- SwitchWithLabel - Switch with label and description.
-
-
- • label?: string - Label text displayed next to switch
-
-
- • description?: string - Description text below label
-
-
- • checked: boolean - Current switch state
-
-
- • onChange?: (checked: boolean) => void - Called when toggled
-
-
- • disabled?: boolean - Disable interaction
-
-
+
+
+ On:
+
+
+
+ Off:
+
+
+
+ Disabled On:
+
+
+
+ Disabled Off:
+
+
);
}
+
+function LabelDemo() {
+ const [on, setOn] = useState(true);
+ const [off, setOff] = useState(false);
+
+ return (
+
+
+
+
+ );
+}
+
+function DescriptionDemo() {
+ const [checked, setChecked] = useState(true);
+ return (
+
+ );
+}
+
+export default function SwitchTab() {
+ return (
+
,
+ code: "
",
+ relevantProps: ["checked", "onChange", "disabled"],
+ },
+ {
+ title: "Switch with Label",
+ description: "SwitchWithLabel renders a label next to the toggle.",
+ children:
,
+ code: `
`,
+ },
+ {
+ title: "With Description",
+ description: "Label with description text below.",
+ children:
,
+ code: `
`,
+ },
+ {
+ title: "Disabled States",
+ description: "Both checked and unchecked disabled states.",
+ children: (
+
+
+
+
+ ),
+ },
+ ]}
+ props={PROP_GROUPS}
+ />
+ );
+}
diff --git a/src/equicordplugins/components.dev/components/tabs/TabBarTab.tsx b/src/equicordplugins/components.dev/components/tabs/TabBarTab.tsx
index cc3180e56..56f6031b5 100644
--- a/src/equicordplugins/components.dev/components/tabs/TabBarTab.tsx
+++ b/src/equicordplugins/components.dev/components/tabs/TabBarTab.tsx
@@ -5,184 +5,175 @@
*/
import { Paragraph, TabBar, useState } from "..";
-import { SectionWrapper } from "../SectionWrapper";
+import { DocPage, type PropDef, type PropGroup } from "../DocPage";
-export default function TabBarTab() {
- const [sideTab, setSideTab] = useState("tab1");
- const [topTab, setTopTab] = useState("tab1");
- const [topPillTab, setTopPillTab] = useState("tab1");
- const [brandTab, setBrandTab] = useState("tab1");
+const TABBAR_PROPS: PropDef[] = [
+ { name: "type", type: '"side" | "top" | "top-pill"', description: "Tab bar visual style." },
+ { name: "look", type: '"brand" | "grey"', description: "Color scheme." },
+ { name: "selectedItem", type: "string", description: "ID of the currently selected tab." },
+ { name: "onItemSelect", type: "(id: string) => void", description: "Called when a tab is selected." },
+ { name: "orientation", type: '"horizontal" | "vertical"', description: "Layout direction." },
+ { name: "className", type: "string", description: "Custom CSS class." },
+ { name: "style", type: "CSSProperties", description: "Inline styles." },
+ { name: "aria-label", type: "string", description: "Accessibility label." },
+];
+
+const ITEM_PROPS: PropDef[] = [
+ { name: "id", type: "string", required: true, description: "Unique tab identifier." },
+ { name: "children", type: "ReactNode", required: true, description: "Tab label content." },
+ { name: "disabled", type: "boolean", description: "Disable the tab." },
+ { name: "color", type: "string", description: "Custom tab color (hex or CSS color)." },
+ { name: "variant", type: '"destructive"', description: "Danger styling for actions like logout." },
+ { name: "disableItemStyles", type: "boolean", description: "Remove default tab styles." },
+ { name: "onClick", type: "MouseEventHandler", description: "Custom click handler." },
+];
+
+const PROP_GROUPS: PropGroup[] = [
+ { title: "TabBar", props: TABBAR_PROPS },
+ { title: "TabBar.Item", props: ITEM_PROPS },
+];
+
+function SideDemo() {
+ const [tab, setTab] = useState("tab1");
+ return (
+
+
Selected: {tab}
+
+ First Tab
+ Second Tab
+ Third Tab
+
+
+ );
+}
+
+function TopDemo() {
+ const [tab, setTab] = useState("tab1");
+ return (
+
+ Overview
+ Settings
+ Members
+
+ );
+}
+
+function TopPillDemo() {
+ const [tab, setTab] = useState("tab1");
+ return (
+
+ All
+ Online
+ Pending
+ Blocked
+
+ );
+}
+
+function BrandDemo() {
+ const [tab, setTab] = useState("tab1");
+ return (
+
+ Home
+ Explore
+ Library
+
+ );
+}
+
+function HeaderSeparatorDemo() {
+ const [tab, setTab] = useState("tab1");
+ return (
+
+ User Settings
+ My Account
+ Privacy
+
+ App Settings
+ Appearance
+ Notifications
+
+ );
+}
+
+function FeaturesDemo() {
+ const [tab, setTab] = useState("tab1");
const [colorTab, setColorTab] = useState("tab1");
return (
-
-
-
- Default side-style tab bar with grey look. Selected: {sideTab}
-
-
- First Tab
- Second Tab
- Third Tab
-
-
-
-
-
- Top-style tab bar with underline indicator. Selected: {topTab}
-
-
- Overview
- Settings
- Members
-
-
-
-
-
- Pill-style tabs for top navigation. Selected: {topPillTab}
-
-
- All
- Online
- Pending
- Blocked
-
-
-
-
-
- Brand-colored tab bar style. Selected: {brandTab}
-
-
- Home
- Explore
- Library
-
-
-
-
-
- Tab bar with header section and separator.
-
-
- User Settings
- My Account
- Privacy
-
- App Settings
- Appearance
- Notifications
-
-
-
-
-
- Some tabs can be disabled.
-
-
+
+
+
Disabled items:
+
Active
Disabled
Another Active
-
-
-
-
- Individual tabs can have custom colors. Selected: {colorTab}
-
-
+
+
+
Custom colors:
+
Green
Yellow
Red
-
-
-
-
- Tab with destructive/danger styling.
-
-
+
+
+
Destructive variant:
+
Settings
- Privacy
Log Out
-
-
-
-
- TabBar - Container component
-
- • type?: "side" | "top" | "top-pill" - Tab bar style
- • look?: "brand" | "grey" - Color scheme
- • selectedItem?: string - Currently selected tab ID
- • onItemSelect?: (id) ={">"} void - Selection callback
- • orientation?: "horizontal" | "vertical" - Layout direction
- • className?: string - Additional CSS classes
- • style?: CSSProperties - Inline styles
- • aria-label?: string - Accessibility label
-
-
- TabBar.Item - Individual tab
-
- • id: string - Unique tab identifier (required)
- • disabled?: boolean - Disable the tab
- • color?: string - Custom tab color
- • variant?: "destructive" - Danger styling
- • disableItemStyles?: boolean - Remove default styles
- • onClick?: MouseEventHandler - Custom click handler
-
-
- TabBar.Header - Section header
-
- • children: ReactNode - Header text
- • onClick?: MouseEventHandler - Click handler
-
-
- TabBar.Separator - Visual divider
-
- • style?: CSSProperties - Custom styles
-
+
);
}
+
+export default function TabBarTab() {
+ return (
+ ,
+ code: `
+ First Tab
+ Second Tab
+`,
+ relevantProps: ["type", "look", "selectedItem", "onItemSelect"],
+ },
+ {
+ title: "Top",
+ description: "Horizontal tabs with underline indicator.",
+ children: ,
+ },
+ {
+ title: "Top Pill",
+ description: "Pill-style horizontal tabs.",
+ children: ,
+ },
+ {
+ title: "Brand Look",
+ description: "Brand-colored tab styling.",
+ children: ,
+ },
+ {
+ title: "Headers and Separators",
+ description: "TabBar.Header and TabBar.Separator for organizing groups of tabs.",
+ children: ,
+ },
+ {
+ title: "Disabled, Colors, Destructive",
+ description: "Items can be disabled, colored, or styled as destructive.",
+ children: ,
+ relevantProps: ["disabled", "color", "variant"],
+ },
+ ]}
+ props={PROP_GROUPS}
+ />
+ );
+}
diff --git a/src/equicordplugins/components.dev/components/tabs/TextAreaTab.tsx b/src/equicordplugins/components.dev/components/tabs/TextAreaTab.tsx
index ed854a248..954bdcefa 100644
--- a/src/equicordplugins/components.dev/components/tabs/TextAreaTab.tsx
+++ b/src/equicordplugins/components.dev/components/tabs/TextAreaTab.tsx
@@ -4,74 +4,97 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-import { ManaTextArea, Paragraph, useState } from "..";
-import { SectionWrapper } from "../SectionWrapper";
+import { ManaTextArea, useState } from "..";
+import { DocPage, type PropDef } from "../DocPage";
+
+const TEXTAREA_PROPS: PropDef[] = [
+ { name: "value", type: "string", description: "Current textarea value (controlled)." },
+ { name: "defaultValue", type: "string", description: "Initial value (uncontrolled)." },
+ { name: "onChange", type: "(value: string, name?: string) => void", description: "Called when the text changes." },
+ { name: "placeholder", type: "string", description: "Placeholder text when empty." },
+ { name: "name", type: "string", description: "HTML name attribute for form submission." },
+ { name: "rows", type: "number", description: "Fixed number of visible text rows." },
+ { name: "autosize", type: "boolean", description: "Automatically grow height to fit content." },
+ { name: "autoFocus", type: "boolean", description: "Focus on mount." },
+ { name: "maxLength", type: "number", description: "Maximum character limit." },
+ { name: "minLength", type: "number", description: "Minimum character requirement." },
+ { name: "showCharacterCount", type: "boolean", description: "Display current character count." },
+ { name: "showRemainingCharacterCount", type: "boolean", description: "Display remaining characters instead of current count." },
+ { name: "error", type: "string | boolean", description: "Error state. String shows error message, boolean shows red border." },
+ { name: "disabled", type: "boolean", default: "false", description: "Disable the textarea." },
+ { name: "readOnly", type: "boolean", description: "Make the textarea read-only." },
+ { name: "fullWidth", type: "boolean", description: "Expand to full available width." },
+ { name: "inputRef", type: "Ref", internal: true, description: "Ref to the underlying textarea element." },
+];
+
+function BasicDemo() {
+ const [value, setValue] = useState("Hello world\nThis is a textarea");
+ return ;
+}
+
+function AutosizeDemo() {
+ const [value, setValue] = useState("This textarea will grow as you type more content...");
+ return ;
+}
+
+function CharCountDemo() {
+ const [value, setValue] = useState("Count characters");
+ return ;
+}
export default function TextAreaTab() {
- const [basic, setBasic] = useState("Hello world\nThis is a textarea");
- const [withPlaceholder, setWithPlaceholder] = useState("");
- const [autosize, setAutosize] = useState("This textarea will grow as you type more content...");
- const [fixedRows, setFixedRows] = useState("Fixed 5 rows");
- const [charCount, setCharCount] = useState("Count characters");
-
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- • value: string - Textarea value
-
-
- • onChange?: (value: string) => void - Called on input change
-
-
- • placeholder?: string - Placeholder text
-
-
- • rows?: number - Fixed number of rows
-
-
- • autosize?: boolean - Auto-grow with content
-
-
- • showCharacterCount?: boolean - Display character count
-
-
- • maxLength?: number - Maximum character limit
-
-
- • disabled?: boolean - Disable textarea
-
-
- • readOnly?: boolean - Make textarea read-only
-
-
-
+ ,
+ code: "",
+ relevantProps: ["value", "onChange"],
+ },
+ {
+ title: "With Placeholder",
+ children: (
+ { }} placeholder="Enter your message..." />
+ ),
+ relevantProps: ["placeholder"],
+ },
+ {
+ title: "Autosize",
+ description: "Automatically grows to fit content as you type.",
+ children: ,
+ relevantProps: ["autosize"],
+ },
+ {
+ title: "Fixed Rows",
+ description: "Fixed height with 5 visible rows.",
+ children: (
+ { }} rows={5} />
+ ),
+ relevantProps: ["rows"],
+ },
+ {
+ title: "Character Count",
+ description: "Shows character count with a max length of 200.",
+ children: ,
+ relevantProps: ["showCharacterCount", "maxLength"],
+ },
+ {
+ title: "States",
+ description: "Disabled and read-only states.",
+ children: (
+
+
+
+
+ ),
+ relevantProps: ["disabled", "readOnly"],
+ },
+ ]}
+ props={TEXTAREA_PROPS}
+ />
);
}
diff --git a/src/equicordplugins/components.dev/components/tabs/TextButtonTab.tsx b/src/equicordplugins/components.dev/components/tabs/TextButtonTab.tsx
index 92d040dcb..aa6f25796 100644
--- a/src/equicordplugins/components.dev/components/tabs/TextButtonTab.tsx
+++ b/src/equicordplugins/components.dev/components/tabs/TextButtonTab.tsx
@@ -4,60 +4,77 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-import { ManaTextButton, ManaTextButtonTextVariants, ManaTextButtonVariants, Paragraph } from "..";
-import { SectionWrapper } from "../SectionWrapper";
+import { ManaTextButton, ManaTextButtonTextVariants, ManaTextButtonVariants } from "..";
+import { DocPage, type PropDef } from "../DocPage";
+
+const TEXTBUTTON_PROPS: PropDef[] = [
+ { name: "text", type: "string", required: true, description: "Button label text." },
+ { name: "variant", type: '"primary" | "secondary" | "always-white" | "critical"', description: "Color variant." },
+ { name: "textVariant", type: "string", description: 'Typography variant, e.g. "text-sm/medium", "text-lg/medium".' },
+ { name: "lineClamp", type: "number", description: "Max lines before truncation with ellipsis." },
+ { name: "disabled", type: "boolean", default: "false", description: "Disable the button." },
+ { name: "onClick", type: "(e: MouseEvent) => void", description: "Click handler." },
+ { name: "role", type: "string", description: "ARIA role attribute." },
+ { name: "type", type: '"button" | "submit" | "reset"', description: "HTML button type." },
+ { name: "buttonRef", type: "Ref", internal: true, description: "Ref to the underlying button element." },
+ { name: "className", type: "string", description: "Custom CSS class." },
+ { name: "style", type: "CSSProperties", description: "Inline styles." },
+];
export default function TextButtonTab() {
return (
-
-
-
- {ManaTextButtonVariants.map(variant => (
-
- ))}
-
-
-
-
-
- {ManaTextButtonTextVariants.map(textVariant => (
-
- ))}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- • text - Button label text
- • variant - primary, secondary, always-white, critical
- • textVariant - Typography variant (e.g., text-sm/medium)
- • lineClamp - Max lines before truncation
- • disabled - Disable button
- • onClick - Click handler
-
-
+
+ {ManaTextButtonVariants.map(variant => (
+
+ ))}
+
+ ),
+ code: '
',
+ relevantProps: ["variant"],
+ },
+ {
+ title: "Text Variants",
+ description: "Different typography sizes and weights.",
+ children: (
+
+ {ManaTextButtonTextVariants.map(textVariant => (
+
+ ))}
+
+ ),
+ relevantProps: ["textVariant"],
+ },
+ {
+ title: "States",
+ description: "Normal and disabled states.",
+ children: (
+
+
+
+
+ ),
+ relevantProps: ["disabled"],
+ },
+ {
+ title: "Line Clamp",
+ description: "Truncate long text to a single line.",
+ children: (
+
+
+
+ ),
+ relevantProps: ["lineClamp"],
+ },
+ ]}
+ props={TEXTBUTTON_PROPS}
+ />
);
}
diff --git a/src/equicordplugins/components.dev/components/tabs/TextInputTab.tsx b/src/equicordplugins/components.dev/components/tabs/TextInputTab.tsx
index 3bb864daf..478b27795 100644
--- a/src/equicordplugins/components.dev/components/tabs/TextInputTab.tsx
+++ b/src/equicordplugins/components.dev/components/tabs/TextInputTab.tsx
@@ -4,86 +4,118 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-import { ManaTextInput, Paragraph, useState } from "..";
-import { SectionWrapper } from "../SectionWrapper";
+import { ManaTextInput, useState } from "..";
+import { DocPage, type PropDef } from "../DocPage";
-export default function TextInputTab() {
- const [basic, setBasic] = useState("Hello world");
- const [sizeSm, setSizeSm] = useState("Small input");
- const [sizeMd, setSizeMd] = useState("Medium input");
- const [withPlaceholder, setWithPlaceholder] = useState("");
- const [clearable, setClearable] = useState("Clear me");
- const [charCount, setCharCount] = useState("Count chars");
- const [error, setError] = useState("Invalid input");
+const TEXTINPUT_PROPS: PropDef[] = [
+ { name: "value", type: "string", description: "Current input value (controlled)." },
+ { name: "defaultValue", type: "string", description: "Initial value (uncontrolled)." },
+ { name: "onChange", type: "(value: string, name?: string) => void", description: "Called when the input value changes." },
+ { name: "placeholder", type: "string", description: "Placeholder text when empty." },
+ { name: "name", type: "string", description: "HTML name attribute for form submission." },
+ { name: "type", type: '"text" | "password" | "email" | "number" | "search" | "tel" | "url"', default: '"text"', description: "Input type." },
+ { name: "size", type: '"sm" | "md"', default: '"md"', description: "Input size variant." },
+ { name: "clearable", type: "boolean | { show: boolean }", description: "Show a clear button when the input has a value." },
+ { name: "showCharacterCount", type: "boolean", description: "Display current character count." },
+ { name: "maxLength", type: "number", description: "Maximum character limit." },
+ { name: "minLength", type: "number", description: "Minimum character requirement." },
+ { name: "error", type: "string | boolean", description: "Error state. String shows error message, boolean shows red border." },
+ { name: "disabled", type: "boolean", default: "false", description: "Disable the input." },
+ { name: "readOnly", type: "boolean", description: "Make the input read-only." },
+ { name: "fullWidth", type: "boolean", description: "Expand to full available width." },
+ { name: "leading", type: "TextInputLeadingAccessory", description: "Leading accessory (icon, button, tags, or image)." },
+ { name: "trailing", type: "TextInputTrailingAccessory", description: "Trailing accessory (icon or button)." },
+ { name: "inputRef", type: "Ref
", internal: true, description: "Ref to the underlying input element." },
+];
+function BasicDemo() {
+ const [value, setValue] = useState("Hello world");
+ return ;
+}
+
+function SizesDemo() {
+ const [sm, setSm] = useState("Small");
+ const [md, setMd] = useState("Medium");
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- • value: string - Input value
-
-
- • onChange?: (value: string) => void - Called on input change
-
-
- • placeholder?: string - Placeholder text
-
-
- • size?: "sm" | "md" - Input size (default: "md")
-
-
- • clearable?: boolean - Show clear button
-
-
- • showCharacterCount?: boolean - Display character count
-
-
- • maxLength?: number - Maximum character limit
-
-
- • error?: boolean - Show error state styling
-
-
- • disabled?: boolean - Disable input
-
-
- • readOnly?: boolean - Make input read-only
-
-
+
+
+
);
}
+
+function ClearableDemo() {
+ const [value, setValue] = useState("Clear me");
+ return
;
+}
+
+function CharCountDemo() {
+ const [value, setValue] = useState("Count chars");
+ return
;
+}
+
+function ErrorDemo() {
+ const [value, setValue] = useState("Invalid input");
+ return
;
+}
+
+export default function TextInputTab() {
+ return (
+
,
+ code: "
",
+ relevantProps: ["value", "onChange"],
+ },
+ {
+ title: "Sizes",
+ description: "Available in sm and md (default) sizes.",
+ children:
,
+ relevantProps: ["size"],
+ },
+ {
+ title: "With Placeholder",
+ children: (
+
{ }} placeholder="Enter text here..." />
+ ),
+ relevantProps: ["placeholder"],
+ },
+ {
+ title: "Clearable",
+ description: "Shows a clear button when the input has a value.",
+ children: ,
+ relevantProps: ["clearable"],
+ },
+ {
+ title: "Character Count",
+ description: "Displays character count with a 50-character max.",
+ children: ,
+ relevantProps: ["showCharacterCount", "maxLength"],
+ },
+ {
+ title: "Error State",
+ description: "Red border indicating invalid input.",
+ children: ,
+ relevantProps: ["error"],
+ },
+ {
+ title: "States",
+ description: "Disabled and read-only states.",
+ children: (
+
+
+
+
+ ),
+ relevantProps: ["disabled", "readOnly"],
+ },
+ ]}
+ props={TEXTINPUT_PROPS}
+ />
+ );
+}
diff --git a/src/equicordplugins/components.dev/components/tabs/TimestampTab.tsx b/src/equicordplugins/components.dev/components/tabs/TimestampTab.tsx
index 6bbe18645..5804f7e15 100644
--- a/src/equicordplugins/components.dev/components/tabs/TimestampTab.tsx
+++ b/src/equicordplugins/components.dev/components/tabs/TimestampTab.tsx
@@ -5,162 +5,154 @@
*/
import { Paragraph, Timestamp, TimestampDisplayFormats, TooltipPositions } from "..";
-import { SectionWrapper } from "../SectionWrapper";
+import { DocPage, type PropDef } from "../DocPage";
+
+const TIMESTAMP_PROPS: PropDef[] = [
+ { name: "timestamp", type: "Date | Moment", required: true, description: "The date or moment object to display." },
+ { name: "timestampFormat", type: "TimestampDisplayFormat", description: 'Moment.js format string. One of: "LT", "LTS", "L", "LL", "LLL", "LLLL", "l", "ll", "lll", "llll".' },
+ { name: "compact", type: "boolean", default: "false", description: "Use a shorter display style." },
+ { name: "cozyAlt", type: "boolean", default: "false", description: "Use the cozy alternative layout." },
+ { name: "isInline", type: "boolean", default: "false", description: "Render the timestamp inline." },
+ { name: "isVisibleOnlyOnHover", type: "boolean", default: "false", description: "Hide the timestamp until the parent is hovered." },
+ { name: "isEdited", type: "boolean", default: "false", description: 'Show an "(edited)" indicator after the timestamp.' },
+ { name: "tooltipPosition", type: '"top" | "bottom" | "left" | "right"', description: "Position of the full-date tooltip." },
+ { name: "id", type: "string", description: "HTML id attribute." },
+ { name: "className", type: "string", description: "Additional CSS class." },
+ { name: "children", type: "ReactNode", description: "Custom content to render instead of the formatted timestamp." },
+];
export default function TimestampTab() {
const now = new Date();
return (
-
-
-
- All available timestamp format options using moment.js format strings.
-
-
- {TimestampDisplayFormats.map(({ format, description }) => (
-
-
-
- {format}: {description}
-
+
+ {TimestampDisplayFormats.map(({ format, description }) => (
+
+
+
+ {format}: {description}
+
+
+ ))}
- ))}
-
-
-
-
-
- Compact mode displays a shorter version of the timestamp.
-
-
-
-
-
- compact=false (default)
-
-
-
-
-
-
-
-
- Different display modes for timestamps.
-
-
-
-
-
- isInline=false (default)
-
-
-
-
-
-
-
-
-
- Shows an "(edited)" indicator after the timestamp.
-
-
-
-
-
- isEdited=false (default)
-
-
-
-
-
-
-
-
- Timestamp can be hidden until hovered.
-
-
-
-
- Hover me:
-
-
- isVisibleOnlyOnHover=true
-
-
-
-
-
-
-
- The tooltip showing full date can be positioned differently.
-
-
- {TooltipPositions.map(position => (
-
-
-
- tooltipPosition="{position}"
-
+ ),
+ code: '
',
+ relevantProps: ["timestamp", "timestampFormat"],
+ },
+ {
+ title: "Compact Mode",
+ description: "Compact mode shows a shorter version of the timestamp.",
+ children: (
+
+
+
+
+ compact=false (default)
+
+
+
- ))}
-
-
-
-
-
- • timestamp: Date | Moment - The timestamp to display (required)
-
-
- • timestampFormat?: TimestampFormat - Format string (LT, LTS, L, LL, LLL, LLLL, l, ll, lll, llll)
-
-
- • compact?: boolean - Use compact display mode
-
-
- • cozyAlt?: boolean - Use cozy alternative display
-
-
- • isInline?: boolean - Display inline
-
-
- • isVisibleOnlyOnHover?: boolean - Only show on hover
-
-
- • isEdited?: boolean - Show "(edited)" indicator
-
-
- • tooltipPosition?: "top" | "bottom" | "left" | "right" - Tooltip position
-
-
- • id?: string - Element ID
-
-
- • className?: string - Additional CSS class
-
-
- • children?: ReactNode - Custom content
-
-
-
+ ),
+ relevantProps: ["compact"],
+ },
+ {
+ title: "Display Variants",
+ description: "Inline and cozy alternative display modes.",
+ children: (
+
+
+
+
+ isInline=false (default)
+
+
+
+
+
+ ),
+ relevantProps: ["isInline", "cozyAlt"],
+ },
+ {
+ title: "Edited Indicator",
+ description: 'Shows an "(edited)" indicator after the timestamp.',
+ children: (
+
+
+
+
+ isEdited=false (default)
+
+
+
+
+ ),
+ relevantProps: ["isEdited"],
+ },
+ {
+ title: "Visibility on Hover",
+ description: "Timestamp can be hidden until the parent element is hovered.",
+ children: (
+
+
+
+ Hover me:
+
+
+ isVisibleOnlyOnHover=true
+
+
+
+ ),
+ relevantProps: ["isVisibleOnlyOnHover"],
+ },
+ {
+ title: "Tooltip Positions",
+ description: "The tooltip showing the full date can be positioned on any side.",
+ children: (
+
+ {TooltipPositions.map(position => (
+
+
+
+ tooltipPosition="{position}"
+
+
+ ))}
+
+ ),
+ relevantProps: ["tooltipPosition"],
+ },
+ ]}
+ props={TIMESTAMP_PROPS}
+ />
);
}
diff --git a/src/equicordplugins/components.dev/components/tabs/ToastTab.tsx b/src/equicordplugins/components.dev/components/tabs/ToastTab.tsx
index 7c6974072..8c187fe3e 100644
--- a/src/equicordplugins/components.dev/components/tabs/ToastTab.tsx
+++ b/src/equicordplugins/components.dev/components/tabs/ToastTab.tsx
@@ -4,137 +4,150 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-import { ManaButton, Paragraph, showToast, Toasts, ToastType, ToastTypeValue } from "..";
-import { SectionWrapper } from "../SectionWrapper";
+import { ManaButton, Paragraph, showToast, Toasts, ToastType, type ToastTypeValue } from "..";
+import { DocPage, type PropGroup } from "../DocPage";
-const TOAST_TYPES = [
- { type: ToastType.MESSAGE, label: "MESSAGE", description: "Default message toast" },
- { type: ToastType.SUCCESS, label: "SUCCESS", description: "Green success toast" },
- { type: ToastType.FAILURE, label: "FAILURE", description: "Red failure/error toast" },
- { type: ToastType.CLIP, label: "CLIP", description: "Clip/copy toast" },
- { type: ToastType.LINK, label: "LINK", description: "Link copied toast" },
- { type: ToastType.FORWARD, label: "FORWARD", description: "Forward action toast" },
- { type: ToastType.INVITE, label: "INVITE", description: "Invite action toast" },
- { type: ToastType.BOOKMARK, label: "BOOKMARK", description: "Bookmark action toast" },
- { type: ToastType.CLOCK, label: "CLOCK", description: "Clock/timer toast" },
- { type: ToastType.AI, label: "AI", description: "AI action toast" },
-] as const;
+const TOAST_TYPES: { type: ToastTypeValue; label: string; description: string; }[] = [
+ { type: ToastType.MESSAGE, label: "MESSAGE", description: "Default message toast." },
+ { type: ToastType.SUCCESS, label: "SUCCESS", description: "Green success toast." },
+ { type: ToastType.FAILURE, label: "FAILURE", description: "Red failure/error toast." },
+ { type: ToastType.CLIP, label: "CLIP", description: "Clip/copy toast." },
+ { type: ToastType.LINK, label: "LINK", description: "Link copied toast." },
+ { type: ToastType.FORWARD, label: "FORWARD", description: "Forward action toast." },
+ { type: ToastType.BOOKMARK, label: "BOOKMARK", description: "Bookmark action toast." },
+ { type: ToastType.CLOCK, label: "CLOCK", description: "Clock/timer toast." },
+];
+
+const PROP_GROUPS: PropGroup[] = [
+ {
+ title: "showToast(message, type)",
+ props: [
+ { name: "message", type: "string", required: true, description: "Toast message text." },
+ { name: "type", type: "ToastTypeValue", default: '"message"', description: "Toast type from ToastType." },
+ ],
+ },
+ {
+ title: "Toasts.create(message, type, options)",
+ props: [
+ { name: "message", type: "string", required: true, description: "Toast message text." },
+ { name: "type", type: "ToastTypeValue", required: true, description: "Toast type from ToastType." },
+ { name: "options.duration", type: "number", description: "Display time in milliseconds." },
+ { name: "options.position", type: "0 | 1", description: "Toast position. 0 = TOP, 1 = BOTTOM." },
+ { name: "options.component", type: "ReactNode", description: "Custom React content for CUSTOM type toasts." },
+ ],
+ },
+ {
+ title: "ToastType",
+ props: [
+ { name: "MESSAGE", type: '"message"', description: "Default message style." },
+ { name: "SUCCESS", type: '"success"', description: "Green checkmark icon." },
+ { name: "FAILURE", type: '"failure"', description: "Red X icon." },
+ { name: "CUSTOM", type: '"custom"', description: "Custom component content." },
+ { name: "CLIP", type: '"clip"', description: "Clip/scissors icon." },
+ { name: "LINK", type: '"link"', description: "Link icon." },
+ { name: "FORWARD", type: '"forward"', description: "Forward arrow icon." },
+ { name: "BOOKMARK", type: '"bookmark"', description: "Bookmark icon." },
+ { name: "CLOCK", type: '"clock"', description: "Clock icon." },
+ ],
+ },
+];
export default function ToastTab() {
- const showSimpleToast = (type: ToastTypeValue, label: string) => {
- showToast(`This is a ${label} toast!`, type);
- };
-
- const showAdvancedToast = () => {
- const toast = Toasts.create("Advanced toast with options", ToastType.SUCCESS, {
- duration: 5000,
- position: Toasts.Position.BOTTOM,
- });
- Toasts.show(toast);
- };
-
- const showCustomToast = () => {
- const toast = Toasts.create("Custom component toast", ToastType.CUSTOM, {
- component: Custom JSX content!,
- });
- Toasts.show(toast);
- };
-
return (
-
-
-
- Click buttons to show different toast types. Toasts appear at screen edges.
-
-
- {TOAST_TYPES.map(({ type, label, description }) => (
-
+
+ {TOAST_TYPES.map(({ type, label, description }) => (
+
+
showToast(`This is a ${label} toast!`, type)}
+ />
+
+ {description}
+
+
+ ))}
+
+ ),
+ code: 'showToast("Copied to clipboard!", ToastType.SUCCESS);',
+ },
+ {
+ title: "Simple Usage",
+ description: "showToast is the quickest way to show a toast. It creates and shows a toast in one call.",
+ children: (
+
showToast("Hello from showToast!", ToastType.SUCCESS)}
+ />
+ ),
+ code: 'showToast("Hello from showToast!", ToastType.SUCCESS);',
+ },
+ {
+ title: "Advanced Usage",
+ description: "Use Toasts.create to build a toast with custom duration, position, or component content, then Toasts.show to display it.",
+ children: (
+
showSimpleToast(type, label)}
+ text="5s Duration Toast"
+ onClick={() => {
+ const toast = Toasts.create("This lasts 5 seconds", ToastType.SUCCESS, { duration: 5000 });
+ Toasts.show(toast);
+ }}
+ />
+ {
+ const toast = Toasts.create("Bottom toast", ToastType.MESSAGE, { position: Toasts.Position.BOTTOM });
+ Toasts.show(toast);
+ }}
+ />
+ {
+ const toast = Toasts.create("Custom", ToastType.CUSTOM, {
+ component: Custom JSX content!,
+ });
+ Toasts.show(toast);
+ }}
/>
-
- {description}
-
- ))}
-
-
-
-
-
- showToast(message, type) - Quick way to show a toast.
-
- showToast("Hello from showToast!", ToastType.SUCCESS)}
- />
-
-
-
-
- Toasts.show() with full options object.
-
-
-
-
-
-
-
-
-
- Toasts.pop() removes the most recent toast.
-
- Toasts.pop()}
- />
-
-
-
- • MESSAGE - Default message style
- • SUCCESS - Green checkmark icon
- • FAILURE - Red X icon
- • CUSTOM - Custom component content
- • CLIP - Clip/scissors icon
- • LINK - Link icon
- • FORWARD - Forward arrow icon
- • INVITE - Invite icon
- • BOOKMARK - Bookmark icon
- • CLOCK - Clock icon
- • AI - AI icon
-
-
-
- • TOP (0) - Toast appears at top
- • BOTTOM (1) - Toast appears at bottom
-
-
-
- • message - Toast message text
- • type - Toast type from ToastType
- • id - Unique ID (use Toasts.genId())
- • options.duration - Display time in ms
- • options.position - ToastPosition value
- • options.component - Custom React component
-
-
-
-
- {"import { showToast, Toasts, ToastType, ToastPosition } from \"../components\";"}
-
-
-
+ ),
+ code: `const toast = Toasts.create("Done!", ToastType.SUCCESS, {
+ duration: 5000,
+ position: Toasts.Position.BOTTOM,
+});
+Toasts.show(toast);`,
+ },
+ {
+ title: "Pop Toast",
+ description: "Toasts.pop removes the most recent toast from the stack.",
+ children: (
+ Toasts.pop()}
+ />
+ ),
+ code: "Toasts.pop();",
+ },
+ ]}
+ props={PROP_GROUPS}
+ />
);
}
diff --git a/src/equicordplugins/components.dev/components/tabs/TooltipTab.tsx b/src/equicordplugins/components.dev/components/tabs/TooltipTab.tsx
index b25c4aa56..42a8f50df 100644
--- a/src/equicordplugins/components.dev/components/tabs/TooltipTab.tsx
+++ b/src/equicordplugins/components.dev/components/tabs/TooltipTab.tsx
@@ -5,90 +5,153 @@
*/
import { ManaButton, ManaTooltip, Paragraph, TooltipColors, TooltipPositions } from "..";
-import { SectionWrapper } from "../SectionWrapper";
+import { DocPage, type PropDef } from "../DocPage";
+
+const TOOLTIP_PROPS: PropDef[] = [
+ { name: "text", type: "string | (() => ReactNode)", required: true, description: "Tooltip content. Can be a string or a render function for rich content." },
+ { name: "children", type: "(props) => ReactNode", required: true, description: "Render function that receives props to spread on the trigger element." },
+ { name: "position", type: '"top" | "bottom" | "left" | "right"', default: '"top"', description: "Which side of the trigger the tooltip appears on." },
+ { name: "align", type: '"start" | "center" | "end"', default: '"center"', description: "Alignment along the tooltip edge." },
+ { name: "color", type: '"primary" | "grey" | "brand" | "green" | "red"', default: '"primary"', description: "Tooltip background color." },
+ { name: "spacing", type: "number", default: "8", description: "Gap in pixels between the trigger and tooltip." },
+ { name: "delay", type: "number", description: "Delay in milliseconds before the tooltip appears." },
+ { name: "hideOnClick", type: "boolean", default: "true", description: "Hide the tooltip when the trigger is clicked." },
+ { name: "forceOpen", type: "boolean", description: "Force the tooltip to stay open." },
+ { name: "shouldShow", type: "boolean", description: "Externally control whether the tooltip is shown." },
+ { name: "allowOverflow", type: "boolean", description: "Allow the tooltip to overflow its container." },
+ { name: "overflowOnly", type: "boolean", description: "Only show the tooltip when the trigger text is overflowing." },
+ { name: "tooltipClassName", type: "string", description: "CSS class for the tooltip container." },
+ { name: "tooltipStyle", type: "CSSProperties", description: "Inline styles for the tooltip container." },
+ { name: "tooltipContentClassName", type: "string", description: "CSS class for the tooltip content." },
+ { name: "tooltipPointerClassName", type: "string", description: "CSS class for the tooltip arrow pointer." },
+ { name: "positionKeyStemOverride", type: "string", internal: true, description: "Override the position key stem used for animation keying." },
+ { name: "clickableOnMobile", type: "boolean", description: "Make the tooltip trigger clickable on mobile devices." },
+ { name: "disableTooltipPointerEvents", type: "boolean", description: "Disable pointer events on the tooltip overlay." },
+ { name: "targetElementRef", type: "RefObject", description: "Ref to an external element to position the tooltip against." },
+ { name: "onTooltipShow", type: "() => void", description: "Callback when the tooltip becomes visible." },
+ { name: "onTooltipHide", type: "() => void", description: "Callback when the tooltip is hidden." },
+ { name: "onAnimationRest", type: "() => void", description: "Callback when the tooltip show/hide animation completes." },
+ { name: "aria-label", type: "string | false", description: "Accessibility label. Set to false to disable." },
+];
export default function TooltipTab() {
return (
-
-
-
- {TooltipPositions.map(position => (
-
- {props => (
-
- )}
-
- ))}
-
-
-
-
-
- {TooltipColors.map(color => (
-
- {props => (
-
- )}
-
- ))}
-
-
-
-
-
-
- {props => (
-
- )}
-
-
- {props => (
-
- )}
-
-
- {props => (
-
- )}
-
-
-
-
-
-
-
- {props => (
-
- )}
-
-
- {props => (
-
- )}
-
-
-
-
-
-
- • text: string - Tooltip content
-
-
- • children: (props) => ReactNode - Render function for trigger element
-
-
- • position?: "top" | "bottom" | "left" | "right" - Tooltip position
-
-
- • color?: "primary" | "black" | "grey" | "brand" | "green" | "yellow" | "red"
-
-
- • delay?: number - Show delay in milliseconds
-
-
- • hideOnClick?: boolean - Hide tooltip when trigger is clicked
-
-
-
+
+ {TooltipPositions.map(position => (
+
+ {props => (
+
+ )}
+
+ ))}
+
+ ),
+ code: `
+ {props => }
+`,
+ relevantProps: ["position"],
+ },
+ {
+ title: "Colors",
+ description: "Five background color variants.",
+ children: (
+
+ {TooltipColors.map(color => (
+
+ {props => (
+
+ )}
+
+ ))}
+
+ ),
+ code: '\n {props => }\n',
+ relevantProps: ["color"],
+ },
+ {
+ title: "Delay",
+ description: "Configure how long to wait before showing the tooltip.",
+ children: (
+
+
+ {props => (
+
+ )}
+
+
+ {props => (
+
+ )}
+
+
+ {props => (
+
+ )}
+
+
+ ),
+ relevantProps: ["delay"],
+ },
+ {
+ title: "Hide on Click",
+ description: "By default tooltips hide when the trigger is clicked. Set hideOnClick=false to keep them visible.",
+ children: (
+
+
+ {props => (
+
+ )}
+
+
+ {props => (
+
+ )}
+
+
+ ),
+ relevantProps: ["hideOnClick"],
+ },
+ {
+ title: "Rich Content",
+ description: "The text prop accepts a function that returns JSX for rich tooltip content.",
+ children: (
+
+
(
+
+
Rich Tooltip
+
With multiple lines of content.
+
+ )}>
+ {props => (
+
+ )}
+
+
+ ),
+ code: ` (
+
+
Title
+
Description text
+
+)}>
+ {props => }
+`,
+ relevantProps: ["text"],
+ },
+ ]}
+ props={TOOLTIP_PROPS}
+ />
);
}
diff --git a/src/equicordplugins/components.dev/components/tabs/TypographyTab.tsx b/src/equicordplugins/components.dev/components/tabs/TypographyTab.tsx
index 675fd894e..2a7acead9 100644
--- a/src/equicordplugins/components.dev/components/tabs/TypographyTab.tsx
+++ b/src/equicordplugins/components.dev/components/tabs/TypographyTab.tsx
@@ -5,117 +5,140 @@
*/
import { CodeColors, FontSizeMap, Paragraph, TextColors, TextSizes, TextWeights } from "..";
-import { SectionWrapper } from "../SectionWrapper";
+import { DocPage, type PropGroup } from "../DocPage";
+
+const PROP_GROUPS: PropGroup[] = [
+ {
+ title: "Text Colors",
+ props: TextColors.map(color => ({
+ name: color,
+ type: "CSS variable",
+ description: `var(--${color})`,
+ })),
+ },
+ {
+ title: "Text Sizes",
+ props: TextSizes.map(({ name, value, pixels }) => ({
+ name,
+ type: "font-size",
+ description: `${value} (${pixels}).`,
+ })),
+ },
+ {
+ title: "Text Weights",
+ props: TextWeights.map(({ name, value }) => ({
+ name,
+ type: "font-weight",
+ description: `font-weight: ${value}.`,
+ })),
+ },
+ {
+ title: "Code Colors",
+ props: CodeColors.map(color => ({
+ name: color,
+ type: "CSS variable",
+ description: `var(--${color})`,
+ })),
+ },
+];
export default function TypographyTab() {
return (
-
-
-
- {TextColors.map(color => (
-
-
- {color}
-
-
- var(--{color})
-
+
+ {TextColors.map(color => (
+
+
+ {color}
+
+
+ var(--{color})
+
+
+ ))}
- ))}
-
-
-
-
-
- {TextSizes.map(({ name, value, pixels }) => (
-
-
- {name}
-
-
- {value} ({pixels})
-
+ ),
+ code: '
Muted text',
+ },
+ {
+ title: "Text Sizes",
+ description: "Font sizes from xxs (10px) to xxl (32px).",
+ children: (
+
+ {TextSizes.map(({ name, value, pixels }) => (
+
+
+ {name}
+
+
+ {value} ({pixels})
+
+
+ ))}
- ))}
-
-
-
-
-
- {TextWeights.map(({ name, value }) => (
-
-
- {name}
-
-
- font-weight: {value}
-
+ ),
+ },
+ {
+ title: "Text Weights",
+ description: "Font weights from thin (100) to extrabold (800).",
+ children: (
+
+ {TextWeights.map(({ name, value }) => (
+
+
+ {name}
+
+
+ font-weight: {value}
+
+
+ ))}
- ))}
-
-
-
-
-
-
- {"import { BaseText } from \"@components/BaseText\";"}
-
-
- {"Text"}
-
-
-
-
-
-
- {CodeColors.map(color => (
-
-
- {color}
-
-
- var(--{color})
-
+ ),
+ },
+ {
+ title: "Code Colors",
+ description: "Syntax highlighting colors for code blocks.",
+ children: (
+
+ {CodeColors.map(color => (
+
+
+ {color}
+
+
+ var(--{color})
+
+
+ ))}
- ))}
-
-
-
-
-
- BaseText - from @components/BaseText
-
-
- • size?: "xxs" | "xs" | "sm" | "md" | "lg" | "xl" | "xxl"
-
-
- • weight?: "thin" | "extralight" | "light" | "normal" | "medium" | "semibold" | "bold" | "extrabold"
-
-
- • color?: string - CSS variable name (e.g., "text-muted")
-
-
- • tag?: "span" | "p" | "div" | "h1" - etc.
-
-
- Heading - from @components/Heading
-
-
- • tag?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" (default: h5)
-
-
- Paragraph - from @components/Paragraph
-
-
- • color?: string - CSS variable name
-
-
- Span - from @components/Span
-
-
- • Inline text with default styling
-
-
-
+ ),
+ },
+ {
+ title: "Usage with Components",
+ description: "These values are used with Paragraph, DiscordHeading, and DiscordText. See those tabs for component-specific documentation.",
+ children: (
+
+
text-default: Primary readable text.
+
text-muted: Secondary, less prominent text.
+
text-link: Clickable link text.
+
text-brand: Brand-colored text.
+
+ ),
+ code: `Muted text
+Brand text
+Bold heading`,
+ },
+ ]}
+ props={PROP_GROUPS}
+ />
);
}
diff --git a/src/equicordplugins/components.dev/components/tabs/UserSummaryItemTab.tsx b/src/equicordplugins/components.dev/components/tabs/UserSummaryItemTab.tsx
index 0b6cd42dc..597ec004d 100644
--- a/src/equicordplugins/components.dev/components/tabs/UserSummaryItemTab.tsx
+++ b/src/equicordplugins/components.dev/components/tabs/UserSummaryItemTab.tsx
@@ -4,89 +4,146 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-import { Paragraph, UserStore, UserSummaryItem } from "..";
-import { SectionWrapper } from "../SectionWrapper";
+import { Paragraph, UserStore, UserSummaryItem, useState } from "..";
+import { DocPage, type PropDef } from "../DocPage";
-export default function UserSummaryItemTab() {
+const USER_SUMMARY_PROPS: PropDef[] = [
+ { name: "users", type: "(User | null)[]", required: true, description: "Array of User objects to display as avatars. Null entries render as empty slots." },
+ { name: "max", type: "number", default: "10", description: "Maximum number of avatars to show before the overflow indicator." },
+ { name: "count", type: "number", description: 'Override the count used in the "+N" overflow display.' },
+ { name: "size", type: "16 | 24 | 32 | 56", default: "24", description: "Avatar size in pixels." },
+ { name: "guildId", type: "string", description: "Guild context for server-specific avatars." },
+ { name: "showUserPopout", type: "boolean", default: "false", description: "Show user popout when an avatar is clicked." },
+ { name: "showDefaultAvatarsForNullUsers", type: "boolean", description: "Render default avatars for null entries in the users array." },
+ { name: "renderUser", type: "(user, isLast, index) => ReactNode", description: "Custom render function for each user avatar." },
+ { name: "renderMoreUsers", type: "(text, count) => ReactNode", description: 'Custom render function for the "+N" overflow indicator.' },
+ { name: "renderIcon", type: "boolean", description: "Whether to render an icon." },
+ { name: "renderLeadingIcon", type: "(className) => ReactNode", description: "Render a leading icon before the user avatars." },
+ { name: "dimEmptyUsers", type: "boolean", description: "Dim null user slots." },
+ { name: "hideMoreUsers", type: "boolean", default: "false", description: 'Hide the "+N" overflow count.' },
+ { name: "useFallbackUserForPopout", type: "boolean", description: "Use fallback user data for popout when user data is unavailable." },
+ { name: "extraDetail", type: "ReactNode", description: "Additional content rendered after the avatars." },
+ { name: "className", type: "string", description: "CSS class for the container." },
+];
+
+function MaxUsersDemo() {
const currentUser = UserStore.getCurrentUser();
- const users = currentUser ? [currentUser, currentUser, currentUser, currentUser, currentUser] : [];
+ const users = currentUser ? Array(5).fill(currentUser) : [];
return (
-
-
-
- Displays a row of user avatars with overflow indicator.
-
-
-
+
+ {[2, 3, 5].map(max => (
+
-
-
-
-
- Available sizes: 16, 24, 32, 56.
-
-
-
-
-
-
- Control how many avatars to show before overflow.
-
-
-
-
-
-
- Enable user popout on avatar click.
-
-
-
-
-
-
-
- • users - Array of User objects (or null for empty slots)
- • max - Maximum avatars to show (default 10)
- • count - Override count for "+N" display
- • size - 16, 24, 32, or 56 (default 24)
- • guildId - Guild context for avatars
- • showUserPopout - Enable user popout on click
- • showDefaultAvatarsForNullUsers - Show default avatar for null
- • renderUser - Custom render function for each user
- • renderMoreUsers - Custom render for overflow indicator
- • hideMoreUsers - Hide the "+N" overflow count
-
+ ))}
);
}
+
+function SizesDemo() {
+ const currentUser = UserStore.getCurrentUser();
+ const users = currentUser ? Array(5).fill(currentUser) : [];
+
+ return (
+
+ {([16, 24, 32, 56] as const).map(size => (
+
+ ))}
+
+ );
+}
+
+function OverrideCountDemo() {
+ const currentUser = UserStore.getCurrentUser();
+ const users = currentUser ? Array(3).fill(currentUser) : [];
+ const [count, setCount] = useState(42);
+
+ return (
+
+ );
+}
+
+export default function UserSummaryItemTab() {
+ const currentUser = UserStore.getCurrentUser();
+ const users = currentUser ? Array(5).fill(currentUser) : [];
+
+ return (
+
+ ),
+ code: `const users = [user1, user2, user3, user4, user5];
+
`,
+ relevantProps: ["users", "max"],
+ },
+ {
+ title: "Sizes",
+ description: "Four avatar sizes: 16, 24, 32, and 56 pixels.",
+ children:
,
+ code: "
",
+ relevantProps: ["size"],
+ },
+ {
+ title: "Max Users",
+ description: "Control how many avatars are visible before the overflow count.",
+ children:
,
+ relevantProps: ["max"],
+ },
+ {
+ title: "Override Count",
+ description: 'The count prop overrides the number shown in the "+N" indicator, useful when the total is different from users.length.',
+ children:
,
+ relevantProps: ["count"],
+ },
+ {
+ title: "User Popout",
+ description: "Enable user popout on avatar click with showUserPopout.",
+ children: (
+
+ ),
+ code: "
",
+ relevantProps: ["showUserPopout"],
+ },
+ {
+ title: "Hide Overflow",
+ description: 'Hide the "+N" overflow indicator entirely.',
+ children: (
+
+
+
hideMoreUsers=false:
+
+
+
+
hideMoreUsers=true:
+
+
+
+ ),
+ relevantProps: ["hideMoreUsers"],
+ },
+ ]}
+ props={USER_SUMMARY_PROPS}
+ />
+ );
+}
diff --git a/src/equicordplugins/components.dev/constants.ts b/src/equicordplugins/components.dev/constants.ts
index 6577cfc0a..faad5dda5 100644
--- a/src/equicordplugins/components.dev/constants.ts
+++ b/src/equicordplugins/components.dev/constants.ts
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-export const ManaButtonVariants = ["primary", "secondary", "critical-primary", "critical-secondary", "overlay-primary", "overlay-secondary", "expressive"] as const;
+export const ManaButtonVariants = ["primary", "secondary", "critical-primary", "critical-secondary", "active", "overlay-primary", "overlay-secondary", "expressive"] as const;
export type ManaButtonVariant = typeof ManaButtonVariants[number];
export const ManaButtonSizes = ["xs", "sm", "md"] as const;
@@ -34,7 +34,7 @@ export type TooltipPosition = typeof TooltipPositions[number];
export const TooltipAligns = ["start", "center", "end"] as const;
export type TooltipAlign = typeof TooltipAligns[number];
-export const TooltipColors = ["primary", "black", "grey", "brand", "green", "yellow", "red"] as const;
+export const TooltipColors = ["primary", "grey", "brand", "green", "red"] as const;
export type TooltipColor = typeof TooltipColors[number];
export const TextInputSizes = ["sm", "md"] as const;
@@ -174,10 +174,8 @@ export const ToastType = {
CLIP: "clip",
LINK: "link",
FORWARD: "forward",
- INVITE: "invite",
BOOKMARK: "bookmark",
CLOCK: "clock",
- AI: "ai",
} as const;
export const ToastPosition = {
diff --git a/src/equicordplugins/components.dev/styles.css b/src/equicordplugins/components.dev/styles.css
index bd5a919bc..d0033e15f 100644
--- a/src/equicordplugins/components.dev/styles.css
+++ b/src/equicordplugins/components.dev/styles.css
@@ -1,3 +1,5 @@
+/* ── Search & Tab Navigation ── */
+
.vc-compfinder-search {
margin-bottom: 40px;
}
@@ -22,12 +24,18 @@
padding-top: 16px;
}
+/* ── Shared Utility Layouts ── */
+
.vc-compfinder-section {
display: flex;
flex-direction: column;
gap: 8px;
}
+.vc-compfinder-section-block > :nth-child(n+3) {
+ margin-top: 8px;
+}
+
.vc-compfinder-grid {
display: flex;
flex-wrap: wrap;
@@ -46,23 +54,25 @@
align-items: center;
gap: 8px;
padding: 8px 12px;
- background: var(--background-secondary);
+ background: rgb(0 0 0 / 15%);
border-radius: 4px;
}
.vc-compfinder-demo-button {
padding: 8px 16px;
- background: var(--background-secondary);
- border: 1px solid var(--border-subtle);
+ background: rgb(0 0 0 / 15%);
+ border: 1px solid rgb(255 255 255 / 6%);
border-radius: 4px;
color: var(--text-normal);
cursor: pointer;
}
.vc-compfinder-demo-button:hover {
- background: var(--background-secondary-alt);
+ background: rgb(0 0 0 / 25%);
}
+/* ── Modal Demo Helpers ── */
+
.vc-compfinder-modal-header {
display: flex;
align-items: flex-start;
@@ -96,3 +106,209 @@
color: var(--white-500);
background-color: var(--button-danger-background);
}
+
+/* ── DocPage Layout ── */
+
+.vc-compfinder-doc-page {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.vc-compfinder-doc-page > .vc-divider {
+ margin: 8px 0;
+}
+
+.vc-compfinder-doc-title {
+ margin-bottom: -8px;
+}
+
+.vc-compfinder-doc-section {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.vc-compfinder-doc-section [id] {
+ scroll-margin-top: 16px;
+}
+
+.vc-compfinder-doc-demo {
+ padding: 16px;
+}
+
+.vc-compfinder-doc-relevant-props {
+ margin-top: 8px;
+}
+
+.vc-compfinder-doc-prop-group {
+ margin-bottom: 16px;
+}
+
+.vc-compfinder-doc-example {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.vc-compfinder-doc-example + .vc-compfinder-doc-example {
+ margin-top: 12px;
+}
+
+/* ── Import Block ── */
+
+.vc-compfinder-import-block {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+}
+
+.vc-compfinder-import-label {
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+/* ── Table of Contents ── */
+
+.vc-compfinder-toc {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+}
+
+.vc-compfinder-toc-label {
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+.vc-compfinder-toc-links {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 2px 12px;
+}
+
+.vc-compfinder-toc-link {
+ color: var(--text-link);
+ font-size: 0.8125rem;
+ text-decoration: none;
+ cursor: pointer;
+ line-height: 1.6;
+}
+
+.vc-compfinder-toc-link:hover {
+ text-decoration: underline;
+}
+
+/* ── Props Table ── */
+
+.vc-compfinder-table-wrapper {
+ overflow-x: auto;
+}
+
+.vc-compfinder-table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 0.75rem;
+}
+
+.vc-compfinder-table th {
+ text-align: left;
+ padding: 8px 12px;
+ font-size: 0.625rem;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ color: var(--text-muted);
+ background: rgb(0 0 0 / 20%);
+ border-bottom: 1px solid rgb(255 255 255 / 6%);
+ vertical-align: middle;
+}
+
+.vc-compfinder-table td {
+ padding: 8px 12px;
+ color: var(--text-normal);
+ vertical-align: middle;
+}
+
+.vc-compfinder-table tbody tr:nth-child(odd) {
+ background: rgb(0 0 0 / 8%);
+}
+
+.vc-compfinder-table tbody tr:nth-child(even) {
+ background: rgb(0 0 0 / 15%);
+}
+
+.vc-compfinder-table code.inline {
+ padding: 1px 4px !important;
+ font-size: 0.625rem !important;
+ line-height: 1.3;
+ white-space: nowrap;
+}
+
+.vc-compfinder-doc-page code.inline {
+ padding: 2px 5px;
+ font-size: 0.75rem;
+}
+
+.vc-compfinder-doc-page pre code {
+ font-size: 0.75rem !important;
+}
+
+.vc-compfinder-table td:nth-child(2) {
+ white-space: nowrap;
+}
+
+.vc-compfinder-table-field {
+ font-weight: 600;
+ font-size: 0.75rem;
+ color: var(--text-normal);
+ font-family: var(--font-code);
+ white-space: nowrap;
+}
+
+.vc-compfinder-table-row-required td:first-child {
+ border-left: 3px solid var(--status-positive);
+ padding-left: 9px;
+}
+
+.vc-compfinder-table-row-internal td:first-child {
+ border-left: 3px solid var(--status-warning);
+ padding-left: 9px;
+}
+
+.vc-compfinder-table-legend {
+ display: flex;
+ gap: 16px;
+ margin-top: 8px;
+}
+
+.vc-compfinder-table-legend-item {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ font-size: 0.6875rem;
+ color: var(--text-muted);
+}
+
+.vc-compfinder-table-legend-bar {
+ width: 3px;
+ height: 12px;
+ border-radius: 1px;
+}
+
+.vc-compfinder-table-legend-required {
+ background: var(--status-positive);
+}
+
+.vc-compfinder-table-legend-internal {
+ background: var(--status-warning);
+}
+
+.vc-compfinder-table-dash {
+ color: var(--text-faint);
+}
+
+.vc-compfinder-table-desc {
+ color: var(--text-muted);
+ line-height: 1.4;
+}
diff --git a/src/equicordplugins/components.dev/types/avatar.d.ts b/src/equicordplugins/components.dev/types/avatar.d.ts
index e4ff7e5e7..50fdc530a 100644
--- a/src/equicordplugins/components.dev/types/avatar.d.ts
+++ b/src/equicordplugins/components.dev/types/avatar.d.ts
@@ -22,6 +22,7 @@ export interface AvatarProps {
statusColor?: string;
statusBackdropColor?: string;
isMobile?: boolean;
+ isVR?: boolean;
isTyping?: boolean;
isSpeaking?: boolean;
isLatched?: boolean;
@@ -35,9 +36,17 @@ export interface AvatarProps {
avatarTooltipAsset?: React.ReactNode;
avatarTooltipText?: string;
avatarTooltipTitle?: string;
+ avatarDecoration?: string;
"aria-hidden"?: boolean;
"aria-label"?: string;
imageClassName?: string;
className?: string;
+ onClick?: React.MouseEventHandler
;
+ onMouseDown?: React.MouseEventHandler;
+ onKeyDown?: React.KeyboardEventHandler;
+ onContextMenu?: React.MouseEventHandler;
+ onMouseEnter?: React.MouseEventHandler;
+ onMouseLeave?: React.MouseEventHandler;
+ tabIndex?: number;
ref?: React.Ref;
}
diff --git a/src/equicordplugins/components.dev/types/badge.d.ts b/src/equicordplugins/components.dev/types/badge.d.ts
index 7e23861d0..3f58a57d2 100644
--- a/src/equicordplugins/components.dev/types/badge.d.ts
+++ b/src/equicordplugins/components.dev/types/badge.d.ts
@@ -11,7 +11,7 @@ export interface BadgeShapesType {
SQUARE: string;
}
-export interface NumberBadgeProps {
+export interface NumberBadgeProps extends Omit, "children"> {
count: number;
color?: string;
disableColor?: boolean;
@@ -21,7 +21,7 @@ export interface NumberBadgeProps {
renderBadgeCount?: (count: number) => string;
}
-export interface TextBadgeProps {
+export interface TextBadgeProps extends Omit, "children"> {
text: string;
color?: string;
disableColor?: boolean;
@@ -39,10 +39,19 @@ export interface IconBadgeProps {
style?: React.CSSProperties;
}
-export interface CircleBadgeProps {
+export interface CircleBadgeProps extends Omit, "children"> {
color?: string;
disableColor?: boolean;
shape?: string;
className?: string;
style?: React.CSSProperties;
}
+
+export interface PremiumBadgeProps extends Omit, "children"> {
+ text: string;
+ className?: string;
+ color?: string;
+ disableColor?: boolean;
+ shape?: string;
+ style?: React.CSSProperties;
+}
diff --git a/src/equicordplugins/components.dev/types/calendar.d.ts b/src/equicordplugins/components.dev/types/calendar.d.ts
index 3d0300d7e..1de325466 100644
--- a/src/equicordplugins/components.dev/types/calendar.d.ts
+++ b/src/equicordplugins/components.dev/types/calendar.d.ts
@@ -27,6 +27,14 @@ export interface ManaDatePickerProps {
disabled?: boolean;
required?: boolean;
label?: string;
+ hideLabel?: boolean;
+ badge?: React.ReactNode;
+ icon?: React.ReactNode;
description?: string;
+ helperText?: string;
errorMessage?: string;
+ successMessage?: string;
+ id?: string;
+ layout?: string;
+ layoutConfig?: Record;
}
diff --git a/src/equicordplugins/components.dev/types/checkbox.d.ts b/src/equicordplugins/components.dev/types/checkbox.d.ts
index 065ff1803..5b891e55a 100644
--- a/src/equicordplugins/components.dev/types/checkbox.d.ts
+++ b/src/equicordplugins/components.dev/types/checkbox.d.ts
@@ -35,4 +35,16 @@ export interface ManaCheckboxGroupProps {
selectedValues: (string | number)[];
onChange?: (values: (string | number)[]) => void;
disabled?: boolean;
+ label?: string;
+ hideLabel?: boolean;
+ badge?: React.ReactNode;
+ icon?: React.ReactNode;
+ required?: boolean;
+ description?: string;
+ helperText?: string;
+ errorMessage?: string;
+ successMessage?: string;
+ id?: string;
+ layout?: string;
+ layoutConfig?: Record;
}
diff --git a/src/equicordplugins/components.dev/types/input.d.ts b/src/equicordplugins/components.dev/types/input.d.ts
index 2fbccadad..f438e1ebf 100644
--- a/src/equicordplugins/components.dev/types/input.d.ts
+++ b/src/equicordplugins/components.dev/types/input.d.ts
@@ -47,6 +47,18 @@ export interface ManaTextInputProps {
defaultDirty?: boolean;
focusProps?: Record;
inputRef?: React.Ref;
+ label?: string;
+ hideLabel?: boolean;
+ badge?: React.ReactNode;
+ icon?: React.ReactNode;
+ required?: boolean;
+ description?: string;
+ helperText?: string;
+ errorMessage?: string;
+ successMessage?: string;
+ id?: string;
+ layout?: string;
+ layoutConfig?: Record;
"aria-label"?: string;
"aria-labelledby"?: string;
"aria-describedby"?: string;
@@ -74,6 +86,18 @@ export interface ManaTextAreaProps {
fullWidth?: boolean;
focusProps?: Record;
inputRef?: React.Ref;
+ label?: string;
+ hideLabel?: boolean;
+ badge?: React.ReactNode;
+ icon?: React.ReactNode;
+ required?: boolean;
+ description?: string;
+ helperText?: string;
+ errorMessage?: string;
+ successMessage?: string;
+ id?: string;
+ layout?: string;
+ layoutConfig?: Record;
"aria-label"?: string;
"aria-labelledby"?: string;
"aria-describedby"?: string;
@@ -92,6 +116,6 @@ export interface SearchBarProps {
onFocus?: () => void;
autoComplete?: string;
inputProps?: Record;
- className?: string;
+ ref?: React.Ref;
"aria-label"?: string;
}
diff --git a/src/equicordplugins/components.dev/types/menu.d.ts b/src/equicordplugins/components.dev/types/menu.d.ts
index 035e6ad76..8f0e62e1a 100644
--- a/src/equicordplugins/components.dev/types/menu.d.ts
+++ b/src/equicordplugins/components.dev/types/menu.d.ts
@@ -36,12 +36,19 @@ export interface MenuItemProps {
iconLeft?: ComponentType;
iconLeftSize?: MenuIconSize;
iconProps?: MenuItemIconProps;
+ leadingAccessory?: ReactNode;
+ trailingIndicator?: ReactNode;
hint?: ReactNode | ((props: MenuItemProps) => ReactNode);
+ shortcut?: ReactNode;
subtext?: ReactNode;
subtextLineClamp?: number;
hasSubmenu?: boolean;
+ loading?: boolean;
+ badge?: ReactNode;
disabled?: boolean;
action?: (e: MouseEvent) => void;
+ onClose?: () => void;
+ onFocus?: () => void;
dontCloseOnAction?: boolean;
dontCloseOnActionIfHoldingShiftKey?: boolean;
className?: string;
@@ -64,6 +71,9 @@ export interface MenuCheckboxItemProps {
action?: (e: MouseEvent) => void;
disabled?: boolean;
subtext?: ReactNode;
+ subtextLineClamp?: number;
+ leftIcon?: ComponentType;
+ leadingAccessory?: ReactNode;
className?: string;
focusedClassName?: string;
}
@@ -77,6 +87,9 @@ export interface MenuRadioItemProps {
action?: (e: MouseEvent) => void;
disabled?: boolean;
subtext?: ReactNode;
+ subtextLineClamp?: number;
+ leftIcon?: ComponentType;
+ leadingAccessory?: ReactNode;
}
export interface MenuSwitchItemProps {
@@ -86,6 +99,8 @@ export interface MenuSwitchItemProps {
checked: boolean;
action: (e: MouseEvent) => void;
disabled?: boolean;
+ subtext?: ReactNode;
+ subtextLineClamp?: number;
className?: string;
}
@@ -150,6 +165,7 @@ export interface MenuSliderControlProps {
minValue?: number;
maxValue?: number;
onChange: (value: number) => void;
+ onInteraction?: (type?: number) => void;
renderValue?: (value: number) => string;
"aria-label"?: string;
}
@@ -157,7 +173,9 @@ export interface MenuSliderControlProps {
export interface MenuSearchControlProps {
query: string;
onChange: (query: string) => void;
+ disabled?: boolean;
placeholder?: string;
+ onInteraction?: (type?: number) => void;
"aria-label"?: string;
}
diff --git a/src/equicordplugins/components.dev/types/modal.d.ts b/src/equicordplugins/components.dev/types/modal.d.ts
index 6568064c0..bcf51f6f3 100644
--- a/src/equicordplugins/components.dev/types/modal.d.ts
+++ b/src/equicordplugins/components.dev/types/modal.d.ts
@@ -21,11 +21,20 @@ export interface ModalNotice {
type: "info" | "warn" | "critical" | "positive";
}
+export type ModalAnimationVariant = "default" | "fade" | "slide-up";
+
+export type ModalMaxHeight = "default" | "full";
+
export interface ModalProps {
title: string;
subtitle?: string;
size?: NativeModalSize;
transitionState?: number;
+ animationVariant?: ModalAnimationVariant;
+ paddingSize?: "sm" | "lg";
+ fullScreenOnMobile?: boolean;
+ maxHeight?: ModalMaxHeight;
+ dismissable?: boolean;
children?: React.ReactNode;
actions?: ModalAction[];
actionBarInput?: React.ReactNode;
@@ -35,7 +44,11 @@ export interface ModalProps {
listProps?: Record;
notice?: ModalNotice;
onClose: () => void;
+ onScroll?: (e: React.UIEvent) => void;
+ scrollerRef?: React.Ref;
+ returnRef?: React.Ref;
role?: string;
+ "aria-label"?: string;
className?: string;
}
@@ -54,13 +67,25 @@ export interface ConfirmModalProps extends Omit void;
}
diff --git a/src/equicordplugins/components.dev/types/progress.d.ts b/src/equicordplugins/components.dev/types/progress.d.ts
index cf9eaa5c6..89cee00cc 100644
--- a/src/equicordplugins/components.dev/types/progress.d.ts
+++ b/src/equicordplugins/components.dev/types/progress.d.ts
@@ -12,14 +12,18 @@ export interface ProgressBarOverride {
gradientEnd?: string;
}
+export type ProgressBarWeight = "light" | "medium";
+
export interface ProgressBarProps {
progress: number;
minimum?: number;
maximum?: number;
+ weight?: ProgressBarWeight;
variant?: ProgressBarVariant;
override?: {
default?: ProgressBarOverride;
[key: string]: ProgressBarOverride | undefined;
};
+ glowing?: boolean;
labelledBy?: string;
}
diff --git a/src/equicordplugins/components.dev/types/radio.d.ts b/src/equicordplugins/components.dev/types/radio.d.ts
index 26f14c030..d4f4133c6 100644
--- a/src/equicordplugins/components.dev/types/radio.d.ts
+++ b/src/equicordplugins/components.dev/types/radio.d.ts
@@ -7,18 +7,35 @@
export interface RadioOption {
value: string | number;
name: string;
- desc?: string;
+ description?: string;
disabled?: boolean;
- leadingIcon?: React.ComponentType<{ className?: string; size?: string; color?: string; }>;
+ icon?: React.ComponentType<{ className?: string; size?: string; color?: string; }>;
+ color?: string;
+ radioItemIconClassName?: string;
+ radioBarClassName?: string;
}
+export type RadioPosition = "left" | "right";
+
export interface ManaBaseRadioGroupProps {
options: RadioOption[];
- value?: string | number;
+ value?: string | number | null;
onChange?: (value: string | number) => void;
disabled?: boolean;
+ size?: string;
+ orientation?: "vertical" | "horizontal";
+ radioPosition?: RadioPosition;
+ withTransparentBackground?: boolean;
label?: string;
+ description?: string;
+ required?: boolean;
+ errorMessage?: string;
"aria-labelledby"?: string;
+ className?: string;
+ itemInfoClassName?: string;
+ itemTitleClassName?: string;
+ radioItemClassName?: string;
+ collapsibleClassName?: string;
}
export interface StandaloneRadioIndicatorProps {
diff --git a/src/equicordplugins/components.dev/types/scroller.d.ts b/src/equicordplugins/components.dev/types/scroller.d.ts
index e9170b559..9ed39c1ef 100644
--- a/src/equicordplugins/components.dev/types/scroller.d.ts
+++ b/src/equicordplugins/components.dev/types/scroller.d.ts
@@ -4,21 +4,43 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-export interface ScrollerProps {
+export interface ScrollerProps extends Omit, "dir"> {
className?: string;
style?: React.CSSProperties;
children?: React.ReactNode;
orientation?: "vertical" | "horizontal";
+ paddingFix?: boolean;
fade?: boolean;
dir?: "ltr" | "rtl";
onScroll?: (e: React.UIEvent) => void;
}
-export interface ListScrollerProps extends ScrollerProps {
- rowHeight: number;
+export interface ListScrollerProps {
+ className?: string;
+ style?: React.CSSProperties;
+ dir?: "ltr" | "rtl";
+ fade?: boolean;
+ customTheme?: boolean;
+ onScroll?: (e: React.UIEvent) => void;
+ onResize?: ((entries: ResizeObserverEntry[]) => void) | null;
+ onContentResize?: ((entries: ResizeObserverEntry[]) => void) | null;
sections: number[];
sectionHeight: number;
- renderSection: (section: number) => React.ReactNode;
- renderRow: (row: { section: number; row: number }) => React.ReactNode;
- role?: string;
+ rowHeight: number;
+ footerHeight?: number;
+ sidebarHeight?: number;
+ listHeaderHeight?: number;
+ renderSection?: (section: { type: string; section: number; }) => React.ReactNode;
+ renderRow: (row: { type: string; section: number; row: number; }) => React.ReactNode;
+ renderFooter?: (footer: { type: string; section: number; }) => React.ReactNode;
+ renderSidebar?: (isListVisible: boolean, isSidebarVisible: boolean) => React.ReactNode;
+ renderListHeader?: () => React.ReactNode;
+ stickyListHeader?: boolean;
+ wrapSection?: (section: number, children: React.ReactNode[]) => React.ReactNode;
+ paddingTop?: number;
+ paddingBottom?: number;
+ chunkSize?: number;
+ innerId?: string;
+ innerRole?: string;
+ innerAriaLabel?: string;
}
diff --git a/src/equicordplugins/components.dev/types/slider.d.ts b/src/equicordplugins/components.dev/types/slider.d.ts
index 83abcec26..9d0271b50 100644
--- a/src/equicordplugins/components.dev/types/slider.d.ts
+++ b/src/equicordplugins/components.dev/types/slider.d.ts
@@ -23,6 +23,7 @@ export interface SliderProps {
renderMarker?: (value: number) => React.ReactNode;
getAriaValueText?: (value: number) => string;
keyboardStep?: number;
+ handleSize?: number;
disabled?: boolean;
mini?: boolean;
hideBubble?: boolean;
@@ -39,4 +40,11 @@ export interface SliderProps {
"aria-label"?: string;
"aria-labelledby"?: string;
"aria-describedby"?: string;
+ label?: string;
+ hideLabel?: boolean;
+ required?: boolean;
+ description?: string;
+ helperText?: string;
+ errorMessage?: string;
+ successMessage?: string;
}
diff --git a/src/equicordplugins/components.dev/types/timestamp.d.ts b/src/equicordplugins/components.dev/types/timestamp.d.ts
index 4725c184f..8a0de3ef8 100644
--- a/src/equicordplugins/components.dev/types/timestamp.d.ts
+++ b/src/equicordplugins/components.dev/types/timestamp.d.ts
@@ -20,6 +20,7 @@ export interface TimestampProps {
isInline?: boolean;
isVisibleOnlyOnHover?: boolean;
isEdited?: boolean;
+ application?: any;
id?: string;
className?: string;
children?: React.ReactNode;
diff --git a/src/equicordplugins/components.dev/types/toast.d.ts b/src/equicordplugins/components.dev/types/toast.d.ts
index 398047739..27527ca90 100644
--- a/src/equicordplugins/components.dev/types/toast.d.ts
+++ b/src/equicordplugins/components.dev/types/toast.d.ts
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-export type ToastTypeValue = "message" | "success" | "failure" | "custom" | "clip" | "link" | "forward" | "invite" | "bookmark" | "clock" | "ai";
+export type ToastTypeValue = "message" | "success" | "failure" | "custom" | "clip" | "link" | "forward" | "bookmark" | "clock";
export type ToastPositionValue = 0 | 1;
diff --git a/src/equicordplugins/components.dev/types/tooltip.d.ts b/src/equicordplugins/components.dev/types/tooltip.d.ts
index 1b755535a..27c1dfe9b 100644
--- a/src/equicordplugins/components.dev/types/tooltip.d.ts
+++ b/src/equicordplugins/components.dev/types/tooltip.d.ts
@@ -27,6 +27,7 @@ export interface ManaTooltipProps {
tooltipStyle?: React.CSSProperties;
tooltipContentClassName?: string;
tooltipPointerClassName?: string;
+ positionKeyStemOverride?: string;
onTooltipShow?: () => void;
onTooltipHide?: () => void;
onAnimationRest?: () => void;
@@ -50,6 +51,13 @@ export interface ManaRichTooltipProps {
anchorRef?: React.RefObject;
positionKey?: string;
ariaHidden?: boolean;
+ shouldShow?: boolean;
+ delay?: number;
+ onTooltipShow?: () => void;
+ onTooltipHide?: () => void;
+ forceOpen?: boolean;
+ overflowOnly?: boolean;
+ hideOnClick?: boolean;
children: React.ReactNode | ((props: Record) => React.ReactNode);
}
@@ -68,10 +76,14 @@ export interface ManaPopoverProps {
actions?: PopoverAction[];
textLink?: { text: string; onClick?: () => void; };
gradientColor?: string;
+ scrollBehavior?: string;
+ hasVideo?: boolean;
onRequestClose?: (reason: string) => void;
+ popoverRef?: React.Ref;
targetElementRef: React.RefObject;
shouldShow: boolean;
position?: TooltipPosition;
+ caretConfig?: { align?: "start" | "center" | "end"; };
alignmentStrategy?: "edge" | "trigger-center";
align?: "left" | "center" | "right";
}