@noya-app/noya-designsystem 0.1.30 → 0.1.32

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 (64) hide show
  1. package/.turbo/turbo-build.log +20 -12
  2. package/.turbo/turbo-lint.log +15 -1
  3. package/CHANGELOG.md +17 -0
  4. package/README.md +13 -1
  5. package/dist/index.css +1 -0
  6. package/dist/index.d.ts +238 -627
  7. package/dist/index.js +4259 -2862
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +4159 -2764
  10. package/dist/index.mjs.map +1 -1
  11. package/package.json +17 -7
  12. package/src/components/ActivityIndicator.tsx +4 -36
  13. package/src/components/Avatar.tsx +63 -62
  14. package/src/components/Button.tsx +53 -170
  15. package/src/components/Chip.tsx +117 -150
  16. package/src/components/ContextMenu.tsx +13 -35
  17. package/src/components/Dialog.tsx +66 -54
  18. package/src/components/Divider.tsx +31 -41
  19. package/src/components/DraggableMenuButton.tsx +29 -30
  20. package/src/components/DropdownMenu.tsx +30 -40
  21. package/src/components/FillInputField.tsx +16 -26
  22. package/src/components/FillPreviewBackground.tsx +18 -22
  23. package/src/components/FloatingWindow.tsx +4 -7
  24. package/src/components/GridView.tsx +70 -200
  25. package/src/components/IconButton.tsx +1 -5
  26. package/src/components/InputField.tsx +258 -234
  27. package/src/components/InputFieldWithCompletions.tsx +20 -27
  28. package/src/components/InspectorContainer.tsx +4 -9
  29. package/src/components/InspectorPrimitives.tsx +135 -109
  30. package/src/components/Label.tsx +5 -36
  31. package/src/components/LabeledElementView.tsx +5 -26
  32. package/src/components/ListView.tsx +239 -167
  33. package/src/components/Popover.tsx +15 -39
  34. package/src/components/Progress.tsx +21 -44
  35. package/src/components/RadioGroup.tsx +6 -71
  36. package/src/components/ScrollArea.tsx +11 -39
  37. package/src/components/SelectMenu.tsx +72 -32
  38. package/src/components/Slider.tsx +7 -43
  39. package/src/components/Spacer.tsx +6 -18
  40. package/src/components/Switch.tsx +4 -42
  41. package/src/components/Text.tsx +31 -66
  42. package/src/components/TextArea.tsx +5 -31
  43. package/src/components/Toast.tsx +15 -57
  44. package/src/components/Tooltip.tsx +4 -13
  45. package/src/components/WorkspaceLayout.tsx +27 -17
  46. package/src/components/internal/Menu.tsx +37 -83
  47. package/src/contexts/DesignSystemConfiguration.tsx +1 -47
  48. package/src/contexts/DialogContext.tsx +2 -10
  49. package/src/hooks/useDarkMode.ts +14 -0
  50. package/src/index.css +108 -0
  51. package/src/index.tsx +4 -5
  52. package/src/theme/index.ts +4 -16
  53. package/src/utils/tailwind.ts +17 -0
  54. package/tailwind.config.ts +223 -0
  55. package/tailwind.d.ts +11 -0
  56. package/tsconfig.json +4 -1
  57. package/tsup.config.ts +16 -0
  58. package/dist/index.d.mts +0 -1455
  59. package/src/components/Grid.tsx +0 -54
  60. package/src/components/Select.tsx +0 -183
  61. package/src/components/Stack.tsx +0 -155
  62. package/src/theme/dark.ts +0 -45
  63. package/src/theme/light.ts +0 -226
  64. package/src/utils/breakpoints.ts +0 -45
@@ -1,9 +1,9 @@
1
1
  import React, { ForwardedRef, forwardRef, ReactHTML, ReactNode } from "react";
2
- import styled, { CSSProperties } from "styled-components";
3
- import { Theme, ThemeColorName } from "../theme";
4
- import { BreakpointCollection, mergeBreakpoints } from "../utils/breakpoints";
2
+ import { camelCaseToKebabCase, ThemeColor } from "../utils/tailwind";
5
3
 
6
- const elements: Record<keyof Theme["textStyles"], keyof ReactHTML> = {
4
+ type Variant = "title" | "subtitle" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "body" | "small" | "button" | "code" | "label";
5
+
6
+ const elements: Record<Variant, keyof ReactHTML> = {
7
7
  title: "h1",
8
8
  subtitle: "h1",
9
9
  heading1: "h1",
@@ -18,47 +18,28 @@ const elements: Record<keyof Theme["textStyles"], keyof ReactHTML> = {
18
18
  label: "span",
19
19
  };
20
20
 
21
- type StyleProps = {
22
- flex?: CSSProperties["flex"];
23
- padding?: CSSProperties["padding"];
24
- background?: CSSProperties["background"];
25
- borderRadius?: CSSProperties["borderRadius"];
26
- textAlign?: CSSProperties["textAlign"];
27
- fontWeight?: CSSProperties["fontWeight"];
28
- fontStyle?: CSSProperties["fontStyle"];
29
- fontSize?: CSSProperties["fontSize"];
30
- lineHeight?: CSSProperties["lineHeight"];
31
- fontFamily?: CSSProperties["fontFamily"];
32
- wordBreak?: CSSProperties["wordBreak"];
33
- whiteSpace?: CSSProperties["whiteSpace"];
34
- height?: CSSProperties["height"];
35
- width?: CSSProperties["width"];
36
- minWidth?: CSSProperties["minWidth"];
37
- maxWidth?: CSSProperties["maxWidth"];
38
- opacity?: CSSProperties["opacity"];
39
- position?: CSSProperties["position"];
40
- overflow?: CSSProperties["overflow"];
41
- textOverflow?: CSSProperties["textOverflow"];
42
- textDecoration?: CSSProperties["textDecoration"];
43
- display?: CSSProperties["display"];
44
- top?: CSSProperties["top"];
45
- right?: CSSProperties["right"];
46
- bottom?: CSSProperties["bottom"];
47
- left?: CSSProperties["left"];
48
- userSelect?: CSSProperties["userSelect"];
49
- cursor?: CSSProperties["cursor"];
50
- };
51
-
52
- export type TextBreakpointList = BreakpointCollection<StyleProps>;
53
-
54
- interface Props extends StyleProps {
21
+ export const textStyles: Record<Variant, string> = {
22
+ title: "font-sans text-title font-bold sm:text-[36px]",
23
+ subtitle: "font-sans text-subtitle font-medium sm:text-[18px]",
24
+ heading1: "font-sans text-heading1 font-semibold",
25
+ heading2: "font-sans text-heading2 font-medium",
26
+ heading3: "font-sans text-heading3 font-normal",
27
+ heading4: "font-sans text-heading4 font-medium",
28
+ heading5: "font-sans text-heading5 font-medium",
29
+ body: "font-sans text-base font-normal",
30
+ small: "font-sans text-heading5 font-normal",
31
+ button: "font-sans text-button font-medium",
32
+ code: "font-mono text-code",
33
+ label: "font-sans text-label font-normal uppercase",
34
+ } as const;
35
+
36
+ export type TextProps = {
55
37
  as?: keyof ReactHTML;
56
38
  href?: string;
57
39
  className?: string;
58
40
  style?: React.CSSProperties;
59
- variant: keyof Theme["textStyles"];
60
- breakpoints?: BreakpointCollection<StyleProps> | null | false;
61
- color?: ThemeColorName;
41
+ variant: Variant;
42
+ color?: ThemeColor;
62
43
  children: ReactNode;
63
44
  onClick?: () => void;
64
45
  onDoubleClick?: () => void;
@@ -66,58 +47,42 @@ interface Props extends StyleProps {
66
47
  tabIndex?: number;
67
48
  }
68
49
 
69
- const StyledElement = styled.span<{
70
- $variant: keyof Theme["textStyles"];
71
- $styleProps: StyleProps;
72
- $color: ThemeColorName;
73
- $breakpoints: BreakpointCollection<StyleProps> | null | false;
74
- }>(({ theme, $variant, $styleProps, $breakpoints, $color }) => ({
75
- ...(theme.textStyles as any)[$variant],
76
- color: $color ? theme.colors[$color] : undefined,
77
- ...$styleProps,
78
- ...mergeBreakpoints($breakpoints || []),
79
- }));
80
-
81
50
  export const Text = forwardRef(function Text(
82
51
  {
83
52
  as,
84
53
  variant,
85
- breakpoints,
86
54
  children,
87
55
  className,
88
- color,
56
+ color = "text",
89
57
  href,
90
58
  tabIndex,
91
59
  onClick,
92
60
  onKeyDown,
93
61
  style,
94
62
  ...rest
95
- }: Props,
63
+ }: TextProps,
96
64
  forwardedRef: ForwardedRef<HTMLElement>
97
65
  ) {
98
- const element = as ?? elements[variant] ?? "span";
66
+ const Component = as ?? elements[variant] ?? "span";
99
67
 
100
68
  return (
101
- <StyledElement
69
+ <Component
70
+ // @ts-expect-error expected to be many semantic html elements
102
71
  ref={forwardedRef}
103
- as={element}
104
- className={className}
72
+ className={`${textStyles[variant]} text-${camelCaseToKebabCase(String(color)) ?? "text"} ${className ?? ""}`}
105
73
  style={style}
106
74
  tabIndex={tabIndex}
107
- $variant={variant}
108
- $breakpoints={breakpoints}
109
- $styleProps={rest}
110
- $color={color}
111
75
  onClick={onClick}
112
76
  onKeyDown={onKeyDown}
113
77
  {...((href && { href }) as any)}
78
+ {...rest}
114
79
  >
115
80
  {children}
116
- </StyledElement>
81
+ </Component>
117
82
  );
118
83
  });
119
84
 
120
- type PresetProps = Omit<Props, "variant">;
85
+ type PresetProps = Omit<TextProps, "variant">;
121
86
 
122
87
  export const Heading1 = forwardRef(
123
88
  (props: PresetProps, ref: ForwardedRef<HTMLElement>) => (
@@ -1,30 +1,5 @@
1
1
  import { assignRef } from "@noya-app/react-utils";
2
2
  import React, { forwardRef, memo, useCallback, useEffect, useRef } from "react";
3
- import styled from "styled-components";
4
-
5
- const TextAreaElement = styled.textarea(({ theme }) => ({
6
- ...theme.textStyles.small,
7
- color: theme.colors.text,
8
- background: theme.colors.inputBackground,
9
- width: "0px",
10
- flex: "1 1 auto",
11
- padding: "4px 6px",
12
- border: "none",
13
- outline: "none",
14
- height: 100,
15
- borderRadius: "4px",
16
- "&::placeholder": {
17
- color: theme.colors.textDisabled,
18
- },
19
- "&:focus": {
20
- boxShadow: `0 0 0 2px ${theme.colors.primary}`,
21
- },
22
- // readonly
23
- "&:read-only": {
24
- color: theme.colors.textDisabled,
25
- },
26
- resize: "none",
27
- }));
28
3
 
29
4
  export const useAutoResize = (value: string) => {
30
5
  const textareaRef = useRef<HTMLTextAreaElement | null>(null);
@@ -44,14 +19,12 @@ export const AutoResizingTextArea = memo(
44
19
  {
45
20
  value,
46
21
  onChangeText,
22
+ className,
47
23
  ...rest
48
- }: Omit<
49
- React.ComponentProps<typeof TextAreaElement>,
50
- "onChange" | "value"
51
- > & {
24
+ }: {
52
25
  onChangeText: (value: string) => void;
53
26
  value?: string;
54
- },
27
+ } & React.TextareaHTMLAttributes<HTMLTextAreaElement>,
55
28
  forwardedRef: React.ForwardedRef<HTMLTextAreaElement>
56
29
  ) {
57
30
  const ref = useAutoResize(value || rest.placeholder || "");
@@ -71,7 +44,8 @@ export const AutoResizingTextArea = memo(
71
44
  );
72
45
 
73
46
  return (
74
- <TextAreaElement
47
+ <textarea
48
+ className={`font-sans text-heading5 font-normal text-text bg-input-background w-0 flex-1 py-1 px-1.5 border-none outline-none h-[100px] rounded-4 resize-none placeholder:text-text-disabled focus:ring-2 focus:ring-primary focus:z-10 read-only:text-text-disabled ${className ?? ""}`}
75
49
  ref={handleRef}
76
50
  {...rest}
77
51
  onChange={handleChange}
@@ -1,56 +1,7 @@
1
1
  import * as ToastPrimitive from '@radix-ui/react-toast';
2
2
  import React, { ReactNode } from 'react';
3
- import styled from 'styled-components';
4
3
  import { IconButton } from './IconButton';
5
-
6
- const ToastViewport = styled(ToastPrimitive.Viewport)({
7
- position: 'fixed',
8
- bottom: 0,
9
- right: 0,
10
- display: 'flex',
11
- flexDirection: 'column',
12
- padding: 20,
13
- gap: 10,
14
- minWidth: 200,
15
- maxWidth: '100vw',
16
- margin: 0,
17
- listStyle: 'none',
18
- zIndex: 2147483647,
19
- outline: 'none',
20
- });
21
-
22
- const ToastRoot = styled(ToastPrimitive.Root)(({ theme }) => ({
23
- borderRadius: 4,
24
- fontSize: 14,
25
- backgroundColor: theme.colors.popover.background,
26
- boxShadow: '0 2px 4px rgba(0,0,0,0.2), 0 0 12px rgba(0,0,0,0.1)',
27
- color: theme.colors.textMuted,
28
-
29
- padding: '8px 10px',
30
- display: 'grid',
31
- gridTemplateAreas: '"title action" "description action"',
32
- gridTemplateColumns: 'auto max-content',
33
- columnGap: 10,
34
- alignItems: 'center',
35
- }));
36
-
37
- const ToastTitle = styled(ToastPrimitive.Title)(({ theme }) => ({
38
- gridArea: 'title',
39
- marginBottom: 5,
40
- ...theme.textStyles.label,
41
- fontWeight: 'bold',
42
- color: theme.colors.text,
43
- }));
44
-
45
- const ToastDescription = styled(ToastPrimitive.Description)(({ theme }) => ({
46
- gridArea: 'description',
47
- ...theme.textStyles.small,
48
- color: theme.colors.textMuted,
49
- }));
50
-
51
- const ToastAction = styled(ToastPrimitive.Action)({
52
- gridArea: 'action',
53
- });
4
+ import { textStyles } from './Text';
54
5
 
55
6
  export const Toast = ({
56
7
  title,
@@ -63,24 +14,31 @@ export const Toast = ({
63
14
  children?: React.ReactNode;
64
15
  }) => {
65
16
  return (
66
- <ToastRoot {...props}>
67
- {title && <ToastTitle>{title}</ToastTitle>}
68
- <ToastDescription>{content}</ToastDescription>
17
+ <ToastPrimitive.Root
18
+ className="px-2 py-2.5 grid grid-cols-[auto_max-content] gap-x-2.5 items-center rounded text-sm bg-popover-background shadow-[0_2px_4px_rgba(0,0,0,0.2),0_0_12px_rgba(0,0,0,0.1)] text-text-muted"
19
+ {...props}
20
+ >
21
+ {title && (
22
+ <ToastPrimitive.Title className={`mb-[5px] ${textStyles.label} font-bold text-text`}>
23
+ {title}
24
+ </ToastPrimitive.Title>
25
+ )}
26
+ <ToastPrimitive.Description className={`${textStyles.small} text-text-muted`}>{content}</ToastPrimitive.Description>
69
27
  {children && (
70
- <ToastAction asChild altText="">
28
+ <ToastPrimitive.Action asChild altText="">
71
29
  {children}
72
- </ToastAction>
30
+ </ToastPrimitive.Action>
73
31
  )}
74
32
  <ToastPrimitive.Close aria-label="Close" asChild>
75
33
  <IconButton iconName="Cross1Icon" />
76
34
  </ToastPrimitive.Close>
77
- </ToastRoot>
35
+ </ToastPrimitive.Root>
78
36
  );
79
37
  };
80
38
 
81
39
  export const ToastProvider = ({ children }: { children: React.ReactNode }) => (
82
40
  <ToastPrimitive.Provider>
83
41
  {children}
84
- <ToastViewport />
42
+ <ToastPrimitive.Viewport className="fixed bottom-0 right-0 flex flex-col p-5 g-2.5 min-w-[200px] max-w-[100vw] m-0 list-none z-[2147483647] outline-none" />
85
43
  </ToastPrimitive.Provider>
86
44
  );
@@ -1,21 +1,11 @@
1
1
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
2
2
  import React, { memo, ReactNode } from 'react';
3
- import styled from 'styled-components';
3
+ import { textStyles } from './Text';
4
4
 
5
5
  // const Arrow = styled(TooltipPrimitive.Arrow)(({ theme }) => ({
6
6
  // fill: theme.colors.popover.background,
7
7
  // }));
8
8
 
9
- const Content = styled(TooltipPrimitive.Content)(({ theme }) => ({
10
- ...theme.textStyles.small,
11
- color: theme.colors.text,
12
- borderRadius: 3,
13
- padding: `${theme.sizes.spacing.small}px ${theme.sizes.spacing.medium}px`,
14
- backgroundColor: theme.colors.popover.background,
15
- boxShadow: '0 2px 4px rgba(0,0,0,0.2), 0 0 12px rgba(0,0,0,0.1)',
16
- border: `1px solid ${theme.colors.dividerStrong}`,
17
- }));
18
-
19
9
  interface Props {
20
10
  children: ReactNode;
21
11
  content: ReactNode;
@@ -27,15 +17,16 @@ export const Tooltip = memo(function Tooltip({ children, content }: Props) {
27
17
  <TooltipPrimitive.Root>
28
18
  <TooltipPrimitive.Trigger asChild>{children}</TooltipPrimitive.Trigger>
29
19
  <TooltipPrimitive.Portal>
30
- <Content
20
+ <TooltipPrimitive.Content
31
21
  side="bottom"
32
22
  align="center"
33
23
  sideOffset={2}
34
24
  collisionPadding={8}
25
+ className={`${textStyles.small} text-text rounded-[3px] py-small px-medium bg-popover-background shadow-[0_2px_4px_var(--shadow-color)_0_0_12px_var(--shadow-color)] border border-solid border-divider-strong`}
35
26
  >
36
27
  {content}
37
28
  {/* <Arrow /> */}
38
- </Content>
29
+ </TooltipPrimitive.Content>
39
30
  </TooltipPrimitive.Portal>
40
31
  </TooltipPrimitive.Root>
41
32
  </TooltipPrimitive.Provider>
@@ -1,9 +1,11 @@
1
- import {
2
- DesignSystemThemeProvider,
3
- useDesignSystemTheme,
4
- } from "@noya-app/noya-designsystem";
5
1
  import { useKeyboardShortcuts } from "@noya-app/noya-keymap";
6
- import React, { forwardRef, useImperativeHandle, useRef } from "react";
2
+ import React, {
3
+ forwardRef,
4
+ useCallback,
5
+ useImperativeHandle,
6
+ useRef,
7
+ useState,
8
+ } from "react";
7
9
  import {
8
10
  ImperativePanelGroupHandle,
9
11
  ImperativePanelHandle,
@@ -98,9 +100,17 @@ const WorkspaceLayoutWithTheme = forwardRef(function WorkspaceLayoutWithTheme(
98
100
  const leftSidebarRef = useRef<ImperativePanelHandle>(null);
99
101
  const rightSidebarRef = useRef<ImperativePanelHandle>(null);
100
102
 
101
- usePreservePanelSize(panelGroupRef, onChangeLayoutState);
103
+ const [internalLayoutState, setInternalLayoutState] =
104
+ useState<PanelLayoutState | null>(null);
105
+ const handleChangeLayoutState = useCallback(
106
+ (state: PanelLayoutState) => {
107
+ setInternalLayoutState(state);
108
+ onChangeLayoutState?.(state);
109
+ },
110
+ [onChangeLayoutState]
111
+ );
102
112
 
103
- const theme = useDesignSystemTheme();
113
+ usePreservePanelSize(panelGroupRef, handleChangeLayoutState);
104
114
 
105
115
  useImperativeHandle(forwardedRef, () => ({
106
116
  setLeftSidebarExpanded: (expanded: boolean) => {
@@ -174,7 +184,7 @@ const WorkspaceLayoutWithTheme = forwardRef(function WorkspaceLayoutWithTheme(
174
184
  id={id}
175
185
  className={className}
176
186
  style={{
177
- backgroundColor: theme.colors.canvas.background,
187
+ backgroundColor: "var(--canvas-background)",
178
188
  display: "flex",
179
189
  flexDirection: "row",
180
190
  ...style,
@@ -207,14 +217,16 @@ const WorkspaceLayoutWithTheme = forwardRef(function WorkspaceLayoutWithTheme(
207
217
  position: "relative",
208
218
  }}
209
219
  >
210
- {leftPanelContent}
220
+ {internalLayoutState?.leftSidebarCollapsed
221
+ ? null
222
+ : leftPanelContent}
211
223
  </Panel>
212
224
  <PanelResizeHandle
213
225
  style={{
214
226
  cursor: "col-resize",
215
227
  width: "1px",
216
228
  height: "100%",
217
- backgroundColor: theme.colors.divider,
229
+ backgroundColor: "var(--divider)",
218
230
  }}
219
231
  />
220
232
  </>
@@ -239,7 +251,7 @@ const WorkspaceLayoutWithTheme = forwardRef(function WorkspaceLayoutWithTheme(
239
251
  cursor: "col-resize",
240
252
  width: "1px",
241
253
  height: "100%",
242
- backgroundColor: theme.colors.divider,
254
+ backgroundColor: "var(--divider)",
243
255
  }}
244
256
  />
245
257
  <Panel
@@ -255,7 +267,9 @@ const WorkspaceLayoutWithTheme = forwardRef(function WorkspaceLayoutWithTheme(
255
267
  position: "relative",
256
268
  }}
257
269
  >
258
- {rightPanelContent}
270
+ {internalLayoutState?.rightSidebarCollapsed
271
+ ? null
272
+ : rightPanelContent}
259
273
  </Panel>
260
274
  </>
261
275
  )}
@@ -268,9 +282,5 @@ export const WorkspaceLayout = forwardRef(function WorkspaceLayout(
268
282
  props: Props,
269
283
  forwardedRef: React.ForwardedRef<IWorkspaceLayout>
270
284
  ) {
271
- return (
272
- <DesignSystemThemeProvider>
273
- <WorkspaceLayoutWithTheme {...props} ref={forwardedRef} />
274
- </DesignSystemThemeProvider>
275
- );
285
+ return <WorkspaceLayoutWithTheme {...props} ref={forwardedRef} />;
276
286
  });
@@ -1,10 +1,10 @@
1
1
  import { getShortcutDisplayParts } from "@noya-app/noya-keymap";
2
2
  import React, { memo, ReactNode } from "react";
3
- import styled, { CSSObject } from "styled-components";
4
3
  import { useDesignSystemConfiguration } from "../../contexts/DesignSystemConfiguration";
5
- import { Theme } from "../../theme";
6
4
  import withSeparatorElements from "../../utils/withSeparatorElements";
7
5
  import { IconName } from "../Icons";
6
+ import { cn } from "../../utils/tailwind";
7
+ import { textStyles } from "../Text";
8
8
 
9
9
  export const SEPARATOR_ITEM = "separator";
10
10
 
@@ -77,76 +77,39 @@ export type MenuItem<T extends string> =
77
77
  export type ExtractMenuItemType<T> =
78
78
  T extends RegularMenuItem<infer U> ? U : never;
79
79
 
80
- export const CHECKBOX_WIDTH = 15;
81
- export const CHECKBOX_RIGHT_INSET = 3;
80
+ export const CHECKBOX_WIDTH = 16;
81
+ export const CHECKBOX_RIGHT_INSET = 8;
82
82
 
83
83
  export const styles = {
84
- separatorStyle: ({ theme }: { theme: Theme }): CSSObject => ({
85
- height: "1px",
86
- backgroundColor: theme.colors.divider,
87
- margin: "4px -4px",
88
- }),
89
-
90
- itemStyle: ({
91
- theme,
92
- disabled,
93
- }: {
94
- theme: Theme;
95
- disabled?: boolean;
96
- }): CSSObject => ({
97
- ...theme.textStyles.button,
98
- flex: "0 0 auto",
99
- userSelect: "none",
100
- cursor: "pointer",
101
- borderRadius: "3px",
102
- padding: "6px 8px",
103
- ...(disabled && {
104
- color: theme.colors.textDisabled,
105
- }),
106
- "&:focus": {
107
- outline: "none",
108
- color: "white",
109
- backgroundColor: theme.colors.primary,
110
-
111
- "& kbd": {
112
- color: "white",
113
- },
114
- },
115
- "&:active": {
116
- background: theme.colors.primaryLight,
117
- },
118
- display: "flex",
119
- alignItems: "center",
120
- }),
121
-
122
- itemIndicatorStyle: {
123
- display: "flex",
124
- alignItems: "center",
125
- left: `-${CHECKBOX_WIDTH / 2}px`,
126
- position: "relative",
127
- marginRight: `-${CHECKBOX_RIGHT_INSET}px`,
128
- } as CSSObject,
129
-
130
- contentStyle: ({
131
- theme,
132
- scrollable,
133
- }: {
134
- theme: Theme;
135
- scrollable?: boolean;
136
- }): CSSObject => ({
137
- borderRadius: 4,
138
- backgroundColor: theme.colors.popover.background,
139
- color: theme.colors.text,
140
- boxShadow: "0 2px 4px rgba(0,0,0,0.2), 0 0 12px rgba(0,0,0,0.1)",
141
- padding: "4px",
142
- border: `1px solid ${theme.colors.popover.divider}`,
143
- zIndex: 1000,
144
- ...(scrollable && {
145
- height: "100%",
146
- maxHeight: "calc(100vh - 80px)",
147
- overflow: "hidden auto",
148
- }),
149
- }),
84
+ separatorStyle: "h-px bg-divider mx-[-4px] my-1",
85
+
86
+ itemStyle: ({ disabled }: { disabled?: boolean }) => `
87
+ flex-none select-none cursor-pointer rounded
88
+ p-[6px_8px]
89
+ flex items-center
90
+ font-sans text-button font-medium
91
+ ${disabled ? "text-text-disabled" : ""}
92
+ focus:outline-none focus:text-white focus:bg-primary
93
+ focus:kbd:text-white
94
+ active:bg-primary-light
95
+ `,
96
+
97
+ itemIndicatorStyle: `
98
+ flex items-center
99
+ relative
100
+ -left-2.5
101
+ -mr-2
102
+ `,
103
+
104
+ contentStyle: `
105
+ rounded
106
+ bg-popover-background
107
+ text-text
108
+ shadow-[0_2px_4px_rgba(0,0,0,0.2),_0_0_12px_rgba(0,0,0,0.1)]
109
+ p-1
110
+ border border-popover-divider
111
+ z-50
112
+ `,
150
113
  };
151
114
 
152
115
  function getKeyboardShortcuts<T extends string>(
@@ -172,18 +135,9 @@ export function getKeyboardShortcutsForMenuItems<T extends string>(
172
135
  );
173
136
  }
174
137
 
175
- const ShortcutElement = styled.kbd<{
176
- $fixedWidth?: boolean;
177
- }>(
178
- ({ theme, $fixedWidth }): CSSObject => ({
179
- ...theme.textStyles.small,
180
- color: theme.colors.textDisabled,
181
- ...($fixedWidth && {
182
- width: "0.9rem",
183
- textAlign: "center",
184
- }),
185
- })
186
- );
138
+ const ShortcutElement = ({children, fixedWidth}: {children?: React.ReactNode; fixedWidth?: boolean}) => (
139
+ <kbd className={cn(textStyles.small, "text-text-disabled", fixedWidth && "w-[0.9rem] text-center")}>{children}</kbd>
140
+ )
187
141
 
188
142
  export const KeyboardShortcut = memo(function KeyboardShortcut({
189
143
  shortcut,
@@ -197,7 +151,7 @@ export const KeyboardShortcut = memo(function KeyboardShortcut({
197
151
  const keyElements = keys.map((key) => (
198
152
  <ShortcutElement
199
153
  key={key}
200
- $fixedWidth={platform === "mac" && key.length === 1}
154
+ fixedWidth={platform === "mac" && key.length === 1}
201
155
  >
202
156
  {key}
203
157
  </ShortcutElement>
@@ -8,41 +8,10 @@ import React, {
8
8
  useMemo,
9
9
  useState,
10
10
  } from "react";
11
- import { ThemeProvider, useTheme } from "styled-components";
12
11
  import { ToastProvider } from "../components/Toast";
13
- import { Theme } from "../theme";
14
- import * as darkTheme from "../theme/dark";
15
- import * as lightTheme from "../theme/light";
16
12
  import { DialogProvider } from "./DialogContext";
17
13
  import { FloatingWindowProvider } from "./FloatingWindowContext";
18
14
 
19
- export const DesignSystemThemeProvider = memo(
20
- function DesignSystemThemeProvider({
21
- children,
22
- theme,
23
- }: {
24
- children: ReactNode;
25
- theme?: Theme;
26
- }) {
27
- let parentTheme: Theme | undefined;
28
-
29
- try {
30
- // eslint-disable-next-line react-hooks/rules-of-hooks
31
- parentTheme = useTheme();
32
- } catch (e) {
33
- // console.error(e);
34
- }
35
-
36
- if (theme) {
37
- return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
38
- } else if (parentTheme) {
39
- return children;
40
- } else {
41
- return <ThemeProvider theme={lightTheme}>{children}</ThemeProvider>;
42
- }
43
- }
44
- );
45
-
46
15
  export type DesignSystemConfigurationContextValue = {
47
16
  platform: PlatformName;
48
17
  };
@@ -55,11 +24,9 @@ const DesignSystemConfigurationContext =
55
24
  export const DesignSystemConfigurationProvider = memo(
56
25
  function DesignSystemConfigurationProvider({
57
26
  children,
58
- theme,
59
27
  platform,
60
28
  }: {
61
29
  children: ReactNode;
62
- theme?: Theme | "light" | "dark";
63
30
  platform?: PlatformName;
64
31
  }) {
65
32
  const [internalPlatform, setInternalPlatform] = useState<PlatformName>(
@@ -79,22 +46,13 @@ export const DesignSystemConfigurationProvider = memo(
79
46
  [platform, internalPlatform]
80
47
  );
81
48
 
82
- const resolvedTheme =
83
- theme === "light"
84
- ? lightTheme
85
- : theme === "dark"
86
- ? darkTheme
87
- : theme ?? lightTheme;
88
-
89
49
  return (
90
50
  <DesignSystemConfigurationContext.Provider value={contextValue}>
91
- <ThemeProvider theme={resolvedTheme}>
92
51
  <DialogProvider>
93
52
  <ToastProvider>
94
53
  <FloatingWindowProvider>{children}</FloatingWindowProvider>
95
54
  </ToastProvider>
96
55
  </DialogProvider>
97
- </ThemeProvider>
98
56
  </DesignSystemConfigurationContext.Provider>
99
57
  );
100
58
  }
@@ -102,8 +60,4 @@ export const DesignSystemConfigurationProvider = memo(
102
60
 
103
61
  export function useDesignSystemConfiguration(): DesignSystemConfigurationContextValue {
104
62
  return useContext(DesignSystemConfigurationContext);
105
- }
106
-
107
- export function useDesignSystemTheme() {
108
- return useTheme();
109
- }
63
+ }