@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.
Files changed (72) hide show
  1. package/dist/components/Breadcrumb/Breadcrumb.d.ts +2 -5
  2. package/dist/components/Breadcrumb/types.d.ts +6 -0
  3. package/dist/components/Charts/ChartUtils.d.ts +2 -0
  4. package/dist/components/Charts/types.d.ts +2 -2
  5. package/dist/components/DateRangePicker/types.d.ts +1 -1
  6. package/dist/components/DateRangePicker/utils.d.ts +2 -0
  7. package/dist/components/Directory/Directory.d.ts +1 -1
  8. package/dist/components/Directory/types.d.ts +1 -1
  9. package/dist/components/Directory/utils.d.ts +2 -0
  10. package/dist/components/Radio/StyledRadio.d.ts +0 -1
  11. package/dist/components/Sidebar/SidebarContent.d.ts +1 -1
  12. package/dist/components/Sidebar/types.d.ts +10 -1
  13. package/dist/components/Sidebar/utils.d.ts +1 -1
  14. package/dist/components/SidebarV2/SidebarV2Panel.d.ts +1 -1
  15. package/dist/components/SidebarV2/index.d.ts +1 -1
  16. package/dist/components/SidebarV2/types.d.ts +3 -0
  17. package/dist/components/Stepper/types.d.ts +2 -0
  18. package/dist/main.js +27657 -27314
  19. package/dist/tokens.js +17 -16
  20. package/lib/components/Avatar/Avatar.tsx +6 -1
  21. package/lib/components/AvatarGroup/AvatarGroup.tsx +1 -1
  22. package/lib/components/AvatarV2/AvatarV2.tsx +10 -1
  23. package/lib/components/Breadcrumb/Breadcrumb.tsx +9 -8
  24. package/lib/components/Breadcrumb/types.ts +12 -0
  25. package/lib/components/Button/ButtonBase.tsx +1 -1
  26. package/lib/components/Card/CardComponents.tsx +52 -17
  27. package/lib/components/Charts/ChartUtils.tsx +7 -0
  28. package/lib/components/Charts/Charts.tsx +4 -2
  29. package/lib/components/Charts/CoreChart.tsx +4 -2
  30. package/lib/components/Charts/types.tsx +2 -2
  31. package/lib/components/ChartsV2/ChartV2.tsx +1 -1
  32. package/lib/components/Checkbox/Checkbox.tsx +29 -7
  33. package/lib/components/CodeBlock/CodeBlock.tsx +47 -1
  34. package/lib/components/CodeBlock/codeBlock.token.ts +5 -5
  35. package/lib/components/CodeEditor/CodeEditor.tsx +26 -4
  36. package/lib/components/CodeEditor/MonacoEditorWrapper.tsx +13 -1
  37. package/lib/components/DataTable/DataTable.tsx +8 -0
  38. package/lib/components/DataTable/TableHeader/FilterComponents.tsx +4 -0
  39. package/lib/components/DateRangePicker/DateRangePicker.tsx +34 -17
  40. package/lib/components/DateRangePicker/types.ts +5 -5
  41. package/lib/components/DateRangePicker/utils.ts +5 -0
  42. package/lib/components/Directory/Directory.tsx +3 -2
  43. package/lib/components/Directory/types.ts +1 -1
  44. package/lib/components/Directory/utils.ts +6 -0
  45. package/lib/components/Drawer/components/DrawerBase.tsx +16 -0
  46. package/lib/components/Drawer/components/NestedSelectDrawer.tsx +13 -1
  47. package/lib/components/Drawer/components/SelectDrawer.tsx +9 -1
  48. package/lib/components/Inputs/OTPInput/OTPInput.tsx +5 -3
  49. package/lib/components/Menu/Menu.tsx +9 -1
  50. package/lib/components/Modal/useModal.ts +7 -0
  51. package/lib/components/Radio/Radio.tsx +12 -5
  52. package/lib/components/Radio/StyledRadio.tsx +33 -17
  53. package/lib/components/Sidebar/Sidebar.tsx +11 -1
  54. package/lib/components/Sidebar/SidebarContent.tsx +5 -2
  55. package/lib/components/Sidebar/TenantPanel.tsx +52 -34
  56. package/lib/components/Sidebar/types.ts +11 -1
  57. package/lib/components/Sidebar/utils.ts +1 -1
  58. package/lib/components/SidebarV2/SecondarySidebar.tsx +86 -44
  59. package/lib/components/SidebarV2/SidebarV2Panel.tsx +4 -2
  60. package/lib/components/SidebarV2/index.ts +1 -0
  61. package/lib/components/SidebarV2/types.ts +4 -0
  62. package/lib/components/StatCard/statcard.tokens.ts +1 -1
  63. package/lib/components/Stepper/VerticalStepper.tsx +209 -171
  64. package/lib/components/Stepper/types.ts +2 -0
  65. package/lib/components/StepperV2/Stepper/Steps.tsx +15 -1
  66. package/lib/components/Text/Text.tsx +1 -0
  67. package/lib/components/Upload/Upload.tsx +6 -0
  68. package/lib/components/Upload/components/FileListDisplay.tsx +159 -16
  69. package/lib/components/Upload/utils.ts +10 -2
  70. package/lib/context/ThemeProvider.tsx +19 -8
  71. package/lib/hooks/useDebounce.ts +9 -1
  72. package/package.json +1 -1
@@ -1,9 +1,9 @@
1
- import React from 'react'
1
+ import React, { useState } from 'react'
2
2
  import Block from '../../Primitives/Block/Block'
3
3
  import Text from '../../Text/Text'
4
- import { Tag, Tooltip } from '../../../main'
4
+ import { Tag, Tooltip, Popover } from '../../../main'
5
5
  import { TagColor, TagVariant, TagShape } from '../../Tags/types'
6
- import { X } from 'lucide-react'
6
+ import { X, ChevronUp, ChevronDown } from 'lucide-react'
7
7
  import type { UploadedFileWithStatus } from '../types'
8
8
  import type { UploadTokenType } from '../upload.tokens'
9
9
  import { truncateFileList } from '../utils'
@@ -21,6 +21,8 @@ const FileListDisplay: React.FC<FileListDisplayProps> = ({
21
21
  onFileRemove,
22
22
  uploadTokens,
23
23
  }) => {
24
+ const [isOpen, setIsOpen] = useState(false)
25
+
24
26
  const sortedFiles = [...files].sort((a, b) => {
25
27
  if (a.status === 'error' && b.status !== 'error') return -1
26
28
  if (a.status !== 'error' && b.status === 'error') return 1
@@ -89,20 +91,161 @@ const FileListDisplay: React.FC<FileListDisplayProps> = ({
89
91
  />
90
92
  </Tooltip>
91
93
  ))}
94
+ {truncatedCount > 0 && (
95
+ <Popover
96
+ open={isOpen}
97
+ onOpenChange={setIsOpen}
98
+ trigger={
99
+ <Tag
100
+ text={`+ ${truncatedCount}`}
101
+ variant={TagVariant.SUBTLE}
102
+ color={TagColor.NEUTRAL}
103
+ shape={TagShape.ROUNDED}
104
+ rightSlot={
105
+ isOpen ? (
106
+ <ChevronUp size={14} />
107
+ ) : (
108
+ <ChevronDown size={14} />
109
+ )
110
+ }
111
+ onClick={(e) => e.stopPropagation()}
112
+ cursor="pointer"
113
+ />
114
+ }
115
+ minWidth={240}
116
+ maxWidth={300}
117
+ maxHeight={220}
118
+ showCloseButton={false}
119
+ asModal={true}
120
+ >
121
+ <Block
122
+ display="flex"
123
+ flexDirection="column"
124
+ gap={FOUNDATION_THEME.unit[8]}
125
+ padding={FOUNDATION_THEME.unit[12]}
126
+ overflow="auto"
127
+ >
128
+ {sortedFiles
129
+ .slice(displayFiles.length)
130
+ .map((file) => (
131
+ <Block
132
+ key={file.id}
133
+ display="flex"
134
+ alignItems="center"
135
+ justifyContent="space-between"
136
+ gap={FOUNDATION_THEME.unit[12]}
137
+ >
138
+ <Block
139
+ display="flex"
140
+ alignItems="center"
141
+ gap={FOUNDATION_THEME.unit[8]}
142
+ minWidth={0}
143
+ flexGrow={1}
144
+ >
145
+ <Tooltip
146
+ content={
147
+ file.status === 'error' &&
148
+ file.error
149
+ ? file.error
150
+ : file.file.name
151
+ }
152
+ fullWidth
153
+ >
154
+ <Block
155
+ display="flex"
156
+ alignItems="center"
157
+ gap={
158
+ FOUNDATION_THEME.unit[8]
159
+ }
160
+ minWidth={0}
161
+ flexGrow={1}
162
+ width="0"
163
+ overflow="hidden"
164
+ >
165
+ <Text
166
+ fontSize={
167
+ uploadTokens
168
+ .container
169
+ .content.text
170
+ .subtitle
171
+ .fontSize
172
+ }
173
+ fontWeight={
174
+ uploadTokens
175
+ .container
176
+ .content.text
177
+ .subtitle
178
+ .fontWeight
179
+ }
180
+ color={
181
+ uploadTokens
182
+ .container
183
+ .content.text
184
+ .subtitle.color
185
+ }
186
+ truncate={true}
187
+ >
188
+ {file.file.name}
189
+ </Text>
190
+ </Block>
191
+ </Tooltip>
192
+ </Block>
193
+ {(file.status === 'error' ||
194
+ file.error) && (
195
+ <Block
196
+ padding={`${FOUNDATION_THEME.unit[2]} ${FOUNDATION_THEME.unit[8]}`}
197
+ borderRadius={
198
+ FOUNDATION_THEME.unit[4]
199
+ }
200
+ backgroundColor={
201
+ FOUNDATION_THEME.colors
202
+ .red[50]
203
+ }
204
+ >
205
+ <Text
206
+ fontSize={12}
207
+ fontWeight={500}
208
+ color={
209
+ FOUNDATION_THEME.colors
210
+ .red[600]
211
+ }
212
+ >
213
+ Failed
214
+ </Text>
215
+ </Block>
216
+ )}
217
+ {onFileRemove && (
218
+ <X
219
+ size={14}
220
+ onClick={(e) => {
221
+ e.stopPropagation()
222
+ onFileRemove(file.id)
223
+ }}
224
+ style={{
225
+ cursor: 'pointer',
226
+ flexShrink: 0,
227
+ }}
228
+ aria-label={`Remove ${file.file.name}`}
229
+ role="button"
230
+ tabIndex={0}
231
+ onKeyDown={(e) => {
232
+ if (
233
+ e.key === 'Enter' ||
234
+ e.key === ' '
235
+ ) {
236
+ e.preventDefault()
237
+ e.stopPropagation()
238
+ onFileRemove(file.id)
239
+ }
240
+ }}
241
+ />
242
+ )}
243
+ </Block>
244
+ ))}
245
+ </Block>
246
+ </Popover>
247
+ )}
92
248
  </Block>
93
- {truncatedCount > 0 && (
94
- <Text
95
- fontSize={
96
- uploadTokens.container.content.text.subtitle.fontSize
97
- }
98
- fontWeight={
99
- uploadTokens.container.content.text.subtitle.fontWeight
100
- }
101
- color={uploadTokens.container.content.text.subtitle.color}
102
- >
103
- +{truncatedCount} more files
104
- </Text>
105
- )}
106
249
  </Block>
107
250
  )
108
251
  }
@@ -601,12 +601,16 @@ export const createUploadManager = () => {
601
601
  progressInterval: number = 200
602
602
  ): (() => void) => {
603
603
  let currentProgress = uploadFile.progress || 0
604
+ let completeTimeout: ReturnType<typeof setTimeout> | null = null
604
605
 
605
606
  const interval = setInterval(() => {
606
607
  if (currentProgress >= 100) {
607
608
  clearInterval(interval)
608
- runningUploads.delete(uploadFile.id)
609
- setTimeout(() => onComplete(uploadFile.id), 500)
609
+ completeTimeout = setTimeout(() => {
610
+ completeTimeout = null
611
+ runningUploads.delete(uploadFile.id)
612
+ onComplete(uploadFile.id)
613
+ }, 500)
610
614
  return
611
615
  }
612
616
 
@@ -617,6 +621,10 @@ export const createUploadManager = () => {
617
621
 
618
622
  const cleanup = () => {
619
623
  clearInterval(interval)
624
+ if (completeTimeout !== null) {
625
+ clearTimeout(completeTimeout)
626
+ completeTimeout = null
627
+ }
620
628
  runningUploads.delete(uploadFile.id)
621
629
  }
622
630
 
@@ -1,3 +1,4 @@
1
+ import { useMemo } from 'react'
1
2
  import { BREAKPOINTS, type BreakpointType } from '../breakpoints/breakPoints'
2
3
  import { FOUNDATION_THEME, type ThemeType } from '../tokens'
3
4
  import initTokens from './initComponentTokens'
@@ -6,6 +7,8 @@ import { Theme } from './theme.enum'
6
7
  import { AutofillStyles } from '../components/Inputs/AutofillStyles/AutofillStyles'
7
8
  import ShadowAware from './ShadowAware'
8
9
 
10
+ const EMPTY_COMPONENT_TOKENS: ComponentTokenType = {}
11
+
9
12
  type ThemeProviderProps = {
10
13
  foundationTokens?: ThemeType
11
14
  componentTokens?: ComponentTokenType
@@ -25,18 +28,26 @@ type ThemeProviderProps = {
25
28
 
26
29
  const ThemeProvider = ({
27
30
  foundationTokens = FOUNDATION_THEME,
28
- componentTokens = {},
31
+ componentTokens = EMPTY_COMPONENT_TOKENS,
29
32
  breakpoints = BREAKPOINTS,
30
33
  theme = Theme.LIGHT,
31
34
  children,
32
35
  target,
33
36
  }: ThemeProviderProps) => {
34
- const defaultThemeContextValue = {
35
- foundationTokens,
36
- componentTokens: initTokens(componentTokens, foundationTokens, theme),
37
- breakpoints,
38
- theme,
39
- }
37
+ const resolvedComponentTokens = useMemo(
38
+ () => initTokens(componentTokens, foundationTokens, theme),
39
+ [componentTokens, foundationTokens, theme]
40
+ )
41
+
42
+ const themeContextValue = useMemo(
43
+ () => ({
44
+ foundationTokens,
45
+ componentTokens: resolvedComponentTokens,
46
+ breakpoints,
47
+ theme,
48
+ }),
49
+ [foundationTokens, resolvedComponentTokens, breakpoints, theme]
50
+ )
40
51
 
41
52
  const content = (
42
53
  <>
@@ -46,7 +57,7 @@ const ThemeProvider = ({
46
57
  )
47
58
 
48
59
  return (
49
- <ThemeContext.Provider value={defaultThemeContextValue}>
60
+ <ThemeContext.Provider value={themeContextValue}>
50
61
  {target ? (
51
62
  <ShadowAware target={target}>{content}</ShadowAware>
52
63
  ) : (
@@ -1,4 +1,4 @@
1
- import { useRef, useCallback } from 'react'
1
+ import { useRef, useCallback, useEffect } from 'react'
2
2
  export const useDebounce = <Args extends unknown[]>(
3
3
  fn: (...args: Args) => void,
4
4
  delay: number
@@ -15,5 +15,13 @@ export const useDebounce = <Args extends unknown[]>(
15
15
  [fn, delay]
16
16
  )
17
17
 
18
+ useEffect(() => {
19
+ return () => {
20
+ if (timeoutRef.current) {
21
+ clearTimeout(timeoutRef.current)
22
+ }
23
+ }
24
+ }, [])
25
+
18
26
  return debouncedFn
19
27
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@juspay/blend-design-system",
3
3
  "private": false,
4
- "version": "0.0.37-beta.4",
4
+ "version": "0.0.37-beta.5",
5
5
  "description": "A comprehensive React component library and design system by Juspay",
6
6
  "type": "module",
7
7
  "main": "./dist/main.js",