@parallelworks/ui 0.77.0 → 0.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -6
- package/dist/access/AccessDrawer.d.ts +49 -7
- package/dist/access/AccessDrawer.js +243 -38
- package/dist/access/AccessList.d.ts +19 -1
- package/dist/access/AccessList.js +220 -9
- package/dist/access/GrantView.d.ts +3 -1
- package/dist/access/GrantView.js +17 -4
- package/dist/access/PrincipalPicker.js +5 -5
- package/dist/access/focus.js +1 -1
- package/dist/access/index.d.ts +2 -2
- package/dist/access/index.js +2 -2
- package/dist/access/strings.d.ts +25 -1
- package/dist/access/strings.js +27 -3
- package/dist/access/types.d.ts +26 -0
- package/dist/ai/components/AllocationSelector.js +1 -1
- package/dist/ai/components/AttachmentManager.js +5 -5
- package/dist/ai/components/AttachmentUpload.js +2 -2
- package/dist/ai/components/BranchNavigator.js +1 -1
- package/dist/ai/components/ChatActivity.js +1 -1
- package/dist/ai/components/ChatEmptyState.js +3 -3
- package/dist/ai/components/ChatInput.js +3 -5
- package/dist/ai/components/ChatLayout.js +1 -1
- package/dist/ai/components/ChatMessage.js +1 -1
- package/dist/ai/components/ChatMessageList.js +23 -8
- package/dist/ai/components/ChatSidebar.js +3 -3
- package/dist/ai/components/ChatThread.js +4 -4
- package/dist/ai/components/ComposerAddMenu.js +9 -20
- package/dist/ai/components/ModelSelector.js +3 -3
- package/dist/ai/components/PastedText.js +5 -5
- package/dist/ai/components/SessionView.js +1 -1
- package/dist/ai/components/ShareDialog.js +3 -3
- package/dist/ai/components/SlashMenu.d.ts +31 -4
- package/dist/ai/components/SlashMenu.js +36 -63
- package/dist/ai/components/agent/ActivityLine.js +1 -1
- package/dist/ai/components/agent/AgentMessageParts.js +13 -13
- package/dist/ai/components/conversationActions.js +3 -3
- package/dist/ai/core/ChatProvider.js +1 -1
- package/dist/ai/core/config.js +1 -1
- package/dist/ai/ui/ConversationSidebar.js +3 -3
- package/dist/ai/ui/sidebar.js +3 -3
- package/dist/assets/yaml.worker-DOBV2lND.js +884 -0
- package/dist/components/ActionMenu.d.ts +38 -9
- package/dist/components/ActionMenu.js +48 -22
- package/dist/components/Avatar.d.ts +66 -6
- package/dist/components/Avatar.js +130 -18
- package/dist/components/Breadcrumbs.d.ts +4 -0
- package/dist/components/Breadcrumbs.js +26 -10
- package/dist/components/Button.d.ts +3 -2
- package/dist/components/Button.js +11 -1
- package/dist/components/Callout.d.ts +3 -2
- package/dist/components/Callout.js +3 -2
- package/dist/components/Card.d.ts +33 -9
- package/dist/components/Card.js +24 -8
- package/dist/components/Checkbox.d.ts +3 -1
- package/dist/components/Checkbox.js +4 -2
- package/dist/components/ColorInput.js +1 -1
- package/dist/components/Combobox.d.ts +23 -0
- package/dist/components/Combobox.js +252 -86
- package/dist/components/ConfirmModal.d.ts +28 -2
- package/dist/components/ConfirmModal.js +100 -15
- package/dist/components/ContextMenu.d.ts +29 -2
- package/dist/components/ContextMenu.js +60 -8
- package/dist/components/CopyButton.d.ts +21 -8
- package/dist/components/CopyButton.js +29 -9
- package/dist/components/CreateModal.d.ts +20 -4
- package/dist/components/CreateModal.js +28 -17
- package/dist/components/DatePicker.d.ts +31 -1
- package/dist/components/DatePicker.js +178 -47
- package/dist/components/DescriptionList.d.ts +13 -3
- package/dist/components/DescriptionList.js +43 -11
- package/dist/components/Disclosure.d.ts +10 -2
- package/dist/components/Disclosure.js +18 -7
- package/dist/components/Drawer.js +5 -5
- package/dist/components/EmptyState.d.ts +12 -4
- package/dist/components/EmptyState.js +18 -10
- package/dist/components/ErrorPage.d.ts +40 -0
- package/dist/components/ErrorPage.js +101 -0
- package/dist/components/ExternalLink.d.ts +4 -1
- package/dist/components/ExternalLink.js +4 -5
- package/dist/components/Field.d.ts +21 -6
- package/dist/components/Field.js +32 -16
- package/dist/components/FileButton.d.ts +19 -0
- package/dist/components/FileButton.js +32 -0
- package/dist/components/HoverCard.d.ts +26 -6
- package/dist/components/HoverCard.js +11 -5
- package/dist/components/IconButton.js +4 -2
- package/dist/components/InfoTip.js +3 -3
- package/dist/components/Input.d.ts +33 -3
- package/dist/components/Input.js +149 -14
- package/dist/components/Kbd.d.ts +40 -0
- package/dist/components/Kbd.js +168 -0
- package/dist/components/Listbox.d.ts +103 -0
- package/dist/components/Listbox.js +190 -0
- package/dist/components/Loader.d.ts +8 -2
- package/dist/components/Loader.js +16 -1
- package/dist/components/Markdown.js +1 -1
- package/dist/components/MarkdownImpl.js +1 -1
- package/dist/components/Menu.d.ts +20 -2
- package/dist/components/Menu.js +48 -19
- package/dist/components/MenuEntries.d.ts +41 -4
- package/dist/components/MenuEntries.js +266 -39
- package/dist/components/Meter.d.ts +50 -11
- package/dist/components/Meter.js +71 -21
- package/dist/components/Modal.d.ts +9 -3
- package/dist/components/Modal.js +68 -29
- package/dist/components/OneTimeCodeInput.js +1 -1
- package/dist/components/PageHeader.js +111 -7
- package/dist/components/PageHeaderAction.d.ts +8 -3
- package/dist/components/PageHeaderAction.js +122 -34
- package/dist/components/Pagination.d.ts +13 -1
- package/dist/components/Pagination.js +90 -19
- package/dist/components/Popover.d.ts +16 -2
- package/dist/components/Popover.js +20 -21
- package/dist/components/Provider.d.ts +172 -5
- package/dist/components/Provider.js +157 -14
- package/dist/components/RefreshButton.d.ts +13 -6
- package/dist/components/RefreshButton.js +17 -9
- package/dist/components/RunStatusIcon.d.ts +16 -7
- package/dist/components/RunStatusIcon.js +21 -8
- package/dist/components/Section.d.ts +11 -4
- package/dist/components/Section.js +33 -22
- package/dist/components/SegmentedControl.d.ts +16 -3
- package/dist/components/SegmentedControl.js +7 -3
- package/dist/components/Select.d.ts +19 -3
- package/dist/components/Select.js +114 -68
- package/dist/components/SelectionCopy.d.ts +10 -0
- package/dist/components/SelectionCopy.js +105 -0
- package/dist/components/SettingModeOption.js +1 -1
- package/dist/components/SettingsCard.js +1 -1
- package/dist/components/Skeleton.js +1 -1
- package/dist/components/StatusBadge.d.ts +55 -10
- package/dist/components/StatusBadge.js +91 -15
- package/dist/components/StickyBar.js +1 -1
- package/dist/components/Table.d.ts +22 -4
- package/dist/components/Table.js +46 -24
- package/dist/components/Tabs.d.ts +9 -4
- package/dist/components/Tabs.js +9 -4
- package/dist/components/Tag.d.ts +49 -0
- package/dist/components/Tag.js +199 -0
- package/dist/components/ThemeEditor.js +1 -1
- package/dist/components/Toast.js +1 -1
- package/dist/components/ToggleGroup.d.ts +4 -1
- package/dist/components/ToggleGroup.js +30 -13
- package/dist/components/Tooltip.d.ts +9 -3
- package/dist/components/Tooltip.js +55 -39
- package/dist/components/buttonClasses.d.ts +5 -2
- package/dist/components/buttonClasses.js +11 -10
- package/dist/components/chart.d.ts +69 -0
- package/dist/components/chart.js +145 -0
- package/dist/components/comboboxItems.d.ts +7 -1
- package/dist/components/comboboxItems.js +6 -2
- package/dist/components/dismiss.d.ts +5 -1
- package/dist/components/dismiss.js +6 -2
- package/dist/components/floating.d.ts +4 -4
- package/dist/components/floating.js +5 -5
- package/dist/components/headerActionsFit.d.ts +37 -0
- package/dist/components/headerActionsFit.js +81 -0
- package/dist/components/pageHeaderStore.d.ts +3 -0
- package/dist/components/pageHeaderStore.js +3 -0
- package/dist/components/pathBreaks.js +2 -2
- package/dist/components/popupContainer.d.ts +17 -0
- package/dist/components/popupContainer.js +69 -0
- package/dist/components/relativeTime.d.ts +21 -10
- package/dist/components/relativeTime.js +50 -22
- package/dist/components/segmented.d.ts +18 -4
- package/dist/components/segmented.js +48 -6
- package/dist/components/typedDate.d.ts +5 -0
- package/dist/components/typedDate.js +50 -0
- package/dist/components/useClosingValue.d.ts +4 -0
- package/dist/components/useClosingValue.js +12 -0
- package/dist/components/useCopy.d.ts +6 -0
- package/dist/components/useCopy.js +3 -3
- package/dist/components/useNarrow.d.ts +2 -0
- package/dist/components/useNarrow.js +16 -0
- package/dist/editor/Editor.js +1 -1
- package/dist/editor/FormCodePanel.js +1 -1
- package/dist/editor/Monaco.js +1 -1
- package/dist/editor/workers.js +1 -1
- package/dist/file-explorer/FileExplorer.js +16 -15
- package/dist/file-explorer/FileExplorerContext.js +2 -2
- package/dist/file-explorer/FilePreview/Viewer.js +3 -3
- package/dist/file-explorer/FilePreview/index.js +2 -2
- package/dist/file-explorer/FileRowsWindow.js +3 -3
- package/dist/file-explorer/FileTable.js +1 -1
- package/dist/file-explorer/LoadMoreRow.js +1 -1
- package/dist/file-explorer/TreeView.js +5 -5
- package/dist/file-explorer/helpers.js +2 -2
- package/dist/file-explorer/toasts.js +2 -2
- package/dist/form/Fields/CheckboxGroupField.js +1 -1
- package/dist/form/Fields/DropdownField.js +1 -1
- package/dist/form/Fields/DurationField.js +2 -2
- package/dist/form/Fields/MultiDropdownField.js +1 -1
- package/dist/form/Fields/NumberField.js +1 -1
- package/dist/form/Fields/ObjectField.js +1 -1
- package/dist/form/Fields/RangeField.js +1 -1
- package/dist/form/Fields/StringField.js +1 -1
- package/dist/form/Form.js +3 -3
- package/dist/form/FormLayout.js +1 -1
- package/dist/form/Wizard/WizardContainer.js +1 -1
- package/dist/form/Wizard/WizardNavigation.js +1 -1
- package/dist/form/Wizard/WizardStepContent.js +1 -1
- package/dist/form/fieldRegistry.js +1 -1
- package/dist/form/formEditing.js +1 -1
- package/dist/format.d.ts +17 -7
- package/dist/format.js +39 -16
- package/dist/graph/AnnotationBanner.js +2 -2
- package/dist/graph/Connectors.js +5 -5
- package/dist/graph/DependencyGraph.js +10 -9
- package/dist/graph/GraphEditor.js +4 -4
- package/dist/graph/GraphEditorDialogs.js +13 -12
- package/dist/graph/GraphNode.js +1 -1
- package/dist/graph/InputDialog.js +5 -5
- package/dist/graph/InputsEditor.js +10 -9
- package/dist/graph/MatrixGroup.js +2 -2
- package/dist/graph/ProblemPageLink.d.ts +9 -0
- package/dist/graph/ProblemPageLink.js +21 -0
- package/dist/graph/ProblemsButton.js +26 -16
- package/dist/graph/Reveal.js +1 -1
- package/dist/graph/RunWarningsList.js +21 -12
- package/dist/graph/ShortcutsButton.js +25 -8
- package/dist/graph/StepSummaries.js +1 -1
- package/dist/graph/TreeView.js +2 -2
- package/dist/graph/WorkflowSettingsDialog.js +3 -3
- package/dist/graph/editorApi.d.ts +10 -0
- package/dist/graph/editorFields.js +3 -3
- package/dist/graph/editorPrimitives.js +1 -1
- package/dist/graph/editorRows.js +8 -6
- package/dist/graph/editorStrings.d.ts +1 -0
- package/dist/graph/editorStrings.js +1 -0
- package/dist/graph/fieldProblems.js +2 -2
- package/dist/graph/inputRefs.js +7 -6
- package/dist/graph/runWarnings.d.ts +12 -1
- package/dist/graph/stepWith.js +2 -2
- package/dist/index.d.ts +30 -21
- package/dist/index.js +20 -12
- package/dist/list/ActionToolbar.d.ts +4 -0
- package/dist/list/ActionToolbar.js +35 -12
- package/dist/list/ListFilterBar.d.ts +42 -0
- package/dist/list/ListFilterBar.js +789 -0
- package/dist/list/ListPage.d.ts +42 -4
- package/dist/list/ListPage.js +56 -22
- package/dist/list/ListTable.d.ts +27 -3
- package/dist/list/ListTable.js +48 -23
- package/dist/list/ListToolbar.d.ts +31 -0
- package/dist/list/ListToolbar.js +43 -0
- package/dist/list/ListViewControls.d.ts +8 -4
- package/dist/list/ListViewControls.js +22 -14
- package/dist/list/UserHoverCard.d.ts +8 -2
- package/dist/list/UserHoverCard.js +26 -13
- package/dist/list/filterModel.d.ts +122 -0
- package/dist/list/filterModel.js +308 -0
- package/dist/list/index.d.ts +6 -2
- package/dist/list/index.js +6 -2
- package/dist/list/listSearch.d.ts +1 -1
- package/dist/list/listSearch.js +8 -4
- package/dist/list/listView.d.ts +24 -2
- package/dist/list/listView.js +47 -45
- package/dist/list/rowMenu.d.ts +10 -5
- package/dist/list/rowMenu.js +17 -7
- package/dist/list/useListFilters.d.ts +68 -0
- package/dist/list/useListFilters.js +252 -0
- package/dist/logviewer/LogViewer.js +4 -4
- package/dist/styles/theme.css +94 -0
- package/dist/styles.css +1 -1
- package/package.json +11 -11
- package/dist/assets/yaml.worker-k9AdOqzf.js +0 -1441
- package/dist/components/fullscreen.d.ts +0 -4
- package/dist/components/fullscreen.js +0 -18
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
//#region src/components/EmptyState.tsx
|
|
4
|
+
var frames = {
|
|
5
|
+
panel: "panel px-6 py-12",
|
|
6
|
+
plain: "px-6 py-16",
|
|
7
|
+
dashed: "rounded-xl border border-dashed border-(--theme-border) px-6 py-12",
|
|
8
|
+
bare: "px-3 py-6"
|
|
9
|
+
};
|
|
4
10
|
/** What shows where there is nothing yet, or nothing matches: what's missing,
|
|
5
11
|
* and what to do about it. */
|
|
6
|
-
function EmptyState({ title, description, action, icon, variant = "panel", className, testId }) {
|
|
7
|
-
const
|
|
12
|
+
function EmptyState({ title, description, action, icon, variant = "panel", headingLevel, className, testId }) {
|
|
13
|
+
const bare = variant === "bare";
|
|
14
|
+
const Title = headingLevel ? `h${headingLevel}` : "p";
|
|
8
15
|
return /* @__PURE__ */ jsxs("div", {
|
|
9
16
|
"data-testid": testId,
|
|
10
|
-
className: cx("flex flex-col items-center justify-center text-center",
|
|
17
|
+
className: cx("flex flex-col items-center justify-center text-center", frames[variant], className),
|
|
11
18
|
children: [
|
|
12
|
-
icon && /* @__PURE__ */ jsx("div", {
|
|
13
|
-
|
|
19
|
+
!!icon && /* @__PURE__ */ jsx("div", {
|
|
20
|
+
"aria-hidden": "true",
|
|
21
|
+
className: cx("flex items-center justify-center text-(--theme-muted-text-color) opacity-40", bare ? "mb-2 [&_svg]:size-6" : "mb-3 [&_svg]:size-8"),
|
|
14
22
|
children: icon
|
|
15
23
|
}),
|
|
16
|
-
/* @__PURE__ */ jsx(
|
|
17
|
-
className: cx("text-sm",
|
|
24
|
+
/* @__PURE__ */ jsx(Title, {
|
|
25
|
+
className: cx("m-0 text-sm", bare ? "text-(--theme-muted-text-color)" : "mb-1 font-medium text-(--theme-app)"),
|
|
18
26
|
children: title
|
|
19
27
|
}),
|
|
20
|
-
description && /* @__PURE__ */ jsx("p", {
|
|
21
|
-
className: "max-w-
|
|
28
|
+
!!description && /* @__PURE__ */ jsx("p", {
|
|
29
|
+
className: "m-0 max-w-sm text-xs text-(--theme-muted-text-color)",
|
|
22
30
|
children: description
|
|
23
31
|
}),
|
|
24
|
-
action && /* @__PURE__ */ jsx("div", {
|
|
32
|
+
!!action && /* @__PURE__ */ jsx("div", {
|
|
25
33
|
className: "mt-4",
|
|
26
34
|
children: action
|
|
27
35
|
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type ErrorPageKind } from './Provider.js';
|
|
3
|
+
export type { ErrorPageKind } from './Provider.js';
|
|
4
|
+
export interface ErrorPageProps {
|
|
5
|
+
/** The HTTP status, shown large over the title and left out of what a
|
|
6
|
+
* screen reader reads, since the title says it in words. It also picks the
|
|
7
|
+
* default words: 404, 403, 401, 502 to 504, or another 5xx. */
|
|
8
|
+
status?: number | string | undefined;
|
|
9
|
+
/** What went wrong, when no status says it, such as `network` for a request
|
|
10
|
+
* that never reached the server. Picks the default title and description. */
|
|
11
|
+
kind?: ErrorPageKind | undefined;
|
|
12
|
+
/** By default the kind's title, then "Error {status}". With neither, the
|
|
13
|
+
* description becomes the title, so a message alone still heads the page. */
|
|
14
|
+
title?: ReactNode;
|
|
15
|
+
/** By default the kind's description. `null` shows none. */
|
|
16
|
+
description?: ReactNode;
|
|
17
|
+
/** `page` fills its container over a backdrop of drifting glows; `card`
|
|
18
|
+
* fills a card, clipping the backdrop to its corners; `inline` sits in a
|
|
19
|
+
* section's flow with no backdrop. */
|
|
20
|
+
layout?: 'page' | 'card' | 'inline' | undefined;
|
|
21
|
+
/** The way back. By default back through the history when there is some,
|
|
22
|
+
* and home (`/`) when there isn't; `href` goes there instead, such as
|
|
23
|
+
* "Back to sessions". `false` offers none. */
|
|
24
|
+
back?: {
|
|
25
|
+
href?: string | undefined;
|
|
26
|
+
label?: string | undefined;
|
|
27
|
+
} | false | undefined;
|
|
28
|
+
/** More ways on, before the way back, such as "Sign in" after a 401. */
|
|
29
|
+
actions?: ReactNode;
|
|
30
|
+
/** The title's level: 1 for a page, 2 in a card or inline. */
|
|
31
|
+
headingLevel?: 1 | 2 | 3 | undefined;
|
|
32
|
+
className?: string | undefined;
|
|
33
|
+
testId?: string | undefined;
|
|
34
|
+
}
|
|
35
|
+
/** The kind of error an HTTP status names, or none for one without its own words. */
|
|
36
|
+
export declare function errorPageKind(status: number | string | undefined): ErrorPageKind | undefined;
|
|
37
|
+
/** A page, card or section that could not show what it was asked for: the
|
|
38
|
+
* status large in the theme's gradient, what happened in words, and the way
|
|
39
|
+
* back. Every word defaults from the status, and the host may pass its own. */
|
|
40
|
+
export declare function ErrorPage({ status, kind: kindProp, title, description, layout, back, actions, headingLevel, className, testId, }: ErrorPageProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { cx } from "../cx.js";
|
|
2
|
+
import { ArrowLeftIcon } from "../icons.js";
|
|
3
|
+
import { useNavigation, useStrings } from "./Provider.js";
|
|
4
|
+
import { AppLink } from "./AppLink.js";
|
|
5
|
+
import { useSyncExternalStore } from "react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/components/ErrorPage.tsx
|
|
8
|
+
/** The kind of error an HTTP status names, or none for one without its own words. */
|
|
9
|
+
function errorPageKind(status) {
|
|
10
|
+
const code = typeof status === "string" ? Number.parseInt(status, 10) : status;
|
|
11
|
+
if (code === void 0 || Number.isNaN(code)) return;
|
|
12
|
+
if (code === 404) return "notFound";
|
|
13
|
+
if (code === 403) return "forbidden";
|
|
14
|
+
if (code === 401) return "unauthenticated";
|
|
15
|
+
if (code === 502 || code === 503 || code === 504) return "unavailable";
|
|
16
|
+
return code >= 500 && code < 600 ? "server" : void 0;
|
|
17
|
+
}
|
|
18
|
+
var subscribeNever = () => () => {};
|
|
19
|
+
var linkClassName = "group inline-flex items-center gap-1.5 rounded-sm text-sm text-(--theme-link) hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--theme-focus) cursor-pointer";
|
|
20
|
+
/** A page, card or section that could not show what it was asked for: the
|
|
21
|
+
* status large in the theme's gradient, what happened in words, and the way
|
|
22
|
+
* back. Every word defaults from the status, and the host may pass its own. */
|
|
23
|
+
function ErrorPage({ status, kind: kindProp, title, description, layout = "page", back, actions, headingLevel, className, testId }) {
|
|
24
|
+
const { errorPage: t } = useStrings();
|
|
25
|
+
const kind = kindProp ?? errorPageKind(status);
|
|
26
|
+
const hasStatus = status !== void 0 && status !== "";
|
|
27
|
+
const shownDescription = description === void 0 && kind ? t.descriptions[kind] : description;
|
|
28
|
+
const fallbackTitle = kind ? t.titles[kind] : hasStatus ? t.statusTitle(String(status)) : null;
|
|
29
|
+
const promoted = title === void 0 && fallbackTitle === null && present(shownDescription);
|
|
30
|
+
const heading = title ?? fallbackTitle ?? (promoted ? shownDescription : t.error);
|
|
31
|
+
const Heading = `h${headingLevel ?? (layout === "page" ? 1 : 2)}`;
|
|
32
|
+
const framed = layout !== "inline";
|
|
33
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
34
|
+
"data-testid": testId,
|
|
35
|
+
className: cx("@container relative flex w-full items-center justify-center px-4 text-center", framed && "isolate overflow-hidden", layout === "page" && "min-h-full flex-1 py-16", layout === "card" && "h-full rounded-[inherit] py-12", layout === "inline" && "py-16", className),
|
|
36
|
+
children: [framed && /* @__PURE__ */ jsx(Backdrop, {}), /* @__PURE__ */ jsxs("div", {
|
|
37
|
+
className: "error-page-content relative flex w-full max-w-md flex-col items-center gap-6",
|
|
38
|
+
children: [hasStatus && /* @__PURE__ */ jsx("span", {
|
|
39
|
+
"aria-hidden": "true",
|
|
40
|
+
className: cx("error-page-code select-none font-black leading-none tracking-tighter opacity-75", layout === "page" ? "text-[7rem] @md:text-[10rem]" : "text-[5rem] @md:text-[7rem]"),
|
|
41
|
+
children: status
|
|
42
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
43
|
+
className: cx("flex flex-col items-center gap-3", hasStatus && "-mt-4"),
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ jsx(Heading, {
|
|
46
|
+
className: "m-0 text-xl font-semibold tracking-tight text-(--theme-app)",
|
|
47
|
+
children: heading
|
|
48
|
+
}),
|
|
49
|
+
!promoted && present(shownDescription) && /* @__PURE__ */ jsx("p", {
|
|
50
|
+
className: "m-0 max-w-md text-sm text-(--theme-muted-text-color)",
|
|
51
|
+
children: shownDescription
|
|
52
|
+
}),
|
|
53
|
+
(present(actions) || back !== false) && /* @__PURE__ */ jsxs("div", {
|
|
54
|
+
className: "mt-2 flex flex-wrap items-center justify-center gap-x-5 gap-y-2",
|
|
55
|
+
children: [actions, back !== false && /* @__PURE__ */ jsx(BackLink, {
|
|
56
|
+
href: back?.href,
|
|
57
|
+
label: back?.label
|
|
58
|
+
})]
|
|
59
|
+
})
|
|
60
|
+
]
|
|
61
|
+
})]
|
|
62
|
+
})]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function present(node) {
|
|
66
|
+
return node !== void 0 && node !== null && node !== false && node !== "";
|
|
67
|
+
}
|
|
68
|
+
function BackLink({ href, label }) {
|
|
69
|
+
const { errorPage: t } = useStrings();
|
|
70
|
+
const navigation = useNavigation();
|
|
71
|
+
const canGoBack = useSyncExternalStore(subscribeNever, () => navigation.canGoBack(), () => false);
|
|
72
|
+
const arrow = /* @__PURE__ */ jsx(ArrowLeftIcon, {
|
|
73
|
+
"aria-hidden": "true",
|
|
74
|
+
className: "size-3.5 shrink-0 transition-transform duration-200 group-hover:-translate-x-0.5 motion-reduce:transition-none rtl:rotate-180"
|
|
75
|
+
});
|
|
76
|
+
if (href === void 0 && canGoBack) return /* @__PURE__ */ jsxs("button", {
|
|
77
|
+
type: "button",
|
|
78
|
+
onClick: () => navigation.goBack(),
|
|
79
|
+
className: linkClassName,
|
|
80
|
+
children: [arrow, label ?? t.back]
|
|
81
|
+
});
|
|
82
|
+
return /* @__PURE__ */ jsxs(AppLink, {
|
|
83
|
+
href: href ?? "/",
|
|
84
|
+
className: linkClassName,
|
|
85
|
+
children: [arrow, label ?? (href === void 0 ? t.home : t.back)]
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/** Two slow glows in the theme's gradient colors over a faint grid. */
|
|
89
|
+
function Backdrop() {
|
|
90
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
91
|
+
"aria-hidden": "true",
|
|
92
|
+
className: "pointer-events-none absolute inset-0 -z-10 overflow-hidden rounded-[inherit]",
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ jsx("div", { className: "error-page-glow -top-1/5 -right-1/10 size-150 error-page-glow-start" }),
|
|
95
|
+
/* @__PURE__ */ jsx("div", { className: "error-page-glow -bottom-1/5 -left-1/10 size-125 error-page-glow-mid [animation-delay:2s]" }),
|
|
96
|
+
/* @__PURE__ */ jsx("div", { className: "error-page-grid absolute inset-0" })
|
|
97
|
+
]
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
101
|
+
export { ErrorPage, errorPageKind };
|
|
@@ -2,8 +2,11 @@ import type { ComponentPropsWithRef } from 'react';
|
|
|
2
2
|
export type ExternalLinkProps = Omit<ComponentPropsWithRef<'a'>, 'target' | 'rel'> & {
|
|
3
3
|
/** Marks the link as leaving the page with an arrow after its text. */
|
|
4
4
|
icon?: boolean;
|
|
5
|
+
/** Says "opens in a new tab" to screen readers after the text, unless false: for a link
|
|
6
|
+
* whose own words already say so, or whose `aria-label` replaces its text. */
|
|
7
|
+
announce?: boolean;
|
|
5
8
|
};
|
|
6
9
|
/** A link that opens in a new tab, says so to screen readers, and gives the
|
|
7
10
|
* page it opens no hold on this one. Its href passes `safeUrl`, as every
|
|
8
11
|
* component's does, and one that doesn't is dropped. */
|
|
9
|
-
export declare function ExternalLink({ href, children, icon, className, ...props }: ExternalLinkProps): import("react").JSX.Element;
|
|
12
|
+
export declare function ExternalLink({ href, children, icon, announce, className, ...props }: ExternalLinkProps): import("react").JSX.Element;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { cx } from "../cx.js";
|
|
2
1
|
import { ExternalLinkIcon } from "../icons.js";
|
|
3
2
|
import { safeUrl } from "../safeUrl.js";
|
|
4
3
|
import { useStrings } from "./Provider.js";
|
|
@@ -7,22 +6,22 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
7
6
|
/** A link that opens in a new tab, says so to screen readers, and gives the
|
|
8
7
|
* page it opens no hold on this one. Its href passes `safeUrl`, as every
|
|
9
8
|
* component's does, and one that doesn't is dropped. */
|
|
10
|
-
function ExternalLink({ href, children, icon = false, className, ...props }) {
|
|
9
|
+
function ExternalLink({ href, children, icon = false, announce = true, className, ...props }) {
|
|
11
10
|
const { common } = useStrings();
|
|
12
11
|
return /* @__PURE__ */ jsxs("a", {
|
|
13
12
|
...props,
|
|
14
13
|
href: safeUrl(href),
|
|
15
14
|
target: "_blank",
|
|
16
15
|
rel: "noopener noreferrer",
|
|
17
|
-
className
|
|
16
|
+
className,
|
|
18
17
|
children: [
|
|
19
18
|
children,
|
|
20
|
-
/* @__PURE__ */ jsxs("span", {
|
|
19
|
+
announce && /* @__PURE__ */ jsxs("span", {
|
|
21
20
|
className: "sr-only",
|
|
22
21
|
children: [" ", common.opensInNewTab]
|
|
23
22
|
}),
|
|
24
23
|
icon && /* @__PURE__ */ jsx(ExternalLinkIcon, {
|
|
25
|
-
className: "h-3 w-3
|
|
24
|
+
className: "ml-1 inline-block h-3 w-3 align-[-1px]",
|
|
26
25
|
"aria-hidden": true
|
|
27
26
|
})
|
|
28
27
|
]
|
|
@@ -76,13 +76,24 @@ export interface FieldProps {
|
|
|
76
76
|
* function. A value shown but not edited goes in a `FieldValue`. */
|
|
77
77
|
children: ReactNode | ((control: FieldControlProps) => ReactNode);
|
|
78
78
|
}
|
|
79
|
-
|
|
80
|
-
* one rather than the whole of it, such as a row of a list editor. Give it an `id` and name it
|
|
81
|
-
* in the control's `aria-describedby` so the error is read with the control. */
|
|
82
|
-
export declare function ErrorText({ id, children }: {
|
|
79
|
+
export interface ErrorTextProps {
|
|
83
80
|
id?: string | undefined;
|
|
81
|
+
/** `sm` is a Field's own error, under one control; `md` is for an error
|
|
82
|
+
* about a whole form or an action, such as a Save that failed. */
|
|
83
|
+
size?: 'sm' | 'md' | undefined;
|
|
84
|
+
/** Sits in a line of text instead of a line of its own, in that text's size; `size`
|
|
85
|
+
* applies only on a line of its own. */
|
|
86
|
+
inline?: boolean | undefined;
|
|
87
|
+
/** Places it, such as its margins, or a card footer's rule and padding. */
|
|
88
|
+
className?: string | undefined;
|
|
89
|
+
/** Nothing renders without it, so an error that may be absent needs no guard. */
|
|
84
90
|
children: ReactNode;
|
|
85
|
-
}
|
|
91
|
+
}
|
|
92
|
+
/** An error in the look a Field gives its own, for a control outside a Field, or for a part of
|
|
93
|
+
* one rather than the whole of it, such as a row of a list editor; `size="md"` for an error
|
|
94
|
+
* under a whole form or after an action. It is announced as it appears. Give it an `id` and
|
|
95
|
+
* name it in the control's `aria-describedby` so the error is read with the control. */
|
|
96
|
+
export declare function ErrorText({ id, size, inline, className, children, }: ErrorTextProps): import("react").JSX.Element | null;
|
|
86
97
|
/** A control with its label, help and error, tied to it for assistive technology. One frame
|
|
87
98
|
* for every field, in a form or standing alone. */
|
|
88
99
|
export declare function Field({ label, hint, help, actions, description, error, invalid, required, disabled, layout, compact, size, group, controlFirst, id: ownId, className, children, }: FieldProps): import("react").JSX.Element;
|
|
@@ -95,10 +106,14 @@ export declare function FieldOption({ disabled, className, children, }: {
|
|
|
95
106
|
}): import("react").JSX.Element;
|
|
96
107
|
/** The eye button inside a secret's box that shows or hides what was typed. Give the box
|
|
97
108
|
* room for it on the right, such as `pr-9`. */
|
|
98
|
-
export declare function RevealToggle({ revealed, onRevealedChange, disabled, }: {
|
|
109
|
+
export declare function RevealToggle({ revealed, onRevealedChange, disabled, align, size, }: {
|
|
99
110
|
revealed: boolean;
|
|
100
111
|
onRevealedChange: (revealed: boolean) => void;
|
|
101
112
|
disabled?: boolean | undefined;
|
|
113
|
+
/** `top` keeps it on the first line of a tall box, such as a textarea's, of the box's
|
|
114
|
+
* `size`. */
|
|
115
|
+
align?: 'center' | 'top' | undefined;
|
|
116
|
+
size?: FieldBoxSize | undefined;
|
|
102
117
|
}): import("react").JSX.Element;
|
|
103
118
|
export interface FieldValueProps extends OutputHTMLAttributes<HTMLOutputElement> {
|
|
104
119
|
/** Matches the height and text of the controls around it, as `size` does on a control. */
|
package/dist/components/Field.js
CHANGED
|
@@ -4,8 +4,8 @@ import { useStrings } from "./Provider.js";
|
|
|
4
4
|
import { focusCameFromKeyboard, trackFocusModality } from "./focus.js";
|
|
5
5
|
import { InfoTip, formatInfoTipContent } from "./InfoTip.js";
|
|
6
6
|
import { RequiredMark } from "./RequiredMark.js";
|
|
7
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
7
|
import { createContext, use, useCallback, useEffect, useId, useLayoutEffect, useState } from "react";
|
|
8
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
import { Field } from "@base-ui/react/field";
|
|
10
10
|
import { Fieldset } from "@base-ui/react/fieldset";
|
|
11
11
|
//#region src/components/Field.tsx
|
|
@@ -68,20 +68,32 @@ var controlFirstExtrasClassName = "ms-1 inline-flex items-center gap-1 align-[-0
|
|
|
68
68
|
var switchOnTwoLines = "has-[[role=switch]]:max-h-[2lh]";
|
|
69
69
|
var switchOnLabelAndDescription = "has-[[role=switch]]:max-h-[calc(1lh+1rem)]";
|
|
70
70
|
var switchRowStartsAtText = "has-[[role=switch]]:-mt-1";
|
|
71
|
-
var errorTextClassName = "
|
|
71
|
+
var errorTextClassName = "items-start gap-1.5 text-xs text-(--theme-error-text)";
|
|
72
|
+
var errorIconClassName = "mt-px size-3.5 shrink-0";
|
|
72
73
|
/** An error in the look a Field gives its own, for a control outside a Field, or for a part of
|
|
73
|
-
* one rather than the whole of it, such as a row of a list editor
|
|
74
|
-
*
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
* one rather than the whole of it, such as a row of a list editor; `size="md"` for an error
|
|
75
|
+
* under a whole form or after an action. It is announced as it appears. Give it an `id` and
|
|
76
|
+
* name it in the control's `aria-describedby` so the error is read with the control. */
|
|
77
|
+
function ErrorText({ id, size = "sm", inline = false, className, children }) {
|
|
78
|
+
if (!children) return null;
|
|
79
|
+
if (inline) return /* @__PURE__ */ jsxs("span", {
|
|
77
80
|
id,
|
|
78
81
|
role: "alert",
|
|
79
|
-
className:
|
|
82
|
+
className: cx("text-(--theme-error-text)", className),
|
|
80
83
|
children: [/* @__PURE__ */ jsx(WarningIcon, {
|
|
81
84
|
"aria-hidden": "true",
|
|
82
|
-
className: "
|
|
85
|
+
className: "me-[0.3em] inline size-[1em] align-[-0.125em]"
|
|
83
86
|
}), children]
|
|
84
|
-
})
|
|
87
|
+
});
|
|
88
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
89
|
+
id,
|
|
90
|
+
role: "alert",
|
|
91
|
+
className: cx("flex", size === "md" ? "items-start gap-2 text-sm text-(--theme-error-text)" : errorTextClassName, className),
|
|
92
|
+
children: [/* @__PURE__ */ jsx(WarningIcon, {
|
|
93
|
+
"aria-hidden": "true",
|
|
94
|
+
className: size === "md" ? "mt-0.5 size-4 shrink-0" : errorIconClassName
|
|
95
|
+
}), children]
|
|
96
|
+
});
|
|
85
97
|
}
|
|
86
98
|
/** A control with its label, help and error, tied to it for assistive technology. One frame
|
|
87
99
|
* for every field, in a form or standing alone. */
|
|
@@ -146,8 +158,8 @@ function Field$1({ label, hint, help, actions, description, error, invalid, requ
|
|
|
146
158
|
}
|
|
147
159
|
} : {};
|
|
148
160
|
const labelBox = cx(labelClassName, labelSize.text, inline && cx(labelSize.inlineHeight, "shrink-0", compact ? "mr-2 w-fit" : "w-52 pr-3 max-sm:min-h-0 max-sm:w-full max-sm:pr-0"), inRow && "row-start-1 self-end");
|
|
149
|
-
const nameContent = /* @__PURE__ */ jsxs(Fragment, { children: [label, required && /* @__PURE__ */ jsx(RequiredMark, {})] });
|
|
150
|
-
const labelExtras = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
161
|
+
const nameContent = /* @__PURE__ */ jsxs(Fragment$1, { children: [label, required && /* @__PURE__ */ jsx(RequiredMark, {})] });
|
|
162
|
+
const labelExtras = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
151
163
|
helpTip,
|
|
152
164
|
hint,
|
|
153
165
|
actions && /* @__PURE__ */ jsx("span", {
|
|
@@ -163,7 +175,7 @@ function Field$1({ label, hint, help, actions, description, error, invalid, requ
|
|
|
163
175
|
children: placed
|
|
164
176
|
})
|
|
165
177
|
});
|
|
166
|
-
const messages = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
178
|
+
const messages = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
167
179
|
description && /* @__PURE__ */ jsx(Field.Description, {
|
|
168
180
|
id: descriptionId,
|
|
169
181
|
className: cx("text-xs text-(--theme-muted-text-color)", controlFirst && !group ? "leading-4" : "leading-relaxed"),
|
|
@@ -178,10 +190,10 @@ function Field$1({ label, hint, help, actions, description, error, invalid, requ
|
|
|
178
190
|
id: errorId,
|
|
179
191
|
match: true,
|
|
180
192
|
role: "alert",
|
|
181
|
-
className: errorTextClassName,
|
|
193
|
+
className: cx("flex", errorTextClassName),
|
|
182
194
|
children: [/* @__PURE__ */ jsx(WarningIcon, {
|
|
183
195
|
"aria-hidden": "true",
|
|
184
|
-
className:
|
|
196
|
+
className: errorIconClassName
|
|
185
197
|
}), error]
|
|
186
198
|
})
|
|
187
199
|
] });
|
|
@@ -286,7 +298,7 @@ function FieldOption({ disabled, className, children }) {
|
|
|
286
298
|
}
|
|
287
299
|
/** The eye button inside a secret's box that shows or hides what was typed. Give the box
|
|
288
300
|
* room for it on the right, such as `pr-9`. */
|
|
289
|
-
function RevealToggle({ revealed, onRevealedChange, disabled }) {
|
|
301
|
+
function RevealToggle({ revealed, onRevealedChange, disabled, align = "center", size = "md" }) {
|
|
290
302
|
const { common: t } = useStrings();
|
|
291
303
|
const Icon = revealed ? EyeOffIcon : EyeIcon;
|
|
292
304
|
return /* @__PURE__ */ jsx("button", {
|
|
@@ -295,7 +307,11 @@ function RevealToggle({ revealed, onRevealedChange, disabled }) {
|
|
|
295
307
|
"aria-pressed": revealed,
|
|
296
308
|
disabled,
|
|
297
309
|
onClick: () => onRevealedChange(!revealed),
|
|
298
|
-
className: "absolute
|
|
310
|
+
className: cx("absolute right-0 flex w-9 cursor-pointer items-center justify-center text-(--theme-muted-text-color) hover:text-(--theme-app) disabled:cursor-not-allowed disabled:opacity-50", align === "top" ? cx("top-0", {
|
|
311
|
+
sm: "h-7",
|
|
312
|
+
md: "h-8",
|
|
313
|
+
lg: "h-10"
|
|
314
|
+
}[size]) : "inset-y-0"),
|
|
299
315
|
children: /* @__PURE__ */ jsx(Icon, {
|
|
300
316
|
"aria-hidden": "true",
|
|
301
317
|
className: "size-4"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ButtonHTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import type { ButtonStyle } from './buttonClasses.js';
|
|
3
|
+
export interface FileButtonProps extends ButtonStyle, Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'type' | 'onChange' | 'children' | 'className'> {
|
|
4
|
+
/** The file types offered, as the file input's `accept`, such as `image/*` or `.pem,.crt`. */
|
|
5
|
+
accept?: string | undefined;
|
|
6
|
+
multiple?: boolean | undefined;
|
|
7
|
+
/** The files picked, never empty. Picking the same file again calls it again. */
|
|
8
|
+
onFiles: (files: File[]) => void;
|
|
9
|
+
/** Before the label. */
|
|
10
|
+
icon?: ReactNode;
|
|
11
|
+
/** Busy with the files: see `Button`'s `loading`. */
|
|
12
|
+
loading?: boolean | undefined;
|
|
13
|
+
className?: string | undefined;
|
|
14
|
+
children?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
/** A button that opens the file picker, such as Upload logo. It is a real button,
|
|
17
|
+
* so Tab reaches it and Enter or Space opens the picker, where a label over a
|
|
18
|
+
* hidden file input can't be focused. */
|
|
19
|
+
export declare function FileButton({ accept, multiple, onFiles, onClick, ...props }: FileButtonProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Button } from "./Button.js";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/FileButton.tsx
|
|
5
|
+
/** A button that opens the file picker, such as Upload logo. It is a real button,
|
|
6
|
+
* so Tab reaches it and Enter or Space opens the picker, where a label over a
|
|
7
|
+
* hidden file input can't be focused. */
|
|
8
|
+
function FileButton({ accept, multiple = false, onFiles, onClick, ...props }) {
|
|
9
|
+
const input = useRef(null);
|
|
10
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button, {
|
|
11
|
+
...props,
|
|
12
|
+
onClick: (event) => {
|
|
13
|
+
onClick?.(event);
|
|
14
|
+
if (!event.defaultPrevented) input.current?.click();
|
|
15
|
+
}
|
|
16
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
17
|
+
ref: input,
|
|
18
|
+
type: "file",
|
|
19
|
+
hidden: true,
|
|
20
|
+
tabIndex: -1,
|
|
21
|
+
"aria-hidden": "true",
|
|
22
|
+
accept,
|
|
23
|
+
multiple,
|
|
24
|
+
onChange: (event) => {
|
|
25
|
+
const files = Array.from(event.currentTarget.files ?? []);
|
|
26
|
+
event.currentTarget.value = "";
|
|
27
|
+
if (files.length > 0) onFiles(files);
|
|
28
|
+
}
|
|
29
|
+
})] });
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { FileButton };
|
|
@@ -1,14 +1,34 @@
|
|
|
1
|
-
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type { PointerEventHandler, ReactElement, ReactNode } from 'react';
|
|
2
|
+
/** What a hover card opens from: its own anchor, which opens it on hover or focus,
|
|
3
|
+
* or an element the host watches itself and opens it at, such as a term in
|
|
4
|
+
* rendered text that one listener on the page serves for every term. */
|
|
5
|
+
type HoverCardOpener = {
|
|
5
6
|
/** The anchor. It receives the trigger's props and ref, so it must pass them to its element. */
|
|
6
7
|
children: ReactElement;
|
|
8
|
+
at?: never;
|
|
9
|
+
} | {
|
|
10
|
+
/** The element it opens at while `open`. The host opens and closes it, with its own
|
|
11
|
+
* delays; Escape and a press outside ask it to close through `onOpenChange`. Null
|
|
12
|
+
* keeps it closed. */
|
|
13
|
+
at: Element | null;
|
|
14
|
+
children?: never;
|
|
15
|
+
};
|
|
16
|
+
export type HoverCardProps = HoverCardOpener & {
|
|
17
|
+
/** Mounted only while open, so a card that loads its own data loads on first hover. */
|
|
18
|
+
card: ReactNode;
|
|
7
19
|
/** Opens on first render, for stories and screenshots. */
|
|
8
20
|
defaultOpen?: boolean;
|
|
9
|
-
|
|
21
|
+
/** Open from outside, as with `at`. */
|
|
22
|
+
open?: boolean | undefined;
|
|
23
|
+
onOpenChange?: ((open: boolean) => void) | undefined;
|
|
24
|
+
/** The pointer entered or left the card, so a host opening it with `at` can keep
|
|
25
|
+
* it open while the reader is over it. */
|
|
26
|
+
onPointerEnter?: PointerEventHandler<HTMLDivElement> | undefined;
|
|
27
|
+
onPointerLeave?: PointerEventHandler<HTMLDivElement> | undefined;
|
|
28
|
+
};
|
|
10
29
|
/** Detail about its anchor, such as a person's profile, after a short hover or
|
|
11
30
|
* on focus. A visual enhancement: whatever the card shows must also be
|
|
12
31
|
* reachable another way, such as the page the anchor links to. The card
|
|
13
32
|
* stays open while the pointer is over it. */
|
|
14
|
-
export declare function HoverCard({ card, children, defaultOpen }: HoverCardProps): import("react").JSX.Element;
|
|
33
|
+
export declare function HoverCard({ card, children, at, defaultOpen, open, onOpenChange, onPointerEnter, onPointerLeave, }: HoverCardProps): import("react").JSX.Element;
|
|
34
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cardClassName, positionerClassName } from "./floating.js";
|
|
2
|
-
import {
|
|
2
|
+
import { usePopupContainer } from "./popupContainer.js";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { PreviewCard } from "@base-ui/react/preview-card";
|
|
5
5
|
//#region src/components/HoverCard.tsx
|
|
@@ -18,25 +18,31 @@ var pressHandlers = {
|
|
|
18
18
|
* on focus. A visual enhancement: whatever the card shows must also be
|
|
19
19
|
* reachable another way, such as the page the anchor links to. The card
|
|
20
20
|
* stays open while the pointer is over it. */
|
|
21
|
-
function HoverCard({ card, children, defaultOpen = false }) {
|
|
22
|
-
const
|
|
21
|
+
function HoverCard({ card, children, at, defaultOpen = false, open, onOpenChange, onPointerEnter, onPointerLeave }) {
|
|
22
|
+
const portal = usePopupContainer();
|
|
23
|
+
const shown = at !== void 0 ? Boolean(open && at) : open;
|
|
23
24
|
return /* @__PURE__ */ jsxs(PreviewCard.Root, {
|
|
24
25
|
defaultOpen,
|
|
25
|
-
|
|
26
|
+
...shown === void 0 ? {} : { open: shown },
|
|
27
|
+
...onOpenChange ? { onOpenChange: (next) => onOpenChange(next) } : {},
|
|
28
|
+
children: [children && /* @__PURE__ */ jsx(PreviewCard.Trigger, {
|
|
26
29
|
delay: 350,
|
|
27
30
|
closeDelay: 150,
|
|
28
31
|
render: children
|
|
29
32
|
}), /* @__PURE__ */ jsx(PreviewCard.Portal, {
|
|
30
|
-
|
|
33
|
+
...portal,
|
|
31
34
|
children: /* @__PURE__ */ jsx(PreviewCard.Positioner, {
|
|
32
35
|
side: "bottom",
|
|
33
36
|
align: "start",
|
|
34
37
|
sideOffset: 8,
|
|
35
38
|
collisionPadding: 8,
|
|
39
|
+
...at ? { anchor: at } : {},
|
|
36
40
|
className: positionerClassName,
|
|
37
41
|
children: /* @__PURE__ */ jsx(PreviewCard.Popup, {
|
|
38
42
|
className: cardClassName,
|
|
39
43
|
...pressHandlers,
|
|
44
|
+
onPointerEnter,
|
|
45
|
+
onPointerLeave,
|
|
40
46
|
children: card
|
|
41
47
|
})
|
|
42
48
|
})
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
2
|
import { buttonClasses } from "./buttonClasses.js";
|
|
3
|
+
import { ariaKeyShortcuts } from "./Kbd.js";
|
|
3
4
|
import { Tooltip } from "./Tooltip.js";
|
|
4
5
|
import { AppLink } from "./AppLink.js";
|
|
5
6
|
import { useShortcutKey } from "./shortcutKey.js";
|
|
6
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { useCallback, useRef } from "react";
|
|
8
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
9
|
//#region src/components/IconButton.tsx
|
|
9
10
|
/** A button that shows only an icon, named by its tooltip, or with `href` a
|
|
10
11
|
* link that looks like one. It can be a popup's trigger: it passes the
|
|
@@ -19,13 +20,14 @@ function IconButton({ icon, label, variant = "ghost", size = "sm", pressed, dot
|
|
|
19
20
|
}, [ref]);
|
|
20
21
|
const shared = {
|
|
21
22
|
"aria-label": label,
|
|
23
|
+
"aria-keyshortcuts": shortcut ? ariaKeyShortcuts(shortcut) : void 0,
|
|
22
24
|
className: cx(buttonClasses({
|
|
23
25
|
variant,
|
|
24
26
|
size,
|
|
25
27
|
iconOnly: true
|
|
26
28
|
}), className)
|
|
27
29
|
};
|
|
28
|
-
const content = /* @__PURE__ */ jsxs(Fragment, { children: [icon, dot && /* @__PURE__ */ jsx("span", { className: "absolute right-0 top-0 h-1.5 w-1.5 rounded-full bg-(--theme-link)" })] });
|
|
30
|
+
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [icon, dot && /* @__PURE__ */ jsx("span", { className: "absolute right-0 top-0 h-1.5 w-1.5 rounded-full bg-(--theme-link)" })] });
|
|
29
31
|
useShortcutKey(shortcut, () => button.current?.click());
|
|
30
32
|
return /* @__PURE__ */ jsx(Tooltip, {
|
|
31
33
|
content: label,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
2
|
import { HelpIcon } from "../icons.js";
|
|
3
|
-
import { keyedByContent } from "./keys.js";
|
|
4
3
|
import { useStrings } from "./Provider.js";
|
|
4
|
+
import { keyedByContent } from "./keys.js";
|
|
5
5
|
import { ExternalLink } from "./ExternalLink.js";
|
|
6
6
|
import { Popover } from "./Popover.js";
|
|
7
|
+
import { Fragment } from "react";
|
|
7
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import { Fragment as Fragment$1 } from "react";
|
|
9
9
|
//#region src/components/InfoTip.tsx
|
|
10
10
|
var linkRegex = /\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g;
|
|
11
11
|
function formatLine(line) {
|
|
@@ -26,7 +26,7 @@ function formatLine(line) {
|
|
|
26
26
|
/** Infotip text can come from untrusted sources (workflow YAML), so all markup is literal text — only `[text](url)` links and newlines are parsed. */
|
|
27
27
|
function formatInfoTipContent(content) {
|
|
28
28
|
if (!content) return null;
|
|
29
|
-
return keyedByContent(content.split(/<br\s*\/?>|\n/i), (l) => l).map(({ key, item: line }, idx) => /* @__PURE__ */ jsxs(Fragment
|
|
29
|
+
return keyedByContent(content.split(/<br\s*\/?>|\n/i), (l) => l).map(({ key, item: line }, idx) => /* @__PURE__ */ jsxs(Fragment, { children: [idx > 0 && /* @__PURE__ */ jsx("br", {}), formatLine(line)] }, key));
|
|
30
30
|
}
|
|
31
31
|
var hasLink = (content) => new RegExp(linkRegex.source).test(content);
|
|
32
32
|
/** Extra detail behind an info trigger. A popover that also opens on hover, so
|
|
@@ -21,6 +21,19 @@ export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>,
|
|
|
21
21
|
}
|
|
22
22
|
export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement>, FramedProps {
|
|
23
23
|
ref?: Ref<HTMLTextAreaElement> | undefined;
|
|
24
|
+
/** Grows with its text instead of scrolling, from `rows` lines up to `maxRows`, past which
|
|
25
|
+
* it scrolls. */
|
|
26
|
+
autosize?: boolean | {
|
|
27
|
+
maxRows?: number | undefined;
|
|
28
|
+
} | undefined;
|
|
29
|
+
/** Draws no box of its own, for a textarea in a frame that draws one, such as a comment
|
|
30
|
+
* composer with its buttons: frame it with `fieldBox({ multiline: true, within: true })`.
|
|
31
|
+
* It has no padding either, so the frame's own lines up with what is around it. */
|
|
32
|
+
bare?: boolean | undefined;
|
|
33
|
+
/** Hides what is typed, as a password field does, with a button that shows it: for a
|
|
34
|
+
* private key or a certificate. It is monospace, unchecked for spelling and left alone by
|
|
35
|
+
* password managers and autofill. */
|
|
36
|
+
secret?: boolean | undefined;
|
|
24
37
|
}
|
|
25
38
|
/** The Field around a control when it has a label; the control alone when it doesn't. */
|
|
26
39
|
export declare function framed({ label, hint, help, actions, description, error, size, }: Omit<FramedProps, 'mono'> & {
|
|
@@ -33,7 +46,24 @@ export declare function framed({ label, hint, help, actions, description, error,
|
|
|
33
46
|
/** A single-line text field. `type="password"` adds a button that shows what was typed. Placed in
|
|
34
47
|
* a Field, it takes the Field's label, description and invalid state. */
|
|
35
48
|
export declare function Input({ label, hint, help, description, error, className, mono, size, type, ref, ...props }: InputProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
|
|
36
|
-
/** A multi-line text field that grows by hand
|
|
37
|
-
* description and invalid state. */
|
|
38
|
-
export declare function Textarea({ label, hint, help, description, error, className, mono, size, ref, ...props }: TextareaProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
|
|
49
|
+
/** A multi-line text field that grows by hand, or with its text with `autosize`. Placed in a
|
|
50
|
+
* Field, it takes the Field's label, description and invalid state. */
|
|
51
|
+
export declare function Textarea({ label, hint, help, description, error, className, mono, size, ref, autosize, bare, secret, style, ...props }: TextareaProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
|
|
52
|
+
export interface TitleInputProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'defaultValue' | 'onChange' | 'rows' | 'aria-label'> {
|
|
53
|
+
/** The saved title. Changes from outside show while the title isn't being edited. */
|
|
54
|
+
value: string;
|
|
55
|
+
/** Called with the trimmed title when an edit ends with a change: on Enter or on leaving
|
|
56
|
+
* the field. An empty title isn't committed; the saved one comes back. */
|
|
57
|
+
onCommit: (value: string) => void;
|
|
58
|
+
'aria-label': string;
|
|
59
|
+
/** Focuses the title and selects its text as it appears, such as for a thing just made. */
|
|
60
|
+
autoSelect?: boolean | undefined;
|
|
61
|
+
/** `xl` for a page's own title, `lg` for one in a panel or drawer. */
|
|
62
|
+
size?: 'lg' | 'xl' | undefined;
|
|
63
|
+
ref?: Ref<HTMLTextAreaElement> | undefined;
|
|
64
|
+
}
|
|
65
|
+
/** A title edited where it reads: one line that wraps and grows, with no box until the
|
|
66
|
+
* pointer or focus is on it. Enter saves, Escape puts the saved title back, and leaving the
|
|
67
|
+
* field saves. */
|
|
68
|
+
export declare function TitleInput({ value, onCommit, autoSelect, size, readOnly, className, onBlur, onFocus, onKeyDown, ref, ...props }: TitleInputProps): import("react").JSX.Element;
|
|
39
69
|
export {};
|