@@ -9,15 +9,19 @@ import {
99 AvatarImage ,
1010 Badge ,
1111 Breadcrumb ,
12+ BubbleChatClose ,
1213 BubbleChatPreview ,
1314 Button ,
15+ ButtonGroup ,
16+ ButtonGroupItem ,
1417 Card as CardIcon ,
1518 Checkbox ,
1619 ChevronDown ,
1720 Code ,
1821 Combobox ,
1922 Connections ,
2023 Copy ,
24+ DatePicker ,
2125 DocumentAttachment ,
2226 Duplicate ,
2327 Eye ,
@@ -29,6 +33,7 @@ import {
2933 Label ,
3034 Layout ,
3135 Library ,
36+ Loader ,
3237 Modal ,
3338 ModalBody ,
3439 ModalContent ,
@@ -69,10 +74,15 @@ import {
6974 Switch ,
7075 Table ,
7176 TableBody ,
77+ TableCaption ,
7278 TableCell ,
79+ TableFooter ,
7380 TableHead ,
7481 TableHeader ,
7582 TableRow ,
83+ Tag ,
84+ TagInput ,
85+ type TagItem ,
7686 Textarea ,
7787 TimePicker ,
7888 Tooltip ,
@@ -129,6 +139,14 @@ export default function PlaygroundPage() {
129139 const [ timeValue , setTimeValue ] = useState ( '09:30' )
130140 const [ activeTab , setActiveTab ] = useState ( 'profile' )
131141 const [ isDarkMode , setIsDarkMode ] = useState ( false )
142+ const [ buttonGroupValue , setButtonGroupValue ] = useState ( 'curl' )
143+ const [ dateValue , setDateValue ] = useState ( '' )
144+ const [ dateRangeStart , setDateRangeStart ] = useState ( '' )
145+ const [ dateRangeEnd , setDateRangeEnd ] = useState ( '' )
146+ const [ tagItems , setTagItems ] = useState < TagItem [ ] > ( [
147+ { value :
'[email protected] ' , isValid :
true } , 148+ { value : 'invalid-email' , isValid : false } ,
149+ ] )
132150
133151 const toggleDarkMode = ( ) => {
134152 setIsDarkMode ( ! isDarkMode )
@@ -208,6 +226,57 @@ export default function PlaygroundPage() {
208226 < VariantRow label = 'disabled' >
209227 < Button disabled > Disabled</ Button >
210228 </ VariantRow >
229+ < VariantRow label = 'size sm' >
230+ < Button size = 'sm' > Small</ Button >
231+ < Button size = 'sm' variant = 'primary' >
232+ Small Primary
233+ </ Button >
234+ </ VariantRow >
235+ < VariantRow label = 'size md' >
236+ < Button size = 'md' > Medium</ Button >
237+ < Button size = 'md' variant = 'primary' >
238+ Medium Primary
239+ </ Button >
240+ </ VariantRow >
241+ < VariantRow label = 'size branded' >
242+ < Button size = 'branded' variant = 'branded' className = 'branded-button-gradient' >
243+ Branded
244+ </ Button >
245+ </ VariantRow >
246+ </ Section >
247+
248+ { /* ButtonGroup */ }
249+ < Section title = 'ButtonGroup' >
250+ < VariantRow label = 'default' >
251+ < ButtonGroup value = { buttonGroupValue } onValueChange = { setButtonGroupValue } >
252+ < ButtonGroupItem value = 'curl' > cURL</ ButtonGroupItem >
253+ < ButtonGroupItem value = 'python' > Python</ ButtonGroupItem >
254+ < ButtonGroupItem value = 'javascript' > JavaScript</ ButtonGroupItem >
255+ </ ButtonGroup >
256+ </ VariantRow >
257+ < VariantRow label = 'gap none' >
258+ < ButtonGroup value = 'opt1' gap = 'none' >
259+ < ButtonGroupItem value = 'opt1' > Option 1</ ButtonGroupItem >
260+ < ButtonGroupItem value = 'opt2' > Option 2</ ButtonGroupItem >
261+ </ ButtonGroup >
262+ </ VariantRow >
263+ < VariantRow label = 'gap sm' >
264+ < ButtonGroup value = 'opt1' gap = 'sm' >
265+ < ButtonGroupItem value = 'opt1' > Option 1</ ButtonGroupItem >
266+ < ButtonGroupItem value = 'opt2' > Option 2</ ButtonGroupItem >
267+ </ ButtonGroup >
268+ </ VariantRow >
269+ < VariantRow label = 'disabled' >
270+ < ButtonGroup value = 'opt1' disabled >
271+ < ButtonGroupItem value = 'opt1' > Option 1</ ButtonGroupItem >
272+ < ButtonGroupItem value = 'opt2' > Option 2</ ButtonGroupItem >
273+ </ ButtonGroup >
274+ </ VariantRow >
275+ < VariantRow label = 'single item' >
276+ < ButtonGroup value = 'only' >
277+ < ButtonGroupItem value = 'only' > Only Option</ ButtonGroupItem >
278+ </ ButtonGroup >
279+ </ VariantRow >
211280 </ Section >
212281
213282 { /* Badge */ }
@@ -274,6 +343,46 @@ export default function PlaygroundPage() {
274343 </ VariantRow >
275344 </ Section >
276345
346+ { /* TagInput */ }
347+ < Section title = 'TagInput' >
348+ < VariantRow label = 'default' >
349+ < div className = 'w-80' >
350+ < TagInput
351+ items = { tagItems }
352+ onAdd = { ( value ) => {
353+ const isValid = value . includes ( '@' ) && value . includes ( '.' )
354+ setTagItems ( ( prev ) => [ ...prev , { value, isValid } ] )
355+ return isValid
356+ } }
357+ onRemove = { ( _ , index ) => {
358+ setTagItems ( ( prev ) => prev . filter ( ( _ , i ) => i !== index ) )
359+ } }
360+ placeholder = 'Enter emails...'
361+ placeholderWithTags = 'Add another'
362+ />
363+ </ div >
364+ </ VariantRow >
365+ < VariantRow label = 'tag variants' >
366+ < Tag value = '[email protected] ' variant = 'default' /> 367+ < Tag value = 'invalid-email' variant = 'invalid' />
368+ </ VariantRow >
369+ < VariantRow label = 'tag with remove' >
370+ < Tag value = '[email protected] ' variant = 'default' onRemove = { ( ) => { } } /> 371+ < Tag value = 'invalid-removable' variant = 'invalid' onRemove = { ( ) => { } } />
372+ </ VariantRow >
373+ < VariantRow label = 'disabled' >
374+ < div className = 'w-80' >
375+ < TagInput
376+ items = { [ { value :
'[email protected] ' , isValid :
true } ] } 377+ onAdd = { ( ) => false }
378+ onRemove = { ( ) => { } }
379+ placeholder = 'Disabled input'
380+ disabled
381+ />
382+ </ div >
383+ </ VariantRow >
384+ </ Section >
385+
277386 { /* Textarea */ }
278387 < Section title = 'Textarea' >
279388 < Textarea placeholder = 'Enter your message...' className = 'max-w-md' rows = { 4 } />
@@ -432,6 +541,53 @@ export default function PlaygroundPage() {
432541 </ TableBody >
433542 </ Table >
434543 </ VariantRow >
544+ < VariantRow label = 'with footer' >
545+ < Table className = 'max-w-md' >
546+ < TableHeader >
547+ < TableRow >
548+ < TableHead > Item</ TableHead >
549+ < TableHead className = 'text-right' > Price</ TableHead >
550+ </ TableRow >
551+ </ TableHeader >
552+ < TableBody >
553+ < TableRow >
554+ < TableCell > Product A</ TableCell >
555+ < TableCell className = 'text-right' > $10.00</ TableCell >
556+ </ TableRow >
557+ < TableRow >
558+ < TableCell > Product B</ TableCell >
559+ < TableCell className = 'text-right' > $20.00</ TableCell >
560+ </ TableRow >
561+ </ TableBody >
562+ < TableFooter >
563+ < TableRow >
564+ < TableCell > Total</ TableCell >
565+ < TableCell className = 'text-right' > $30.00</ TableCell >
566+ </ TableRow >
567+ </ TableFooter >
568+ </ Table >
569+ </ VariantRow >
570+ < VariantRow label = 'with caption' >
571+ < Table className = 'max-w-md' >
572+ < TableCaption > A list of team members</ TableCaption >
573+ < TableHeader >
574+ < TableRow >
575+ < TableHead > Name</ TableHead >
576+ < TableHead > Department</ TableHead >
577+ </ TableRow >
578+ </ TableHeader >
579+ < TableBody >
580+ < TableRow >
581+ < TableCell > Alice</ TableCell >
582+ < TableCell > Engineering</ TableCell >
583+ </ TableRow >
584+ < TableRow >
585+ < TableCell > Bob</ TableCell >
586+ < TableCell > Design</ TableCell >
587+ </ TableRow >
588+ </ TableBody >
589+ </ Table >
590+ </ VariantRow >
435591 </ Section >
436592
437593 { /* Combobox */ }
@@ -518,6 +674,43 @@ export default function PlaygroundPage() {
518674 </ VariantRow >
519675 </ Section >
520676
677+ { /* DatePicker */ }
678+ < Section title = 'DatePicker' >
679+ < VariantRow label = 'single date' >
680+ < div className = 'w-56' >
681+ < DatePicker value = { dateValue } onChange = { setDateValue } placeholder = 'Select date' />
682+ </ div >
683+ < span className = 'text-[var(--text-secondary)] text-sm' > { dateValue || 'No date' } </ span >
684+ </ VariantRow >
685+ < VariantRow label = 'size sm' >
686+ < div className = 'w-56' >
687+ < DatePicker placeholder = 'Small size' size = 'sm' onChange = { ( ) => { } } />
688+ </ div >
689+ </ VariantRow >
690+ < VariantRow label = 'range mode' >
691+ < div className = 'w-72' >
692+ < DatePicker
693+ mode = 'range'
694+ startDate = { dateRangeStart }
695+ endDate = { dateRangeEnd }
696+ onRangeChange = { ( start , end ) => {
697+ setDateRangeStart ( start )
698+ setDateRangeEnd ( end )
699+ } }
700+ placeholder = 'Select date range'
701+ />
702+ </ div >
703+ </ VariantRow >
704+ < VariantRow label = 'disabled' >
705+ < div className = 'w-56' >
706+ < DatePicker value = '2025-01-15' disabled />
707+ </ div >
708+ </ VariantRow >
709+ < VariantRow label = 'inline' >
710+ < DatePicker inline value = { dateValue } onChange = { setDateValue } />
711+ </ VariantRow >
712+ </ Section >
713+
521714 { /* Breadcrumb */ }
522715 < Section title = 'Breadcrumb' >
523716 < Breadcrumb
@@ -539,6 +732,26 @@ export default function PlaygroundPage() {
539732 < Tooltip . Content > Tooltip content</ Tooltip . Content >
540733 </ Tooltip . Root >
541734 </ VariantRow >
735+ < VariantRow label = 'with shortcut' >
736+ < Tooltip . Root >
737+ < Tooltip . Trigger asChild >
738+ < Button variant = 'default' > Clear console</ Button >
739+ </ Tooltip . Trigger >
740+ < Tooltip . Content >
741+ < Tooltip . Shortcut keys = '⌘D' > Clear console</ Tooltip . Shortcut >
742+ </ Tooltip . Content >
743+ </ Tooltip . Root >
744+ </ VariantRow >
745+ < VariantRow label = 'shortcut only' >
746+ < Tooltip . Root >
747+ < Tooltip . Trigger asChild >
748+ < Button variant = 'default' > Save</ Button >
749+ </ Tooltip . Trigger >
750+ < Tooltip . Content >
751+ < Tooltip . Shortcut keys = '⌘S' />
752+ </ Tooltip . Content >
753+ </ Tooltip . Root >
754+ </ VariantRow >
542755 </ Section >
543756
544757 { /* Popover */ }
@@ -760,6 +973,7 @@ export default function PlaygroundPage() {
760973 < Section title = 'Icons' >
761974 < div className = 'grid grid-cols-6 gap-4 sm:grid-cols-8 md:grid-cols-10' >
762975 { [
976+ { Icon : BubbleChatClose , name : 'BubbleChatClose' } ,
763977 { Icon : BubbleChatPreview , name : 'BubbleChatPreview' } ,
764978 { Icon : CardIcon , name : 'Card' } ,
765979 { Icon : ChevronDown , name : 'ChevronDown' } ,
@@ -774,6 +988,7 @@ export default function PlaygroundPage() {
774988 { Icon : KeyIcon , name : 'Key' } ,
775989 { Icon : Layout , name : 'Layout' } ,
776990 { Icon : Library , name : 'Library' } ,
991+ { Icon : Loader , name : 'Loader' } ,
777992 { Icon : MoreHorizontal , name : 'MoreHorizontal' } ,
778993 { Icon : NoWrap , name : 'NoWrap' } ,
779994 { Icon : PanelLeft , name : 'PanelLeft' } ,
0 commit comments