@xingxingmofashu/ui 0.1.8 → 0.1.10

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.
Files changed (52) hide show
  1. package/README.md +8 -7
  2. package/dist/components/button.d.ts +1 -1
  3. package/dist/components/button.mjs +7 -2
  4. package/dist/components/card.d.ts +1 -1
  5. package/dist/components/checkbox-group.d.ts +41 -0
  6. package/dist/components/checkbox-group.mjs +223 -0
  7. package/dist/components/checkbox.d.ts +1 -1
  8. package/dist/components/checkbox.mjs +4 -0
  9. package/dist/components/field.d.ts +23 -0
  10. package/dist/components/field.mjs +62 -0
  11. package/dist/components/fieldset.d.ts +18 -0
  12. package/dist/components/fieldset.mjs +45 -0
  13. package/dist/components/form.d.ts +14 -0
  14. package/dist/components/form.mjs +21 -0
  15. package/dist/components/input.d.ts +1 -5
  16. package/dist/components/input.mjs +5 -35
  17. package/dist/components/menu.d.ts +8 -23
  18. package/dist/components/menu.mjs +11 -2
  19. package/dist/components/popover.d.ts +1 -12
  20. package/dist/components/radio-group.d.ts +1 -1
  21. package/dist/components/radio-group.mjs +7 -1
  22. package/dist/components/select.d.ts +1 -14
  23. package/dist/components/select.mjs +5 -3
  24. package/dist/components/slider.d.ts +2 -6
  25. package/dist/components/slider.mjs +4 -0
  26. package/dist/components/switch.mjs +3 -1
  27. package/dist/components/tabs.d.ts +1 -5
  28. package/dist/components/toggle-group.d.ts +1 -1
  29. package/dist/components/toggle-group.mjs +4 -0
  30. package/dist/components/toggle.d.ts +1 -1
  31. package/dist/components/toggle.mjs +4 -0
  32. package/dist/components/tooltip.d.ts +3 -18
  33. package/dist/components/tooltip.mjs +2 -2
  34. package/dist/index.d.ts +5 -1
  35. package/dist/index.mjs +6 -0
  36. package/dist/internal/fieldset.d.ts +8 -0
  37. package/dist/internal/fieldset.mjs +13 -0
  38. package/dist/theme/alert-dialog.mjs +2 -2
  39. package/dist/theme/card.mjs +1 -1
  40. package/dist/theme/checkbox-group.d.ts +41 -0
  41. package/dist/theme/checkbox-group.mjs +111 -0
  42. package/dist/theme/dialog.mjs +2 -2
  43. package/dist/theme/field.d.ts +25 -0
  44. package/dist/theme/field.mjs +66 -0
  45. package/dist/theme/fieldset.d.ts +5 -0
  46. package/dist/theme/fieldset.mjs +14 -0
  47. package/dist/theme/form.d.ts +4 -0
  48. package/dist/theme/form.mjs +6 -0
  49. package/dist/theme/input.d.ts +0 -2
  50. package/dist/theme/input.mjs +10 -10
  51. package/dist/theme/tabs.mjs +1 -1
  52. package/package.json +6 -3
@@ -2,45 +2,26 @@
2
2
  import { Input as UIInput } from "@base-ui/react/input";
3
3
  import { cn } from "cn";
4
4
  import * as React from "react";
5
- import { mergeIds } from "../internal/aria.mjs";
5
+ import { useFieldsetDisabled } from "../internal/fieldset.mjs";
6
6
  import theme from "../theme/input.mjs";
7
7
  function Input({
8
8
  className,
9
9
  ui,
10
- label,
11
- description,
12
10
  leadingIcon,
13
11
  trailingIcon,
14
12
  size,
15
- id,
16
13
  disabled,
17
- "aria-describedby": ariaDescribedBy,
18
14
  ...props
19
15
  }) {
20
16
  const styles = theme({ size });
21
- const generatedId = React.useId();
22
- const descriptionId = React.useId();
23
- const inputId = id ?? generatedId;
24
- const describedBy = mergeIds(
25
- ariaDescribedBy,
26
- description ? descriptionId : void 0
27
- );
17
+ const fieldsetDisabled = useFieldsetDisabled(disabled);
28
18
  return /* @__PURE__ */ React.createElement(
29
19
  "div",
30
20
  {
31
21
  "data-slot": "root",
32
- "data-disabled": disabled || void 0,
22
+ "data-disabled": fieldsetDisabled || void 0,
33
23
  className: cn(styles.root(), ui?.root, className)
34
24
  },
35
- label ? /* @__PURE__ */ React.createElement(
36
- "label",
37
- {
38
- htmlFor: inputId,
39
- "data-slot": "label",
40
- className: cn(styles.label(), ui?.label)
41
- },
42
- label
43
- ) : null,
44
25
  /* @__PURE__ */ React.createElement(
45
26
  "span",
46
27
  {
@@ -76,9 +57,7 @@ function Input({
76
57
  UIInput,
77
58
  {
78
59
  ...props,
79
- id: inputId,
80
- disabled,
81
- "aria-describedby": describedBy,
60
+ disabled: fieldsetDisabled,
82
61
  "data-slot": "input",
83
62
  className: cn(styles.input(), ui?.input)
84
63
  }
@@ -92,16 +71,7 @@ function Input({
92
71
  },
93
72
  trailingIcon
94
73
  ) : null
95
- ),
96
- description ? /* @__PURE__ */ React.createElement(
97
- "span",
98
- {
99
- id: descriptionId,
100
- "data-slot": "description",
101
- className: cn(styles.description(), ui?.description)
102
- },
103
- description
104
- ) : null
74
+ )
105
75
  );
106
76
  }
107
77
  export { Input };
@@ -3,10 +3,6 @@ import * as React from "react";
3
3
  import { type ComponentConfig } from "../internal/tv";
4
4
  import theme from "../theme/menu";
5
5
  type Menu = ComponentConfig<typeof theme>;
6
- type PositionerProps = UIMenu.Positioner.Props;
7
- type MenuItemUi = Partial<Pick<Menu["slots"], "item" | "itemIcon" | "itemLabel" | "shortcut">>;
8
- type MenuGroupUi = Partial<Pick<Menu["slots"], "group" | "groupLabel" | "item" | "itemIcon" | "itemLabel" | "shortcut">>;
9
- type MenuSeparatorUi = Partial<Pick<Menu["slots"], "separator">>;
10
6
  /** One action item in the menu. */
11
7
  type MenuItemProps<Value extends string = string> = Omit<UIMenu.Item.Props, "children" | "className" | "style" | "label" | "onClick"> & {
12
8
  type?: "item";
@@ -25,10 +21,10 @@ type MenuItemProps<Value extends string = string> = Omit<UIMenu.Item.Props, "chi
25
21
  /** Tailwind classes merged into the item. */
26
22
  className?: string;
27
23
  /** Tailwind classes for this item's internal slots. */
28
- ui?: MenuItemUi;
24
+ ui?: Partial<Pick<Menu["slots"], "item" | "itemIcon" | "itemLabel" | "shortcut">>;
29
25
  };
30
26
  /** A labelled group of menu items. */
31
- type MenuGroupProps<Value extends string = string> = {
27
+ type MenuGroupProps<Value extends string = string> = Omit<UIMenu.Group.Props, "children" | "className" | "style"> & {
32
28
  type: "group";
33
29
  /** Group heading. */
34
30
  label: React.ReactNode;
@@ -37,32 +33,21 @@ type MenuGroupProps<Value extends string = string> = {
37
33
  /** Tailwind classes merged into the group. */
38
34
  className?: string;
39
35
  /** Tailwind classes for the group slots. */
40
- ui?: MenuGroupUi;
36
+ ui?: Partial<Pick<Menu["slots"], "group" | "groupLabel" | "item" | "itemIcon" | "itemLabel" | "shortcut">>;
41
37
  };
42
38
  /** A separator between menu items. */
43
- type MenuSeparatorProps = {
39
+ type MenuSeparatorProps = Omit<UIMenu.Separator.Props, "children" | "className" | "orientation" | "style"> & {
44
40
  type: "separator";
45
41
  /** Tailwind classes merged into the separator. */
46
42
  className?: string;
47
43
  /** Tailwind classes for the separator slot. */
48
- ui?: MenuSeparatorUi;
44
+ ui?: Partial<Pick<Menu["slots"], "separator">>;
49
45
  };
50
- type MenuEntry<Value extends string = string> = MenuItemProps<Value> | MenuGroupProps<Value> | MenuSeparatorProps;
51
- type MenuProps<Value extends string = string> = Omit<UIMenu.Root.Props, "children" | "className" | "style"> & {
46
+ type MenuProps<Value extends string = string> = Omit<UIMenu.Root.Props, "children" | "className" | "style"> & Pick<UIMenu.Positioner.Props, "side" | "align" | "sideOffset" | "alignOffset" | "collisionPadding"> & {
52
47
  /** Element that opens the menu. It must forward props and refs. */
53
48
  trigger: React.ReactElement;
54
49
  /** Items, groups, and separators rendered by the menu. */
55
- items: readonly MenuEntry<Value>[];
56
- /** Side of the trigger the menu is placed on. */
57
- side?: PositionerProps["side"];
58
- /** Alignment of the menu relative to the trigger. */
59
- align?: PositionerProps["align"];
60
- /** Distance between the trigger and the menu in pixels. */
61
- sideOffset?: PositionerProps["sideOffset"];
62
- /** Offset along the alignment axis in pixels. */
63
- alignOffset?: PositionerProps["alignOffset"];
64
- /** Padding between the menu and the edge of the collision boundary. */
65
- collisionPadding?: PositionerProps["collisionPadding"];
50
+ items: readonly (MenuItemProps<Value> | MenuGroupProps<Value> | MenuSeparatorProps)[];
66
51
  /** Tailwind classes merged into the popup. */
67
52
  className?: string;
68
53
  /** Tailwind classes for internal slots, keyed by `data-slot`. */
@@ -70,4 +55,4 @@ type MenuProps<Value extends string = string> = Omit<UIMenu.Root.Props, "childre
70
55
  };
71
56
  declare function Menu<Value extends string = string>({ trigger, items, side, align, sideOffset, alignOffset, collisionPadding, className, ui, ...props }: MenuProps<Value>): React.JSX.Element;
72
57
  export { Menu };
73
- export type { MenuEntry, MenuGroupProps, MenuItemProps, MenuProps, MenuSeparatorProps, };
58
+ export type { MenuGroupProps, MenuItemProps, MenuProps, MenuSeparatorProps, };
@@ -152,12 +152,15 @@ function MenuGroup({
152
152
  className,
153
153
  ui,
154
154
  label,
155
- items
155
+ items,
156
+ type: _type,
157
+ ...props
156
158
  }) {
157
159
  const styles = theme();
158
160
  return /* @__PURE__ */ React.createElement(
159
161
  UIMenu.Group,
160
162
  {
163
+ ...props,
161
164
  "data-slot": "group",
162
165
  className: cn(styles.group(), ui?.group, className)
163
166
  },
@@ -184,11 +187,17 @@ function MenuGroup({
184
187
  ))
185
188
  );
186
189
  }
187
- function MenuSeparator({ className, ui }) {
190
+ function MenuSeparator({
191
+ className,
192
+ ui,
193
+ type: _type,
194
+ ...props
195
+ }) {
188
196
  const styles = theme();
189
197
  return /* @__PURE__ */ React.createElement(
190
198
  UIMenu.Separator,
191
199
  {
200
+ ...props,
192
201
  "data-slot": "separator",
193
202
  className: cn(styles.separator(), ui?.separator, className)
194
203
  }
@@ -3,8 +3,7 @@ import * as React from "react";
3
3
  import { type ComponentConfig } from "../internal/tv";
4
4
  import theme from "../theme/popover";
5
5
  type Popover = ComponentConfig<typeof theme>;
6
- type PositionerProps = UIPopover.Positioner.Props;
7
- type PopoverProps = Omit<UIPopover.Root.Props, "children"> & {
6
+ type PopoverProps = Omit<UIPopover.Root.Props, "children"> & Pick<UIPopover.Positioner.Props, "side" | "align" | "sideOffset" | "alignOffset" | "collisionPadding"> & {
8
7
  /** Element that opens the popover. It must forward props and refs. */
9
8
  trigger: React.ReactElement;
10
9
  /** Popover heading. */
@@ -17,16 +16,6 @@ type PopoverProps = Omit<UIPopover.Root.Props, "children"> & {
17
16
  footer?: React.ReactNode;
18
17
  /** Whether to render the directional arrow. */
19
18
  arrow?: boolean;
20
- /** Side of the trigger the popover is placed on. */
21
- side?: PositionerProps["side"];
22
- /** Alignment of the popover relative to the trigger. */
23
- align?: PositionerProps["align"];
24
- /** Distance between the trigger and the popup in pixels. */
25
- sideOffset?: PositionerProps["sideOffset"];
26
- /** Offset along the alignment axis in pixels. */
27
- alignOffset?: PositionerProps["alignOffset"];
28
- /** Padding between the popup and the edge of the collision boundary. */
29
- collisionPadding?: PositionerProps["collisionPadding"];
30
19
  /** Tailwind classes merged into the popup. */
31
20
  className?: string;
32
21
  /** Tailwind classes for internal slots, keyed by `data-slot`. */
@@ -30,6 +30,6 @@ type RadioGroupProps<Value extends string = string> = Omit<UIRadioGroup.Props<Va
30
30
  /** Tailwind classes for internal slots, keyed by `data-slot`. */
31
31
  ui?: RadioGroup["slots"];
32
32
  };
33
- declare function RadioGroup<Value extends string = string>({ className, ui, size, items, label, description, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...props }: RadioGroupProps<Value>): React.JSX.Element;
33
+ declare function RadioGroup<Value extends string = string>({ className, ui, size, items, label, description, disabled, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...props }: RadioGroupProps<Value>): React.JSX.Element;
34
34
  export { RadioGroup };
35
35
  export type { RadioGroupItemProps, RadioGroupProps };
@@ -1,9 +1,11 @@
1
1
  "use client";
2
+ import { useLabelableId } from "@base-ui/react/internals/labelable-provider";
2
3
  import { Radio as UIRadio } from "@base-ui/react/radio";
3
4
  import { RadioGroup as UIRadioGroup } from "@base-ui/react/radio-group";
4
5
  import { cn } from "cn";
5
6
  import * as React from "react";
6
7
  import { mergeIds } from "../internal/aria.mjs";
8
+ import { useFieldsetDisabled } from "../internal/fieldset.mjs";
7
9
  import theme from "../theme/radio-group.mjs";
8
10
  function RadioGroup({
9
11
  className,
@@ -12,12 +14,14 @@ function RadioGroup({
12
14
  items,
13
15
  label,
14
16
  description,
17
+ disabled,
15
18
  "aria-label": ariaLabel,
16
19
  "aria-labelledby": ariaLabelledBy,
17
20
  "aria-describedby": ariaDescribedBy,
18
21
  ...props
19
22
  }) {
20
23
  const styles = theme({ size });
24
+ const fieldsetDisabled = useFieldsetDisabled(disabled);
21
25
  const labelId = React.useId();
22
26
  const descriptionId = React.useId();
23
27
  const hasName = Boolean(label || ariaLabel || ariaLabelledBy);
@@ -26,13 +30,15 @@ function RadioGroup({
26
30
  ariaDescribedBy,
27
31
  description && hasName ? descriptionId : void 0
28
32
  );
33
+ useLabelableId({ id: null });
29
34
  return /* @__PURE__ */ React.createElement(
30
35
  UIRadioGroup,
31
36
  {
32
37
  ...props,
33
38
  "aria-describedby": describedBy,
34
39
  "aria-label": ariaLabel,
35
- "aria-labelledby": labelledBy,
40
+ ...labelledBy ? { "aria-labelledby": labelledBy } : {},
41
+ disabled: fieldsetDisabled,
36
42
  "data-slot": "root",
37
43
  className: cn(styles.root(), ui?.root, className)
38
44
  },
@@ -4,7 +4,6 @@ import { type VariantProps } from "tailwind-variants";
4
4
  import { type ComponentConfig } from "../internal/tv";
5
5
  import theme from "../theme/select";
6
6
  type Select = ComponentConfig<typeof theme>;
7
- type PositionerProps = UISelect.Positioner.Props;
8
7
  /** One option rendered by the select. */
9
8
  type SelectItemProps<Value extends string = string> = {
10
9
  /** Value submitted and passed to `onValueChange`. */
@@ -16,7 +15,7 @@ type SelectItemProps<Value extends string = string> = {
16
15
  /** Whether the option is disabled. */
17
16
  disabled?: boolean;
18
17
  };
19
- type SelectProps<Value extends string = string> = Omit<UISelect.Root.Props<Value>, "children" | "className" | "style" | "items" | "multiple" | "value" | "defaultValue" | "onValueChange"> & VariantProps<typeof theme> & {
18
+ type SelectProps<Value extends string = string> = Omit<UISelect.Root.Props<Value>, "children" | "className" | "style" | "items" | "multiple" | "value" | "defaultValue" | "onValueChange"> & VariantProps<typeof theme> & Pick<UISelect.Positioner.Props, "side" | "align" | "sideOffset" | "alignOffset" | "collisionPadding" | "alignItemWithTrigger"> & {
20
19
  /** Options rendered by the select. */
21
20
  items: readonly SelectItemProps<Value>[];
22
21
  /** Visible label associated with the trigger. */
@@ -31,18 +30,6 @@ type SelectProps<Value extends string = string> = Omit<UISelect.Root.Props<Value
31
30
  defaultValue?: Value | null;
32
31
  /** Called when the selected value changes. */
33
32
  onValueChange?: (value: Value | null, details: UISelect.Root.ChangeEventDetails) => void;
34
- /** Side of the trigger the popup is placed on. */
35
- side?: PositionerProps["side"];
36
- /** Alignment of the popup relative to the trigger. */
37
- align?: PositionerProps["align"];
38
- /** Distance between the trigger and the popup in pixels. */
39
- sideOffset?: PositionerProps["sideOffset"];
40
- /** Offset along the alignment axis in pixels. */
41
- alignOffset?: PositionerProps["alignOffset"];
42
- /** Padding between the popup and the edge of the collision boundary. */
43
- collisionPadding?: PositionerProps["collisionPadding"];
44
- /** Whether the popup overlaps the trigger to align the selected item. */
45
- alignItemWithTrigger?: PositionerProps["alignItemWithTrigger"];
46
33
  /** Accessible name for the trigger when no visible label is rendered. */
47
34
  "aria-label"?: string;
48
35
  /** Names the trigger from another element. */
@@ -3,6 +3,7 @@ import { Select as UISelect } from "@base-ui/react/select";
3
3
  import { cn } from "cn";
4
4
  import * as React from "react";
5
5
  import { mergeIds } from "../internal/aria.mjs";
6
+ import { useFieldsetDisabled } from "../internal/fieldset.mjs";
6
7
  import theme from "../theme/select.mjs";
7
8
  import { CheckIcon } from "./icons/check.mjs";
8
9
  import { ChevronDownIcon } from "./icons/chevron-down.mjs";
@@ -30,6 +31,7 @@ function Select({
30
31
  ...props
31
32
  }) {
32
33
  const styles = theme({ size });
34
+ const fieldsetDisabled = useFieldsetDisabled(disabled);
33
35
  const descriptionId = React.useId();
34
36
  const describedBy = mergeIds(
35
37
  ariaDescribedBy,
@@ -48,13 +50,13 @@ function Select({
48
50
  value,
49
51
  defaultValue,
50
52
  onValueChange,
51
- disabled
53
+ disabled: fieldsetDisabled
52
54
  },
53
55
  /* @__PURE__ */ React.createElement(
54
56
  "div",
55
57
  {
56
58
  "data-slot": "root",
57
- "data-disabled": disabled || void 0,
59
+ "data-disabled": fieldsetDisabled || void 0,
58
60
  className: cn(styles.root(), ui?.root, className)
59
61
  },
60
62
  label ? /* @__PURE__ */ React.createElement(
@@ -70,7 +72,7 @@ function Select({
70
72
  {
71
73
  "data-slot": "trigger",
72
74
  ...triggerAriaProps,
73
- disabled,
75
+ disabled: fieldsetDisabled,
74
76
  className: cn(styles.trigger(), ui?.trigger)
75
77
  },
76
78
  /* @__PURE__ */ React.createElement(
@@ -3,21 +3,17 @@ import * as React from "react";
3
3
  import { type ComponentConfig } from "../internal/tv";
4
4
  import theme from "../theme/slider";
5
5
  type Slider = ComponentConfig<typeof theme>;
6
- type SliderProps<Value extends number | readonly number[] = number> = Omit<UISlider.Root.Props<Value>, "children" | "style" | "className"> & {
6
+ type SliderProps<Value extends number | readonly number[] = number> = Omit<UISlider.Root.Props<Value>, "children" | "style" | "className"> & Pick<UISlider.Thumb.Props, "getAriaLabel" | "getAriaValueText"> & {
7
7
  /** Tailwind classes merged into the root. */
8
8
  className?: string;
9
9
  /** Tailwind classes for internal slots, keyed by `data-slot`. */
10
10
  ui?: Slider["slots"];
11
- /** Accessible name for the thumb at `index`. Useful for range sliders. */
12
- getAriaLabel?: UISlider.Thumb.Props["getAriaLabel"];
13
- /** Accessible value text for the thumb at `index`. */
14
- getAriaValueText?: UISlider.Thumb.Props["getAriaValueText"];
15
11
  };
16
12
  /**
17
13
  * Sliders need an accessible name. Pass `aria-label` or `aria-labelledby`;
18
14
  * both are forwarded from the root to every thumb. `aria-describedby` is also
19
15
  * forwarded so supporting copy is announced with each thumb.
20
16
  */
21
- declare function Slider<Value extends number | readonly number[] = number>({ className, ui, value, defaultValue, "aria-describedby": ariaDescribedBy, "aria-errormessage": ariaErrorMessage, "aria-invalid": ariaInvalid, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, getAriaLabel, getAriaValueText, ...props }: SliderProps<Value>): React.JSX.Element;
17
+ declare function Slider<Value extends number | readonly number[] = number>({ className, ui, value, defaultValue, disabled, "aria-describedby": ariaDescribedBy, "aria-errormessage": ariaErrorMessage, "aria-invalid": ariaInvalid, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, getAriaLabel, getAriaValueText, ...props }: SliderProps<Value>): React.JSX.Element;
22
18
  export { Slider };
23
19
  export type { SliderProps };
@@ -2,6 +2,7 @@
2
2
  import { Slider as UISlider } from "@base-ui/react/slider";
3
3
  import { cn } from "cn";
4
4
  import * as React from "react";
5
+ import { useFieldsetDisabled } from "../internal/fieldset.mjs";
5
6
  import theme from "../theme/slider.mjs";
6
7
  function setAriaAttribute(input, name, value) {
7
8
  if (value === void 0 || value === null) {
@@ -15,6 +16,7 @@ function Slider({
15
16
  ui,
16
17
  value,
17
18
  defaultValue,
19
+ disabled,
18
20
  "aria-describedby": ariaDescribedBy,
19
21
  "aria-errormessage": ariaErrorMessage,
20
22
  "aria-invalid": ariaInvalid,
@@ -25,6 +27,7 @@ function Slider({
25
27
  ...props
26
28
  }) {
27
29
  const styles = theme();
30
+ const fieldsetDisabled = useFieldsetDisabled(disabled);
28
31
  const syncThumbAria = React.useCallback(
29
32
  (input) => {
30
33
  if (!input) {
@@ -45,6 +48,7 @@ function Slider({
45
48
  "aria-labelledby": ariaLabelledBy,
46
49
  value,
47
50
  defaultValue,
51
+ disabled: fieldsetDisabled,
48
52
  "data-slot": "root",
49
53
  className: cn(styles.root(), ui?.root, className)
50
54
  },
@@ -3,6 +3,7 @@ import { Switch as UISwitch } from "@base-ui/react/switch";
3
3
  import { cn } from "cn";
4
4
  import * as React from "react";
5
5
  import { mergeIds } from "../internal/aria.mjs";
6
+ import { useFieldsetDisabled } from "../internal/fieldset.mjs";
6
7
  import theme from "../theme/switch.mjs";
7
8
  function LiquidGlassFilter({ id }) {
8
9
  return /* @__PURE__ */ React.createElement("svg", { "aria-hidden": "true", focusable: "false", "data-layer": "filter" }, /* @__PURE__ */ React.createElement("defs", null, /* @__PURE__ */ React.createElement("filter", { id: `${id}-goo` }, /* @__PURE__ */ React.createElement(
@@ -61,6 +62,7 @@ function Switch({
61
62
  ...props
62
63
  }) {
63
64
  const styles = theme({ size });
65
+ const fieldsetDisabled = useFieldsetDisabled(disabled);
64
66
  const filterId = React.useId();
65
67
  const labelId = React.useId();
66
68
  const descriptionId = React.useId();
@@ -96,7 +98,7 @@ function Switch({
96
98
  "aria-describedby": describedBy,
97
99
  "aria-label": ariaLabel,
98
100
  "aria-labelledby": labelledBy,
99
- disabled,
101
+ disabled: fieldsetDisabled,
100
102
  readOnly,
101
103
  "data-slot": "root",
102
104
  "data-animating": animating || void 0,
@@ -21,7 +21,7 @@ type TabsItemProps<Value extends string = string> = Omit<UITabs.Tab.Props, "chil
21
21
  /** Tailwind classes for this item's internal slots, keyed by `data-slot`. */
22
22
  ui?: Partial<Pick<Tabs["slots"], "tab" | "icon" | "label" | "panel" | "panelContent">>;
23
23
  };
24
- type TabsProps<Value extends string = string> = Omit<UITabs.Root.Props, "children" | "className" | "style" | "value" | "defaultValue" | "onValueChange"> & VariantProps<typeof theme> & {
24
+ type TabsProps<Value extends string = string> = Omit<UITabs.Root.Props, "children" | "className" | "style" | "value" | "defaultValue" | "onValueChange"> & Pick<UITabs.List.Props, "activateOnFocus" | "loopFocus"> & VariantProps<typeof theme> & {
25
25
  /** Tabs and panels rendered by the component. */
26
26
  items: readonly TabsItemProps<Value>[];
27
27
  /** Controlled active value. Use `null` to render no active tab. */
@@ -30,10 +30,6 @@ type TabsProps<Value extends string = string> = Omit<UITabs.Root.Props, "childre
30
30
  defaultValue?: Value | null;
31
31
  /** Called when the active value changes. */
32
32
  onValueChange?: (value: Value, details: UITabs.Root.ChangeEventDetails) => void;
33
- /** Whether arrow keys activate a tab as focus moves. */
34
- activateOnFocus?: boolean;
35
- /** Whether keyboard focus loops back to the first tab. */
36
- loopFocus?: boolean;
37
33
  /** Disables every tab. */
38
34
  disabled?: boolean;
39
35
  /** Tailwind classes merged into the root. */
@@ -26,6 +26,6 @@ type ToggleGroupProps<Value extends string = string> = Omit<UIToggleGroup.Props<
26
26
  /** Tailwind classes for internal slots, keyed by `data-slot`. */
27
27
  ui?: ToggleGroup["slots"];
28
28
  };
29
- declare function ToggleGroup<Value extends string = string>({ className, ui, size, items, ...props }: ToggleGroupProps<Value>): React.JSX.Element;
29
+ declare function ToggleGroup<Value extends string = string>({ className, ui, size, items, disabled, ...props }: ToggleGroupProps<Value>): React.JSX.Element;
30
30
  export { ToggleGroup };
31
31
  export type { ToggleGroupItemProps, ToggleGroupProps };
@@ -3,19 +3,23 @@ import { Toggle as UIToggle } from "@base-ui/react/toggle";
3
3
  import { ToggleGroup as UIToggleGroup } from "@base-ui/react/toggle-group";
4
4
  import { cn } from "cn";
5
5
  import * as React from "react";
6
+ import { useFieldsetDisabled } from "../internal/fieldset.mjs";
6
7
  import theme from "../theme/toggle-group.mjs";
7
8
  function ToggleGroup({
8
9
  className,
9
10
  ui,
10
11
  size,
11
12
  items,
13
+ disabled,
12
14
  ...props
13
15
  }) {
14
16
  const styles = theme({ size });
17
+ const fieldsetDisabled = useFieldsetDisabled(disabled);
15
18
  return /* @__PURE__ */ React.createElement(
16
19
  UIToggleGroup,
17
20
  {
18
21
  ...props,
22
+ disabled: fieldsetDisabled,
19
23
  "data-slot": "root",
20
24
  className: cn(styles.root(), ui?.root, className)
21
25
  },
@@ -16,6 +16,6 @@ type ToggleProps<Value extends string = string> = Omit<UIToggle.Props<Value>, "c
16
16
  /** Icon rendered before the label. */
17
17
  icon?: React.ReactNode;
18
18
  };
19
- declare function Toggle<Value extends string = string>({ className, ui, icon, label, size, ...props }: ToggleProps<Value>): React.JSX.Element;
19
+ declare function Toggle<Value extends string = string>({ className, ui, icon, label, size, disabled, ...props }: ToggleProps<Value>): React.JSX.Element;
20
20
  export { Toggle };
21
21
  export type { ToggleProps };
@@ -2,6 +2,7 @@
2
2
  import { Toggle as UIToggle } from "@base-ui/react/toggle";
3
3
  import { cn } from "cn";
4
4
  import * as React from "react";
5
+ import { useFieldsetDisabled } from "../internal/fieldset.mjs";
5
6
  import theme from "../theme/toggle.mjs";
6
7
  function Toggle({
7
8
  className,
@@ -9,13 +10,16 @@ function Toggle({
9
10
  icon,
10
11
  label,
11
12
  size,
13
+ disabled,
12
14
  ...props
13
15
  }) {
14
16
  const styles = theme({ size, iconOnly: !label });
17
+ const fieldsetDisabled = useFieldsetDisabled(disabled);
15
18
  return /* @__PURE__ */ React.createElement(
16
19
  UIToggle,
17
20
  {
18
21
  ...props,
22
+ disabled: fieldsetDisabled,
19
23
  "data-slot": "root",
20
24
  className: cn(styles.root(), ui?.root, className)
21
25
  },
@@ -3,33 +3,18 @@ import * as React from "react";
3
3
  import { type ComponentConfig } from "../internal/tv";
4
4
  import theme from "../theme/tooltip";
5
5
  type Tooltip = ComponentConfig<typeof theme>;
6
- type PositionerProps = UITooltip.Positioner.Props;
7
- type TooltipProps = Omit<UITooltip.Root.Props, "children"> & {
6
+ type TooltipProps = Omit<UITooltip.Root.Props, "children"> & Pick<UITooltip.Trigger.Props, "delay" | "closeDelay"> & Pick<UITooltip.Positioner.Props, "side" | "align" | "sideOffset" | "alignOffset" | "collisionPadding"> & {
8
7
  /** Element that opens the tooltip. It must forward props and refs. */
9
8
  trigger: React.ReactElement;
10
9
  /** Short hint displayed while the trigger is hovered or focused. */
11
- content: React.ReactNode;
10
+ children: React.ReactNode;
12
11
  /** Whether to render the directional arrow. */
13
12
  arrow?: boolean;
14
- /** Delay before the tooltip opens on hover, in milliseconds. */
15
- delay?: number;
16
- /** Delay before the tooltip closes, in milliseconds. */
17
- closeDelay?: number;
18
- /** Side of the trigger the tooltip is placed on. */
19
- side?: PositionerProps["side"];
20
- /** Alignment of the tooltip relative to the trigger. */
21
- align?: PositionerProps["align"];
22
- /** Distance between the trigger and the tooltip in pixels. */
23
- sideOffset?: PositionerProps["sideOffset"];
24
- /** Offset along the alignment axis in pixels. */
25
- alignOffset?: PositionerProps["alignOffset"];
26
- /** Padding between the tooltip and the edge of the collision boundary. */
27
- collisionPadding?: PositionerProps["collisionPadding"];
28
13
  /** Tailwind classes merged into the tooltip popup. */
29
14
  className?: string;
30
15
  /** Tailwind classes for internal slots, keyed by `data-slot`. */
31
16
  ui?: Tooltip["slots"];
32
17
  };
33
- declare function Tooltip({ trigger, content, arrow, delay, closeDelay, side, align, sideOffset, alignOffset, collisionPadding, className, ui, ...props }: TooltipProps): React.JSX.Element;
18
+ declare function Tooltip({ trigger, children, arrow, delay, closeDelay, side, align, sideOffset, alignOffset, collisionPadding, className, ui, ...props }: TooltipProps): React.JSX.Element;
34
19
  export { Tooltip };
35
20
  export type { TooltipProps };
@@ -5,7 +5,7 @@ import * as React from "react";
5
5
  import theme from "../theme/tooltip.mjs";
6
6
  function Tooltip({
7
7
  trigger,
8
- content,
8
+ children,
9
9
  arrow = true,
10
10
  delay,
11
11
  closeDelay,
@@ -72,7 +72,7 @@ function Tooltip({
72
72
  "data-slot": "content",
73
73
  className: cn(styles.content(), ui?.content)
74
74
  },
75
- content
75
+ children
76
76
  )
77
77
  )
78
78
  )));
package/dist/index.d.ts CHANGED
@@ -3,10 +3,14 @@ export { AlertDialog, type AlertDialogProps } from "./components/alert-dialog";
3
3
  export { Button, type ButtonProps } from "./components/button";
4
4
  export { Card, type CardProps } from "./components/card";
5
5
  export { Checkbox, type CheckboxProps } from "./components/checkbox";
6
+ export { CheckboxGroup, type CheckboxGroupItemProps, type CheckboxGroupProps, } from "./components/checkbox-group";
6
7
  export { Dialog, type DialogProps } from "./components/dialog";
7
8
  export { Drawer, type DrawerProps } from "./components/drawer";
9
+ export { Field, type FieldProps } from "./components/field";
10
+ export { Fieldset, type FieldsetProps } from "./components/fieldset";
11
+ export { Form, type FormProps } from "./components/form";
8
12
  export { Input, type InputProps } from "./components/input";
9
- export { Menu, type MenuEntry, type MenuGroupProps, type MenuItemProps, type MenuProps, type MenuSeparatorProps, } from "./components/menu";
13
+ export { Menu, type MenuGroupProps, type MenuItemProps, type MenuProps, type MenuSeparatorProps, } from "./components/menu";
10
14
  export { Popover, type PopoverProps } from "./components/popover";
11
15
  export { Progress, type ProgressProps } from "./components/progress";
12
16
  export { RadioGroup, type RadioGroupItemProps, type RadioGroupProps, } from "./components/radio-group";
package/dist/index.mjs CHANGED
@@ -5,8 +5,14 @@ export { AlertDialog } from "./components/alert-dialog.mjs";
5
5
  export { Button } from "./components/button.mjs";
6
6
  export { Card } from "./components/card.mjs";
7
7
  export { Checkbox } from "./components/checkbox.mjs";
8
+ export {
9
+ CheckboxGroup
10
+ } from "./components/checkbox-group.mjs";
8
11
  export { Dialog } from "./components/dialog.mjs";
9
12
  export { Drawer } from "./components/drawer.mjs";
13
+ export { Field } from "./components/field.mjs";
14
+ export { Fieldset } from "./components/fieldset.mjs";
15
+ export { Form } from "./components/form.mjs";
10
16
  export { Input } from "./components/input.mjs";
11
17
  export {
12
18
  Menu
@@ -0,0 +1,8 @@
1
+ import * as React from "react";
2
+ type FieldsetDisabledProviderProps = {
3
+ disabled: boolean;
4
+ children: React.ReactNode;
5
+ };
6
+ declare function FieldsetDisabledProvider({ disabled, children, }: FieldsetDisabledProviderProps): React.JSX.Element;
7
+ declare function useFieldsetDisabled(disabled?: boolean): boolean;
8
+ export { FieldsetDisabledProvider, useFieldsetDisabled };
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import * as React from "react";
3
+ const FieldsetDisabledContext = React.createContext(false);
4
+ function FieldsetDisabledProvider({
5
+ disabled,
6
+ children
7
+ }) {
8
+ return /* @__PURE__ */ React.createElement(FieldsetDisabledContext.Provider, { value: disabled }, children);
9
+ }
10
+ function useFieldsetDisabled(disabled = false) {
11
+ return React.useContext(FieldsetDisabledContext) || disabled;
12
+ }
13
+ export { FieldsetDisabledProvider, useFieldsetDisabled };
@@ -7,9 +7,9 @@ export default tv({
7
7
  "data-[starting-style]:opacity-0 data-[ending-style]:opacity-0",
8
8
  "motion-reduce:transition-none"
9
9
  ],
10
- viewport: "fixed inset-0 z-50 flex items-center justify-center overflow-y-auto p-4",
10
+ viewport: "fixed inset-0 z-50 flex overflow-y-auto overscroll-contain p-4",
11
11
  popup: [
12
- "relative isolate w-full max-w-md bg-ui-surface",
12
+ "relative isolate m-auto w-full max-w-md bg-ui-surface",
13
13
  "rounded-[1.75rem] text-ui-ink outline-none",
14
14
  "transition-[opacity,scale,translate] duration-200 ease-out",
15
15
  "data-[starting-style]:translate-y-2 data-[starting-style]:scale-95 data-[starting-style]:opacity-0",
@@ -7,7 +7,7 @@ export default tv({
7
7
  ],
8
8
  glass: [
9
9
  "ui-glass ui-glass-inner ui-glass-highlight",
10
- "pointer-events-none relative col-start-1 row-start-1 h-full w-full overflow-hidden rounded-[2rem]"
10
+ "pointer-events-none relative col-start-1 row-start-1 h-full w-full overflow-hidden rounded-[inherit]"
11
11
  ],
12
12
  overlay: "ui-glass-rim",
13
13
  layout: [