@juspay/blend-design-system 0.0.37-beta.4 → 0.0.37-beta.5
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/components/Breadcrumb/Breadcrumb.d.ts +2 -5
- package/dist/components/Breadcrumb/types.d.ts +6 -0
- package/dist/components/Charts/ChartUtils.d.ts +2 -0
- package/dist/components/Charts/types.d.ts +2 -2
- package/dist/components/DateRangePicker/types.d.ts +1 -1
- package/dist/components/DateRangePicker/utils.d.ts +2 -0
- package/dist/components/Directory/Directory.d.ts +1 -1
- package/dist/components/Directory/types.d.ts +1 -1
- package/dist/components/Directory/utils.d.ts +2 -0
- package/dist/components/Radio/StyledRadio.d.ts +0 -1
- package/dist/components/Sidebar/SidebarContent.d.ts +1 -1
- package/dist/components/Sidebar/types.d.ts +10 -1
- package/dist/components/Sidebar/utils.d.ts +1 -1
- package/dist/components/SidebarV2/SidebarV2Panel.d.ts +1 -1
- package/dist/components/SidebarV2/index.d.ts +1 -1
- package/dist/components/SidebarV2/types.d.ts +3 -0
- package/dist/components/Stepper/types.d.ts +2 -0
- package/dist/main.js +27657 -27314
- package/dist/tokens.js +17 -16
- package/lib/components/Avatar/Avatar.tsx +6 -1
- package/lib/components/AvatarGroup/AvatarGroup.tsx +1 -1
- package/lib/components/AvatarV2/AvatarV2.tsx +10 -1
- package/lib/components/Breadcrumb/Breadcrumb.tsx +9 -8
- package/lib/components/Breadcrumb/types.ts +12 -0
- package/lib/components/Button/ButtonBase.tsx +1 -1
- package/lib/components/Card/CardComponents.tsx +52 -17
- package/lib/components/Charts/ChartUtils.tsx +7 -0
- package/lib/components/Charts/Charts.tsx +4 -2
- package/lib/components/Charts/CoreChart.tsx +4 -2
- package/lib/components/Charts/types.tsx +2 -2
- package/lib/components/ChartsV2/ChartV2.tsx +1 -1
- package/lib/components/Checkbox/Checkbox.tsx +29 -7
- package/lib/components/CodeBlock/CodeBlock.tsx +47 -1
- package/lib/components/CodeBlock/codeBlock.token.ts +5 -5
- package/lib/components/CodeEditor/CodeEditor.tsx +26 -4
- package/lib/components/CodeEditor/MonacoEditorWrapper.tsx +13 -1
- package/lib/components/DataTable/DataTable.tsx +8 -0
- package/lib/components/DataTable/TableHeader/FilterComponents.tsx +4 -0
- package/lib/components/DateRangePicker/DateRangePicker.tsx +34 -17
- package/lib/components/DateRangePicker/types.ts +5 -5
- package/lib/components/DateRangePicker/utils.ts +5 -0
- package/lib/components/Directory/Directory.tsx +3 -2
- package/lib/components/Directory/types.ts +1 -1
- package/lib/components/Directory/utils.ts +6 -0
- package/lib/components/Drawer/components/DrawerBase.tsx +16 -0
- package/lib/components/Drawer/components/NestedSelectDrawer.tsx +13 -1
- package/lib/components/Drawer/components/SelectDrawer.tsx +9 -1
- package/lib/components/Inputs/OTPInput/OTPInput.tsx +5 -3
- package/lib/components/Menu/Menu.tsx +9 -1
- package/lib/components/Modal/useModal.ts +7 -0
- package/lib/components/Radio/Radio.tsx +12 -5
- package/lib/components/Radio/StyledRadio.tsx +33 -17
- package/lib/components/Sidebar/Sidebar.tsx +11 -1
- package/lib/components/Sidebar/SidebarContent.tsx +5 -2
- package/lib/components/Sidebar/TenantPanel.tsx +52 -34
- package/lib/components/Sidebar/types.ts +11 -1
- package/lib/components/Sidebar/utils.ts +1 -1
- package/lib/components/SidebarV2/SecondarySidebar.tsx +86 -44
- package/lib/components/SidebarV2/SidebarV2Panel.tsx +4 -2
- package/lib/components/SidebarV2/index.ts +1 -0
- package/lib/components/SidebarV2/types.ts +4 -0
- package/lib/components/StatCard/statcard.tokens.ts +1 -1
- package/lib/components/Stepper/VerticalStepper.tsx +209 -171
- package/lib/components/Stepper/types.ts +2 -0
- package/lib/components/StepperV2/Stepper/Steps.tsx +15 -1
- package/lib/components/Text/Text.tsx +1 -0
- package/lib/components/Upload/Upload.tsx +6 -0
- package/lib/components/Upload/components/FileListDisplay.tsx +159 -16
- package/lib/components/Upload/utils.ts +10 -2
- package/lib/context/ThemeProvider.tsx +19 -8
- package/lib/hooks/useDebounce.ts +9 -1
- package/package.json +1 -1
package/dist/tokens.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as u, T as d, g as k, a as E, b as V, c as g, d as v, e as
|
|
2
|
-
import { BRANCH_COLLECTION as ie, BRANCH_ID_PATTERN as ae, PRESETS as ce, PRESET_BLEND_DEFAULT as fe, PRESET_GREEN as le, PRESET_JUSPAY as Te, PRESET_ORANGE as ue, PRESET_PURPLE as de, RADIUS_PRESETS as Oe, SNAPSHOT_SUBCOLLECTION as ke, STORAGE_KEYS as Ee, TEAM_ROLE_PERMISSIONS as Ve, VERSION_PATTERN as ge, VERSION_SUBCOLLECTION as ve, analyzeContrast as
|
|
1
|
+
import { F as u, T as d, g as k, a as E, b as V, c as g, d as v, e as p, f as S, h, i as R, j as A, k as y, l as C, m as N, n as I, o as P, p as m, q as _, r as B, s as L, t as w, u as M, v as j, w as U, x as D, y as G, z as H } from "./node-C2uf3sNA.js";
|
|
2
|
+
import { BRANCH_COLLECTION as ie, BRANCH_ID_PATTERN as ae, PRESETS as ce, PRESET_BLEND_DEFAULT as fe, PRESET_GREEN as le, PRESET_JUSPAY as Te, PRESET_ORANGE as ue, PRESET_PURPLE as de, RADIUS_PRESETS as Oe, SNAPSHOT_SUBCOLLECTION as ke, STORAGE_KEYS as Ee, TEAM_ROLE_PERMISSIONS as Ve, VERSION_PATTERN as ge, VERSION_SUBCOLLECTION as ve, analyzeContrast as pe, canUserPerformAction as Se, diffBrandConfigs as he, extractOverridePaths as Re, generateBranchId as Ae, generateColorScale as ye, getContrastRatio as Ce, getContrastRatioHex as Ne, getDefaultOnboardingState as Ie, getDefaultPreferences as Pe, getPreset as me, hexToRgb as _e, incrementVersion as Be, isValidHexColor as Le, listPresets as we, meetsWCAG as Me, parseBranchId as je, relativeLuminance as Ue, resolveWithInheritance as De, snapshotsPath as Ge, suggestForeground as He, validateAgainstLocks as xe, validateBranchId as Ke, validateBrandConfig as Fe, validatePaletteContrast as Je, validateVersion as $e, versionsPath as Ye } from "./tokens-server.js";
|
|
3
3
|
function O(e) {
|
|
4
4
|
const o = typeof structuredClone == "function" ? structuredClone(u) : JSON.parse(JSON.stringify(u));
|
|
5
5
|
return x(o, e), K(o, e), F(o, e), J(o, e), o;
|
|
@@ -30,8 +30,9 @@ function F(e, o) {
|
|
|
30
30
|
function J(e, o) {
|
|
31
31
|
if (o.font) {
|
|
32
32
|
if (o.font.family) {
|
|
33
|
-
const t = e.font;
|
|
34
|
-
|
|
33
|
+
const t = e.font.family, n = o.font.family.trim(), s = n.toLowerCase() === "system ui" ? "system-ui, sans-serif" : n;
|
|
34
|
+
for (const r of Object.keys(t))
|
|
35
|
+
r !== "mono" && (t[r] = s);
|
|
35
36
|
}
|
|
36
37
|
if (o.font.weight) {
|
|
37
38
|
const t = e.font.weight;
|
|
@@ -46,12 +47,12 @@ const l = {
|
|
|
46
47
|
ALERTV2: D,
|
|
47
48
|
AVATARV2: U,
|
|
48
49
|
BREADCRUMBV2: j,
|
|
49
|
-
CHARTSV2:
|
|
50
|
-
CHECKBOXV2:
|
|
50
|
+
CHARTSV2: M,
|
|
51
|
+
CHECKBOXV2: w,
|
|
51
52
|
CODEEDITORV2: L,
|
|
52
53
|
KEYVALUEPAIRV2: B,
|
|
53
|
-
MENU_V2:
|
|
54
|
-
MULTI_SELECT_V2:
|
|
54
|
+
MENU_V2: _,
|
|
55
|
+
MULTI_SELECT_V2: m,
|
|
55
56
|
POPOVERV2: P,
|
|
56
57
|
PROGRESS_BARV2: I,
|
|
57
58
|
RADIOV2: N,
|
|
@@ -60,8 +61,8 @@ const l = {
|
|
|
60
61
|
SNACKBARV2: A,
|
|
61
62
|
STATCARDV2: R,
|
|
62
63
|
TABSV2: h,
|
|
63
|
-
TAGV2:
|
|
64
|
-
TEXT_INPUTV2:
|
|
64
|
+
TAGV2: S,
|
|
65
|
+
TEXT_INPUTV2: p,
|
|
65
66
|
TIMELINE: v,
|
|
66
67
|
TOOLTIPV2: g,
|
|
67
68
|
TOPBARV2: V,
|
|
@@ -198,9 +199,9 @@ export {
|
|
|
198
199
|
te as V2_COMPONENT_KEYS,
|
|
199
200
|
ge as VERSION_PATTERN,
|
|
200
201
|
ve as VERSION_SUBCOLLECTION,
|
|
201
|
-
|
|
202
|
+
pe as analyzeContrast,
|
|
202
203
|
O as buildBrandFoundation,
|
|
203
|
-
|
|
204
|
+
Se as canUserPerformAction,
|
|
204
205
|
z as clearTokenCache,
|
|
205
206
|
he as diffBrandConfigs,
|
|
206
207
|
Re as extractOverridePaths,
|
|
@@ -210,12 +211,12 @@ export {
|
|
|
210
211
|
Ne as getContrastRatioHex,
|
|
211
212
|
Ie as getDefaultOnboardingState,
|
|
212
213
|
Pe as getDefaultPreferences,
|
|
213
|
-
|
|
214
|
-
|
|
214
|
+
me as getPreset,
|
|
215
|
+
_e as hexToRgb,
|
|
215
216
|
Be as incrementVersion,
|
|
216
217
|
Le as isValidHexColor,
|
|
217
|
-
|
|
218
|
-
|
|
218
|
+
we as listPresets,
|
|
219
|
+
Me as meetsWCAG,
|
|
219
220
|
je as parseBranchId,
|
|
220
221
|
oe as registerResolver,
|
|
221
222
|
Ue as relativeLuminance,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef, useState } from 'react'
|
|
1
|
+
import { forwardRef, useEffect, useState } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
type AvatarProps,
|
|
4
4
|
AvatarSize,
|
|
@@ -33,6 +33,11 @@ const Avatar = forwardRef<HTMLDivElement, AvatarProps>(
|
|
|
33
33
|
ref
|
|
34
34
|
) => {
|
|
35
35
|
const [imageError, setImageError] = useState(false)
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
setImageError(false)
|
|
39
|
+
}, [src])
|
|
40
|
+
|
|
36
41
|
const hasImage = src && !imageError
|
|
37
42
|
const shouldShowSkeleton = skeleton?.show
|
|
38
43
|
const variant = hasImage ? 'withImage' : 'withoutImage'
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useEffect,
|
|
4
|
+
useState,
|
|
5
|
+
type ReactElement,
|
|
6
|
+
} from 'react'
|
|
2
7
|
import {
|
|
3
8
|
AvatarV2Props,
|
|
4
9
|
AvatarV2Size,
|
|
@@ -176,6 +181,10 @@ const AvatarV2 = forwardRef<HTMLDivElement, AvatarV2Props>(
|
|
|
176
181
|
) => {
|
|
177
182
|
const [imageError, setImageError] = useState(false)
|
|
178
183
|
|
|
184
|
+
useEffect(() => {
|
|
185
|
+
setImageError(false)
|
|
186
|
+
}, [src])
|
|
187
|
+
|
|
179
188
|
const tokens = useResponsiveTokens<AvatarV2TokensType>('AVATARV2')
|
|
180
189
|
|
|
181
190
|
const hasImage = src && !imageError
|
|
@@ -5,7 +5,12 @@ import PrimitiveButton from '../Primitives/PrimitiveButton/PrimitiveButton'
|
|
|
5
5
|
import PrimitiveText from '../Primitives/PrimitiveText/PrimitiveText'
|
|
6
6
|
import { FOUNDATION_THEME } from '../../tokens'
|
|
7
7
|
import type { BreadcrumbTokenType } from './breadcrumb.tokens'
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
BreadcrumbItemType,
|
|
10
|
+
BreadcrumbProps,
|
|
11
|
+
BreadcrumbSkeletonProps,
|
|
12
|
+
} from './types'
|
|
13
|
+
import { normalizeBreadcrumbItems } from './types'
|
|
9
14
|
import { useResponsiveTokens } from '../../hooks/useResponsiveTokens'
|
|
10
15
|
import { SkeletonVariant } from '../Skeleton'
|
|
11
16
|
import BreadcrumbSkeleton from './BreadcrumbSkeleton'
|
|
@@ -111,13 +116,9 @@ const BreadcrumbItem = ({
|
|
|
111
116
|
)
|
|
112
117
|
}
|
|
113
118
|
|
|
114
|
-
const Breadcrumb = ({
|
|
115
|
-
items
|
|
116
|
-
|
|
117
|
-
}: {
|
|
118
|
-
items: BreadcrumbItemType[]
|
|
119
|
-
skeleton?: BreadcrumbSkeletonProps
|
|
120
|
-
}) => {
|
|
119
|
+
const Breadcrumb = ({ items: itemsProp, skeleton }: BreadcrumbProps) => {
|
|
120
|
+
const items = normalizeBreadcrumbItems(itemsProp)
|
|
121
|
+
|
|
121
122
|
const breadcrumbTokens =
|
|
122
123
|
useResponsiveTokens<BreadcrumbTokenType>('BREADCRUMB')
|
|
123
124
|
if (items.length === 0) return null
|
|
@@ -5,6 +5,18 @@ export type BreadcrumbSkeletonProps = {
|
|
|
5
5
|
variant: SkeletonVariant
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
/** Replace null, undefined, or non-array `items` with `[]`. */
|
|
9
|
+
export function normalizeBreadcrumbItems(
|
|
10
|
+
items: BreadcrumbItemType[] | null | undefined
|
|
11
|
+
): BreadcrumbItemType[] {
|
|
12
|
+
return Array.isArray(items) ? items : []
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type BreadcrumbProps = {
|
|
16
|
+
items: BreadcrumbItemType[] | null
|
|
17
|
+
skeleton?: BreadcrumbSkeletonProps
|
|
18
|
+
}
|
|
19
|
+
|
|
8
20
|
export type BreadcrumbItemType = {
|
|
9
21
|
leftSlot?: React.ReactNode
|
|
10
22
|
rightSlot?: React.ReactNode
|
|
@@ -11,7 +11,7 @@ import type { ButtonTokensType } from './button.tokens'
|
|
|
11
11
|
import { LoaderCircle } from 'lucide-react'
|
|
12
12
|
import { useResponsiveTokens } from '../../hooks/useResponsiveTokens'
|
|
13
13
|
import { FOUNDATION_THEME } from '../../tokens'
|
|
14
|
-
const StyledButtonText = styled
|
|
14
|
+
const StyledButtonText = styled.span`
|
|
15
15
|
display: flex;
|
|
16
16
|
align-items: center;
|
|
17
17
|
justify-content: center;
|
|
@@ -44,6 +44,37 @@ type CustomCardComponentProps = {
|
|
|
44
44
|
baseId?: string
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
const isPlainTextContent = (content: React.ReactNode) =>
|
|
48
|
+
typeof content === 'string' || typeof content === 'number'
|
|
49
|
+
|
|
50
|
+
const CardBodyContent = ({
|
|
51
|
+
content,
|
|
52
|
+
contentId,
|
|
53
|
+
cardToken,
|
|
54
|
+
describedBy,
|
|
55
|
+
}: {
|
|
56
|
+
content: React.ReactNode
|
|
57
|
+
contentId: string
|
|
58
|
+
cardToken: CardTokenType
|
|
59
|
+
describedBy?: string
|
|
60
|
+
}) => {
|
|
61
|
+
const sharedProps = {
|
|
62
|
+
id: contentId,
|
|
63
|
+
style: getBodyContentStyles(cardToken),
|
|
64
|
+
'aria-describedby': describedBy,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (isPlainTextContent(content)) {
|
|
68
|
+
return (
|
|
69
|
+
<Text as="p" {...sharedProps}>
|
|
70
|
+
{content}
|
|
71
|
+
</Text>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return <Block {...sharedProps}>{content}</Block>
|
|
76
|
+
}
|
|
77
|
+
|
|
47
78
|
export const DefaultCard: React.FC<CardComponentProps> = ({
|
|
48
79
|
props,
|
|
49
80
|
cardToken,
|
|
@@ -80,6 +111,9 @@ export const DefaultCard: React.FC<CardComponentProps> = ({
|
|
|
80
111
|
const subHeaderId = `${baseId}-subheader`
|
|
81
112
|
const bodyTitleId = `${baseId}-body-title`
|
|
82
113
|
const contentId = `${baseId}-content`
|
|
114
|
+
const contentDataId = isPlainTextContent(content)
|
|
115
|
+
? String(content)
|
|
116
|
+
: undefined
|
|
83
117
|
|
|
84
118
|
return (
|
|
85
119
|
<>
|
|
@@ -228,22 +262,20 @@ export const DefaultCard: React.FC<CardComponentProps> = ({
|
|
|
228
262
|
),
|
|
229
263
|
}}
|
|
230
264
|
data-element="card-body-content"
|
|
231
|
-
data-id={
|
|
265
|
+
data-id={contentDataId}
|
|
232
266
|
>
|
|
233
|
-
<
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
267
|
+
<CardBodyContent
|
|
268
|
+
content={content}
|
|
269
|
+
contentId={contentId}
|
|
270
|
+
cardToken={cardToken}
|
|
271
|
+
describedBy={
|
|
238
272
|
bodyTitle
|
|
239
273
|
? bodyTitleId
|
|
240
274
|
: headerTitle
|
|
241
275
|
? headerTitleId
|
|
242
276
|
: undefined
|
|
243
277
|
}
|
|
244
|
-
|
|
245
|
-
{content}
|
|
246
|
-
</Text>
|
|
278
|
+
/>
|
|
247
279
|
</Block>
|
|
248
280
|
)}
|
|
249
281
|
|
|
@@ -461,20 +493,18 @@ const CardContent: React.FC<{
|
|
|
461
493
|
}
|
|
462
494
|
>
|
|
463
495
|
{hasContent && (
|
|
464
|
-
<
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
496
|
+
<CardBodyContent
|
|
497
|
+
content={content}
|
|
498
|
+
contentId={contentId}
|
|
499
|
+
cardToken={cardToken}
|
|
500
|
+
describedBy={
|
|
469
501
|
bodyTitle
|
|
470
502
|
? bodyTitleId
|
|
471
503
|
: headerTitle
|
|
472
504
|
? headerTitleId
|
|
473
505
|
: undefined
|
|
474
506
|
}
|
|
475
|
-
|
|
476
|
-
{content}
|
|
477
|
-
</Text>
|
|
507
|
+
/>
|
|
478
508
|
)}
|
|
479
509
|
|
|
480
510
|
{hasActionButton && (
|
|
@@ -612,7 +642,12 @@ export const CustomCard: React.FC<CustomCardComponentProps> = ({
|
|
|
612
642
|
|
|
613
643
|
return (
|
|
614
644
|
<Block
|
|
645
|
+
display="flex"
|
|
646
|
+
flexDirection="column"
|
|
647
|
+
flexGrow={1}
|
|
615
648
|
style={{
|
|
649
|
+
minHeight: 0,
|
|
650
|
+
width: '100%',
|
|
616
651
|
...(maxHeight && {
|
|
617
652
|
overflowY: 'auto',
|
|
618
653
|
overflowX: 'hidden',
|
|
@@ -6,6 +6,13 @@ import {
|
|
|
6
6
|
} from './types'
|
|
7
7
|
import { parseTimestamp, dateFormat } from './DateTimeFormatter'
|
|
8
8
|
|
|
9
|
+
/** Replace null, undefined, or non-array `data` with `[]` (empty / no-data state). */
|
|
10
|
+
export function normalizeChartData(
|
|
11
|
+
data: NewNestedDataPoint[] | null | undefined
|
|
12
|
+
): NewNestedDataPoint[] {
|
|
13
|
+
return Array.isArray(data) ? data : []
|
|
14
|
+
}
|
|
15
|
+
|
|
9
16
|
export function transformNestedData(
|
|
10
17
|
data: NewNestedDataPoint[],
|
|
11
18
|
selectedKeys: string[] = []
|
|
@@ -5,7 +5,7 @@ import ChartHeader from './ChartHeader'
|
|
|
5
5
|
import ChartLegends from './ChartLegend'
|
|
6
6
|
import { useRef, useState, useEffect, useCallback, useId, useMemo } from 'react'
|
|
7
7
|
import { renderChart } from './renderChart'
|
|
8
|
-
import { transformNestedData } from './ChartUtils'
|
|
8
|
+
import { normalizeChartData, transformNestedData } from './ChartUtils'
|
|
9
9
|
import Block from '../../components/Primitives/Block/Block'
|
|
10
10
|
import { ChartTokensType } from './chart.tokens'
|
|
11
11
|
import { FOUNDATION_THEME } from '../../tokens'
|
|
@@ -20,7 +20,7 @@ import ChartsSkeleton from './ChartsSkeleton'
|
|
|
20
20
|
|
|
21
21
|
const Charts: React.FC<ChartsProps> = ({
|
|
22
22
|
chartType = ChartType.LINE,
|
|
23
|
-
data,
|
|
23
|
+
data: dataProp,
|
|
24
24
|
colors,
|
|
25
25
|
slot1,
|
|
26
26
|
slot2,
|
|
@@ -46,6 +46,8 @@ const Charts: React.FC<ChartsProps> = ({
|
|
|
46
46
|
lineSeriesKeys,
|
|
47
47
|
...props
|
|
48
48
|
}) => {
|
|
49
|
+
const data = normalizeChartData(dataProp)
|
|
50
|
+
|
|
49
51
|
const { breakPointLabel } = useBreakpoints(BREAKPOINTS)
|
|
50
52
|
const isSmallScreen = breakPointLabel === 'sm'
|
|
51
53
|
const chartTokens = useResponsiveTokens<ChartTokensType>('CHARTS')
|
|
@@ -3,11 +3,11 @@ import { ResponsiveContainer } from 'recharts'
|
|
|
3
3
|
import { ChartType, CoreChartProps } from './types'
|
|
4
4
|
import { DEFAULT_COLORS } from './utils'
|
|
5
5
|
import { renderChart } from './renderChart'
|
|
6
|
-
import { transformNestedData } from './ChartUtils'
|
|
6
|
+
import { normalizeChartData, transformNestedData } from './ChartUtils'
|
|
7
7
|
|
|
8
8
|
export const CoreChart: React.FC<CoreChartProps> = ({
|
|
9
9
|
chartType = ChartType.LINE,
|
|
10
|
-
data,
|
|
10
|
+
data: dataProp,
|
|
11
11
|
colors = DEFAULT_COLORS,
|
|
12
12
|
barsize,
|
|
13
13
|
xAxis,
|
|
@@ -22,6 +22,8 @@ export const CoreChart: React.FC<CoreChartProps> = ({
|
|
|
22
22
|
enableHover = false,
|
|
23
23
|
lineSeriesKeys,
|
|
24
24
|
}) => {
|
|
25
|
+
const data = normalizeChartData(dataProp)
|
|
26
|
+
|
|
25
27
|
const [internalHoveredKey, setInternalHoveredKey] = useState<string | null>(
|
|
26
28
|
null
|
|
27
29
|
)
|
|
@@ -151,7 +151,7 @@ export type RenderChartProps = {
|
|
|
151
151
|
|
|
152
152
|
export type CoreChartProps = {
|
|
153
153
|
chartType?: ChartType
|
|
154
|
-
data
|
|
154
|
+
data?: NewNestedDataPoint[] | null
|
|
155
155
|
colors?: { key: string; color: string }[]
|
|
156
156
|
barsize?: number
|
|
157
157
|
xAxis?: XAxisConfig
|
|
@@ -175,7 +175,7 @@ export type ChartsSkeletonProps = {
|
|
|
175
175
|
|
|
176
176
|
export type ChartsProps = {
|
|
177
177
|
chartType?: ChartType
|
|
178
|
-
data
|
|
178
|
+
data?: NewNestedDataPoint[] | null
|
|
179
179
|
colors?: { key: string; color: string }[]
|
|
180
180
|
slot1?: ReactNode
|
|
181
181
|
slot2?: ReactNode
|
|
@@ -32,7 +32,7 @@ const ChartV2 = forwardRef<ChartV2ReactRefObject, ChartV2Props>(
|
|
|
32
32
|
ref
|
|
33
33
|
) => {
|
|
34
34
|
const tokens = useResponsiveTokens<ChartV2TokensType>('CHARTSV2')
|
|
35
|
-
const { options, ...restProps } = props
|
|
35
|
+
const { options = {}, ...restProps } = props
|
|
36
36
|
|
|
37
37
|
const hasSeriesData =
|
|
38
38
|
(options.series as ChartV2SeriesOptionsType[] | undefined)?.some(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef, useId } from 'react'
|
|
1
|
+
import { forwardRef, useEffect, useId, useState } from 'react'
|
|
2
2
|
import { Check, Minus } from 'lucide-react'
|
|
3
3
|
import type { CheckboxProps } from './types'
|
|
4
4
|
import { CheckboxSize } from './types'
|
|
@@ -46,6 +46,26 @@ export const Checkbox = forwardRef<HTMLButtonElement, CheckboxProps>(
|
|
|
46
46
|
const generatedId = useId()
|
|
47
47
|
const uniqueId = id || generatedId
|
|
48
48
|
const shouldShake = useErrorShake(error)
|
|
49
|
+
const isControlled = checked !== undefined
|
|
50
|
+
const [uncontrolledChecked, setUncontrolledChecked] = useState<
|
|
51
|
+
boolean | 'indeterminate'
|
|
52
|
+
>(defaultChecked ?? false)
|
|
53
|
+
const resolvedChecked = isControlled ? checked : uncontrolledChecked
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (!isControlled) {
|
|
57
|
+
setUncontrolledChecked(defaultChecked ?? false)
|
|
58
|
+
}
|
|
59
|
+
}, [defaultChecked, isControlled])
|
|
60
|
+
|
|
61
|
+
const handleCheckedChange = (
|
|
62
|
+
nextChecked: boolean | 'indeterminate'
|
|
63
|
+
) => {
|
|
64
|
+
if (!isControlled) {
|
|
65
|
+
setUncontrolledChecked(nextChecked)
|
|
66
|
+
}
|
|
67
|
+
onCheckedChange?.(nextChecked)
|
|
68
|
+
}
|
|
49
69
|
|
|
50
70
|
const labelMaxLength = maxLength?.label
|
|
51
71
|
const subtextMaxLength = maxLength?.subtext
|
|
@@ -76,28 +96,30 @@ export const Checkbox = forwardRef<HTMLButtonElement, CheckboxProps>(
|
|
|
76
96
|
id={uniqueId}
|
|
77
97
|
name={name}
|
|
78
98
|
ref={ref}
|
|
79
|
-
|
|
80
|
-
|
|
99
|
+
{...(isControlled
|
|
100
|
+
? { checked }
|
|
101
|
+
: { defaultChecked: defaultChecked ?? false })}
|
|
102
|
+
onCheckedChange={handleCheckedChange}
|
|
81
103
|
disabled={disabled}
|
|
82
104
|
required={required}
|
|
83
105
|
size={size}
|
|
84
106
|
$isDisabled={disabled}
|
|
85
|
-
$checked={
|
|
107
|
+
$checked={resolvedChecked}
|
|
86
108
|
$error={error}
|
|
87
109
|
style={getErrorShakeStyle(shouldShake)}
|
|
88
110
|
{...ariaAttributes}
|
|
89
111
|
{...restProps}
|
|
90
112
|
data-element="checkbox"
|
|
91
113
|
data-state={
|
|
92
|
-
|
|
114
|
+
resolvedChecked === 'indeterminate'
|
|
93
115
|
? 'indeterminate'
|
|
94
|
-
:
|
|
116
|
+
: resolvedChecked
|
|
95
117
|
? 'checked'
|
|
96
118
|
: 'unchecked'
|
|
97
119
|
}
|
|
98
120
|
>
|
|
99
121
|
<CheckboxIndicator
|
|
100
|
-
checked={
|
|
122
|
+
checked={resolvedChecked}
|
|
101
123
|
size={size}
|
|
102
124
|
tokens={tokens}
|
|
103
125
|
disabled={disabled}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
useCallback,
|
|
8
8
|
useMemo,
|
|
9
9
|
} from 'react'
|
|
10
|
+
import styled from 'styled-components'
|
|
10
11
|
import { Check, Copy, FileCode } from 'lucide-react'
|
|
11
12
|
import Block from '../Primitives/Block/Block'
|
|
12
13
|
import Button from '../Button/Button'
|
|
@@ -33,6 +34,21 @@ import {
|
|
|
33
34
|
buildDiffViewSegments,
|
|
34
35
|
} from './utils'
|
|
35
36
|
|
|
37
|
+
const CopyOverlay = styled.div`
|
|
38
|
+
position: absolute;
|
|
39
|
+
top: 12px;
|
|
40
|
+
right: 12px;
|
|
41
|
+
z-index: 10;
|
|
42
|
+
opacity: 0;
|
|
43
|
+
pointer-events: none;
|
|
44
|
+
transition: opacity 0.15s ease;
|
|
45
|
+
|
|
46
|
+
.code-body:hover & {
|
|
47
|
+
opacity: 1;
|
|
48
|
+
pointer-events: auto;
|
|
49
|
+
}
|
|
50
|
+
`
|
|
51
|
+
|
|
36
52
|
const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
|
|
37
53
|
(
|
|
38
54
|
{
|
|
@@ -255,7 +271,7 @@ const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
|
|
|
255
271
|
type="button"
|
|
256
272
|
onClick={copyToClipboard}
|
|
257
273
|
buttonType={ButtonType.SECONDARY}
|
|
258
|
-
subType={ButtonSubType.
|
|
274
|
+
subType={ButtonSubType.INLINE}
|
|
259
275
|
size={ButtonSize.SMALL}
|
|
260
276
|
aria-label={
|
|
261
277
|
isCopied
|
|
@@ -284,8 +300,38 @@ const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
|
|
|
284
300
|
}
|
|
285
301
|
backgroundColor={tokens.body.backgroundColor}
|
|
286
302
|
overflow="auto"
|
|
303
|
+
position={
|
|
304
|
+
!showHeader && showCopyButton ? 'relative' : undefined
|
|
305
|
+
}
|
|
306
|
+
className={
|
|
307
|
+
!showHeader && showCopyButton ? 'code-body' : undefined
|
|
308
|
+
}
|
|
287
309
|
style={{ maxHeight: maxHeight || 'none' }}
|
|
288
310
|
>
|
|
311
|
+
{!showHeader && showCopyButton && (
|
|
312
|
+
<CopyOverlay>
|
|
313
|
+
<Button
|
|
314
|
+
data-element="copy-button"
|
|
315
|
+
type="button"
|
|
316
|
+
onClick={copyToClipboard}
|
|
317
|
+
buttonType={ButtonType.SECONDARY}
|
|
318
|
+
subType={ButtonSubType.ICON_ONLY}
|
|
319
|
+
size={ButtonSize.SMALL}
|
|
320
|
+
aria-label={
|
|
321
|
+
isCopied
|
|
322
|
+
? 'Code copied to clipboard'
|
|
323
|
+
: 'Copy code'
|
|
324
|
+
}
|
|
325
|
+
leadingIcon={
|
|
326
|
+
isCopied ? (
|
|
327
|
+
<Check size={16} aria-hidden="true" />
|
|
328
|
+
) : (
|
|
329
|
+
<Copy size={16} aria-hidden="true" />
|
|
330
|
+
)
|
|
331
|
+
}
|
|
332
|
+
/>
|
|
333
|
+
</CopyOverlay>
|
|
334
|
+
)}
|
|
289
335
|
{isDiffMode && diffLines?.length ? (
|
|
290
336
|
<CodeBlockDiffView
|
|
291
337
|
diffLines={diffLines}
|
|
@@ -130,9 +130,9 @@ export const getCodeBlockTokens = (
|
|
|
130
130
|
borderBottom: `1px solid ${foundationToken.colors.gray[200]}`,
|
|
131
131
|
padding: {
|
|
132
132
|
x: foundationToken.unit[12],
|
|
133
|
-
y: foundationToken.unit[
|
|
133
|
+
y: foundationToken.unit[8],
|
|
134
134
|
},
|
|
135
|
-
gap: foundationToken.unit[
|
|
135
|
+
gap: foundationToken.unit[6],
|
|
136
136
|
icon: {
|
|
137
137
|
width: 16,
|
|
138
138
|
},
|
|
@@ -229,11 +229,11 @@ export const getCodeBlockTokens = (
|
|
|
229
229
|
borderBottom: `1px solid ${foundationToken.colors.gray[200]}`,
|
|
230
230
|
padding: {
|
|
231
231
|
x: foundationToken.unit[16],
|
|
232
|
-
y: foundationToken.unit[
|
|
232
|
+
y: foundationToken.unit[8],
|
|
233
233
|
},
|
|
234
|
-
gap: foundationToken.unit[
|
|
234
|
+
gap: foundationToken.unit[8],
|
|
235
235
|
icon: {
|
|
236
|
-
width:
|
|
236
|
+
width: 16,
|
|
237
237
|
},
|
|
238
238
|
text: {
|
|
239
239
|
fontSize: foundationToken.font.size.body.md.fontSize,
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { forwardRef, useState } from 'react'
|
|
1
|
+
import { forwardRef, useCallback, useEffect, useRef, useState } from 'react'
|
|
2
2
|
import Block from '../Primitives/Block/Block'
|
|
3
3
|
import { useResponsiveTokens } from '../../hooks/useResponsiveTokens'
|
|
4
4
|
import type { CodeBlockTokenType } from '../CodeBlock/codeBlock.token'
|
|
5
5
|
import { CodeEditorVariant, type CodeEditorProps } from './types'
|
|
6
|
-
import { createCopyToClipboard } from '../CodeBlock/utils'
|
|
7
6
|
import { shouldShowLineNumbers, getContainerStyles } from './utils'
|
|
8
7
|
import { CodeEditorHeader } from './CodeEditorHeader'
|
|
9
8
|
import { MonacoEditorWrapper } from './MonacoEditorWrapper'
|
|
@@ -37,6 +36,31 @@ const CodeEditor = forwardRef<HTMLDivElement, CodeEditorProps>(
|
|
|
37
36
|
) => {
|
|
38
37
|
const tokens = useResponsiveTokens<CodeBlockTokenType>('CODE_BLOCK')
|
|
39
38
|
const [isCopied, setIsCopied] = useState(false)
|
|
39
|
+
const copyFeedbackTimeoutRef = useRef<ReturnType<
|
|
40
|
+
typeof setTimeout
|
|
41
|
+
> | null>(null)
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
return () => {
|
|
45
|
+
if (copyFeedbackTimeoutRef.current !== null) {
|
|
46
|
+
clearTimeout(copyFeedbackTimeoutRef.current)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}, [])
|
|
50
|
+
|
|
51
|
+
const copyToClipboard = useCallback(() => {
|
|
52
|
+
navigator.clipboard.writeText(value)
|
|
53
|
+
setIsCopied(true)
|
|
54
|
+
|
|
55
|
+
if (copyFeedbackTimeoutRef.current !== null) {
|
|
56
|
+
clearTimeout(copyFeedbackTimeoutRef.current)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
copyFeedbackTimeoutRef.current = setTimeout(() => {
|
|
60
|
+
setIsCopied(false)
|
|
61
|
+
copyFeedbackTimeoutRef.current = null
|
|
62
|
+
}, 2000)
|
|
63
|
+
}, [value])
|
|
40
64
|
|
|
41
65
|
// Determine if line numbers should be shown
|
|
42
66
|
const shouldShowLineNumbersValue = shouldShowLineNumbers(
|
|
@@ -44,8 +68,6 @@ const CodeEditor = forwardRef<HTMLDivElement, CodeEditorProps>(
|
|
|
44
68
|
variant
|
|
45
69
|
)
|
|
46
70
|
|
|
47
|
-
// Handlers
|
|
48
|
-
const copyToClipboard = createCopyToClipboard(value, setIsCopied)
|
|
49
71
|
const containerStyles = getContainerStyles(minHeight, maxHeight)
|
|
50
72
|
|
|
51
73
|
return (
|
|
@@ -342,6 +342,7 @@ export const MonacoEditorWrapper = ({
|
|
|
342
342
|
const editorRef = useRef<Monaco.editor.IStandaloneCodeEditor | null>(null)
|
|
343
343
|
const monacoRef = useRef<typeof import('monaco-editor') | null>(null)
|
|
344
344
|
const shortcutDisposables = useRef<Monaco.IDisposable[]>([])
|
|
345
|
+
const focusTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
345
346
|
const [isEditorReady, setIsEditorReady] = useState(false)
|
|
346
347
|
const monacoLanguage = useMemo(() => mapLanguage(language), [language])
|
|
347
348
|
|
|
@@ -449,6 +450,14 @@ export const MonacoEditorWrapper = ({
|
|
|
449
450
|
}
|
|
450
451
|
}, [disposeShortcuts, isEditorReady, registerKeyboardShortcuts])
|
|
451
452
|
|
|
453
|
+
useEffect(() => {
|
|
454
|
+
return () => {
|
|
455
|
+
if (focusTimeoutRef.current !== null) {
|
|
456
|
+
clearTimeout(focusTimeoutRef.current)
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}, [])
|
|
460
|
+
|
|
452
461
|
const handleEditorDidMount: OnMount = (editor, monacoInstance) => {
|
|
453
462
|
editorRef.current = editor
|
|
454
463
|
monacoRef.current = monacoInstance
|
|
@@ -502,7 +511,10 @@ export const MonacoEditorWrapper = ({
|
|
|
502
511
|
editor.onDidBlurEditorText(() => onBlur?.())
|
|
503
512
|
|
|
504
513
|
if (autoFocus && !disabled && !readOnly) {
|
|
505
|
-
|
|
514
|
+
focusTimeoutRef.current = setTimeout(
|
|
515
|
+
() => editor.focus(),
|
|
516
|
+
EDITOR_FOCUS_DELAY_MS
|
|
517
|
+
)
|
|
506
518
|
}
|
|
507
519
|
}
|
|
508
520
|
|