@connectycube/react-ui-kit 0.0.16 → 0.0.17

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 (38) hide show
  1. package/configs/dependencies.json +11 -3
  2. package/configs/imports.json +6 -2
  3. package/dist/index.cjs +4 -4
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.js +4 -4
  6. package/dist/index.js.map +1 -1
  7. package/dist/types/components/alert-dialog.d.ts.map +1 -1
  8. package/dist/types/components/badge.d.ts +11 -0
  9. package/dist/types/components/badge.d.ts.map +1 -0
  10. package/dist/types/components/button.d.ts +3 -5
  11. package/dist/types/components/button.d.ts.map +1 -1
  12. package/dist/types/components/input.d.ts +5 -0
  13. package/dist/types/components/input.d.ts.map +1 -0
  14. package/dist/types/components/search.d.ts +15 -0
  15. package/dist/types/components/search.d.ts.map +1 -0
  16. package/dist/types/components/spinner.d.ts +10 -0
  17. package/dist/types/components/spinner.d.ts.map +1 -0
  18. package/gen/components/alert-dialog.jsx +3 -1
  19. package/gen/components/badge.jsx +45 -0
  20. package/gen/components/button.jsx +4 -7
  21. package/gen/components/input.jsx +23 -0
  22. package/gen/components/search.jsx +75 -0
  23. package/gen/components/spinner.jsx +12 -0
  24. package/package.json +2 -2
  25. package/src/components/alert-dialog.tsx +3 -1
  26. package/src/components/avatar.tsx +1 -1
  27. package/src/components/badge.tsx +42 -0
  28. package/src/components/button.tsx +10 -12
  29. package/src/components/input.tsx +26 -0
  30. package/src/components/placeholder-text.tsx +1 -1
  31. package/src/components/search.tsx +86 -0
  32. package/src/components/spinner.tsx +16 -0
  33. package/src/components/stream-view.tsx +4 -4
  34. package/dist/tsconfig.tsbuildinfo +0 -1
  35. package/dist/types/components/animated-loader.d.ts +0 -10
  36. package/dist/types/components/animated-loader.d.ts.map +0 -1
  37. package/gen/components/animated-loader.jsx +0 -12
  38. package/src/components/animated-loader.tsx +0 -16
@@ -1 +1 @@
1
- {"version":3,"file":"alert-dialog.d.ts","sourceRoot":"","sources":["../../../src/components/alert-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,oBAAoB,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAGpD,UAAU,gBAAiB,SAAQ,oBAAoB,CAAC,gBAAgB;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,oBAAoB,CAAC,gBAAgB,CAAC;IAClD,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC;IACnC,YAAY,CAAC,EAAE,oBAAoB,CAAC,uBAAuB,CAAC;IAC5D,WAAW,CAAC,EAAE,oBAAoB,CAAC,sBAAsB,CAAC;IAC1D,YAAY,CAAC,EAAE,oBAAoB,CAAC,uBAAuB,CAAC;IAC5D,YAAY,CAAC,EAAE,oBAAoB,CAAC,uBAAuB,CAAC;IAC5D,WAAW,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,oBAAoB,CAAC,qBAAqB,CAAC;IACxD,gBAAgB,CAAC,EAAE,oBAAoB,CAAC,2BAA2B,CAAC;IACpE,WAAW,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,oBAAoB,CAAC,sBAAsB,CAAC;IAC1D,iBAAiB,CAAC,EAAE,WAAW,CAAC;IAChC,WAAW,CAAC,EAAE,oBAAoB,CAAC,sBAAsB,CAAC;IAC1D,iBAAiB,CAAC,EAAE,WAAW,CAAC;CACjC;AAoFD,QAAA,MAAM,WAAW,yFAAgE,CAAC;AAIlF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"alert-dialog.d.ts","sourceRoot":"","sources":["../../../src/components/alert-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,oBAAoB,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAGpD,UAAU,gBAAiB,SAAQ,oBAAoB,CAAC,gBAAgB;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,oBAAoB,CAAC,gBAAgB,CAAC;IAClD,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC;IACnC,YAAY,CAAC,EAAE,oBAAoB,CAAC,uBAAuB,CAAC;IAC5D,WAAW,CAAC,EAAE,oBAAoB,CAAC,sBAAsB,CAAC;IAC1D,YAAY,CAAC,EAAE,oBAAoB,CAAC,uBAAuB,CAAC;IAC5D,YAAY,CAAC,EAAE,oBAAoB,CAAC,uBAAuB,CAAC;IAC5D,WAAW,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,oBAAoB,CAAC,qBAAqB,CAAC;IACxD,gBAAgB,CAAC,EAAE,oBAAoB,CAAC,2BAA2B,CAAC;IACpE,WAAW,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,oBAAoB,CAAC,sBAAsB,CAAC;IAC1D,iBAAiB,CAAC,EAAE,WAAW,CAAC;IAChC,WAAW,CAAC,EAAE,oBAAoB,CAAC,sBAAsB,CAAC;IAC1D,iBAAiB,CAAC,EAAE,WAAW,CAAC;CACjC;AAsFD,QAAA,MAAM,WAAW,yFAAgE,CAAC;AAIlF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type React from 'react';
2
+ import { type VariantProps } from 'class-variance-authority';
3
+ interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
4
+ asChild?: boolean;
5
+ }
6
+ declare const badgeVariants: (props?: ({
7
+ variant?: "default" | "destructive" | "outline" | "secondary" | null | undefined;
8
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
9
+ declare const Badge: React.ForwardRefExoticComponent<BadgeProps & React.RefAttributes<HTMLSpanElement>>;
10
+ export { Badge, type BadgeProps };
11
+ //# sourceMappingURL=badge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../src/components/badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGlE,UAAU,UAAW,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,YAAY,CAAC,OAAO,aAAa,CAAC;IACnG,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,QAAA,MAAM,aAAa;;mFAgBlB,CAAC;AAWF,QAAA,MAAM,KAAK,oFAAqD,CAAC;AAIjE,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,CAAC"}
@@ -1,14 +1,12 @@
1
1
  import type React from 'react';
2
2
  import { type VariantProps } from 'class-variance-authority';
3
+ interface ButtonProps extends React.ComponentProps<'button'>, VariantProps<typeof buttonVariants> {
4
+ asChild?: boolean;
5
+ }
3
6
  declare const buttonVariants: (props?: ({
4
7
  variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
5
8
  size?: "default" | "sm" | "lg" | "icon" | null | undefined;
6
9
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
7
- interface ButtonProps extends React.ComponentProps<'button'>, VariantProps<typeof buttonVariants> {
8
- asChild?: boolean;
9
- leftElement?: React.ReactElement;
10
- rightElement?: React.ReactElement;
11
- }
12
10
  declare const Button: React.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
13
11
  export { Button, type ButtonProps };
14
12
  //# sourceMappingURL=button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGlE,QAAA,MAAM,cAAc;;;mFA0BnB,CAAC;AAEF,UAAU,WAAY,SAAQ,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC,OAAO,cAAc,CAAC;IAC/F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC;IACjC,YAAY,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC;CACnC;AAiBD,QAAA,MAAM,MAAM,oGAAyD,CAAC;AAItE,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGlE,UAAU,WAAY,SAAQ,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC,OAAO,cAAc,CAAC;IAC/F,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,QAAA,MAAM,cAAc;;;mFA0BnB,CAAC;AAiBF,QAAA,MAAM,MAAM,oGAAyD,CAAC;AAItE,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type React from 'react';
2
+ type InputProps = React.ComponentProps<'input'>;
3
+ declare const Input: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref"> & React.RefAttributes<HTMLInputElement>>;
4
+ export { Input, type InputProps };
5
+ //# sourceMappingURL=input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/components/input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,KAAK,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;AAiBhD,QAAA,MAAM,KAAK,8KAAwB,CAAC;AAIpC,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type React from 'react';
2
+ import { type InputProps } from './input';
3
+ import { type LucideProps } from 'lucide-react';
4
+ interface SearchProps extends InputProps {
5
+ onSearch?: (value: string) => void;
6
+ onCancel?: () => void;
7
+ hasSearchIcon?: boolean;
8
+ hasCancelIcon?: boolean;
9
+ searchIconProps?: LucideProps;
10
+ cancelIconProps?: LucideProps;
11
+ containerProps?: React.ComponentProps<'div'>;
12
+ }
13
+ declare const Search: React.ForwardRefExoticComponent<Omit<SearchProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
14
+ export { Search, type SearchProps };
15
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/components/search.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtF,UAAU,WAAY,SAAQ,UAAU;IACtC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,WAAW,CAAC;IAC9B,eAAe,CAAC,EAAE,WAAW,CAAC;IAC9B,cAAc,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;CAC9C;AAmED,QAAA,MAAM,MAAM,mGAAwD,CAAC;AAIrE,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type LucideProps } from 'lucide-react';
2
+ interface SpinnerProps extends LucideProps {
3
+ loading?: boolean;
4
+ }
5
+ declare function Spinner({ loading, ...props }: SpinnerProps): import("react/jsx-runtime").JSX.Element | null;
6
+ declare namespace Spinner {
7
+ var displayName: string;
8
+ }
9
+ export { Spinner, type SpinnerProps };
10
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../../src/components/spinner.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAG9D,UAAU,YAAa,SAAQ,WAAW;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,iBAAS,OAAO,CAAC,EAAE,OAAc,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,kDAI1D;kBAJQ,OAAO;;;AAQhB,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,CAAC"}
@@ -72,7 +72,9 @@ function AlertDialogBase(
72
72
  className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', footerProps?.className)}
73
73
  >
74
74
  <AlertDialogPrimitive.Cancel {...cancelProps} onClick={onCancel}>
75
- <Button {...cancelButtonProps}>{cancelTitle}</Button>
75
+ <Button variant="outline" {...cancelButtonProps}>
76
+ {cancelTitle}
77
+ </Button>
76
78
  </AlertDialogPrimitive.Cancel>
77
79
  <AlertDialogPrimitive.Action {...actionProps} onClick={onConfirm}>
78
80
  <Button {...actionButtonProps}>{actionTitle}</Button>
@@ -0,0 +1,45 @@
1
+ import { forwardRef } from 'react';
2
+ import * as SlotPrimitive from '@radix-ui/react-slot';
3
+ import { cva } from 'class-variance-authority';
4
+ import { cn } from './utils';
5
+
6
+ const badgeVariants = cva(
7
+ 'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
12
+ secondary: 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
13
+ destructive:
14
+ 'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
15
+ outline: 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
16
+ },
17
+ },
18
+ defaultVariants: {
19
+ variant: 'default',
20
+ },
21
+ }
22
+ );
23
+
24
+ function BadgeBase({ className, variant, asChild = false, ...props }, ref) {
25
+ const Comp = asChild ? SlotPrimitive.Root : 'span';
26
+
27
+ return (
28
+ <Comp
29
+ ref={ref}
30
+ className={cn(
31
+ badgeVariants({
32
+ variant,
33
+ }),
34
+ className
35
+ )}
36
+ {...props}
37
+ />
38
+ );
39
+ }
40
+
41
+ const Badge = forwardRef(BadgeBase);
42
+
43
+ Badge.displayName = 'Badge';
44
+
45
+ export { Badge };
@@ -31,7 +31,7 @@ const buttonVariants = cva(
31
31
  }
32
32
  );
33
33
 
34
- function ButtonBase({ asChild = false, variant, size, className, leftElement, rightElement, children, ...props }, ref) {
34
+ function ButtonBase({ asChild = false, variant, size, className, ...props }, ref) {
35
35
  const Comp = asChild ? SlotPrimitive.Root : 'button';
36
36
 
37
37
  return (
@@ -43,13 +43,10 @@ function ButtonBase({ asChild = false, variant, size, className, leftElement, ri
43
43
  variant,
44
44
  size,
45
45
  className,
46
- })
46
+ }),
47
+ 'transition-all ease-in-out duration-300'
47
48
  )}
48
- >
49
- {leftElement}
50
- <SlotPrimitive.Slottable>{children}</SlotPrimitive.Slottable>
51
- {rightElement}
52
- </Comp>
49
+ />
53
50
  );
54
51
  }
55
52
 
@@ -0,0 +1,23 @@
1
+ import { forwardRef } from 'react';
2
+ import { cn } from './utils';
3
+
4
+ function InputBase(props, ref) {
5
+ return (
6
+ <input
7
+ ref={ref}
8
+ {...props}
9
+ className={cn(
10
+ 'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-10 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
11
+ 'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring',
12
+ 'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
13
+ props?.className
14
+ )}
15
+ />
16
+ );
17
+ }
18
+
19
+ const Input = forwardRef(InputBase);
20
+
21
+ Input.displayName = 'Input';
22
+
23
+ export { Input };
@@ -0,0 +1,75 @@
1
+ import { forwardRef, useState } from 'react';
2
+ import { cn } from './utils';
3
+ import { Input } from './input';
4
+ import { Search as SearchIcon, X as CloseIcon } from 'lucide-react';
5
+
6
+ function SearchBase(
7
+ {
8
+ onSearch = () => {},
9
+ onCancel = () => {},
10
+ hasSearchIcon = true,
11
+ hasCancelIcon = true,
12
+ searchIconProps,
13
+ cancelIconProps,
14
+ containerProps,
15
+ ...props
16
+ },
17
+ ref
18
+ ) {
19
+ const [value, setValue] = useState('');
20
+ const handleOnSearch = (e) => {
21
+ const keyword = e.target.value;
22
+
23
+ setValue(keyword);
24
+ onSearch(keyword.toLowerCase());
25
+ };
26
+ const handleOnCancel = () => {
27
+ setValue('');
28
+ onCancel();
29
+ };
30
+
31
+ return (
32
+ <div {...containerProps} className={cn('group relative', containerProps?.className)}>
33
+ {hasSearchIcon && (
34
+ <SearchIcon
35
+ {...searchIconProps}
36
+ className={cn(
37
+ 'absolute top-1/2 left-2 transform -translate-y-1/2 size-5 text-muted-foreground group-focus-within:text-ring',
38
+ searchIconProps?.className
39
+ )}
40
+ />
41
+ )}
42
+ <Input
43
+ ref={ref}
44
+ name="search"
45
+ placeholder={props?.placeholder || 'Search...'}
46
+ value={value}
47
+ onChange={handleOnSearch}
48
+ {...props}
49
+ className={cn(
50
+ 'placeholder:text-muted-foreground focus-visible:ring-ring/50 focus-visible:ring flex',
51
+ hasSearchIcon ? 'pl-10' : 'pl-3',
52
+ hasCancelIcon ? 'pr-10' : 'pr-3',
53
+ props?.className
54
+ )}
55
+ />
56
+ {hasCancelIcon && (
57
+ <CloseIcon
58
+ onClick={handleOnCancel}
59
+ {...cancelIconProps}
60
+ className={cn(
61
+ 'absolute top-1/2 right-2 transform -translate-y-1/2 size-5 text-muted-foreground cursor-pointer hover:text-ring transition-all duration-300 ease-in-out',
62
+ value.length > 0 ? 'opacity-100 scale-100' : 'opacity-0 scale-75 pointer-events-none',
63
+ cancelIconProps?.className
64
+ )}
65
+ />
66
+ )}
67
+ </div>
68
+ );
69
+ }
70
+
71
+ const Search = forwardRef(SearchBase);
72
+
73
+ Search.displayName = 'Search';
74
+
75
+ export { Search };
@@ -0,0 +1,12 @@
1
+ import { LoaderCircle } from 'lucide-react';
2
+ import { cn } from './utils';
3
+
4
+ function Spinner({ loading = true, ...props }) {
5
+ return loading ? (
6
+ <LoaderCircle strokeWidth={2.5} {...props} className={cn('animate-spin mx-auto text-ring', props?.className)} />
7
+ ) : null;
8
+ }
9
+
10
+ Spinner.displayName = 'Spinner';
11
+
12
+ export { Spinner };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@connectycube/react-ui-kit",
3
- "version": "0.0.16",
3
+ "version": "0.0.17",
4
4
  "description": "Simple React UI Kit generator with TSX/JSX",
5
5
  "homepage": "https://github.com/ConnectyCube/react-ui-kit#readme",
6
6
  "bugs": {
@@ -70,7 +70,7 @@
70
70
  "clsx": "^2.1.1",
71
71
  "execa": "^9.6.0",
72
72
  "fs-extra": "^11.3.2",
73
- "lucide-react": "^0.554.0",
73
+ "lucide-react": "^0.555.0",
74
74
  "prompts": "^2.4.2",
75
75
  "tailwind-merge": "^3.4.0"
76
76
  },
@@ -96,7 +96,9 @@ function AlertDialogBase(
96
96
  className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', footerProps?.className)}
97
97
  >
98
98
  <AlertDialogPrimitive.Cancel {...cancelProps} onClick={onCancel}>
99
- <Button {...cancelButtonProps}>{cancelTitle}</Button>
99
+ <Button variant="outline" {...cancelButtonProps}>
100
+ {cancelTitle}
101
+ </Button>
100
102
  </AlertDialogPrimitive.Cancel>
101
103
  <AlertDialogPrimitive.Action {...actionProps} onClick={onConfirm}>
102
104
  <Button {...actionButtonProps}>{actionTitle}</Button>
@@ -28,7 +28,7 @@ function AvatarBase(
28
28
  fallbackProps,
29
29
  ...props
30
30
  }: AvatarProps,
31
- ref: React.Ref<HTMLDivElement>
31
+ ref: React.ForwardedRef<HTMLDivElement>
32
32
  ) {
33
33
  const initials = getInitialsFromName(name);
34
34
 
@@ -0,0 +1,42 @@
1
+ import type React from 'react';
2
+ import { forwardRef } from 'react';
3
+ import * as SlotPrimitive from '@radix-ui/react-slot';
4
+ import { cva, type VariantProps } from 'class-variance-authority';
5
+ import { cn } from './utils';
6
+
7
+ interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
8
+ asChild?: boolean;
9
+ }
10
+
11
+ const badgeVariants = cva(
12
+ 'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
13
+ {
14
+ variants: {
15
+ variant: {
16
+ default: 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
17
+ secondary: 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
18
+ destructive:
19
+ 'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
20
+ outline: 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
21
+ },
22
+ },
23
+ defaultVariants: {
24
+ variant: 'default',
25
+ },
26
+ }
27
+ );
28
+
29
+ function BadgeBase(
30
+ { className, variant, asChild = false, ...props }: BadgeProps,
31
+ ref?: React.ForwardedRef<HTMLSpanElement>
32
+ ) {
33
+ const Comp = asChild ? SlotPrimitive.Root : 'span';
34
+
35
+ return <Comp ref={ref} className={cn(badgeVariants({ variant }), className)} {...props} />;
36
+ }
37
+
38
+ const Badge = forwardRef<HTMLSpanElement, BadgeProps>(BadgeBase);
39
+
40
+ Badge.displayName = 'Badge';
41
+
42
+ export { Badge, type BadgeProps };
@@ -4,6 +4,10 @@ import * as SlotPrimitive from '@radix-ui/react-slot';
4
4
  import { cva, type VariantProps } from 'class-variance-authority';
5
5
  import { cn } from './utils';
6
6
 
7
+ interface ButtonProps extends React.ComponentProps<'button'>, VariantProps<typeof buttonVariants> {
8
+ asChild?: boolean;
9
+ }
10
+
7
11
  const buttonVariants = cva(
8
12
  'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
9
13
  {
@@ -32,24 +36,18 @@ const buttonVariants = cva(
32
36
  }
33
37
  );
34
38
 
35
- interface ButtonProps extends React.ComponentProps<'button'>, VariantProps<typeof buttonVariants> {
36
- asChild?: boolean;
37
- leftElement?: React.ReactElement;
38
- rightElement?: React.ReactElement;
39
- }
40
-
41
39
  function ButtonBase(
42
- { asChild = false, variant, size, className, leftElement, rightElement, children, ...props }: ButtonProps,
40
+ { asChild = false, variant, size, className, ...props }: ButtonProps,
43
41
  ref?: React.ForwardedRef<HTMLButtonElement>
44
42
  ) {
45
43
  const Comp = asChild ? SlotPrimitive.Root : 'button';
46
44
 
47
45
  return (
48
- <Comp ref={ref} {...props} className={cn(buttonVariants({ variant, size, className }))}>
49
- {leftElement}
50
- <SlotPrimitive.Slottable>{children}</SlotPrimitive.Slottable>
51
- {rightElement}
52
- </Comp>
46
+ <Comp
47
+ ref={ref}
48
+ {...props}
49
+ className={cn(buttonVariants({ variant, size, className }), 'transition-all ease-in-out duration-300')}
50
+ />
53
51
  );
54
52
  }
55
53
 
@@ -0,0 +1,26 @@
1
+ import type React from 'react';
2
+ import { forwardRef } from 'react';
3
+ import { cn } from './utils';
4
+
5
+ type InputProps = React.ComponentProps<'input'>;
6
+
7
+ function InputBase(props: InputProps, ref?: React.ForwardedRef<HTMLInputElement>) {
8
+ return (
9
+ <input
10
+ ref={ref}
11
+ {...props}
12
+ className={cn(
13
+ 'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-10 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
14
+ 'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring',
15
+ 'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
16
+ props?.className
17
+ )}
18
+ />
19
+ );
20
+ }
21
+
22
+ const Input = forwardRef(InputBase);
23
+
24
+ Input.displayName = 'Input';
25
+
26
+ export { Input, type InputProps };
@@ -10,7 +10,7 @@ interface PlaceholderTextProps extends React.ComponentProps<'div'> {
10
10
 
11
11
  function PlaceholderTextBase(
12
12
  { title, titles = [], rowProps, ...props }: PlaceholderTextProps,
13
- ref: React.Ref<HTMLDivElement>
13
+ ref: React.ForwardedRef<HTMLDivElement>
14
14
  ) {
15
15
  const rows = typeof title === 'string' ? [title, ...titles] : titles;
16
16
 
@@ -0,0 +1,86 @@
1
+ import type React from 'react';
2
+ import { forwardRef, useState } from 'react';
3
+ import { cn } from './utils';
4
+ import { Input, type InputProps } from './input';
5
+ import { Search as SearchIcon, X as CloseIcon, type LucideProps } from 'lucide-react';
6
+
7
+ interface SearchProps extends InputProps {
8
+ onSearch?: (value: string) => void;
9
+ onCancel?: () => void;
10
+ hasSearchIcon?: boolean;
11
+ hasCancelIcon?: boolean;
12
+ searchIconProps?: LucideProps;
13
+ cancelIconProps?: LucideProps;
14
+ containerProps?: React.ComponentProps<'div'>;
15
+ }
16
+
17
+ function SearchBase(
18
+ {
19
+ onSearch = () => {},
20
+ onCancel = () => {},
21
+ hasSearchIcon = true,
22
+ hasCancelIcon = true,
23
+ searchIconProps,
24
+ cancelIconProps,
25
+ containerProps,
26
+ ...props
27
+ }: SearchProps,
28
+ ref?: React.ForwardedRef<HTMLInputElement>
29
+ ) {
30
+ const [value, setValue] = useState<string>('');
31
+ const handleOnSearch = (e: React.ChangeEvent<HTMLInputElement>): void => {
32
+ const keyword = e.target.value;
33
+
34
+ setValue(keyword);
35
+ onSearch(keyword.toLowerCase());
36
+ };
37
+ const handleOnCancel = (): void => {
38
+ setValue('');
39
+ onCancel();
40
+ };
41
+
42
+ return (
43
+ <div {...containerProps} className={cn('group relative', containerProps?.className)}>
44
+ {hasSearchIcon && (
45
+ <SearchIcon
46
+ {...searchIconProps}
47
+ className={cn(
48
+ 'absolute top-1/2 left-2 transform -translate-y-1/2 size-5 text-muted-foreground group-focus-within:text-ring',
49
+ searchIconProps?.className
50
+ )}
51
+ />
52
+ )}
53
+ <Input
54
+ ref={ref}
55
+ name="search"
56
+ placeholder={props?.placeholder || 'Search...'}
57
+ value={value}
58
+ onChange={handleOnSearch}
59
+ {...props}
60
+ className={cn(
61
+ 'placeholder:text-muted-foreground focus-visible:ring-ring/50 focus-visible:ring flex',
62
+ hasSearchIcon ? 'pl-10' : 'pl-3',
63
+ hasCancelIcon ? 'pr-10' : 'pr-3',
64
+ props?.className
65
+ )}
66
+ />
67
+ {hasCancelIcon && (
68
+ <CloseIcon
69
+ onClick={handleOnCancel}
70
+ {...cancelIconProps}
71
+ className={cn(
72
+ 'absolute top-1/2 right-2 transform -translate-y-1/2 size-5 text-muted-foreground cursor-pointer hover:text-ring transition-all duration-300 ease-in-out',
73
+ value.length > 0 ? 'opacity-100 scale-100' : 'opacity-0 scale-75 pointer-events-none',
74
+ cancelIconProps?.className
75
+ )}
76
+ />
77
+ )}
78
+ </div>
79
+ );
80
+ }
81
+
82
+ const Search = forwardRef<HTMLInputElement, SearchProps>(SearchBase);
83
+
84
+ Search.displayName = 'Search';
85
+
86
+ export { Search, type SearchProps };
@@ -0,0 +1,16 @@
1
+ import { LoaderCircle, type LucideProps } from 'lucide-react';
2
+ import { cn } from './utils';
3
+
4
+ interface SpinnerProps extends LucideProps {
5
+ loading?: boolean;
6
+ }
7
+
8
+ function Spinner({ loading = true, ...props }: SpinnerProps) {
9
+ return loading ? (
10
+ <LoaderCircle strokeWidth={2.5} {...props} className={cn('animate-spin mx-auto text-ring', props?.className)} />
11
+ ) : null;
12
+ }
13
+
14
+ Spinner.displayName = 'Spinner';
15
+
16
+ export { Spinner, type SpinnerProps };
@@ -10,7 +10,7 @@ interface StreamViewProps extends React.ComponentProps<'video'> {
10
10
 
11
11
  function StreamViewBase(
12
12
  { id, stream, mirror, className, muted, ...props }: StreamViewProps,
13
- ref: React.Ref<HTMLVideoElement>
13
+ ref: React.ForwardedRef<HTMLVideoElement>
14
14
  ) {
15
15
  const innerRef = useRef<HTMLVideoElement>(null);
16
16
  const elementId = useMemo(() => id ?? `stream-${getRandomString()}`, [id]);
@@ -57,7 +57,7 @@ const StreamView = forwardRef<HTMLVideoElement, StreamViewProps>(StreamViewBase)
57
57
 
58
58
  StreamView.displayName = 'StreamView';
59
59
 
60
- function LocalStreamViewBase({ muted, mirror, ...props }: StreamViewProps, ref: React.Ref<HTMLVideoElement>) {
60
+ function LocalStreamViewBase({ muted, mirror, ...props }: StreamViewProps, ref: React.ForwardedRef<HTMLVideoElement>) {
61
61
  const isMuted = typeof muted === 'boolean' ? muted : true;
62
62
  const isMirror = typeof mirror === 'boolean' ? mirror : true;
63
63
 
@@ -68,7 +68,7 @@ const LocalStreamView = forwardRef<HTMLVideoElement, StreamViewProps>(LocalStrea
68
68
 
69
69
  LocalStreamView.displayName = 'LocalStreamView';
70
70
 
71
- function RemoteStreamViewBase({ muted, mirror, ...props }: StreamViewProps, ref: React.Ref<HTMLVideoElement>) {
71
+ function RemoteStreamViewBase({ muted, mirror, ...props }: StreamViewProps, ref: React.ForwardedRef<HTMLVideoElement>) {
72
72
  const isMuted = typeof muted === 'boolean' ? muted : false;
73
73
  const isMirror = typeof mirror === 'boolean' ? mirror : false;
74
74
 
@@ -114,7 +114,7 @@ function FullscreenStreamViewBase(
114
114
  pipButtonIconProps,
115
115
  ...props
116
116
  }: FullscreenStreamViewProps,
117
- ref: React.Ref<FullscreenStreamViewRef>
117
+ ref: React.ForwardedRef<FullscreenStreamViewRef>
118
118
  ) {
119
119
  const innerRef = useRef<HTMLDivElement>(null);
120
120
  const [isFullscreen, setIsFullscreen] = useState<boolean>(false);