@gtivr4/a1-design-system-react 0.18.0 → 0.19.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/package.json
CHANGED
|
@@ -13,6 +13,10 @@ export interface CodeProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
13
13
|
editable?: boolean;
|
|
14
14
|
/** Called with the current string value whenever the editable textarea changes. */
|
|
15
15
|
onChangeValue?: (value: string) => void;
|
|
16
|
+
/** Cap a long read-only block to `collapsedLines` with a fade + Show more/less toggle (the toggle appears only when the content overflows). Block, non-editable only. Default: false */
|
|
17
|
+
collapsible?: boolean;
|
|
18
|
+
/** Approximate number of lines shown when collapsed. Default: 14 */
|
|
19
|
+
collapsedLines?: number;
|
|
16
20
|
children?: React.ReactNode;
|
|
17
21
|
}
|
|
18
22
|
|
|
@@ -56,12 +56,17 @@ export function Code({
|
|
|
56
56
|
copyText,
|
|
57
57
|
editable = false,
|
|
58
58
|
onChangeValue,
|
|
59
|
+
collapsible = false,
|
|
60
|
+
collapsedLines = 14,
|
|
59
61
|
className = "",
|
|
60
62
|
children,
|
|
61
63
|
...props
|
|
62
64
|
}) {
|
|
63
65
|
const resolvedVariant = variants.includes(variant) ? variant : "inline";
|
|
64
66
|
const [copied, setCopied] = useState(false);
|
|
67
|
+
const [expanded, setExpanded] = useState(false);
|
|
68
|
+
const [overflows, setOverflows] = useState(false);
|
|
69
|
+
const preRef = useRef(null);
|
|
65
70
|
const [editableValue, setEditableValue] = useState(() =>
|
|
66
71
|
textFromChildren(Children.toArray(children))
|
|
67
72
|
);
|
|
@@ -78,11 +83,15 @@ export function Code({
|
|
|
78
83
|
const copyLabel = useLabel("code.copyCode", "Copy code");
|
|
79
84
|
const copiedLabel = useLabel("code.copied", "Copied");
|
|
80
85
|
const editLabel = useLabel("code.editCode", "Edit code");
|
|
86
|
+
const showMoreLabel = useLabel("code.showMore", "Show more");
|
|
87
|
+
const showLessLabel = useLabel("code.showLess", "Show less");
|
|
81
88
|
const textToCopy = useMemo(
|
|
82
89
|
() => copyText || (editable ? editableValue : textFromChildren(Children.toArray(children))),
|
|
83
90
|
[children, copyText, editable, editableValue],
|
|
84
91
|
);
|
|
85
92
|
const shouldRenderBlock = resolvedVariant === "block" || copyCode || editable;
|
|
93
|
+
// Collapsible only applies to a read-only block (not the editable textarea).
|
|
94
|
+
const collapses = collapsible && !editable && shouldRenderBlock;
|
|
86
95
|
|
|
87
96
|
useEffect(() => {
|
|
88
97
|
return () => {
|
|
@@ -90,6 +99,16 @@ export function Code({
|
|
|
90
99
|
};
|
|
91
100
|
}, []);
|
|
92
101
|
|
|
102
|
+
// Detect whether the (collapsed) content actually overflows the cap, so the
|
|
103
|
+
// toggle only appears when it's needed. scrollHeight reports the full content
|
|
104
|
+
// height even while clipped, so this is accurate in either state.
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (!collapses) { setOverflows(false); return; }
|
|
107
|
+
if (expanded) return; // measured while collapsed; keep so "Show less" stays
|
|
108
|
+
const el = preRef.current;
|
|
109
|
+
if (el) setOverflows(el.scrollHeight - el.clientHeight > 4);
|
|
110
|
+
}, [collapses, expanded, children, collapsedLines]);
|
|
111
|
+
|
|
93
112
|
function handleTextareaChange(e) {
|
|
94
113
|
setEditableValue(e.target.value);
|
|
95
114
|
onChangeValue?.(e.target.value);
|
|
@@ -127,12 +146,15 @@ export function Code({
|
|
|
127
146
|
);
|
|
128
147
|
}
|
|
129
148
|
|
|
149
|
+
const collapsed = collapses && overflows && !expanded;
|
|
150
|
+
|
|
130
151
|
return (
|
|
131
152
|
<div
|
|
132
153
|
className={[
|
|
133
154
|
"a1-code-block",
|
|
134
155
|
copyCode && "a1-code-block--copyable",
|
|
135
156
|
editable && "a1-code-block--editable",
|
|
157
|
+
collapsed && "a1-code-block--collapsed",
|
|
136
158
|
className,
|
|
137
159
|
]
|
|
138
160
|
.filter(Boolean)
|
|
@@ -153,7 +175,11 @@ export function Code({
|
|
|
153
175
|
{...editableProps}
|
|
154
176
|
/>
|
|
155
177
|
) : (
|
|
156
|
-
<pre
|
|
178
|
+
<pre
|
|
179
|
+
ref={preRef}
|
|
180
|
+
className="a1-code-block__pre"
|
|
181
|
+
style={collapses ? { "--a1-code-collapsed-max": `${collapsedLines * 1.6}em` } : undefined}
|
|
182
|
+
>
|
|
157
183
|
<code className={codeClasses} {...props}>
|
|
158
184
|
{children}
|
|
159
185
|
</code>
|
|
@@ -171,6 +197,18 @@ export function Code({
|
|
|
171
197
|
{copied ? copiedLabel : copyLabel}
|
|
172
198
|
</Button>
|
|
173
199
|
)}
|
|
200
|
+
{collapses && overflows && (
|
|
201
|
+
<Button
|
|
202
|
+
className="a1-code-block__toggle"
|
|
203
|
+
icon={expanded ? "expand_less" : "expand_more"}
|
|
204
|
+
size="sm"
|
|
205
|
+
variant="tertiary"
|
|
206
|
+
onClick={() => setExpanded((v) => !v)}
|
|
207
|
+
type="button"
|
|
208
|
+
>
|
|
209
|
+
{expanded ? showLessLabel : showMoreLabel}
|
|
210
|
+
</Button>
|
|
211
|
+
)}
|
|
174
212
|
</div>
|
|
175
213
|
);
|
|
176
214
|
}
|
|
@@ -87,3 +87,26 @@
|
|
|
87
87
|
.a1-code-block__copy {
|
|
88
88
|
margin: 0;
|
|
89
89
|
}
|
|
90
|
+
|
|
91
|
+
/* Collapsible block: cap the height with a fade and an Expand/Collapse toggle. */
|
|
92
|
+
.a1-code-block--collapsed .a1-code-block__pre {
|
|
93
|
+
position: relative;
|
|
94
|
+
max-block-size: var(--a1-code-collapsed-max, 22rem);
|
|
95
|
+
overflow-y: hidden;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.a1-code-block--collapsed .a1-code-block__pre::after {
|
|
99
|
+
content: "";
|
|
100
|
+
position: absolute;
|
|
101
|
+
inset-inline: 0;
|
|
102
|
+
inset-block-end: 0;
|
|
103
|
+
block-size: var(--base-spacing-48, 3rem);
|
|
104
|
+
background: linear-gradient(to top, var(--semantic-color-surface-panel), transparent);
|
|
105
|
+
pointer-events: none;
|
|
106
|
+
border-end-start-radius: var(--base-radius-md);
|
|
107
|
+
border-end-end-radius: var(--base-radius-md);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.a1-code-block__toggle {
|
|
111
|
+
margin: 0;
|
|
112
|
+
}
|
|
@@ -20,6 +20,8 @@ export interface GridProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
20
20
|
layout?: "default" | "bento";
|
|
21
21
|
/** CSS value for `grid-auto-rows` */
|
|
22
22
|
autoRows?: string;
|
|
23
|
+
/** Cross-axis (vertical) alignment of items within their row. Omit to inherit the grid default ("stretch" = equal-height items filling the row height). */
|
|
24
|
+
alignItems?: "start" | "center" | "end" | "stretch";
|
|
23
25
|
children?: React.ReactNode;
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -11,6 +11,7 @@ const gapSizes = {
|
|
|
11
11
|
};
|
|
12
12
|
const layouts = ["default", "bento"];
|
|
13
13
|
const breakpoints = ["xs", "sm", "md", "lg", "xl"];
|
|
14
|
+
const alignments = ["start", "center", "end", "stretch"];
|
|
14
15
|
|
|
15
16
|
function resolveGap(key) {
|
|
16
17
|
if (key == null) return undefined;
|
|
@@ -29,6 +30,7 @@ export function Grid({
|
|
|
29
30
|
columnGap,
|
|
30
31
|
layout = "default",
|
|
31
32
|
autoRows,
|
|
33
|
+
alignItems,
|
|
32
34
|
className = "",
|
|
33
35
|
children,
|
|
34
36
|
...props
|
|
@@ -40,6 +42,12 @@ export function Grid({
|
|
|
40
42
|
classes.push(`a1-grid--${resolvedLayout}`);
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
// Cross-axis (vertical) alignment of items in their row. Omit to inherit the
|
|
46
|
+
// grid default (stretch = equal-height items filling the row).
|
|
47
|
+
if (alignments.includes(alignItems)) {
|
|
48
|
+
classes.push(`a1-grid--align-${alignItems}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
43
51
|
let inlineCols;
|
|
44
52
|
if (typeof columns === "number") {
|
|
45
53
|
inlineCols = columns;
|
|
@@ -9,6 +9,12 @@
|
|
|
9
9
|
align-items: stretch;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
/* Cross-axis (vertical) alignment of items within their row. */
|
|
13
|
+
.a1-grid--align-start { align-items: start; }
|
|
14
|
+
.a1-grid--align-center { align-items: center; }
|
|
15
|
+
.a1-grid--align-end { align-items: end; }
|
|
16
|
+
.a1-grid--align-stretch { align-items: stretch; }
|
|
17
|
+
|
|
12
18
|
.a1-grid--bento > .a1-grid-item {
|
|
13
19
|
min-height: 0;
|
|
14
20
|
}
|