@xemahq/ui-kernel 0.11.1 → 0.12.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/dist/errors/http-error-status.d.ts +17 -0
- package/dist/errors/http-error-status.d.ts.map +1 -0
- package/dist/errors/http-error-status.js +59 -0
- package/dist/errors/http-error-status.js.map +1 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +2 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/biome-host/errors.d.ts.map +1 -1
- package/dist/lib/biome-host/errors.js +1 -19
- package/dist/lib/biome-host/errors.js.map +1 -1
- package/dist/offline/index.d.ts.map +1 -1
- package/dist/offline/index.js.map +1 -1
- package/dist/offline/online-controller.d.ts.map +1 -1
- package/dist/offline/online-controller.js +6 -1
- package/dist/offline/online-controller.js.map +1 -1
- package/dist/offline/outbox.d.ts.map +1 -1
- package/dist/offline/outbox.js +2 -24
- package/dist/offline/outbox.js.map +1 -1
- package/package.json +1 -2
- package/src/index.ts +0 -17
- package/src/lib/biome-host/agent-validation.ts +0 -239
- package/src/lib/biome-host/biome-builders.ts +0 -112
- package/src/lib/biome-host/biome-mode.ts +0 -6
- package/src/lib/biome-host/biome-navigation.ts +0 -37
- package/src/lib/biome-host/biome-registry.ts +0 -299
- package/src/lib/biome-host/biome-scope-hooks.ts +0 -41
- package/src/lib/biome-host/biome-scope.tsx +0 -52
- package/src/lib/biome-host/biome-scoped-query.ts +0 -134
- package/src/lib/biome-host/create-biome-orval-config.ts +0 -82
- package/src/lib/biome-host/define-web-biome.spec.ts +0 -221
- package/src/lib/biome-host/define-web-biome.ts +0 -222
- package/src/lib/biome-host/errors.ts +0 -220
- package/src/lib/biome-host/frontend-biome.ts +0 -256
- package/src/lib/biome-host/host-bridge.ts +0 -281
- package/src/lib/biome-host/host-sources.ts +0 -54
- package/src/lib/biome-host/i18n-hooks.ts +0 -51
- package/src/lib/biome-host/i18n-port.test.ts +0 -50
- package/src/lib/biome-host/i18n-port.ts +0 -96
- package/src/lib/biome-host/index.ts +0 -35
- package/src/lib/biome-host/realtime-hooks.ts +0 -75
- package/src/lib/biome-host/realtime-port.ts +0 -115
- package/src/lib/biome-host/session-contributions.ts +0 -296
- package/src/lib/biome-host/use-mutation-with-error-toast.ts +0 -90
- package/src/lib/biome-host/use-page-state.ts +0 -248
- package/src/lib/capabilities/capability-context.ts +0 -25
- package/src/lib/capabilities/capability-provider.tsx +0 -73
- package/src/lib/capabilities/index.ts +0 -17
- package/src/lib/capabilities/types.ts +0 -69
- package/src/lib/capabilities/use-capability.ts +0 -79
- package/src/lib/contribution-registry/contribution-registry.spec.ts +0 -141
- package/src/lib/contribution-registry/contribution-registry.ts +0 -204
- package/src/lib/contribution-registry/index.ts +0 -9
- package/src/lib/contribution-registry/renderable-registry.ts +0 -142
- package/src/lib/system-bus/capability-invoke.ts +0 -92
- package/src/lib/system-bus/deeplink.ts +0 -210
- package/src/lib/system-bus/enums.ts +0 -86
- package/src/lib/system-bus/host-ports.ts +0 -93
- package/src/lib/system-bus/index.ts +0 -16
- package/src/lib/system-bus/intent-registry.ts +0 -109
- package/src/lib/system-bus/intents.ts +0 -113
- package/src/lib/system-bus/palette.ts +0 -78
- package/src/lib/system-bus/system-bus-builder.ts +0 -159
- package/src/lib/system-bus/system-bus.ts +0 -37
- package/src/lib/system-bus/windows.ts +0 -51
- package/src/offline/id.ts +0 -16
- package/src/offline/index.ts +0 -54
- package/src/offline/mutation.ts +0 -75
- package/src/offline/offline-status-badge.tsx +0 -51
- package/src/offline/online-controller.ts +0 -105
- package/src/offline/outbox.test.ts +0 -172
- package/src/offline/outbox.ts +0 -348
- package/src/offline/react-hooks.ts +0 -40
- package/src/offline/react.tsx +0 -32
- package/src/offline/storage.ts +0 -112
- package/src/offline/types.ts +0 -77
- package/src/org-db/components/DbResultTable.tsx +0 -176
- package/src/org-db/index.ts +0 -1
- package/src/pdf/index.ts +0 -11
- package/src/registry/index.ts +0 -9
- package/src/registry/lib/agent-validation-host.ts +0 -36
- package/src/registry/lib/biome-slot.tsx +0 -50
- package/src/registry/lib/biomes-enabled-context.ts +0 -20
- package/src/registry/lib/extension-points.ts +0 -134
- package/src/registry/lib/primitives/SessionEventCard.tsx +0 -164
- package/src/registry/lib/primitives/SessionEventTimeline.tsx +0 -95
- package/src/registry/lib/primitives/SessionMutationBar.tsx +0 -76
- package/src/registry/lib/primitives/SessionTabbedDrawer.tsx +0 -165
- package/src/registry/lib/primitives/index.ts +0 -18
- package/src/registry/lib/session-context-builder.ts +0 -84
- package/src/registry/lib/session-context-provider.tsx +0 -33
- package/src/registry/lib/session-context.ts +0 -21
- package/src/registry/lib/session-selectors.ts +0 -272
- package/src/session/comments/CommentRail.tsx +0 -164
- package/src/session/index.ts +0 -3
- package/src/session/lib/cn.ts +0 -11
- package/src/session/shell/SessionWorkspaceShell.tsx +0 -147
- package/src/session-kit/approvals/ApprovalButton.tsx +0 -89
- package/src/session-kit/approvals/ApprovalCard.tsx +0 -341
- package/src/session-kit/approvals/ApprovalsCenter.tsx +0 -336
- package/src/session-kit/approvals/CapabilityApprovalStickyBar.tsx +0 -118
- package/src/session-kit/approvals/Obligation.tsx +0 -111
- package/src/session-kit/approvals/ScopedBody.tsx +0 -392
- package/src/session-kit/approvals/approval-icons.ts +0 -31
- package/src/session-kit/approvals/approval-model.ts +0 -204
- package/src/session-kit/approvals/index.ts +0 -22
- package/src/session-kit/approvals/obligation-display.ts +0 -100
- package/src/session-kit/approvals/risk-accent.ts +0 -47
- package/src/session-kit/approvals/scope-icons.ts +0 -19
- package/src/session-kit/combobox/Combobox.tsx +0 -358
- package/src/session-kit/combobox/use-click-outside.ts +0 -21
- package/src/session-kit/display/ContextHeader.tsx +0 -148
- package/src/session-kit/display/FileDiffCard.tsx +0 -140
- package/src/session-kit/display/MD.tsx +0 -162
- package/src/session-kit/display/MessageTurn.tsx +0 -157
- package/src/session-kit/display/ThinkingPanel.tsx +0 -81
- package/src/session-kit/display/TodoChecklist.tsx +0 -120
- package/src/session-kit/display/TokenMeter.tsx +0 -89
- package/src/session-kit/display/ToolStrip.tsx +0 -278
- package/src/session-kit/display/TypingDots.tsx +0 -24
- package/src/session-kit/index.ts +0 -44
- package/src/session-kit/lib/enums.ts +0 -66
- package/src/session-kit/lib/portal-accent.ts +0 -30
- package/src/session-kit/lib/status-dot.ts +0 -68
- package/src/session-kit/primitives/Avatar.tsx +0 -44
- package/src/session-kit/primitives/PortalGlyph.tsx +0 -51
- package/src/session-kit/primitives/RiskPill.tsx +0 -95
- package/src/session-kit/primitives/ScopeDot.tsx +0 -47
- package/src/session-kit/primitives/Segmented.tsx +0 -71
- package/src/ui/branding/app-branding-context.ts +0 -20
- package/src/ui/branding/app-branding-provider.tsx +0 -123
- package/src/ui/branding/sanitize.ts +0 -89
- package/src/ui/breakpoints.ts +0 -14
- package/src/ui/capture/document-preview.tsx +0 -166
- package/src/ui/capture/field-spec-to-zod.test.ts +0 -81
- package/src/ui/capture/field-spec-to-zod.ts +0 -174
- package/src/ui/capture/field-spec-validate.ts +0 -236
- package/src/ui/capture/field-spec.test.ts +0 -49
- package/src/ui/capture/field-spec.ts +0 -274
- package/src/ui/capture/index.ts +0 -51
- package/src/ui/capture/schema-field-input.tsx +0 -620
- package/src/ui/capture/schema-form.tsx +0 -149
- package/src/ui/capture/submit-values.test.ts +0 -70
- package/src/ui/capture/submit-values.ts +0 -63
- package/src/ui/capture/use-prefill.ts +0 -186
- package/src/ui/capture/use-schema-validation.ts +0 -145
- package/src/ui/capture/use-wizard.ts +0 -180
- package/src/ui/capture/value-format.ts +0 -32
- package/src/ui/capture/wizard.tsx +0 -105
- package/src/ui/charts/bar-chart.tsx +0 -139
- package/src/ui/charts/chart-frame.tsx +0 -125
- package/src/ui/charts/chart-types.ts +0 -52
- package/src/ui/charts/chart-utils.ts +0 -190
- package/src/ui/charts/charts.test.tsx +0 -204
- package/src/ui/charts/donut-chart.tsx +0 -129
- package/src/ui/charts/index.ts +0 -27
- package/src/ui/charts/line-chart.tsx +0 -202
- package/src/ui/charts/sparkline.tsx +0 -109
- package/src/ui/chrome/AsyncBoundary.tsx +0 -74
- package/src/ui/chrome/EmptyState.tsx +0 -257
- package/src/ui/chrome/ErrorCard.tsx +0 -63
- package/src/ui/chrome/LoadingState.tsx +0 -61
- package/src/ui/chrome/PageHeader.tsx +0 -137
- package/src/ui/chrome/RecordCardList.tsx +0 -98
- package/src/ui/chrome/StateCard.tsx +0 -150
- package/src/ui/chrome/confirm-delete-dialog.tsx +0 -59
- package/src/ui/chrome/page-shell.spec.tsx +0 -117
- package/src/ui/chrome/page-shell.tsx +0 -221
- package/src/ui/chrome/scope-badge.tsx +0 -40
- package/src/ui/chrome/status-badge.tsx +0 -79
- package/src/ui/cn.ts +0 -32
- package/src/ui/design-tokens.ts +0 -372
- package/src/ui/hooks/use-debounced-value.ts +0 -16
- package/src/ui/hooks/use-is-mobile.ts +0 -28
- package/src/ui/index.ts +0 -110
- package/src/ui/pdf/pdf-preview.tsx +0 -122
- package/src/ui/primitives/alert-dialog.tsx +0 -104
- package/src/ui/primitives/async-combobox.tsx +0 -182
- package/src/ui/primitives/badge-variants.ts +0 -21
- package/src/ui/primitives/badge.tsx +0 -25
- package/src/ui/primitives/button-variants.ts +0 -31
- package/src/ui/primitives/button.tsx +0 -29
- package/src/ui/primitives/card.tsx +0 -43
- package/src/ui/primitives/checkbox.tsx +0 -26
- package/src/ui/primitives/collapsible.tsx +0 -9
- package/src/ui/primitives/dialog.tsx +0 -103
- package/src/ui/primitives/dropdown-menu.tsx +0 -179
- package/src/ui/primitives/form-stepper.tsx +0 -94
- package/src/ui/primitives/form-stepper.types.ts +0 -15
- package/src/ui/primitives/input.tsx +0 -22
- package/src/ui/primitives/label.tsx +0 -17
- package/src/ui/primitives/overflow-tabs.tsx +0 -331
- package/src/ui/primitives/popover.tsx +0 -33
- package/src/ui/primitives/preview-device-frame.tsx +0 -213
- package/src/ui/primitives/radio-group.tsx +0 -36
- package/src/ui/primitives/resizable.tsx +0 -67
- package/src/ui/primitives/scroll-area.tsx +0 -38
- package/src/ui/primitives/select.tsx +0 -143
- package/src/ui/primitives/separator.tsx +0 -20
- package/src/ui/primitives/sheet.tsx +0 -107
- package/src/ui/primitives/skeleton.tsx +0 -99
- package/src/ui/primitives/switch.tsx +0 -27
- package/src/ui/primitives/table.tsx +0 -72
- package/src/ui/primitives/tabs.tsx +0 -53
- package/src/ui/primitives/tag-multi-select.tsx +0 -261
- package/src/ui/primitives/textarea.tsx +0 -21
- package/src/ui/primitives/tooltip.tsx +0 -30
- package/src/ui/primitives/url-preview-chrome.tsx +0 -103
- package/src/vista/GenericCatalogueSurface.tsx +0 -179
- package/src/vista/SurfaceFallbackCard.tsx +0 -109
- package/src/vista/VistaPanel.tsx +0 -163
- package/src/vista/form-payload.spec.ts +0 -139
- package/src/vista/html/CustomUiFrame.spec.tsx +0 -127
- package/src/vista/html/CustomUiFrame.tsx +0 -206
- package/src/vista/html/custom-ui-frame-bridge.spec.ts +0 -191
- package/src/vista/html/custom-ui-frame-bridge.ts +0 -98
- package/src/vista/html/custom-ui-frame-contract.ts +0 -88
- package/src/vista/html/custom-ui-intents.spec.ts +0 -135
- package/src/vista/html/custom-ui-intents.ts +0 -155
- package/src/vista/html/custom-ui-srcdoc.spec.ts +0 -151
- package/src/vista/html/custom-ui-srcdoc.ts +0 -193
- package/src/vista/html/index.ts +0 -13
- package/src/vista/index.ts +0 -52
- package/src/vista/surface-catalogue.spec.ts +0 -140
- package/src/vista/surface-catalogue.ts +0 -90
- package/src/vista/surface-icons.ts +0 -57
- package/src/vista/surface-registry.ts +0 -56
- package/src/vista/surfaces/ChartSurface.tsx +0 -34
- package/src/vista/surfaces/FilesSurface.tsx +0 -202
- package/src/vista/surfaces/FormSurface.tsx +0 -380
- package/src/vista/surfaces/HtmlSurface.tsx +0 -43
- package/src/vista/surfaces/TableSurface.tsx +0 -100
- package/src/vista/surfaces/UrlSurface.tsx +0 -40
- package/src/vista/surfaces/blob-surfaces.tsx +0 -139
- package/src/vista/surfaces/elicitation-transport.spec.ts +0 -369
- package/src/vista/surfaces/elicitation-transport.ts +0 -367
- package/src/vista/surfaces/file-surface-utils.ts +0 -69
- package/src/vista/surfaces/index.ts +0 -24
- package/src/vista/surfaces/register-surfaces.tsx +0 -139
- package/src/vista/surfaces/text-surfaces.tsx +0 -132
- package/src/vista/use-vista-tabs.ts +0 -196
- package/src/vista/vista-code-renderer-context.ts +0 -16
- package/src/vista/vista-code-renderer.tsx +0 -35
- package/src/vista/vista-file-context.ts +0 -14
- package/src/vista/vista-file-source.tsx +0 -141
- package/src/vista/vista-form-context.ts +0 -20
- package/src/vista/vista-form-host.tsx +0 -48
- package/src/vista/vista-model.ts +0 -137
- package/src/vista/vista-open-context.tsx +0 -27
- package/src/vista/vista-open-state.ts +0 -11
- package/src/vista/vista-payloads.ts +0 -635
- package/src/vista/vista-tabs-manifest.ts +0 -138
- package/src/vista/vista-tools.ts +0 -232
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { cn } from '../cn';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Skeleton types for visual variety
|
|
5
|
-
*/
|
|
6
|
-
export type SkeletonVariant = "pulse" | "shimmer";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Skeleton color presets matching the theme
|
|
10
|
-
*/
|
|
11
|
-
export type SkeletonColor = "muted" | "paper" | "paper-elev" | "paper-sunk" | "ink" | "ink-2" | "ink-3";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Skeleton border radius options
|
|
15
|
-
*/
|
|
16
|
-
export type SkeletonRounded = "sm" | "md" | "lg" | "full" | "none";
|
|
17
|
-
|
|
18
|
-
export interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
19
|
-
/** Visual animation variant */
|
|
20
|
-
variant?: SkeletonVariant;
|
|
21
|
-
/** Background color */
|
|
22
|
-
color?: SkeletonColor;
|
|
23
|
-
/** Border radius */
|
|
24
|
-
rounded?: SkeletonRounded;
|
|
25
|
-
/** Height in pixels */
|
|
26
|
-
height?: number;
|
|
27
|
-
/** Width (CSS value or percentage) */
|
|
28
|
-
width?: string | number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Skeleton primitive for loading states.
|
|
33
|
-
*
|
|
34
|
-
* Usage:
|
|
35
|
-
* ```tsx
|
|
36
|
-
* // Basic usage (default: shimmer animation, muted color)
|
|
37
|
-
* <Skeleton />
|
|
38
|
-
*
|
|
39
|
-
* // Customized
|
|
40
|
-
* <Skeleton variant="pulse" color="paper-elev" rounded="lg" height={24} width="80%" />
|
|
41
|
-
*
|
|
42
|
-
* // Inline in a loading branch
|
|
43
|
-
* {isLoading && <Skeleton height={16} className="mb-2" />}
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
function Skeleton({
|
|
47
|
-
className,
|
|
48
|
-
variant = "shimmer",
|
|
49
|
-
color = "muted",
|
|
50
|
-
rounded = "md",
|
|
51
|
-
height,
|
|
52
|
-
width,
|
|
53
|
-
...props
|
|
54
|
-
}: SkeletonProps) {
|
|
55
|
-
// Color mapping to tailwind classes
|
|
56
|
-
const colorMap: Record<SkeletonColor, string> = {
|
|
57
|
-
muted: "bg-muted",
|
|
58
|
-
paper: "bg-paper",
|
|
59
|
-
"paper-elev": "bg-paper-elev",
|
|
60
|
-
"paper-sunk": "bg-paper-sunk",
|
|
61
|
-
ink: "bg-ink",
|
|
62
|
-
"ink-2": "bg-ink-2",
|
|
63
|
-
"ink-3": "bg-ink-3",
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// Rounded mapping to tailwind classes
|
|
67
|
-
const roundedMap: Record<SkeletonRounded, string> = {
|
|
68
|
-
sm: "rounded-sm",
|
|
69
|
-
md: "rounded-md",
|
|
70
|
-
lg: "rounded-lg",
|
|
71
|
-
full: "rounded-full",
|
|
72
|
-
none: "rounded-none",
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
// Base classes for all skeleton variants
|
|
76
|
-
const baseClasses = cn(colorMap[color], roundedMap[rounded]);
|
|
77
|
-
|
|
78
|
-
// Animation classes
|
|
79
|
-
const animationClasses =
|
|
80
|
-
variant === "pulse"
|
|
81
|
-
? "animate-pulse"
|
|
82
|
-
: "shimmer"; // CSS class handled via global styles
|
|
83
|
-
|
|
84
|
-
return (
|
|
85
|
-
<div
|
|
86
|
-
className={cn(
|
|
87
|
-
baseClasses,
|
|
88
|
-
animationClasses,
|
|
89
|
-
height && `h-[${height}px]`,
|
|
90
|
-
width && `w-[${width}]`,
|
|
91
|
-
className,
|
|
92
|
-
)}
|
|
93
|
-
style={{ animationDuration: variant === "shimmer" ? "2s" : undefined, ...props.style }}
|
|
94
|
-
{...props}
|
|
95
|
-
/>
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export { Skeleton };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import * as SwitchPrimitives from "@radix-ui/react-switch";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
|
|
4
|
-
import { cn } from '../cn';
|
|
5
|
-
|
|
6
|
-
const Switch = React.forwardRef<
|
|
7
|
-
React.ElementRef<typeof SwitchPrimitives.Root>,
|
|
8
|
-
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
|
|
9
|
-
>(({ className, ...props }, ref) => (
|
|
10
|
-
<SwitchPrimitives.Root
|
|
11
|
-
className={cn(
|
|
12
|
-
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",
|
|
13
|
-
className,
|
|
14
|
-
)}
|
|
15
|
-
{...props}
|
|
16
|
-
ref={ref}
|
|
17
|
-
>
|
|
18
|
-
<SwitchPrimitives.Thumb
|
|
19
|
-
className={cn(
|
|
20
|
-
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0",
|
|
21
|
-
)}
|
|
22
|
-
/>
|
|
23
|
-
</SwitchPrimitives.Root>
|
|
24
|
-
));
|
|
25
|
-
Switch.displayName = SwitchPrimitives.Root.displayName;
|
|
26
|
-
|
|
27
|
-
export { Switch };
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from '../cn';
|
|
4
|
-
|
|
5
|
-
const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(
|
|
6
|
-
({ className, ...props }, ref) => (
|
|
7
|
-
<div className="relative w-full overflow-auto">
|
|
8
|
-
<table ref={ref} className={cn("w-full caption-bottom text-body-1", className)} {...props} />
|
|
9
|
-
</div>
|
|
10
|
-
),
|
|
11
|
-
);
|
|
12
|
-
Table.displayName = "Table";
|
|
13
|
-
|
|
14
|
-
const TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
|
|
15
|
-
({ className, ...props }, ref) => <thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />,
|
|
16
|
-
);
|
|
17
|
-
TableHeader.displayName = "TableHeader";
|
|
18
|
-
|
|
19
|
-
const TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
|
|
20
|
-
({ className, ...props }, ref) => (
|
|
21
|
-
<tbody ref={ref} className={cn("[&_tr:last-child]:border-0", className)} {...props} />
|
|
22
|
-
),
|
|
23
|
-
);
|
|
24
|
-
TableBody.displayName = "TableBody";
|
|
25
|
-
|
|
26
|
-
const TableFooter = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
|
|
27
|
-
({ className, ...props }, ref) => (
|
|
28
|
-
<tfoot ref={ref} className={cn("border-t bg-paper-elev/60 font-medium [&>tr]:last:border-b-0", className)} {...props} />
|
|
29
|
-
),
|
|
30
|
-
);
|
|
31
|
-
TableFooter.displayName = "TableFooter";
|
|
32
|
-
|
|
33
|
-
const TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(
|
|
34
|
-
({ className, ...props }, ref) => (
|
|
35
|
-
<tr
|
|
36
|
-
ref={ref}
|
|
37
|
-
className={cn("border-b transition-colors data-[state=selected]:bg-muted hover:bg-paper-elev", className)}
|
|
38
|
-
{...props}
|
|
39
|
-
/>
|
|
40
|
-
),
|
|
41
|
-
);
|
|
42
|
-
TableRow.displayName = "TableRow";
|
|
43
|
-
|
|
44
|
-
const TableHead = React.forwardRef<HTMLTableCellElement, React.ThHTMLAttributes<HTMLTableCellElement>>(
|
|
45
|
-
({ className, ...props }, ref) => (
|
|
46
|
-
<th
|
|
47
|
-
ref={ref}
|
|
48
|
-
className={cn(
|
|
49
|
-
"h-12 px-4 text-left align-middle font-medium text-ink-3 [&:has([role=checkbox])]:pr-0",
|
|
50
|
-
className,
|
|
51
|
-
)}
|
|
52
|
-
{...props}
|
|
53
|
-
/>
|
|
54
|
-
),
|
|
55
|
-
);
|
|
56
|
-
TableHead.displayName = "TableHead";
|
|
57
|
-
|
|
58
|
-
const TableCell = React.forwardRef<HTMLTableCellElement, React.TdHTMLAttributes<HTMLTableCellElement>>(
|
|
59
|
-
({ className, ...props }, ref) => (
|
|
60
|
-
<td ref={ref} className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)} {...props} />
|
|
61
|
-
),
|
|
62
|
-
);
|
|
63
|
-
TableCell.displayName = "TableCell";
|
|
64
|
-
|
|
65
|
-
const TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(
|
|
66
|
-
({ className, ...props }, ref) => (
|
|
67
|
-
<caption ref={ref} className={cn("mt-4 text-body-1 text-ink-3", className)} {...props} />
|
|
68
|
-
),
|
|
69
|
-
);
|
|
70
|
-
TableCaption.displayName = "TableCaption";
|
|
71
|
-
|
|
72
|
-
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
|
|
4
|
-
import { cn } from '../cn';
|
|
5
|
-
|
|
6
|
-
const Tabs = TabsPrimitive.Root;
|
|
7
|
-
|
|
8
|
-
const TabsList = React.forwardRef<
|
|
9
|
-
React.ElementRef<typeof TabsPrimitive.List>,
|
|
10
|
-
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
|
|
11
|
-
>(({ className, ...props }, ref) => (
|
|
12
|
-
<TabsPrimitive.List
|
|
13
|
-
ref={ref}
|
|
14
|
-
className={cn(
|
|
15
|
-
"inline-flex h-10 items-center justify-center rounded-md bg-paper-elev/60 p-1 text-ink-3",
|
|
16
|
-
className,
|
|
17
|
-
)}
|
|
18
|
-
{...props}
|
|
19
|
-
/>
|
|
20
|
-
));
|
|
21
|
-
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
22
|
-
|
|
23
|
-
const TabsTrigger = React.forwardRef<
|
|
24
|
-
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
|
25
|
-
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
|
26
|
-
>(({ className, ...props }, ref) => (
|
|
27
|
-
<TabsPrimitive.Trigger
|
|
28
|
-
ref={ref}
|
|
29
|
-
className={cn(
|
|
30
|
-
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-body-1 font-medium text-ink-2 ring-offset-background transition-[background-color,color,border-color,box-shadow] hover:text-ink data-[state=active]:bg-paper-elev data-[state=active]:text-ink data-[state=active]:shadow-[var(--shadow-2)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
31
|
-
className,
|
|
32
|
-
)}
|
|
33
|
-
{...props}
|
|
34
|
-
/>
|
|
35
|
-
));
|
|
36
|
-
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
37
|
-
|
|
38
|
-
const TabsContent = React.forwardRef<
|
|
39
|
-
React.ElementRef<typeof TabsPrimitive.Content>,
|
|
40
|
-
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
|
|
41
|
-
>(({ className, ...props }, ref) => (
|
|
42
|
-
<TabsPrimitive.Content
|
|
43
|
-
ref={ref}
|
|
44
|
-
className={cn(
|
|
45
|
-
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
46
|
-
className,
|
|
47
|
-
)}
|
|
48
|
-
{...props}
|
|
49
|
-
/>
|
|
50
|
-
));
|
|
51
|
-
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
52
|
-
|
|
53
|
-
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
import { Check, ChevronsUpDown, Plus, Search, X } from 'lucide-react';
|
|
2
|
-
import { useMemo, useRef, useState, type KeyboardEvent } from 'react';
|
|
3
|
-
|
|
4
|
-
import { Badge } from './badge';
|
|
5
|
-
import { Button } from './button';
|
|
6
|
-
import { Input } from './input';
|
|
7
|
-
import { Popover, PopoverContent, PopoverTrigger } from './popover';
|
|
8
|
-
import { ScrollArea } from './scroll-area';
|
|
9
|
-
import { cn } from '../cn';
|
|
10
|
-
|
|
11
|
-
export interface TagOption {
|
|
12
|
-
value: string;
|
|
13
|
-
label: string;
|
|
14
|
-
hint?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface TagMultiSelectProps {
|
|
18
|
-
value: string[];
|
|
19
|
-
onChange: (next: string[]) => void;
|
|
20
|
-
options: TagOption[];
|
|
21
|
-
placeholder?: string;
|
|
22
|
-
searchPlaceholder?: string;
|
|
23
|
-
emptyMessage?: string;
|
|
24
|
-
/** Allow the user to add values that aren't in the predefined options. */
|
|
25
|
-
allowCustom?: boolean;
|
|
26
|
-
/** Badge tone for selected chips. */
|
|
27
|
-
chipVariant?: 'default' | 'secondary' | 'success' | 'destructive';
|
|
28
|
-
/** Extra className for the trigger. */
|
|
29
|
-
triggerClassName?: string;
|
|
30
|
-
disabled?: boolean;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const CHIP_CLASSES: Record<
|
|
34
|
-
NonNullable<TagMultiSelectProps['chipVariant']>,
|
|
35
|
-
string
|
|
36
|
-
> = {
|
|
37
|
-
default: 'bg-primary/10 text-primary border-primary/20',
|
|
38
|
-
secondary: 'bg-secondary text-secondary-foreground border-secondary',
|
|
39
|
-
success: 'bg-success/10 text-success border-success/20',
|
|
40
|
-
destructive: 'bg-destructive/10 text-destructive border-destructive/20',
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export function TagMultiSelect({
|
|
44
|
-
value,
|
|
45
|
-
onChange,
|
|
46
|
-
options,
|
|
47
|
-
placeholder = 'Select…',
|
|
48
|
-
searchPlaceholder = 'Search…',
|
|
49
|
-
emptyMessage = 'No matches',
|
|
50
|
-
allowCustom = false,
|
|
51
|
-
chipVariant = 'default',
|
|
52
|
-
triggerClassName,
|
|
53
|
-
disabled,
|
|
54
|
-
}: Readonly<TagMultiSelectProps>) {
|
|
55
|
-
const [open, setOpen] = useState(false);
|
|
56
|
-
const [search, setSearch] = useState('');
|
|
57
|
-
const inputRef = useRef<HTMLInputElement>(null);
|
|
58
|
-
|
|
59
|
-
const selectedSet = useMemo(() => new Set(value), [value]);
|
|
60
|
-
|
|
61
|
-
const optionByValue = useMemo(() => {
|
|
62
|
-
const map = new Map<string, TagOption>();
|
|
63
|
-
options.forEach((o) => map.set(o.value, o));
|
|
64
|
-
return map;
|
|
65
|
-
}, [options]);
|
|
66
|
-
|
|
67
|
-
const filteredOptions = useMemo(() => {
|
|
68
|
-
const q = search.trim().toLowerCase();
|
|
69
|
-
if (!q) {
|
|
70
|
-
return options;
|
|
71
|
-
}
|
|
72
|
-
return options.filter(
|
|
73
|
-
(o) =>
|
|
74
|
-
o.label.toLowerCase().includes(q) ||
|
|
75
|
-
o.value.toLowerCase().includes(q) ||
|
|
76
|
-
(o.hint?.toLowerCase().includes(q) ?? false),
|
|
77
|
-
);
|
|
78
|
-
}, [options, search]);
|
|
79
|
-
|
|
80
|
-
const normalizedSearch = search.trim();
|
|
81
|
-
const canAddCustom =
|
|
82
|
-
allowCustom &&
|
|
83
|
-
normalizedSearch.length > 0 &&
|
|
84
|
-
!optionByValue.has(normalizedSearch) &&
|
|
85
|
-
!selectedSet.has(normalizedSearch);
|
|
86
|
-
|
|
87
|
-
const toggle = (val: string) => {
|
|
88
|
-
if (selectedSet.has(val)) {
|
|
89
|
-
onChange(value.filter((v) => v !== val));
|
|
90
|
-
} else {
|
|
91
|
-
onChange([...value, val]);
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const remove = (val: string, e?: React.MouseEvent) => {
|
|
96
|
-
e?.stopPropagation();
|
|
97
|
-
onChange(value.filter((v) => v !== val));
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const addCustom = () => {
|
|
101
|
-
if (!canAddCustom) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
onChange([...value, normalizedSearch]);
|
|
105
|
-
setSearch('');
|
|
106
|
-
inputRef.current?.focus();
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const onKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
|
|
110
|
-
if (e.key === 'Enter') {
|
|
111
|
-
e.preventDefault();
|
|
112
|
-
if (canAddCustom) {
|
|
113
|
-
addCustom();
|
|
114
|
-
} else {
|
|
115
|
-
// Enter with exactly one remaining match selects it.
|
|
116
|
-
const onlyMatch =
|
|
117
|
-
filteredOptions.length === 1 ? filteredOptions[0] : undefined;
|
|
118
|
-
if (onlyMatch !== undefined) {
|
|
119
|
-
toggle(onlyMatch.value);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
const chipClass = CHIP_CLASSES[chipVariant];
|
|
126
|
-
|
|
127
|
-
return (
|
|
128
|
-
<Popover open={open} onOpenChange={setOpen}>
|
|
129
|
-
<PopoverTrigger asChild>
|
|
130
|
-
<Button
|
|
131
|
-
variant="outline"
|
|
132
|
-
role="combobox"
|
|
133
|
-
aria-expanded={open}
|
|
134
|
-
disabled={disabled}
|
|
135
|
-
className={cn(
|
|
136
|
-
'w-full min-h-9 h-auto justify-between font-normal py-1.5',
|
|
137
|
-
triggerClassName,
|
|
138
|
-
)}
|
|
139
|
-
>
|
|
140
|
-
<div className="flex flex-wrap gap-1 flex-1 text-left">
|
|
141
|
-
{value.length === 0 && (
|
|
142
|
-
<span className="text-ink-3 text-body-1">{placeholder}</span>
|
|
143
|
-
)}
|
|
144
|
-
{value.map((val) => {
|
|
145
|
-
const opt = optionByValue.get(val);
|
|
146
|
-
return (
|
|
147
|
-
<Badge
|
|
148
|
-
key={val}
|
|
149
|
-
variant="outline"
|
|
150
|
-
className={cn('text-body-1 gap-1 pr-1', chipClass)}
|
|
151
|
-
>
|
|
152
|
-
<span className="truncate max-w-[160px]">
|
|
153
|
-
{opt?.label ?? val}
|
|
154
|
-
</span>
|
|
155
|
-
<button
|
|
156
|
-
type="button"
|
|
157
|
-
onClick={(e) => remove(val, e)}
|
|
158
|
-
onKeyDown={(e) => {
|
|
159
|
-
if (e.key === 'Enter' || e.key === ' ') {
|
|
160
|
-
e.preventDefault();
|
|
161
|
-
e.stopPropagation();
|
|
162
|
-
remove(val);
|
|
163
|
-
}
|
|
164
|
-
}}
|
|
165
|
-
className="rounded-sm hover:bg-paper-elev p-0.5"
|
|
166
|
-
aria-label={`Remove ${opt?.label ?? val}`}
|
|
167
|
-
>
|
|
168
|
-
<X className="h-4 w-4" />
|
|
169
|
-
</button>
|
|
170
|
-
</Badge>
|
|
171
|
-
);
|
|
172
|
-
})}
|
|
173
|
-
</div>
|
|
174
|
-
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
|
175
|
-
</Button>
|
|
176
|
-
</PopoverTrigger>
|
|
177
|
-
<PopoverContent
|
|
178
|
-
className="w-[--radix-popover-trigger-width] p-0"
|
|
179
|
-
align="start"
|
|
180
|
-
onOpenAutoFocus={(e) => {
|
|
181
|
-
e.preventDefault();
|
|
182
|
-
setTimeout(() => inputRef.current?.focus(), 30);
|
|
183
|
-
}}
|
|
184
|
-
>
|
|
185
|
-
<div className="relative border-b">
|
|
186
|
-
<Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-ink-3" />
|
|
187
|
-
<Input
|
|
188
|
-
ref={inputRef}
|
|
189
|
-
value={search}
|
|
190
|
-
onChange={(e) => setSearch(e.target.value)}
|
|
191
|
-
onKeyDown={onKeyDown}
|
|
192
|
-
placeholder={searchPlaceholder}
|
|
193
|
-
className="h-9 text-body-1 pl-8 border-0 rounded-none focus-visible:ring-0 focus-visible:ring-offset-0"
|
|
194
|
-
/>
|
|
195
|
-
</div>
|
|
196
|
-
|
|
197
|
-
<ScrollArea className="max-h-56">
|
|
198
|
-
<div className="p-1">
|
|
199
|
-
{filteredOptions.length === 0 && !canAddCustom && (
|
|
200
|
-
<p className="text-body-1 text-ink-3 text-center py-3">
|
|
201
|
-
{emptyMessage}
|
|
202
|
-
</p>
|
|
203
|
-
)}
|
|
204
|
-
|
|
205
|
-
{filteredOptions.map((opt) => {
|
|
206
|
-
const selected = selectedSet.has(opt.value);
|
|
207
|
-
return (
|
|
208
|
-
<button
|
|
209
|
-
key={opt.value}
|
|
210
|
-
type="button"
|
|
211
|
-
onClick={() => toggle(opt.value)}
|
|
212
|
-
className={cn(
|
|
213
|
-
'w-full text-left text-body-1 px-2 py-1.5 rounded hover:bg-paper-elev transition-colors flex items-start gap-2',
|
|
214
|
-
selected && 'bg-paper-elev/60',
|
|
215
|
-
)}
|
|
216
|
-
>
|
|
217
|
-
<span
|
|
218
|
-
className={cn(
|
|
219
|
-
'mt-0.5 h-4 w-4 shrink-0 rounded border flex items-center justify-center',
|
|
220
|
-
selected
|
|
221
|
-
? 'bg-primary border-primary text-primary-foreground'
|
|
222
|
-
: 'border-muted-foreground/40',
|
|
223
|
-
)}
|
|
224
|
-
>
|
|
225
|
-
{selected && <Check className="h-4 w-4" />}
|
|
226
|
-
</span>
|
|
227
|
-
<span className="flex-1 min-w-0">
|
|
228
|
-
<span className="font-medium block truncate">
|
|
229
|
-
{opt.label}
|
|
230
|
-
</span>
|
|
231
|
-
{opt.hint && (
|
|
232
|
-
<span className="text-body-1 text-ink-3 block truncate">
|
|
233
|
-
{opt.hint}
|
|
234
|
-
</span>
|
|
235
|
-
)}
|
|
236
|
-
</span>
|
|
237
|
-
</button>
|
|
238
|
-
);
|
|
239
|
-
})}
|
|
240
|
-
|
|
241
|
-
{canAddCustom && (
|
|
242
|
-
<button
|
|
243
|
-
type="button"
|
|
244
|
-
onClick={addCustom}
|
|
245
|
-
className="w-full text-left text-body-1 px-2 py-1.5 rounded hover:bg-paper-elev transition-colors flex items-center gap-2 border-t mt-1 pt-2"
|
|
246
|
-
>
|
|
247
|
-
<Plus className="h-4 w-4 text-ink-3" />
|
|
248
|
-
<span>
|
|
249
|
-
Add{' '}
|
|
250
|
-
<span className="font-mono font-medium">
|
|
251
|
-
{normalizedSearch}
|
|
252
|
-
</span>
|
|
253
|
-
</span>
|
|
254
|
-
</button>
|
|
255
|
-
)}
|
|
256
|
-
</div>
|
|
257
|
-
</ScrollArea>
|
|
258
|
-
</PopoverContent>
|
|
259
|
-
</Popover>
|
|
260
|
-
);
|
|
261
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from '../cn';
|
|
4
|
-
|
|
5
|
-
export type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;
|
|
6
|
-
|
|
7
|
-
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({ className, ...props }, ref) => {
|
|
8
|
-
return (
|
|
9
|
-
<textarea
|
|
10
|
-
className={cn(
|
|
11
|
-
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-body-1 ring-offset-background placeholder:text-ink-3 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
12
|
-
className,
|
|
13
|
-
)}
|
|
14
|
-
ref={ref}
|
|
15
|
-
{...props}
|
|
16
|
-
/>
|
|
17
|
-
);
|
|
18
|
-
});
|
|
19
|
-
Textarea.displayName = "Textarea";
|
|
20
|
-
|
|
21
|
-
export { Textarea };
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
|
|
4
|
-
import { cn } from '../cn';
|
|
5
|
-
|
|
6
|
-
const TooltipProvider = TooltipPrimitive.Provider;
|
|
7
|
-
|
|
8
|
-
const Tooltip = TooltipPrimitive.Root;
|
|
9
|
-
|
|
10
|
-
const TooltipTrigger = TooltipPrimitive.Trigger;
|
|
11
|
-
|
|
12
|
-
const TooltipContent = React.forwardRef<
|
|
13
|
-
React.ElementRef<typeof TooltipPrimitive.Content>,
|
|
14
|
-
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
|
|
15
|
-
>(({ className, sideOffset = 4, ...props }, ref) => (
|
|
16
|
-
<TooltipPrimitive.Portal>
|
|
17
|
-
<TooltipPrimitive.Content
|
|
18
|
-
ref={ref}
|
|
19
|
-
sideOffset={sideOffset}
|
|
20
|
-
className={cn(
|
|
21
|
-
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-body-1 text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
22
|
-
className,
|
|
23
|
-
)}
|
|
24
|
-
{...props}
|
|
25
|
-
/>
|
|
26
|
-
</TooltipPrimitive.Portal>
|
|
27
|
-
));
|
|
28
|
-
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
29
|
-
|
|
30
|
-
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mock browser chrome for a URL preview.
|
|
3
|
-
*
|
|
4
|
-
* Renders the traffic-light dots + an address bar + a refresh affordance, then
|
|
5
|
-
* the caller-supplied live content (the real iframe) below.
|
|
6
|
-
*
|
|
7
|
-
* Owned by the UI kernel so the Vista `url` surface, the thin session
|
|
8
|
-
* workspace, and any biome preview reuse ONE chrome — there is no second
|
|
9
|
-
* implementation.
|
|
10
|
-
*/
|
|
11
|
-
import { RotateCw } from 'lucide-react';
|
|
12
|
-
|
|
13
|
-
import type { ReactElement, ReactNode } from 'react';
|
|
14
|
-
|
|
15
|
-
const TRAFFIC_LIGHTS = ['#e5645a', '#e8b13d', '#5bb35b'] as const;
|
|
16
|
-
|
|
17
|
-
export interface UrlPreviewChromeProps {
|
|
18
|
-
/** Address shown in the mock address bar. */
|
|
19
|
-
readonly url: string;
|
|
20
|
-
/** Live preview content (the real iframe). */
|
|
21
|
-
readonly children: ReactNode;
|
|
22
|
-
/** Optional reload handler wired to the refresh glyph. */
|
|
23
|
-
readonly onReload?: () => void;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function UrlPreviewChrome({
|
|
27
|
-
url,
|
|
28
|
-
children,
|
|
29
|
-
onReload,
|
|
30
|
-
}: UrlPreviewChromeProps): ReactElement {
|
|
31
|
-
return (
|
|
32
|
-
<div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
|
|
33
|
-
<div
|
|
34
|
-
style={{
|
|
35
|
-
display: 'flex',
|
|
36
|
-
alignItems: 'center',
|
|
37
|
-
gap: 8,
|
|
38
|
-
padding: '8px 12px',
|
|
39
|
-
borderBottom: '1px solid hsl(var(--rule))',
|
|
40
|
-
background: 'hsl(var(--paper) / 0.5)',
|
|
41
|
-
flexShrink: 0,
|
|
42
|
-
}}
|
|
43
|
-
>
|
|
44
|
-
<span style={{ display: 'flex', gap: 5 }}>
|
|
45
|
-
{TRAFFIC_LIGHTS.map((color) => (
|
|
46
|
-
<span
|
|
47
|
-
key={color}
|
|
48
|
-
style={{
|
|
49
|
-
width: 9,
|
|
50
|
-
height: 9,
|
|
51
|
-
borderRadius: '50%',
|
|
52
|
-
background: color,
|
|
53
|
-
}}
|
|
54
|
-
/>
|
|
55
|
-
))}
|
|
56
|
-
</span>
|
|
57
|
-
<span
|
|
58
|
-
className="mono"
|
|
59
|
-
style={{
|
|
60
|
-
fontSize: 11,
|
|
61
|
-
color: 'hsl(var(--ink-4))',
|
|
62
|
-
marginLeft: 6,
|
|
63
|
-
padding: '3px 10px',
|
|
64
|
-
background: 'hsl(var(--paper-sunk))',
|
|
65
|
-
borderRadius: 6,
|
|
66
|
-
flex: 1,
|
|
67
|
-
overflow: 'hidden',
|
|
68
|
-
textOverflow: 'ellipsis',
|
|
69
|
-
whiteSpace: 'nowrap',
|
|
70
|
-
}}
|
|
71
|
-
>
|
|
72
|
-
{url}
|
|
73
|
-
</span>
|
|
74
|
-
{onReload ? (
|
|
75
|
-
<button
|
|
76
|
-
type="button"
|
|
77
|
-
onClick={onReload}
|
|
78
|
-
aria-label="Reload preview"
|
|
79
|
-
style={{
|
|
80
|
-
display: 'inline-flex',
|
|
81
|
-
color: 'hsl(var(--ink-4))',
|
|
82
|
-
padding: 2,
|
|
83
|
-
borderRadius: 5,
|
|
84
|
-
}}
|
|
85
|
-
>
|
|
86
|
-
<RotateCw size={13} />
|
|
87
|
-
</button>
|
|
88
|
-
) : (
|
|
89
|
-
<RotateCw size={13} style={{ color: 'hsl(var(--ink-4))' }} />
|
|
90
|
-
)}
|
|
91
|
-
</div>
|
|
92
|
-
<div
|
|
93
|
-
style={{
|
|
94
|
-
flex: 1,
|
|
95
|
-
minHeight: 0,
|
|
96
|
-
background: 'hsl(var(--paper-elev))',
|
|
97
|
-
}}
|
|
98
|
-
>
|
|
99
|
-
{children}
|
|
100
|
-
</div>
|
|
101
|
-
</div>
|
|
102
|
-
);
|
|
103
|
-
}
|