@minimalstuff/ui 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ import { ReactElement } from 'react';
8
8
  import { ReactNode } from 'react';
9
9
  import { ReactPortal } from 'react';
10
10
  import { Ref } from 'react';
11
+ import { RefObject } from 'react';
11
12
  import { StoreApi } from 'zustand';
12
13
  import { UseBoundStore } from 'zustand';
13
14
 
@@ -134,7 +135,7 @@ export declare interface CharacterCountProps {
134
135
  className?: string;
135
136
  }
136
137
 
137
- export declare function Checkbox({ label, description, error, radius, unstyled, fullWidth, variant, className, wrapperClassName, checked, defaultChecked, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<CheckboxProps>): JSX.Element;
138
+ export declare function Checkbox({ label, indeterminate, description, error, radius, unstyled, fullWidth, variant, className, wrapperClassName, checked, defaultChecked, onChange, id, 'aria-describedby': callerDescribedBy, ref, ...props }: Readonly<CheckboxProps>): JSX.Element;
138
139
 
139
140
  export declare type CheckboxOption = ChoiceOption;
140
141
 
@@ -160,6 +161,8 @@ export declare interface CheckboxOptionsProps extends Omit<ComponentPropsWithRef
160
161
 
161
162
  export declare interface CheckboxProps extends Omit<ComponentPropsWithRef<'input'>, 'type' | 'className'> {
162
163
  label?: string | React.ReactNode;
164
+ /** Shows a dash instead of the checkmark and exposes the mixed state to assistive technology. */
165
+ indeterminate?: boolean;
163
166
  description?: string | React.ReactNode;
164
167
  error?: string;
165
168
  radius?: Radius;
@@ -298,6 +301,7 @@ export declare type IconButtonProps = ComponentPropsWithRef<'button'> & {
298
301
  'aria-label': string;
299
302
  size?: ControlSize;
300
303
  children?: ReactNode;
304
+ tooltip?: IconButtonTooltip;
301
305
  } & IconButtonStyle;
302
306
 
303
307
  declare type IconButtonStyle = {
@@ -309,10 +313,28 @@ declare type IconButtonStyle = {
309
313
  radius?: Radius;
310
314
  };
311
315
 
312
- export declare function Input({ label, error, showCharCount, minLength, maxLength, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<InputProps>): JSX.Element;
316
+ /**
317
+ * Wraps the button in a `Tooltip`. `true` shows the `aria-label` at the
318
+ * default position, a position string moves it, and an object also allows
319
+ * custom `content`. When the tooltip repeats the `aria-label` it does not
320
+ * describe the button, so screen readers do not announce the name twice.
321
+ */
322
+ export declare type IconButtonTooltip =
323
+ | boolean
324
+ | TooltipPosition
325
+ | IconButtonTooltipOptions;
326
+
327
+ declare interface IconButtonTooltipOptions {
328
+ position?: TooltipPosition;
329
+ /** Defaults to the button's `aria-label`. */
330
+ content?: ReactNode;
331
+ }
332
+
333
+ export declare function Input({ label, description, error, showCharCount, minLength, maxLength, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<InputProps>): JSX.Element;
313
334
 
314
335
  export declare interface InputProps extends ComponentPropsWithRef<'input'> {
315
336
  label?: string | ReactNode;
337
+ description?: string | ReactNode;
316
338
  error?: string;
317
339
  showCharCount?: boolean;
318
340
  minLength?: number;
@@ -481,9 +503,10 @@ export declare const Modal: Callable<ModalProps, void, {}>;
481
503
  * Declares `children` as the modal's pinned footer, wherever this is
482
504
  * rendered in the content tree — including inside a separate content
483
505
  * component, any number of levels below `Modal`'s own `children`. Renders
484
- * nothing itself; `Modal` places the actual footer in its own layout.
506
+ * nothing in place; the children are portaled into the modal's own footer
507
+ * slot, so they stay React children of this component.
485
508
  */
486
- export declare function ModalFooter({ children }: Readonly<ModalFooterProps>): null;
509
+ export declare function ModalFooter({ children }: Readonly<ModalFooterProps>): ReactPortal | null;
487
510
 
488
511
  export declare interface ModalFooterProps {
489
512
  children: ReactNode;
@@ -497,6 +520,10 @@ export declare interface ModalProps {
497
520
  className?: string;
498
521
  dismissible?: boolean;
499
522
  closeLabel?: string;
523
+ /** `alertdialog` for urgent messages that need a response (describes the dialog by its content); pair with `dismissible={false}` when it must not be dismissed. */
524
+ role?: ModalRole;
525
+ /** Wins over the first-tabbable rule for where focus lands on open; may point at an element in the content or in a `ModalFooter`. */
526
+ initialFocusRef?: RefObject<HTMLElement | null>;
500
527
  /** Names the dialog when there is no `title`; ignored when `title` is set since the title labels it. */
501
528
  'aria-label'?: string;
502
529
  }
@@ -505,6 +532,8 @@ export declare function ModalProvider(): JSX.Element;
505
532
 
506
533
  declare type ModalRenderProp = ReactNode | ((close: () => void) => ReactNode);
507
534
 
535
+ export declare type ModalRole = 'dialog' | 'alertdialog';
536
+
508
537
  export declare type ModalSize = 'sm' | 'md' | 'lg' | 'xl';
509
538
 
510
539
  /**
@@ -577,7 +606,7 @@ export declare interface RadioOptionsProps extends Omit<ComponentPropsWithRef<'f
577
606
 
578
607
  declare type Radius = 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
579
608
 
580
- export declare function Select({ options, label, error, placeholder, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<SelectProps>): JSX.Element;
609
+ export declare function Select({ options, label, description, error, placeholder, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<SelectProps>): JSX.Element;
581
610
 
582
611
  export declare interface SelectOption {
583
612
  value: string;
@@ -587,6 +616,7 @@ export declare interface SelectOption {
587
616
  export declare interface SelectProps extends Omit<ComponentPropsWithRef<'select'>, 'children'> {
588
617
  options: SelectOption[];
589
618
  label?: string | ReactNode;
619
+ description?: string | ReactNode;
590
620
  error?: string;
591
621
  placeholder?: string;
592
622
  radius?: Radius;
@@ -678,10 +708,11 @@ export declare interface TabsProps {
678
708
 
679
709
  export declare type TabsVariant = 'line' | 'segmented';
680
710
 
681
- export declare function Textarea({ label, error, showCharCount, minLength, maxLength, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<TextareaProps>): JSX.Element;
711
+ export declare function Textarea({ label, description, error, showCharCount, minLength, maxLength, radius, unstyled, className, wrapperClassName, value, defaultValue, onChange, id, 'aria-describedby': callerDescribedBy, ...props }: Readonly<TextareaProps>): JSX.Element;
682
712
 
683
713
  export declare interface TextareaProps extends ComponentPropsWithRef<'textarea'> {
684
714
  label?: string | ReactNode;
715
+ description?: string | ReactNode;
685
716
  error?: string;
686
717
  showCharCount?: boolean;
687
718
  minLength?: number;
@@ -699,9 +730,15 @@ declare interface ThemeStore {
699
730
  setTheme: (theme: Theme) => void;
700
731
  }
701
732
 
702
- export declare function ThemeToggle({ isTransitionEnabled, transitionDuration, transitionEasing, size, radius, variant, getAriaLabel, }: Readonly<ThemeToggleProps>): JSX.Element;
733
+ export declare function ThemeToggle({ isTransitionEnabled, transitionDuration, transitionEasing, size, radius, variant, getAriaLabel, tooltip, }: Readonly<ThemeToggleProps>): JSX.Element;
703
734
 
704
735
  export declare interface ThemeToggleProps {
736
+ /**
737
+ * Animate the theme change with the View Transition API.
738
+ * Defaults to automatic: enabled, except on WebKitGTK where
739
+ * `startViewTransition` crashes the web process (2.54).
740
+ * `prefers-reduced-motion` is always respected.
741
+ */
705
742
  isTransitionEnabled?: boolean;
706
743
  transitionDuration?: number;
707
744
  transitionEasing?: string;
@@ -709,15 +746,42 @@ export declare interface ThemeToggleProps {
709
746
  radius?: Radius;
710
747
  variant?: ButtonVariant;
711
748
  getAriaLabel?: (theme: Theme) => string;
749
+ tooltip?: IconButtonTooltip;
712
750
  }
713
751
 
752
+ /**
753
+ * A group of related controls with a single tab stop (WAI-ARIA toolbar).
754
+ * Tab enters the toolbar on the last focused item (the first enabled one
755
+ * initially); the arrow keys of the orientation (Left/Right horizontally,
756
+ * Up/Down vertically) move focus between items and wrap at the ends, Home and
757
+ * End jump to the first and last item, and disabled items are skipped. Arrow
758
+ * keys are left alone inside text fields. Requires `aria-label` or
759
+ * `aria-labelledby`.
760
+ */
761
+ export declare function Toolbar(toolbarProps: Readonly<ToolbarProps>): JSX.Element;
762
+
763
+ declare type ToolbarAccessibleName = {
764
+ 'aria-label': string;
765
+ 'aria-labelledby'?: undefined;
766
+ } | {
767
+ 'aria-labelledby': string;
768
+ 'aria-label'?: undefined;
769
+ };
770
+
771
+ declare type ToolbarOrientation = 'horizontal' | 'vertical';
772
+
773
+ export declare type ToolbarProps = Omit<ComponentPropsWithRef<'div'>, 'role' | 'aria-label' | 'aria-labelledby' | 'aria-orientation'> & {
774
+ orientation?: ToolbarOrientation;
775
+ unstyled?: boolean;
776
+ } & ToolbarAccessibleName;
777
+
714
778
  /**
715
779
  * The trigger (`children`) must be focusable, otherwise the tooltip is
716
780
  * unreachable by keyboard. Shows on hover and focus; Escape dismisses it.
717
781
  * `temporaryContent` is announced to screen readers through a polite status
718
782
  * region.
719
783
  */
720
- export declare function Tooltip({ content, children, position, showOnClick, temporaryContent, temporaryDuration, disabled, radius, onTemporaryShow, className, ref, }: Readonly<TooltipProps>): JSX.Element;
784
+ export declare function Tooltip({ content, children, position, showOnClick, temporaryContent, temporaryDuration, disabled, radius, onTemporaryShow, className, describeChild, portalContainer, ref, }: Readonly<TooltipProps>): JSX.Element;
721
785
 
722
786
  export declare type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';
723
787
 
@@ -732,10 +796,76 @@ export declare interface TooltipProps {
732
796
  radius?: Radius;
733
797
  onTemporaryShow?: () => void;
734
798
  className?: string;
799
+ /**
800
+ * Whether the trigger is described by the tooltip (`aria-describedby`).
801
+ * `true` always describes, `false` never does. By default the trigger is
802
+ * described unless the tooltip text repeats its accessible name, which
803
+ * screen readers would otherwise announce twice.
804
+ */
805
+ describeChild?: boolean;
806
+ /**
807
+ * Where the tooltip is rendered. Defaults to the trigger's closest
808
+ * landmark or dialog (so it stays inside a landmark and inside an open
809
+ * modal), falling back to `document.body`. Transformed ancestors (such as the modal
810
+ * panel) can clip it; pass `portalContainer` to escape.
811
+ */
812
+ portalContainer?: HTMLElement | null;
735
813
  /** Attaches to the wrapper `<span>` around `children`, alongside `Tooltip`'s own internal ref. */
736
814
  ref?: Ref<HTMLSpanElement>;
737
815
  }
738
816
 
817
+ export declare interface UILabels {
818
+ /** Accessible name of the modal close button. */
819
+ close: string;
820
+ /** Confirm button of `ConfirmModal`. */
821
+ confirm: string;
822
+ /** Cancel button of `ConfirmModal`. */
823
+ cancel: string;
824
+ /** Empty state of `Combobox` and `MultiCombobox`. */
825
+ noResults: string;
826
+ /** Accessible name of the button clearing a selection. */
827
+ clearSelection: string;
828
+ /** Placeholder and accessible name of the `MultiCombobox` search field. */
829
+ search: string;
830
+ /** Visible text of the `MultiCombobox` clear button. */
831
+ clear: string;
832
+ /** Screen-reader suffix of a required `CheckboxOptions` group. */
833
+ required: string;
834
+ /** Accessible name of `ThemeToggle` for the current theme. */
835
+ currentTheme: (theme: Theme) => string;
836
+ /** `MultiCombobox` badge summarising the values that do not fit. */
837
+ overflowCount: (hiddenCount: number) => string;
838
+ /** `MultiCombobox` summary of the number of selected values. */
839
+ selectedCount: (selectedCount: number) => string;
840
+ /** `MultiCombobox` hint shown when the selection limit is reached. */
841
+ maxSelectedHint: (maxSelectedValues: number) => string;
842
+ }
843
+
844
+ /**
845
+ * Provides default user-facing labels (close, confirm, no results...) to every
846
+ * component below it. Precedence: explicit prop > provider > English default.
847
+ *
848
+ * `Modal` and `ConfirmModal` render where `<ModalProvider />` is mounted, so
849
+ * mount `ModalProvider` inside `UIProvider` for them to receive the labels.
850
+ */
851
+ export declare function UIProvider({ labels, announceFieldErrors, children, }: Readonly<UIProviderProps>): JSX.Element;
852
+
853
+ export declare interface UIProviderProps {
854
+ /** Overrides the default labels. Nested providers merge over their parent. */
855
+ labels?: Partial<UILabels>;
856
+ /**
857
+ * Whether field errors are announced as they appear (`role="alert"`).
858
+ * Defaults to `true`; nested providers inherit the parent value unless set.
859
+ * Set it to `false` when the app announces errors itself (an error summary
860
+ * or focus on the first invalid field): it avoids several alerts firing at
861
+ * once on submit, and lets WebKitGTK re-read the error on focus, since it
862
+ * leaves `role="alert"` content out of the computed description. The error
863
+ * stays linked by `aria-describedby` either way.
864
+ */
865
+ announceFieldErrors?: boolean;
866
+ children: ReactNode;
867
+ }
868
+
739
869
  export declare function useDisableHotkeysWhileMounted(): void;
740
870
 
741
871
  export declare const useGlobalHotkeysStore: UseBoundStore<StoreApi<GlobalHotkeysStore>>;
@@ -748,3 +878,10 @@ export declare const useThemeStore: UseBoundStore<StoreApi<ThemeStore>>;
748
878
  export declare const withClientOnly: <TProps extends object>(Component: React.ComponentType<TProps>) => React.ComponentType<TProps>;
749
879
 
750
880
  export { }
881
+
882
+
883
+
884
+ declare module 'vitest' {
885
+ interface Assertion<T = unknown> extends AxeMatchers {}
886
+ interface AsymmetricMatchersContaining extends AxeMatchers {}
887
+ }