@reopt-ai/opt-ui 1.12.4 → 1.13.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/CHANGELOG.md +236 -0
- package/COMPONENT_CATALOG.md +290 -111
- package/dist/core/index.cjs +13 -13
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +2 -2
- package/dist/docs/02-components/01-core.md +49 -49
- package/dist/docs/02-components/02-visuals.md +1 -1
- package/dist/docs/02-components/03-shells.md +260 -63
- package/dist/docs/02-components/04-surfaces.md +1 -1
- package/dist/docs/02-components/index.md +4 -4
- package/dist/{field-sidebar-C8bDzGPs.js → field-sidebar-CRdToHRO.js} +3975 -235
- package/dist/{field-sidebar-DX5wP0qn.cjs → field-sidebar-CxxSK4JO.cjs} +4338 -244
- package/dist/{field-sidebar-Ct8c9L4V.d.cts → field-sidebar-D-rwuN_w.d.cts} +824 -2
- package/dist/{field-sidebar-YaWHfLLW.d.ts → field-sidebar-Dz7J4ett.d.ts} +824 -2
- package/dist/id-registry.cjs +72 -0
- package/dist/id-registry.js +72 -0
- package/dist/id-registry.json +153 -0
- package/dist/index.cjs +334 -1419
- package/dist/index.d.cts +51 -86
- package/dist/index.d.ts +51 -86
- package/dist/index.js +248 -1356
- package/dist/{key-pad-menu-1YN221Oi.cjs → key-pad-menu-0KWOnELe.cjs} +53 -483
- package/dist/{key-pad-menu-CwcY_Vps.d.cts → key-pad-menu-BOVu97bj.d.cts} +4 -55
- package/dist/{key-pad-menu-CUiQ-vKw.js → key-pad-menu-DMmbQ1jF.js} +54 -418
- package/dist/{key-pad-menu-WBJShCJn.d.ts → key-pad-menu-NlZ9zNF8.d.ts} +4 -55
- package/dist/meta.cjs +896 -7
- package/dist/meta.js +896 -7
- package/dist/shells/index.cjs +20 -1
- package/dist/shells/index.d.cts +2 -2
- package/dist/shells/index.d.ts +2 -2
- package/dist/shells/index.js +2 -2
- package/dist/{text-truncate-BFWd2cE_.js → text-truncate-Bd-0WkSP.js} +463 -99
- package/dist/{text-truncate-DsG5UAOY.cjs → text-truncate-BeYW6XZu.cjs} +525 -101
- package/dist/{text-truncate-CQyfUZvq.d.cts → text-truncate-eMzvU_7k.d.cts} +52 -1
- package/dist/{text-truncate-CQyfUZvq.d.ts → text-truncate-eMzvU_7k.d.ts} +52 -1
- package/dist/theme/server.cjs +2 -2
- package/dist/theme/server.js +2 -2
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -1,114 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { $ as
|
|
3
|
-
import { $ as
|
|
4
|
-
import { $ as
|
|
2
|
+
import { $ as useFormContext, $n as OPT_HOVER_ITEM, $t as CompositeItem, A as FormGroup, An as SkeletonText, At as AlertDialogPanel, B as FormRemove, Bn as OPT_BADGE_NEUTRAL, Bt as SelectItem, C as FormCheckbox, Cn as koComboboxLabels, Ct as ComboboxEmpty, D as FormDescription, Dn as SkeletonAvatar, Dt as ComboboxItem, E as FormDateRangePicker, En as Skeleton, Et as ComboboxInput, F as FormNumberInput, Ft as DialogFooter, G as FormSelectPopover, Gt as Tab, H as FormRoot, Hn as OPT_BADGE_YELLOW, Ht as SelectPopover, I as FormProvider, It as DialogHeader, J as FormSubmit, Jn as OPT_DOT_GREEN, Jt as TabsRoot, K as FormSlider, Kt as TabList, L as FormPush, Lt as DialogHeading, M as FormIconPicker, Mt as DialogDescription, N as FormInput, Nt as DialogDisclosure, O as FormError, On as SkeletonCard, Ot as ComboboxPopover, P as FormLabel, Pt as DialogDismiss, Q as useFieldValue, Qn as OPT_FOCUS_VISIBLE, Qt as Composite, R as FormRadio, Rn as OPT_BADGE_BLUE, Rt as DialogPanel, S as formatOptTime, Sn as koBreadcrumbLabels, St as MenubarRoot, T as FormControl, Tn as StatCard, Tt as ComboboxGroupLabel, U as FormSelect, Un as OPT_BORDER, Ut as SelectRoot, V as FormReset, Vn as OPT_BADGE_RED, Vt as SelectLabel, W as FormSelectItem, Wt as SelectTrigger, X as FormTagInput, Xn as OPT_DOT_YELLOW, Xt as DisclosureRoot, Y as FormSwitch, Yn as OPT_DOT_RED, Yt as DisclosureContent, Z as FormTextarea, Zn as OPT_FOCUS, Zt as DisclosureTrigger, _ as DropdownTrigger, _n as Spinner, _r as cn, _t as MenuPopover, a as FieldTokenLegend, an as StarRating, at as getIconRegistryEntry, b as formatOptNumber, bn as EmptyState, bt as MenuTrigger, c as ResizableHandle, cn as useInputId, ct as PopoverContent, d as Checkbox, dn as ToolbarRoot, dr as OPT_TEXT_SECONDARY, dt as Slider, en as CompositeProvider, er as OPT_INPUT, et as useFormStore, f as CheckboxGroup, fn as ToolbarSeparator, fr as OPT_TEXT_TERTIARY, ft as NumberInput, g as DropdownSeparator, gn as Alert, gr as Kbd, gt as MenuItemRadio, h as DropdownMenu, hn as TooltipProvider, hr as _objectWithoutProperties, ht as MenuItemCheckbox, i as FieldToken, in as Textarea, it as IconPicker, j as FormGroupLabel, jn as useControlledState, jt as DialogBody, k as FormField, kn as SkeletonTable, kt as ComboboxRoot, l as ResizablePanel, ln as ToolbarButton, lt as PopoverRoot, m as DropdownItem, mn as TooltipAnchor, mr as _objectSpread2, mt as MenuItem, n as Highlight, nn as CompositeZone, nt as DateRangePicker, o as resolveFieldType, on as Switch, ot as ColorPicker, p as DropdownContent, pn as Tooltip, pr as OPT_TH, pt as MenuButtonArrow, q as FormStarRating, qn as OPT_DOT_GRAY, qt as TabPanel, r as FIELD_TYPE_TOKENS, rn as Meter, rt as TagInput, s as Pagination, sn as Input, sr as OPT_TD, st as PopoverClose, t as TextTruncate, tn as CompositeRow, tt as DEFAULT_PRESETS, u as ResizablePanelGroup, un as ToolbarContainer, ur as OPT_TEXT_PRIMARY, ut as PopoverTrigger, vn as Badge, vt as MenuRoot, w as FormColorPicker, wn as koStarRatingLabels, wt as ComboboxGroup, x as formatOptShortDate, xn as Button, xt as MenubarContainer, y as formatOptDateTime, yn as DescriptionList, yt as MenuSeparator, z as FormRadioGroup, zn as OPT_BADGE_GREEN, zt as DialogRoot } from "./text-truncate-Bd-0WkSP.js";
|
|
3
|
+
import { $ as OtpField, A as LoadingOverlay, B as CardFooter, C as Logo, D as PageHeader, E as ScrollArea, F as CircularProgress, G as AvatarGroup, H as CardTitle, I as Progress, J as AccordionItem, K as Breadcrumb, L as Card, M as RadioGroup, N as ConditionBuilder, O as createBlock, P as StepBuilder, Q as ToggleGroup, R as CardContent, S as DrawerRoot, T as Container, U as Identity, V as CardHeader, W as Avatar, X as AccordionTrigger, Y as AccordionRoot, Z as Toggle, _ as getShaderFragment, a as THEME_PALETTES, b as DrawerClose, c as ExpressionGroup, d as ShaderSurface, et as Separator, f as SHADER_OVERLAY_PARAM_KEYS, g as SHADER_PRESET_IDS, h as SHADER_PRESETS, i as ColorPalettePicker, j as Radio, k as BlockLayout, l as Facet, m as SHADER_PARAM_KEYS, n as InlineEdit, nt as Text, o as LiveRegion, p as SHADER_PARAM_FALLBACK, q as AccordionContent, r as ColorPaletteDisplay, s as Expression, t as KeyPadMenu, tt as Heading, u as FacetGroup, v as getShaderPreset, w as Section, x as DrawerPanel, y as VirtualList, z as CardDescription } from "./key-pad-menu-DMmbQ1jF.js";
|
|
4
|
+
import { $ as generatedTheme, $t as Command, A as useOptThemeController, At as KeyValueEditor, B as THEME_SPEC_STORAGE_KEY, Bt as ProjectSwitcher, C as ScoreBreakdown, Ct as QueryOutputPane, D as useOptTheme, Dt as formatQueryCell, E as OptThemeProvider, Et as QueryResultsTable, F as getCompoundTheme, Ft as useToast, G as isForceLightSpec, Gt as EditorToolbar, H as buildTokenCache, Ht as SettingsForm, I as readStoredTheme, It as DataTable, J as safeParseStoredTokens, Jt as StatusSelect, K as resolveDescriptor, Kt as SidebarNav, L as resolveThemeMode, Lt as DomainTable, M as FORCE_LIGHT_PRESETS, Mt as NotificationToast, N as coerceThemeMode, Nt as ToastProvider, O as useOptionalOptTheme, Ot as Flyout, P as createThemeBootScript, Pt as toast, Q as defineThemeOverrides, Qt as CommandPalette, R as GENERATED_THEME_ID_DEFAULT, Rt as BranchSelect, S as withoutField, St as numericResultColumns, T as SqlEditor, Tt as SchemaTree, U as computeGeneratedTokens, Ut as FaqAccordion, V as THEME_TOKENS_STORAGE_KEY, Vt as DeploymentTimeline, W as getCompoundIdForSpec, Wt as ContentTabs, X as serializeThemeRule, Xt as DashboardGrid, Y as serializeGeneratedTheme, Yt as SearchCombobox, Z as serializeTokenBody, Zt as CommandPaletteTrigger, _ as fieldValues, _t as VALUELESS_OPERATORS, a as TimeRangeControl, an as CommandList, at as THEME_PRESET_IDS, b as removeClause, bt as QueryResultChart, c as describeClause, cn as SegmentedControl, ct as isThemePresetId, d as quoteValue, dt as SaveQueryDialog, en as CommandDialog, et as isDescriptorSpec, f as parseQuery, ft as QueryHistoryList, g as applyCellAction, gt as QueryFiltersMenu, h as addClause, ht as EMPTY_QUERY_FILTERS, i as DEFAULT_TIME_PRESETS, in as CommandItem, it as FORCE_LIGHT_PRESET_IDS, j as ALL_COMPOUND_THEMES, jt as FailureList, k as OptThemeControllerContext, kt as WorkflowCanvas, l as formatClause, ln as Callout, lt as QueryWorkspace, m as EMPTY_QUERY, mt as isValidQueryVariableName, n as LogTable, nn as CommandGroup, nt as isPresetSpec, o as useAutoRefresh, on as CommandSeparator, ot as THEME_REGISTRY, p as parseQueryWithDiagnostics, pt as QueryVariablesMenu, q as safeParseStoredSpec, qt as AppMenubar, r as TimeSeriesPanel, rn as CommandInput, rt as presetTheme, s as QueryBar, sn as CommandShortcut, st as getThemeDescriptor, t as FieldSidebar, tn as CommandEmpty, tt as isGeneratedSpec, u as formatQuery, ut as useMediaQuery, v as isEmptyQuery, vt as countActiveQueryFilters, w as EventTimeline, wt as QueryToolbar, x as withFieldValue, xt as defaultQueryChartConfig, y as queryFields, yt as hasActiveQueryFilters, z as GLOBAL_THEME_STYLE_ID, zt as EnvPanel } from "./field-sidebar-CRdToHRO.js";
|
|
5
5
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import * as React from "react";
|
|
7
|
-
import { Component,
|
|
8
|
-
import {
|
|
9
|
-
import { Check, ChevronDown, CircleAlert, CircleCheck, Copy, FilePen, GitMerge, Info, MessageSquare, MoreHorizontal, Pencil, Rocket, Search, Sparkles, Trash2, TriangleAlert, User, X } from "lucide-react";
|
|
10
|
-
import { generatePalette } from "@reopt-ai/opt-palette";
|
|
7
|
+
import { Component, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
8
|
+
import { Check, ChevronDown, CircleCheck, Copy, FilePen, GitMerge, MessageSquare, MoreHorizontal, Pencil, Rocket, Search, Sparkles, Trash2, User, X } from "lucide-react";
|
|
11
9
|
import { EventSparkline, MetricsCard, ReportWidget, TrendChart } from "@reopt-ai/opt-charts";
|
|
12
10
|
import { matchSorter } from "match-sorter";
|
|
13
11
|
import { usePathname } from "next/navigation";
|
|
14
12
|
export * from "@reopt-ai/opt-charts";
|
|
15
|
-
//#region src/core/callout.tsx
|
|
16
|
-
const _excluded$2 = [
|
|
17
|
-
"tone",
|
|
18
|
-
"title",
|
|
19
|
-
"icon",
|
|
20
|
-
"action",
|
|
21
|
-
"size",
|
|
22
|
-
"className",
|
|
23
|
-
"children"
|
|
24
|
-
];
|
|
25
|
-
const toneStyles = {
|
|
26
|
-
info: "border-info/40 bg-info-subtle",
|
|
27
|
-
success: "border-success/40 bg-success-subtle",
|
|
28
|
-
warning: "border-warning/40 bg-warning-subtle",
|
|
29
|
-
danger: "border-danger/40 bg-danger-subtle",
|
|
30
|
-
neutral: "border-border bg-bg-subtle"
|
|
31
|
-
};
|
|
32
|
-
const iconTone = {
|
|
33
|
-
info: "text-info-fg",
|
|
34
|
-
success: "text-success-fg",
|
|
35
|
-
warning: "text-warning-fg",
|
|
36
|
-
danger: "text-danger-fg",
|
|
37
|
-
neutral: "text-text-tertiary"
|
|
38
|
-
};
|
|
39
|
-
const titleTone = {
|
|
40
|
-
info: "text-info-fg",
|
|
41
|
-
success: "text-success-fg",
|
|
42
|
-
warning: "text-warning-fg",
|
|
43
|
-
danger: "text-danger-fg",
|
|
44
|
-
neutral: "text-text-primary"
|
|
45
|
-
};
|
|
46
|
-
const defaultIcons = {
|
|
47
|
-
info: Info,
|
|
48
|
-
success: CircleCheck,
|
|
49
|
-
warning: TriangleAlert,
|
|
50
|
-
danger: CircleAlert,
|
|
51
|
-
neutral: null
|
|
52
|
-
};
|
|
53
|
-
const sizeStyles$3 = {
|
|
54
|
-
sm: "gap-2 p-2.5 text-xs [&_svg]:size-3.5",
|
|
55
|
-
md: "gap-3 p-3 text-sm [&_svg]:size-4"
|
|
56
|
-
};
|
|
57
|
-
/**
|
|
58
|
-
* Callout — a notice that belongs to the page, not to the moment.
|
|
59
|
-
*
|
|
60
|
-
* `Alert` reports something that just happened and can be dismissed once read.
|
|
61
|
-
* A callout is the opposite: it is part of the layout, it is true for as long
|
|
62
|
-
* as the condition holds, and dismissing it would only hide a fact that is
|
|
63
|
-
* still true. "12 new events to triage" above a list, or "these numbers come
|
|
64
|
-
* from a 10,000-row sample" above a chart — both are read many times and
|
|
65
|
-
* dismissed never.
|
|
66
|
-
*
|
|
67
|
-
* That is why there is no `onDismiss` here, and why `action` takes one control:
|
|
68
|
-
* a notice earns its space by naming the single thing to do about it.
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```tsx
|
|
72
|
-
* <Callout tone="info" title="정리할 신규 이벤트 12개"
|
|
73
|
-
* action={<Button size="sm" onClick={showNew}>보기</Button>}>
|
|
74
|
-
* 7일 안에 처음 관측된 이벤트입니다.
|
|
75
|
-
* </Callout>
|
|
76
|
-
* ```
|
|
77
|
-
*/
|
|
78
|
-
function Callout(_ref) {
|
|
79
|
-
let { tone = "info", title, icon, action, size = "md", className, children } = _ref, props = _objectWithoutProperties(_ref, _excluded$2);
|
|
80
|
-
const DefaultIcon = defaultIcons[tone];
|
|
81
|
-
const glyph = icon === void 0 ? DefaultIcon ? /* @__PURE__ */ jsx(DefaultIcon, { "aria-hidden": "true" }) : null : icon;
|
|
82
|
-
return /* @__PURE__ */ jsxs("div", _objectSpread2(_objectSpread2({
|
|
83
|
-
role: "status",
|
|
84
|
-
className: cn("flex items-start rounded-lg border", toneStyles[tone], sizeStyles$3[size], className)
|
|
85
|
-
}, props), {}, {
|
|
86
|
-
"data-opt-id": "AT7TX",
|
|
87
|
-
"data-opt-slug": "callout.Callout",
|
|
88
|
-
"data-tone": tone,
|
|
89
|
-
children: [
|
|
90
|
-
glyph && /* @__PURE__ */ jsx("span", {
|
|
91
|
-
className: cn("mt-0.5 shrink-0", iconTone[tone]),
|
|
92
|
-
children: glyph
|
|
93
|
-
}),
|
|
94
|
-
/* @__PURE__ */ jsxs("div", {
|
|
95
|
-
className: "min-w-0 flex-1",
|
|
96
|
-
children: [title && /* @__PURE__ */ jsx("p", {
|
|
97
|
-
className: cn("font-medium", titleTone[tone]),
|
|
98
|
-
children: title
|
|
99
|
-
}), children && /* @__PURE__ */ jsx("div", {
|
|
100
|
-
className: cn("text-text-secondary", title && "mt-1"),
|
|
101
|
-
children
|
|
102
|
-
})]
|
|
103
|
-
}),
|
|
104
|
-
action && /* @__PURE__ */ jsx("div", {
|
|
105
|
-
className: "shrink-0 self-center",
|
|
106
|
-
children: action
|
|
107
|
-
})
|
|
108
|
-
]
|
|
109
|
-
}));
|
|
110
|
-
}
|
|
111
|
-
//#endregion
|
|
112
13
|
//#region src/core/status-dot.tsx
|
|
113
14
|
const _excluded$1 = [
|
|
114
15
|
"tone",
|
|
@@ -133,7 +34,7 @@ const textTone = {
|
|
|
133
34
|
warning: "text-text-secondary",
|
|
134
35
|
danger: "text-text-secondary"
|
|
135
36
|
};
|
|
136
|
-
const sizeStyles$
|
|
37
|
+
const sizeStyles$1 = {
|
|
137
38
|
sm: "gap-1.5 text-[11px]",
|
|
138
39
|
md: "gap-2 text-xs"
|
|
139
40
|
};
|
|
@@ -164,7 +65,7 @@ const dotSize = {
|
|
|
164
65
|
function StatusDot(_ref) {
|
|
165
66
|
let { tone = "neutral", size = "md", hint, className, children } = _ref, props = _objectWithoutProperties(_ref, _excluded$1);
|
|
166
67
|
const dot = /* @__PURE__ */ jsxs("span", _objectSpread2(_objectSpread2({
|
|
167
|
-
className: cn("inline-flex items-center whitespace-nowrap", sizeStyles$
|
|
68
|
+
className: cn("inline-flex items-center whitespace-nowrap", sizeStyles$1[size], textTone[tone], hint && "focus-visible:ring-ring rounded-sm outline-none focus-visible:ring-2", className),
|
|
168
69
|
tabIndex: hint ? 0 : void 0
|
|
169
70
|
}, props), {}, {
|
|
170
71
|
"data-opt-id": "N51AT",
|
|
@@ -191,12 +92,12 @@ const _excluded = [
|
|
|
191
92
|
"disabled",
|
|
192
93
|
"onClick"
|
|
193
94
|
];
|
|
194
|
-
const defaultLabels$
|
|
95
|
+
const defaultLabels$33 = {
|
|
195
96
|
copy: "복사",
|
|
196
97
|
copied: "복사됨",
|
|
197
98
|
failed: "복사할 수 없습니다"
|
|
198
99
|
};
|
|
199
|
-
const sizeStyles
|
|
100
|
+
const sizeStyles = {
|
|
200
101
|
sm: "h-6 gap-1 text-[11px] [&>svg]:size-3",
|
|
201
102
|
md: "h-7 gap-1.5 text-xs [&>svg]:size-3.5"
|
|
202
103
|
};
|
|
@@ -238,7 +139,7 @@ const stateTone = {
|
|
|
238
139
|
*/
|
|
239
140
|
function CopyButton(_ref) {
|
|
240
141
|
let { value, variant = "icon", size = "md", feedbackDuration = 1500, onCopy, labels: customLabels, className, disabled, onClick } = _ref, props = _objectWithoutProperties(_ref, _excluded);
|
|
241
|
-
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$
|
|
142
|
+
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$33), customLabels);
|
|
242
143
|
const [state, setState] = useState("idle");
|
|
243
144
|
const timer = useRef(null);
|
|
244
145
|
useEffect(() => () => {
|
|
@@ -271,7 +172,7 @@ function CopyButton(_ref) {
|
|
|
271
172
|
onClick: handleClick,
|
|
272
173
|
disabled,
|
|
273
174
|
"aria-label": variant === "icon" ? label : void 0,
|
|
274
|
-
className: cn("inline-flex shrink-0 items-center rounded transition-colors", "disabled:pointer-events-none disabled:opacity-50", OPT_FOCUS_VISIBLE, sizeStyles
|
|
175
|
+
className: cn("inline-flex shrink-0 items-center rounded transition-colors", "disabled:pointer-events-none disabled:opacity-50", OPT_FOCUS_VISIBLE, sizeStyles[size], paddingStyles[variant][size], stateTone[state], className)
|
|
275
176
|
}, props), {}, {
|
|
276
177
|
"data-opt-id": "E0C8T",
|
|
277
178
|
"data-opt-slug": "copy-button.CopyButton",
|
|
@@ -289,76 +190,6 @@ function CopyButton(_ref) {
|
|
|
289
190
|
}));
|
|
290
191
|
}
|
|
291
192
|
//#endregion
|
|
292
|
-
//#region src/core/segmented-control.tsx
|
|
293
|
-
const sizeStyles = {
|
|
294
|
-
sm: "h-7 text-[11px] [&_svg]:size-3",
|
|
295
|
-
md: "h-8 text-xs [&_svg]:size-3.5"
|
|
296
|
-
};
|
|
297
|
-
const segmentPadding = {
|
|
298
|
-
sm: "gap-1 px-2",
|
|
299
|
-
md: "gap-1.5 px-2.5"
|
|
300
|
-
};
|
|
301
|
-
/**
|
|
302
|
-
* SegmentedControl — one of a few views, all of them visible.
|
|
303
|
-
*
|
|
304
|
-
* A `Select` hides the alternatives behind a click; a `ToggleGroup` presses
|
|
305
|
-
* buttons that may be on together. Neither is what "이벤트 | 속성" is: exactly
|
|
306
|
-
* one is true, the set is small enough to show, and the reader is choosing a
|
|
307
|
-
* view rather than filtering anything.
|
|
308
|
-
*
|
|
309
|
-
* Built on the radio-group primitive rather than on buttons, so the arrow keys,
|
|
310
|
-
* the group name and the checked state come from the platform. A control that
|
|
311
|
-
* merely looks like a radiogroup is one a keyboard cannot drive.
|
|
312
|
-
*
|
|
313
|
-
* @example
|
|
314
|
-
* ```tsx
|
|
315
|
-
* <SegmentedControl
|
|
316
|
-
* aria-label="카탈로그 탭"
|
|
317
|
-
* options={[
|
|
318
|
-
* { value: "events", label: "이벤트", badge: 128 },
|
|
319
|
-
* { value: "properties", label: "속성", badge: 341 },
|
|
320
|
-
* ]}
|
|
321
|
-
* value={tab}
|
|
322
|
-
* onChange={setTab}
|
|
323
|
-
* />
|
|
324
|
-
* ```
|
|
325
|
-
*/
|
|
326
|
-
function SegmentedControl({ options, value, onChange, size = "md", fullWidth = false, disabled = false, "aria-label": ariaLabel, className }) {
|
|
327
|
-
const name = useId();
|
|
328
|
-
return /* @__PURE__ */ jsx(RadioGroupRoot, {
|
|
329
|
-
value,
|
|
330
|
-
onValueChange: (next) => onChange(next),
|
|
331
|
-
disabled,
|
|
332
|
-
orientation: "horizontal",
|
|
333
|
-
name,
|
|
334
|
-
"aria-label": ariaLabel,
|
|
335
|
-
className: cn("inline-flex items-center rounded-lg border border-border bg-bg-subtle p-0.5", fullWidth && "flex w-full", sizeStyles[size], className),
|
|
336
|
-
"data-opt-id": "YKENE",
|
|
337
|
-
"data-opt-slug": "segmented-control.SegmentedControl",
|
|
338
|
-
children: options.map((option) => {
|
|
339
|
-
const selected = option.value === value;
|
|
340
|
-
const itemDisabled = disabled || option.disabled;
|
|
341
|
-
return /* @__PURE__ */ jsxs("label", {
|
|
342
|
-
className: cn("relative inline-flex h-full cursor-pointer items-center justify-center", "rounded-md font-medium whitespace-nowrap transition-colors", "has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-ring has-[:focus-visible]:ring-offset-1 has-[:focus-visible]:ring-offset-ring-offset", segmentPadding[size], fullWidth && "flex-1", selected ? "bg-surface text-text-primary shadow-sm" : "text-text-tertiary hover:text-text-secondary", itemDisabled && "pointer-events-none opacity-50"),
|
|
343
|
-
"data-selected": selected || void 0,
|
|
344
|
-
children: [
|
|
345
|
-
/* @__PURE__ */ jsx(Radio$1, {
|
|
346
|
-
value: option.value,
|
|
347
|
-
disabled: itemDisabled,
|
|
348
|
-
className: "absolute inset-0 m-0 h-full w-full cursor-pointer opacity-0"
|
|
349
|
-
}),
|
|
350
|
-
option.icon,
|
|
351
|
-
/* @__PURE__ */ jsx("span", { children: option.label }),
|
|
352
|
-
option.badge != null && /* @__PURE__ */ jsx("span", {
|
|
353
|
-
className: cn("tabular-nums", selected ? "text-text-tertiary" : "text-text-tertiary/70"),
|
|
354
|
-
children: option.badge
|
|
355
|
-
})
|
|
356
|
-
]
|
|
357
|
-
}, option.value);
|
|
358
|
-
})
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
//#endregion
|
|
362
193
|
//#region src/lib/schema-validator.ts
|
|
363
194
|
/** Handles schema validator. */
|
|
364
195
|
function schemaValidator(schema) {
|
|
@@ -433,7 +264,7 @@ function PageAside({ header, children, footer, widthClassName = "w-60", label, h
|
|
|
433
264
|
PageAside.displayName = "PageAside";
|
|
434
265
|
//#endregion
|
|
435
266
|
//#region src/shells/task-list.tsx
|
|
436
|
-
const defaultLabels$
|
|
267
|
+
const defaultLabels$32 = {
|
|
437
268
|
title: "작업 목록",
|
|
438
269
|
emptyMessage: "작업이 없습니다",
|
|
439
270
|
completedOf: "{completed}/{total} 완료",
|
|
@@ -453,9 +284,9 @@ const defaultLabels$34 = {
|
|
|
453
284
|
};
|
|
454
285
|
/** Renders the task list component. */
|
|
455
286
|
function TaskList({ tasks, title, onTaskClick, onTaskStatusChange, emptyMessage, showSubtasks = false, maxItems, labels: customLabels, className }) {
|
|
456
|
-
const labels = _objectSpread2(_objectSpread2(_objectSpread2({}, defaultLabels$
|
|
457
|
-
priority: _objectSpread2(_objectSpread2({}, defaultLabels$
|
|
458
|
-
status: _objectSpread2(_objectSpread2({}, defaultLabels$
|
|
287
|
+
const labels = _objectSpread2(_objectSpread2(_objectSpread2({}, defaultLabels$32), customLabels), {}, {
|
|
288
|
+
priority: _objectSpread2(_objectSpread2({}, defaultLabels$32.priority), customLabels === null || customLabels === void 0 ? void 0 : customLabels.priority),
|
|
289
|
+
status: _objectSpread2(_objectSpread2({}, defaultLabels$32.status), customLabels === null || customLabels === void 0 ? void 0 : customLabels.status)
|
|
459
290
|
});
|
|
460
291
|
const displayTitle = title !== null && title !== void 0 ? title : labels.title;
|
|
461
292
|
const displayEmptyMessage = emptyMessage !== null && emptyMessage !== void 0 ? emptyMessage : labels.emptyMessage;
|
|
@@ -613,7 +444,7 @@ function TaskList({ tasks, title, onTaskClick, onTaskStatusChange, emptyMessage,
|
|
|
613
444
|
}
|
|
614
445
|
//#endregion
|
|
615
446
|
//#region src/shells/activity-feed.tsx
|
|
616
|
-
const defaultLabels$
|
|
447
|
+
const defaultLabels$31 = {
|
|
617
448
|
title: "활동 피드",
|
|
618
449
|
emptyMessage: "활동이 없습니다",
|
|
619
450
|
moreItems: "{count}개 더 보기",
|
|
@@ -663,24 +494,24 @@ const variantBorder = {
|
|
|
663
494
|
function ActivityFeed({ activities, title, maxItems, onActivityClick, onShowMore, emptyMessage, labels: customLabels, locale = "ko-KR", loading = false, layout = "list", renderActions, className }) {
|
|
664
495
|
var _customLabels$timeAgo, _customLabels$timeAgo2, _customLabels$timeAgo3, _customLabels$timeAgo4, _customLabels$timeAgo5, _customLabels$timeAgo6, _customLabels$timeAgo7, _customLabels$timeAgo8, _customLabels$activit, _customLabels$activit2, _customLabels$activit3, _customLabels$activit4, _customLabels$activit5, _customLabels$activit6, _customLabels$activit7, _customLabels$activit8, _customLabels$activit9, _customLabels$activit10, _customLabels$activit11, _customLabels$activit12, _customLabels$activit13, _customLabels$activit14, _customLabels$title, _customLabels$emptyMe, _customLabels$moreIte;
|
|
665
496
|
const mergedTimeAgo = {
|
|
666
|
-
justNow: (_customLabels$timeAgo = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo2 = customLabels.timeAgo) === null || _customLabels$timeAgo2 === void 0 ? void 0 : _customLabels$timeAgo2.justNow) !== null && _customLabels$timeAgo !== void 0 ? _customLabels$timeAgo : defaultLabels$
|
|
667
|
-
minutesAgo: (_customLabels$timeAgo3 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo4 = customLabels.timeAgo) === null || _customLabels$timeAgo4 === void 0 ? void 0 : _customLabels$timeAgo4.minutesAgo) !== null && _customLabels$timeAgo3 !== void 0 ? _customLabels$timeAgo3 : defaultLabels$
|
|
668
|
-
hoursAgo: (_customLabels$timeAgo5 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo6 = customLabels.timeAgo) === null || _customLabels$timeAgo6 === void 0 ? void 0 : _customLabels$timeAgo6.hoursAgo) !== null && _customLabels$timeAgo5 !== void 0 ? _customLabels$timeAgo5 : defaultLabels$
|
|
669
|
-
daysAgo: (_customLabels$timeAgo7 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo8 = customLabels.timeAgo) === null || _customLabels$timeAgo8 === void 0 ? void 0 : _customLabels$timeAgo8.daysAgo) !== null && _customLabels$timeAgo7 !== void 0 ? _customLabels$timeAgo7 : defaultLabels$
|
|
497
|
+
justNow: (_customLabels$timeAgo = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo2 = customLabels.timeAgo) === null || _customLabels$timeAgo2 === void 0 ? void 0 : _customLabels$timeAgo2.justNow) !== null && _customLabels$timeAgo !== void 0 ? _customLabels$timeAgo : defaultLabels$31.timeAgo.justNow,
|
|
498
|
+
minutesAgo: (_customLabels$timeAgo3 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo4 = customLabels.timeAgo) === null || _customLabels$timeAgo4 === void 0 ? void 0 : _customLabels$timeAgo4.minutesAgo) !== null && _customLabels$timeAgo3 !== void 0 ? _customLabels$timeAgo3 : defaultLabels$31.timeAgo.minutesAgo,
|
|
499
|
+
hoursAgo: (_customLabels$timeAgo5 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo6 = customLabels.timeAgo) === null || _customLabels$timeAgo6 === void 0 ? void 0 : _customLabels$timeAgo6.hoursAgo) !== null && _customLabels$timeAgo5 !== void 0 ? _customLabels$timeAgo5 : defaultLabels$31.timeAgo.hoursAgo,
|
|
500
|
+
daysAgo: (_customLabels$timeAgo7 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo8 = customLabels.timeAgo) === null || _customLabels$timeAgo8 === void 0 ? void 0 : _customLabels$timeAgo8.daysAgo) !== null && _customLabels$timeAgo7 !== void 0 ? _customLabels$timeAgo7 : defaultLabels$31.timeAgo.daysAgo
|
|
670
501
|
};
|
|
671
502
|
const mergedActivityVerbs = {
|
|
672
|
-
created: (_customLabels$activit = customLabels === null || customLabels === void 0 || (_customLabels$activit2 = customLabels.activityVerbs) === null || _customLabels$activit2 === void 0 ? void 0 : _customLabels$activit2.created) !== null && _customLabels$activit !== void 0 ? _customLabels$activit : defaultLabels$
|
|
673
|
-
updated: (_customLabels$activit3 = customLabels === null || customLabels === void 0 || (_customLabels$activit4 = customLabels.activityVerbs) === null || _customLabels$activit4 === void 0 ? void 0 : _customLabels$activit4.updated) !== null && _customLabels$activit3 !== void 0 ? _customLabels$activit3 : defaultLabels$
|
|
674
|
-
completed: (_customLabels$activit5 = customLabels === null || customLabels === void 0 || (_customLabels$activit6 = customLabels.activityVerbs) === null || _customLabels$activit6 === void 0 ? void 0 : _customLabels$activit6.completed) !== null && _customLabels$activit5 !== void 0 ? _customLabels$activit5 : defaultLabels$
|
|
675
|
-
commented: (_customLabels$activit7 = customLabels === null || customLabels === void 0 || (_customLabels$activit8 = customLabels.activityVerbs) === null || _customLabels$activit8 === void 0 ? void 0 : _customLabels$activit8.commented) !== null && _customLabels$activit7 !== void 0 ? _customLabels$activit7 : defaultLabels$
|
|
676
|
-
assigned: (_customLabels$activit9 = customLabels === null || customLabels === void 0 || (_customLabels$activit10 = customLabels.activityVerbs) === null || _customLabels$activit10 === void 0 ? void 0 : _customLabels$activit10.assigned) !== null && _customLabels$activit9 !== void 0 ? _customLabels$activit9 : defaultLabels$
|
|
677
|
-
deployed: (_customLabels$activit11 = customLabels === null || customLabels === void 0 || (_customLabels$activit12 = customLabels.activityVerbs) === null || _customLabels$activit12 === void 0 ? void 0 : _customLabels$activit12.deployed) !== null && _customLabels$activit11 !== void 0 ? _customLabels$activit11 : defaultLabels$
|
|
678
|
-
merged: (_customLabels$activit13 = customLabels === null || customLabels === void 0 || (_customLabels$activit14 = customLabels.activityVerbs) === null || _customLabels$activit14 === void 0 ? void 0 : _customLabels$activit14.merged) !== null && _customLabels$activit13 !== void 0 ? _customLabels$activit13 : defaultLabels$
|
|
503
|
+
created: (_customLabels$activit = customLabels === null || customLabels === void 0 || (_customLabels$activit2 = customLabels.activityVerbs) === null || _customLabels$activit2 === void 0 ? void 0 : _customLabels$activit2.created) !== null && _customLabels$activit !== void 0 ? _customLabels$activit : defaultLabels$31.activityVerbs.created,
|
|
504
|
+
updated: (_customLabels$activit3 = customLabels === null || customLabels === void 0 || (_customLabels$activit4 = customLabels.activityVerbs) === null || _customLabels$activit4 === void 0 ? void 0 : _customLabels$activit4.updated) !== null && _customLabels$activit3 !== void 0 ? _customLabels$activit3 : defaultLabels$31.activityVerbs.updated,
|
|
505
|
+
completed: (_customLabels$activit5 = customLabels === null || customLabels === void 0 || (_customLabels$activit6 = customLabels.activityVerbs) === null || _customLabels$activit6 === void 0 ? void 0 : _customLabels$activit6.completed) !== null && _customLabels$activit5 !== void 0 ? _customLabels$activit5 : defaultLabels$31.activityVerbs.completed,
|
|
506
|
+
commented: (_customLabels$activit7 = customLabels === null || customLabels === void 0 || (_customLabels$activit8 = customLabels.activityVerbs) === null || _customLabels$activit8 === void 0 ? void 0 : _customLabels$activit8.commented) !== null && _customLabels$activit7 !== void 0 ? _customLabels$activit7 : defaultLabels$31.activityVerbs.commented,
|
|
507
|
+
assigned: (_customLabels$activit9 = customLabels === null || customLabels === void 0 || (_customLabels$activit10 = customLabels.activityVerbs) === null || _customLabels$activit10 === void 0 ? void 0 : _customLabels$activit10.assigned) !== null && _customLabels$activit9 !== void 0 ? _customLabels$activit9 : defaultLabels$31.activityVerbs.assigned,
|
|
508
|
+
deployed: (_customLabels$activit11 = customLabels === null || customLabels === void 0 || (_customLabels$activit12 = customLabels.activityVerbs) === null || _customLabels$activit12 === void 0 ? void 0 : _customLabels$activit12.deployed) !== null && _customLabels$activit11 !== void 0 ? _customLabels$activit11 : defaultLabels$31.activityVerbs.deployed,
|
|
509
|
+
merged: (_customLabels$activit13 = customLabels === null || customLabels === void 0 || (_customLabels$activit14 = customLabels.activityVerbs) === null || _customLabels$activit14 === void 0 ? void 0 : _customLabels$activit14.merged) !== null && _customLabels$activit13 !== void 0 ? _customLabels$activit13 : defaultLabels$31.activityVerbs.merged
|
|
679
510
|
};
|
|
680
511
|
const labels = {
|
|
681
|
-
title: (_customLabels$title = customLabels === null || customLabels === void 0 ? void 0 : customLabels.title) !== null && _customLabels$title !== void 0 ? _customLabels$title : defaultLabels$
|
|
682
|
-
emptyMessage: (_customLabels$emptyMe = customLabels === null || customLabels === void 0 ? void 0 : customLabels.emptyMessage) !== null && _customLabels$emptyMe !== void 0 ? _customLabels$emptyMe : defaultLabels$
|
|
683
|
-
moreItems: (_customLabels$moreIte = customLabels === null || customLabels === void 0 ? void 0 : customLabels.moreItems) !== null && _customLabels$moreIte !== void 0 ? _customLabels$moreIte : defaultLabels$
|
|
512
|
+
title: (_customLabels$title = customLabels === null || customLabels === void 0 ? void 0 : customLabels.title) !== null && _customLabels$title !== void 0 ? _customLabels$title : defaultLabels$31.title,
|
|
513
|
+
emptyMessage: (_customLabels$emptyMe = customLabels === null || customLabels === void 0 ? void 0 : customLabels.emptyMessage) !== null && _customLabels$emptyMe !== void 0 ? _customLabels$emptyMe : defaultLabels$31.emptyMessage,
|
|
514
|
+
moreItems: (_customLabels$moreIte = customLabels === null || customLabels === void 0 ? void 0 : customLabels.moreItems) !== null && _customLabels$moreIte !== void 0 ? _customLabels$moreIte : defaultLabels$31.moreItems,
|
|
684
515
|
timeAgo: mergedTimeAgo,
|
|
685
516
|
activityVerbs: mergedActivityVerbs
|
|
686
517
|
};
|
|
@@ -808,13 +639,13 @@ function ActivityFeed({ activities, title, maxItems, onActivityClick, onShowMore
|
|
|
808
639
|
ActivityFeed.displayName = "ActivityFeed";
|
|
809
640
|
//#endregion
|
|
810
641
|
//#region src/shells/filter-bar.tsx
|
|
811
|
-
const defaultLabels$
|
|
642
|
+
const defaultLabels$30 = {
|
|
812
643
|
clearAll: "필터 초기화",
|
|
813
644
|
searchPlaceholder: "검색..."
|
|
814
645
|
};
|
|
815
646
|
/** Renders the filter bar component. */
|
|
816
647
|
function FilterBar({ filters, onFilterChange, onDateRangeChange, onClearAll, labels: customLabels, presetActions, className }) {
|
|
817
|
-
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$
|
|
648
|
+
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$30), customLabels);
|
|
818
649
|
const [searchValues, setSearchValues] = useState({});
|
|
819
650
|
const [tagInputValues, setTagInputValues] = useState({});
|
|
820
651
|
const [multiSelectOpen, setMultiSelectOpen] = useState({});
|
|
@@ -1040,10 +871,10 @@ function matchesShortcut(event, shortcut) {
|
|
|
1040
871
|
if (requiresMeta && !event.metaKey) return false;
|
|
1041
872
|
return event.key.toLowerCase() === key;
|
|
1042
873
|
}
|
|
1043
|
-
const defaultLabels$
|
|
874
|
+
const defaultLabels$29 = { title: "빠른 작업" };
|
|
1044
875
|
/** Renders the quick actions component. */
|
|
1045
876
|
function QuickActions({ actions, title, layout = "grid", columns = 3, showDescriptionInGrid = false, bindShortcuts = false, labels: customLabels, className }) {
|
|
1046
|
-
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$
|
|
877
|
+
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$29), customLabels);
|
|
1047
878
|
const displayTitle = title !== null && title !== void 0 ? title : labels.title;
|
|
1048
879
|
const titleId = useId();
|
|
1049
880
|
useEffect(() => {
|
|
@@ -1121,7 +952,7 @@ function QuickActions({ actions, title, layout = "grid", columns = 3, showDescri
|
|
|
1121
952
|
QuickActions.displayName = "QuickActions";
|
|
1122
953
|
//#endregion
|
|
1123
954
|
//#region src/shells/team-member-list.tsx
|
|
1124
|
-
const defaultLabels$
|
|
955
|
+
const defaultLabels$28 = {
|
|
1125
956
|
title: "팀원",
|
|
1126
957
|
emptyMessage: "팀원이 없습니다",
|
|
1127
958
|
onlineCount: "{online}/{total} 온라인",
|
|
@@ -1142,7 +973,7 @@ const statusDot = {
|
|
|
1142
973
|
};
|
|
1143
974
|
/** Renders the team member list component. */
|
|
1144
975
|
function TeamMemberList({ members, title, layout = "list", maxDisplay, onMemberClick, onShowMore, emptyMessage, labels: customLabels, className }) {
|
|
1145
|
-
const labels = _objectSpread2(_objectSpread2(_objectSpread2({}, defaultLabels$
|
|
976
|
+
const labels = _objectSpread2(_objectSpread2(_objectSpread2({}, defaultLabels$28), customLabels), {}, { status: _objectSpread2(_objectSpread2({}, defaultLabels$28.status), customLabels === null || customLabels === void 0 ? void 0 : customLabels.status) });
|
|
1146
977
|
const displayTitle = title !== null && title !== void 0 ? title : labels.title;
|
|
1147
978
|
const displayEmptyMessage = emptyMessage !== null && emptyMessage !== void 0 ? emptyMessage : labels.emptyMessage;
|
|
1148
979
|
const titleId = useId();
|
|
@@ -2042,7 +1873,7 @@ const COLOR_PRESETS = [
|
|
|
2042
1873
|
"#f97316",
|
|
2043
1874
|
"#14b8a6"
|
|
2044
1875
|
];
|
|
2045
|
-
const defaultLabels$
|
|
1876
|
+
const defaultLabels$27 = {
|
|
2046
1877
|
eventLabelPrefix: "Event",
|
|
2047
1878
|
defaultAriaLabel: "Event icon"
|
|
2048
1879
|
};
|
|
@@ -2073,7 +1904,7 @@ function getEventIconStyle(color) {
|
|
|
2073
1904
|
/** Renders the event icon component. */
|
|
2074
1905
|
function EventIcon({ icon, color, size = "md", className, labels: customLabels }) {
|
|
2075
1906
|
var _iconEntry$label;
|
|
2076
|
-
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$
|
|
1907
|
+
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$27), customLabels);
|
|
2077
1908
|
const sizes = SIZE_MAP[size];
|
|
2078
1909
|
const resolvedColor = (color === null || color === void 0 ? void 0 : color.trim()) ? color : void 0;
|
|
2079
1910
|
const iconEntry = typeof icon === "string" ? getIconRegistryEntry(icon) : void 0;
|
|
@@ -2165,14 +1996,14 @@ function ConnectionIndicator({ status, tone, label, showLabel = true, pulse, cla
|
|
|
2165
1996
|
ConnectionIndicator.displayName = "ConnectionIndicator";
|
|
2166
1997
|
//#endregion
|
|
2167
1998
|
//#region src/shells/floating-action-bar.tsx
|
|
2168
|
-
const defaultLabels$
|
|
1999
|
+
const defaultLabels$26 = {
|
|
2169
2000
|
toolbarAriaLabel: "Actions",
|
|
2170
2001
|
selectedLabel: (count) => `${count} selected`,
|
|
2171
2002
|
dismissAriaLabel: "Dismiss"
|
|
2172
2003
|
};
|
|
2173
2004
|
/** Renders the floating action bar component. */
|
|
2174
2005
|
function FloatingActionBar({ actions, selectedCount, onAction, onDismiss, className, labels: customLabels }) {
|
|
2175
|
-
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$
|
|
2006
|
+
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$26), customLabels);
|
|
2176
2007
|
if (actions.length === 0) return null;
|
|
2177
2008
|
return /* @__PURE__ */ jsxs("div", {
|
|
2178
2009
|
role: "toolbar",
|
|
@@ -2209,7 +2040,7 @@ function FloatingActionBar({ actions, selectedCount, onAction, onDismiss, classN
|
|
|
2209
2040
|
FloatingActionBar.displayName = "FloatingActionBar";
|
|
2210
2041
|
//#endregion
|
|
2211
2042
|
//#region src/shells/template-picker.tsx
|
|
2212
|
-
const defaultLabels$
|
|
2043
|
+
const defaultLabels$25 = {
|
|
2213
2044
|
ariaLabel: "Templates",
|
|
2214
2045
|
defaultCategory: "General",
|
|
2215
2046
|
searchPlaceholder: "Search templates...",
|
|
@@ -2217,7 +2048,7 @@ const defaultLabels$27 = {
|
|
|
2217
2048
|
};
|
|
2218
2049
|
/** Renders the template picker component. */
|
|
2219
2050
|
function TemplatePicker({ templates, selected, onSelect, labels: customLabels, showSearch = false, className }) {
|
|
2220
|
-
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$
|
|
2051
|
+
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$25), customLabels);
|
|
2221
2052
|
const [search, setSearch] = React.useState("");
|
|
2222
2053
|
const filtered = React.useMemo(() => {
|
|
2223
2054
|
if (!showSearch || !search) return templates;
|
|
@@ -2303,7 +2134,7 @@ function TemplatePicker({ templates, selected, onSelect, labels: customLabels, s
|
|
|
2303
2134
|
TemplatePicker.displayName = "TemplatePicker";
|
|
2304
2135
|
//#endregion
|
|
2305
2136
|
//#region src/shells/code-snippet-viewer.tsx
|
|
2306
|
-
const defaultLabels$
|
|
2137
|
+
const defaultLabels$24 = {
|
|
2307
2138
|
copy: "Copy",
|
|
2308
2139
|
copied: "Copied!",
|
|
2309
2140
|
codeRegion: "Code snippet"
|
|
@@ -2341,7 +2172,7 @@ const syntaxThemeClasses = {
|
|
|
2341
2172
|
/** Renders the code snippet viewer component. */
|
|
2342
2173
|
function CodeSnippetViewer({ code, language = "text", title, showLineNumbers = true, showCopyButton = true, maxHeight = 400, syntaxTheme = "default", className, labels: customLabels }) {
|
|
2343
2174
|
var _syntaxThemeClasses$s;
|
|
2344
|
-
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$
|
|
2175
|
+
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$24), customLabels);
|
|
2345
2176
|
const [copied, setCopied] = React.useState(false);
|
|
2346
2177
|
const lines = code.split("\n");
|
|
2347
2178
|
const theme = (_syntaxThemeClasses$s = syntaxThemeClasses[syntaxTheme]) !== null && _syntaxThemeClasses$s !== void 0 ? _syntaxThemeClasses$s : syntaxThemeClasses.default;
|
|
@@ -2393,7 +2224,7 @@ function CodeSnippetViewer({ code, language = "text", title, showLineNumbers = t
|
|
|
2393
2224
|
CodeSnippetViewer.displayName = "CodeSnippetViewer";
|
|
2394
2225
|
//#endregion
|
|
2395
2226
|
//#region src/shells/property-explorer.tsx
|
|
2396
|
-
const defaultLabels$
|
|
2227
|
+
const defaultLabels$23 = {
|
|
2397
2228
|
searchPlaceholder: "Search properties...",
|
|
2398
2229
|
noPropertiesFound: "No properties found",
|
|
2399
2230
|
edit: (property) => `${property} 편집`,
|
|
@@ -2401,7 +2232,7 @@ const defaultLabels$25 = {
|
|
|
2401
2232
|
};
|
|
2402
2233
|
/** Renders the property explorer component. */
|
|
2403
2234
|
function PropertyExplorer({ groups, onSelect, onEdit, className, labels: customLabels }) {
|
|
2404
|
-
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$
|
|
2235
|
+
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$23), customLabels);
|
|
2405
2236
|
const [search, setSearch] = React.useState("");
|
|
2406
2237
|
const filtered = React.useMemo(() => {
|
|
2407
2238
|
if (!search) return groups;
|
|
@@ -2485,99 +2316,209 @@ function PropertyExplorer({ groups, onSelect, onEdit, className, labels: customL
|
|
|
2485
2316
|
}
|
|
2486
2317
|
PropertyExplorer.displayName = "PropertyExplorer";
|
|
2487
2318
|
//#endregion
|
|
2488
|
-
//#region src/
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
"
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
"
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
return
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2319
|
+
//#region src/lib/sql/statements.ts
|
|
2320
|
+
/**
|
|
2321
|
+
* Split editor text into statements on top-level semicolons.
|
|
2322
|
+
*
|
|
2323
|
+
* Blank statements (two semicolons in a row, a trailing semicolon) are dropped.
|
|
2324
|
+
*/
|
|
2325
|
+
function splitSqlStatements(text) {
|
|
2326
|
+
const out = [];
|
|
2327
|
+
let segmentStart = 0;
|
|
2328
|
+
let i = 0;
|
|
2329
|
+
const length = text.length;
|
|
2330
|
+
const push = (from, to) => {
|
|
2331
|
+
let start = from;
|
|
2332
|
+
let end = to;
|
|
2333
|
+
while (start < end && /\s/.test(text[start])) start++;
|
|
2334
|
+
while (end > start && /\s/.test(text[end - 1])) end--;
|
|
2335
|
+
if (end > start) out.push({
|
|
2336
|
+
text: text.slice(start, end),
|
|
2337
|
+
start,
|
|
2338
|
+
end
|
|
2339
|
+
});
|
|
2340
|
+
};
|
|
2341
|
+
while (i < length) {
|
|
2342
|
+
const ch = text[i];
|
|
2343
|
+
const next = text[i + 1];
|
|
2344
|
+
if (ch === "'" || ch === "\"" || ch === "`") {
|
|
2345
|
+
i = skipQuoted(text, i, ch);
|
|
2346
|
+
continue;
|
|
2347
|
+
}
|
|
2348
|
+
if (ch === "-" && next === "-") {
|
|
2349
|
+
i = skipLineComment(text, i + 2);
|
|
2350
|
+
continue;
|
|
2351
|
+
}
|
|
2352
|
+
if (ch === "/" && next === "*") {
|
|
2353
|
+
i = skipBlockComment(text, i + 2);
|
|
2354
|
+
continue;
|
|
2355
|
+
}
|
|
2356
|
+
if (ch === ";") {
|
|
2357
|
+
push(segmentStart, i);
|
|
2358
|
+
segmentStart = i + 1;
|
|
2359
|
+
}
|
|
2360
|
+
i++;
|
|
2361
|
+
}
|
|
2362
|
+
push(segmentStart, length);
|
|
2363
|
+
return out;
|
|
2364
|
+
}
|
|
2365
|
+
/**
|
|
2366
|
+
* The statement the cursor is in, or the nearest one when the cursor sits in
|
|
2367
|
+
* the whitespace between two. `null` only when there are no statements.
|
|
2368
|
+
*
|
|
2369
|
+
* "Nearest" prefers the statement before the cursor: a reader who just typed a
|
|
2370
|
+
* semicolon and pressed run means the thing they finished, not the empty line
|
|
2371
|
+
* after it.
|
|
2372
|
+
*/
|
|
2373
|
+
function sqlStatementAtOffset(statements, offset) {
|
|
2374
|
+
var _before;
|
|
2375
|
+
if (statements.length === 0) return null;
|
|
2376
|
+
let before = null;
|
|
2377
|
+
for (const statement of statements) {
|
|
2378
|
+
if (offset >= statement.start && offset <= statement.end) return statement;
|
|
2379
|
+
if (statement.end < offset) before = statement;
|
|
2380
|
+
else break;
|
|
2381
|
+
}
|
|
2382
|
+
return (_before = before) !== null && _before !== void 0 ? _before : statements[0];
|
|
2383
|
+
}
|
|
2384
|
+
/**
|
|
2385
|
+
* Whether the SQL uses a `{name}` placeholder outside strings and comments.
|
|
2386
|
+
* Also matches `{name.` and `{name(` so a `{filters(...)}` binding counts.
|
|
2387
|
+
*/
|
|
2388
|
+
function sqlUsesPlaceholder(sql, name) {
|
|
2389
|
+
const needle = `{${name}`;
|
|
2390
|
+
let i = 0;
|
|
2391
|
+
const length = sql.length;
|
|
2392
|
+
while (i < length) {
|
|
2393
|
+
const ch = sql[i];
|
|
2394
|
+
const next = sql[i + 1];
|
|
2395
|
+
if (ch === "'" || ch === "\"" || ch === "`") {
|
|
2396
|
+
i = skipQuoted(sql, i, ch);
|
|
2397
|
+
continue;
|
|
2398
|
+
}
|
|
2399
|
+
if (ch === "-" && next === "-") {
|
|
2400
|
+
i = skipLineComment(sql, i + 2);
|
|
2401
|
+
continue;
|
|
2402
|
+
}
|
|
2403
|
+
if (ch === "/" && next === "*") {
|
|
2404
|
+
i = skipBlockComment(sql, i + 2);
|
|
2405
|
+
continue;
|
|
2406
|
+
}
|
|
2407
|
+
if (sql.startsWith(needle, i)) {
|
|
2408
|
+
const after = sql[i + needle.length];
|
|
2409
|
+
if (after === "}" || after === "." || after === "(") return true;
|
|
2410
|
+
}
|
|
2411
|
+
i++;
|
|
2412
|
+
}
|
|
2413
|
+
return false;
|
|
2414
|
+
}
|
|
2415
|
+
/**
|
|
2416
|
+
* Replace every `{name}` placeholder outside strings and comments with the
|
|
2417
|
+
* given text. A `{name(...)}` binding is left alone — that form carries
|
|
2418
|
+
* arguments the caller must interpret, and a blind substitution would corrupt it.
|
|
2419
|
+
*/
|
|
2420
|
+
function replaceSqlPlaceholder(sql, name, replacement) {
|
|
2421
|
+
const needle = `{${name}}`;
|
|
2422
|
+
let out = "";
|
|
2423
|
+
let i = 0;
|
|
2424
|
+
const length = sql.length;
|
|
2425
|
+
while (i < length) {
|
|
2426
|
+
const ch = sql[i];
|
|
2427
|
+
const next = sql[i + 1];
|
|
2428
|
+
let skipTo = -1;
|
|
2429
|
+
if (ch === "'" || ch === "\"" || ch === "`") skipTo = skipQuoted(sql, i, ch);
|
|
2430
|
+
else if (ch === "-" && next === "-") skipTo = skipLineComment(sql, i + 2);
|
|
2431
|
+
else if (ch === "/" && next === "*") skipTo = skipBlockComment(sql, i + 2);
|
|
2432
|
+
if (skipTo !== -1) {
|
|
2433
|
+
out += sql.slice(i, skipTo);
|
|
2434
|
+
i = skipTo;
|
|
2435
|
+
continue;
|
|
2436
|
+
}
|
|
2437
|
+
if (sql.startsWith(needle, i)) {
|
|
2438
|
+
out += replacement;
|
|
2439
|
+
i += needle.length;
|
|
2440
|
+
continue;
|
|
2441
|
+
}
|
|
2442
|
+
out += ch;
|
|
2443
|
+
i++;
|
|
2444
|
+
}
|
|
2445
|
+
return out;
|
|
2446
|
+
}
|
|
2447
|
+
/** Names of every `{name}` / `{name.x}` placeholder, in order of first use. */
|
|
2448
|
+
function sqlPlaceholderNames(sql) {
|
|
2449
|
+
const names = [];
|
|
2450
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2451
|
+
let i = 0;
|
|
2452
|
+
const length = sql.length;
|
|
2453
|
+
while (i < length) {
|
|
2454
|
+
const ch = sql[i];
|
|
2455
|
+
const next = sql[i + 1];
|
|
2456
|
+
if (ch === "'" || ch === "\"" || ch === "`") {
|
|
2457
|
+
i = skipQuoted(sql, i, ch);
|
|
2458
|
+
continue;
|
|
2459
|
+
}
|
|
2460
|
+
if (ch === "-" && next === "-") {
|
|
2461
|
+
i = skipLineComment(sql, i + 2);
|
|
2462
|
+
continue;
|
|
2463
|
+
}
|
|
2464
|
+
if (ch === "/" && next === "*") {
|
|
2465
|
+
i = skipBlockComment(sql, i + 2);
|
|
2466
|
+
continue;
|
|
2467
|
+
}
|
|
2468
|
+
if (ch === "{") {
|
|
2469
|
+
const match = /^\{([A-Za-z_][A-Za-z0-9_]*)/.exec(sql.slice(i));
|
|
2470
|
+
if (match) {
|
|
2471
|
+
const name = match[1];
|
|
2472
|
+
if (!seen.has(name)) {
|
|
2473
|
+
seen.add(name);
|
|
2474
|
+
names.push(name);
|
|
2475
|
+
}
|
|
2476
|
+
i += match[0].length;
|
|
2477
|
+
continue;
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
i++;
|
|
2481
|
+
}
|
|
2482
|
+
return names;
|
|
2483
|
+
}
|
|
2484
|
+
function skipQuoted(text, from, quote) {
|
|
2485
|
+
let i = from + 1;
|
|
2486
|
+
const length = text.length;
|
|
2487
|
+
while (i < length) {
|
|
2488
|
+
const ch = text[i];
|
|
2489
|
+
if (ch === "\\") {
|
|
2490
|
+
i += 2;
|
|
2491
|
+
continue;
|
|
2492
|
+
}
|
|
2493
|
+
if (ch === quote) {
|
|
2494
|
+
if (text[i + 1] === quote) {
|
|
2495
|
+
i += 2;
|
|
2496
|
+
continue;
|
|
2497
|
+
}
|
|
2498
|
+
return i + 1;
|
|
2499
|
+
}
|
|
2500
|
+
i++;
|
|
2501
|
+
}
|
|
2502
|
+
return length;
|
|
2503
|
+
}
|
|
2504
|
+
function skipLineComment(text, from) {
|
|
2505
|
+
let i = from;
|
|
2506
|
+
const length = text.length;
|
|
2507
|
+
while (i < length && text[i] !== "\n") i++;
|
|
2508
|
+
return i;
|
|
2509
|
+
}
|
|
2510
|
+
function skipBlockComment(text, from) {
|
|
2511
|
+
let i = from;
|
|
2512
|
+
const length = text.length;
|
|
2513
|
+
while (i < length) {
|
|
2514
|
+
if (text[i] === "*" && text[i + 1] === "/") return i + 2;
|
|
2515
|
+
i++;
|
|
2516
|
+
}
|
|
2517
|
+
return length;
|
|
2576
2518
|
}
|
|
2577
|
-
QueryResultsTable.displayName = "QueryResultsTable";
|
|
2578
2519
|
//#endregion
|
|
2579
2520
|
//#region src/shells/alert-builder.tsx
|
|
2580
|
-
const defaultLabels$
|
|
2521
|
+
const defaultLabels$22 = {
|
|
2581
2522
|
alertNameLabel: "Alert name",
|
|
2582
2523
|
conditionsLabel: "Conditions",
|
|
2583
2524
|
metricLabel: "Metric",
|
|
@@ -2648,7 +2589,7 @@ function AlertBuilder({ value, onChange, metrics = [
|
|
|
2648
2589
|
], labels: customLabels, className }) {
|
|
2649
2590
|
const resolvedMetrics = eventOptions ? eventOptions.map((e) => e.id) : metrics;
|
|
2650
2591
|
const metricLabelMap = eventOptions ? Object.fromEntries(eventOptions.map((e) => [e.id, e.name])) : null;
|
|
2651
|
-
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$
|
|
2592
|
+
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$22), customLabels);
|
|
2652
2593
|
const alertNameId = React.useId();
|
|
2653
2594
|
const conditionsId = React.useId();
|
|
2654
2595
|
const checkFrequencyId = React.useId();
|
|
@@ -2802,186 +2743,6 @@ function AlertBuilder({ value, onChange, metrics = [
|
|
|
2802
2743
|
}
|
|
2803
2744
|
AlertBuilder.displayName = "AlertBuilder";
|
|
2804
2745
|
//#endregion
|
|
2805
|
-
//#region src/shells/sql-editor.tsx
|
|
2806
|
-
const defaultLabels$22 = {
|
|
2807
|
-
placeholder: "SELECT * FROM events LIMIT 100",
|
|
2808
|
-
runHint: "Ctrl+Enter to run",
|
|
2809
|
-
runButton: "Run Query",
|
|
2810
|
-
editor: "SQL 편집기"
|
|
2811
|
-
};
|
|
2812
|
-
/** Renders the sql editor component. */
|
|
2813
|
-
function SqlEditor({ value, onChange, onRun, onRunAndAdvance, placeholder, readOnly = false, height = 200, schema, completionSources, keymap: customKeymap, extensions: customExtensions, ariaLabel, autoFocus = false, showFooter, labels: customLabels, className }) {
|
|
2814
|
-
const labels = _objectSpread2(_objectSpread2({}, defaultLabels$22), customLabels);
|
|
2815
|
-
const fill = height === "fill";
|
|
2816
|
-
const footerVisible = showFooter !== null && showFooter !== void 0 ? showFooter : Boolean(onRun);
|
|
2817
|
-
const editorRef = React.useRef(null);
|
|
2818
|
-
const viewRef = React.useRef(null);
|
|
2819
|
-
const completionCompartmentRef = React.useRef(null);
|
|
2820
|
-
const editableCompartmentRef = React.useRef(null);
|
|
2821
|
-
const buildCompletionRef = React.useRef(null);
|
|
2822
|
-
const latestValueRef = React.useRef(value);
|
|
2823
|
-
const onChangeRef = React.useRef(onChange);
|
|
2824
|
-
const onRunRef = React.useRef(onRun);
|
|
2825
|
-
const onRunAndAdvanceRef = React.useRef(onRunAndAdvance);
|
|
2826
|
-
const customKeymapRef = React.useRef(customKeymap);
|
|
2827
|
-
const schemaRef = React.useRef(schema);
|
|
2828
|
-
const completionSourcesRef = React.useRef(completionSources);
|
|
2829
|
-
const autoFocusRef = React.useRef(autoFocus);
|
|
2830
|
-
latestValueRef.current = value;
|
|
2831
|
-
onChangeRef.current = onChange;
|
|
2832
|
-
onRunRef.current = onRun;
|
|
2833
|
-
onRunAndAdvanceRef.current = onRunAndAdvance;
|
|
2834
|
-
customKeymapRef.current = customKeymap;
|
|
2835
|
-
schemaRef.current = schema;
|
|
2836
|
-
completionSourcesRef.current = completionSources;
|
|
2837
|
-
autoFocusRef.current = autoFocus;
|
|
2838
|
-
const autocompleteEnabled = React.useRef(schema !== void 0 || completionSources !== void 0).current;
|
|
2839
|
-
React.useEffect(() => {
|
|
2840
|
-
let view = null;
|
|
2841
|
-
let cancelled = false;
|
|
2842
|
-
async function init() {
|
|
2843
|
-
var _customKeymapRef$curr;
|
|
2844
|
-
const parent = editorRef.current;
|
|
2845
|
-
if (!parent) return;
|
|
2846
|
-
const [{ EditorView, keymap: cmKeymap, placeholder: cmPlaceholder }, { Compartment, EditorState }, langSql, { oneDark }, autocomplete] = await Promise.all([
|
|
2847
|
-
import("@codemirror/view"),
|
|
2848
|
-
import("@codemirror/state"),
|
|
2849
|
-
import("@codemirror/lang-sql"),
|
|
2850
|
-
import("@codemirror/theme-one-dark"),
|
|
2851
|
-
autocompleteEnabled ? import("@codemirror/autocomplete") : Promise.resolve(null)
|
|
2852
|
-
]);
|
|
2853
|
-
if (cancelled || !parent.isConnected) return;
|
|
2854
|
-
const completionCompartment = new Compartment();
|
|
2855
|
-
const editableCompartment = new Compartment();
|
|
2856
|
-
completionCompartmentRef.current = completionCompartment;
|
|
2857
|
-
editableCompartmentRef.current = editableCompartment;
|
|
2858
|
-
const buildCompletion = (nextSchema, nextSources) => {
|
|
2859
|
-
if (!autocomplete) return [];
|
|
2860
|
-
const dialect = langSql.PostgreSQL;
|
|
2861
|
-
return [autocomplete.autocompletion({ override: [
|
|
2862
|
-
langSql.schemaCompletionSource({
|
|
2863
|
-
dialect,
|
|
2864
|
-
schema: nextSchema !== null && nextSchema !== void 0 ? nextSchema : {}
|
|
2865
|
-
}),
|
|
2866
|
-
langSql.keywordCompletionSource(dialect),
|
|
2867
|
-
...nextSources !== null && nextSources !== void 0 ? nextSources : []
|
|
2868
|
-
] }), cmKeymap.of(autocomplete.completionKeymap)];
|
|
2869
|
-
};
|
|
2870
|
-
buildCompletionRef.current = buildCompletion;
|
|
2871
|
-
const runKeymap = [{
|
|
2872
|
-
key: "Shift-Enter",
|
|
2873
|
-
run: (target) => {
|
|
2874
|
-
const handler = onRunAndAdvanceRef.current;
|
|
2875
|
-
if (!handler) return false;
|
|
2876
|
-
handler(target.state.doc.toString());
|
|
2877
|
-
return true;
|
|
2878
|
-
}
|
|
2879
|
-
}, {
|
|
2880
|
-
key: "Mod-Enter",
|
|
2881
|
-
run: (target) => {
|
|
2882
|
-
const handler = onRunRef.current;
|
|
2883
|
-
if (!handler) return false;
|
|
2884
|
-
handler(target.state.doc.toString());
|
|
2885
|
-
return true;
|
|
2886
|
-
}
|
|
2887
|
-
}];
|
|
2888
|
-
const extensions = [
|
|
2889
|
-
langSql.PostgreSQL.extension,
|
|
2890
|
-
completionCompartment.of(buildCompletion(schemaRef.current, completionSourcesRef.current)),
|
|
2891
|
-
oneDark,
|
|
2892
|
-
cmKeymap.of([...(_customKeymapRef$curr = customKeymapRef.current) !== null && _customKeymapRef$curr !== void 0 ? _customKeymapRef$curr : [], ...runKeymap]),
|
|
2893
|
-
EditorView.theme({
|
|
2894
|
-
"&": { height: "100%" },
|
|
2895
|
-
"&.cm-focused": {
|
|
2896
|
-
outline: "2px solid var(--opt-ring)",
|
|
2897
|
-
outlineOffset: "-2px"
|
|
2898
|
-
},
|
|
2899
|
-
".cm-scroller": {
|
|
2900
|
-
height: "100%",
|
|
2901
|
-
overflow: "auto"
|
|
2902
|
-
}
|
|
2903
|
-
}),
|
|
2904
|
-
cmPlaceholder(placeholder !== null && placeholder !== void 0 ? placeholder : labels.placeholder),
|
|
2905
|
-
EditorView.lineWrapping,
|
|
2906
|
-
EditorView.updateListener.of((update) => {
|
|
2907
|
-
if (update.docChanged) onChangeRef.current(update.state.doc.toString());
|
|
2908
|
-
}),
|
|
2909
|
-
editableCompartment.of(EditorView.editable.of(!readOnly)),
|
|
2910
|
-
EditorView.contentAttributes.of({ "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : labels.editor }),
|
|
2911
|
-
...customExtensions !== null && customExtensions !== void 0 ? customExtensions : []
|
|
2912
|
-
];
|
|
2913
|
-
view = new EditorView({
|
|
2914
|
-
state: EditorState.create({
|
|
2915
|
-
doc: latestValueRef.current,
|
|
2916
|
-
extensions
|
|
2917
|
-
}),
|
|
2918
|
-
parent
|
|
2919
|
-
});
|
|
2920
|
-
viewRef.current = view;
|
|
2921
|
-
if (autoFocusRef.current) view.focus();
|
|
2922
|
-
}
|
|
2923
|
-
init();
|
|
2924
|
-
return () => {
|
|
2925
|
-
cancelled = true;
|
|
2926
|
-
view === null || view === void 0 || view.destroy();
|
|
2927
|
-
if (viewRef.current === view) viewRef.current = null;
|
|
2928
|
-
completionCompartmentRef.current = null;
|
|
2929
|
-
editableCompartmentRef.current = null;
|
|
2930
|
-
buildCompletionRef.current = null;
|
|
2931
|
-
};
|
|
2932
|
-
}, []);
|
|
2933
|
-
React.useEffect(() => {
|
|
2934
|
-
const view = viewRef.current;
|
|
2935
|
-
if (view && view.state.doc.toString() !== value) view.dispatch({ changes: {
|
|
2936
|
-
from: 0,
|
|
2937
|
-
to: view.state.doc.length,
|
|
2938
|
-
insert: value
|
|
2939
|
-
} });
|
|
2940
|
-
}, [value]);
|
|
2941
|
-
React.useEffect(() => {
|
|
2942
|
-
const view = viewRef.current;
|
|
2943
|
-
const compartment = completionCompartmentRef.current;
|
|
2944
|
-
const build = buildCompletionRef.current;
|
|
2945
|
-
if (!view || !compartment || !build) return;
|
|
2946
|
-
view.dispatch({ effects: compartment.reconfigure(build(schema, completionSources)) });
|
|
2947
|
-
}, [schema, completionSources]);
|
|
2948
|
-
React.useEffect(() => {
|
|
2949
|
-
const view = viewRef.current;
|
|
2950
|
-
const compartment = editableCompartmentRef.current;
|
|
2951
|
-
if (!view || !compartment) return;
|
|
2952
|
-
let cancelled = false;
|
|
2953
|
-
import("@codemirror/view").then(({ EditorView }) => {
|
|
2954
|
-
if (cancelled || viewRef.current !== view) return;
|
|
2955
|
-
view.dispatch({ effects: compartment.reconfigure(EditorView.editable.of(!readOnly)) });
|
|
2956
|
-
});
|
|
2957
|
-
return () => {
|
|
2958
|
-
cancelled = true;
|
|
2959
|
-
};
|
|
2960
|
-
}, [readOnly]);
|
|
2961
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
2962
|
-
className: cn("gap-element flex flex-col", fill && "h-full min-h-0", className),
|
|
2963
|
-
"data-opt-id": "RSGKV",
|
|
2964
|
-
"data-opt-slug": "sql-editor.SqlEditor",
|
|
2965
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
2966
|
-
ref: editorRef,
|
|
2967
|
-
className: cn("border-border overflow-hidden rounded-lg border", fill && "min-h-0 flex-1"),
|
|
2968
|
-
style: fill ? void 0 : { height }
|
|
2969
|
-
}), footerVisible && /* @__PURE__ */ jsxs("div", {
|
|
2970
|
-
className: "flex flex-none items-center justify-between",
|
|
2971
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
2972
|
-
className: "text-text-tertiary text-xs",
|
|
2973
|
-
children: labels.runHint
|
|
2974
|
-
}), onRun && /* @__PURE__ */ jsx(Button, {
|
|
2975
|
-
variant: "primary",
|
|
2976
|
-
size: "sm",
|
|
2977
|
-
onClick: () => onRun(value),
|
|
2978
|
-
children: labels.runButton
|
|
2979
|
-
})]
|
|
2980
|
-
})]
|
|
2981
|
-
});
|
|
2982
|
-
}
|
|
2983
|
-
SqlEditor.displayName = "SqlEditor";
|
|
2984
|
-
//#endregion
|
|
2985
2746
|
//#region src/shells/event-meta-editor.tsx
|
|
2986
2747
|
const defaultLabels$21 = {
|
|
2987
2748
|
icon: "Icon",
|
|
@@ -4565,28 +4326,6 @@ function matchesQueryObject(query, row, options = {}) {
|
|
|
4565
4326
|
return matchesQuery(query, read, searchable);
|
|
4566
4327
|
}
|
|
4567
4328
|
//#endregion
|
|
4568
|
-
//#region src/lib/use-media-query.ts
|
|
4569
|
-
/**
|
|
4570
|
-
* Whether a media query matches, kept in sync with the browser.
|
|
4571
|
-
*
|
|
4572
|
-
* `useSyncExternalStore` rather than an effect: a layout that switches on width
|
|
4573
|
-
* must not render the wrong shape for a frame first. The server snapshot is the
|
|
4574
|
-
* caller's `serverFallback`, because the server does not know the viewport and
|
|
4575
|
-
* guessing "narrow" collapses a wide layout on every first paint.
|
|
4576
|
-
*
|
|
4577
|
-
* Internal. Exported from `lib` for the components in this package, not from
|
|
4578
|
-
* the package barrel — a hook that answers "is this viewport wide" invites
|
|
4579
|
-
* layout decisions that belong in CSS.
|
|
4580
|
-
*/
|
|
4581
|
-
function useMediaQuery(query, serverFallback = false) {
|
|
4582
|
-
return useSyncExternalStore((onChange) => {
|
|
4583
|
-
if (typeof window === "undefined") return () => {};
|
|
4584
|
-
const list = window.matchMedia(query);
|
|
4585
|
-
list.addEventListener("change", onChange);
|
|
4586
|
-
return () => list.removeEventListener("change", onChange);
|
|
4587
|
-
}, () => typeof window === "undefined" ? serverFallback : window.matchMedia(query).matches, () => serverFallback);
|
|
4588
|
-
}
|
|
4589
|
-
//#endregion
|
|
4590
4329
|
//#region src/shells/inspector-layout.tsx
|
|
4591
4330
|
/** Tailwind needs whole class names, so the queries and widths are literals. */
|
|
4592
4331
|
const breakpointQuery = {
|
|
@@ -5122,853 +4861,6 @@ function ComparisonSelector({ segments, valueA, valueB, onChangeA, onChangeB, va
|
|
|
5122
4861
|
});
|
|
5123
4862
|
}
|
|
5124
4863
|
ComparisonSelector.displayName = "ComparisonSelector";
|
|
5125
|
-
const THEME_REGISTRY = {
|
|
5126
|
-
default: {
|
|
5127
|
-
id: "default",
|
|
5128
|
-
label: "Default",
|
|
5129
|
-
description: "Blue accent, balanced radius & shadow",
|
|
5130
|
-
palette: {
|
|
5131
|
-
seed: "#2563eb",
|
|
5132
|
-
harmony: "split-complementary",
|
|
5133
|
-
radiusScale: "medium",
|
|
5134
|
-
shadowIntensity: "subtle",
|
|
5135
|
-
neutralTemperature: "cool"
|
|
5136
|
-
},
|
|
5137
|
-
switcherSwatches: [
|
|
5138
|
-
"hsl(221 83% 53%)",
|
|
5139
|
-
"hsl(142 71% 45%)",
|
|
5140
|
-
"hsl(38 92% 50%)"
|
|
5141
|
-
]
|
|
5142
|
-
},
|
|
5143
|
-
minimal: {
|
|
5144
|
-
id: "minimal",
|
|
5145
|
-
label: "Minimal",
|
|
5146
|
-
description: "Monochrome, no shadow, sharp edges",
|
|
5147
|
-
palette: {
|
|
5148
|
-
seed: "#333333",
|
|
5149
|
-
harmony: "analogous",
|
|
5150
|
-
radiusScale: "sharp",
|
|
5151
|
-
shadowIntensity: "none",
|
|
5152
|
-
neutralTemperature: "cool"
|
|
5153
|
-
},
|
|
5154
|
-
switcherSwatches: [
|
|
5155
|
-
"hsl(0 0% 20%)",
|
|
5156
|
-
"hsl(0 0% 45%)",
|
|
5157
|
-
"hsl(0 0% 70%)"
|
|
5158
|
-
]
|
|
5159
|
-
},
|
|
5160
|
-
natural: {
|
|
5161
|
-
id: "natural",
|
|
5162
|
-
label: "Natural",
|
|
5163
|
-
description: "Always light — sage accent, warm cream",
|
|
5164
|
-
forceLightOnly: true,
|
|
5165
|
-
palette: {
|
|
5166
|
-
seed: "#5a9376",
|
|
5167
|
-
harmony: "complementary",
|
|
5168
|
-
radiusScale: "medium",
|
|
5169
|
-
shadowIntensity: "subtle",
|
|
5170
|
-
neutralTemperature: "warm"
|
|
5171
|
-
},
|
|
5172
|
-
switcherSwatches: [
|
|
5173
|
-
"hsl(155 38% 45%)",
|
|
5174
|
-
"hsl(25 65% 55%)",
|
|
5175
|
-
"hsl(45 75% 50%)"
|
|
5176
|
-
]
|
|
5177
|
-
},
|
|
5178
|
-
pro: {
|
|
5179
|
-
id: "pro",
|
|
5180
|
-
label: "Pro",
|
|
5181
|
-
description: "Neon blue accent, mono headings, ultra-dense",
|
|
5182
|
-
palette: {
|
|
5183
|
-
seed: "#0080ff",
|
|
5184
|
-
harmony: "tetradic",
|
|
5185
|
-
radiusScale: "sharp",
|
|
5186
|
-
shadowIntensity: "subtle",
|
|
5187
|
-
neutralTemperature: "cool"
|
|
5188
|
-
},
|
|
5189
|
-
switcherSwatches: [
|
|
5190
|
-
"hsl(210 100% 55%)",
|
|
5191
|
-
"hsl(170 90% 48%)",
|
|
5192
|
-
"hsl(290 85% 60%)"
|
|
5193
|
-
]
|
|
5194
|
-
},
|
|
5195
|
-
"mono-dark": {
|
|
5196
|
-
id: "mono-dark",
|
|
5197
|
-
label: "Mono Dark",
|
|
5198
|
-
description: "OLED-friendly black, neon cyan accent, mono headings",
|
|
5199
|
-
palette: {
|
|
5200
|
-
seed: "#00d4ff",
|
|
5201
|
-
harmony: "tetradic",
|
|
5202
|
-
radiusScale: "sharp",
|
|
5203
|
-
shadowIntensity: "subtle",
|
|
5204
|
-
neutralTemperature: "cool"
|
|
5205
|
-
},
|
|
5206
|
-
switcherSwatches: [
|
|
5207
|
-
"hsl(190 100% 50%)",
|
|
5208
|
-
"hsl(0 0% 8%)",
|
|
5209
|
-
"hsl(280 90% 65%)"
|
|
5210
|
-
]
|
|
5211
|
-
}
|
|
5212
|
-
};
|
|
5213
|
-
/** All registered preset ids in declaration order. */
|
|
5214
|
-
const THEME_PRESET_IDS = Object.keys(THEME_REGISTRY);
|
|
5215
|
-
/** Look up a descriptor by id. Returns `undefined` for unknown ids. */
|
|
5216
|
-
function getThemeDescriptor(id) {
|
|
5217
|
-
return THEME_REGISTRY[id];
|
|
5218
|
-
}
|
|
5219
|
-
/** Type guard for a known preset id. */
|
|
5220
|
-
function isThemePresetId(id) {
|
|
5221
|
-
return id in THEME_REGISTRY;
|
|
5222
|
-
}
|
|
5223
|
-
/** Preset ids that suppress dark mode generation. */
|
|
5224
|
-
const FORCE_LIGHT_PRESET_IDS = new Set(THEME_PRESET_IDS.filter((id) => THEME_REGISTRY[id].forceLightOnly));
|
|
5225
|
-
/**
|
|
5226
|
-
* Map from removed preset ids to the closest surviving preset. Boot script and
|
|
5227
|
-
* `readStoredTheme` consult this so users with persisted `corporate`/`playful`
|
|
5228
|
-
* values silently land on a working preset on next page load instead of
|
|
5229
|
-
* showing the global default fallback for an unknown id.
|
|
5230
|
-
*
|
|
5231
|
-
* Keep this around indefinitely — localStorage values are forever and the
|
|
5232
|
-
* cost of two extra entries is negligible.
|
|
5233
|
-
*/
|
|
5234
|
-
const DEPRECATED_PRESET_MIGRATIONS = Object.freeze({
|
|
5235
|
-
corporate: "default",
|
|
5236
|
-
playful: "default"
|
|
5237
|
-
});
|
|
5238
|
-
/**
|
|
5239
|
-
* Resolve a possibly-deprecated preset id to a registered one. Returns the
|
|
5240
|
-
* input unchanged when it is already valid; returns the migration target when
|
|
5241
|
-
* it is a known deprecated id; returns `null` when the id is unknown
|
|
5242
|
-
* altogether (caller should fall back to its default).
|
|
5243
|
-
*/
|
|
5244
|
-
function migrateDeprecatedPresetId(id) {
|
|
5245
|
-
if (!id) return null;
|
|
5246
|
-
if (isThemePresetId(id)) return id;
|
|
5247
|
-
if (id in DEPRECATED_PRESET_MIGRATIONS) return DEPRECATED_PRESET_MIGRATIONS[id];
|
|
5248
|
-
return null;
|
|
5249
|
-
}
|
|
5250
|
-
//#endregion
|
|
5251
|
-
//#region src/lib/theme/theme-types.ts
|
|
5252
|
-
/**
|
|
5253
|
-
* Author canonical theme overrides with token-name autocomplete.
|
|
5254
|
-
* ThemeOverrides remains broad for backward compatibility with older custom
|
|
5255
|
-
* variables; new themes should use this helper as the governed entry point.
|
|
5256
|
-
*/
|
|
5257
|
-
function defineThemeOverrides(overrides) {
|
|
5258
|
-
return overrides;
|
|
5259
|
-
}
|
|
5260
|
-
/** Construct a `PresetThemeSpec` — convenience for the common case. */
|
|
5261
|
-
function presetTheme(preset, overrides) {
|
|
5262
|
-
return overrides ? {
|
|
5263
|
-
kind: "preset",
|
|
5264
|
-
preset,
|
|
5265
|
-
overrides
|
|
5266
|
-
} : {
|
|
5267
|
-
kind: "preset",
|
|
5268
|
-
preset
|
|
5269
|
-
};
|
|
5270
|
-
}
|
|
5271
|
-
/** Construct a `GeneratedThemeSpec` from an inline `PaletteConfig`. */
|
|
5272
|
-
function generatedTheme(palette, options) {
|
|
5273
|
-
return _objectSpread2({
|
|
5274
|
-
kind: "generated",
|
|
5275
|
-
palette
|
|
5276
|
-
}, options);
|
|
5277
|
-
}
|
|
5278
|
-
/** True when `spec` references a registered preset id. */
|
|
5279
|
-
function isPresetSpec(spec) {
|
|
5280
|
-
return spec.kind === "preset";
|
|
5281
|
-
}
|
|
5282
|
-
/** True when `spec` carries an inline `PaletteConfig`. */
|
|
5283
|
-
function isGeneratedSpec(spec) {
|
|
5284
|
-
return spec.kind === "generated";
|
|
5285
|
-
}
|
|
5286
|
-
/** True when `spec` wraps a fully-formed `ThemeDescriptor`. */
|
|
5287
|
-
function isDescriptorSpec(spec) {
|
|
5288
|
-
return spec.kind === "descriptor";
|
|
5289
|
-
}
|
|
5290
|
-
//#endregion
|
|
5291
|
-
//#region src/lib/theme/theme-serialize.ts
|
|
5292
|
-
/**
|
|
5293
|
-
* theme-serialize.ts
|
|
5294
|
-
*
|
|
5295
|
-
* Pure helpers that turn a `ThemeSpec` into the artifacts the runtime needs:
|
|
5296
|
-
* resolved descriptor + mode, computed token maps for generated palettes, and
|
|
5297
|
-
* `<style>` CSS strings ready to be injected into `<head>`.
|
|
5298
|
-
*
|
|
5299
|
-
* Kept side-effect free so the boot script and the provider can share the
|
|
5300
|
-
* same logic without dragging React into the client bundle's critical path.
|
|
5301
|
-
*/
|
|
5302
|
-
/** Element id used for the global generated theme style tag. */
|
|
5303
|
-
const GLOBAL_THEME_STYLE_ID = "opt-global-theme";
|
|
5304
|
-
/** localStorage key for the persisted ThemeSpec (generated mode). */
|
|
5305
|
-
const THEME_SPEC_STORAGE_KEY = "opt-theme-spec";
|
|
5306
|
-
/**
|
|
5307
|
-
* localStorage key for the cached, pre-serialized token maps that match the
|
|
5308
|
-
* spec under `THEME_SPEC_STORAGE_KEY`. The boot script reads this directly so
|
|
5309
|
-
* it can inline tokens without invoking opt-palette at startup.
|
|
5310
|
-
*/
|
|
5311
|
-
const THEME_TOKENS_STORAGE_KEY = "opt-theme-tokens";
|
|
5312
|
-
/** Stable id used for unnamed generated themes. */
|
|
5313
|
-
const GENERATED_THEME_ID_DEFAULT = "generated";
|
|
5314
|
-
/** Cached token maps keyed by spec hash. Lazy-built per process. */
|
|
5315
|
-
const generatedCache = /* @__PURE__ */ new Map();
|
|
5316
|
-
/** Build a stable cache key for a `PaletteConfig`. */
|
|
5317
|
-
function paletteCacheKey(config) {
|
|
5318
|
-
return JSON.stringify(config);
|
|
5319
|
-
}
|
|
5320
|
-
/** Run opt-palette with caching. */
|
|
5321
|
-
function generatePaletteCached(config) {
|
|
5322
|
-
const key = paletteCacheKey(config);
|
|
5323
|
-
let cached = generatedCache.get(key);
|
|
5324
|
-
if (!cached) {
|
|
5325
|
-
cached = generatePalette(config);
|
|
5326
|
-
generatedCache.set(key, cached);
|
|
5327
|
-
}
|
|
5328
|
-
return cached;
|
|
5329
|
-
}
|
|
5330
|
-
/** Apply sparse override maps onto a base token record. */
|
|
5331
|
-
function applyOverrides(base, overrides, mode) {
|
|
5332
|
-
if (!overrides) return base;
|
|
5333
|
-
const merged = _objectSpread2({}, base);
|
|
5334
|
-
if (overrides.shared) Object.assign(merged, overrides.shared);
|
|
5335
|
-
const modeOverrides = mode === "light" ? overrides.light : overrides.dark;
|
|
5336
|
-
if (modeOverrides) Object.assign(merged, modeOverrides);
|
|
5337
|
-
return merged;
|
|
5338
|
-
}
|
|
5339
|
-
/**
|
|
5340
|
-
* Stable id used in `<html data-theme>` and the `<style>` selector.
|
|
5341
|
-
* - preset → the preset id (force-light) or `${id}` / `${id}-dark`
|
|
5342
|
-
* - generated → `spec.id ?? "generated"` with `-dark` suffix when applicable
|
|
5343
|
-
* - descriptor → `descriptor.id` with same suffix logic
|
|
5344
|
-
*/
|
|
5345
|
-
function getCompoundIdForSpec(spec, resolvedMode, forceLightOnly) {
|
|
5346
|
-
const baseId = baseIdFor(spec);
|
|
5347
|
-
if (forceLightOnly) return baseId;
|
|
5348
|
-
return resolvedMode === "dark" ? `${baseId}-dark` : baseId;
|
|
5349
|
-
}
|
|
5350
|
-
function baseIdFor(spec) {
|
|
5351
|
-
var _spec$id;
|
|
5352
|
-
if (isPresetSpec(spec)) return spec.preset;
|
|
5353
|
-
if (isDescriptorSpec(spec)) return spec.descriptor.id;
|
|
5354
|
-
return (_spec$id = spec.id) !== null && _spec$id !== void 0 ? _spec$id : GENERATED_THEME_ID_DEFAULT;
|
|
5355
|
-
}
|
|
5356
|
-
/** Whether the given spec emits dark variants at all. */
|
|
5357
|
-
function isForceLightSpec(spec) {
|
|
5358
|
-
if (isPresetSpec(spec)) {
|
|
5359
|
-
const desc = THEME_REGISTRY[spec.preset];
|
|
5360
|
-
return (desc === null || desc === void 0 ? void 0 : desc.forceLightOnly) === true;
|
|
5361
|
-
}
|
|
5362
|
-
if (isDescriptorSpec(spec)) return spec.descriptor.forceLightOnly === true;
|
|
5363
|
-
return spec.forceLightOnly === true;
|
|
5364
|
-
}
|
|
5365
|
-
/**
|
|
5366
|
-
* Compute the inline tokens for a `GeneratedThemeSpec` or
|
|
5367
|
-
* `DescriptorThemeSpec` whose descriptor carries a `palette`. Returns `null`
|
|
5368
|
-
* for preset specs (their tokens live in the static CSS files).
|
|
5369
|
-
*/
|
|
5370
|
-
function computeGeneratedTokens(spec) {
|
|
5371
|
-
if (isPresetSpec(spec)) return null;
|
|
5372
|
-
let palette;
|
|
5373
|
-
let overrides;
|
|
5374
|
-
let id;
|
|
5375
|
-
let forceLight;
|
|
5376
|
-
if (isGeneratedSpec(spec)) {
|
|
5377
|
-
var _spec$id2;
|
|
5378
|
-
palette = spec.palette;
|
|
5379
|
-
overrides = spec.overrides;
|
|
5380
|
-
id = (_spec$id2 = spec.id) !== null && _spec$id2 !== void 0 ? _spec$id2 : GENERATED_THEME_ID_DEFAULT;
|
|
5381
|
-
forceLight = spec.forceLightOnly === true;
|
|
5382
|
-
} else {
|
|
5383
|
-
palette = spec.descriptor.palette;
|
|
5384
|
-
overrides = spec.overrides;
|
|
5385
|
-
id = spec.descriptor.id;
|
|
5386
|
-
forceLight = spec.descriptor.forceLightOnly === true;
|
|
5387
|
-
}
|
|
5388
|
-
if (!palette) return null;
|
|
5389
|
-
const generated = generatePaletteCached(palette);
|
|
5390
|
-
return {
|
|
5391
|
-
id,
|
|
5392
|
-
light: applyOverrides(generated.light, overrides, "light"),
|
|
5393
|
-
dark: forceLight ? null : applyOverrides(generated.dark, overrides, "dark")
|
|
5394
|
-
};
|
|
5395
|
-
}
|
|
5396
|
-
/**
|
|
5397
|
-
* Serialize a token record into a CSS rule body — `--name:value;...` — without
|
|
5398
|
-
* surrounding selector or braces. Values are not escaped; callers are
|
|
5399
|
-
* responsible for trusted input. Boot script and provider both rely on this
|
|
5400
|
-
* shape.
|
|
5401
|
-
*/
|
|
5402
|
-
function serializeTokenBody(tokens) {
|
|
5403
|
-
return Object.entries(tokens).map(([k, v]) => `${k}:${v}`).join(";");
|
|
5404
|
-
}
|
|
5405
|
-
/**
|
|
5406
|
-
* Build a CSS rule scoped to `[data-theme="<id>"]`.
|
|
5407
|
-
*/
|
|
5408
|
-
function serializeThemeRule(themeId, tokens) {
|
|
5409
|
-
return `[data-theme="${themeId}"]{${serializeTokenBody(tokens)}}`;
|
|
5410
|
-
}
|
|
5411
|
-
/**
|
|
5412
|
-
* Build the full CSS for a generated theme style tag — covers light + dark
|
|
5413
|
-
* selectors based on the computed tokens. Caller chooses the id used in
|
|
5414
|
-
* the selector (typically the spec base id).
|
|
5415
|
-
*/
|
|
5416
|
-
function serializeGeneratedTheme(tokens) {
|
|
5417
|
-
const { id, light, dark } = tokens;
|
|
5418
|
-
let css = serializeThemeRule(id, light);
|
|
5419
|
-
if (dark) css += serializeThemeRule(`${id}-dark`, dark);
|
|
5420
|
-
return css;
|
|
5421
|
-
}
|
|
5422
|
-
/**
|
|
5423
|
-
* Resolve a spec into its descriptor counterpart. Preset specs map to
|
|
5424
|
-
* `THEME_REGISTRY[preset]`. Generated specs are wrapped into a synthetic
|
|
5425
|
-
* descriptor so callers can treat them uniformly.
|
|
5426
|
-
*/
|
|
5427
|
-
function resolveDescriptor(spec) {
|
|
5428
|
-
if (isPresetSpec(spec)) {
|
|
5429
|
-
const desc = THEME_REGISTRY[spec.preset];
|
|
5430
|
-
if (!desc) throw new Error(`[opt-ui] Unknown theme preset id: "${spec.preset}". Registered ids: ${Object.keys(THEME_REGISTRY).join(", ")}`);
|
|
5431
|
-
return desc;
|
|
5432
|
-
}
|
|
5433
|
-
if (isDescriptorSpec(spec)) return spec.descriptor;
|
|
5434
|
-
return generatedSpecToDescriptor(spec);
|
|
5435
|
-
}
|
|
5436
|
-
function generatedSpecToDescriptor(spec) {
|
|
5437
|
-
var _spec$id3, _spec$label;
|
|
5438
|
-
return {
|
|
5439
|
-
id: (_spec$id3 = spec.id) !== null && _spec$id3 !== void 0 ? _spec$id3 : GENERATED_THEME_ID_DEFAULT,
|
|
5440
|
-
label: (_spec$label = spec.label) !== null && _spec$label !== void 0 ? _spec$label : "Custom",
|
|
5441
|
-
description: "Generated theme",
|
|
5442
|
-
palette: spec.palette,
|
|
5443
|
-
forceLightOnly: spec.forceLightOnly
|
|
5444
|
-
};
|
|
5445
|
-
}
|
|
5446
|
-
/**
|
|
5447
|
-
* Validate a `ThemeSpec` parsed from localStorage. Returns the spec on
|
|
5448
|
-
* success or `null` if any required field is missing or the preset id is
|
|
5449
|
-
* unknown. Defensive parsing — never throws.
|
|
5450
|
-
*/
|
|
5451
|
-
function safeParseStoredSpec(json) {
|
|
5452
|
-
if (!json) return null;
|
|
5453
|
-
try {
|
|
5454
|
-
const parsed = JSON.parse(json);
|
|
5455
|
-
if (!parsed || typeof parsed !== "object" || !("kind" in parsed)) return null;
|
|
5456
|
-
if (parsed.kind === "preset") {
|
|
5457
|
-
const preset = parsed.preset;
|
|
5458
|
-
if (typeof preset !== "string" || !isThemePresetId(preset)) return null;
|
|
5459
|
-
return {
|
|
5460
|
-
kind: "preset",
|
|
5461
|
-
preset
|
|
5462
|
-
};
|
|
5463
|
-
}
|
|
5464
|
-
if (parsed.kind === "generated") {
|
|
5465
|
-
const palette = parsed.palette;
|
|
5466
|
-
if (!isPaletteConfig(palette)) return null;
|
|
5467
|
-
return {
|
|
5468
|
-
kind: "generated",
|
|
5469
|
-
palette,
|
|
5470
|
-
id: typeof parsed.id === "string" ? parsed.id : void 0,
|
|
5471
|
-
label: typeof parsed.label === "string" ? parsed.label : void 0,
|
|
5472
|
-
forceLightOnly: parsed.forceLightOnly === true,
|
|
5473
|
-
overrides: isObjectMap(parsed.overrides) ? parsed.overrides : void 0
|
|
5474
|
-
};
|
|
5475
|
-
}
|
|
5476
|
-
return null;
|
|
5477
|
-
} catch (_unused) {
|
|
5478
|
-
return null;
|
|
5479
|
-
}
|
|
5480
|
-
}
|
|
5481
|
-
function isObjectMap(value) {
|
|
5482
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5483
|
-
}
|
|
5484
|
-
function isPaletteConfig(value) {
|
|
5485
|
-
if (!isObjectMap(value)) return false;
|
|
5486
|
-
const v = value;
|
|
5487
|
-
return typeof v.seed === "string" && typeof v.harmony === "string" && typeof v.radiusScale === "string" && typeof v.shadowIntensity === "string" && typeof v.neutralTemperature === "string";
|
|
5488
|
-
}
|
|
5489
|
-
/**
|
|
5490
|
-
* Parse the cached token payload from localStorage. Returns `null` on any
|
|
5491
|
-
* shape mismatch — caller will recompute from the spec.
|
|
5492
|
-
*/
|
|
5493
|
-
function safeParseStoredTokens(json) {
|
|
5494
|
-
if (!json) return null;
|
|
5495
|
-
try {
|
|
5496
|
-
const parsed = JSON.parse(json);
|
|
5497
|
-
if (!parsed || typeof parsed.id !== "string" || !isObjectMap(parsed.light)) return null;
|
|
5498
|
-
return {
|
|
5499
|
-
id: parsed.id,
|
|
5500
|
-
light: parsed.light,
|
|
5501
|
-
dark: isObjectMap(parsed.dark) ? parsed.dark : void 0
|
|
5502
|
-
};
|
|
5503
|
-
} catch (_unused2) {
|
|
5504
|
-
return null;
|
|
5505
|
-
}
|
|
5506
|
-
}
|
|
5507
|
-
/** Build the storage payload that pairs with `opt-theme-spec`. */
|
|
5508
|
-
function buildTokenCache(tokens) {
|
|
5509
|
-
var _tokens$dark;
|
|
5510
|
-
return {
|
|
5511
|
-
id: tokens.id,
|
|
5512
|
-
light: tokens.light,
|
|
5513
|
-
dark: (_tokens$dark = tokens.dark) !== null && _tokens$dark !== void 0 ? _tokens$dark : void 0
|
|
5514
|
-
};
|
|
5515
|
-
}
|
|
5516
|
-
//#endregion
|
|
5517
|
-
//#region src/lib/theme/theme-resolution.ts
|
|
5518
|
-
/**
|
|
5519
|
-
* Registered preset id list. Preferred for runtime iteration.
|
|
5520
|
-
* @deprecated Prefer `THEME_PRESET_IDS` from `./presets`.
|
|
5521
|
-
*/
|
|
5522
|
-
const THEME_PRESET_VALUES = THEME_PRESET_IDS;
|
|
5523
|
-
const THEME_MODE_VALUES = [
|
|
5524
|
-
"light",
|
|
5525
|
-
"dark",
|
|
5526
|
-
"system"
|
|
5527
|
-
];
|
|
5528
|
-
const LEGACY_THEME_STORAGE_KEY = "opt-theme";
|
|
5529
|
-
const THEME_PRESET_STORAGE_KEY = "opt-preset";
|
|
5530
|
-
const THEME_MODE_STORAGE_KEY = "opt-mode";
|
|
5531
|
-
const DARK_MQ = "(prefers-color-scheme: dark)";
|
|
5532
|
-
/**
|
|
5533
|
-
* Presets that force light mode regardless of system dark/light preference.
|
|
5534
|
-
* Mirrors `FORCE_LIGHT_PRESET_IDS` from `./presets` — kept as alias for
|
|
5535
|
-
* existing imports.
|
|
5536
|
-
*/
|
|
5537
|
-
const FORCE_LIGHT_PRESETS = FORCE_LIGHT_PRESET_IDS;
|
|
5538
|
-
/** All valid compound theme names. Useful for static enumeration. */
|
|
5539
|
-
const ALL_COMPOUND_THEMES = THEME_PRESET_IDS.flatMap((id) => FORCE_LIGHT_PRESET_IDS.has(id) ? [id] : [id, `${id}-dark`]);
|
|
5540
|
-
function hasStorageMutation(storage) {
|
|
5541
|
-
return typeof storage.setItem === "function" && typeof storage.removeItem === "function";
|
|
5542
|
-
}
|
|
5543
|
-
/** Handles is theme mode. */
|
|
5544
|
-
function isThemeMode(value) {
|
|
5545
|
-
return typeof value === "string" && THEME_MODE_VALUES.includes(value);
|
|
5546
|
-
}
|
|
5547
|
-
/** Compute compound theme name from preset + resolved mode. */
|
|
5548
|
-
function getCompoundTheme(preset, resolvedMode) {
|
|
5549
|
-
if (FORCE_LIGHT_PRESETS.has(preset)) return preset;
|
|
5550
|
-
return resolvedMode === "dark" ? `${preset}-dark` : preset;
|
|
5551
|
-
}
|
|
5552
|
-
/** Handles resolve theme mode. */
|
|
5553
|
-
function resolveThemeMode(preset, mode, systemDark) {
|
|
5554
|
-
if (FORCE_LIGHT_PRESETS.has(preset)) return "light";
|
|
5555
|
-
if (mode === "system") return systemDark ? "dark" : "light";
|
|
5556
|
-
return mode;
|
|
5557
|
-
}
|
|
5558
|
-
/** Handles read stored theme. */
|
|
5559
|
-
function readStoredTheme(storage, defaultPreset, defaultMode, options = {}) {
|
|
5560
|
-
const legacy = storage.getItem(LEGACY_THEME_STORAGE_KEY);
|
|
5561
|
-
const storedPreset = storage.getItem(THEME_PRESET_STORAGE_KEY);
|
|
5562
|
-
const storedMode = storage.getItem(THEME_MODE_STORAGE_KEY);
|
|
5563
|
-
let preset = defaultPreset;
|
|
5564
|
-
if (typeof legacy === "string") {
|
|
5565
|
-
const migratedLegacy = migrateDeprecatedPresetId(legacy);
|
|
5566
|
-
if (migratedLegacy) {
|
|
5567
|
-
if (options.migrateLegacy && hasStorageMutation(storage)) {
|
|
5568
|
-
storage.setItem(THEME_PRESET_STORAGE_KEY, migratedLegacy);
|
|
5569
|
-
storage.removeItem(LEGACY_THEME_STORAGE_KEY);
|
|
5570
|
-
}
|
|
5571
|
-
preset = migratedLegacy;
|
|
5572
|
-
}
|
|
5573
|
-
} else if (typeof storedPreset === "string") {
|
|
5574
|
-
const migrated = migrateDeprecatedPresetId(storedPreset);
|
|
5575
|
-
if (migrated) {
|
|
5576
|
-
preset = migrated;
|
|
5577
|
-
if (hasStorageMutation(storage) && migrated !== storedPreset && storedPreset in DEPRECATED_PRESET_MIGRATIONS) storage.setItem(THEME_PRESET_STORAGE_KEY, migrated);
|
|
5578
|
-
}
|
|
5579
|
-
}
|
|
5580
|
-
const mode = isThemeMode(storedMode) ? storedMode : defaultMode;
|
|
5581
|
-
return {
|
|
5582
|
-
preset,
|
|
5583
|
-
mode
|
|
5584
|
-
};
|
|
5585
|
-
}
|
|
5586
|
-
/** Normalize a mode against an optional allowed-mode list. */
|
|
5587
|
-
function coerceThemeMode(mode, allowedModes, fallback = "system") {
|
|
5588
|
-
var _allowedModes$;
|
|
5589
|
-
if (!allowedModes || allowedModes.length === 0) return mode;
|
|
5590
|
-
if (allowedModes.includes(mode)) return mode;
|
|
5591
|
-
if (allowedModes.includes(fallback)) return fallback;
|
|
5592
|
-
return (_allowedModes$ = allowedModes[0]) !== null && _allowedModes$ !== void 0 ? _allowedModes$ : fallback;
|
|
5593
|
-
}
|
|
5594
|
-
/**
|
|
5595
|
-
* Build the inline `<head>` boot script that paints the correct theme before
|
|
5596
|
-
* React mounts. Two paths:
|
|
5597
|
-
*
|
|
5598
|
-
* 1. **Generated** — when both `opt-theme-spec` (kind: "generated") and
|
|
5599
|
-
* `opt-theme-tokens` are present and well-formed, a `<style id="…">` tag
|
|
5600
|
-
* is inserted with the cached tokens and `<html data-theme>` is set to the
|
|
5601
|
-
* generated id (with optional `-dark` suffix). This bypasses opt-palette
|
|
5602
|
-
* at startup so first paint is instant.
|
|
5603
|
-
* 2. **Preset (legacy)** — falls through to the existing preset selector,
|
|
5604
|
-
* including legacy `opt-theme` → `opt-preset` migration.
|
|
5605
|
-
*
|
|
5606
|
-
* Returned as a single minified line; intended for `dangerouslySetInnerHTML`.
|
|
5607
|
-
*/
|
|
5608
|
-
function createThemeBootScript(defaultPreset = "default", defaultMode = "system", options = {}) {
|
|
5609
|
-
var _options$allowedModes, _allowedModes$2;
|
|
5610
|
-
const presetValues = JSON.stringify(THEME_PRESET_VALUES);
|
|
5611
|
-
const modeValues = JSON.stringify(THEME_MODE_VALUES);
|
|
5612
|
-
const allowedModes = ((_options$allowedModes = options.allowedModes) === null || _options$allowedModes === void 0 ? void 0 : _options$allowedModes.length) ? options.allowedModes : THEME_MODE_VALUES;
|
|
5613
|
-
const allowedModeValues = JSON.stringify(allowedModes);
|
|
5614
|
-
const forceLightPresets = JSON.stringify(Array.from(FORCE_LIGHT_PRESETS));
|
|
5615
|
-
const deprecatedMap = JSON.stringify(DEPRECATED_PRESET_MIGRATIONS);
|
|
5616
|
-
const lockedPreset = options.lockedPreset;
|
|
5617
|
-
const defaultPresetLiteral = JSON.stringify(lockedPreset !== null && lockedPreset !== void 0 ? lockedPreset : defaultPreset);
|
|
5618
|
-
const defaultModeLiteral = JSON.stringify(coerceThemeMode(defaultMode, allowedModes, (_allowedModes$2 = allowedModes[0]) !== null && _allowedModes$2 !== void 0 ? _allowedModes$2 : "system"));
|
|
5619
|
-
const lockedPresetLiteral = JSON.stringify(lockedPreset !== null && lockedPreset !== void 0 ? lockedPreset : null);
|
|
5620
|
-
const styleId = JSON.stringify(GLOBAL_THEME_STYLE_ID);
|
|
5621
|
-
const specKey = JSON.stringify(THEME_SPEC_STORAGE_KEY);
|
|
5622
|
-
const tokensKey = JSON.stringify(THEME_TOKENS_STORAGE_KEY);
|
|
5623
|
-
const presetKey = JSON.stringify(THEME_PRESET_STORAGE_KEY);
|
|
5624
|
-
const modeKey = JSON.stringify(THEME_MODE_STORAGE_KEY);
|
|
5625
|
-
const legacyKey = JSON.stringify(LEGACY_THEME_STORAGE_KEY);
|
|
5626
|
-
const darkMq = JSON.stringify(DARK_MQ);
|
|
5627
|
-
return `
|
|
5628
|
-
try {
|
|
5629
|
-
var pv=${presetValues},mv=${modeValues},am=${allowedModeValues},fp=${forceLightPresets},dm=${deprecatedMap},lk=${lockedPresetLiteral};
|
|
5630
|
-
function mp(v){if(typeof v!=="string")return null;if(pv.indexOf(v)>=0)return v;return Object.prototype.hasOwnProperty.call(dm,v)?dm[v]:null;}
|
|
5631
|
-
var p=${defaultPresetLiteral};
|
|
5632
|
-
if(!lk){
|
|
5633
|
-
var lp=localStorage.getItem(${legacyKey}),sp=localStorage.getItem(${presetKey});
|
|
5634
|
-
var lpm=mp(lp),spm=mp(sp);
|
|
5635
|
-
p=lpm||spm||${defaultPresetLiteral};
|
|
5636
|
-
if(lpm){localStorage.setItem(${presetKey},lpm);localStorage.removeItem(${legacyKey});}
|
|
5637
|
-
else if(sp&&spm&&sp!==spm){localStorage.setItem(${presetKey},spm);}
|
|
5638
|
-
}
|
|
5639
|
-
var sm=localStorage.getItem(${modeKey});
|
|
5640
|
-
var m=(typeof sm==="string"&&mv.indexOf(sm)>=0&&am.indexOf(sm)>=0)?sm:${defaultModeLiteral};
|
|
5641
|
-
var spec=null,tk=null;
|
|
5642
|
-
if(!lk){try{var sj=localStorage.getItem(${specKey});if(sj)spec=JSON.parse(sj);}catch(e){}}
|
|
5643
|
-
if(!lk){try{var tj=localStorage.getItem(${tokensKey});if(tj)tk=JSON.parse(tj);}catch(e){}}
|
|
5644
|
-
if(!lk&&spec&&spec.kind==="generated"&&tk&&typeof tk.id==="string"&&tk.light&&typeof tk.light==="object"){
|
|
5645
|
-
var fld=spec.forceLightOnly===true;
|
|
5646
|
-
var dk=!fld&&(m==="dark"||(m==="system"&&matchMedia(${darkMq}).matches));
|
|
5647
|
-
var tt=(dk&&tk.dark)?tk.dark:tk.light;
|
|
5648
|
-
var cid=(dk&&tk.dark)?(tk.id+"-dark"):tk.id;
|
|
5649
|
-
var css="";
|
|
5650
|
-
for(var k in tt){if(Object.prototype.hasOwnProperty.call(tt,k))css+=k+":"+tt[k]+";"}
|
|
5651
|
-
var st=document.getElementById(${styleId});
|
|
5652
|
-
if(!st){st=document.createElement("style");st.id=${styleId};document.head.appendChild(st);}
|
|
5653
|
-
st.textContent='[data-theme="'+cid+'"]{'+css+'}';
|
|
5654
|
-
document.documentElement.setAttribute("data-theme",cid);
|
|
5655
|
-
} else {
|
|
5656
|
-
var d=fp.indexOf(p)<0&&(m==="dark"||(m==="system"&&matchMedia(${darkMq}).matches));
|
|
5657
|
-
document.documentElement.setAttribute("data-theme",d?p+"-dark":p);
|
|
5658
|
-
}
|
|
5659
|
-
} catch(e){}`.replace(/\n\s*/g, "");
|
|
5660
|
-
}
|
|
5661
|
-
//#endregion
|
|
5662
|
-
//#region src/lib/theme/theme-controller-context.tsx
|
|
5663
|
-
const OptThemeControllerContext = createContext(null);
|
|
5664
|
-
/**
|
|
5665
|
-
* Reads the controller exposed by the nearest `OptThemeProvider`. Returns
|
|
5666
|
-
* `null` when used outside a provider — callers should treat that as "no
|
|
5667
|
-
* promotion available" and behave as if scope === "override".
|
|
5668
|
-
*/
|
|
5669
|
-
function useOptThemeController() {
|
|
5670
|
-
return useContext(OptThemeControllerContext);
|
|
5671
|
-
}
|
|
5672
|
-
//#endregion
|
|
5673
|
-
//#region src/lib/theme/theme-provider.tsx
|
|
5674
|
-
const THEME_STORAGE_KEYS = /* @__PURE__ */ new Set([
|
|
5675
|
-
LEGACY_THEME_STORAGE_KEY,
|
|
5676
|
-
THEME_PRESET_STORAGE_KEY,
|
|
5677
|
-
THEME_MODE_STORAGE_KEY,
|
|
5678
|
-
THEME_SPEC_STORAGE_KEY,
|
|
5679
|
-
THEME_TOKENS_STORAGE_KEY
|
|
5680
|
-
]);
|
|
5681
|
-
function getSystemDark() {
|
|
5682
|
-
if (typeof window === "undefined") return false;
|
|
5683
|
-
return window.matchMedia(DARK_MQ).matches;
|
|
5684
|
-
}
|
|
5685
|
-
function subscribeSystemDark(cb) {
|
|
5686
|
-
if (typeof window === "undefined") return () => {};
|
|
5687
|
-
const mql = window.matchMedia(DARK_MQ);
|
|
5688
|
-
mql.addEventListener("change", cb);
|
|
5689
|
-
return () => mql.removeEventListener("change", cb);
|
|
5690
|
-
}
|
|
5691
|
-
/**
|
|
5692
|
-
* Read the persisted ThemeSpec, preferring a generated spec when present.
|
|
5693
|
-
* Falls back to the legacy preset path otherwise. Does not touch localStorage
|
|
5694
|
-
* apart from the legacy migration handled by `readStoredTheme`.
|
|
5695
|
-
*/
|
|
5696
|
-
function readStoredSpec(defaultPreset, defaultMode, options = {}) {
|
|
5697
|
-
const generated = safeParseStoredSpec(window.localStorage.getItem(THEME_SPEC_STORAGE_KEY));
|
|
5698
|
-
const { preset, mode } = readStoredTheme(window.localStorage, defaultPreset, defaultMode, options);
|
|
5699
|
-
if (generated && generated.kind === "generated") return {
|
|
5700
|
-
spec: generated,
|
|
5701
|
-
mode,
|
|
5702
|
-
presetShadow: preset
|
|
5703
|
-
};
|
|
5704
|
-
return {
|
|
5705
|
-
spec: presetTheme(preset),
|
|
5706
|
-
mode,
|
|
5707
|
-
presetShadow: preset
|
|
5708
|
-
};
|
|
5709
|
-
}
|
|
5710
|
-
function persistSpec(spec) {
|
|
5711
|
-
if (isPresetSpec(spec)) {
|
|
5712
|
-
window.localStorage.setItem(THEME_PRESET_STORAGE_KEY, spec.preset);
|
|
5713
|
-
window.localStorage.removeItem(THEME_SPEC_STORAGE_KEY);
|
|
5714
|
-
window.localStorage.removeItem(THEME_TOKENS_STORAGE_KEY);
|
|
5715
|
-
return;
|
|
5716
|
-
}
|
|
5717
|
-
if (isGeneratedSpec(spec)) {
|
|
5718
|
-
const tokens = computeGeneratedTokens(spec);
|
|
5719
|
-
window.localStorage.setItem(THEME_SPEC_STORAGE_KEY, JSON.stringify(spec));
|
|
5720
|
-
if (tokens) window.localStorage.setItem(THEME_TOKENS_STORAGE_KEY, JSON.stringify(buildTokenCache(tokens)));
|
|
5721
|
-
else window.localStorage.removeItem(THEME_TOKENS_STORAGE_KEY);
|
|
5722
|
-
return;
|
|
5723
|
-
}
|
|
5724
|
-
const descriptor = spec.descriptor;
|
|
5725
|
-
if (isThemePresetId(descriptor.id) && !descriptor.palette) {
|
|
5726
|
-
window.localStorage.setItem(THEME_PRESET_STORAGE_KEY, descriptor.id);
|
|
5727
|
-
window.localStorage.removeItem(THEME_SPEC_STORAGE_KEY);
|
|
5728
|
-
window.localStorage.removeItem(THEME_TOKENS_STORAGE_KEY);
|
|
5729
|
-
return;
|
|
5730
|
-
}
|
|
5731
|
-
if (descriptor.palette) persistSpec({
|
|
5732
|
-
kind: "generated",
|
|
5733
|
-
id: descriptor.id,
|
|
5734
|
-
label: descriptor.label,
|
|
5735
|
-
palette: descriptor.palette,
|
|
5736
|
-
forceLightOnly: descriptor.forceLightOnly
|
|
5737
|
-
});
|
|
5738
|
-
}
|
|
5739
|
-
function upsertGlobalStyle(css) {
|
|
5740
|
-
if (typeof document === "undefined") return;
|
|
5741
|
-
let node = document.getElementById(GLOBAL_THEME_STYLE_ID);
|
|
5742
|
-
if (!node) {
|
|
5743
|
-
node = document.createElement("style");
|
|
5744
|
-
node.id = GLOBAL_THEME_STYLE_ID;
|
|
5745
|
-
document.head.appendChild(node);
|
|
5746
|
-
}
|
|
5747
|
-
if (node.textContent !== css) node.textContent = css;
|
|
5748
|
-
}
|
|
5749
|
-
function removeGlobalStyle() {
|
|
5750
|
-
var _document$getElementB;
|
|
5751
|
-
if (typeof document === "undefined") return;
|
|
5752
|
-
(_document$getElementB = document.getElementById("opt-global-theme")) === null || _document$getElementB === void 0 || _document$getElementB.remove();
|
|
5753
|
-
}
|
|
5754
|
-
const ThemeContext = createContext(void 0);
|
|
5755
|
-
/** Renders the opt theme provider component. */
|
|
5756
|
-
function OptThemeProvider({ children, defaultTheme, controlledTheme, defaultPreset = "default", defaultMode = "system", lockedPreset, allowedModes, allowThemePromotion = true }) {
|
|
5757
|
-
var _allowedModes$, _ref, _effectiveStackTop$sp;
|
|
5758
|
-
const normalizedDefaultMode = coerceThemeMode(defaultMode, allowedModes, (_allowedModes$ = allowedModes === null || allowedModes === void 0 ? void 0 : allowedModes[0]) !== null && _allowedModes$ !== void 0 ? _allowedModes$ : "system");
|
|
5759
|
-
const initialSpec = (_ref = controlledTheme !== null && controlledTheme !== void 0 ? controlledTheme : lockedPreset ? presetTheme(lockedPreset) : defaultTheme) !== null && _ref !== void 0 ? _ref : presetTheme(defaultPreset);
|
|
5760
|
-
const initialPresetShadow = isPresetSpec(initialSpec) ? initialSpec.preset : lockedPreset !== null && lockedPreset !== void 0 ? lockedPreset : defaultPreset;
|
|
5761
|
-
const [theme, setThemeState] = useState(initialSpec);
|
|
5762
|
-
const [presetShadow, setPresetShadow] = useState(initialPresetShadow);
|
|
5763
|
-
const [mode, setModeState] = useState(normalizedDefaultMode);
|
|
5764
|
-
/**
|
|
5765
|
-
* Transient theme override stack — descendants (typically harnesses in
|
|
5766
|
-
* promote-global mode) push specs that take priority over `controlledTheme`
|
|
5767
|
-
* and persisted state. The stack is intentionally kept out of localStorage.
|
|
5768
|
-
*/
|
|
5769
|
-
const [stack, setStack] = useState([]);
|
|
5770
|
-
const isControlled = controlledTheme !== void 0;
|
|
5771
|
-
const isLocked = !isControlled && lockedPreset !== void 0;
|
|
5772
|
-
useEffect(() => {
|
|
5773
|
-
if (!isControlled) return;
|
|
5774
|
-
setThemeState(controlledTheme);
|
|
5775
|
-
if (isPresetSpec(controlledTheme)) setPresetShadow(controlledTheme.preset);
|
|
5776
|
-
}, [controlledTheme, isControlled]);
|
|
5777
|
-
useEffect(() => {
|
|
5778
|
-
if (isControlled) return;
|
|
5779
|
-
if (isLocked) {
|
|
5780
|
-
const locked = lockedPreset !== null && lockedPreset !== void 0 ? lockedPreset : defaultPreset;
|
|
5781
|
-
const { mode: storedMode } = readStoredTheme(window.localStorage, locked, normalizedDefaultMode);
|
|
5782
|
-
const nextMode = coerceThemeMode(storedMode, allowedModes, normalizedDefaultMode);
|
|
5783
|
-
const nextSpec = presetTheme(locked);
|
|
5784
|
-
setThemeState((prev) => themeEqual(prev, nextSpec) ? prev : nextSpec);
|
|
5785
|
-
setPresetShadow((prev) => prev === locked ? prev : locked);
|
|
5786
|
-
setModeState((prev) => prev === nextMode ? prev : nextMode);
|
|
5787
|
-
return;
|
|
5788
|
-
}
|
|
5789
|
-
const next = readStoredSpec(defaultPreset, defaultMode, { migrateLegacy: true });
|
|
5790
|
-
const nextMode = coerceThemeMode(next.mode, allowedModes, normalizedDefaultMode);
|
|
5791
|
-
setThemeState((prev) => themeEqual(prev, next.spec) ? prev : next.spec);
|
|
5792
|
-
setPresetShadow((prev) => prev === next.presetShadow ? prev : next.presetShadow);
|
|
5793
|
-
setModeState((prev) => prev === nextMode ? prev : nextMode);
|
|
5794
|
-
}, [
|
|
5795
|
-
allowedModes,
|
|
5796
|
-
isControlled,
|
|
5797
|
-
isLocked,
|
|
5798
|
-
lockedPreset,
|
|
5799
|
-
normalizedDefaultMode
|
|
5800
|
-
]);
|
|
5801
|
-
useEffect(() => {
|
|
5802
|
-
if (isControlled) return;
|
|
5803
|
-
function handleStorage(event) {
|
|
5804
|
-
if (event.storageArea && event.storageArea !== window.localStorage) return;
|
|
5805
|
-
if (event.key != null && !THEME_STORAGE_KEYS.has(event.key)) return;
|
|
5806
|
-
if (isLocked) {
|
|
5807
|
-
const locked = lockedPreset !== null && lockedPreset !== void 0 ? lockedPreset : defaultPreset;
|
|
5808
|
-
const { mode: storedMode } = readStoredTheme(window.localStorage, locked, normalizedDefaultMode);
|
|
5809
|
-
const nextMode = coerceThemeMode(storedMode, allowedModes, normalizedDefaultMode);
|
|
5810
|
-
const nextSpec = presetTheme(locked);
|
|
5811
|
-
setThemeState((prev) => themeEqual(prev, nextSpec) ? prev : nextSpec);
|
|
5812
|
-
setPresetShadow((prev) => prev === locked ? prev : locked);
|
|
5813
|
-
setModeState((prev) => prev === nextMode ? prev : nextMode);
|
|
5814
|
-
return;
|
|
5815
|
-
}
|
|
5816
|
-
const next = readStoredSpec(defaultPreset, defaultMode, { migrateLegacy: event.key === LEGACY_THEME_STORAGE_KEY });
|
|
5817
|
-
const nextMode = coerceThemeMode(next.mode, allowedModes, normalizedDefaultMode);
|
|
5818
|
-
setThemeState((prev) => themeEqual(prev, next.spec) ? prev : next.spec);
|
|
5819
|
-
setPresetShadow((prev) => prev === next.presetShadow ? prev : next.presetShadow);
|
|
5820
|
-
setModeState((prev) => prev === nextMode ? prev : nextMode);
|
|
5821
|
-
}
|
|
5822
|
-
window.addEventListener("storage", handleStorage);
|
|
5823
|
-
return () => window.removeEventListener("storage", handleStorage);
|
|
5824
|
-
}, [
|
|
5825
|
-
allowedModes,
|
|
5826
|
-
isControlled,
|
|
5827
|
-
isLocked,
|
|
5828
|
-
defaultMode,
|
|
5829
|
-
defaultPreset,
|
|
5830
|
-
lockedPreset,
|
|
5831
|
-
normalizedDefaultMode
|
|
5832
|
-
]);
|
|
5833
|
-
const systemDark = useSyncExternalStore(subscribeSystemDark, getSystemDark, () => false);
|
|
5834
|
-
const stackTop = stack.length > 0 ? stack[stack.length - 1] : null;
|
|
5835
|
-
const effectiveStackTop = allowThemePromotion ? stackTop : null;
|
|
5836
|
-
const isPromoted = effectiveStackTop !== null;
|
|
5837
|
-
const effectiveSpec = (_effectiveStackTop$sp = effectiveStackTop === null || effectiveStackTop === void 0 ? void 0 : effectiveStackTop.spec) !== null && _effectiveStackTop$sp !== void 0 ? _effectiveStackTop$sp : theme;
|
|
5838
|
-
const forceLight = isForceLightSpec(effectiveSpec);
|
|
5839
|
-
const resolvedMode = computeResolvedMode(forceLight, mode, systemDark);
|
|
5840
|
-
const compoundId = getCompoundIdForSpec(effectiveSpec, resolvedMode, forceLight);
|
|
5841
|
-
const [hydrated, setHydrated] = useState(false);
|
|
5842
|
-
useEffect(() => {
|
|
5843
|
-
setHydrated(true);
|
|
5844
|
-
}, []);
|
|
5845
|
-
useEffect(() => {
|
|
5846
|
-
if (!hydrated) return;
|
|
5847
|
-
if (document.documentElement.getAttribute("data-theme") !== compoundId) document.documentElement.setAttribute("data-theme", compoundId);
|
|
5848
|
-
}, [compoundId, hydrated]);
|
|
5849
|
-
useEffect(() => {
|
|
5850
|
-
if (isPresetSpec(effectiveSpec)) {
|
|
5851
|
-
removeGlobalStyle();
|
|
5852
|
-
return;
|
|
5853
|
-
}
|
|
5854
|
-
const tokens = computeGeneratedTokens(effectiveSpec);
|
|
5855
|
-
if (!tokens) {
|
|
5856
|
-
removeGlobalStyle();
|
|
5857
|
-
return;
|
|
5858
|
-
}
|
|
5859
|
-
upsertGlobalStyle(serializeGeneratedTheme(tokens));
|
|
5860
|
-
if (!isControlled && !isPromoted && effectiveSpec === theme) try {
|
|
5861
|
-
window.localStorage.setItem(THEME_TOKENS_STORAGE_KEY, JSON.stringify(buildTokenCache(tokens)));
|
|
5862
|
-
} catch (_unused) {}
|
|
5863
|
-
}, [
|
|
5864
|
-
effectiveSpec,
|
|
5865
|
-
theme,
|
|
5866
|
-
isControlled,
|
|
5867
|
-
isPromoted
|
|
5868
|
-
]);
|
|
5869
|
-
const setTheme = useCallback((next) => {
|
|
5870
|
-
if (isLocked) {
|
|
5871
|
-
if (process.env.NODE_ENV !== "production") console.warn("[OptThemeProvider] setTheme called while lockedPreset is set — ignoring.");
|
|
5872
|
-
return;
|
|
5873
|
-
}
|
|
5874
|
-
if (isControlled) {
|
|
5875
|
-
if (process.env.NODE_ENV !== "production") console.warn("[OptThemeProvider] setTheme called while controlledTheme is set — ignoring.");
|
|
5876
|
-
return;
|
|
5877
|
-
}
|
|
5878
|
-
setThemeState(next);
|
|
5879
|
-
if (isPresetSpec(next)) setPresetShadow(next.preset);
|
|
5880
|
-
try {
|
|
5881
|
-
persistSpec(next);
|
|
5882
|
-
} catch (_unused2) {}
|
|
5883
|
-
}, [isControlled, isLocked]);
|
|
5884
|
-
const setPreset = useCallback((p) => {
|
|
5885
|
-
setTheme(presetTheme(p));
|
|
5886
|
-
}, [setTheme]);
|
|
5887
|
-
const setMode = useCallback((m) => {
|
|
5888
|
-
const nextMode = coerceThemeMode(m, allowedModes, normalizedDefaultMode);
|
|
5889
|
-
setModeState(nextMode);
|
|
5890
|
-
if (!isControlled) try {
|
|
5891
|
-
window.localStorage.setItem(THEME_MODE_STORAGE_KEY, nextMode);
|
|
5892
|
-
} catch (_unused3) {}
|
|
5893
|
-
}, [
|
|
5894
|
-
allowedModes,
|
|
5895
|
-
isControlled,
|
|
5896
|
-
normalizedDefaultMode
|
|
5897
|
-
]);
|
|
5898
|
-
const controller = useMemo(() => ({
|
|
5899
|
-
pushTheme(id, spec) {
|
|
5900
|
-
if (!allowThemePromotion) return;
|
|
5901
|
-
setStack((prev) => {
|
|
5902
|
-
return [...prev.filter((entry) => entry.id !== id), {
|
|
5903
|
-
id,
|
|
5904
|
-
spec
|
|
5905
|
-
}];
|
|
5906
|
-
});
|
|
5907
|
-
},
|
|
5908
|
-
popTheme(id) {
|
|
5909
|
-
if (!allowThemePromotion) return;
|
|
5910
|
-
setStack((prev) => prev.filter((entry) => entry.id !== id));
|
|
5911
|
-
}
|
|
5912
|
-
}), [allowThemePromotion]);
|
|
5913
|
-
const value = useMemo(() => ({
|
|
5914
|
-
theme: effectiveSpec,
|
|
5915
|
-
setTheme,
|
|
5916
|
-
preset: presetShadow,
|
|
5917
|
-
setPreset,
|
|
5918
|
-
mode,
|
|
5919
|
-
setMode,
|
|
5920
|
-
resolvedMode,
|
|
5921
|
-
isControlled,
|
|
5922
|
-
isGenerated: !isPresetSpec(effectiveSpec),
|
|
5923
|
-
isPromoted
|
|
5924
|
-
}), [
|
|
5925
|
-
effectiveSpec,
|
|
5926
|
-
setTheme,
|
|
5927
|
-
presetShadow,
|
|
5928
|
-
setPreset,
|
|
5929
|
-
mode,
|
|
5930
|
-
setMode,
|
|
5931
|
-
resolvedMode,
|
|
5932
|
-
isControlled,
|
|
5933
|
-
isPromoted
|
|
5934
|
-
]);
|
|
5935
|
-
return /* @__PURE__ */ jsx(ThemeContext.Provider, {
|
|
5936
|
-
value,
|
|
5937
|
-
children: /* @__PURE__ */ jsx(OptThemeControllerContext.Provider, {
|
|
5938
|
-
value: controller,
|
|
5939
|
-
children
|
|
5940
|
-
})
|
|
5941
|
-
});
|
|
5942
|
-
}
|
|
5943
|
-
/** Provides opt theme. */
|
|
5944
|
-
function useOptTheme() {
|
|
5945
|
-
const ctx = useContext(ThemeContext);
|
|
5946
|
-
if (!ctx) throw new Error("useOptTheme must be used within OptThemeProvider");
|
|
5947
|
-
return ctx;
|
|
5948
|
-
}
|
|
5949
|
-
/** Reads opt theme context when present without requiring a provider. */
|
|
5950
|
-
function useOptionalOptTheme() {
|
|
5951
|
-
return useContext(ThemeContext);
|
|
5952
|
-
}
|
|
5953
|
-
function computeResolvedMode(forceLight, mode, systemDark) {
|
|
5954
|
-
if (forceLight) return "light";
|
|
5955
|
-
if (mode === "system") return systemDark ? "dark" : "light";
|
|
5956
|
-
return mode;
|
|
5957
|
-
}
|
|
5958
|
-
function themeEqual(a, b) {
|
|
5959
|
-
if (a === b) return true;
|
|
5960
|
-
if (a.kind !== b.kind) return false;
|
|
5961
|
-
if (a.kind === "preset" && b.kind === "preset") return a.preset === b.preset && overridesEqual(a.overrides, b.overrides);
|
|
5962
|
-
if (a.kind === "generated" && b.kind === "generated") return a.id === b.id && a.label === b.label && a.forceLightOnly === b.forceLightOnly && JSON.stringify(a.palette) === JSON.stringify(b.palette) && overridesEqual(a.overrides, b.overrides);
|
|
5963
|
-
if (a.kind === "descriptor" && b.kind === "descriptor") return a.descriptor === b.descriptor && overridesEqual(a.overrides, b.overrides);
|
|
5964
|
-
return false;
|
|
5965
|
-
}
|
|
5966
|
-
function overridesEqual(a, b) {
|
|
5967
|
-
if (a === b) return true;
|
|
5968
|
-
if (!a && !b) return true;
|
|
5969
|
-
if (!a || !b) return false;
|
|
5970
|
-
return JSON.stringify(a) === JSON.stringify(b);
|
|
5971
|
-
}
|
|
5972
4864
|
//#endregion
|
|
5973
4865
|
//#region src/shells/theme-switcher.tsx
|
|
5974
4866
|
const FALLBACK_SWATCHES = [
|
|
@@ -9284,4 +8176,4 @@ const enStarRatingLabels = {
|
|
|
9284
8176
|
};
|
|
9285
8177
|
const enBreadcrumbLabels = { navAriaLabel: "Go to {label}" };
|
|
9286
8178
|
//#endregion
|
|
9287
|
-
export { ALL_COMPOUND_THEMES, AccordionContent, AccordionItem, AccordionRoot, AccordionTrigger, ActivityFeed, Alert, AlertBuilder, AlertDialogPanel, AppMenubar, AppShell, AsyncCombobox, AuditLog, AuditTimeline, AuthForm, Avatar, AvatarGroup, Badge, BlockLayout, BlockLayout as SurfaceLayout, BranchSelect, Breadcrumb, BulkActions, Button, COLOR_PRESETS, Callout, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CatalogCellControls, CatalogFrame, CatalogRowActions, ChatInput, ChatMessageList, ChatSidebar, Checkbox, CheckboxGroup, CircularProgress, CodeDiffViewer, CodeSnippetViewer, ColorPaletteDisplay, ColorPalettePicker, ColorPicker, ColumnToggler, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxPopover, ComboboxRoot, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandPalette, CommandPaletteTrigger, CommandSeparator, CommandShortcut, ComparisonSelector, Composite, CompositeItem, CompositeProvider, CompositeRow, CompositeZone, ConditionBuilder, ConfirmDialog, ConnectionIndicator, Container, ContentTabs, CopyButton, DEFAULT_PRESETS, DEFAULT_TIME_PRESETS, DashboardGrid, DataImportWizard, DataTable, DateRangePicker, DeploymentTimeline, DescriptionList, DesignGuidePanel, DialogBody, DialogDescription, DialogDisclosure, DialogDismiss, DialogFooter, DialogHeader, DialogHeading, DialogPanel, DialogRoot, DisclosureContent, DisclosureRoot, DisclosureTrigger, DomainTable, DrawerClose, DrawerPanel, DrawerRoot, DropdownContent, DropdownItem, DropdownMenu, DropdownSeparator, DropdownTrigger, DynamicFieldForm, EMPTY_QUERY, EditorToolbar, EmptyState, EnvPanel, ErrorBoundary, EventIcon, EventMetaEditor, EventSparkline, EventTimeline, ExportButton, Expression, ExpressionGroup, FIELD_TYPE_TOKENS, FORCE_LIGHT_PRESETS, FORCE_LIGHT_PRESET_IDS, Facet, FacetGroup, FailureList, FaqAccordion, FeatureFlagPanel, FieldSidebar, FieldToken, FieldTokenLegend, FileUploadForm, FilterBar, FloatingActionBar, Flyout, FormCheckbox, FormColorPicker, FormControl, FormDateRangePicker, FormDescription, FormError, FormField, FormGroup, FormGroupLabel, FormIconPicker, FormInput, FormLabel, FormNumberInput, FormProvider, FormPush, FormRadio, FormRadioGroup, FormRemove, FormReset, FormRoot, FormSelect, FormSelectItem, FormSelectPopover, FormSlider, FormStarRating, FormSubmit, FormSwitch, FormTagInput, FormTextarea, GENERATED_THEME_ID_DEFAULT, GLOBAL_THEME_STYLE_ID, Heading, Highlight, IconPicker, Identity, InlineEdit, InlineEditTable, Input, InsightsPanel, InspectorLayout, KanbanBoard, Kbd, KeyPadMenu, KeyValueEditor, LiveRegion, LoadingOverlay, LogTable, Logo, MegaMenu, MenuButtonArrow, MenuItem, MenuItemCheckbox, MenuItemRadio, MenuPopover, MenuRoot, MenuSeparator, MenuTrigger, MenubarContainer, MenubarRoot, Meter, MetricsCard, NotificationCenter, NotificationToast, NumberInput, OPT_TEXT_PRIMARY, OPT_TEXT_SECONDARY, OptThemeControllerContext, OptThemeProvider, OtpField, POPULAR_ICONS, PageAside, PageHeader, Pagination, PopoverClose, PopoverContent, PopoverRoot, PopoverTrigger, Progress, ProjectSwitcher, PromptTemplate, PropertyExplorer, QueryBar, QueryFilterBar, QueryResultsTable, QuickActions, Radio, RadioGroup, ReportBuilder, ReportWidget, ResizableHandle, ResizablePanel, ResizablePanelGroup, RichTextEditor, RouteFocusManager, SHADER_OVERLAY_PARAM_KEYS, SHADER_PARAM_FALLBACK, SHADER_PARAM_KEYS, SHADER_PRESETS, SHADER_PRESET_IDS, SavedFilters, ScoreBreakdown, ScrollArea, SearchCombobox, Section, SegmentBuilder, SegmentedControl, SelectItem, SelectLabel, SelectPopover, SelectRoot, SelectTrigger, Separator, SettingsForm, ShaderSurface, Sidebar, SidebarNav, Skeleton, SkeletonAvatar, SkeletonCard, SkeletonTable, SkeletonText, Slider, SpatialNavProvider, Spinner, SqlEditor, StarRating, StatCard, StatusDot, StatusSelect, StepBuilder, SummaryRow, Switch, THEME_PALETTES, THEME_PRESET_IDS, THEME_REGISTRY, THEME_SPEC_STORAGE_KEY, THEME_TOKENS_STORAGE_KEY, Tab, TabList, TabPanel, TabsRoot, TagInput, TaskList, TeamMemberList, TemplatePicker, Text, TextTruncate, Textarea, ThemeSwitcher, TimeRangeControl, TimeRangeSelector, TimeSeriesPanel, ToastProvider, Toggle, ToggleGroup, ToolbarButton, ToolbarContainer, ToolbarRoot, ToolbarSeparator, Tooltip, TooltipAnchor, TooltipProvider, TreeTable, TrendChart, VerticalTabs, VirtualList, WebhookConfig, WidgetGrid, WizardForm, WorkflowCanvas, addClause, applyCellAction, buildTokenCache, cn, coerceThemeMode, computeGeneratedTokens, computeSpatialTargets, createBlock, createBlock as createSurface, createThemeBootScript, defineThemeOverrides, describeClause, enBreadcrumbLabels, enComboboxLabels, enStarRatingLabels, fieldValues, formatClause, formatOptDateTime, formatOptNumber, formatOptShortDate, formatOptTime, formatQuery, generatedTheme, getCompoundIdForSpec, getCompoundTheme, getShaderFragment, getShaderPreset, getThemeDescriptor, getTrappedContextRole, hasActiveQuery, isDescriptorSpec, isEmptyQuery, isForceLightSpec, isGeneratedSpec, isPresetSpec, isThemePresetId, koBreadcrumbLabels, koComboboxLabels, koStarRatingLabels, matchesQuery, matchesQueryObject, parseQuery, parseQueryWithDiagnostics, presetTheme, queryFields, quoteValue, readStoredTheme, removeClause, resolveDescriptor, resolveFieldType, resolveThemeMode, safeParseStoredSpec, safeParseStoredTokens, schemaValidator, serializeGeneratedTheme, serializeThemeRule, serializeTokenBody, shouldSkipArrow, toast, useAutoRefresh, useControlledState, useFieldValue, useFormContext, useFormStore, useInputId, useOptTheme, useOptThemeController, useOptionalOptTheme, useSidebar, useToast, withFieldValue, withoutField };
|
|
8179
|
+
export { ALL_COMPOUND_THEMES, AccordionContent, AccordionItem, AccordionRoot, AccordionTrigger, ActivityFeed, Alert, AlertBuilder, AlertDialogPanel, AppMenubar, AppShell, AsyncCombobox, AuditLog, AuditTimeline, AuthForm, Avatar, AvatarGroup, Badge, BlockLayout, BlockLayout as SurfaceLayout, BranchSelect, Breadcrumb, BulkActions, Button, COLOR_PRESETS, Callout, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CatalogCellControls, CatalogFrame, CatalogRowActions, ChatInput, ChatMessageList, ChatSidebar, Checkbox, CheckboxGroup, CircularProgress, CodeDiffViewer, CodeSnippetViewer, ColorPaletteDisplay, ColorPalettePicker, ColorPicker, ColumnToggler, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxPopover, ComboboxRoot, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandPalette, CommandPaletteTrigger, CommandSeparator, CommandShortcut, ComparisonSelector, Composite, CompositeItem, CompositeProvider, CompositeRow, CompositeZone, ConditionBuilder, ConfirmDialog, ConnectionIndicator, Container, ContentTabs, CopyButton, DEFAULT_PRESETS, DEFAULT_TIME_PRESETS, DashboardGrid, DataImportWizard, DataTable, DateRangePicker, DeploymentTimeline, DescriptionList, DesignGuidePanel, DialogBody, DialogDescription, DialogDisclosure, DialogDismiss, DialogFooter, DialogHeader, DialogHeading, DialogPanel, DialogRoot, DisclosureContent, DisclosureRoot, DisclosureTrigger, DomainTable, DrawerClose, DrawerPanel, DrawerRoot, DropdownContent, DropdownItem, DropdownMenu, DropdownSeparator, DropdownTrigger, DynamicFieldForm, EMPTY_QUERY, EMPTY_QUERY_FILTERS, EditorToolbar, EmptyState, EnvPanel, ErrorBoundary, EventIcon, EventMetaEditor, EventSparkline, EventTimeline, ExportButton, Expression, ExpressionGroup, FIELD_TYPE_TOKENS, FORCE_LIGHT_PRESETS, FORCE_LIGHT_PRESET_IDS, Facet, FacetGroup, FailureList, FaqAccordion, FeatureFlagPanel, FieldSidebar, FieldToken, FieldTokenLegend, FileUploadForm, FilterBar, FloatingActionBar, Flyout, FormCheckbox, FormColorPicker, FormControl, FormDateRangePicker, FormDescription, FormError, FormField, FormGroup, FormGroupLabel, FormIconPicker, FormInput, FormLabel, FormNumberInput, FormProvider, FormPush, FormRadio, FormRadioGroup, FormRemove, FormReset, FormRoot, FormSelect, FormSelectItem, FormSelectPopover, FormSlider, FormStarRating, FormSubmit, FormSwitch, FormTagInput, FormTextarea, GENERATED_THEME_ID_DEFAULT, GLOBAL_THEME_STYLE_ID, Heading, Highlight, IconPicker, Identity, InlineEdit, InlineEditTable, Input, InsightsPanel, InspectorLayout, KanbanBoard, Kbd, KeyPadMenu, KeyValueEditor, LiveRegion, LoadingOverlay, LogTable, Logo, MegaMenu, MenuButtonArrow, MenuItem, MenuItemCheckbox, MenuItemRadio, MenuPopover, MenuRoot, MenuSeparator, MenuTrigger, MenubarContainer, MenubarRoot, Meter, MetricsCard, NotificationCenter, NotificationToast, NumberInput, OPT_TEXT_PRIMARY, OPT_TEXT_SECONDARY, OptThemeControllerContext, OptThemeProvider, OtpField, POPULAR_ICONS, PageAside, PageHeader, Pagination, PopoverClose, PopoverContent, PopoverRoot, PopoverTrigger, Progress, ProjectSwitcher, PromptTemplate, PropertyExplorer, QueryBar, QueryFilterBar, QueryFiltersMenu, QueryHistoryList, QueryOutputPane, QueryResultChart, QueryResultsTable, QueryToolbar, QueryVariablesMenu, QueryWorkspace, QuickActions, Radio, RadioGroup, ReportBuilder, ReportWidget, ResizableHandle, ResizablePanel, ResizablePanelGroup, RichTextEditor, RouteFocusManager, SHADER_OVERLAY_PARAM_KEYS, SHADER_PARAM_FALLBACK, SHADER_PARAM_KEYS, SHADER_PRESETS, SHADER_PRESET_IDS, SaveQueryDialog, SavedFilters, SchemaTree, ScoreBreakdown, ScrollArea, SearchCombobox, Section, SegmentBuilder, SegmentedControl, SelectItem, SelectLabel, SelectPopover, SelectRoot, SelectTrigger, Separator, SettingsForm, ShaderSurface, Sidebar, SidebarNav, Skeleton, SkeletonAvatar, SkeletonCard, SkeletonTable, SkeletonText, Slider, SpatialNavProvider, Spinner, SqlEditor, StarRating, StatCard, StatusDot, StatusSelect, StepBuilder, SummaryRow, Switch, THEME_PALETTES, THEME_PRESET_IDS, THEME_REGISTRY, THEME_SPEC_STORAGE_KEY, THEME_TOKENS_STORAGE_KEY, Tab, TabList, TabPanel, TabsRoot, TagInput, TaskList, TeamMemberList, TemplatePicker, Text, TextTruncate, Textarea, ThemeSwitcher, TimeRangeControl, TimeRangeSelector, TimeSeriesPanel, ToastProvider, Toggle, ToggleGroup, ToolbarButton, ToolbarContainer, ToolbarRoot, ToolbarSeparator, Tooltip, TooltipAnchor, TooltipProvider, TreeTable, TrendChart, VALUELESS_OPERATORS, VerticalTabs, VirtualList, WebhookConfig, WidgetGrid, WizardForm, WorkflowCanvas, addClause, applyCellAction, buildTokenCache, cn, coerceThemeMode, computeGeneratedTokens, computeSpatialTargets, countActiveQueryFilters, createBlock, createBlock as createSurface, createThemeBootScript, defaultQueryChartConfig, defineThemeOverrides, describeClause, enBreadcrumbLabels, enComboboxLabels, enStarRatingLabels, fieldValues, formatClause, formatOptDateTime, formatOptNumber, formatOptShortDate, formatOptTime, formatQuery, formatQueryCell, generatedTheme, getCompoundIdForSpec, getCompoundTheme, getShaderFragment, getShaderPreset, getThemeDescriptor, getTrappedContextRole, hasActiveQuery, hasActiveQueryFilters, isDescriptorSpec, isEmptyQuery, isForceLightSpec, isGeneratedSpec, isPresetSpec, isThemePresetId, isValidQueryVariableName, koBreadcrumbLabels, koComboboxLabels, koStarRatingLabels, matchesQuery, matchesQueryObject, numericResultColumns, parseQuery, parseQueryWithDiagnostics, presetTheme, queryFields, quoteValue, readStoredTheme, removeClause, replaceSqlPlaceholder, resolveDescriptor, resolveFieldType, resolveThemeMode, safeParseStoredSpec, safeParseStoredTokens, schemaValidator, serializeGeneratedTheme, serializeThemeRule, serializeTokenBody, shouldSkipArrow, splitSqlStatements, sqlPlaceholderNames, sqlStatementAtOffset, sqlUsesPlaceholder, toast, useAutoRefresh, useControlledState, useFieldValue, useFormContext, useFormStore, useInputId, useOptTheme, useOptThemeController, useOptionalOptTheme, useSidebar, useToast, withFieldValue, withoutField };
|