@robr0/design-system 0.7.0 → 0.9.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 +4 -4
- package/components/Accordion/Accordion.js +1 -0
- package/components/AgentPlan/AgentPlan.css +231 -0
- package/components/AgentPlan/AgentPlan.d.ts +41 -0
- package/components/AgentPlan/AgentPlan.js +100 -0
- package/components/AgentStatus/AgentStatus.js +1 -0
- package/components/AiButton/AiButton.js +1 -0
- package/components/AlertDialog/AlertDialog.js +1 -0
- package/components/AnchorNav/AnchorNav.css +63 -0
- package/components/AnchorNav/AnchorNav.d.ts +33 -0
- package/components/AnchorNav/AnchorNav.js +82 -0
- package/components/AppLayout/AppLayout.js +1 -0
- package/components/AppSidebar/AppSidebar.js +1 -0
- package/components/Avatar/Avatar.js +1 -0
- package/components/Button/Button.js +1 -0
- package/components/Card/Card.js +1 -0
- package/components/Carousel/Carousel.js +1 -0
- package/components/ChatThread/ChatThread.js +1 -0
- package/components/Checkbox/Checkbox.js +1 -0
- package/components/CodeBlock/CodeBlock.js +1 -0
- package/components/CodeDiff/CodeDiff.css +175 -0
- package/components/CodeDiff/CodeDiff.d.ts +58 -0
- package/components/CodeDiff/CodeDiff.js +114 -0
- package/components/ColorPicker/ColorPicker.js +1 -0
- package/components/Combobox/Combobox.js +1 -0
- package/components/CommandPalette/CommandPalette.js +1 -0
- package/components/Composer/Composer.js +1 -0
- package/components/ContactCard/ContactCard.js +1 -0
- package/components/ContextMenu/ContextMenu.js +1 -0
- package/components/DataTable/DataTable.css +105 -0
- package/components/DataTable/DataTable.d.ts +81 -0
- package/components/DataTable/DataTable.js +236 -0
- package/components/DateInput/DateInput.js +1 -0
- package/components/DatePicker/DatePicker.js +1 -0
- package/components/Dialog/Dialog.js +1 -0
- package/components/Drawer/Drawer.js +1 -0
- package/components/Dropdown/Dropdown.js +1 -0
- package/components/DropdownMenu/DropdownMenu.css +1 -1
- package/components/DropdownMenu/DropdownMenu.js +1 -0
- package/components/EventCalendar/EventCalendar.css +328 -0
- package/components/EventCalendar/EventCalendar.d.ts +51 -0
- package/components/EventCalendar/EventCalendar.js +214 -0
- package/components/Field/Field.js +1 -0
- package/components/Field/FieldContext.js +1 -0
- package/components/FileInput/FileInput.js +1 -0
- package/components/Input/Input.js +1 -0
- package/components/InterruptCard/InterruptCard.css +11 -21
- package/components/InterruptCard/InterruptCard.d.ts +5 -6
- package/components/MessageCard/MessageCard.css +1 -2
- package/components/ModelPicker/ModelPicker.css +240 -0
- package/components/ModelPicker/ModelPicker.d.ts +60 -0
- package/components/ModelPicker/ModelPicker.js +218 -0
- package/components/NavList/NavList.js +1 -0
- package/components/NotificationCenter/NotificationCenter.css +262 -0
- package/components/NotificationCenter/NotificationCenter.d.ts +72 -0
- package/components/NotificationCenter/NotificationCenter.js +129 -0
- package/components/NumberInput/NumberInput.css +154 -0
- package/components/NumberInput/NumberInput.d.ts +44 -0
- package/components/NumberInput/NumberInput.js +147 -0
- package/components/Pagination/Pagination.js +1 -0
- package/components/PinInput/PinInput.css +92 -0
- package/components/PinInput/PinInput.d.ts +46 -0
- package/components/PinInput/PinInput.js +161 -0
- package/components/Popover/Popover.css +5 -6
- package/components/Popover/Popover.js +1 -0
- package/components/RadioButton/RadioButton.js +1 -0
- package/components/Reasoning/Reasoning.js +1 -0
- package/components/SegmentedControl/SegmentedControl.js +1 -0
- package/components/SelectionCard/SelectionCard.js +1 -0
- package/components/ShaderField/ShaderField.js +1 -0
- package/components/ShaderField/field.glsl.d.ts +11 -5
- package/components/ShaderField/field.glsl.js +4 -3
- package/components/ShaderField/useShaderField.d.ts +19 -2
- package/components/ShaderField/useShaderField.js +18 -3
- package/components/Slider/Slider.js +1 -0
- package/components/Sparkline/Sparkline.css +52 -0
- package/components/Sparkline/Sparkline.d.ts +49 -0
- package/components/Sparkline/Sparkline.js +86 -0
- package/components/Stepper/Stepper.css +207 -0
- package/components/Stepper/Stepper.d.ts +41 -0
- package/components/Stepper/Stepper.js +61 -0
- package/components/Tabs/Tabs.js +1 -0
- package/components/TagInput/TagInput.css +160 -0
- package/components/TagInput/TagInput.d.ts +43 -0
- package/components/TagInput/TagInput.js +137 -0
- package/components/Textarea/Textarea.js +1 -0
- package/components/TimePicker/TimePicker.css +230 -0
- package/components/TimePicker/TimePicker.d.ts +46 -0
- package/components/TimePicker/TimePicker.js +246 -0
- package/components/Timeline/Timeline.css +17 -0
- package/components/Timeline/Timeline.d.ts +2 -0
- package/components/Timeline/Timeline.js +1 -0
- package/components/Toast/Toast.js +1 -0
- package/components/ToggleGroup/ToggleGroup.js +1 -0
- package/components/ToggleSwitch/ToggleSwitch.js +1 -0
- package/components/ToolCall/ToolCall.css +7 -11
- package/components/ToolCall/ToolCall.js +1 -0
- package/components/Tooltip/Tooltip.js +1 -0
- package/components/TreeView/TreeView.css +119 -0
- package/components/TreeView/TreeView.d.ts +45 -0
- package/components/TreeView/TreeView.js +232 -0
- package/components/registry.d.ts +22 -6
- package/components/registry.js +3 -1
- package/components/registry.json +246 -20
- package/components/registry.json.d.ts +246 -20
- package/components/registry.json.js +2 -2
- package/index.d.ts +16 -2
- package/index.js +32 -1
- package/package.json +1 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
CODE DIFF COMPONENT
|
|
3
|
+
Unified diff view: added, removed, and context
|
|
4
|
+
lines with old/new line number gutters.
|
|
5
|
+
Note: the system typeface is Nunito Sans;
|
|
6
|
+
code is the one sanctioned monospace context.
|
|
7
|
+
============================================ */
|
|
8
|
+
|
|
9
|
+
.ds-codediff {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
width: 100%;
|
|
13
|
+
border: var(--border-xs) solid var(--color-bg-container-border);
|
|
14
|
+
border-radius: var(--radius-md);
|
|
15
|
+
background-color: var(--color-bg-container-primary);
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* ============================================
|
|
20
|
+
HEADER — filename + additions/deletions stats
|
|
21
|
+
============================================ */
|
|
22
|
+
|
|
23
|
+
.ds-codediff__header {
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
justify-content: space-between;
|
|
27
|
+
gap: var(--gap-sm);
|
|
28
|
+
padding: var(--padding-xs) var(--padding-md);
|
|
29
|
+
border-bottom: var(--border-xs) solid var(--color-bg-container-border);
|
|
30
|
+
flex-shrink: 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.ds-codediff__filename {
|
|
34
|
+
font-family: var(--font-family-code);
|
|
35
|
+
font-size: var(--font-paragraph-sm-size);
|
|
36
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
37
|
+
color: var(--color-text-secondary);
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
text-overflow: ellipsis;
|
|
40
|
+
white-space: nowrap;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.ds-codediff__stats {
|
|
44
|
+
display: inline-flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
gap: var(--gap-xs);
|
|
47
|
+
flex-shrink: 0;
|
|
48
|
+
font-family: var(--font-paragraph-sm-em-family);
|
|
49
|
+
font-size: var(--font-paragraph-sm-em-size);
|
|
50
|
+
font-weight: var(--font-paragraph-sm-em-weight);
|
|
51
|
+
line-height: var(--font-paragraph-sm-em-line-height);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.ds-codediff__stat--add {
|
|
55
|
+
color: var(--color-status-positive-text);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.ds-codediff__stat--remove {
|
|
59
|
+
color: var(--color-status-error-text);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* ============================================
|
|
63
|
+
SCROLL CONTAINER
|
|
64
|
+
Long lines scroll horizontally inside the
|
|
65
|
+
component; the tab stop makes that scroll
|
|
66
|
+
keyboard-reachable.
|
|
67
|
+
============================================ */
|
|
68
|
+
|
|
69
|
+
.ds-codediff__scroll {
|
|
70
|
+
overflow-x: auto;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.ds-codediff__scroll:focus-visible {
|
|
74
|
+
outline: 2px solid var(--color-action-primary-bg);
|
|
75
|
+
outline-offset: -2px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* ============================================
|
|
79
|
+
LINES
|
|
80
|
+
============================================ */
|
|
81
|
+
|
|
82
|
+
/* width: max-content + min-width: 100% so row tints
|
|
83
|
+
span the full width of the longest line, not just
|
|
84
|
+
the visible scrollport */
|
|
85
|
+
.ds-codediff__lines {
|
|
86
|
+
list-style: none;
|
|
87
|
+
margin: 0;
|
|
88
|
+
padding: var(--padding-xs) 0;
|
|
89
|
+
width: max-content;
|
|
90
|
+
min-width: 100%;
|
|
91
|
+
font-family: var(--font-family-code);
|
|
92
|
+
font-size: var(--font-paragraph-sm-size);
|
|
93
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
94
|
+
color: var(--color-text-primary);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.ds-codediff__line {
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: baseline;
|
|
100
|
+
/* keeps blank diff lines from collapsing to zero height */
|
|
101
|
+
min-height: var(--font-paragraph-sm-line-height);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* ============================================
|
|
105
|
+
GUTTERS & MARKER
|
|
106
|
+
Fixed-width columns in the monospace metric so
|
|
107
|
+
rows align; excluded from text selection so a
|
|
108
|
+
copied diff carries only the code.
|
|
109
|
+
============================================ */
|
|
110
|
+
|
|
111
|
+
.ds-codediff__gutter {
|
|
112
|
+
flex-shrink: 0;
|
|
113
|
+
min-width: 4ch;
|
|
114
|
+
padding: 0 var(--padding-xxs);
|
|
115
|
+
text-align: right;
|
|
116
|
+
color: var(--color-text-tertiary);
|
|
117
|
+
user-select: none;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.ds-codediff__marker {
|
|
121
|
+
flex-shrink: 0;
|
|
122
|
+
width: 2ch;
|
|
123
|
+
text-align: center;
|
|
124
|
+
user-select: none;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.ds-codediff__content {
|
|
128
|
+
white-space: pre;
|
|
129
|
+
padding-right: var(--padding-md);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* ============================================
|
|
133
|
+
LINE VARIANTS
|
|
134
|
+
Added rows tint with the positive status
|
|
135
|
+
background, removed with the error one.
|
|
136
|
+
============================================ */
|
|
137
|
+
|
|
138
|
+
.ds-codediff__line--add {
|
|
139
|
+
background-color: var(--color-status-positive-bg);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.ds-codediff__line--add .ds-codediff__marker {
|
|
143
|
+
color: var(--color-status-positive-text);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.ds-codediff__line--remove {
|
|
147
|
+
background-color: var(--color-status-error-bg);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.ds-codediff__line--remove .ds-codediff__marker {
|
|
151
|
+
color: var(--color-status-error-text);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.ds-codediff__line--hunk {
|
|
155
|
+
background-color: var(--color-bg-container-secondary);
|
|
156
|
+
color: var(--color-text-tertiary);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* ============================================
|
|
160
|
+
SCREEN-READER-ONLY TEXT
|
|
161
|
+
Announces the change type; the marker column
|
|
162
|
+
itself is decorative (aria-hidden).
|
|
163
|
+
============================================ */
|
|
164
|
+
|
|
165
|
+
.ds-codediff__sr-only {
|
|
166
|
+
position: absolute;
|
|
167
|
+
width: 1px;
|
|
168
|
+
height: 1px;
|
|
169
|
+
padding: 0;
|
|
170
|
+
margin: -1px;
|
|
171
|
+
overflow: hidden;
|
|
172
|
+
clip: rect(0, 0, 0, 0);
|
|
173
|
+
white-space: nowrap;
|
|
174
|
+
border: 0;
|
|
175
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/** The kind of line a parsed diff row represents. */
|
|
3
|
+
export type CodeDiffLineType = 'add' | 'remove' | 'context' | 'hunk';
|
|
4
|
+
export interface CodeDiffLine {
|
|
5
|
+
/** Whether the line is an addition, a removal, unchanged context, or a hunk header */
|
|
6
|
+
type: CodeDiffLineType;
|
|
7
|
+
/** The line's text with its diff marker stripped (hunk headers keep the full `@@` line) */
|
|
8
|
+
content: string;
|
|
9
|
+
/** Line number in the old file, or null for additions and hunk headers */
|
|
10
|
+
oldLine: number | null;
|
|
11
|
+
/** Line number in the new file, or null for removals and hunk headers */
|
|
12
|
+
newLine: number | null;
|
|
13
|
+
}
|
|
14
|
+
export interface ParsedCodeDiff {
|
|
15
|
+
/** The diff's rows in order, with per-side line numbers computed */
|
|
16
|
+
lines: CodeDiffLine[];
|
|
17
|
+
/** Count of added lines */
|
|
18
|
+
additions: number;
|
|
19
|
+
/** Count of removed lines */
|
|
20
|
+
deletions: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Parse a unified-format diff body into typed lines with old/new line
|
|
24
|
+
* numbers. Lines starting with `+` are additions, `-` removals, `@@ … @@`
|
|
25
|
+
* hunk headers, and everything else context. File header lines (`+++`,
|
|
26
|
+
* `---`) and no-newline markers (``) carry no
|
|
27
|
+
* content and are skipped. A diff with no hunk headers is treated as one
|
|
28
|
+
* hunk starting at line 1.
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseUnifiedDiff(diff: string): ParsedCodeDiff;
|
|
31
|
+
/** Props owned by CodeDiff itself — everything else falls through to the root div. */
|
|
32
|
+
type CodeDiffOwnProps = {
|
|
33
|
+
/**
|
|
34
|
+
* A unified-format diff body. Lines starting with `+` render as additions,
|
|
35
|
+
* `-` as removals, `@@ … @@` as hunk headers, everything else as context;
|
|
36
|
+
* `+++`/`---` file header lines are ignored. Without hunk headers the
|
|
37
|
+
* whole string is treated as one hunk starting at line 1.
|
|
38
|
+
*/
|
|
39
|
+
diff: string;
|
|
40
|
+
/** Filename shown in a header bar above the diff, with an additions/deletions summary */
|
|
41
|
+
filename?: string;
|
|
42
|
+
/** Show the old and new line number gutters */
|
|
43
|
+
showLineNumbers?: boolean;
|
|
44
|
+
/** Additional CSS classes */
|
|
45
|
+
className?: string;
|
|
46
|
+
};
|
|
47
|
+
export interface CodeDiffProps extends CodeDiffOwnProps, Omit<React.ComponentPropsWithoutRef<'div'>, keyof CodeDiffOwnProps> {
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* CodeDiff component — unified diff view for code changes. Added lines tint
|
|
51
|
+
* with the positive status background, removed lines with the error one, and
|
|
52
|
+
* two gutters track old and new line numbers. Purely presentational: parsing
|
|
53
|
+
* happens in the exported `parseUnifiedDiff`, long lines scroll horizontally
|
|
54
|
+
* inside the block, and the change type is announced through visually hidden
|
|
55
|
+
* text while the marker column stays decorative.
|
|
56
|
+
*/
|
|
57
|
+
export declare const CodeDiff: React.ForwardRefExoticComponent<CodeDiffProps & React.RefAttributes<HTMLDivElement>>;
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import "./CodeDiff.css";
|
|
4
|
+
const HUNK_HEADER = /^@@\s+-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/;
|
|
5
|
+
function parseUnifiedDiff(diff) {
|
|
6
|
+
const rawLines = diff.replace(/\n$/, "").split("\n");
|
|
7
|
+
const lines = [];
|
|
8
|
+
let additions = 0;
|
|
9
|
+
let deletions = 0;
|
|
10
|
+
let oldLine = 1;
|
|
11
|
+
let newLine = 1;
|
|
12
|
+
for (const raw of rawLines) {
|
|
13
|
+
if (raw.startsWith("+++") || raw.startsWith("---") || raw.startsWith("\\")) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
const hunk = raw.match(HUNK_HEADER);
|
|
17
|
+
if (hunk) {
|
|
18
|
+
oldLine = parseInt(hunk[1], 10);
|
|
19
|
+
newLine = parseInt(hunk[2], 10);
|
|
20
|
+
lines.push({ type: "hunk", content: raw, oldLine: null, newLine: null });
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (raw.startsWith("+")) {
|
|
24
|
+
additions += 1;
|
|
25
|
+
lines.push({ type: "add", content: raw.slice(1), oldLine: null, newLine });
|
|
26
|
+
newLine += 1;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (raw.startsWith("-")) {
|
|
30
|
+
deletions += 1;
|
|
31
|
+
lines.push({ type: "remove", content: raw.slice(1), oldLine, newLine: null });
|
|
32
|
+
oldLine += 1;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
lines.push({
|
|
36
|
+
type: "context",
|
|
37
|
+
content: raw.startsWith(" ") ? raw.slice(1) : raw,
|
|
38
|
+
oldLine,
|
|
39
|
+
newLine
|
|
40
|
+
});
|
|
41
|
+
oldLine += 1;
|
|
42
|
+
newLine += 1;
|
|
43
|
+
}
|
|
44
|
+
return { lines, additions, deletions };
|
|
45
|
+
}
|
|
46
|
+
const CHANGE_LABELS = {
|
|
47
|
+
add: "Added line:",
|
|
48
|
+
remove: "Removed line:"
|
|
49
|
+
};
|
|
50
|
+
const CodeDiff = React.forwardRef(
|
|
51
|
+
({ diff, filename, showLineNumbers = true, className = "", ...rest }, ref) => {
|
|
52
|
+
const baseClass = "ds-codediff";
|
|
53
|
+
const { lines, additions, deletions } = parseUnifiedDiff(diff);
|
|
54
|
+
const classes = [baseClass, className].filter(Boolean).join(" ");
|
|
55
|
+
return /* @__PURE__ */ jsxs("div", { ...rest, ref, className: classes, children: [
|
|
56
|
+
filename && /* @__PURE__ */ jsxs("div", { className: `${baseClass}__header`, children: [
|
|
57
|
+
/* @__PURE__ */ jsx("code", { className: `${baseClass}__filename`, children: filename }),
|
|
58
|
+
/* @__PURE__ */ jsxs("span", { className: `${baseClass}__stats`, children: [
|
|
59
|
+
/* @__PURE__ */ jsxs("span", { className: `${baseClass}__stat ${baseClass}__stat--add`, children: [
|
|
60
|
+
"+",
|
|
61
|
+
additions,
|
|
62
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__sr-only`, children: " added" })
|
|
63
|
+
] }),
|
|
64
|
+
/* @__PURE__ */ jsxs("span", { className: `${baseClass}__stat ${baseClass}__stat--remove`, children: [
|
|
65
|
+
"-",
|
|
66
|
+
deletions,
|
|
67
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__sr-only`, children: " removed" })
|
|
68
|
+
] })
|
|
69
|
+
] })
|
|
70
|
+
] }),
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
"div",
|
|
73
|
+
{
|
|
74
|
+
className: `${baseClass}__scroll`,
|
|
75
|
+
tabIndex: 0,
|
|
76
|
+
role: "region",
|
|
77
|
+
"aria-label": filename ? `Code diff: ${filename}` : "Code diff",
|
|
78
|
+
children: /* @__PURE__ */ jsx("ol", { className: `${baseClass}__lines`, children: lines.map((line, index) => {
|
|
79
|
+
const changeLabel = CHANGE_LABELS[line.type];
|
|
80
|
+
return /* @__PURE__ */ jsxs(
|
|
81
|
+
"li",
|
|
82
|
+
{
|
|
83
|
+
className: [
|
|
84
|
+
`${baseClass}__line`,
|
|
85
|
+
line.type === "add" ? `${baseClass}__line--add` : "",
|
|
86
|
+
line.type === "remove" ? `${baseClass}__line--remove` : "",
|
|
87
|
+
line.type === "hunk" ? `${baseClass}__line--hunk` : ""
|
|
88
|
+
].filter(Boolean).join(" "),
|
|
89
|
+
children: [
|
|
90
|
+
showLineNumbers && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
91
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__gutter`, "aria-hidden": "true", children: line.oldLine ?? "" }),
|
|
92
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__gutter`, "aria-hidden": "true", children: line.newLine ?? "" })
|
|
93
|
+
] }),
|
|
94
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__marker`, "aria-hidden": "true", children: line.type === "add" ? "+" : line.type === "remove" ? "-" : "" }),
|
|
95
|
+
changeLabel && /* @__PURE__ */ jsxs("span", { className: `${baseClass}__sr-only`, children: [
|
|
96
|
+
changeLabel,
|
|
97
|
+
" "
|
|
98
|
+
] }),
|
|
99
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__content`, children: line.content })
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
index
|
|
103
|
+
);
|
|
104
|
+
}) })
|
|
105
|
+
}
|
|
106
|
+
)
|
|
107
|
+
] });
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
CodeDiff.displayName = "CodeDiff";
|
|
111
|
+
export {
|
|
112
|
+
CodeDiff,
|
|
113
|
+
parseUnifiedDiff
|
|
114
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
DATA TABLE COMPONENT
|
|
3
|
+
The wired table block: toolbar with search
|
|
4
|
+
and filter slot, sortable headers, selection,
|
|
5
|
+
pagination footer. Row and cell styling all
|
|
6
|
+
comes from the underlying Table — this file
|
|
7
|
+
only styles the chrome around it.
|
|
8
|
+
============================================ */
|
|
9
|
+
|
|
10
|
+
.ds-data-table {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
gap: var(--gap-sm);
|
|
14
|
+
width: 100%;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* ============================================
|
|
18
|
+
TOOLBAR
|
|
19
|
+
============================================ */
|
|
20
|
+
|
|
21
|
+
.ds-data-table__toolbar {
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
justify-content: space-between;
|
|
25
|
+
gap: var(--gap-sm);
|
|
26
|
+
flex-wrap: wrap;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.ds-data-table__filters {
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
gap: var(--gap-sm);
|
|
33
|
+
flex-wrap: wrap;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* The search field sits at the end of the toolbar even with no filters */
|
|
37
|
+
.ds-data-table__search {
|
|
38
|
+
margin-left: auto;
|
|
39
|
+
max-width: 240px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ============================================
|
|
43
|
+
SORTABLE HEADERS
|
|
44
|
+
The button fills the header cell so the whole
|
|
45
|
+
label is the click target.
|
|
46
|
+
============================================ */
|
|
47
|
+
|
|
48
|
+
.ds-data-table__sort {
|
|
49
|
+
display: inline-flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
gap: var(--gap-xxs);
|
|
52
|
+
padding: 0;
|
|
53
|
+
background: none;
|
|
54
|
+
border: none;
|
|
55
|
+
cursor: pointer;
|
|
56
|
+
color: inherit;
|
|
57
|
+
font: inherit;
|
|
58
|
+
letter-spacing: inherit;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.ds-data-table__sort:focus-visible {
|
|
62
|
+
outline: 2px solid var(--color-action-primary-bg);
|
|
63
|
+
outline-offset: 2px;
|
|
64
|
+
border-radius: var(--radius-xxs);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.ds-data-table__sort-icon {
|
|
68
|
+
--icon-size: var(--icon-size-sm);
|
|
69
|
+
|
|
70
|
+
color: var(--color-icon-secondary);
|
|
71
|
+
opacity: 0;
|
|
72
|
+
transition: opacity var(--motion-duration-fast) var(--motion-ease-standard);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.ds-data-table__sort:hover .ds-data-table__sort-icon,
|
|
76
|
+
.ds-data-table__sort:focus-visible .ds-data-table__sort-icon,
|
|
77
|
+
.ds-data-table__sort-icon--active {
|
|
78
|
+
opacity: 1;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.ds-data-table__sort-icon--active {
|
|
82
|
+
color: var(--color-text-primary);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* ============================================
|
|
86
|
+
FOOTER
|
|
87
|
+
============================================ */
|
|
88
|
+
|
|
89
|
+
.ds-data-table__footer {
|
|
90
|
+
display: flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
justify-content: space-between;
|
|
93
|
+
gap: var(--gap-sm);
|
|
94
|
+
flex-wrap: wrap;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.ds-data-table__count {
|
|
98
|
+
color: var(--color-text-tertiary);
|
|
99
|
+
font-family: var(--font-paragraph-sm-family);
|
|
100
|
+
font-size: var(--font-paragraph-sm-size);
|
|
101
|
+
font-weight: var(--font-paragraph-sm-weight);
|
|
102
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
103
|
+
letter-spacing: var(--font-paragraph-sm-letter-spacing);
|
|
104
|
+
font-variant-numeric: tabular-nums;
|
|
105
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface DataTableColumn {
|
|
3
|
+
/** Unique column identifier, used as the key into each row's values. */
|
|
4
|
+
key: string;
|
|
5
|
+
/** Header label displayed in the column header. */
|
|
6
|
+
header: React.ReactNode;
|
|
7
|
+
/** Whether clicking this header sorts by the column. */
|
|
8
|
+
sortable?: boolean;
|
|
9
|
+
/** Optional column width (CSS value like '200px', '30%', 'auto'). */
|
|
10
|
+
width?: string;
|
|
11
|
+
/** Text alignment for cells in this column. */
|
|
12
|
+
align?: 'left' | 'center' | 'right';
|
|
13
|
+
/** Render the cell for a row; defaults to the row's raw value for this key. */
|
|
14
|
+
render?: (row: DataTableRow) => React.ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export interface DataTableRow {
|
|
17
|
+
/** Unique row identifier. */
|
|
18
|
+
id: string;
|
|
19
|
+
/** Raw values keyed by column key — used for sorting, searching, and default rendering. */
|
|
20
|
+
values: Record<string, string | number | null | undefined>;
|
|
21
|
+
}
|
|
22
|
+
export interface DataTableSort {
|
|
23
|
+
/** The column being sorted. */
|
|
24
|
+
key: string;
|
|
25
|
+
/** Sort direction. */
|
|
26
|
+
direction: 'asc' | 'desc';
|
|
27
|
+
}
|
|
28
|
+
/** Props owned by DataTable itself — everything else falls through to the root element. */
|
|
29
|
+
type DataTableOwnProps = {
|
|
30
|
+
/** Column definitions. */
|
|
31
|
+
columns: DataTableColumn[];
|
|
32
|
+
/** Row data, as raw values the table can sort and search. */
|
|
33
|
+
rows: DataTableRow[];
|
|
34
|
+
/** Rows per page. Setting this turns on the built-in pagination. */
|
|
35
|
+
pageSize?: number;
|
|
36
|
+
/** Adds a checkbox column with a select-all header. */
|
|
37
|
+
selectable?: boolean;
|
|
38
|
+
/** Selected row ids for controlled use. Pair with `onSelectionChange`. */
|
|
39
|
+
selectedIds?: string[];
|
|
40
|
+
/** Initially selected row ids for uncontrolled use. */
|
|
41
|
+
defaultSelectedIds?: string[];
|
|
42
|
+
/** Fires with the full list of selected row ids after every change. */
|
|
43
|
+
onSelectionChange?: (ids: string[]) => void;
|
|
44
|
+
/** Sort state for controlled use. Pair with `onSortChange`; `null` means unsorted. */
|
|
45
|
+
sort?: DataTableSort | null;
|
|
46
|
+
/** Initial sort state for uncontrolled use. */
|
|
47
|
+
defaultSort?: DataTableSort;
|
|
48
|
+
/** Fires with the new sort state — `null` when a third click clears the sort. */
|
|
49
|
+
onSortChange?: (sort: DataTableSort | null) => void;
|
|
50
|
+
/** Shows the built-in search field, matching against every column's raw value. */
|
|
51
|
+
searchable?: boolean;
|
|
52
|
+
/** Placeholder for the search field. */
|
|
53
|
+
searchPlaceholder?: string;
|
|
54
|
+
/** Slot beside the search field for consumer-owned filter controls. */
|
|
55
|
+
toolbar?: React.ReactNode;
|
|
56
|
+
/** Visual size, passed through to the underlying Table. */
|
|
57
|
+
size?: 'default' | 'compact';
|
|
58
|
+
/** Alternating row backgrounds, passed through to the underlying Table. */
|
|
59
|
+
striped?: boolean;
|
|
60
|
+
/** Accessible caption for the underlying table (visually hidden). */
|
|
61
|
+
caption?: string;
|
|
62
|
+
/** What to render when no rows match — defaults to a built-in empty state. */
|
|
63
|
+
emptyState?: React.ReactNode;
|
|
64
|
+
/** Additional CSS classes */
|
|
65
|
+
className?: string;
|
|
66
|
+
};
|
|
67
|
+
export interface DataTableProps extends DataTableOwnProps, Omit<React.ComponentPropsWithoutRef<'div'>, keyof DataTableOwnProps> {
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* DataTable is the wired version of Table: sorting on header click, a search
|
|
71
|
+
* field, row selection with a select-all header, client-side pagination, and
|
|
72
|
+
* an empty state — assembled from Table, Pagination, Checkbox, Input and
|
|
73
|
+
* EmptyState so a working data view is one component, not an afternoon of
|
|
74
|
+
* plumbing.
|
|
75
|
+
*
|
|
76
|
+
* Rows carry raw values rather than rendered nodes; a column's `render`
|
|
77
|
+
* turns them into cells when text isn't enough. For server-driven data,
|
|
78
|
+
* control `sort` and slot your own filters into `toolbar`.
|
|
79
|
+
*/
|
|
80
|
+
export declare const DataTable: React.ForwardRefExoticComponent<DataTableProps & React.RefAttributes<HTMLDivElement>>;
|
|
81
|
+
export {};
|