@mond-design-system/react 1.0.0-alpha.2 → 1.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { CSSProperties, HTMLAttributes, JSX, ReactElement, ReactNode, ButtonHTMLAttributes, ElementType, Ref, AnchorHTMLAttributes, MouseEventHandler, InputHTMLAttributes, TextareaHTMLAttributes, SelectHTMLAttributes, LiHTMLAttributes, RefObject, KeyboardEvent } from 'react';
2
+ import { CSSProperties, HTMLAttributes, JSX, ReactElement, ReactNode, ButtonHTMLAttributes, ElementType, Ref, AnchorHTMLAttributes, MouseEventHandler, InputHTMLAttributes, TextareaHTMLAttributes, SelectHTMLAttributes, RefObject, KeyboardEvent } from 'react';
3
3
 
4
4
  /**
5
5
  * Join class names, dropping anything falsy.
@@ -120,7 +120,7 @@ interface IconProps extends HTMLAttributes<HTMLSpanElement> {
120
120
  /** A glyph from the app-registered set, sized on the core scale. */
121
121
  declare function Icon({ name, size, label, className, ...rest }: IconProps): ReactElement;
122
122
 
123
- type ButtonVariant = "primary" | "secondary" | "ghost" | "danger";
123
+ type ButtonVariant = "primary" | "secondary" | "ghost" | "danger" | "highlight";
124
124
  type ButtonSize = "sm" | "md" | "lg";
125
125
  interface ButtonBaseProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "type"> {
126
126
  variant?: ButtonVariant;
@@ -158,10 +158,15 @@ type ButtonProps = ButtonBaseProps & IconOnlyEnforcement;
158
158
  */
159
159
  declare function Button({ variant, size, iconLeft, iconRight, loading, disabled, fullWidth, iconOnly, type, href, as, className, children, ...rest }: ButtonProps): ReactElement;
160
160
 
161
- type LinkVariant = "inline" | "standalone";
161
+ type LinkVariant = "inline" | "standalone" | "plain";
162
+ type LinkSize = "xs" | "sm" | "base" | "lg" | "xl";
162
163
  interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
163
- /** inline = underlined, lives in running text. standalone = nav/action link. */
164
+ /** inline = underlined, lives in running text. standalone = nav/action link.
165
+ plain = inherits the surrounding color and weight, underlines on hover —
166
+ for links whose context already marks them (a card title, a list row). */
164
167
  variant?: LinkVariant;
168
+ /** Font size on the core text scale. Default inherits from context. */
169
+ size?: LinkSize;
165
170
  /** Opens in a new tab with rel protection. */
166
171
  external?: boolean;
167
172
  /** Element override, e.g. a router's Link. */
@@ -178,25 +183,33 @@ interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
178
183
  * <Link as={NextLink} href="/about">About</Link>
179
184
  * ```
180
185
  */
181
- declare function Link({ variant, external, as: Element, className, ...rest }: LinkProps): ReactElement;
186
+ declare function Link({ variant, size, external, as: Element, className, ...rest }: LinkProps): ReactElement;
182
187
 
183
- type AvatarSize = "sm" | "md" | "lg";
188
+ type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl";
189
+ /** One of the five brand identity tints (`--mds-avatar-tone-1..5`). */
190
+ type AvatarTone = 1 | 2 | 3 | 4 | 5;
184
191
  interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {
185
192
  /** Person's display name — accessible name and initials source. */
186
193
  name: string;
187
194
  /** Image URL; initials render when absent or empty. */
188
195
  src?: string;
189
196
  size?: AvatarSize;
197
+ /** Identity tint behind the initials. Pick per person (e.g. hash the name)
198
+ so the same person keeps the same color. */
199
+ tone?: AvatarTone;
200
+ /** Hide from assistive tech — for avatars that repeat a name already in
201
+ the row's text. The name prop still drives the initials. */
202
+ decorative?: boolean;
190
203
  }
191
204
  /**
192
205
  * Person marker. Image when available, initials otherwise — never an empty circle.
193
206
  *
194
207
  * ```tsx
195
208
  * <Avatar name="Ada Lovelace" src="/ada.jpg" />
196
- * <Avatar name="Grace Hopper" size="lg" />
209
+ * <Avatar name="Grace Hopper" size="lg" tone={2} />
197
210
  * ```
198
211
  */
199
- declare function Avatar({ name, src, size, className, ...rest }: AvatarProps): ReactElement;
212
+ declare function Avatar({ name, src, size, tone, decorative, className, ...rest }: AvatarProps): ReactElement;
200
213
 
201
214
  interface AvatarGroupProps extends HTMLAttributes<HTMLDivElement> {
202
215
  /** Avatar children. */
@@ -220,7 +233,7 @@ interface AvatarGroupProps extends HTMLAttributes<HTMLDivElement> {
220
233
  */
221
234
  declare function AvatarGroup({ children, max, size, className, ...rest }: AvatarGroupProps): ReactElement;
222
235
 
223
- type BadgeTone = "neutral" | "accent" | "danger" | "warning" | "success";
236
+ type BadgeTone = "neutral" | "accent" | "danger" | "warning" | "success" | "highlight";
224
237
  interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
225
238
  tone?: BadgeTone;
226
239
  }
@@ -234,7 +247,7 @@ interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
234
247
  */
235
248
  declare function Badge({ tone, className, ...rest }: BadgeProps): ReactElement;
236
249
 
237
- type ChipVariant = "soft" | "outline";
250
+ type ChipVariant = "soft" | "outline" | "highlight";
238
251
  interface ChipProps extends HTMLAttributes<HTMLElement> {
239
252
  children: ReactNode;
240
253
  /** Unselected appearance. Default "soft". */
@@ -518,6 +531,14 @@ declare function Field({ label, children, hint, error, required, className }: Fi
518
531
  type InputSize = "sm" | "md" | "lg";
519
532
  interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
520
533
  size?: InputSize;
534
+ /** Marks the value as failing validation — sets aria-invalid and the danger
535
+ border. Inside a Field the field's error state does this already. */
536
+ invalid?: boolean;
537
+ /** Decorative icon inside the leading edge. Icons carry no name here —
538
+ the input's label does the talking. */
539
+ iconLeft?: ReactNode;
540
+ /** Decorative icon inside the trailing edge. */
541
+ iconRight?: ReactNode;
521
542
  ref?: Ref<HTMLInputElement>;
522
543
  }
523
544
  /**
@@ -528,10 +549,10 @@ interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size">
528
549
  * <Input value={name} onChange={(e) => setName(e.target.value)} />
529
550
  * </Field>
530
551
  *
531
- * <Input aria-label="Amount" type="number" size="sm" />
552
+ * <Input aria-label="Search" iconLeft={<Icon name="search" size="sm" />} />
532
553
  * ```
533
554
  */
534
- declare function Input({ size, className, ...rest }: InputProps): ReactElement;
555
+ declare function Input({ size, invalid, iconLeft, iconRight, className, ...rest }: InputProps): ReactElement;
535
556
 
536
557
  type PasswordInputProps = Omit<InputProps, "type">;
537
558
  /**
@@ -584,8 +605,9 @@ interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, "siz
584
605
  declare function Select({ size, className, children, ...rest }: SelectProps): ReactElement;
585
606
 
586
607
  interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> {
587
- /** Inline label — part of the click target. */
588
- label: string;
608
+ /** Inline label — part of the click target. Rich content welcome (an
609
+ inline link, a Text run); the label element names the box either way. */
610
+ label: ReactNode;
589
611
  ref?: Ref<HTMLInputElement>;
590
612
  }
591
613
  /**
@@ -621,11 +643,19 @@ interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"
621
643
  */
622
644
  declare function Radio({ label, className, ...rest }: RadioProps): ReactElement;
623
645
 
624
- interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> {
625
- /** Inline label — part of the click target. */
626
- label: string;
646
+ interface SwitchBaseProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> {
647
+ /** Busy blocks toggling for the same reason disabled does — a second tap
648
+ would queue a write against a value the first one is still deciding. */
649
+ loading?: boolean;
627
650
  ref?: Ref<HTMLInputElement>;
628
651
  }
652
+ type SwitchLabelEnforcement = {
653
+ label: string;
654
+ } | {
655
+ label?: undefined;
656
+ "aria-label": string;
657
+ };
658
+ type SwitchProps = SwitchBaseProps & SwitchLabelEnforcement;
629
659
  /**
630
660
  * On/off toggle. Checkbox under the hood with role="switch" — native
631
661
  * semantics and forms integration, switch announcement.
@@ -636,9 +666,10 @@ interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"
636
666
  * checked={enabled}
637
667
  * onChange={(e) => setEnabled(e.target.checked)}
638
668
  * />
669
+ * <Switch aria-label="Email on new posts" checked={on} loading={saving} onChange={toggle} />
639
670
  * ```
640
671
  */
641
- declare function Switch({ label, className, ...rest }: SwitchProps): ReactElement;
672
+ declare function Switch({ label, loading, disabled, className, ...rest }: SwitchProps): ReactElement;
642
673
 
643
674
  interface SegmentOption<T extends string = string> {
644
675
  value: T;
@@ -650,6 +681,8 @@ interface SegmentedControlProps<T extends string = string> {
650
681
  options: readonly SegmentOption<T>[];
651
682
  value: T;
652
683
  onChange: (value: T) => void;
684
+ /** Disables the whole control — e.g. a choice locked while editing. */
685
+ disabled?: boolean;
653
686
  className?: string;
654
687
  }
655
688
  /**
@@ -668,7 +701,7 @@ interface SegmentedControlProps<T extends string = string> {
668
701
  * />
669
702
  * ```
670
703
  */
671
- declare function SegmentedControl<T extends string = string>({ label, options, value, onChange, className, }: SegmentedControlProps<T>): ReactElement;
704
+ declare function SegmentedControl<T extends string = string>({ label, options, value, onChange, disabled, className, }: SegmentedControlProps<T>): ReactElement;
672
705
 
673
706
  interface SearchFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size" | "value" | "onChange"> {
674
707
  /** Accessible name. */
@@ -706,9 +739,10 @@ interface ListGroupProps extends HTMLAttributes<HTMLUListElement> {
706
739
  * ```
707
740
  */
708
741
  declare function ListGroup({ className, ...rest }: ListGroupProps): ReactElement;
709
- interface ListItemProps extends Omit<LiHTMLAttributes<HTMLLIElement>, "title" | "onClick"> {
710
- title: string;
711
- description?: string;
742
+ type ListItemSurface = "card" | "sunken" | "accent" | "plain";
743
+ interface ListItemProps extends Omit<HTMLAttributes<HTMLElement>, "title" | "onClick"> {
744
+ title: ReactNode;
745
+ description?: ReactNode;
712
746
  /** Slot before the text — Avatar, Icon, … */
713
747
  leading?: ReactNode;
714
748
  /** Slot after the text — Badge, chevron, … */
@@ -717,9 +751,19 @@ interface ListItemProps extends Omit<LiHTMLAttributes<HTMLLIElement>, "title" |
717
751
  onClick?: () => void;
718
752
  /** Makes the whole row a link. Wins over onClick. */
719
753
  href?: string;
754
+ /** What the row paints behind itself. Inside a ListGroup the group is the
755
+ card, so grouped rows default to painting nothing; standalone rows
756
+ default to their own card. `accent` is the tinted, accent-edged prompt
757
+ row. The row paints it itself because a background drawn by a wrapper
758
+ brings its own corner radius, which peeks past the row's in all four
759
+ corners. */
760
+ surface?: ListItemSurface;
720
761
  }
721
- /** One row. Static by default; interactive as one whole-row button/link. */
722
- declare function ListItem({ title, description, leading, trailing, onClick, href, className, ...rest }: ListItemProps): ReactElement;
762
+ /**
763
+ * One row. Static by default; interactive as one whole-row button/link.
764
+ * An `<li>` inside a ListGroup, a standalone `<div>` row anywhere else.
765
+ */
766
+ declare function ListItem({ title, description, leading, trailing, onClick, href, surface, className, ...rest }: ListItemProps): ReactElement;
723
767
 
724
768
  interface EmptyStateProps {
725
769
  title: string;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { CSSProperties, HTMLAttributes, JSX, ReactElement, ReactNode, ButtonHTMLAttributes, ElementType, Ref, AnchorHTMLAttributes, MouseEventHandler, InputHTMLAttributes, TextareaHTMLAttributes, SelectHTMLAttributes, LiHTMLAttributes, RefObject, KeyboardEvent } from 'react';
2
+ import { CSSProperties, HTMLAttributes, JSX, ReactElement, ReactNode, ButtonHTMLAttributes, ElementType, Ref, AnchorHTMLAttributes, MouseEventHandler, InputHTMLAttributes, TextareaHTMLAttributes, SelectHTMLAttributes, RefObject, KeyboardEvent } from 'react';
3
3
 
4
4
  /**
5
5
  * Join class names, dropping anything falsy.
@@ -120,7 +120,7 @@ interface IconProps extends HTMLAttributes<HTMLSpanElement> {
120
120
  /** A glyph from the app-registered set, sized on the core scale. */
121
121
  declare function Icon({ name, size, label, className, ...rest }: IconProps): ReactElement;
122
122
 
123
- type ButtonVariant = "primary" | "secondary" | "ghost" | "danger";
123
+ type ButtonVariant = "primary" | "secondary" | "ghost" | "danger" | "highlight";
124
124
  type ButtonSize = "sm" | "md" | "lg";
125
125
  interface ButtonBaseProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "type"> {
126
126
  variant?: ButtonVariant;
@@ -158,10 +158,15 @@ type ButtonProps = ButtonBaseProps & IconOnlyEnforcement;
158
158
  */
159
159
  declare function Button({ variant, size, iconLeft, iconRight, loading, disabled, fullWidth, iconOnly, type, href, as, className, children, ...rest }: ButtonProps): ReactElement;
160
160
 
161
- type LinkVariant = "inline" | "standalone";
161
+ type LinkVariant = "inline" | "standalone" | "plain";
162
+ type LinkSize = "xs" | "sm" | "base" | "lg" | "xl";
162
163
  interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
163
- /** inline = underlined, lives in running text. standalone = nav/action link. */
164
+ /** inline = underlined, lives in running text. standalone = nav/action link.
165
+ plain = inherits the surrounding color and weight, underlines on hover —
166
+ for links whose context already marks them (a card title, a list row). */
164
167
  variant?: LinkVariant;
168
+ /** Font size on the core text scale. Default inherits from context. */
169
+ size?: LinkSize;
165
170
  /** Opens in a new tab with rel protection. */
166
171
  external?: boolean;
167
172
  /** Element override, e.g. a router's Link. */
@@ -178,25 +183,33 @@ interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
178
183
  * <Link as={NextLink} href="/about">About</Link>
179
184
  * ```
180
185
  */
181
- declare function Link({ variant, external, as: Element, className, ...rest }: LinkProps): ReactElement;
186
+ declare function Link({ variant, size, external, as: Element, className, ...rest }: LinkProps): ReactElement;
182
187
 
183
- type AvatarSize = "sm" | "md" | "lg";
188
+ type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl";
189
+ /** One of the five brand identity tints (`--mds-avatar-tone-1..5`). */
190
+ type AvatarTone = 1 | 2 | 3 | 4 | 5;
184
191
  interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {
185
192
  /** Person's display name — accessible name and initials source. */
186
193
  name: string;
187
194
  /** Image URL; initials render when absent or empty. */
188
195
  src?: string;
189
196
  size?: AvatarSize;
197
+ /** Identity tint behind the initials. Pick per person (e.g. hash the name)
198
+ so the same person keeps the same color. */
199
+ tone?: AvatarTone;
200
+ /** Hide from assistive tech — for avatars that repeat a name already in
201
+ the row's text. The name prop still drives the initials. */
202
+ decorative?: boolean;
190
203
  }
191
204
  /**
192
205
  * Person marker. Image when available, initials otherwise — never an empty circle.
193
206
  *
194
207
  * ```tsx
195
208
  * <Avatar name="Ada Lovelace" src="/ada.jpg" />
196
- * <Avatar name="Grace Hopper" size="lg" />
209
+ * <Avatar name="Grace Hopper" size="lg" tone={2} />
197
210
  * ```
198
211
  */
199
- declare function Avatar({ name, src, size, className, ...rest }: AvatarProps): ReactElement;
212
+ declare function Avatar({ name, src, size, tone, decorative, className, ...rest }: AvatarProps): ReactElement;
200
213
 
201
214
  interface AvatarGroupProps extends HTMLAttributes<HTMLDivElement> {
202
215
  /** Avatar children. */
@@ -220,7 +233,7 @@ interface AvatarGroupProps extends HTMLAttributes<HTMLDivElement> {
220
233
  */
221
234
  declare function AvatarGroup({ children, max, size, className, ...rest }: AvatarGroupProps): ReactElement;
222
235
 
223
- type BadgeTone = "neutral" | "accent" | "danger" | "warning" | "success";
236
+ type BadgeTone = "neutral" | "accent" | "danger" | "warning" | "success" | "highlight";
224
237
  interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
225
238
  tone?: BadgeTone;
226
239
  }
@@ -234,7 +247,7 @@ interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
234
247
  */
235
248
  declare function Badge({ tone, className, ...rest }: BadgeProps): ReactElement;
236
249
 
237
- type ChipVariant = "soft" | "outline";
250
+ type ChipVariant = "soft" | "outline" | "highlight";
238
251
  interface ChipProps extends HTMLAttributes<HTMLElement> {
239
252
  children: ReactNode;
240
253
  /** Unselected appearance. Default "soft". */
@@ -518,6 +531,14 @@ declare function Field({ label, children, hint, error, required, className }: Fi
518
531
  type InputSize = "sm" | "md" | "lg";
519
532
  interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
520
533
  size?: InputSize;
534
+ /** Marks the value as failing validation — sets aria-invalid and the danger
535
+ border. Inside a Field the field's error state does this already. */
536
+ invalid?: boolean;
537
+ /** Decorative icon inside the leading edge. Icons carry no name here —
538
+ the input's label does the talking. */
539
+ iconLeft?: ReactNode;
540
+ /** Decorative icon inside the trailing edge. */
541
+ iconRight?: ReactNode;
521
542
  ref?: Ref<HTMLInputElement>;
522
543
  }
523
544
  /**
@@ -528,10 +549,10 @@ interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size">
528
549
  * <Input value={name} onChange={(e) => setName(e.target.value)} />
529
550
  * </Field>
530
551
  *
531
- * <Input aria-label="Amount" type="number" size="sm" />
552
+ * <Input aria-label="Search" iconLeft={<Icon name="search" size="sm" />} />
532
553
  * ```
533
554
  */
534
- declare function Input({ size, className, ...rest }: InputProps): ReactElement;
555
+ declare function Input({ size, invalid, iconLeft, iconRight, className, ...rest }: InputProps): ReactElement;
535
556
 
536
557
  type PasswordInputProps = Omit<InputProps, "type">;
537
558
  /**
@@ -584,8 +605,9 @@ interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, "siz
584
605
  declare function Select({ size, className, children, ...rest }: SelectProps): ReactElement;
585
606
 
586
607
  interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> {
587
- /** Inline label — part of the click target. */
588
- label: string;
608
+ /** Inline label — part of the click target. Rich content welcome (an
609
+ inline link, a Text run); the label element names the box either way. */
610
+ label: ReactNode;
589
611
  ref?: Ref<HTMLInputElement>;
590
612
  }
591
613
  /**
@@ -621,11 +643,19 @@ interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"
621
643
  */
622
644
  declare function Radio({ label, className, ...rest }: RadioProps): ReactElement;
623
645
 
624
- interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> {
625
- /** Inline label — part of the click target. */
626
- label: string;
646
+ interface SwitchBaseProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> {
647
+ /** Busy blocks toggling for the same reason disabled does — a second tap
648
+ would queue a write against a value the first one is still deciding. */
649
+ loading?: boolean;
627
650
  ref?: Ref<HTMLInputElement>;
628
651
  }
652
+ type SwitchLabelEnforcement = {
653
+ label: string;
654
+ } | {
655
+ label?: undefined;
656
+ "aria-label": string;
657
+ };
658
+ type SwitchProps = SwitchBaseProps & SwitchLabelEnforcement;
629
659
  /**
630
660
  * On/off toggle. Checkbox under the hood with role="switch" — native
631
661
  * semantics and forms integration, switch announcement.
@@ -636,9 +666,10 @@ interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"
636
666
  * checked={enabled}
637
667
  * onChange={(e) => setEnabled(e.target.checked)}
638
668
  * />
669
+ * <Switch aria-label="Email on new posts" checked={on} loading={saving} onChange={toggle} />
639
670
  * ```
640
671
  */
641
- declare function Switch({ label, className, ...rest }: SwitchProps): ReactElement;
672
+ declare function Switch({ label, loading, disabled, className, ...rest }: SwitchProps): ReactElement;
642
673
 
643
674
  interface SegmentOption<T extends string = string> {
644
675
  value: T;
@@ -650,6 +681,8 @@ interface SegmentedControlProps<T extends string = string> {
650
681
  options: readonly SegmentOption<T>[];
651
682
  value: T;
652
683
  onChange: (value: T) => void;
684
+ /** Disables the whole control — e.g. a choice locked while editing. */
685
+ disabled?: boolean;
653
686
  className?: string;
654
687
  }
655
688
  /**
@@ -668,7 +701,7 @@ interface SegmentedControlProps<T extends string = string> {
668
701
  * />
669
702
  * ```
670
703
  */
671
- declare function SegmentedControl<T extends string = string>({ label, options, value, onChange, className, }: SegmentedControlProps<T>): ReactElement;
704
+ declare function SegmentedControl<T extends string = string>({ label, options, value, onChange, disabled, className, }: SegmentedControlProps<T>): ReactElement;
672
705
 
673
706
  interface SearchFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size" | "value" | "onChange"> {
674
707
  /** Accessible name. */
@@ -706,9 +739,10 @@ interface ListGroupProps extends HTMLAttributes<HTMLUListElement> {
706
739
  * ```
707
740
  */
708
741
  declare function ListGroup({ className, ...rest }: ListGroupProps): ReactElement;
709
- interface ListItemProps extends Omit<LiHTMLAttributes<HTMLLIElement>, "title" | "onClick"> {
710
- title: string;
711
- description?: string;
742
+ type ListItemSurface = "card" | "sunken" | "accent" | "plain";
743
+ interface ListItemProps extends Omit<HTMLAttributes<HTMLElement>, "title" | "onClick"> {
744
+ title: ReactNode;
745
+ description?: ReactNode;
712
746
  /** Slot before the text — Avatar, Icon, … */
713
747
  leading?: ReactNode;
714
748
  /** Slot after the text — Badge, chevron, … */
@@ -717,9 +751,19 @@ interface ListItemProps extends Omit<LiHTMLAttributes<HTMLLIElement>, "title" |
717
751
  onClick?: () => void;
718
752
  /** Makes the whole row a link. Wins over onClick. */
719
753
  href?: string;
754
+ /** What the row paints behind itself. Inside a ListGroup the group is the
755
+ card, so grouped rows default to painting nothing; standalone rows
756
+ default to their own card. `accent` is the tinted, accent-edged prompt
757
+ row. The row paints it itself because a background drawn by a wrapper
758
+ brings its own corner radius, which peeks past the row's in all four
759
+ corners. */
760
+ surface?: ListItemSurface;
720
761
  }
721
- /** One row. Static by default; interactive as one whole-row button/link. */
722
- declare function ListItem({ title, description, leading, trailing, onClick, href, className, ...rest }: ListItemProps): ReactElement;
762
+ /**
763
+ * One row. Static by default; interactive as one whole-row button/link.
764
+ * An `<li>` inside a ListGroup, a standalone `<div>` row anywhere else.
765
+ */
766
+ declare function ListItem({ title, description, leading, trailing, onClick, href, surface, className, ...rest }: ListItemProps): ReactElement;
723
767
 
724
768
  interface EmptyStateProps {
725
769
  title: string;