@parallelworks/ui 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/chunks/{CodePreviewEditor-CSPRILMp.js → CodePreviewEditor-B3688Fx4.js} +1 -1
- package/dist/chunks/{Markdown-C5Re2ezs.js → Markdown-iFhq8Gb0.js} +1 -1
- package/dist/chunks/{Monaco-CC4ak1JG.js → Monaco-BEj--GTx.js} +10 -5
- package/dist/chunks/{Provider-DvVvScTQ.js → Provider-uUHgWOWc.js} +55 -2
- package/dist/chunks/{SwitchToggle-2uRw8ZeJ.js → SwitchToggle-BqD0dE-L.js} +36 -29
- package/dist/chunks/{editor-D55tumuZ.js → editor-CdQbKtYO.js} +2 -2
- package/dist/chunks/list-D5f5Fq-O.js +1259 -0
- package/dist/components/Button.d.ts +18 -0
- package/dist/components/Card.d.ts +19 -0
- package/dist/components/Filter.d.ts +15 -0
- package/dist/components/FilterPill.d.ts +7 -0
- package/dist/components/IconButton.d.ts +17 -0
- package/dist/components/Input.d.ts +14 -0
- package/dist/components/LetterBadge.d.ts +6 -0
- package/dist/components/Pagination.d.ts +15 -0
- package/dist/components/Provider.d.ts +25 -0
- package/dist/components/SettingModeOption.d.ts +13 -0
- package/dist/components/SettingRow.d.ts +18 -0
- package/dist/components/SettingsCard.d.ts +24 -0
- package/dist/components/SettingsGroup.d.ts +8 -0
- package/dist/components/Sort.d.ts +9 -0
- package/dist/components/Toggle.d.ts +6 -0
- package/dist/components/dropdownUtils.d.ts +10 -0
- package/dist/components/inputClasses.d.ts +1 -0
- package/dist/editor/index.js +1 -1
- package/dist/file-explorer/index.js +8 -7
- package/dist/form/index.js +2 -2
- package/dist/index.d.ts +15 -0
- package/dist/index.js +429 -5
- package/dist/list/HoverCard.d.ts +22 -0
- package/dist/list/ListPager.d.ts +7 -0
- package/dist/list/ListViewControls.d.ts +12 -0
- package/dist/list/index.d.ts +6 -0
- package/dist/list/index.js +2 -2
- package/dist/list/listSearch.d.ts +27 -0
- package/dist/list/listView.d.ts +129 -0
- package/dist/list/textEntry.d.ts +2 -0
- package/dist/logviewer/index.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/workflow/index.js +1 -1
- package/package.json +4 -2
- package/dist/chunks/list-7PyDF1tz.js +0 -465
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { DEFAULT_PRESET, THEME_PRESETS, THEME_TOKENS, applyTheme, contrastRatio, deriveTheme, isDarkColor } from "./theme/index.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { AlertIcon, AngleRightIcon, EyeIcon, EyeOffIcon, FilterIcon, LoaderIcon, SortDownIcon, SortUnsortedIcon, SortUpIcon } from "./icons.js";
|
|
3
|
+
import { i as Callout, n as CopyCodeBlock, r as CopyToClipboard, t as Markdown } from "./chunks/Markdown-iFhq8Gb0.js";
|
|
4
|
+
import { a as useProvisionCorsRules, c as useStrings, i as useNotify, l as useWorkflowJsonResolver, n as useLink, o as useRunFile, r as useNavigation, s as useSlots, t as UIProvider } from "./chunks/Provider-uUHgWOWc.js";
|
|
4
5
|
import { i as formatTooltipContent, n as TOOLTIP_ID, r as TooltipInfo, t as GlobalTooltip } from "./chunks/Tooltip-WgbiC_nd.js";
|
|
5
|
-
import { a as UncontrolledCollapsiblePanel, c as Dropdown, d as flattenOptions, f as isCategory, i as MaybeCollapsible, l as DropdownCaret, n as SectionHeader, o as MultiSelectDropdown, p as isOption, r as ControlledCollapsiblePanel, s as CustomListbox, t as SwitchToggle, u as filterOption } from "./chunks/SwitchToggle-
|
|
6
|
+
import { a as UncontrolledCollapsiblePanel, c as Dropdown, d as flattenOptions, f as isCategory, i as MaybeCollapsible, l as DropdownCaret, n as SectionHeader, o as MultiSelectDropdown, p as isOption, r as ControlledCollapsiblePanel, s as CustomListbox, t as SwitchToggle, u as filterOption } from "./chunks/SwitchToggle-BqD0dE-L.js";
|
|
6
7
|
import { t as Loader } from "./chunks/Loader-DQiZ75fa.js";
|
|
7
8
|
import { t as Modal } from "./chunks/Modal-sOUEwebV.js";
|
|
8
9
|
import { t as Indicator } from "./chunks/Indicator-hBSIxOPK.js";
|
|
@@ -11,7 +12,7 @@ import { n as StatusDot, t as StatusBadge } from "./chunks/StatusBadge-DXp4zkSd.
|
|
|
11
12
|
import { n as Table, t as CompactTable } from "./chunks/Table-C5z6qWjM.js";
|
|
12
13
|
import cx from "classnames";
|
|
13
14
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
-
import React from "react";
|
|
15
|
+
import React, { forwardRef, useState } from "react";
|
|
15
16
|
import Skeleton from "react-loading-skeleton";
|
|
16
17
|
//#region src/components/DescriptionList.tsx
|
|
17
18
|
function DescriptionListItem({ label, children, tooltip, className, ...props }) {
|
|
@@ -110,4 +111,427 @@ function Overview({ Icon, name, type, children, right, className, loading, iconS
|
|
|
110
111
|
});
|
|
111
112
|
}
|
|
112
113
|
//#endregion
|
|
113
|
-
|
|
114
|
+
//#region src/components/Button.tsx
|
|
115
|
+
var Button = forwardRef(({ children, variant = "primary", size = "default", loading, icon, iconPosition = "right", fullWidth = true, className = "", disabled, ...props }, ref) => {
|
|
116
|
+
const baseClasses = "inline-flex items-center justify-center gap-2 font-semibold rounded-lg transition-all duration-200 cursor-pointer border-none mt-2 disabled:opacity-50 disabled:cursor-not-allowed";
|
|
117
|
+
const variantClasses = {
|
|
118
|
+
primary: "bg-gradient-to-br from-[var(--gradient-start,var(--theme-element))] to-[var(--gradient-mid,var(--theme-link))] text-white shadow-[0_4px_14px_0_rgba(59,130,246,0.3)] hover:enabled:-translate-y-0.5 hover:enabled:shadow-[0_6px_20px_0_rgba(59,130,246,0.4)] active:enabled:translate-y-0",
|
|
119
|
+
secondary: "bg-[var(--theme-muted-panel-bg)] text-[var(--theme-app)] border border-[var(--theme-border)] hover:enabled:bg-[var(--theme-border)]",
|
|
120
|
+
outline: "bg-transparent text-[var(--theme-app)] border border-[var(--theme-border)] hover:enabled:bg-[var(--theme-muted-panel-bg)] hover:enabled:border-[var(--theme-muted-text-color)]",
|
|
121
|
+
ghost: "bg-transparent text-[var(--theme-muted-text-color)] hover:enabled:text-[var(--theme-app)] hover:enabled:bg-[var(--theme-muted-panel-bg)]"
|
|
122
|
+
};
|
|
123
|
+
const sizeClasses = {
|
|
124
|
+
sm: "py-2 px-4 text-[0.8125rem]",
|
|
125
|
+
default: "py-3 px-5 text-sm",
|
|
126
|
+
lg: "py-4 px-6 text-base"
|
|
127
|
+
};
|
|
128
|
+
const widthClass = fullWidth ? "w-full" : "w-auto";
|
|
129
|
+
return /* @__PURE__ */ jsx("button", {
|
|
130
|
+
ref,
|
|
131
|
+
disabled: disabled || loading,
|
|
132
|
+
className: cx(baseClasses, variantClasses[variant], sizeClasses[size], widthClass, className),
|
|
133
|
+
...props,
|
|
134
|
+
children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(LoaderIcon, { className: "size-[18px]" }), children] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
135
|
+
icon && iconPosition === "left" && /* @__PURE__ */ jsx("span", {
|
|
136
|
+
className: "flex items-center",
|
|
137
|
+
children: icon
|
|
138
|
+
}),
|
|
139
|
+
children,
|
|
140
|
+
icon && iconPosition === "right" && /* @__PURE__ */ jsx("span", {
|
|
141
|
+
className: "flex items-center",
|
|
142
|
+
children: icon
|
|
143
|
+
})
|
|
144
|
+
] })
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
Button.displayName = "Button";
|
|
148
|
+
function MethodButton({ icon, label, description, href, className = "", ...props }) {
|
|
149
|
+
const Link = useLink();
|
|
150
|
+
const baseClasses = "flex items-center w-full p-4 bg-[var(--theme-muted-panel-bg)] border border-[var(--theme-border)] rounded-xl text-[var(--theme-app)] text-[0.9375rem] font-medium cursor-pointer transition-all duration-200 no-underline mb-3 last:mb-0 hover:bg-[var(--theme-border)] hover:border-[var(--theme-muted-text-color)] hover:-translate-y-0.5 active:translate-y-0";
|
|
151
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
152
|
+
icon && /* @__PURE__ */ jsx("span", {
|
|
153
|
+
className: "size-10 rounded-lg bg-gradient-to-br from-[var(--gradient-start,var(--theme-element))] to-[var(--gradient-mid,var(--theme-link))] flex items-center justify-center shrink-0 mr-4 [&_svg]:size-5 [&_svg]:text-white",
|
|
154
|
+
children: icon
|
|
155
|
+
}),
|
|
156
|
+
/* @__PURE__ */ jsxs("span", {
|
|
157
|
+
className: "flex-1 text-left",
|
|
158
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
159
|
+
className: "block font-semibold text-[var(--theme-app)]",
|
|
160
|
+
children: label
|
|
161
|
+
}), description && /* @__PURE__ */ jsx("span", {
|
|
162
|
+
className: "block text-[0.8125rem] text-[var(--theme-muted-text-color)] font-normal mt-0.5",
|
|
163
|
+
children: description
|
|
164
|
+
})]
|
|
165
|
+
}),
|
|
166
|
+
/* @__PURE__ */ jsx(AngleRightIcon, { className: "size-5 text-[var(--theme-muted-text-color)] shrink-0 ml-2 transition-all duration-200 group-hover:translate-x-[3px] group-hover:text-[var(--theme-app)]" })
|
|
167
|
+
] });
|
|
168
|
+
if (href) {
|
|
169
|
+
if (href.startsWith("/api/") || href.startsWith("http")) return /* @__PURE__ */ jsx("a", {
|
|
170
|
+
href,
|
|
171
|
+
className: cx("group", baseClasses, className),
|
|
172
|
+
children: content
|
|
173
|
+
});
|
|
174
|
+
return /* @__PURE__ */ jsx(Link, {
|
|
175
|
+
to: href,
|
|
176
|
+
className: cx("group", baseClasses, className),
|
|
177
|
+
children: content
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
return /* @__PURE__ */ jsx("button", {
|
|
181
|
+
className: cx("group", baseClasses, className),
|
|
182
|
+
...props,
|
|
183
|
+
children: content
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region src/components/Card.tsx
|
|
188
|
+
function Card({ children, className = "", wide, compact, interactive, authShadow }) {
|
|
189
|
+
return /* @__PURE__ */ jsx("div", {
|
|
190
|
+
className: cx("w-full bg-[var(--theme-panel-bg)] backdrop-blur-xl border border-[var(--theme-border)] rounded-2xl", authShadow ? "shadow-[0_25px_80px_-20px_rgba(0,0,0,0.4),0_10px_30px_-10px_rgba(0,0,0,0.25)]" : "shadow-md", wide && "max-w-[560px] p-8", compact && "max-w-[400px] p-6", !wide && !compact && "max-w-[520px] p-10", interactive && "ds-card-interactive cursor-pointer", className),
|
|
191
|
+
children
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
function CardHeader({ badge, title, description, className = "", align = "center" }) {
|
|
195
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
196
|
+
className: cx(align === "center" ? "text-center" : "text-left", "mb-6", className),
|
|
197
|
+
children: [
|
|
198
|
+
badge && /* @__PURE__ */ jsx("div", {
|
|
199
|
+
className: "inline-flex items-center gap-1.5 py-1.5 px-3 text-xs font-medium bg-[var(--theme-muted-panel-bg)] border border-[var(--theme-border)] rounded-full text-[var(--theme-muted-text-color)] mb-4 transition-colors duration-200",
|
|
200
|
+
children: badge
|
|
201
|
+
}),
|
|
202
|
+
/* @__PURE__ */ jsx("h1", {
|
|
203
|
+
className: "text-2xl font-bold tracking-tight text-[var(--theme-app)]",
|
|
204
|
+
style: { letterSpacing: "-0.025em" },
|
|
205
|
+
children: title
|
|
206
|
+
}),
|
|
207
|
+
description && /* @__PURE__ */ jsx("p", {
|
|
208
|
+
className: "text-[var(--theme-muted-text-color)] text-sm leading-relaxed mt-2",
|
|
209
|
+
children: description
|
|
210
|
+
})
|
|
211
|
+
]
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
//#endregion
|
|
215
|
+
//#region src/components/Input.tsx
|
|
216
|
+
var Input = forwardRef(({ label, error, className = "", mono, type, ...props }, ref) => {
|
|
217
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
218
|
+
const isPassword = type === "password";
|
|
219
|
+
const inputType = isPassword && showPassword ? "text" : type;
|
|
220
|
+
const inputClasses = cx("w-full py-3 px-4 bg-[var(--theme-muted-panel-bg)] border border-[var(--theme-border)] rounded-lg text-[var(--theme-app)] text-sm transition-all duration-200 box-border", "focus:outline-none focus:border-[var(--theme-element)] focus:shadow-[0_0_0_3px_color-mix(in_srgb,var(--theme-element)_25%,transparent)]", "placeholder:text-[var(--theme-muted-text-color)]", "disabled:bg-[var(--theme-muted-panel-bg)] disabled:text-[var(--theme-muted-text-color)] disabled:cursor-not-allowed disabled:opacity-70", mono && "font-mono text-[0.8125rem]", error && "border-[#ef4444]", isPassword && "pr-11", className);
|
|
221
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
222
|
+
className: "flex flex-col gap-1.5",
|
|
223
|
+
children: [
|
|
224
|
+
label && /* @__PURE__ */ jsx("label", {
|
|
225
|
+
className: "text-[0.8125rem] font-medium text-[var(--theme-app)]",
|
|
226
|
+
htmlFor: props.id || props.name,
|
|
227
|
+
children: label
|
|
228
|
+
}),
|
|
229
|
+
/* @__PURE__ */ jsxs("div", {
|
|
230
|
+
className: isPassword ? "relative w-full" : "",
|
|
231
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
232
|
+
ref,
|
|
233
|
+
type: inputType,
|
|
234
|
+
className: inputClasses,
|
|
235
|
+
...props
|
|
236
|
+
}), isPassword && /* @__PURE__ */ jsx("button", {
|
|
237
|
+
type: "button",
|
|
238
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 bg-transparent border-none text-[var(--theme-muted-text-color)] cursor-pointer p-1 transition-colors duration-200 flex items-center justify-center hover:text-[var(--theme-app)]",
|
|
239
|
+
onClick: () => setShowPassword(!showPassword),
|
|
240
|
+
tabIndex: -1,
|
|
241
|
+
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
242
|
+
children: showPassword ? /* @__PURE__ */ jsx(EyeOffIcon, { className: "w-5 h-5" }) : /* @__PURE__ */ jsx(EyeIcon, { className: "w-5 h-5" })
|
|
243
|
+
})]
|
|
244
|
+
}),
|
|
245
|
+
error && /* @__PURE__ */ jsxs("span", {
|
|
246
|
+
className: "text-[0.8125rem] text-[#ef4444] flex items-center gap-1.5",
|
|
247
|
+
children: [/* @__PURE__ */ jsx(AlertIcon, { className: "w-4 h-4" }), error]
|
|
248
|
+
})
|
|
249
|
+
]
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
Input.displayName = "Input";
|
|
253
|
+
var Textarea = forwardRef(({ label, error, className = "", mono, ...props }, ref) => {
|
|
254
|
+
const textareaClasses = cx("w-full py-3 px-4 bg-[var(--theme-muted-panel-bg)] border border-[var(--theme-border)] rounded-lg text-[var(--theme-app)] text-sm transition-all duration-200 box-border min-h-[140px] resize-y", "focus:outline-none focus:border-[var(--theme-element)] focus:shadow-[0_0_0_3px_color-mix(in_srgb,var(--theme-element)_25%,transparent)]", "placeholder:text-[var(--theme-muted-text-color)]", mono && "font-mono text-[0.8125rem]", error && "border-[#ef4444]", className);
|
|
255
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
256
|
+
className: "flex flex-col gap-1.5",
|
|
257
|
+
children: [
|
|
258
|
+
label && /* @__PURE__ */ jsx("label", {
|
|
259
|
+
className: "text-[0.8125rem] font-medium text-[var(--theme-app)]",
|
|
260
|
+
htmlFor: props.id || props.name,
|
|
261
|
+
children: label
|
|
262
|
+
}),
|
|
263
|
+
/* @__PURE__ */ jsx("textarea", {
|
|
264
|
+
ref,
|
|
265
|
+
className: textareaClasses,
|
|
266
|
+
...props
|
|
267
|
+
}),
|
|
268
|
+
error && /* @__PURE__ */ jsxs("span", {
|
|
269
|
+
className: "text-[0.8125rem] text-[#ef4444] flex items-center gap-1.5",
|
|
270
|
+
children: [/* @__PURE__ */ jsx(AlertIcon, { className: "w-4 h-4" }), error]
|
|
271
|
+
})
|
|
272
|
+
]
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
Textarea.displayName = "Textarea";
|
|
276
|
+
//#endregion
|
|
277
|
+
//#region src/components/inputClasses.ts
|
|
278
|
+
var inputClasses = "w-full rounded-md border theme-border bg-(--theme-input-bg) px-3 py-2 text-sm text-(--theme-panel) outline-none focus:ring-2 focus:ring-(--theme-element)";
|
|
279
|
+
//#endregion
|
|
280
|
+
//#region src/components/IconButton.tsx
|
|
281
|
+
var IconButton = forwardRef(({ icon, label, variant = "default", size = "md", active = false, showTooltip = true, className, disabled, ...props }, ref) => {
|
|
282
|
+
const sizeClasses = {
|
|
283
|
+
sm: "w-7 h-7 [&_svg]:w-3.5 [&_svg]:h-3.5",
|
|
284
|
+
md: "w-9 h-9 [&_svg]:w-4 [&_svg]:h-4",
|
|
285
|
+
lg: "w-11 h-11 [&_svg]:w-5 [&_svg]:h-5"
|
|
286
|
+
};
|
|
287
|
+
const variantClasses = {
|
|
288
|
+
default: cx("bg-[var(--theme-muted-panel-bg)] text-[var(--theme-muted-text-color)]", "hover:bg-[var(--theme-border)] hover:text-[var(--theme-app)]", active && "bg-[var(--theme-element)]/10 text-[var(--theme-element)]"),
|
|
289
|
+
ghost: cx("bg-transparent text-[var(--theme-muted-text-color)]", "hover:bg-[var(--theme-muted-panel-bg)] hover:text-[var(--theme-app)]", active && "text-[var(--theme-element)]"),
|
|
290
|
+
primary: cx("bg-[var(--theme-element)] text-white", "hover:bg-[var(--theme-element)]/90", active && "ring-2 ring-[var(--theme-element)]/50"),
|
|
291
|
+
success: cx("bg-[#22c55e] text-white", "hover:bg-[#22c55e]/90", active && "ring-2 ring-[#22c55e]/50")
|
|
292
|
+
};
|
|
293
|
+
return /* @__PURE__ */ jsx("button", {
|
|
294
|
+
ref,
|
|
295
|
+
type: "button",
|
|
296
|
+
"aria-label": label,
|
|
297
|
+
disabled,
|
|
298
|
+
"data-tooltip-id": showTooltip ? TOOLTIP_ID : void 0,
|
|
299
|
+
"data-tooltip-content": label,
|
|
300
|
+
"data-tooltip-delay-show": 300,
|
|
301
|
+
"data-tooltip-class-name": "!bg-[var(--theme-app)] !text-[var(--theme-app-bg)] !text-xs !py-1 !px-2 !rounded-md",
|
|
302
|
+
className: cx("inline-flex items-center justify-center rounded-lg", "transition-all duration-200 cursor-pointer", "disabled:opacity-50 disabled:cursor-not-allowed", sizeClasses[size], variantClasses[variant], className),
|
|
303
|
+
...props,
|
|
304
|
+
children: icon
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
IconButton.displayName = "IconButton";
|
|
308
|
+
//#endregion
|
|
309
|
+
//#region src/components/Toggle.tsx
|
|
310
|
+
function Toggle({ checked, onChange, disabled, label }) {
|
|
311
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
312
|
+
onClick: (e) => e.stopPropagation(),
|
|
313
|
+
className: cx("relative inline-flex items-center", disabled ? "cursor-not-allowed opacity-60" : "cursor-pointer"),
|
|
314
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
315
|
+
type: "checkbox",
|
|
316
|
+
className: "peer sr-only",
|
|
317
|
+
checked,
|
|
318
|
+
onChange: (e) => onChange(e.target.checked),
|
|
319
|
+
disabled,
|
|
320
|
+
"aria-label": label
|
|
321
|
+
}), /* @__PURE__ */ jsx("div", { className: "h-6 w-11 rounded-full bg-(--theme-muted-panel-bg) transition-colors peer-checked:bg-(--theme-element) peer-focus-visible:ring-2 peer-focus-visible:ring-[color-mix(in_srgb,var(--theme-element)_25%,transparent)] after:absolute after:start-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:bg-white after:shadow-sm after:transition-transform after:content-[\"\"] motion-reduce:after:transition-none peer-checked:after:translate-x-5" })]
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/components/LetterBadge.tsx
|
|
326
|
+
/** A compact letter badge ("AI", "PUB", "SSH") used as a type mark in place of
|
|
327
|
+
* an icon. Size the box and text via className (e.g. "h-5 w-5 text-[8px]"). */
|
|
328
|
+
function LetterBadge({ text, className }) {
|
|
329
|
+
return /* @__PURE__ */ jsx("span", {
|
|
330
|
+
className: cx("inline-flex shrink-0 items-center justify-center rounded-[3px] border theme-border font-bold leading-none tracking-tight text-(--theme-app)", className),
|
|
331
|
+
children: text
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
//#endregion
|
|
335
|
+
//#region src/components/FilterPill.tsx
|
|
336
|
+
function FilterPill({ active, onClick, children }) {
|
|
337
|
+
return /* @__PURE__ */ jsx("button", {
|
|
338
|
+
type: "button",
|
|
339
|
+
onClick,
|
|
340
|
+
className: cx("px-3 py-1.5 text-xs font-medium rounded-full border transition-all duration-200", active ? "bg-[var(--theme-panel-bg)] border-[var(--theme-border)] text-[var(--theme-panel)] shadow-sm" : "bg-transparent border-transparent text-[var(--theme-muted-text-color)] hover:text-[var(--theme-panel)] hover:bg-[var(--theme-hover)]"),
|
|
341
|
+
children
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
345
|
+
//#region src/components/Filter.tsx
|
|
346
|
+
function Filter({ filter, setFilter, placeholder = "Filter...", pills, activePill, onPillChange }) {
|
|
347
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
348
|
+
className: "flex items-center gap-2",
|
|
349
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
350
|
+
className: "relative flex items-center",
|
|
351
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
352
|
+
placeholder,
|
|
353
|
+
type: "text",
|
|
354
|
+
value: filter,
|
|
355
|
+
onChange: (e) => setFilter(e.target.value.toLowerCase()),
|
|
356
|
+
className: "shadow-sm focus:ring-1 block w-full pr-3 sm:text-sm theme-border rounded-md py-1.5 pl-8"
|
|
357
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
358
|
+
className: "absolute inset-y-0 left-0 flex py-2.5 pl-2",
|
|
359
|
+
children: /* @__PURE__ */ jsx(FilterIcon, {})
|
|
360
|
+
})]
|
|
361
|
+
}), pills && onPillChange && /* @__PURE__ */ jsx("div", {
|
|
362
|
+
className: "flex gap-1",
|
|
363
|
+
children: pills.map((pill) => /* @__PURE__ */ jsx("button", {
|
|
364
|
+
type: "button",
|
|
365
|
+
onClick: () => onPillChange(pill.value),
|
|
366
|
+
className: cx("px-2.5 py-1 text-xs rounded-full transition-colors border", activePill === pill.value ? "bg-(--theme-element) text-(--theme-element-text) border-transparent" : "theme-border theme-text hover:theme-hover"),
|
|
367
|
+
children: pill.label
|
|
368
|
+
}, pill.value))
|
|
369
|
+
})]
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
//#endregion
|
|
373
|
+
//#region src/components/Sort.tsx
|
|
374
|
+
var SortIcon = ({ currentlySorted, currentDirection, name }) => {
|
|
375
|
+
const style = { transform: "translateY(2px)" };
|
|
376
|
+
if (currentlySorted === name) {
|
|
377
|
+
if (currentDirection === "ascending") return /* @__PURE__ */ jsx(SortDownIcon, { style });
|
|
378
|
+
else if (currentDirection === "descending") return /* @__PURE__ */ jsx(SortUpIcon, { style });
|
|
379
|
+
} else return /* @__PURE__ */ jsx(SortUnsortedIcon, { style });
|
|
380
|
+
return null;
|
|
381
|
+
};
|
|
382
|
+
function Sort({ currentlySorted, name, setCurrentDirection, setCurrentlySorted, currentDirection }) {
|
|
383
|
+
const sort = (sorted, direction) => {
|
|
384
|
+
if (sorted === name) {
|
|
385
|
+
if (direction === "ascending") setCurrentDirection("descending");
|
|
386
|
+
else if (direction === "descending") {
|
|
387
|
+
setCurrentDirection("unsorted");
|
|
388
|
+
setCurrentlySorted("");
|
|
389
|
+
}
|
|
390
|
+
} else {
|
|
391
|
+
setCurrentDirection("ascending");
|
|
392
|
+
setCurrentlySorted(name);
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
return /* @__PURE__ */ jsx("div", {
|
|
396
|
+
className: "inline",
|
|
397
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
398
|
+
onClick: () => sort(currentlySorted, currentDirection),
|
|
399
|
+
children: /* @__PURE__ */ jsx(SortIcon, {
|
|
400
|
+
currentDirection,
|
|
401
|
+
currentlySorted,
|
|
402
|
+
name
|
|
403
|
+
})
|
|
404
|
+
})
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
//#endregion
|
|
408
|
+
//#region src/components/Pagination.tsx
|
|
409
|
+
function Pagination({ endingNumber, endingTime, nextCallback, prevCallback, roundedBottom, startingNumber, startingTime, nextDisabled, prevDisabled, name, useTimeRange = false }) {
|
|
410
|
+
const t = useStrings().list;
|
|
411
|
+
return /* @__PURE__ */ jsxs("nav", {
|
|
412
|
+
className: cx(roundedBottom && "rounded-b-2xl", "theme-muted-panel flex items-center justify-between border-t theme-border px-4 py-1 sm:px-6"),
|
|
413
|
+
"aria-label": "Pagination",
|
|
414
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
415
|
+
className: cx("hidden", (startingNumber !== void 0 && startingNumber !== null && endingNumber !== void 0 && endingNumber !== null || startingTime && endingTime) && "sm:block"),
|
|
416
|
+
children: /* @__PURE__ */ jsx("p", {
|
|
417
|
+
className: "text-sm whitespace-nowrap",
|
|
418
|
+
children: useTimeRange && startingTime && endingTime ? t.paginationShowingTimeRange(name ?? "", startingTime, endingTime) : t.paginationShowing(name ?? "", startingNumber ?? "", endingNumber ?? "")
|
|
419
|
+
})
|
|
420
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
421
|
+
className: "flex flex-1 justify-between sm:justify-end gap-x-2",
|
|
422
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
423
|
+
disabled: prevDisabled,
|
|
424
|
+
onClick: prevCallback,
|
|
425
|
+
className: cx("link text-sm", prevDisabled && "disabled"),
|
|
426
|
+
children: t.paginationPrevious
|
|
427
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
428
|
+
disabled: nextDisabled,
|
|
429
|
+
onClick: nextCallback,
|
|
430
|
+
className: cx("link text-sm", nextDisabled && "disabled"),
|
|
431
|
+
children: t.paginationNext
|
|
432
|
+
})]
|
|
433
|
+
})]
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
//#endregion
|
|
437
|
+
//#region src/components/SettingsCard.tsx
|
|
438
|
+
/**
|
|
439
|
+
* A settings card: an optional sentence-case section label sits above a
|
|
440
|
+
* bordered panel of rows. The label carries the breathing-room rhythm between
|
|
441
|
+
* cards; the rows inside provide their own dividers via SettingRow's `isFirst`.
|
|
442
|
+
*/
|
|
443
|
+
function SettingsCard({ title, description, action, actionAlign = "adjacent", overflowVisible, children, className }) {
|
|
444
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
445
|
+
className: cx("mt-10 first:mt-0", className),
|
|
446
|
+
children: [(title || action) && /* @__PURE__ */ jsxs("div", {
|
|
447
|
+
className: "mb-3 px-0.5",
|
|
448
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
449
|
+
className: cx("flex items-center gap-1.5", actionAlign === "right" && "justify-between"),
|
|
450
|
+
children: [title && /* @__PURE__ */ jsx("h2", {
|
|
451
|
+
className: "text-[15px] font-semibold theme-text leading-none",
|
|
452
|
+
children: title
|
|
453
|
+
}), action]
|
|
454
|
+
}), description && /* @__PURE__ */ jsx("p", {
|
|
455
|
+
className: "text-xs theme-muted-text mt-1.5 leading-snug",
|
|
456
|
+
children: description
|
|
457
|
+
})]
|
|
458
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
459
|
+
className: cx("panel", overflowVisible ? "overflow-visible" : "overflow-hidden"),
|
|
460
|
+
children
|
|
461
|
+
})]
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
//#endregion
|
|
465
|
+
//#region src/components/SettingsGroup.tsx
|
|
466
|
+
function SettingsGroup({ title, children, className }) {
|
|
467
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
468
|
+
className: cx("mt-8 first:mt-0", className),
|
|
469
|
+
children: [title && /* @__PURE__ */ jsx("h2", {
|
|
470
|
+
className: "text-[11px] font-semibold uppercase tracking-wider theme-muted-text mb-2 px-1",
|
|
471
|
+
children: title
|
|
472
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
473
|
+
className: "panel divide-y divide-(--theme-border)",
|
|
474
|
+
children
|
|
475
|
+
})]
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
//#endregion
|
|
479
|
+
//#region src/components/SettingRow.tsx
|
|
480
|
+
function SettingRow({ label, htmlFor, helpText, children, isFirst, fill, onClick }) {
|
|
481
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
482
|
+
onClick,
|
|
483
|
+
className: cx("px-5 py-5 grid grid-cols-1 gap-x-8 gap-y-2", fill ? "md:grid-cols-[200px_1fr]" : "md:grid-cols-[1fr_auto]", !isFirst && "border-t theme-border", onClick && "cursor-pointer select-none hover:theme-hover transition-colors"),
|
|
484
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
485
|
+
className: "flex flex-col gap-y-1",
|
|
486
|
+
children: [/* @__PURE__ */ jsx("label", {
|
|
487
|
+
htmlFor,
|
|
488
|
+
className: "font-semibold theme-text leading-tight",
|
|
489
|
+
children: label
|
|
490
|
+
}), helpText && /* @__PURE__ */ jsx("div", {
|
|
491
|
+
className: "theme-muted-text text-xs leading-snug",
|
|
492
|
+
children: helpText
|
|
493
|
+
})]
|
|
494
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
495
|
+
className: cx("min-w-0", !fill && "flex items-center justify-end"),
|
|
496
|
+
children
|
|
497
|
+
})]
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
function SettingSection({ title, isFirst }) {
|
|
501
|
+
return /* @__PURE__ */ jsx("div", {
|
|
502
|
+
className: cx("px-5 py-3 theme-muted-panel", !isFirst && "border-t theme-border"),
|
|
503
|
+
children: /* @__PURE__ */ jsx("h2", {
|
|
504
|
+
className: "font-semibold text-sm uppercase tracking-wider theme-muted-text",
|
|
505
|
+
children: title
|
|
506
|
+
})
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
//#endregion
|
|
510
|
+
//#region src/components/SettingModeOption.tsx
|
|
511
|
+
/** A labeled + described radio option row, used inside a SettingsCard to pick
|
|
512
|
+
* between modes (e.g. default vs custom). Stacked rows share the card's
|
|
513
|
+
* dividers via `isFirst`. */
|
|
514
|
+
function SettingModeOption({ name, checked, onSelect, label, description, isFirst, disabled }) {
|
|
515
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
516
|
+
className: cx("flex items-start gap-3 px-5 py-4", disabled ? "cursor-default opacity-60" : "cursor-pointer", !isFirst && "border-t theme-border"),
|
|
517
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
518
|
+
type: "radio",
|
|
519
|
+
name,
|
|
520
|
+
checked,
|
|
521
|
+
onChange: onSelect,
|
|
522
|
+
disabled,
|
|
523
|
+
className: "mt-0.5 w-4 h-4 theme-input shrink-0"
|
|
524
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
525
|
+
className: "min-w-0",
|
|
526
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
527
|
+
className: "font-semibold theme-text leading-tight",
|
|
528
|
+
children: label
|
|
529
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
530
|
+
className: "theme-muted-text text-xs leading-snug mt-0.5",
|
|
531
|
+
children: description
|
|
532
|
+
})]
|
|
533
|
+
})]
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
//#endregion
|
|
537
|
+
export { Button, Callout, Card, CardHeader, CompactTable, ControlledCollapsiblePanel, CopyCodeBlock, CopyToClipboard, CustomListbox, DEFAULT_PRESET, DescriptionList, DescriptionListItem, Dropdown, DropdownCaret, EmptyState, Filter, FilterPill, GlobalTooltip, IconButton, Indicator, Input, LetterBadge, Loader, Markdown, MaybeCollapsible, MethodButton, Modal, MultiSelectDropdown, Overview, Pagination, SectionHeader, SettingModeOption, SettingRow, SettingSection, SettingsCard, SettingsGroup, Sort, StatusBadge, StatusDot, SwitchToggle, SwitchToggleSmall, THEME_PRESETS, THEME_TOKENS, TOOLTIP_ID, Table, Textarea, Toggle, TooltipInfo, UIProvider, UncontrolledCollapsiblePanel, applyTheme, contrastRatio, deriveTheme, filterOption, flattenOptions, formatTooltipContent, inputClasses, isCategory, isDarkColor, isOption, useNavigation, useNotify, useProvisionCorsRules, useRunFile, useSlots, useStrings, useWorkflowJsonResolver };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
type HoverCoords = {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
};
|
|
6
|
+
export declare function useHoverCard<T extends HTMLElement>(): {
|
|
7
|
+
triggerRef: import("react").RefObject<T | null>;
|
|
8
|
+
coords: HoverCoords | null;
|
|
9
|
+
scheduleOpen: () => void;
|
|
10
|
+
scheduleClose: () => void;
|
|
11
|
+
keepOpen: () => void;
|
|
12
|
+
};
|
|
13
|
+
export declare function HoverCardSurface({ x, y, widthClassName, relayoutKey, onKeepOpen, onLeave, children, }: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
widthClassName: string;
|
|
17
|
+
relayoutKey?: unknown;
|
|
18
|
+
onKeepOpen: () => void;
|
|
19
|
+
onLeave: () => void;
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
}): import("react").ReactPortal;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Footer pager bar for paginated new-nav lists: "{start}–{end} of {total}" with prev/next. Renders nothing for a single page. */
|
|
2
|
+
export declare function ListPager({ page, pageSize, total, onPageChange, }: {
|
|
3
|
+
page: number;
|
|
4
|
+
pageSize: number;
|
|
5
|
+
total: number;
|
|
6
|
+
onPageChange: (page: number) => void;
|
|
7
|
+
}): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ListView } from './listView.js';
|
|
2
|
+
/** Shared chrome for the toolbar control buttons (Filter, Display, Search) so
|
|
3
|
+
* they read as a consistent button cluster — matched by ListSearchControl. */
|
|
4
|
+
export declare const listControlButtonClasses = "relative flex h-7 w-7 items-center justify-center rounded-md border border-(--theme-border) text-(--theme-muted-text-color) hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app) transition-colors";
|
|
5
|
+
export declare function ListDisplayMenu<T>({ view, label, }: {
|
|
6
|
+
view: ListView<T>;
|
|
7
|
+
label?: string;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
9
|
+
export declare function ListFilterMenu<T>({ view, label, }: {
|
|
10
|
+
view: ListView<T>;
|
|
11
|
+
label?: string;
|
|
12
|
+
}): import("react").JSX.Element | null;
|
package/dist/list/index.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
export { assembleRowMenu, copySubmenu, MoreButton, rowContextMenuProps, toolbarActionToRowAction, toRowMenuItem, useRowMenu, useRowMenuActive, type OpenMenu, type RowAction, type RowMenuItem, } from './RowContextMenu.js';
|
|
2
2
|
export { actionsColumnWidth, GroupRow, ListActionsHeader, ListError, ListSkeleton, listTableFixedProps, listTableProps, NAME_MIN_WIDTH_PX, NameCell, RowSelectCheckbox, } from './ListTable.js';
|
|
3
|
+
export { DEFAULT_ORDER, FAVORITE_ORDER, useListView, type ActionDef, type ColumnDef, type FilterFacet, type ListView, type ListViewChrome, type ListViewConfig, type OrderByOption, } from './listView.js';
|
|
4
|
+
export { ListCount, ListSearchControl, useListSearch, type ListSearch, } from './listSearch.js';
|
|
5
|
+
export { listControlButtonClasses, ListDisplayMenu, ListFilterMenu, } from './ListViewControls.js';
|
|
6
|
+
export { ListPager } from './ListPager.js';
|
|
7
|
+
export { HoverCardSurface, useHoverCard } from './HoverCard.js';
|
|
8
|
+
export { isTextEntryContext } from './textEntry.js';
|
package/dist/list/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { GroupRow, ListActionsHeader, ListError, ListSkeleton, MoreButton, NAME_MIN_WIDTH_PX, NameCell, RowSelectCheckbox, actionsColumnWidth, assembleRowMenu, copySubmenu, listTableFixedProps, listTableProps, rowContextMenuProps, toRowMenuItem, toolbarActionToRowAction, useRowMenu, useRowMenuActive };
|
|
1
|
+
import { A as useRowMenu, C as listTableProps, D as rowContextMenuProps, E as copySubmenu, O as toRowMenuItem, S as listTableFixedProps, T as assembleRowMenu, _ as ListSkeleton, a as ListSearchControl, b as RowSelectCheckbox, c as ListFilterMenu, d as DEFAULT_ORDER, f as FAVORITE_ORDER, g as ListError, h as ListActionsHeader, i as ListCount, j as useRowMenuActive, k as toolbarActionToRowAction, l as listControlButtonClasses, m as GroupRow, n as useHoverCard, o as useListSearch, p as useListView, r as ListPager, s as ListDisplayMenu, t as HoverCardSurface, u as isTextEntryContext, v as NAME_MIN_WIDTH_PX, w as MoreButton, x as actionsColumnWidth, y as NameCell } from "../chunks/list-D5f5Fq-O.js";
|
|
2
|
+
export { DEFAULT_ORDER, FAVORITE_ORDER, GroupRow, HoverCardSurface, ListActionsHeader, ListCount, ListDisplayMenu, ListError, ListFilterMenu, ListPager, ListSearchControl, ListSkeleton, MoreButton, NAME_MIN_WIDTH_PX, NameCell, RowSelectCheckbox, actionsColumnWidth, assembleRowMenu, copySubmenu, isTextEntryContext, listControlButtonClasses, listTableFixedProps, listTableProps, rowContextMenuProps, toRowMenuItem, toolbarActionToRowAction, useHoverCard, useListSearch, useListView, useRowMenu, useRowMenuActive };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Pass `enabled: false` to suspend the global ⌘F/`/` hijack (e.g. when search isn't shown and browser Find should stay active). */
|
|
2
|
+
export declare function useListSearch(enabled?: boolean, storageKey?: string): {
|
|
3
|
+
filter: string;
|
|
4
|
+
setFilter: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
5
|
+
searchOpen: boolean;
|
|
6
|
+
openSearch: () => void;
|
|
7
|
+
closeSearch: () => void;
|
|
8
|
+
clearSearch: () => void;
|
|
9
|
+
terms: string[];
|
|
10
|
+
addTerm: (term: string) => void;
|
|
11
|
+
removeTerm: (term: string) => void;
|
|
12
|
+
queries: string[];
|
|
13
|
+
inputRef: import("react").RefObject<HTMLInputElement | null>;
|
|
14
|
+
};
|
|
15
|
+
export type ListSearch = ReturnType<typeof useListSearch>;
|
|
16
|
+
export declare function ListSearchControl({ search, placeholder, label, }: {
|
|
17
|
+
search: ListSearch;
|
|
18
|
+
placeholder: string;
|
|
19
|
+
label?: string;
|
|
20
|
+
}): import("react").JSX.Element;
|
|
21
|
+
export declare function ListCount({ total, matches, filterActive, noun, nounPlural, }: {
|
|
22
|
+
total: number;
|
|
23
|
+
matches: number;
|
|
24
|
+
filterActive: boolean;
|
|
25
|
+
noun: string;
|
|
26
|
+
nounPlural: string;
|
|
27
|
+
}): import("react").JSX.Element;
|