@phreshos/react-ui 0.1.41 → 0.1.43
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/alert.js +5 -4
- package/dist/app-layout.js +2 -1
- package/dist/badge.js +2 -2
- package/dist/breadcrumbs.js +2 -2
- package/dist/calendar-layout.js +2 -2
- package/dist/color-slider.js +2 -2
- package/dist/control/control.d.ts +4 -0
- package/dist/control/control.js +4 -0
- package/dist/control/field.d.ts +2 -0
- package/dist/control/field.js +5 -3
- package/dist/control/text-control.js +2 -1
- package/dist/dialog.js +5 -2
- package/dist/disclosure.js +2 -2
- package/dist/foundation/spacing.d.ts +6 -0
- package/dist/foundation/spacing.js +8 -0
- package/dist/grid-list.d.ts +53 -0
- package/dist/grid-list.js +95 -0
- package/dist/list-box.js +2 -2
- package/dist/main.d.ts +2 -0
- package/dist/main.js +2 -0
- package/dist/panel.js +2 -1
- package/dist/radio.js +3 -3
- package/dist/segmented-control.js +3 -3
- package/dist/select.js +2 -2
- package/dist/slider.js +2 -2
- package/dist/snippet.d.ts +22 -0
- package/dist/snippet.js +60 -0
- package/dist/table.js +2 -2
- package/dist/toast.js +6 -4
- package/dist/typography.d.ts +1 -0
- package/dist/typography.js +3 -4
- package/package.json +2 -2
package/dist/alert.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
|
-
import { controlFontSizes, controlFontWeight, useControlMetrics } from "./control/control.js";
|
|
3
|
+
import { controlFontSizes, controlFontWeight, useControlMetrics, controlLineHeight } from "./control/control.js";
|
|
4
4
|
import { iconProps } from "./control/icon.js";
|
|
5
5
|
import { meaningIcon, urgentMeaning } from "./control/meaning.js";
|
|
6
6
|
import { colorLevel, resolveColor } from "./foundation/color.js";
|
|
7
7
|
import { resolveRadius } from "./foundation/radius.js";
|
|
8
8
|
import { Surface } from "./surface/surface.js";
|
|
9
|
+
import { containerPadding } from "./foundation/spacing.js";
|
|
9
10
|
/**
|
|
10
11
|
* A message that stays in place, such as a failed save. It is painted in the
|
|
11
12
|
* subtle level of its color, like a selection, and leads with the icon of its
|
|
@@ -21,9 +22,9 @@ export const Alert = forwardRef(function Alert({ color = "info", title, icon, ch
|
|
|
21
22
|
gridTemplateColumns: icon === false ? "minmax(0, 1fr)" : "auto minmax(0, 1fr)",
|
|
22
23
|
alignItems: "start",
|
|
23
24
|
gap: metrics.gap * 2,
|
|
24
|
-
padding: metrics.spacing,
|
|
25
|
+
padding: containerPadding(metrics.visual.spacing),
|
|
25
26
|
fontSize: controlFontSizes.medium,
|
|
26
|
-
lineHeight:
|
|
27
|
+
lineHeight: controlLineHeight,
|
|
27
28
|
...style
|
|
28
|
-
}, children: [icon !== false && _jsx("span", { style: { display: "grid", height:
|
|
29
|
+
}, children: [icon !== false && _jsx("span", { style: { display: "grid", height: `${controlLineHeight}em`, alignItems: "center" }, children: icon ?? _jsx(MeaningIcon, { ...iconProps(16) }) }), _jsxs("div", { style: { display: "grid", gap: 2, minWidth: 0 }, children: [title != null && _jsx("strong", { style: { fontWeight: controlFontWeight }, children: title }), children != null && _jsx("div", { children: children })] })] });
|
|
29
30
|
});
|
package/dist/app-layout.js
CHANGED
|
@@ -7,6 +7,7 @@ import { scale } from "./foundation/scale.js";
|
|
|
7
7
|
import { useVisual } from "./foundation/visual.js";
|
|
8
8
|
import { ScrollArea } from "./scroll-area.js";
|
|
9
9
|
import { Surface } from "./surface/surface.js";
|
|
10
|
+
import { containerPadding } from "./foundation/spacing.js";
|
|
10
11
|
const AppLayoutContext = createContext(false);
|
|
11
12
|
/**
|
|
12
13
|
* The frame of a program's interface: a title above a sidebar, and a header,
|
|
@@ -81,7 +82,7 @@ const AppLayoutContent = forwardRef(function AppLayoutContent({ children, style,
|
|
|
81
82
|
// The Surface owns its shape: what scrolls inside stays within its corners.
|
|
82
83
|
overflow: "clip",
|
|
83
84
|
...style
|
|
84
|
-
}, children: _jsx(ScrollArea, { style: { height: "100%" }, children: _jsx("div", { style: { padding: spacing }, children: children }) }) });
|
|
85
|
+
}, children: _jsx(ScrollArea, { style: { height: "100%" }, children: _jsx("div", { style: { padding: containerPadding(spacing) }, children: children }) }) });
|
|
85
86
|
});
|
|
86
87
|
/** An optional row below the content, such as the actions that apply to it. */
|
|
87
88
|
const AppLayoutFooter = forwardRef(function AppLayoutFooter({ style, ...properties }, ref) {
|
package/dist/badge.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
|
-
import { controlFontSizes, controlFontWeight, useControlMetrics } from "./control/control.js";
|
|
3
|
+
import { controlFontSizes, controlFontWeight, useControlMetrics, controlLineHeight } from "./control/control.js";
|
|
4
4
|
import { colorLevel, resolveColor } from "./foundation/color.js";
|
|
5
5
|
import { Surface } from "./surface/surface.js";
|
|
6
6
|
const smaller = Object.freeze({ xsmall: "xsmall", small: "xsmall", medium: "small", large: "medium", xlarge: "large" });
|
|
@@ -23,7 +23,7 @@ export const Badge = forwardRef(function Badge({ children, color = "foreground",
|
|
|
23
23
|
color: colorLevel(base, "strong", colors),
|
|
24
24
|
fontSize: controlFontSizes[smaller[size ?? "medium"]],
|
|
25
25
|
fontWeight: controlFontWeight,
|
|
26
|
-
lineHeight:
|
|
26
|
+
lineHeight: controlLineHeight,
|
|
27
27
|
whiteSpace: "nowrap",
|
|
28
28
|
verticalAlign: "middle",
|
|
29
29
|
...style
|
package/dist/breadcrumbs.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import { createContext, forwardRef, useContext } from "react";
|
|
3
3
|
import { Breadcrumb as AriaBreadcrumb, Breadcrumbs as AriaBreadcrumbs, Link as AriaLink } from "react-aria-components";
|
|
4
4
|
import { ChevronRight } from "lucide-react";
|
|
5
|
-
import { controlFontWeight, controlOpacity, transition, useControlMetrics } from "./control/control.js";
|
|
5
|
+
import { controlFontWeight, controlOpacity, transition, useControlMetrics, controlLineHeight } from "./control/control.js";
|
|
6
6
|
import { iconProps } from "./control/icon.js";
|
|
7
7
|
import { surfacePaint } from "./surface/surface.js";
|
|
8
8
|
const BreadcrumbsContext = createContext(null);
|
|
@@ -18,7 +18,7 @@ const BreadcrumbsRoot = forwardRef(function Breadcrumbs({ children, size, style,
|
|
|
18
18
|
padding: 0,
|
|
19
19
|
listStyle: "none",
|
|
20
20
|
fontSize: metrics.fontSize,
|
|
21
|
-
lineHeight:
|
|
21
|
+
lineHeight: controlLineHeight,
|
|
22
22
|
...style
|
|
23
23
|
}, children: children }) });
|
|
24
24
|
});
|
package/dist/calendar-layout.js
CHANGED
|
@@ -3,7 +3,7 @@ import { useContext } from "react";
|
|
|
3
3
|
import { isSameDay } from "@internationalized/date";
|
|
4
4
|
import { CalendarCell, CalendarGrid, CalendarGridBody, CalendarGridHeader, CalendarHeaderCell, CalendarHeading, CalendarStateContext, RangeCalendarStateContext } from "react-aria-components";
|
|
5
5
|
import { Button } from "./button.js";
|
|
6
|
-
import { controlFontWeight, controlOpacity, transition } from "./control/control.js";
|
|
6
|
+
import { controlFontWeight, controlOpacity, transition, controlLineHeight } from "./control/control.js";
|
|
7
7
|
import { selectionColor } from "./control/item.js";
|
|
8
8
|
import { colorOpacity, readableColor, resolveColor } from "./foundation/color.js";
|
|
9
9
|
import { useDirection } from "./foundation/direction.js";
|
|
@@ -28,7 +28,7 @@ export function calendarRootStyle(metrics, style) {
|
|
|
28
28
|
padding: metrics.spacing,
|
|
29
29
|
fontFamily: "inherit",
|
|
30
30
|
fontSize: metrics.fontSize,
|
|
31
|
-
lineHeight:
|
|
31
|
+
lineHeight: controlLineHeight
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
/**
|
package/dist/color-slider.js
CHANGED
|
@@ -4,7 +4,7 @@ import { ColorSlider as AriaColorSlider, Label, SliderOutput, SliderTrack } from
|
|
|
4
4
|
import { colorEdge, ColorThumb } from "./control/color-thumb.js";
|
|
5
5
|
import { colorValue } from "./control/color-value.js";
|
|
6
6
|
import { controlFontWeight, controlOpacity, useControlMetrics } from "./control/control.js";
|
|
7
|
-
import { fieldStyle } from "./control/field.js";
|
|
7
|
+
import { fieldStyle, descriptionStyle } from "./control/field.js";
|
|
8
8
|
import { AriaDirectionBoundary } from "./foundation/aria-direction.js";
|
|
9
9
|
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
10
10
|
import { dimmedClass } from "./surface/surface.js";
|
|
@@ -25,5 +25,5 @@ export const ColorSlider = forwardRef(function ColorSlider({ label, description,
|
|
|
25
25
|
// A track is round by its form.
|
|
26
26
|
borderRadius: 9999,
|
|
27
27
|
boxShadow: colorEdge(metrics)
|
|
28
|
-
}), children: _jsx(ColorThumb, { metrics: metrics, center: vertical ? "left" : "top" }) }), description != null && _jsx("span", { style:
|
|
28
|
+
}), children: _jsx(ColorThumb, { metrics: metrics, center: vertical ? "left" : "top" }) }), description != null && _jsx("span", { style: descriptionStyle, children: description })] }) });
|
|
29
29
|
});
|
|
@@ -29,6 +29,10 @@ export type ControlOverrides = keyof ControlProps | keyof FieldProps | "children
|
|
|
29
29
|
export declare const controlFontSizes: Readonly<Record<ScaleLevel, string>>;
|
|
30
30
|
/** A control text size relative to an element that already applies another level. */
|
|
31
31
|
export declare function relativeFontSize(level: ScaleLevel, within: ScaleLevel): string;
|
|
32
|
+
/** Secondary text, such as a description or a section header, reads a step smaller than its control. */
|
|
33
|
+
export declare const secondaryFontSize = "0.92em";
|
|
34
|
+
/** The line height of text in controls and the Surfaces around them. */
|
|
35
|
+
export declare const controlLineHeight = 1.45;
|
|
32
36
|
export declare const controlFontWeight = 600;
|
|
33
37
|
/** Attenuation shared by every control family. */
|
|
34
38
|
export declare const controlOpacity: Readonly<{
|
package/dist/control/control.js
CHANGED
|
@@ -14,6 +14,10 @@ export const controlFontSizes = Object.freeze({
|
|
|
14
14
|
export function relativeFontSize(level, within) {
|
|
15
15
|
return `${Number.parseFloat(controlFontSizes[level]) / Number.parseFloat(controlFontSizes[within])}em`;
|
|
16
16
|
}
|
|
17
|
+
/** Secondary text, such as a description or a section header, reads a step smaller than its control. */
|
|
18
|
+
export const secondaryFontSize = "0.92em";
|
|
19
|
+
/** The line height of text in controls and the Surfaces around them. */
|
|
20
|
+
export const controlLineHeight = 1.45;
|
|
17
21
|
export const controlFontWeight = 600;
|
|
18
22
|
/** Attenuation shared by every control family. */
|
|
19
23
|
export const controlOpacity = Object.freeze({
|
package/dist/control/field.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export declare function fieldStyle(metrics: ControlMetrics, style?: CSSPropertie
|
|
|
8
8
|
export declare function FieldLabel({ label }: Readonly<{
|
|
9
9
|
label?: ReactNode;
|
|
10
10
|
}>): import("react").JSX.Element | null;
|
|
11
|
+
/** The treatment of a control's description: a little smaller and quieter than its label. */
|
|
12
|
+
export declare const descriptionStyle: CSSProperties;
|
|
11
13
|
/** Description and validation text shared by every field. */
|
|
12
14
|
export declare function FieldFeedback({ description, errorMessage, metrics }: Readonly<{
|
|
13
15
|
description?: ReactNode;
|
package/dist/control/field.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { FieldError, Label, Text } from "react-aria-components";
|
|
3
3
|
import { colorOpacity, mixColor } from "../foundation/color.js";
|
|
4
|
-
import { controlFontWeight, controlOpacity } from "./control.js";
|
|
4
|
+
import { controlFontWeight, controlOpacity, controlLineHeight, secondaryFontSize } from "./control.js";
|
|
5
5
|
/**
|
|
6
6
|
* The root of every value-holding component. It is the only element that
|
|
7
7
|
* applies the control text scale; every part inherits from it.
|
|
@@ -14,17 +14,19 @@ export function fieldStyle(metrics, style) {
|
|
|
14
14
|
minWidth: 0,
|
|
15
15
|
fontFamily: "inherit",
|
|
16
16
|
fontSize: metrics.fontSize,
|
|
17
|
-
lineHeight:
|
|
17
|
+
lineHeight: controlLineHeight,
|
|
18
18
|
...style
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
export function FieldLabel({ label }) {
|
|
22
22
|
return label == null ? null : _jsx(Label, { style: { fontWeight: controlFontWeight }, children: label });
|
|
23
23
|
}
|
|
24
|
+
/** The treatment of a control's description: a little smaller and quieter than its label. */
|
|
25
|
+
export const descriptionStyle = Object.freeze({ fontSize: secondaryFontSize, opacity: controlOpacity.secondary });
|
|
24
26
|
/** Description and validation text shared by every field. */
|
|
25
27
|
export function FieldFeedback({ description, errorMessage, metrics }) {
|
|
26
28
|
const { colors } = metrics.visual;
|
|
27
|
-
return _jsxs(_Fragment, { children: [description != null && _jsx(Text, { slot: "description", style:
|
|
29
|
+
return _jsxs(_Fragment, { children: [description != null && _jsx(Text, { slot: "description", style: descriptionStyle, children: description }), _jsx(FieldError, { style: { fontSize: descriptionStyle.fontSize, color: mixColor(colors.danger, colors.foreground, 0.15) }, children: errorMessage })] });
|
|
28
30
|
}
|
|
29
31
|
/** How strongly every separator shows its text color. */
|
|
30
32
|
export const separatorOpacity = 0.1;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { SurfaceView } from "../surface/surface.js";
|
|
3
|
+
import { controlLineHeight } from "./control.js";
|
|
3
4
|
/**
|
|
4
5
|
* The recessed well that holds typed content. Native text elements cannot host
|
|
5
6
|
* Surface layers, so the well wraps the element that React Aria renders.
|
|
@@ -25,7 +26,7 @@ export function nativeTextStyle(metrics, multiline) {
|
|
|
25
26
|
color: "inherit",
|
|
26
27
|
caretColor: "currentColor",
|
|
27
28
|
font: "inherit",
|
|
28
|
-
lineHeight:
|
|
29
|
+
lineHeight: controlLineHeight,
|
|
29
30
|
resize: multiline ? "vertical" : undefined
|
|
30
31
|
};
|
|
31
32
|
}
|
package/dist/dialog.js
CHANGED
|
@@ -8,6 +8,7 @@ import { colorOpacity, darkCanvas } from "./foundation/color.js";
|
|
|
8
8
|
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
9
9
|
import MotionStyle, { backdropMotionClass, overlayLayer, overlayMotionClass, overlayTransition } from "./foundation/motion-style.js";
|
|
10
10
|
import { scale } from "./foundation/scale.js";
|
|
11
|
+
import { containerPadding } from "./foundation/spacing.js";
|
|
11
12
|
import { useVisual } from "./foundation/visual.js";
|
|
12
13
|
import { floatingShadow } from "./surface/shadow-options.js";
|
|
13
14
|
import { Surface } from "./surface/surface.js";
|
|
@@ -49,6 +50,7 @@ export const DialogBackdrop = forwardRef(function DialogBackdrop({ children, cla
|
|
|
49
50
|
export const DialogContent = forwardRef(function DialogContent({ children, className, color, material, radius, shadow, style, ...properties }, ref) {
|
|
50
51
|
const visual = useVisual();
|
|
51
52
|
const inset = scale(visual.spacing, "medium");
|
|
53
|
+
const padding = containerPadding(visual.spacing);
|
|
52
54
|
const transition = overlayTransition(visual);
|
|
53
55
|
const direction = resolveDirection(properties.dir, useDirection());
|
|
54
56
|
return _jsxs(_Fragment, { children: [_jsx(MotionStyle, {}), _jsx(AriaModal, { dir: direction, className: overlayMotionClass, style: {
|
|
@@ -63,7 +65,7 @@ export const DialogContent = forwardRef(function DialogContent({ children, class
|
|
|
63
65
|
boxSizing: "border-box",
|
|
64
66
|
width: "100%",
|
|
65
67
|
maxHeight: "inherit",
|
|
66
|
-
padding
|
|
68
|
+
padding,
|
|
67
69
|
overflow: "hidden",
|
|
68
70
|
...style
|
|
69
71
|
}, children: _jsx(AriaDialog, { ...properties, ref: ref, style: {
|
|
@@ -82,10 +84,11 @@ export const DialogHeader = forwardRef(function DialogHeader({ style, ...propert
|
|
|
82
84
|
export const DialogTitle = forwardRef(function DialogTitle({ style, ...properties }, ref) {
|
|
83
85
|
// The modal is portalled: owned text parts set their relative scale directly,
|
|
84
86
|
// while Dialog.Body remains untouched for consumer-owned content and controls.
|
|
87
|
+
// One level above the description and the content, so the title leads them.
|
|
85
88
|
return _jsx(AriaHeading, { ...properties, ref: ref, slot: "title", style: {
|
|
86
89
|
margin: 0,
|
|
87
90
|
fontFamily: "inherit",
|
|
88
|
-
fontSize: controlFontSizes.
|
|
91
|
+
fontSize: controlFontSizes.large,
|
|
89
92
|
fontWeight: controlFontWeight,
|
|
90
93
|
lineHeight: 1.5,
|
|
91
94
|
...style
|
package/dist/disclosure.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, forwardRef, useContext, useMemo } from "react";
|
|
3
3
|
import { Button as AriaButton, Disclosure as AriaDisclosure, DisclosurePanel as AriaDisclosurePanel, DisclosureStateContext } from "react-aria-components";
|
|
4
|
-
import { transition, useControlMetrics } from "./control/control.js";
|
|
4
|
+
import { transition, useControlMetrics, controlLineHeight } from "./control/control.js";
|
|
5
5
|
import { surfaceRender } from "./control/surface-render.js";
|
|
6
6
|
import { resolveSpacing } from "./foundation/spacing.js";
|
|
7
7
|
import { ChevronDown } from "lucide-react";
|
|
@@ -39,7 +39,7 @@ export const DisclosureTrigger = forwardRef(function DisclosureTrigger({ childre
|
|
|
39
39
|
cursor: "pointer",
|
|
40
40
|
font: "inherit",
|
|
41
41
|
fontWeight: 500,
|
|
42
|
-
lineHeight:
|
|
42
|
+
lineHeight: controlLineHeight,
|
|
43
43
|
textAlign: "start",
|
|
44
44
|
userSelect: "none",
|
|
45
45
|
WebkitTapHighlightColor: "transparent",
|
|
@@ -9,3 +9,9 @@ export type Spacing = ScaleLevel | number | (string & {});
|
|
|
9
9
|
*/
|
|
10
10
|
export declare function resolveSpacing(value: ScaleLevel, spacing: number): number;
|
|
11
11
|
export declare function resolveSpacing(value: Spacing | undefined, spacing: number): CSSProperties["gap"];
|
|
12
|
+
/**
|
|
13
|
+
* The padding of a Surface that holds content, such as a dialog, a panel's
|
|
14
|
+
* content, or an alert: one level above the spacing a control pads with, so a
|
|
15
|
+
* container never wraps its content as tightly as a button wraps its label.
|
|
16
|
+
*/
|
|
17
|
+
export declare function containerPadding(spacing: number): number;
|
|
@@ -2,3 +2,11 @@ import { isScaleLevel, scale } from "./scale.js";
|
|
|
2
2
|
export function resolveSpacing(value, spacing) {
|
|
3
3
|
return isScaleLevel(value) ? scale(spacing, value) : value;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* The padding of a Surface that holds content, such as a dialog, a panel's
|
|
7
|
+
* content, or an alert: one level above the spacing a control pads with, so a
|
|
8
|
+
* container never wraps its content as tightly as a button wraps its label.
|
|
9
|
+
*/
|
|
10
|
+
export function containerPadding(spacing) {
|
|
11
|
+
return scale(spacing, "large");
|
|
12
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement, RefAttributes } from "react";
|
|
2
|
+
import type { GridListHeaderProps as AriaGridListHeaderProps, GridListItemProps as AriaGridListItemProps, GridListProps as AriaGridListProps, GridListSectionProps as AriaGridListSectionProps } from "react-aria-components";
|
|
3
|
+
import { type MultipleSelectionProps, type MultipleStringSelection, type NoSelectionProps, type SingleStringSelectionProps } from "./control/selection.js";
|
|
4
|
+
import type { Color } from "./foundation/color.js";
|
|
5
|
+
import type { RadiusProps } from "./foundation/radius.js";
|
|
6
|
+
import type { ScaleLevel } from "./foundation/scale.js";
|
|
7
|
+
type GridListRootBaseProps<T extends object> = Omit<AriaGridListProps<T>, "className" | "defaultSelectedKeys" | "disabledKeys" | "layout" | "onSelectionChange" | "selectedKeys" | "selectionMode" | "style"> & RadiusProps & Readonly<{
|
|
8
|
+
className?: string;
|
|
9
|
+
/** Color laid beneath selected Items. */
|
|
10
|
+
color?: Color;
|
|
11
|
+
/** The narrowest an Item may be; the grid fits as many columns as that allows. Sixteen times the spacing by default. */
|
|
12
|
+
itemWidth?: CSSProperties["width"];
|
|
13
|
+
size?: ScaleLevel;
|
|
14
|
+
style?: CSSProperties;
|
|
15
|
+
}>;
|
|
16
|
+
/** Cards to show only, such as the progress of work, with nothing to choose. */
|
|
17
|
+
export type GridListNoSelectionProps = NoSelectionProps;
|
|
18
|
+
export type GridListSingleSelectionProps = SingleStringSelectionProps & Readonly<{
|
|
19
|
+
selectionMode?: "single";
|
|
20
|
+
}>;
|
|
21
|
+
export type GridListMultipleValue = MultipleStringSelection;
|
|
22
|
+
export type GridListMultipleSelectionProps = MultipleSelectionProps;
|
|
23
|
+
/** A collection laid out as a grid of cards. Single selection is the default; `none` only shows them. */
|
|
24
|
+
export type GridListRootProps<T extends object = object> = GridListRootBaseProps<T> & (GridListNoSelectionProps | GridListSingleSelectionProps | GridListMultipleSelectionProps);
|
|
25
|
+
export type GridListRootComponent = <T extends object = object>(properties: GridListRootProps<T> & RefAttributes<HTMLDivElement>) => ReactElement | null;
|
|
26
|
+
export interface GridListItemProps<T = object> extends Omit<AriaGridListItemProps<T>, "className" | "id" | "isDisabled" | "render" | "style"> {
|
|
27
|
+
/** Identity of this Item within its collection. */
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly className?: string;
|
|
30
|
+
/** Color laid beneath this Item when it is selected. */
|
|
31
|
+
readonly color?: Color;
|
|
32
|
+
readonly disabled?: boolean;
|
|
33
|
+
readonly style?: CSSProperties;
|
|
34
|
+
}
|
|
35
|
+
export type GridListItemComponent = <T = object>(properties: GridListItemProps<T> & RefAttributes<HTMLDivElement>) => ReactElement | null;
|
|
36
|
+
export interface GridListSectionProps<T extends object = object> extends Omit<AriaGridListSectionProps<T>, "className" | "style"> {
|
|
37
|
+
readonly className?: string;
|
|
38
|
+
readonly style?: CSSProperties;
|
|
39
|
+
}
|
|
40
|
+
export type GridListSectionComponent = <T extends object = object>(properties: GridListSectionProps<T> & RefAttributes<HTMLDivElement>) => ReactElement | null;
|
|
41
|
+
export type GridListHeaderProps = Omit<AriaGridListHeaderProps, "style"> & Readonly<{
|
|
42
|
+
style?: CSSProperties;
|
|
43
|
+
}>;
|
|
44
|
+
/** A selectable grid of cards whose Items and Sections remain independently composable. */
|
|
45
|
+
export declare const GridList: GridListRootComponent & {
|
|
46
|
+
Item: GridListItemComponent;
|
|
47
|
+
Section: GridListSectionComponent;
|
|
48
|
+
Header: import("react").ForwardRefExoticComponent<Omit<AriaGridListHeaderProps, "style"> & Readonly<{
|
|
49
|
+
style?: CSSProperties;
|
|
50
|
+
}> & RefAttributes<HTMLDivElement>>;
|
|
51
|
+
};
|
|
52
|
+
export type GridListProps<T extends object = object> = GridListRootProps<T>;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, forwardRef, useContext, useMemo } from "react";
|
|
3
|
+
import { GridList as AriaGridList, GridListHeader as AriaGridListHeader, GridListItem as AriaGridListItem, GridListSection as AriaGridListSection } from "react-aria-components";
|
|
4
|
+
import { useControlMetrics } from "./control/control.js";
|
|
5
|
+
import { separatorColor } from "./control/field.js";
|
|
6
|
+
import { itemSurface, SelectionMark } from "./control/item.js";
|
|
7
|
+
import { ariaSelection } from "./control/selection.js";
|
|
8
|
+
import { surfaceRender } from "./control/surface-render.js";
|
|
9
|
+
import { AriaDirectionBoundary } from "./foundation/aria-direction.js";
|
|
10
|
+
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
11
|
+
import { collectionHeaderStyle } from "./list-box.js";
|
|
12
|
+
const GridListStyleContext = createContext(null);
|
|
13
|
+
const GridListRootImplementation = forwardRef(function GridList(properties, ref) {
|
|
14
|
+
const { className, color = "primary", defaultValue: _defaultValue, itemWidth, onChange: _onChange, radius, selectionMode: _selectionMode, size, style, value: _value, ...native } = properties;
|
|
15
|
+
const metrics = useControlMetrics(size, radius);
|
|
16
|
+
const width = itemWidth ?? metrics.visual.spacing * 16;
|
|
17
|
+
// As many columns as fit, each at least the Item width; a Section repeats the same columns.
|
|
18
|
+
const columns = `repeat(auto-fill, minmax(min(${typeof width === "number" ? `${width}px` : width}, 100%), 1fr))`;
|
|
19
|
+
const context = useMemo(() => ({ color, metrics, columns }), [color, metrics, columns]);
|
|
20
|
+
const direction = resolveDirection(native.dir, useDirection());
|
|
21
|
+
return _jsx(GridListStyleContext.Provider, { value: context, children: _jsx(AriaDirectionBoundary, { direction: direction, children: _jsx(AriaGridList, { ...native, ...ariaSelection(properties, "single"), ref: ref, dir: direction, layout: "grid", className: className, style: {
|
|
22
|
+
display: "grid",
|
|
23
|
+
gridTemplateColumns: columns,
|
|
24
|
+
gap: metrics.gap * 2,
|
|
25
|
+
minWidth: 0,
|
|
26
|
+
padding: metrics.listInset,
|
|
27
|
+
boxSizing: "border-box",
|
|
28
|
+
outline: "none",
|
|
29
|
+
fontFamily: "inherit",
|
|
30
|
+
fontSize: metrics.fontSize,
|
|
31
|
+
...style
|
|
32
|
+
} }) }) });
|
|
33
|
+
});
|
|
34
|
+
/** One card. It holds whatever it is given, shows its edge at rest, and a check in its corner when selected. */
|
|
35
|
+
const GridListItemImplementation = forwardRef(function GridListItem({ children, className, color, disabled = false, style, textValue, ...properties }, ref) {
|
|
36
|
+
const inherited = useGridListStyle();
|
|
37
|
+
const itemColor = color ?? inherited.color;
|
|
38
|
+
const { metrics } = inherited;
|
|
39
|
+
return _jsx(AriaGridListItem, { ...properties, ref: ref, textValue: textValue ?? (typeof children === "string" ? children : undefined), className: className, isDisabled: disabled, render: surfaceRender("div", state => itemSurface(metrics.visual, itemColor, {
|
|
40
|
+
selected: state.isSelected,
|
|
41
|
+
hovered: state.isHovered,
|
|
42
|
+
pressed: state.isPressed,
|
|
43
|
+
focusVisible: state.isFocusVisible,
|
|
44
|
+
disabled: state.isDisabled
|
|
45
|
+
}, metrics.radius)), style: {
|
|
46
|
+
position: "relative",
|
|
47
|
+
display: "grid",
|
|
48
|
+
alignContent: "start",
|
|
49
|
+
gap: metrics.gap,
|
|
50
|
+
minWidth: 0,
|
|
51
|
+
padding: metrics.inset,
|
|
52
|
+
boxSizing: "border-box",
|
|
53
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
54
|
+
userSelect: "none",
|
|
55
|
+
outlineOffset: -1,
|
|
56
|
+
...style
|
|
57
|
+
}, children: state => _jsxs(_Fragment, { children: [_jsx("span", { "aria-hidden": "true", style: {
|
|
58
|
+
position: "absolute",
|
|
59
|
+
inset: 0,
|
|
60
|
+
// The card's own radius: the edge sits inside the grid cell, not directly in the card.
|
|
61
|
+
borderRadius: metrics.radius,
|
|
62
|
+
border: `1px solid ${separatorColor(metrics)}`,
|
|
63
|
+
opacity: state.isSelected ? 0 : 1,
|
|
64
|
+
pointerEvents: "none"
|
|
65
|
+
} }), typeof children === "function" ? children(state) : children, _jsx("span", { style: { position: "absolute", insetBlockStart: metrics.inset, insetInlineEnd: metrics.inset, display: "flex" }, children: _jsx(SelectionMark, { visible: state.isSelected }) })] }) });
|
|
66
|
+
});
|
|
67
|
+
/** A Section spans the whole grid and lays its own Items out in the same columns. */
|
|
68
|
+
const GridListSectionImplementation = forwardRef(function GridListSection({ className, style, ...properties }, ref) {
|
|
69
|
+
const { metrics, columns } = useGridListStyle();
|
|
70
|
+
return _jsx(AriaGridListSection, { ...properties, ref: ref, className: className, style: {
|
|
71
|
+
gridColumn: "1 / -1",
|
|
72
|
+
display: "grid",
|
|
73
|
+
gridTemplateColumns: columns,
|
|
74
|
+
gap: metrics.gap * 2,
|
|
75
|
+
minWidth: 0,
|
|
76
|
+
...style
|
|
77
|
+
} });
|
|
78
|
+
});
|
|
79
|
+
/** A Section's heading, across the whole row. */
|
|
80
|
+
const GridListHeader = forwardRef(function GridListHeader({ style, ...properties }, ref) {
|
|
81
|
+
const { metrics } = useGridListStyle();
|
|
82
|
+
return _jsx(AriaGridListHeader, { ...properties, ref: ref, style: collectionHeaderStyle(metrics, { gridColumn: "1 / -1", paddingInline: 0, ...style }) });
|
|
83
|
+
});
|
|
84
|
+
function useGridListStyle() {
|
|
85
|
+
const context = useContext(GridListStyleContext);
|
|
86
|
+
if (context == null)
|
|
87
|
+
throw new Error("GridList parts must be used inside GridList");
|
|
88
|
+
return context;
|
|
89
|
+
}
|
|
90
|
+
/** A selectable grid of cards whose Items and Sections remain independently composable. */
|
|
91
|
+
export const GridList = Object.assign(GridListRootImplementation, {
|
|
92
|
+
Item: GridListItemImplementation,
|
|
93
|
+
Section: GridListSectionImplementation,
|
|
94
|
+
Header: GridListHeader
|
|
95
|
+
});
|
package/dist/list-box.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, forwardRef, useContext, useMemo } from "react";
|
|
3
3
|
import { Header as AriaHeader, ListBox as AriaListBox, ListBoxItem as AriaListBoxItem, ListBoxSection as AriaListBoxSection } from "react-aria-components";
|
|
4
|
-
import { controlFontWeight, controlOpacity, useControlMetrics } from "./control/control.js";
|
|
4
|
+
import { controlFontWeight, controlOpacity, useControlMetrics, secondaryFontSize } from "./control/control.js";
|
|
5
5
|
import { itemStyle, itemSurface, SelectionMark } from "./control/item.js";
|
|
6
6
|
import { ariaSelection } from "./control/selection.js";
|
|
7
7
|
import { surfaceRender } from "./control/surface-render.js";
|
|
@@ -52,7 +52,7 @@ export function collectionHeaderStyle(metrics, style) {
|
|
|
52
52
|
return {
|
|
53
53
|
paddingInline: metrics.inset,
|
|
54
54
|
paddingBlock: metrics.gap,
|
|
55
|
-
fontSize:
|
|
55
|
+
fontSize: secondaryFontSize,
|
|
56
56
|
fontWeight: controlFontWeight,
|
|
57
57
|
opacity: controlOpacity.secondary,
|
|
58
58
|
...style
|
package/dist/main.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ export { Switch, type SwitchProps } from "./switch.js";
|
|
|
32
32
|
export { Select, type SelectProps } from "./select.js";
|
|
33
33
|
export { ComboBox, type ComboBoxProps } from "./combo-box.js";
|
|
34
34
|
export { ListBox, type ListBoxProps, type ListBoxSingleSelectionProps, type ListBoxMultipleSelectionProps, type ListBoxMultipleValue, type ListBoxItemProps, type ListBoxSectionProps, type ListBoxHeaderProps } from "./list-box.js";
|
|
35
|
+
export { GridList, type GridListProps, type GridListNoSelectionProps, type GridListSingleSelectionProps, type GridListMultipleSelectionProps, type GridListMultipleValue, type GridListItemProps, type GridListSectionProps, type GridListHeaderProps } from "./grid-list.js";
|
|
35
36
|
export { Tabs, type TabsProps, type TabsListProps, type TabsTabProps, type TabsPanelsProps, type TabsPanelProps } from "./tabs.js";
|
|
36
37
|
export { Table, type TableProps, type TableNoSelectionProps, type TableSingleSelectionProps, type TableMultipleSelectionProps, type TableMultipleValue, type TableSort, type TableSortDirection, type TableHeaderProps, type TableColumnProps, type TableBodyProps, type TableRowProps, type TableCellProps } from "./table.js";
|
|
37
38
|
export { Tree, type TreeProps, type TreeNoSelectionProps, type TreeSingleSelectionProps, type TreeMultipleSelectionProps, type TreeMultipleValue, type TreeItemProps, type TreeContentProps, type TreeCollectionProps } from "./tree.js";
|
|
@@ -50,6 +51,7 @@ export { Breadcrumbs, type BreadcrumbsProps, type BreadcrumbsItemProps } from ".
|
|
|
50
51
|
export { Avatar, type AvatarProps } from "./avatar.js";
|
|
51
52
|
export { TagGroup, type TagGroupProps, type TagGroupTagProps } from "./tag-group.js";
|
|
52
53
|
export { Skeleton, type SkeletonProps } from "./skeleton.js";
|
|
54
|
+
export { Snippet, copyText, type SnippetProps } from "./snippet.js";
|
|
53
55
|
export { toast, ToastRegion, type ToastContent, type ToastOptions, type ToastRegionProps } from "./toast.js";
|
|
54
56
|
export { Readiness, useReadiness, useRequirement, type ReadinessProps, type ReadinessState, type Requirement } from "./readiness.js";
|
|
55
57
|
export { Loading, type LoadingProps } from "./loading.js";
|
package/dist/main.js
CHANGED
|
@@ -31,6 +31,7 @@ export { Switch } from "./switch.js";
|
|
|
31
31
|
export { Select } from "./select.js";
|
|
32
32
|
export { ComboBox } from "./combo-box.js";
|
|
33
33
|
export { ListBox } from "./list-box.js";
|
|
34
|
+
export { GridList } from "./grid-list.js";
|
|
34
35
|
export { Tabs } from "./tabs.js";
|
|
35
36
|
export { Table } from "./table.js";
|
|
36
37
|
export { Tree } from "./tree.js";
|
|
@@ -49,6 +50,7 @@ export { Breadcrumbs } from "./breadcrumbs.js";
|
|
|
49
50
|
export { Avatar } from "./avatar.js";
|
|
50
51
|
export { TagGroup } from "./tag-group.js";
|
|
51
52
|
export { Skeleton } from "./skeleton.js";
|
|
53
|
+
export { Snippet, copyText } from "./snippet.js";
|
|
52
54
|
export { toast, ToastRegion } from "./toast.js";
|
|
53
55
|
export { Readiness, useReadiness, useRequirement } from "./readiness.js";
|
|
54
56
|
export { Loading } from "./loading.js";
|
package/dist/panel.js
CHANGED
|
@@ -7,6 +7,7 @@ import { scale } from "./foundation/scale.js";
|
|
|
7
7
|
import { useVisual } from "./foundation/visual.js";
|
|
8
8
|
import { paintClass, usePaintClasses } from "./surface/paint-class.js";
|
|
9
9
|
import { Surface } from "./surface/surface.js";
|
|
10
|
+
import { containerPadding } from "./foundation/spacing.js";
|
|
10
11
|
const PanelContext = createContext({ color: undefined, hasHeader: false, radius: undefined });
|
|
11
12
|
export const PanelHeader = forwardRef(function PanelHeader({ style, ...properties }, ref) {
|
|
12
13
|
const { spacing } = useVisual();
|
|
@@ -40,7 +41,7 @@ export const PanelRoot = forwardRef(function Panel({ children, style, ...propert
|
|
|
40
41
|
export const PanelContent = forwardRef(function PanelContent({ className, style, ...properties }, ref) {
|
|
41
42
|
const { spacing } = useVisual();
|
|
42
43
|
const inset = scale(spacing, "small");
|
|
43
|
-
const padding =
|
|
44
|
+
const padding = containerPadding(spacing);
|
|
44
45
|
const { color, hasHeader, radius } = useContext(PanelContext);
|
|
45
46
|
// A zero-specificity class keeps the padding a default: any consumer class
|
|
46
47
|
// or style still sets its own.
|
package/dist/radio.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, forwardRef, useContext, useMemo } from "react";
|
|
3
3
|
import { Label, RadioButton, RadioField, RadioGroup as AriaRadioGroup, Text } from "react-aria-components";
|
|
4
|
-
import { controlFontWeight,
|
|
5
|
-
import { FieldFeedback, fieldStyle } from "./control/field.js";
|
|
4
|
+
import { controlFontWeight, useControlMetrics } from "./control/control.js";
|
|
5
|
+
import { FieldFeedback, fieldStyle, descriptionStyle } from "./control/field.js";
|
|
6
6
|
import { ToggleIndicator, toggleRowStyle } from "./control/toggle.js";
|
|
7
7
|
import { AriaDirectionBoundary } from "./foundation/aria-direction.js";
|
|
8
8
|
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
@@ -29,7 +29,7 @@ const RadioGroupItem = forwardRef(function RadioGroupItem({ label, description,
|
|
|
29
29
|
focusVisible: state.isFocusVisible,
|
|
30
30
|
invalid: state.isInvalid,
|
|
31
31
|
disabled: state.isDisabled
|
|
32
|
-
} }), label] }) }), description != null && _jsx(Text, { slot: "description", style: {
|
|
32
|
+
} }), label] }) }), description != null && _jsx(Text, { slot: "description", style: { ...descriptionStyle, paddingInlineStart: metrics.indicator + metrics.gap }, children: description })] });
|
|
33
33
|
});
|
|
34
34
|
/** One exclusive-choice field whose options are its Items. */
|
|
35
35
|
export const RadioGroup = Object.assign(RadioGroupRoot, {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, forwardRef, useContext, useId, useMemo } from "react";
|
|
3
3
|
import { ToggleButton as AriaToggleButton, ToggleButtonGroup as AriaToggleButtonGroup } from "react-aria-components";
|
|
4
|
-
import { controlFontWeight,
|
|
5
|
-
import { fieldStyle } from "./control/field.js";
|
|
4
|
+
import { controlFontWeight, useControlMetrics } from "./control/control.js";
|
|
5
|
+
import { fieldStyle, descriptionStyle } from "./control/field.js";
|
|
6
6
|
import { SelectionItemLabel, selectionItemStyle, selectionListStyle, SelectionTrack } from "./control/selection-track.js";
|
|
7
7
|
import { stringKey } from "./control/selection.js";
|
|
8
8
|
import { AriaDirectionBoundary } from "./foundation/aria-direction.js";
|
|
@@ -25,7 +25,7 @@ const SegmentedControlRoot = forwardRef(function SegmentedControl({ label, descr
|
|
|
25
25
|
const [key] = keys;
|
|
26
26
|
if (key !== undefined)
|
|
27
27
|
onChange?.(stringKey(key));
|
|
28
|
-
}, isDisabled: disabled, style: selectionListStyle(orientation), children: children }) }) }), description != null && _jsx("span", { id: descriptionId, style:
|
|
28
|
+
}, isDisabled: disabled, style: selectionListStyle(orientation), children: children }) }) }), description != null && _jsx("span", { id: descriptionId, style: descriptionStyle, children: description })] }) });
|
|
29
29
|
});
|
|
30
30
|
/** One option; its label may lead with an icon. */
|
|
31
31
|
const SegmentedControlItem = forwardRef(function SegmentedControlItem({ children, disabled, className, style, ...properties }, ref) {
|
package/dist/select.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
3
|
import { Button as AriaButton, Select as AriaSelect, SelectValue } from "react-aria-components";
|
|
4
|
-
import { controlOpacity, transition, useControlMetrics } from "./control/control.js";
|
|
4
|
+
import { controlOpacity, transition, useControlMetrics, controlLineHeight } from "./control/control.js";
|
|
5
5
|
import { FieldFeedback, FieldLabel, fieldStyle } from "./control/field.js";
|
|
6
6
|
import { surfaceRender } from "./control/surface-render.js";
|
|
7
7
|
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
@@ -54,7 +54,7 @@ export function fieldTriggerStyle(metrics, disabled) {
|
|
|
54
54
|
border: 0,
|
|
55
55
|
background: "none",
|
|
56
56
|
font: "inherit",
|
|
57
|
-
lineHeight:
|
|
57
|
+
lineHeight: controlLineHeight,
|
|
58
58
|
textAlign: "start",
|
|
59
59
|
cursor: disabled ? "not-allowed" : "pointer"
|
|
60
60
|
};
|
package/dist/slider.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Slider as BaseSlider } from "@base-ui/react/slider";
|
|
|
5
5
|
import { DirectionProvider as BaseDirectionProvider } from "@base-ui/react/direction-provider";
|
|
6
6
|
import { forwardRef, useEffect, useId, useRef, useState } from "react";
|
|
7
7
|
import { controlFontWeight, controlOpacity, transition, useControlMetrics } from "./control/control.js";
|
|
8
|
-
import { fieldStyle } from "./control/field.js";
|
|
8
|
+
import { fieldStyle, descriptionStyle } from "./control/field.js";
|
|
9
9
|
import { lightColor } from "./foundation/color.js";
|
|
10
10
|
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
11
11
|
import { SurfaceView, dimmedClass } from "./surface/surface.js";
|
|
@@ -68,5 +68,5 @@ export const Slider = forwardRef(function Slider({ label, description, name, for
|
|
|
68
68
|
height: thumb,
|
|
69
69
|
cursor: state.disabled ? "not-allowed" : state.dragging ? "grabbing" : "grab",
|
|
70
70
|
scale: state.dragging ? "0.92" : "1"
|
|
71
|
-
} }) })] }) }) }), description != null && _jsx("span", { id: descriptionId, style:
|
|
71
|
+
} }) })] }) }) }), description != null && _jsx("span", { id: descriptionId, style: descriptionStyle, children: description })] }) });
|
|
72
72
|
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
export interface SnippetProps {
|
|
3
|
+
/** The text to show and copy. */
|
|
4
|
+
readonly children: string;
|
|
5
|
+
/** Sets the text in the monospace font, for commands and code. */
|
|
6
|
+
readonly code?: boolean;
|
|
7
|
+
/** Names the copy button for assistive technology; "Copy" by default. */
|
|
8
|
+
readonly copyLabel?: string;
|
|
9
|
+
readonly className?: string;
|
|
10
|
+
readonly style?: CSSProperties;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A block of text meant to be copied whole, such as a command or a message to
|
|
14
|
+
* hand on. It sits in a recess, can be selected at once, and copies itself
|
|
15
|
+
* from the button in its corner.
|
|
16
|
+
*/
|
|
17
|
+
export declare const Snippet: import("react").ForwardRefExoticComponent<SnippetProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
18
|
+
/**
|
|
19
|
+
* Writes text to the clipboard and reports whether it could. A Program's frame
|
|
20
|
+
* may refuse the Clipboard API, so the older copy command is tried after it.
|
|
21
|
+
*/
|
|
22
|
+
export declare function copyText(text: string): Promise<boolean>;
|
package/dist/snippet.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useState } from "react";
|
|
3
|
+
import { Check, Copy } from "lucide-react";
|
|
4
|
+
import { controlFontSizes, useControlMetrics } from "./control/control.js";
|
|
5
|
+
import { iconProps } from "./control/icon.js";
|
|
6
|
+
import { resolveRadius } from "./foundation/radius.js";
|
|
7
|
+
import { Button } from "./button.js";
|
|
8
|
+
import { Surface } from "./surface/surface.js";
|
|
9
|
+
import { scale } from "./foundation/scale.js";
|
|
10
|
+
/**
|
|
11
|
+
* A block of text meant to be copied whole, such as a command or a message to
|
|
12
|
+
* hand on. It sits in a recess, can be selected at once, and copies itself
|
|
13
|
+
* from the button in its corner.
|
|
14
|
+
*/
|
|
15
|
+
export const Snippet = forwardRef(function Snippet({ children, code = false, copyLabel = "Copy", className, style }, ref) {
|
|
16
|
+
const metrics = useControlMetrics("small");
|
|
17
|
+
const { spacing, radius } = metrics.visual;
|
|
18
|
+
const [copied, setCopied] = useState(false);
|
|
19
|
+
// A recess holding one value, like a field: it pads as a control does, not as a container.
|
|
20
|
+
const padding = scale(spacing, "medium");
|
|
21
|
+
return _jsxs(Surface, { ref: ref, className: className, color: "background", depth: "recessed", radius: resolveRadius("medium", radius), style: {
|
|
22
|
+
position: "relative",
|
|
23
|
+
display: "block",
|
|
24
|
+
// Room at the end for the copy button, so text never runs under it.
|
|
25
|
+
padding,
|
|
26
|
+
paddingInlineEnd: padding + metrics.height + metrics.gap,
|
|
27
|
+
// Its text reads at the size of a field's value, whatever surrounds it.
|
|
28
|
+
fontSize: controlFontSizes.medium,
|
|
29
|
+
...style
|
|
30
|
+
}, children: [_jsx("div", { style: {
|
|
31
|
+
whiteSpace: "pre-wrap",
|
|
32
|
+
overflowWrap: "anywhere",
|
|
33
|
+
userSelect: "all",
|
|
34
|
+
lineHeight: 1.6,
|
|
35
|
+
fontFamily: code ? "ui-monospace, SFMono-Regular, Menlo, monospace" : "inherit",
|
|
36
|
+
fontSize: code ? "0.9em" : undefined
|
|
37
|
+
}, children: children }), _jsx(Button, { size: "small", shadow: false, "aria-label": copied ? "Copied" : copyLabel, style: { position: "absolute", insetBlockStart: padding / 2, insetInlineEnd: padding / 2, width: metrics.height, paddingInline: 0 }, onPress: () => void copyText(children).then(setCopied), children: copied ? _jsx(Check, { ...iconProps(14) }) : _jsx(Copy, { ...iconProps(14) }) })] });
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Writes text to the clipboard and reports whether it could. A Program's frame
|
|
41
|
+
* may refuse the Clipboard API, so the older copy command is tried after it.
|
|
42
|
+
*/
|
|
43
|
+
export async function copyText(text) {
|
|
44
|
+
try {
|
|
45
|
+
await navigator.clipboard.writeText(text);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
const field = document.createElement("textarea");
|
|
50
|
+
field.value = text;
|
|
51
|
+
field.setAttribute("readonly", "");
|
|
52
|
+
field.style.position = "fixed";
|
|
53
|
+
field.style.opacity = "0";
|
|
54
|
+
document.body.append(field);
|
|
55
|
+
field.select();
|
|
56
|
+
const copied = document.execCommand("copy");
|
|
57
|
+
field.remove();
|
|
58
|
+
return copied;
|
|
59
|
+
}
|
|
60
|
+
}
|
package/dist/table.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, forwardRef, useContext, useMemo } from "react";
|
|
3
3
|
import { Cell as AriaCell, Column as AriaColumn, Row as AriaRow, Table as AriaTable, TableBody as AriaTableBody, TableHeader as AriaTableHeader } from "react-aria-components";
|
|
4
|
-
import { controlFontWeight, controlOpacity, transition, useControlMetrics } from "./control/control.js";
|
|
4
|
+
import { controlFontWeight, controlOpacity, transition, useControlMetrics, secondaryFontSize } from "./control/control.js";
|
|
5
5
|
import { separatorColor } from "./control/field.js";
|
|
6
6
|
import { itemPaint } from "./control/item.js";
|
|
7
7
|
import { ariaSelection, stringKey } from "./control/selection.js";
|
|
@@ -50,7 +50,7 @@ const TableColumn = forwardRef(function TableColumn({ sortable = false, rowHeade
|
|
|
50
50
|
outline: `3px solid ${state.isFocusVisible ? colorOpacity(colors.primary, 0.34) : "transparent"}`,
|
|
51
51
|
outlineOffset: -3,
|
|
52
52
|
cursor: sortable ? "pointer" : "default",
|
|
53
|
-
fontSize:
|
|
53
|
+
fontSize: secondaryFontSize,
|
|
54
54
|
fontWeight: controlFontWeight,
|
|
55
55
|
textAlign: "start",
|
|
56
56
|
userSelect: "none",
|
package/dist/toast.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Text, UNSTABLE_Toast as AriaToast, UNSTABLE_ToastContent as AriaToastContent, UNSTABLE_ToastQueue as AriaToastQueue, UNSTABLE_ToastRegion as AriaToastRegion } from "react-aria-components";
|
|
3
3
|
import { X } from "lucide-react";
|
|
4
|
-
import { controlFontSizes, controlFontWeight, controlOpacity, useControlMetrics } from "./control/control.js";
|
|
4
|
+
import { controlFontSizes, controlFontWeight, controlOpacity, useControlMetrics, controlLineHeight } from "./control/control.js";
|
|
5
5
|
import { FieldButton } from "./control/field-button.js";
|
|
6
6
|
import { iconProps } from "./control/icon.js";
|
|
7
7
|
import { meaningIcon } from "./control/meaning.js";
|
|
@@ -11,6 +11,7 @@ import { resolveRadius } from "./foundation/radius.js";
|
|
|
11
11
|
import { scale } from "./foundation/scale.js";
|
|
12
12
|
import { Surface } from "./surface/surface.js";
|
|
13
13
|
import { floatingShadow } from "./surface/shadow-options.js";
|
|
14
|
+
import { containerPadding } from "./foundation/spacing.js";
|
|
14
15
|
const queue = new AriaToastQueue({ maxVisibleToasts: 5 });
|
|
15
16
|
/**
|
|
16
17
|
* Shows a brief message that does not interrupt, such as "Saved". It appears
|
|
@@ -53,10 +54,11 @@ export function ToastRegion({ className, style }) {
|
|
|
53
54
|
gridTemplateColumns: "auto minmax(0, 1fr) auto",
|
|
54
55
|
alignItems: "start",
|
|
55
56
|
gap: metrics.gap * 2,
|
|
56
|
-
padding:
|
|
57
|
+
padding: containerPadding(visual.spacing),
|
|
58
|
+
// The close button carries its own padding, so the end keeps less.
|
|
57
59
|
paddingInlineEnd: metrics.spacing / 2,
|
|
58
60
|
fontSize: controlFontSizes.medium,
|
|
59
|
-
lineHeight:
|
|
60
|
-
}, children: [_jsx("span", { style: { display: "grid", height:
|
|
61
|
+
lineHeight: controlLineHeight
|
|
62
|
+
}, children: [_jsx("span", { style: { display: "grid", height: `${controlLineHeight}em`, alignItems: "center", color: colorLevel(resolveColor(color, visual.colors), "strong", visual.colors) }, children: _jsx(Icon, { ...iconProps(16) }) }), _jsxs(AriaToastContent, { style: { display: "grid", gap: 2, minWidth: 0 }, children: [_jsx(Text, { slot: "title", style: { fontWeight: controlFontWeight }, children: item.content.title }), item.content.description != null && _jsx(Text, { slot: "description", style: { opacity: controlOpacity.secondary }, children: item.content.description })] }), _jsx(FieldButton, { slot: "close", metrics: metrics, "aria-label": "Close", children: _jsx(X, { ...iconProps(14) }) })] }) });
|
|
61
63
|
} })] });
|
|
62
64
|
}
|
package/dist/typography.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export interface KbdProps {
|
|
|
33
33
|
readonly className?: string;
|
|
34
34
|
readonly style?: CSSProperties;
|
|
35
35
|
}
|
|
36
|
+
/** Running text sets its lines at this height, relative to its size. */
|
|
36
37
|
/**
|
|
37
38
|
* A key to press, drawn as a small raised keycap. Its label takes the control
|
|
38
39
|
* text scale, and the cap is as tall as the line of text around it, so it
|
package/dist/typography.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
3
|
import { Heading as AriaHeading, Keyboard as AriaKeyboard, Text as AriaText } from "react-aria-components";
|
|
4
|
-
import { controlFontSizes, controlFontWeight, controlOpacity, useControlMetrics } from "./control/control.js";
|
|
4
|
+
import { controlFontSizes, controlFontWeight, controlLineHeight, controlOpacity, useControlMetrics } from "./control/control.js";
|
|
5
5
|
import { scale, scaleMultiplier } from "./foundation/scale.js";
|
|
6
6
|
import { useVisual } from "./foundation/visual.js";
|
|
7
7
|
import { Surface } from "./surface/surface.js";
|
|
@@ -28,13 +28,12 @@ export const Heading = forwardRef(function Heading({ level = 2, size, style, ...
|
|
|
28
28
|
export const Text = forwardRef(function Text({ tone = "default", size, style, ...properties }, ref) {
|
|
29
29
|
return _jsx(AriaText, { ...properties, ref: ref, style: {
|
|
30
30
|
fontSize: size === undefined ? undefined : controlFontSizes[size],
|
|
31
|
-
lineHeight:
|
|
31
|
+
lineHeight: controlLineHeight,
|
|
32
32
|
opacity: tone === "secondary" ? controlOpacity.secondary : undefined,
|
|
33
33
|
...style
|
|
34
34
|
} });
|
|
35
35
|
});
|
|
36
36
|
/** Running text sets its lines at this height, relative to its size. */
|
|
37
|
-
const textLineHeight = 1.45;
|
|
38
37
|
/**
|
|
39
38
|
* A key to press, drawn as a small raised keycap. Its label takes the control
|
|
40
39
|
* text scale, and the cap is as tall as the line of text around it, so it
|
|
@@ -43,7 +42,7 @@ const textLineHeight = 1.45;
|
|
|
43
42
|
export const Kbd = forwardRef(function Kbd({ children, className, style }, ref) {
|
|
44
43
|
const metrics = useControlMetrics("xsmall");
|
|
45
44
|
const label = Number.parseFloat(controlFontSizes.medium);
|
|
46
|
-
const cap = `${
|
|
45
|
+
const cap = `${controlLineHeight / label}em`;
|
|
47
46
|
return _jsx(AriaKeyboard, { ref: ref, className: className, style: { display: "inline-block", verticalAlign: "middle", lineHeight: 1 }, children: _jsx(Surface, { as: "span", radius: metrics.radius, shadow: false, style: {
|
|
48
47
|
display: "inline-flex",
|
|
49
48
|
alignItems: "center",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phreshos/react-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.43",
|
|
4
4
|
"description": "React components for coherent PhreshOS Program interfaces.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@base-ui/react": "^1.7.0",
|
|
59
59
|
"@internationalized/date": "^3.12.3",
|
|
60
|
-
"@phreshos/core": "^0.1.
|
|
60
|
+
"@phreshos/core": "^0.1.63",
|
|
61
61
|
"colorjs.io": "^0.7.1",
|
|
62
62
|
"lucide-react": "^1.48.0",
|
|
63
63
|
"react-aria": "^3.51.0",
|