@firecms/ui 3.0.0-canary.15 → 3.0.0-canary.151

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 (110) hide show
  1. package/README.md +3 -3
  2. package/dist/components/Avatar.d.ts +1 -0
  3. package/dist/components/BooleanSwitch.d.ts +1 -1
  4. package/dist/components/BooleanSwitchWithLabel.d.ts +4 -1
  5. package/dist/components/Button.d.ts +1 -1
  6. package/dist/components/CenteredView.d.ts +4 -2
  7. package/dist/components/Checkbox.d.ts +3 -2
  8. package/dist/components/Chip.d.ts +3 -2
  9. package/dist/components/DateTimeField.d.ts +5 -7
  10. package/dist/components/Dialog.d.ts +4 -1
  11. package/dist/components/DialogTitle.d.ts +9 -0
  12. package/dist/components/ExpandablePanel.d.ts +2 -1
  13. package/dist/components/FileUpload.d.ts +1 -1
  14. package/dist/components/InputLabel.d.ts +2 -2
  15. package/dist/components/Label.d.ts +4 -1
  16. package/dist/components/Markdown.d.ts +1 -0
  17. package/dist/components/Menu.d.ts +6 -2
  18. package/dist/components/Menubar.d.ts +79 -0
  19. package/dist/components/MultiSelect.d.ts +32 -16
  20. package/dist/components/Popover.d.ts +2 -1
  21. package/dist/components/RadioGroup.d.ts +26 -3
  22. package/dist/components/Select.d.ts +6 -10
  23. package/dist/components/Separator.d.ts +2 -1
  24. package/dist/components/Sheet.d.ts +6 -0
  25. package/dist/components/Slider.d.ts +21 -0
  26. package/dist/components/Table.d.ts +10 -10
  27. package/dist/components/Tabs.d.ts +4 -2
  28. package/dist/components/TextField.d.ts +1 -1
  29. package/dist/components/TextareaAutosize.d.ts +3 -34
  30. package/dist/components/Tooltip.d.ts +6 -2
  31. package/dist/components/Typography.d.ts +5 -4
  32. package/dist/components/index.d.ts +3 -1
  33. package/dist/hooks/index.d.ts +3 -0
  34. package/dist/icons/Icon.d.ts +3 -3
  35. package/dist/index.css +73 -0
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.es.js +13410 -14466
  38. package/dist/index.es.js.map +1 -1
  39. package/dist/index.umd.js +19802 -857
  40. package/dist/index.umd.js.map +1 -1
  41. package/dist/styles.d.ts +9 -9
  42. package/dist/util/{cn.d.ts → cls.d.ts} +4 -0
  43. package/dist/util/index.d.ts +1 -3
  44. package/package.json +112 -118
  45. package/src/components/Alert.tsx +4 -4
  46. package/src/components/Autocomplete.tsx +7 -5
  47. package/src/components/Avatar.tsx +40 -26
  48. package/src/components/Badge.tsx +2 -2
  49. package/src/components/BooleanSwitch.tsx +19 -19
  50. package/src/components/BooleanSwitchWithLabel.tsx +20 -11
  51. package/src/components/Button.tsx +30 -23
  52. package/src/components/Card.tsx +4 -3
  53. package/src/components/CenteredView.tsx +25 -15
  54. package/src/components/Checkbox.tsx +16 -14
  55. package/src/components/Chip.tsx +10 -7
  56. package/src/components/CircularProgress.tsx +3 -3
  57. package/src/components/Collapse.tsx +4 -2
  58. package/src/components/Container.tsx +2 -2
  59. package/src/components/DateTimeField.tsx +142 -921
  60. package/src/components/DebouncedTextField.tsx +1 -0
  61. package/src/components/Dialog.tsx +17 -7
  62. package/src/components/DialogActions.tsx +3 -3
  63. package/src/components/DialogContent.tsx +2 -2
  64. package/src/components/DialogTitle.tsx +35 -0
  65. package/src/components/ExpandablePanel.tsx +20 -12
  66. package/src/components/FileUpload.tsx +8 -10
  67. package/src/components/IconButton.tsx +6 -10
  68. package/src/components/InfoLabel.tsx +2 -2
  69. package/src/components/InputLabel.tsx +11 -9
  70. package/src/components/Label.tsx +17 -4
  71. package/src/components/Markdown.tsx +15 -3
  72. package/src/components/Menu.tsx +49 -31
  73. package/src/components/Menubar.tsx +322 -0
  74. package/src/components/MultiSelect.tsx +341 -167
  75. package/src/components/Paper.tsx +2 -2
  76. package/src/components/Popover.tsx +19 -15
  77. package/src/components/RadioGroup.tsx +41 -9
  78. package/src/components/SearchBar.tsx +12 -11
  79. package/src/components/Select.tsx +99 -126
  80. package/src/components/Separator.tsx +10 -4
  81. package/src/components/Sheet.tsx +53 -31
  82. package/src/components/Skeleton.tsx +9 -6
  83. package/src/components/Slider.tsx +109 -0
  84. package/src/components/Table.tsx +52 -35
  85. package/src/components/Tabs.tsx +19 -15
  86. package/src/components/TextField.tsx +16 -18
  87. package/src/components/TextareaAutosize.tsx +4 -3
  88. package/src/components/Tooltip.tsx +33 -16
  89. package/src/components/Typography.tsx +42 -26
  90. package/src/components/common/SelectInputLabel.tsx +3 -3
  91. package/src/components/index.tsx +3 -1
  92. package/src/hooks/index.ts +3 -0
  93. package/src/icons/Icon.tsx +46 -43
  94. package/src/icons/icon_keys.ts +114 -1301
  95. package/src/index.css +73 -0
  96. package/src/index.ts +1 -0
  97. package/src/scripts/generateIconKeys.ts +20 -11
  98. package/src/styles.ts +9 -9
  99. package/src/util/cls.ts +14 -0
  100. package/src/util/index.ts +1 -3
  101. package/tailwind.config.js +42 -26
  102. package/dist/components/Spinner.d.ts +0 -1
  103. package/src/components/Spinner.tsx +0 -18
  104. package/src/util/cn.ts +0 -6
  105. /package/dist/{util → hooks}/useDebounceValue.d.ts +0 -0
  106. /package/dist/{util → hooks}/useInjectStyles.d.ts +0 -0
  107. /package/dist/{util → hooks}/useOutsideAlerter.d.ts +0 -0
  108. /package/src/{util → hooks}/useDebounceValue.tsx +0 -0
  109. /package/src/{util → hooks}/useInjectStyles.tsx +0 -0
  110. /package/src/{util → hooks}/useOutsideAlerter.tsx +0 -0
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import React, { ChangeEvent, useCallback, useDeferredValue, useEffect } from "react";
2
3
  import { TextField, TextFieldProps } from "./index";
3
4
 
@@ -1,7 +1,8 @@
1
+ "use client";
1
2
  import React, { useEffect, useState } from "react";
2
3
  import * as DialogPrimitive from "@radix-ui/react-dialog";
3
4
  import { paperMixin } from "../styles";
4
- import { cn } from "../util";
5
+ import { cls } from "../util";
5
6
 
6
7
  export type DialogProps = {
7
8
  open?: boolean;
@@ -15,6 +16,9 @@ export type DialogProps = {
15
16
  maxWidth?: keyof typeof widthClasses;
16
17
  modal?: boolean;
17
18
  onOpenAutoFocus?: (e: Event) => void;
19
+ onEscapeKeyDown?: (e: KeyboardEvent) => void;
20
+ onPointerDownOutside?: (e: Event) => void;
21
+ onInteractOutside?: (e: Event) => void;
18
22
  };
19
23
 
20
24
  const widthClasses = {
@@ -43,7 +47,10 @@ export const Dialog = ({
43
47
  scrollable = true,
44
48
  maxWidth = "lg",
45
49
  modal = true,
46
- onOpenAutoFocus
50
+ onOpenAutoFocus,
51
+ onEscapeKeyDown,
52
+ onPointerDownOutside,
53
+ onInteractOutside
47
54
  }: DialogProps) => {
48
55
  const [displayed, setDisplayed] = useState(false);
49
56
 
@@ -51,7 +58,7 @@ export const Dialog = ({
51
58
  if (!open) {
52
59
  const timeout = setTimeout(() => {
53
60
  setDisplayed(false);
54
- }, 250);
61
+ }, 150);
55
62
  return () => clearTimeout(timeout);
56
63
  } else {
57
64
  setDisplayed(true);
@@ -69,7 +76,7 @@ export const Dialog = ({
69
76
  <div className={"fixed inset-0 z-30"}>
70
77
 
71
78
  <DialogPrimitive.Overlay
72
- className={cn("fixed inset-0 transition-opacity z-20 ease-in-out duration-200 bg-black bg-opacity-50 dark:bg-opacity-60 backdrop-blur-sm ",
79
+ className={cls("fixed inset-0 transition-opacity z-20 ease-in-out duration-200 bg-black bg-opacity-50 dark:bg-opacity-60 backdrop-blur-sm ",
73
80
  displayed && open ? "opacity-100" : "opacity-0",
74
81
  "z-20 fixed top-0 left-0 w-full h-full flex justify-center items-center"
75
82
  )}
@@ -79,17 +86,20 @@ export const Dialog = ({
79
86
  />
80
87
 
81
88
  <DialogPrimitive.Content
89
+ onEscapeKeyDown={onEscapeKeyDown}
82
90
  onOpenAutoFocus={onOpenAutoFocus}
83
- className={cn("h-full outline-none flex justify-center items-center z-40 opacity-100 transition-all duration-200 ease-in-out")}
91
+ onPointerDownOutside={onPointerDownOutside}
92
+ onInteractOutside={onInteractOutside}
93
+ className={cls("h-full outline-none flex justify-center items-center z-40 opacity-100 transition-all duration-200 ease-in-out")}
84
94
  >
85
95
  <div
86
- className={cn(paperMixin,
96
+ className={cls(paperMixin,
87
97
  "z-30",
88
98
  "relative",
89
99
  "outline-none focus:outline-none",
90
100
  fullWidth && !fullScreen ? "w-11/12" : undefined,
91
101
  fullHeight && !fullScreen ? "h-full" : undefined,
92
- "text-slate-900 dark:text-white",
102
+ "text-surface-accent-900 dark:text-white",
93
103
  "justify-center items-center",
94
104
  fullScreen ? "h-screen w-screen" : "max-h-[90vh] shadow-xl",
95
105
  "ease-in-out duration-200",
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { defaultBorderMixin } from "../styles";
3
- import { cn } from "../util";
3
+ import { cls } from "../util";
4
4
 
5
5
  export function DialogActions({
6
6
  children,
@@ -15,11 +15,11 @@ export function DialogActions({
15
15
  }) {
16
16
 
17
17
  return <div
18
- className={cn(
18
+ className={cls(
19
19
  defaultBorderMixin,
20
20
  "py-3 px-4 border-t flex flex-row items-center justify-end bottom-0 right-0 left-0 text-right z-2 gap-2",
21
21
  position,
22
- "bg-white bg-opacity-60 dark:bg-gray-900 dark:bg-opacity-60",
22
+ "bg-white bg-opacity-60 dark:bg-surface-900 dark:bg-opacity-60",
23
23
  translucent ? "backdrop-blur-sm" : "",
24
24
  className)}>
25
25
  {children}
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { cn } from "../util";
2
+ import { cls } from "../util";
3
3
 
4
4
  export function DialogContent({
5
5
  children,
@@ -17,7 +17,7 @@ export function DialogContent({
17
17
  </div>;
18
18
 
19
19
  return <div
20
- className={cn("py-6 px-6 h-full flex-grow", className)}>
20
+ className={cls("my-6 mx-6 h-full flex-grow", className)}>
21
21
  {children}
22
22
  </div>;
23
23
  }
@@ -0,0 +1,35 @@
1
+ import React from "react";
2
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
3
+ import * as VisuallyHidden from "@radix-ui/react-visually-hidden";
4
+ import { Typography, TypographyProps, TypographyVariant } from "./Typography";
5
+ import { cls } from "../util";
6
+
7
+ export type DialogContentProps = TypographyProps & {
8
+ children: React.ReactNode,
9
+ hidden?: boolean,
10
+ className?: string,
11
+ variant?: TypographyVariant
12
+ };
13
+
14
+ export function DialogTitle({
15
+ children,
16
+ hidden,
17
+ className,
18
+ variant = "subtitle2",
19
+ ...props
20
+ }: DialogContentProps) {
21
+
22
+ const title = <DialogPrimitive.Title asChild>
23
+ <Typography variant={variant}
24
+ className={cls("mt-8 mb-6 mx-6", className)}
25
+ {...props}>
26
+ {children}
27
+ </Typography>
28
+ </DialogPrimitive.Title>;
29
+
30
+ if (hidden) {
31
+ return <VisuallyHidden.Root>{title}</VisuallyHidden.Root>
32
+ }
33
+
34
+ return title;
35
+ }
@@ -1,9 +1,11 @@
1
+ "use client";
1
2
  import React, { PropsWithChildren, useEffect, useState } from "react";
2
3
 
3
4
  import * as Collapsible from "@radix-ui/react-collapsible";
4
- import { defaultBorderMixin, fieldBackgroundMixin, focusedMixin } from "../styles";
5
+ import { defaultBorderMixin, fieldBackgroundMixin } from "../styles";
5
6
  import { ExpandMoreIcon } from "../icons";
6
- import { cn, useInjectStyles } from "../util";
7
+ import { cls } from "../util";
8
+ import { useInjectStyles } from "../hooks";
7
9
 
8
10
  export function ExpandablePanel({
9
11
  title,
@@ -14,7 +16,8 @@ export function ExpandablePanel({
14
16
  initiallyExpanded = true,
15
17
  titleClassName,
16
18
  asField,
17
- className
19
+ className,
20
+ innerClassName
18
21
  }: PropsWithChildren<{
19
22
  title: React.ReactNode,
20
23
  invisible?: boolean,
@@ -23,7 +26,8 @@ export function ExpandablePanel({
23
26
  onExpandedChange?: (expanded: boolean) => void,
24
27
  titleClassName?: string,
25
28
  asField?: boolean,
26
- className?: string
29
+ className?: string,
30
+ innerClassName?: string
27
31
  }>) {
28
32
 
29
33
  useInjectStyles("ExpandablePanel", `
@@ -75,9 +79,11 @@ export function ExpandablePanel({
75
79
 
76
80
  return (<>
77
81
  <Collapsible.Root
78
- className={cn(
82
+ className={cls(
79
83
  !invisible && defaultBorderMixin + " border",
80
- "rounded-md"
84
+ "rounded-md",
85
+ "w-full",
86
+ className
81
87
  )}
82
88
  open={open}
83
89
  onOpenChange={(updatedOpen: boolean) => {
@@ -86,26 +92,28 @@ export function ExpandablePanel({
86
92
  }}>
87
93
 
88
94
  <Collapsible.Trigger
89
- className={cn(focusedMixin,
90
- "rounded flex items-center justify-between w-full min-h-[52px]",
91
- "hover:bg-slate-50 dark:hover:bg-gray-800 dark:hover:bg-opacity-10",
95
+ className={cls(
96
+ "rounded-t flex items-center justify-between w-full min-h-[52px]",
97
+ "hover:bg-surface-accent-200 hover:bg-opacity-20 dark:hover:bg-surface-800 dark:hover:bg-opacity-20",
92
98
  invisible ? "border-b px-2" : "p-4",
99
+ open ? "py-6" : "py-4",
100
+ "transition-all duration-200",
93
101
  invisible && defaultBorderMixin,
94
102
  asField && fieldBackgroundMixin,
95
103
  titleClassName
96
104
  )}
97
105
  >
98
106
  {title}
99
- <ExpandMoreIcon className={cn("transition", open ? "rotate-180" : "")}/>
107
+ <ExpandMoreIcon className={cls("transition", open ? "rotate-180" : "")}/>
100
108
  </Collapsible.Trigger>
101
109
 
102
110
  <Collapsible.Content
103
- className={cn("CollapsibleContent")}
111
+ className={cls("CollapsibleContent")}
104
112
  style={{
105
113
  overflow: allowOverflow ? "visible" : "hidden"
106
114
  }}
107
115
  >
108
- <div className={className}>
116
+ <div className={innerClassName}>
109
117
  {children}
110
118
  </div>
111
119
  </Collapsible.Content>
@@ -1,7 +1,8 @@
1
+ "use client";
1
2
  import React from "react";
2
3
  import { useDropzone } from "react-dropzone";
3
- import { fieldBackgroundHoverMixin, fieldBackgroundMixin, focusedMixin } from "../styles";
4
- import { cn } from "../util";
4
+ import { fieldBackgroundHoverMixin, fieldBackgroundMixin } from "../styles";
5
+ import { cls } from "../util";
5
6
  import { Typography } from "./Typography";
6
7
 
7
8
  export interface FileUploadError {
@@ -11,7 +12,7 @@ export interface FileUploadError {
11
12
 
12
13
  export type OnFileUploadRejected = (fileRejections: {
13
14
  file: File;
14
- errors: FileUploadError[];
15
+ errors: readonly FileUploadError[];
15
16
  }[], event: object) => void;
16
17
 
17
18
  export type OnFilesUploadAdded = (files: File[]) => void;
@@ -38,7 +39,7 @@ export function FileUpload({
38
39
  disabled,
39
40
  maxFiles,
40
41
  title,
41
- uploadDescription = "Drag and drop a file here or click",
42
+ uploadDescription,
42
43
  children,
43
44
  preventDropOnDocument = true,
44
45
  size
@@ -63,21 +64,18 @@ export function FileUpload({
63
64
  );
64
65
  return <div
65
66
  {...getRootProps()}
66
- className={cn(
67
+ className={cls(
67
68
  fieldBackgroundMixin,
68
- fieldBackgroundHoverMixin,
69
- focusedMixin,
70
69
  "flex gap-2",
71
70
  "p-4 box-border relative items-center border-2 border-solid border-transparent outline-none rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid",
72
71
  {
73
72
  "h-44": size === "medium",
74
73
  "h-28": size === "small",
75
74
  "cursor-pointer": !disabled,
76
- "hover:bg-field-hover dark:hover:bg-field-hover-dark": !isDragActive,
75
+ [fieldBackgroundHoverMixin]: !isDragActive,
77
76
  "transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-red-500": isDragReject,
78
77
  "transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-green-500": isDragAccept,
79
- })}
80
- >
78
+ })}>
81
79
 
82
80
  <Typography variant={"caption"} color={"secondary"} className={"absolute top-2 left-3.5 cursor-inherit"}>
83
81
  {title}
@@ -1,6 +1,5 @@
1
1
  import React from "react";
2
- import { focusedMixin } from "../styles";
3
- import { cn } from "../util";
2
+ import { cls } from "../util";
4
3
 
5
4
  export type IconButtonProps<C extends React.ElementType> =
6
5
  Omit<(C extends "button" ? React.ButtonHTMLAttributes<HTMLButtonElement> : React.ComponentProps<C>), "onClick">
@@ -14,11 +13,9 @@ export type IconButtonProps<C extends React.ElementType> =
14
13
  onClick?: React.MouseEventHandler<any>
15
14
  }
16
15
 
17
- const buttonClasses =
18
- "hover:bg-slate-200 hover:bg-opacity-75 dark:hover:bg-gray-700 dark:hover:bg-opacity-50";
19
- const baseClasses =
20
- "inline-flex items-center justify-center p-2 text-sm font-medium focus:outline-none transition-colors ease-in-out duration-150";
21
- const colorClasses = "text-slate-600 visited:text-slate-600 dark:text-slate-300 dark:visited:text-gray-300";
16
+ const buttonClasses = "hover:bg-surface-accent-200 hover:bg-opacity-75 dark:hover:bg-surface-accent-800 hover:scale-110 transition-transform";
17
+ const baseClasses = "inline-flex items-center justify-center p-2 text-sm font-medium focus:outline-none transition-colors ease-in-out duration-150";
18
+ const colorClasses = "text-surface-accent-600 visited:text-surface-accent-600 dark:text-surface-accent-300 dark:visited:text-surface-300";
22
19
  const sizeClasses = {
23
20
  medium: "w-10 !h-10 min-w-10 min-h-10",
24
21
  small: "w-8 !h-8 min-w-8 min-h-8",
@@ -42,15 +39,14 @@ const IconButtonInner = <C extends React.ElementType = "button">({
42
39
  ...props
43
40
  }: IconButtonProps<C>, ref: React.ForwardedRef<HTMLButtonElement>) => {
44
41
 
45
- const bgClasses = variant === "ghost" ? "bg-transparent" : "bg-slate-50 dark:bg-gray-950 dark:bg-opacity-50";
42
+ const bgClasses = variant === "ghost" ? "bg-transparent" : "bg-surface-accent-200 bg-opacity-50 dark:bg-surface-950 dark:bg-opacity-50";
46
43
  const Component: React.ElementType<any> = component || "button";
47
44
  return (
48
45
  <Component
49
46
  type="button"
50
47
  ref={ref}
51
48
  {...props}
52
- className={cn(
53
- focusedMixin,
49
+ className={cls(
54
50
  disabled ? "opacity-50 pointer-events-none" : "cursor-pointer",
55
51
  toggled ? "outline outline-2 outline-primary" : "",
56
52
  colorClasses,
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { cn } from "../util";
2
+ import { cls } from "../util";
3
3
 
4
4
  const colorClasses = {
5
5
  info: "bg-sky-200 dark:bg-teal-900",
@@ -16,7 +16,7 @@ export function InfoLabel({
16
16
 
17
17
  return (
18
18
  <div
19
- className={cn("my-3 py-2 px-4 rounded", colorClasses[mode])}>
19
+ className={cls("my-3 py-2 px-4 rounded", colorClasses[mode])}>
20
20
  {children}
21
21
  </div>
22
22
  )
@@ -1,5 +1,6 @@
1
1
  import * as React from "react";
2
- import { cn } from "../util";
2
+ import { cls } from "../util";
3
+ import { defaultBorderMixin } from "../styles";
3
4
 
4
5
  export type InputLabelProps = {
5
6
  children?: React.ReactNode;
@@ -7,6 +8,12 @@ export type InputLabelProps = {
7
8
  shrink?: boolean;
8
9
  } & React.LabelHTMLAttributes<HTMLLabelElement>;
9
10
 
11
+ const defaultClasses = {
12
+ root: "origin-left transition-transform block whitespace-nowrap overflow-hidden text-overflow-ellipsis max-w-full",
13
+ shrink: "transform translate-y-[2px] scale-75 translate-x-[12px]",
14
+ expanded: "translate-x-[16px] top-0 transform translate-y-[16px] scale-100"
15
+ };
16
+
10
17
  export const InputLabel = React.forwardRef<HTMLLabelElement, InputLabelProps>(function InputLabel(inProps, ref) {
11
18
  const {
12
19
  shrink,
@@ -14,13 +21,7 @@ export const InputLabel = React.forwardRef<HTMLLabelElement, InputLabelProps>(fu
14
21
  ...other
15
22
  } = inProps;
16
23
 
17
- const defaultClasses = {
18
- root: "origin-left transition-transform block whitespace-nowrap overflow-hidden text-overflow-ellipsis max-w-full",
19
- shrink: "transform translate-y-[2px] scale-75 translate-x-[12px]",
20
- expanded: "translate-x-[16px] top-0 transform translate-y-[16px] scale-100"
21
- };
22
-
23
- const computedClassName = cn(defaultClasses.root,
24
+ const computedClassName = cls(defaultClasses.root,
24
25
  {
25
26
  [defaultClasses.shrink]: shrink,
26
27
  [defaultClasses.expanded]: !shrink
@@ -28,9 +29,10 @@ export const InputLabel = React.forwardRef<HTMLLabelElement, InputLabelProps>(fu
28
29
 
29
30
  return (
30
31
  <label
32
+ className={cls("text-sm font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
33
+ defaultBorderMixin, computedClassName)}
31
34
  data-shrink={shrink}
32
35
  ref={ref}
33
- className={computedClassName}
34
36
  {...other}
35
37
  />
36
38
  );
@@ -1,15 +1,28 @@
1
1
  import * as React from "react"
2
2
  import * as LabelPrimitive from "@radix-ui/react-label"
3
- import { cn } from "../util";
3
+ import { cls } from "../util";
4
4
  import { defaultBorderMixin } from "../styles";
5
5
 
6
+ type LabelProps = React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & {
7
+ border?: boolean,
8
+ onClick?: React.MouseEventHandler<HTMLLabelElement>
9
+ };
6
10
  const Label = React.forwardRef<
7
11
  React.ElementRef<typeof LabelPrimitive.Root>,
8
- React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
9
- >(({ className, ...props }, ref) => (
12
+ LabelProps
13
+ >(({
14
+ className,
15
+ border,
16
+ onClick,
17
+ ...props
18
+ }, ref) => (
10
19
  <LabelPrimitive.Root
11
20
  ref={ref}
12
- className={cn("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", defaultBorderMixin, className)}
21
+ onClick={onClick}
22
+ className={cls("text-sm font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
23
+ border && "border border-surface-300 dark:border-surface-700 rounded-md px-3 py-1.5",
24
+ onClick && "hover:cursor-pointer hover:bg-surface-200 dark:hover:bg-surface-800",
25
+ defaultBorderMixin, className)}
13
26
  {...props}
14
27
  />
15
28
  ))
@@ -1,28 +1,40 @@
1
+ "use client";
1
2
  import React, { useMemo } from "react";
2
3
  import equal from "react-fast-compare"
3
4
 
4
5
  // @ts-ignore
5
6
  import MarkdownIt from "markdown-it";
7
+ import { cls } from "../util";
6
8
 
7
9
  export interface MarkdownProps {
8
10
  source: string,
11
+ size?: "small" | "medium" | "large" | "xl" | "2xl";
9
12
  className?: string
10
13
  }
11
14
 
12
- const md = new MarkdownIt({ html: true, });
15
+ const proseClasses = {
16
+ small: "prose-sm typography-body2",
17
+ medium: "prose typography-body1",
18
+ large: "prose-lg",
19
+ xl: "prose-xl",
20
+ "2xl": "prose-2xl"
21
+ };
22
+
23
+ const md = new MarkdownIt({ html: true });
13
24
  /**
14
25
  * @group Preview components
15
26
  */
16
27
  export const Markdown = React.memo<MarkdownProps>(function Markdown({
17
28
  source,
18
- className
29
+ className,
30
+ size = "medium"
19
31
  }: MarkdownProps) {
20
32
  const html = useMemo(() => {
21
33
  return md.render(typeof source === "string" ? source : "");
22
34
  }, [source]);
23
35
 
24
36
  return <div
25
- className={className}
37
+ className={cls(proseClasses[size], "dark:prose-invert prose-headings:font-title", className)}
26
38
  dangerouslySetInnerHTML={{ __html: html }}
27
39
  />;
28
40
  }
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
3
- import { focusedMixin, paperMixin } from "../styles";
4
- import { cn } from "../util";
3
+ import { focusedDisabled, paperMixin } from "../styles";
4
+ import { cls } from "../util";
5
5
 
6
6
  export type MenuProps = {
7
7
  children: React.ReactNode;
@@ -12,49 +12,67 @@ export type MenuProps = {
12
12
  onOpenChange?(open: boolean): void;
13
13
 
14
14
  portalContainer?: HTMLElement | null;
15
+ side?: "top" | "right" | "bottom" | "left";
16
+ align?: "start" | "center" | "end";
15
17
  }
16
18
 
17
- export function Menu({
18
- children,
19
- trigger,
20
- open,
21
- defaultOpen,
22
- onOpenChange,
23
- portalContainer
24
- }: MenuProps) {
25
- return (
26
- <DropdownMenu.Root
27
- open={open}
28
- defaultOpen={defaultOpen}
29
- onOpenChange={onOpenChange}>
30
- <DropdownMenu.Trigger asChild>
31
- {trigger}
32
- </DropdownMenu.Trigger>
33
- <DropdownMenu.Portal container={portalContainer}>
34
- <DropdownMenu.Content className={cn(paperMixin, "shadow py-2 z-30")}>
35
- {children}
36
- </DropdownMenu.Content>
37
- </DropdownMenu.Portal>
38
- </DropdownMenu.Root>
39
- );
40
- }
19
+ const Menu = React.forwardRef<
20
+ React.ElementRef<typeof DropdownMenu.Trigger>,
21
+ MenuProps
22
+ >(({
23
+ children,
24
+ trigger,
25
+ open,
26
+ defaultOpen,
27
+ side,
28
+ align,
29
+ onOpenChange,
30
+ portalContainer
31
+ }, ref) => (
32
+ <DropdownMenu.Root
33
+ open={open}
34
+ defaultOpen={defaultOpen}
35
+ onOpenChange={onOpenChange}>
36
+ <DropdownMenu.Trigger
37
+ ref={ref}
38
+ asChild>
39
+ {trigger}
40
+ </DropdownMenu.Trigger>
41
+ <DropdownMenu.Portal container={portalContainer}>
42
+ <DropdownMenu.Content
43
+ side={side}
44
+ align={align}
45
+ className={cls(paperMixin, focusedDisabled, "shadow py-2 z-30")}>
46
+ {children}
47
+ </DropdownMenu.Content>
48
+ </DropdownMenu.Portal>
49
+ </DropdownMenu.Root>
50
+ ))
51
+ Menu.displayName = "Menu"
52
+
53
+ export { Menu }
41
54
 
42
55
  export type MenuItemProps = {
43
56
  children: React.ReactNode;
44
57
  dense?: boolean;
45
58
  onClick?: (event: React.MouseEvent) => void;
46
- }
59
+ };
47
60
 
48
61
  export function MenuItem({
49
62
  children,
50
- dense,
63
+ dense = false, // Default value is false if not provided
51
64
  onClick
52
65
  }: MenuItemProps) {
66
+ // Dynamically adjusting the class based on the "dense" prop
67
+ const classNames = cls(
68
+ onClick && "cursor-pointer",
69
+ "rounded-md text-sm font-medium text-surface-accent-700 dark:text-surface-accent-300 hover:bg-surface-accent-100 dark:hover:bg-surface-accent-900 flex items-center gap-4",
70
+ dense ? "px-3 py-1.5" : "px-4 py-2"
71
+ );
72
+
53
73
  return (
54
74
  <DropdownMenu.Item
55
- className={cn(focusedMixin,
56
- onClick && "cursor-pointer",
57
- "rounded-md px-4 py-2 text-sm font-medium text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-900 flex items-center gap-4")}
75
+ className={classNames}
58
76
  onClick={onClick}>
59
77
  {children}
60
78
  </DropdownMenu.Item>