@phreshos/react-ui 0.1.36 → 0.1.38

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 (202) hide show
  1. package/README.md +147 -167
  2. package/dist/accordion.d.ts +7 -6
  3. package/dist/accordion.js +5 -5
  4. package/dist/alert-dialog.d.ts +2 -2
  5. package/dist/alert-dialog.js +3 -1
  6. package/dist/alert.d.ts +17 -0
  7. package/dist/alert.js +30 -0
  8. package/dist/app-layout.d.ts +13 -0
  9. package/dist/app-layout.js +84 -0
  10. package/dist/button.d.ts +31 -27
  11. package/dist/button.js +48 -40
  12. package/dist/calendar-layout.d.ts +9 -5
  13. package/dist/calendar-layout.js +67 -78
  14. package/dist/calendar-trigger.d.ts +4 -4
  15. package/dist/calendar-trigger.js +7 -29
  16. package/dist/calendar.d.ts +2 -2
  17. package/dist/calendar.js +6 -5
  18. package/dist/checkbox.d.ts +4 -4
  19. package/dist/checkbox.js +16 -6
  20. package/dist/color-area.d.ts +20 -0
  21. package/dist/color-area.js +30 -0
  22. package/dist/color-field.d.ts +17 -0
  23. package/dist/color-field.js +17 -0
  24. package/dist/color-picker.d.ts +24 -0
  25. package/dist/color-picker.js +30 -0
  26. package/dist/color-slider.d.ts +19 -0
  27. package/dist/color-slider.js +29 -0
  28. package/dist/color-swatch-picker.d.ts +23 -0
  29. package/dist/color-swatch-picker.js +36 -0
  30. package/dist/color-swatch.d.ts +18 -0
  31. package/dist/color-swatch.js +20 -0
  32. package/dist/combo-box.d.ts +18 -10
  33. package/dist/combo-box.js +43 -58
  34. package/dist/context-menu.d.ts +14 -10
  35. package/dist/context-menu.js +7 -6
  36. package/dist/control/color-thumb.d.ts +13 -0
  37. package/dist/control/color-thumb.js +33 -0
  38. package/dist/control/color-value.d.ts +6 -0
  39. package/dist/control/color-value.js +7 -0
  40. package/dist/control/control.d.ts +60 -0
  41. package/dist/control/control.js +71 -0
  42. package/dist/control/field-button.d.ts +13 -0
  43. package/dist/control/field-button.js +28 -0
  44. package/dist/control/field.d.ts +20 -0
  45. package/dist/control/field.js +34 -0
  46. package/dist/control/icon.d.ts +11 -0
  47. package/dist/control/icon.js +8 -0
  48. package/dist/control/item.d.ts +37 -0
  49. package/dist/control/item.js +57 -0
  50. package/dist/control/open-state.d.ts +25 -0
  51. package/dist/control/open-state.js +8 -0
  52. package/dist/control/selection-track.d.ts +39 -0
  53. package/dist/control/selection-track.js +122 -0
  54. package/dist/control/selection.d.ts +44 -0
  55. package/dist/{selection.js → control/selection.js} +16 -0
  56. package/dist/control/surface-render.d.ts +10 -0
  57. package/dist/control/surface-render.js +12 -0
  58. package/dist/control/text-control.d.ts +32 -0
  59. package/dist/control/text-control.js +31 -0
  60. package/dist/control/toggle.d.ts +32 -0
  61. package/dist/control/toggle.js +80 -0
  62. package/dist/date-control.d.ts +9 -9
  63. package/dist/date-control.js +31 -34
  64. package/dist/date-field.d.ts +7 -6
  65. package/dist/date-field.js +8 -6
  66. package/dist/date-picker.d.ts +13 -6
  67. package/dist/date-picker.js +9 -6
  68. package/dist/date-range-picker.d.ts +15 -6
  69. package/dist/date-range-picker.js +12 -9
  70. package/dist/dialog.d.ts +29 -15
  71. package/dist/dialog.js +37 -28
  72. package/dist/disclosure.d.ts +8 -7
  73. package/dist/disclosure.js +31 -52
  74. package/dist/drop-zone.d.ts +18 -0
  75. package/dist/drop-zone.js +32 -0
  76. package/dist/dropdown-menu.d.ts +11 -8
  77. package/dist/dropdown-menu.js +5 -4
  78. package/dist/fieldset.d.ts +13 -0
  79. package/dist/fieldset.js +26 -0
  80. package/dist/file-trigger.d.ts +13 -0
  81. package/dist/file-trigger.js +6 -0
  82. package/dist/flex.d.ts +1 -1
  83. package/dist/flex.js +5 -4
  84. package/dist/foundation/appearance.d.ts +83 -0
  85. package/dist/foundation/appearance.js +38 -0
  86. package/dist/{aria-direction.js → foundation/aria-direction.js} +3 -1
  87. package/dist/foundation/color.d.ts +61 -0
  88. package/dist/foundation/color.js +247 -0
  89. package/dist/{layout.d.ts → foundation/layout.d.ts} +6 -4
  90. package/dist/{layout.js → foundation/layout.js} +7 -5
  91. package/dist/foundation/motion-style.d.ts +9 -0
  92. package/dist/foundation/motion-style.js +50 -0
  93. package/dist/foundation/preferences.d.ts +15 -0
  94. package/dist/{ui-provider.d.ts → foundation/provider.d.ts} +9 -5
  95. package/dist/{ui-provider.js → foundation/provider.js} +18 -27
  96. package/dist/{radius.d.ts → foundation/radius.d.ts} +6 -3
  97. package/dist/foundation/radius.js +11 -0
  98. package/dist/foundation/spacing.d.ts +11 -0
  99. package/dist/foundation/spacing.js +4 -0
  100. package/dist/foundation/visual.d.ts +42 -0
  101. package/dist/{appearance-context.js → foundation/visual.js} +41 -27
  102. package/dist/grid.d.ts +1 -1
  103. package/dist/grid.js +5 -4
  104. package/dist/icons/main.d.ts +5 -3
  105. package/dist/icons/main.js +5 -3
  106. package/dist/input.d.ts +2 -2
  107. package/dist/input.js +9 -7
  108. package/dist/list-box.d.ts +24 -19
  109. package/dist/list-box.js +52 -109
  110. package/dist/main.d.ts +28 -17
  111. package/dist/main.js +22 -9
  112. package/dist/menu.d.ts +28 -32
  113. package/dist/menu.js +47 -93
  114. package/dist/number-field.d.ts +17 -0
  115. package/dist/number-field.js +28 -0
  116. package/dist/panel.d.ts +10 -5
  117. package/dist/panel.js +33 -12
  118. package/dist/popover.d.ts +26 -12
  119. package/dist/popover.js +22 -15
  120. package/dist/progress-bar.d.ts +8 -10
  121. package/dist/progress-bar.js +18 -34
  122. package/dist/radio.d.ts +15 -12
  123. package/dist/radio.js +27 -37
  124. package/dist/range-calendar.d.ts +5 -3
  125. package/dist/range-calendar.js +8 -7
  126. package/dist/scroll-area.d.ts +2 -2
  127. package/dist/scroll-area.js +10 -9
  128. package/dist/segmented-control.d.ts +23 -0
  129. package/dist/segmented-control.js +38 -0
  130. package/dist/select.d.ts +40 -13
  131. package/dist/select.js +63 -18
  132. package/dist/slider.d.ts +7 -3
  133. package/dist/slider.js +51 -50
  134. package/dist/spinner.d.ts +5 -8
  135. package/dist/spinner.js +12 -27
  136. package/dist/surface/grain.d.ts +12 -0
  137. package/dist/surface/grain.js +65 -0
  138. package/dist/{material-options.d.ts → surface/material-options.d.ts} +1 -2
  139. package/dist/{material-options.js → surface/material-options.js} +2 -2
  140. package/dist/surface/paint-class.d.ts +13 -0
  141. package/dist/surface/paint-class.js +47 -0
  142. package/dist/{shadow-options.d.ts → surface/shadow-options.d.ts} +13 -1
  143. package/dist/{shadow-options.js → surface/shadow-options.js} +17 -2
  144. package/dist/surface/surface.d.ts +80 -0
  145. package/dist/surface/surface.js +239 -0
  146. package/dist/switch.d.ts +4 -5
  147. package/dist/switch.js +17 -8
  148. package/dist/table.d.ts +29 -32
  149. package/dist/table.js +68 -106
  150. package/dist/tabs.d.ts +16 -15
  151. package/dist/tabs.js +44 -86
  152. package/dist/textarea.d.ts +2 -2
  153. package/dist/textarea.js +10 -14
  154. package/dist/time-field.d.ts +6 -6
  155. package/dist/time-field.js +8 -6
  156. package/dist/toolbar.d.ts +6 -4
  157. package/dist/toolbar.js +16 -15
  158. package/dist/tooltip.d.ts +17 -8
  159. package/dist/tooltip.js +17 -15
  160. package/dist/tree.d.ts +22 -27
  161. package/dist/tree.js +54 -99
  162. package/dist/window.d.ts +4 -4
  163. package/dist/window.js +18 -20
  164. package/package.json +3 -3
  165. package/dist/appearance-context.d.ts +0 -54
  166. package/dist/appearance.d.ts +0 -11
  167. package/dist/appearance.js +0 -11
  168. package/dist/color.d.ts +0 -69
  169. package/dist/color.js +0 -192
  170. package/dist/control-surface.d.ts +0 -20
  171. package/dist/control-surface.js +0 -11
  172. package/dist/control.d.ts +0 -70
  173. package/dist/control.js +0 -105
  174. package/dist/field-style.d.ts +0 -3
  175. package/dist/field-style.js +0 -12
  176. package/dist/material-paint.d.ts +0 -13
  177. package/dist/material-paint.js +0 -119
  178. package/dist/motion-style.d.ts +0 -13
  179. package/dist/motion-style.js +0 -75
  180. package/dist/preferences.d.ts +0 -12
  181. package/dist/radius.js +0 -11
  182. package/dist/readiness.d.ts +0 -37
  183. package/dist/readiness.js +0 -134
  184. package/dist/selection.d.ts +0 -18
  185. package/dist/spacing.d.ts +0 -8
  186. package/dist/spacing.js +0 -8
  187. package/dist/surface-edge.d.ts +0 -11
  188. package/dist/surface-edge.js +0 -55
  189. package/dist/surface.d.ts +0 -27
  190. package/dist/surface.js +0 -92
  191. package/dist/text-control.d.ts +0 -10
  192. package/dist/text-control.js +0 -0
  193. package/dist/toggle-indicator.d.ts +0 -18
  194. package/dist/toggle-indicator.js +0 -49
  195. /package/dist/{aria-direction.d.ts → foundation/aria-direction.d.ts} +0 -0
  196. /package/dist/{direction.d.ts → foundation/direction.d.ts} +0 -0
  197. /package/dist/{direction.js → foundation/direction.js} +0 -0
  198. /package/dist/{overlay-placement.d.ts → foundation/overlay-placement.d.ts} +0 -0
  199. /package/dist/{overlay-placement.js → foundation/overlay-placement.js} +0 -0
  200. /package/dist/{preferences.js → foundation/preferences.js} +0 -0
  201. /package/dist/{scale.d.ts → foundation/scale.d.ts} +0 -0
  202. /package/dist/{scale.js → foundation/scale.js} +0 -0
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { ColorArea as AriaColorArea } from "react-aria-components";
4
+ import { colorEdge, ColorThumb } from "./control/color-thumb.js";
5
+ import { colorValue } from "./control/color-value.js";
6
+ import { useControlMetrics } from "./control/control.js";
7
+ import { AriaDirectionBoundary } from "./foundation/aria-direction.js";
8
+ import { resolveDirection, useDirection } from "./foundation/direction.js";
9
+ import { resolveRadius } from "./foundation/radius.js";
10
+ import { dimmedClass } from "./surface/surface.js";
11
+ /**
12
+ * Two channels of a color, such as saturation and brightness, on a square
13
+ * painted with both ranges. Inside a ColorPicker it edits the picker's color.
14
+ */
15
+ export const ColorArea = forwardRef(function ColorArea({ value, defaultValue, onChange, onChangeEnd, disabled, size, radius, className, style, ...properties }, ref) {
16
+ const metrics = useControlMetrics(size);
17
+ const direction = resolveDirection(properties.dir, useDirection());
18
+ return _jsx(AriaDirectionBoundary, { direction: direction, children: _jsx(AriaColorArea, { ...properties, ref: ref, dir: direction, ...(value !== undefined ? { value } : {}), ...(defaultValue !== undefined ? { defaultValue } : {}), ...(onChange !== undefined ? { onChange: (color) => onChange(colorValue(color)) } : {}), ...(onChangeEnd !== undefined ? { onChangeEnd: (color) => onChangeEnd(colorValue(color)) } : {}), isDisabled: disabled, className: dimmedClass(disabled ?? false, className), style: ({ defaultStyle }) => ({
19
+ ...defaultStyle,
20
+ position: "relative",
21
+ boxSizing: "border-box",
22
+ flexShrink: 0,
23
+ width: metrics.height * 6,
24
+ aspectRatio: "1",
25
+ // An area is a region, not a control: it keeps the Appearance radius.
26
+ borderRadius: resolveRadius(radius ?? "medium", metrics.visual.radius),
27
+ boxShadow: colorEdge(metrics),
28
+ ...style
29
+ }), children: _jsx(ColorThumb, { metrics: metrics }) }) });
30
+ });
@@ -0,0 +1,17 @@
1
+ import type { ColorFieldProps as AriaColorFieldProps } from "react-aria-components";
2
+ import { type ControlOverrides, type ControlProps, type FieldProps } from "./control/control.js";
3
+ import type { RadiusProps } from "./foundation/radius.js";
4
+ import type { MaterialOverrides } from "./surface/material-options.js";
5
+ export interface ColorFieldProps extends Omit<AriaColorFieldProps, ControlOverrides | "value" | "defaultValue" | "onChange" | "className" | "style">, ControlProps, FieldProps, RadiusProps, MaterialOverrides {
6
+ /** A hex color, or `null` while the field is empty. */
7
+ readonly value?: string | null;
8
+ readonly defaultValue?: string | null;
9
+ readonly onChange?: (value: string | null) => void;
10
+ readonly placeholder?: string;
11
+ readonly readOnly?: boolean;
12
+ }
13
+ /**
14
+ * A color typed as text: a hex value, or one channel when `channel` is set.
15
+ * Inside a ColorPicker it edits the picker's color.
16
+ */
17
+ export declare const ColorField: import("react").ForwardRefExoticComponent<ColorFieldProps & import("react").RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { ColorField as AriaColorField, Input as AriaInput } from "react-aria-components";
4
+ import { colorValue } from "./control/color-value.js";
5
+ import { useControlMetrics } from "./control/control.js";
6
+ import { FieldFeedback, FieldLabel, fieldStyle } from "./control/field.js";
7
+ import { nativeTextStyle, TextWell } from "./control/text-control.js";
8
+ import MotionStyle, { textControlClass } from "./foundation/motion-style.js";
9
+ import { dimmedClass } from "./surface/surface.js";
10
+ /**
11
+ * A color typed as text: a hex value, or one channel when `channel` is set.
12
+ * Inside a ColorPicker it edits the picker's color.
13
+ */
14
+ export const ColorField = forwardRef(function ColorField({ label, description, errorMessage, disabled, readOnly, required, invalid, value, defaultValue, onChange, size, color = "background", radius, style, className, placeholder, material, ...properties }, ref) {
15
+ const metrics = useControlMetrics(size, radius);
16
+ return _jsxs(AriaColorField, { ...properties, ...(value !== undefined ? { value } : {}), ...(defaultValue !== undefined ? { defaultValue } : {}), ...(onChange !== undefined ? { onChange: (next) => onChange(next === null ? null : colorValue(next)) } : {}), className: dimmedClass(disabled ?? false, className), isDisabled: disabled, isReadOnly: readOnly, isRequired: required, isInvalid: invalid, style: fieldStyle(metrics, style), children: [_jsx(MotionStyle, {}), _jsx(FieldLabel, { label: label }), _jsx(AriaInput, { ref: ref, placeholder: placeholder, className: textControlClass, render: (native, state) => _jsx(TextWell, { color: color, material: material, metrics: metrics, state: state, children: _jsx("input", { ...native }) }), style: { ...nativeTextStyle(metrics, false), fontVariantNumeric: "tabular-nums" } }), _jsx(FieldFeedback, { metrics: metrics, description: description, errorMessage: errorMessage })] });
17
+ });
@@ -0,0 +1,24 @@
1
+ import type { ReactNode } from "react";
2
+ import { type ButtonActionProps } from "./button.js";
3
+ import { type OpenStateProps } from "./control/open-state.js";
4
+ import { type PopoverContentProps } from "./popover.js";
5
+ export type ColorPickerRootProps = OpenStateProps & Readonly<{
6
+ /** A hex color. */
7
+ value?: string;
8
+ defaultValue?: string;
9
+ onChange?: (value: string) => void;
10
+ children: ReactNode;
11
+ }>;
12
+ /**
13
+ * Owns one color and the popover that edits it. The picker draws nothing of
14
+ * its own: its Trigger shows the color, and its Content holds whichever color
15
+ * components edit it, which all follow the picker's color.
16
+ */
17
+ declare function ColorPickerRoot({ value, defaultValue, onChange, children, ...state }: ColorPickerRootProps): import("react").JSX.Element;
18
+ export type ColorPickerTriggerProps = ButtonActionProps;
19
+ export type ColorPickerContentProps = PopoverContentProps;
20
+ export declare const ColorPicker: typeof ColorPickerRoot & {
21
+ Trigger: import("react").ForwardRefExoticComponent<ButtonActionProps & import("react").RefAttributes<HTMLButtonElement>>;
22
+ Content: import("react").ForwardRefExoticComponent<PopoverContentProps & import("react").RefAttributes<HTMLElement>>;
23
+ };
24
+ export {};
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { ColorPicker as AriaColorPicker, DialogTrigger as AriaDialogTrigger } from "react-aria-components";
4
+ import { Button } from "./button.js";
5
+ import { ColorSwatch } from "./color-swatch.js";
6
+ import { colorValue } from "./control/color-value.js";
7
+ import { useControlMetrics } from "./control/control.js";
8
+ import { ariaOpenState } from "./control/open-state.js";
9
+ import { PopoverContent, PopoverDialog } from "./popover.js";
10
+ import { scale } from "./foundation/scale.js";
11
+ import { useVisual } from "./foundation/visual.js";
12
+ /**
13
+ * Owns one color and the popover that edits it. The picker draws nothing of
14
+ * its own: its Trigger shows the color, and its Content holds whichever color
15
+ * components edit it, which all follow the picker's color.
16
+ */
17
+ function ColorPickerRoot({ value, defaultValue, onChange, children, ...state }) {
18
+ return _jsx(AriaColorPicker, { ...(value !== undefined ? { value } : {}), ...(defaultValue !== undefined ? { defaultValue } : {}), ...(onChange !== undefined ? { onChange: (color) => onChange(colorValue(color)) } : {}), children: _jsx(AriaDialogTrigger, { ...ariaOpenState(state), children: children }) });
19
+ }
20
+ /** A Button that shows the picker's color before its own label, if any. */
21
+ const ColorPickerTrigger = forwardRef(function ColorPickerTrigger({ children, size, ...properties }, ref) {
22
+ const metrics = useControlMetrics(size);
23
+ return _jsxs(Button, { ...properties, ref: ref, size: size, children: [_jsx(ColorSwatch, { style: { width: metrics.indicator, height: metrics.indicator } }), children] });
24
+ });
25
+ /** The popover that holds the editing components, stacked by the Appearance spacing. */
26
+ const ColorPickerContent = forwardRef(function ColorPickerContent({ children, style, placement = "bottom start", ...properties }, ref) {
27
+ const { spacing } = useVisual();
28
+ return _jsx(PopoverContent, { ...properties, ref: ref, placement: placement, style: { padding: scale(spacing, "medium"), ...style }, children: _jsx(PopoverDialog, { "aria-label": "Color", style: { display: "grid", gap: scale(spacing, "medium") }, children: children }) });
29
+ });
30
+ export const ColorPicker = Object.assign(ColorPickerRoot, { Trigger: ColorPickerTrigger, Content: ColorPickerContent });
@@ -0,0 +1,19 @@
1
+ import type { CSSProperties } from "react";
2
+ import type { ColorSliderProps as AriaColorSliderProps } from "react-aria-components";
3
+ import { type FieldProps } from "./control/control.js";
4
+ import type { ScaleLevel } from "./foundation/scale.js";
5
+ export interface ColorSliderProps extends Omit<AriaColorSliderProps, "value" | "defaultValue" | "onChange" | "onChangeEnd" | "isDisabled" | "className" | "style" | "children">, Pick<FieldProps, "label" | "description"> {
6
+ readonly value?: string;
7
+ readonly defaultValue?: string;
8
+ readonly onChange?: (value: string) => void;
9
+ readonly onChangeEnd?: (value: string) => void;
10
+ readonly disabled?: boolean;
11
+ readonly size?: ScaleLevel;
12
+ readonly className?: string;
13
+ readonly style?: CSSProperties;
14
+ }
15
+ /**
16
+ * One channel of a color, such as hue or alpha, on a track painted with that
17
+ * channel's range. Inside a ColorPicker it edits the picker's color.
18
+ */
19
+ export declare const ColorSlider: import("react").ForwardRefExoticComponent<ColorSliderProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { ColorSlider as AriaColorSlider, Label, SliderOutput, SliderTrack } from "react-aria-components";
4
+ import { colorEdge, ColorThumb } from "./control/color-thumb.js";
5
+ import { colorValue } from "./control/color-value.js";
6
+ import { controlFontWeight, controlOpacity, useControlMetrics } from "./control/control.js";
7
+ import { fieldStyle } from "./control/field.js";
8
+ import { AriaDirectionBoundary } from "./foundation/aria-direction.js";
9
+ import { resolveDirection, useDirection } from "./foundation/direction.js";
10
+ import { dimmedClass } from "./surface/surface.js";
11
+ /**
12
+ * One channel of a color, such as hue or alpha, on a track painted with that
13
+ * channel's range. Inside a ColorPicker it edits the picker's color.
14
+ */
15
+ export const ColorSlider = forwardRef(function ColorSlider({ label, description, value, defaultValue, onChange, onChangeEnd, disabled, size, className, style, orientation = "horizontal", ...properties }, ref) {
16
+ const metrics = useControlMetrics(size);
17
+ const direction = resolveDirection(properties.dir, useDirection());
18
+ const vertical = orientation === "vertical";
19
+ return _jsx(AriaDirectionBoundary, { direction: direction, children: _jsxs(AriaColorSlider, { ...properties, ref: ref, dir: direction, orientation: orientation, ...(value !== undefined ? { value } : {}), ...(defaultValue !== undefined ? { defaultValue } : {}), ...(onChange !== undefined ? { onChange: (color) => onChange(colorValue(color)) } : {}), ...(onChangeEnd !== undefined ? { onChangeEnd: (color) => onChangeEnd(colorValue(color)) } : {}), isDisabled: disabled, className: dimmedClass(disabled ?? false, className), style: fieldStyle(metrics, style), children: [_jsxs("div", { style: { display: "flex", alignItems: "baseline", justifyContent: "space-between", gap: metrics.gap }, children: [label != null && _jsx(Label, { style: { fontWeight: controlFontWeight }, children: label }), _jsx(SliderOutput, { style: { fontVariantNumeric: "tabular-nums", opacity: controlOpacity.secondary } })] }), _jsx(SliderTrack, { style: ({ defaultStyle }) => ({
20
+ ...defaultStyle,
21
+ position: "relative",
22
+ boxSizing: "border-box",
23
+ width: vertical ? metrics.indicator : "100%",
24
+ height: vertical ? metrics.height * 4 : metrics.indicator,
25
+ // A track is round by its form.
26
+ borderRadius: 9999,
27
+ boxShadow: colorEdge(metrics)
28
+ }), children: _jsx(ColorThumb, { metrics: metrics, center: vertical ? "left" : "top" }) }), description != null && _jsx("span", { style: { fontSize: "0.92em", opacity: controlOpacity.secondary }, children: description })] }) });
29
+ });
@@ -0,0 +1,23 @@
1
+ import type { CSSProperties } from "react";
2
+ import type { ColorSwatchPickerItemProps as AriaColorSwatchPickerItemProps, ColorSwatchPickerProps as AriaColorSwatchPickerProps } from "react-aria-components";
3
+ import type { RadiusProps } from "./foundation/radius.js";
4
+ import type { ScaleLevel } from "./foundation/scale.js";
5
+ export interface ColorSwatchPickerProps extends Omit<AriaColorSwatchPickerProps, "value" | "defaultValue" | "onChange" | "className" | "style">, RadiusProps {
6
+ /** The selected Item's value. */
7
+ readonly value?: string;
8
+ readonly defaultValue?: string;
9
+ readonly onChange?: (value: string) => void;
10
+ readonly size?: ScaleLevel;
11
+ readonly className?: string;
12
+ readonly style?: CSSProperties;
13
+ }
14
+ export interface ColorSwatchPickerItemProps extends Omit<AriaColorSwatchPickerItemProps, "color" | "isDisabled" | "className" | "style" | "children"> {
15
+ /** The color this Item stands for; it is also the value it selects. */
16
+ readonly value: string;
17
+ readonly disabled?: boolean;
18
+ readonly className?: string;
19
+ readonly style?: CSSProperties;
20
+ }
21
+ export declare const ColorSwatchPicker: import("react").ForwardRefExoticComponent<ColorSwatchPickerProps & import("react").RefAttributes<HTMLDivElement>> & {
22
+ Item: import("react").ForwardRefExoticComponent<ColorSwatchPickerItemProps & import("react").RefAttributes<HTMLDivElement>>;
23
+ };
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, forwardRef, useContext, useMemo } from "react";
3
+ import { ColorSwatchPicker as AriaColorSwatchPicker, ColorSwatchPickerItem as AriaColorSwatchPickerItem } from "react-aria-components";
4
+ import { colorValue } from "./control/color-value.js";
5
+ import { transition, useControlMetrics } from "./control/control.js";
6
+ import { ColorSwatch } from "./color-swatch.js";
7
+ import { AriaDirectionBoundary } from "./foundation/aria-direction.js";
8
+ import { colorOpacity } from "./foundation/color.js";
9
+ import { resolveDirection, useDirection } from "./foundation/direction.js";
10
+ import { dimmedClass } from "./surface/surface.js";
11
+ const SwatchPickerStyleContext = createContext(null);
12
+ /** One color chosen from a set of swatches; arrow keys move between them. */
13
+ const ColorSwatchPickerRoot = forwardRef(function ColorSwatchPicker({ value, defaultValue, onChange, size, radius, className, style, ...properties }, ref) {
14
+ const metrics = useControlMetrics(size, radius);
15
+ const direction = resolveDirection(properties.dir, useDirection());
16
+ const context = useMemo(() => ({ metrics, size, radius }), [metrics, size, radius]);
17
+ return _jsx(AriaDirectionBoundary, { direction: direction, children: _jsx(SwatchPickerStyleContext.Provider, { value: context, children: _jsx(AriaColorSwatchPicker, { ...properties, ref: ref, dir: direction, ...(value !== undefined ? { value } : {}), ...(defaultValue !== undefined ? { defaultValue } : {}), onChange: color => onChange?.(colorValue(color)), className: className, style: { display: "flex", flexWrap: "wrap", gap: metrics.gap, ...style } }) }) });
18
+ });
19
+ /** One selectable swatch. Selection draws a ring in the text color around it. */
20
+ const ColorSwatchPickerItem = forwardRef(function ColorSwatchPickerItem({ value, disabled, className, style, ...properties }, ref) {
21
+ const inherited = useContext(SwatchPickerStyleContext);
22
+ if (inherited == null)
23
+ throw new Error("ColorSwatchPicker.Item must be used inside ColorSwatchPicker");
24
+ const { metrics, size, radius } = inherited;
25
+ const { colors } = metrics.visual;
26
+ return _jsx(AriaColorSwatchPickerItem, { ...properties, ref: ref, color: value, isDisabled: disabled, className: state => dimmedClass(state.isDisabled, className ?? state.defaultClassName) ?? "", style: ({ isSelected, isFocusVisible, isDisabled }) => ({
27
+ ...transition(metrics.visual, "outline-color"),
28
+ display: "flex",
29
+ borderRadius: metrics.radius,
30
+ outline: `2px solid ${isFocusVisible ? colorOpacity(colors.primary, 0.6) : isSelected ? colors.foreground : "transparent"}`,
31
+ outlineOffset: 2,
32
+ cursor: isDisabled ? "not-allowed" : "pointer",
33
+ ...style
34
+ }), children: _jsx(ColorSwatch, { size: size, radius: radius }) });
35
+ });
36
+ export const ColorSwatchPicker = Object.assign(ColorSwatchPickerRoot, { Item: ColorSwatchPickerItem });
@@ -0,0 +1,18 @@
1
+ import type { CSSProperties } from "react";
2
+ import type { ColorSwatchProps as AriaColorSwatchProps } from "react-aria-components";
3
+ import { type Color } from "./foundation/color.js";
4
+ import type { RadiusProps } from "./foundation/radius.js";
5
+ import type { ScaleLevel } from "./foundation/scale.js";
6
+ export interface ColorSwatchProps extends Omit<AriaColorSwatchProps, "color" | "className" | "style">, RadiusProps {
7
+ /**
8
+ * The color shown: a role, a level, or any CSS color. Inside a ColorPicker
9
+ * or a ColorSwatchPicker Item it defaults to that owner's color.
10
+ */
11
+ readonly color?: Color;
12
+ /** A control-sized square at each level. */
13
+ readonly size?: ScaleLevel;
14
+ readonly className?: string;
15
+ readonly style?: CSSProperties;
16
+ }
17
+ /** One color shown as a square, with a checkerboard beneath translucent colors. */
18
+ export declare const ColorSwatch: import("react").ForwardRefExoticComponent<ColorSwatchProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { ColorSwatch as AriaColorSwatch } from "react-aria-components";
4
+ import { colorEdge } from "./control/color-thumb.js";
5
+ import { useControlMetrics } from "./control/control.js";
6
+ import { resolveColor } from "./foundation/color.js";
7
+ /** One color shown as a square, with a checkerboard beneath translucent colors. */
8
+ export const ColorSwatch = forwardRef(function ColorSwatch({ color, size, radius, className, style, ...properties }, ref) {
9
+ const metrics = useControlMetrics(size, radius);
10
+ return _jsx(AriaColorSwatch, { ...properties, ref: ref, ...(color === undefined ? {} : { color: resolveColor(color, metrics.visual.colors) }), className: className, style: ({ defaultStyle }) => ({
11
+ ...defaultStyle,
12
+ boxSizing: "border-box",
13
+ flexShrink: 0,
14
+ width: metrics.height,
15
+ height: metrics.height,
16
+ borderRadius: metrics.radius,
17
+ boxShadow: colorEdge(metrics),
18
+ ...style
19
+ }) });
20
+ });
@@ -1,12 +1,11 @@
1
+ import type { ReactNode } from "react";
1
2
  import type { ComboBoxProps as AriaComboBoxProps } from "react-aria-components";
2
- import type { ControlOverrides, ControlProps, FieldProps } from "./control.js";
3
- import type { MaterialOverrides } from "./material-options.js";
4
- import type { RadiusProps } from "./radius.js";
5
- import type { SelectOption } from "./select.js";
6
- import type { ShadowOverrides } from "./shadow-options.js";
7
- export type ComboBoxOption = SelectOption;
8
- export interface ComboBoxProps extends Omit<AriaComboBoxProps<ComboBoxOption>, ControlOverrides | "allowsCustomValue" | "defaultItems" | "defaultInputValue" | "defaultSelectedKey" | "defaultValue" | "disabledKeys" | "inputValue" | "isReadOnly" | "items" | "onChange" | "onInputChange" | "onSelectionChange" | "selectedKey" | "selectionMode" | "value">, ControlProps, FieldProps, RadiusProps, MaterialOverrides, ShadowOverrides {
9
- readonly options: readonly ComboBoxOption[];
3
+ import { type ControlOverrides, type ControlProps, type FieldProps } from "./control/control.js";
4
+ import { type RadiusProps } from "./foundation/radius.js";
5
+ import type { MaterialOverrides } from "./surface/material-options.js";
6
+ export interface ComboBoxProps extends Omit<AriaComboBoxProps<object>, ControlOverrides | "allowsCustomValue" | "defaultItems" | "defaultInputValue" | "defaultSelectedKey" | "defaultValue" | "disabledKeys" | "inputValue" | "items" | "onChange" | "onInputChange" | "onSelectionChange" | "selectedKey" | "selectionMode" | "value" | "onOpenChange" | "allowsEmptyCollection" | "shouldFocusWrap">, ControlProps, FieldProps, RadiusProps, MaterialOverrides {
7
+ /** `ComboBox.Item` and `ComboBox.Section` entries filtered by the typed query. */
8
+ readonly children: ReactNode;
10
9
  readonly value?: string | null;
11
10
  readonly defaultValue?: string | null;
12
11
  readonly onChange?: (value: string | null) => void;
@@ -15,6 +14,15 @@ export interface ComboBoxProps extends Omit<AriaComboBoxProps<ComboBoxOption>, C
15
14
  readonly onInputChange?: (value: string) => void;
16
15
  readonly placeholder?: string;
17
16
  readonly readOnly?: boolean;
17
+ readonly onOpenChange?: (open: boolean) => void;
18
+ /** Whether the list can open while no Item matches. */
19
+ readonly openWhenEmpty?: boolean;
20
+ /** Whether arrow keys wrap from the last Item to the first. */
21
+ readonly focusWrap?: boolean;
18
22
  }
19
- /** A searchable single-selection field whose query filters string-valued options. */
20
- export declare const ComboBox: import("react").ForwardRefExoticComponent<ComboBoxProps & import("react").RefAttributes<HTMLDivElement>>;
23
+ /** A searchable single-choice field whose options are its Items. */
24
+ export declare const ComboBox: import("react").ForwardRefExoticComponent<ComboBoxProps & import("react").RefAttributes<HTMLDivElement>> & {
25
+ Item: import("./list-box.js").ListBoxItemComponent;
26
+ Section: import("./list-box.js").ListBoxSectionComponent;
27
+ Header: import("react").ForwardRefExoticComponent<import("react-aria-components").HeaderProps & import("react").RefAttributes<HTMLElement>>;
28
+ };
package/dist/combo-box.js CHANGED
@@ -1,68 +1,53 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { forwardRef, useMemo } from "react";
3
- import { Button, ComboBox as AriaComboBox, Group, Input as AriaInput } from "react-aria-components";
4
- import { controlPaint, FieldFeedback, FieldLabel, fieldStyle, useControlTheme } from "./control.js";
5
- import { SurfaceField } from "./control-surface.js";
6
- import { resolveDirection, useDirection } from "./direction.js";
7
- import FieldStyle, { textControlClass } from "./field-style.js";
2
+ import { forwardRef } from "react";
3
+ import { Button as AriaButton, ComboBox as AriaComboBox, Group, Input as AriaInput } from "react-aria-components";
4
+ import { useControlMetrics } from "./control/control.js";
5
+ import { FieldFeedback, FieldLabel, fieldStyle } from "./control/field.js";
6
+ import { surfaceRender } from "./control/surface-render.js";
7
+ import { nativeTextStyle } from "./control/text-control.js";
8
+ import { resolveDirection, useDirection } from "./foundation/direction.js";
9
+ import MotionStyle, { textControlClass } from "./foundation/motion-style.js";
10
+ import { resolveRadius } from "./foundation/radius.js";
8
11
  import { ListBox } from "./list-box.js";
9
12
  import { PopoverContent } from "./popover.js";
10
13
  import { ScrollArea } from "./scroll-area.js";
11
- /** A searchable single-selection field whose query filters string-valued options. */
12
- export const ComboBox = forwardRef(function ComboBox({ label, description, errorMessage, disabled = false, readOnly = false, required = false, invalid = false, options, value, defaultValue, onChange, inputValue, defaultInputValue, onInputChange, placeholder, size = "medium", color, radius = "medium", style, material, shadow, ...properties }, ref) {
13
- const theme = useControlTheme({ size, color, radius });
14
+ import { Chevron } from "./select.js";
15
+ import { dimmedClass } from "./surface/surface.js";
16
+ /** A searchable single-choice field whose options are its Items. */
17
+ const ComboBoxRoot = forwardRef(function ComboBox({ label, description, errorMessage, disabled = false, readOnly = false, required = false, invalid = false, children, value, defaultValue, onChange, inputValue, defaultInputValue, onInputChange, placeholder, size, color = "background", radius, style, className, material, onOpenChange, openWhenEmpty, focusWrap, ...properties }, ref) {
18
+ const metrics = useControlMetrics(size, radius);
19
+ // The list shell keeps the Appearance radius at the chosen level.
20
+ const shell = resolveRadius(radius ?? "medium", metrics.visual.radius);
14
21
  const direction = resolveDirection(properties.dir, useDirection());
15
- const disabledValues = useMemo(() => options.filter(option => option.disabled).map(option => option.value), [options]);
16
- return _jsx(AriaComboBox, { ...properties, ref: ref, dir: direction, value: value, defaultValue: defaultValue, onChange: key => onChange?.(key == null ? null : String(key)), inputValue: inputValue, defaultInputValue: defaultInputValue, onInputChange: onInputChange, isDisabled: disabled, isReadOnly: readOnly, isRequired: required, isInvalid: invalid, style: fieldStyle(theme, disabled, style), children: state => _jsxs(_Fragment, { children: [_jsx(FieldStyle, {}), _jsx(FieldLabel, { label: label }), _jsx(Group, { style: group => ({
17
- position: "relative",
18
- minWidth: 0,
19
- height: theme.height,
20
- borderRadius: theme.radius,
21
- outline: group.isFocusVisible ? `1px solid ${theme.focusColor}` : "none",
22
- outlineOffset: 1
23
- }), children: group => _jsxs(SurfaceField, { material: material, shadow: shadow, radius: theme.radius, paint: controlPaint(theme, group.isFocusWithin, group.isInvalid, group.isHovered), style: {
24
- position: "absolute",
25
- inset: 0,
26
- gridTemplateColumns: "minmax(0, 1fr) auto"
27
- }, children: [_jsx(AriaInput, { className: textControlClass, placeholder: placeholder, style: {
28
- appearance: "none",
29
- boxSizing: "border-box",
30
- width: "100%",
31
- minWidth: 0,
32
- height: theme.height,
33
- paddingBlock: 0,
34
- paddingInlineStart: Math.max(8, theme.spacing),
35
- paddingInlineEnd: theme.gap,
36
- border: 0,
37
- borderRadius: "inherit",
38
- outline: "none",
39
- background: "transparent",
40
- color: "inherit",
41
- caretColor: "currentColor",
42
- font: "inherit",
43
- lineHeight: 1.5
44
- } }), _jsx(Button, { "aria-label": "Show options", style: {
45
- ...theme.transition,
46
- display: "grid",
47
- placeItems: "center",
48
- width: theme.height,
49
- height: theme.height,
50
- padding: 0,
51
- border: 0,
52
- borderRadius: "inherit",
53
- outline: "none",
54
- background: "transparent",
55
- color: "inherit",
56
- cursor: disabled || readOnly ? "default" : "pointer"
57
- }, children: _jsx("svg", { "aria-hidden": "true", width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: {
58
- ...theme.transition,
59
- transitionProperty: "transform",
60
- transform: `rotate(${state.isOpen ? 180 : 0}deg)`
61
- }, children: _jsx("path", { d: "m2 4 4 4 4-4" }) }) })] }) }), _jsx(PopoverContent, { dir: direction, placement: "bottom start", offset: theme.gap, style: {
22
+ return _jsx(AriaComboBox, { ...properties, onOpenChange: onOpenChange === undefined ? undefined : open => onOpenChange(open), allowsEmptyCollection: openWhenEmpty, shouldFocusWrap: focusWrap, ref: ref, dir: direction, ...(value !== undefined ? { value } : {}), ...(defaultValue !== undefined ? { defaultValue } : {}), onChange: key => onChange?.(key == null ? null : String(key)), inputValue: inputValue, defaultInputValue: defaultInputValue, onInputChange: onInputChange, isDisabled: disabled, isReadOnly: readOnly, isRequired: required, isInvalid: invalid, className: dimmedClass(disabled, className), style: fieldStyle(metrics, style), children: state => _jsxs(_Fragment, { children: [_jsx(MotionStyle, {}), _jsx(FieldLabel, { label: label }), _jsxs(Group, { render: surfaceRender("div", group => ({
23
+ color,
24
+ depth: "recessed",
25
+ material,
26
+ radius: metrics.radius,
27
+ interaction: { hovered: group.isHovered, focusVisible: group.isFocusWithin, invalid: group.isInvalid, disabled: group.isDisabled }
28
+ })), style: { display: "grid", gridTemplateColumns: "minmax(0, 1fr) auto", alignItems: "center", minWidth: 0, height: metrics.height }, children: [_jsx(AriaInput, { className: textControlClass, placeholder: placeholder, style: { ...nativeTextStyle(metrics, false), paddingInlineEnd: metrics.gap } }), _jsx(AriaButton, { "aria-label": "Show options", style: {
29
+ display: "grid",
30
+ placeItems: "center",
31
+ width: metrics.height,
32
+ height: metrics.height,
33
+ padding: 0,
34
+ border: 0,
35
+ borderRadius: "inherit",
36
+ outline: "none",
37
+ background: "transparent",
38
+ color: "inherit",
39
+ cursor: disabled || readOnly ? "default" : "pointer"
40
+ }, children: _jsx(Chevron, { metrics: metrics, open: state.isOpen }) })] }), _jsx(PopoverContent, { dir: direction, placement: "bottom start", offset: metrics.gap, radius: shell, style: {
62
41
  width: "var(--trigger-width)",
63
- maxHeight: `min(calc(100vh - ${theme.spacing * 2}px), ${theme.height * 8}px)`,
42
+ maxHeight: `min(calc(100vh - ${metrics.spacing * 2}px), ${metrics.height * 8}px)`,
64
43
  padding: 0,
65
44
  display: "flex",
66
45
  flexDirection: "column"
67
- }, children: _jsx(ScrollArea, { style: { flex: "1 1 auto", minHeight: 0 }, children: _jsx(ListBox, { color: color, radius: radius, size: size, disabledValues: disabledValues, children: options.map(option => _jsx(ListBox.Item, { id: option.value, textValue: option.label, disabled: option.disabled, children: option.label }, option.value)) }) }) }), _jsx(FieldFeedback, { theme: theme, description: description, errorMessage: errorMessage })] }) });
46
+ }, children: _jsx(ScrollArea, { style: { flex: "1 1 auto", minHeight: 0 }, children: _jsx(ListBox, { size: size, children: children }) }) }), _jsx(FieldFeedback, { metrics: metrics, description: description, errorMessage: errorMessage })] }) });
47
+ });
48
+ /** A searchable single-choice field whose options are its Items. */
49
+ export const ComboBox = Object.assign(ComboBoxRoot, {
50
+ Item: ListBox.Item,
51
+ Section: ListBox.Section,
52
+ Header: ListBox.Header
68
53
  });
@@ -1,20 +1,24 @@
1
1
  import type { ComponentProps } from "react";
2
2
  import { Pressable as AriaPressable } from "react-aria-components";
3
- import type { MenuTriggerProps as AriaMenuTriggerProps } from "react-aria-components";
3
+ import { type OverlayRootProps } from "./control/open-state.js";
4
4
  import { type PopoverContentProps } from "./popover.js";
5
- export type ContextMenuRootProps = Omit<AriaMenuTriggerProps, "trigger">;
6
- export declare function ContextMenuRoot(properties: ContextMenuRootProps): import("react").JSX.Element;
7
- export type ContextMenuTriggerProps = ComponentProps<typeof AriaPressable>;
8
- export declare const ContextMenuTrigger: import("react").ForwardRefExoticComponent<Omit<import("react-aria").PressableProps & import("react").RefAttributes<import("@react-types/shared").FocusableElement>, "ref"> & import("react").RefAttributes<import("@react-types/shared").FocusableElement>>;
9
- export type ContextMenuContentProps = Omit<PopoverContentProps, "isNonModal">;
10
- export declare const ContextMenuContent: import("react").ForwardRefExoticComponent<ContextMenuContentProps & import("react").RefAttributes<HTMLElement>>;
5
+ export type ContextMenuRootProps = OverlayRootProps;
6
+ export declare function ContextMenuRoot({ children, ...state }: ContextMenuRootProps): import("react").JSX.Element;
7
+ /** The element that opens the menu when it is right-clicked or long-pressed. */
8
+ export interface ContextMenuTriggerProps {
9
+ readonly children: ComponentProps<typeof AriaPressable>["children"];
10
+ readonly disabled?: boolean;
11
+ }
12
+ export declare const ContextMenuTrigger: import("react").ForwardRefExoticComponent<ContextMenuTriggerProps & import("react").RefAttributes<import("@react-types/shared").FocusableElement>>;
13
+ export type ContextMenuContentProps = PopoverContentProps;
14
+ export declare const ContextMenuContent: import("react").ForwardRefExoticComponent<PopoverContentProps & import("react").RefAttributes<HTMLElement>>;
11
15
  /** A context-requested overlay sharing the same Menu contract as DropdownMenu. */
12
16
  export declare const ContextMenu: typeof ContextMenuRoot & {
13
- Trigger: import("react").ForwardRefExoticComponent<Omit<import("react-aria").PressableProps & import("react").RefAttributes<import("@react-types/shared").FocusableElement>, "ref"> & import("react").RefAttributes<import("@react-types/shared").FocusableElement>>;
14
- Content: import("react").ForwardRefExoticComponent<ContextMenuContentProps & import("react").RefAttributes<HTMLElement>>;
17
+ Trigger: import("react").ForwardRefExoticComponent<ContextMenuTriggerProps & import("react").RefAttributes<import("@react-types/shared").FocusableElement>>;
18
+ Content: import("react").ForwardRefExoticComponent<PopoverContentProps & import("react").RefAttributes<HTMLElement>>;
15
19
  Menu: import("./menu.js").MenuRootComponent & {
16
20
  Item: import("./menu.js").MenuItemComponent;
17
- Section: <T>(props: import("react-aria-components").MenuSectionProps<T> & React.RefAttributes<HTMLElement>) => import("react").ReactElement<unknown, string | React.JSXElementConstructor<any>> | null;
21
+ Section: <T extends object = object>(properties: import("./menu.js").MenuSectionProps<T>) => import("react").ReactElement | null;
18
22
  Header: import("react").ForwardRefExoticComponent<import("react-aria-components").HeaderProps & import("react").RefAttributes<HTMLElement>>;
19
23
  Separator: import("react").ForwardRefExoticComponent<import("react-aria-components").SeparatorProps & import("react").RefAttributes<HTMLElement>>;
20
24
  };
@@ -1,13 +1,14 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { forwardRef, useCallback, useContext, useEffect, useRef } from "react";
3
3
  import { MenuTrigger as AriaMenuTrigger, OverlayTriggerStateContext, Pressable as AriaPressable } from "react-aria-components";
4
+ import { ariaOpenState } from "./control/open-state.js";
4
5
  import { Menu } from "./menu.js";
5
- import { PopoverContent } from "./popover.js";
6
- export function ContextMenuRoot(properties) {
7
- return _jsx(AriaMenuTrigger, { ...properties, trigger: "contextMenu" });
6
+ import { MenuContent } from "./popover.js";
7
+ export function ContextMenuRoot({ children, ...state }) {
8
+ return _jsx(AriaMenuTrigger, { ...ariaOpenState(state), trigger: "contextMenu", children: children });
8
9
  }
9
- export const ContextMenuTrigger = forwardRef(function ContextMenuTrigger(properties, ref) {
10
- return _jsx(AriaPressable, { ...properties, ref: ref });
10
+ export const ContextMenuTrigger = forwardRef(function ContextMenuTrigger({ children, disabled }, ref) {
11
+ return _jsx(AriaPressable, { ref: ref, isDisabled: disabled, children: children });
11
12
  });
12
13
  function setRef(ref, value) {
13
14
  if (typeof ref === "function")
@@ -34,7 +35,7 @@ export const ContextMenuContent = forwardRef(function ContextMenuContent(propert
34
35
  document.addEventListener("pointerdown", dismiss, true);
35
36
  return () => document.removeEventListener("pointerdown", dismiss, true);
36
37
  }, [state]);
37
- return _jsx(PopoverContent, { ...properties, ref: ref, isNonModal: true });
38
+ return _jsx(MenuContent, { ...properties, ref: ref, nonModal: true });
38
39
  });
39
40
  /** A context-requested overlay sharing the same Menu contract as DropdownMenu. */
40
41
  export const ContextMenu = Object.assign(ContextMenuRoot, {
@@ -0,0 +1,13 @@
1
+ import { type ControlMetrics } from "./control.js";
2
+ /**
3
+ * The handle of a ColorSlider or ColorArea: the chosen color inside a ring of
4
+ * the light Appearance color, like every thumb, set apart from any gradient by
5
+ * a hairline in the dark Appearance color.
6
+ */
7
+ export declare function ColorThumb({ metrics, center }: Readonly<{
8
+ metrics: ControlMetrics;
9
+ /** The axis React Aria leaves unpositioned on a one-channel track. */
10
+ center?: "top" | "left";
11
+ }>): import("react").JSX.Element;
12
+ /** The edge that sets a color gradient apart from whatever it sits on. */
13
+ export declare function colorEdge(metrics: ControlMetrics): string;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ColorThumb as AriaColorThumb } from "react-aria-components";
3
+ import { colorOpacity, darkCanvas, lightColor } from "../foundation/color.js";
4
+ import { transition } from "./control.js";
5
+ /**
6
+ * The handle of a ColorSlider or ColorArea: the chosen color inside a ring of
7
+ * the light Appearance color, like every thumb, set apart from any gradient by
8
+ * a hairline in the dark Appearance color.
9
+ */
10
+ export function ColorThumb({ metrics, center }) {
11
+ const { colors } = metrics.visual;
12
+ const dark = darkCanvas(colors) ? colors.background : colors.foreground;
13
+ const size = metrics.indicator + 4;
14
+ return _jsx(AriaColorThumb, { style: ({ defaultStyle, isDragging, isFocusVisible, isDisabled }) => ({
15
+ ...defaultStyle,
16
+ ...transition(metrics.visual, "scale, outline-color"),
17
+ ...(center === undefined ? {} : { [center]: "50%" }),
18
+ boxSizing: "border-box",
19
+ width: size,
20
+ height: size,
21
+ borderRadius: "50%",
22
+ border: `3px solid ${lightColor(colors)}`,
23
+ boxShadow: `0 0 0 1px ${colorOpacity(dark, 0.3)}, 0 1px 3px ${colorOpacity(dark, 0.3)}`,
24
+ outline: `3px solid ${isFocusVisible ? colorOpacity(colors.primary, 0.34) : "transparent"}`,
25
+ outlineOffset: 1,
26
+ scale: isDragging ? "0.92" : "1",
27
+ cursor: isDisabled ? "not-allowed" : isDragging ? "grabbing" : "grab"
28
+ }) });
29
+ }
30
+ /** The edge that sets a color gradient apart from whatever it sits on. */
31
+ export function colorEdge(metrics) {
32
+ return `inset 0 0 0 1px ${colorOpacity(metrics.visual.colors.foreground, 0.12)}`;
33
+ }
@@ -0,0 +1,6 @@
1
+ import type { Color as AriaColor } from "react-aria-components";
2
+ /**
3
+ * How React UI exchanges a color value: a hex string, with an alpha pair only
4
+ * when the color is translucent. React Aria's Color objects stay internal.
5
+ */
6
+ export declare function colorValue(color: AriaColor): string;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * How React UI exchanges a color value: a hex string, with an alpha pair only
3
+ * when the color is translucent. React Aria's Color objects stay internal.
4
+ */
5
+ export function colorValue(color) {
6
+ return color.getChannelValue("alpha") < 1 ? color.toString("hexa") : color.toString("hex");
7
+ }