@noya-app/noya-designsystem 0.1.31 → 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 (61) hide show
  1. package/.turbo/turbo-build.log +20 -12
  2. package/.turbo/turbo-lint.log +2 -1
  3. package/CHANGELOG.md +7 -0
  4. package/README.md +13 -1
  5. package/dist/index.css +1 -0
  6. package/dist/index.d.ts +132 -509
  7. package/dist/index.js +4167 -2716
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +4097 -2643
  10. package/dist/index.mjs.map +1 -1
  11. package/package.json +14 -5
  12. package/src/components/ActivityIndicator.tsx +4 -36
  13. package/src/components/Avatar.tsx +63 -62
  14. package/src/components/Button.tsx +53 -172
  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 +191 -194
  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 +31 -48
  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 +4 -14
  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 +3 -4
  52. package/src/theme/index.ts +4 -16
  53. package/src/utils/tailwind.ts +17 -0
  54. package/tailwind.config.ts +106 -166
  55. package/tsup.config.ts +16 -0
  56. package/dist/index.d.mts +0 -1443
  57. package/src/components/Grid.tsx +0 -54
  58. package/src/components/Stack.tsx +0 -164
  59. package/src/theme/dark.ts +0 -45
  60. package/src/theme/light.ts +0 -226
  61. package/src/utils/breakpoints.ts +0 -45
@@ -10,7 +10,6 @@ import React, {
10
10
  useContext,
11
11
  useMemo,
12
12
  } from "react";
13
- import styled, { keyframes } from "styled-components";
14
13
  import { useHover } from "../hooks/useHover";
15
14
  import withSeparatorElements from "../utils/withSeparatorElements";
16
15
  import { ActivityIndicator } from "./ActivityIndicator";
@@ -18,8 +17,8 @@ import { ContextMenu } from "./ContextMenu";
18
17
  import { MenuItem } from "./internal/Menu";
19
18
  import { ScrollArea } from "./ScrollArea";
20
19
  import { Spacer } from "./Spacer";
21
- import { Stack } from "./Stack";
22
20
  import { Tooltip } from "./Tooltip";
21
+ import { cn } from "../utils/tailwind";
23
22
 
24
23
  export type GridViewSize = "xxs" | "xs" | "small" | "medium" | "large" | "xl";
25
24
 
@@ -63,178 +62,42 @@ const sizes: Record<
63
62
  },
64
63
  };
65
64
 
66
- const Grid = styled.div<{
67
- $size: GridViewSize;
68
- $padding: CSSProperties["padding"];
69
- }>(({ theme, $size, $padding }) => {
70
- return {
71
- color: theme.colors.text,
72
- display: "grid",
73
- gridTemplateColumns: `repeat(auto-fill, minmax(${sizes[$size].itemWidth}px, 1fr))`,
74
- // gridAutoRows: `${sizes[size].itemHeight}px`,
75
- gap: `${sizes[$size].gap}px`,
76
- // gridTemplateColumns: `repeat(auto-fill, minmax(
77
- // ${size === 'large' ? '280px' : size === 'small' ? '160px' : '116px'}
78
- // , 1fr))`,
79
- // gridAutoRows:
80
- // size === 'large' ? '280px' : size === 'small' ? '170px' : '116px',
81
- // gap: size === 'large' || size === 'small' ? `20px` : `12px`,
82
- padding: $padding,
83
- };
84
- });
85
-
86
- const Container = styled.div<{ $scrollable: boolean }>(
87
- ({ theme, $scrollable }) => ({
88
- flex: $scrollable ? "1" : "0 0 auto",
89
- display: "flex",
90
- flexDirection: "column",
91
- })
92
- );
93
-
94
- const ContentContainer = styled.div<{
95
- $selected?: boolean;
96
- $hovered?: boolean;
97
- $bordered: boolean;
98
- $disabled: boolean;
99
- }>(({ theme, $selected, $hovered, $bordered, $disabled }) => ({
100
- display: "flex",
101
- flex: "1",
102
- backgroundColor: theme.colors.sidebar.background,
103
- alignItems: "center",
104
- justifyContent: "center",
105
- borderRadius: "2px",
106
- border: `1px solid ${
107
- $selected
108
- ? theme.colors.primary
109
- : // : hovered
110
- // ? `rgb(132, 63, 255, 0.5)`
111
- $bordered
112
- ? theme.colors.divider
113
- : "transparent"
114
- }`,
115
- overflow: "hidden",
116
-
117
- cursor: "pointer",
118
- ...($disabled
119
- ? { opacity: 0.5 }
120
- : {
121
- "&:hover": { opacity: 0.85 },
122
- "&:active": { opacity: 0.7 },
123
- }),
124
- }));
125
-
126
- const ItemContainer = styled.div(({ theme }) => ({
127
- display: "flex",
128
- flexDirection: "column",
129
- position: "relative",
130
-
131
- "&:focus": {
132
- boxShadow: `0 0 0 1px ${theme.colors.sidebar.background}, 0 0 0 3px ${theme.colors.primary}`,
133
- outline: "none",
134
- },
135
- }));
136
-
137
- const ItemTitle = styled.span<{ $showBackground: boolean }>(
138
- ({ theme, $showBackground }) => ({
139
- ...theme.textStyles.small,
140
- lineHeight: "1",
141
- color: theme.colors.text,
142
- fontWeight: 500,
143
- userSelect: "none",
144
- whiteSpace: "pre",
145
- overflow: "hidden",
146
- textOverflow: "ellipsis",
147
-
148
- ...($showBackground && {
149
- background: theme.colors.sidebar.background,
150
- // border: `1px solid ${theme.colors.dividerSubtle}`,
151
- padding: "2px 4px",
152
- borderRadius: "2px",
153
- backdropFilter: "blur(4px)",
154
- }),
155
- })
156
- );
157
-
158
- const ItemDescription = styled.span<{ $showBackground: boolean }>(
159
- ({ theme, $showBackground }) => ({
160
- ...theme.textStyles.small,
161
- fontSize: "0.7rem",
162
- lineHeight: "1",
163
- color: theme.colors.textMuted,
164
- userSelect: "none",
165
- whiteSpace: "pre",
166
- overflow: "hidden",
167
- textOverflow: "ellipsis",
168
-
169
- ...($showBackground && {
170
- background: theme.colors.sidebar.background,
171
- // border: `1px solid ${theme.colors.dividerSubtle}`,
172
- padding: "2px 4px",
173
- borderRadius: "2px",
174
- backdropFilter: "blur(4px)",
175
- }),
176
- })
177
- );
178
-
179
- const SectionTitle = styled.span<{ last?: boolean }>(
180
- ({ theme, last = false }) => ({
181
- ...theme.textStyles.heading3,
182
- color: last ? theme.colors.text : theme.colors.textMuted,
183
- fontWeight: 500,
184
- userSelect: "none",
185
- whiteSpace: "pre",
186
- overflow: "hidden",
187
- textOverflow: "ellipsis",
188
- lineHeight: "1",
189
- })
190
- );
191
-
192
- const SectionHeaderContainer = styled.div(({ theme }) => ({
193
- padding: "0 20px",
194
- }));
65
+ const ItemTitle = ({showBackground, children}: {showBackground?: boolean, children?: React.ReactNode}) => {
66
+ return (
67
+ <span
68
+ className={`font-sans text-heading5 leading-[1] text-text font-medium select-none whitespace-pre overflow-hidden text-ellipsis ${
69
+ showBackground &&
70
+ "bg-sidebar-background border border-dividerSubtle rounded-[2px] backdrop-blur-[4px] p-[2px_4px]"
71
+ }`}
72
+ >
73
+ {children}
74
+ </span>
75
+ );
195
76
 
196
- const TextOverlay = styled.div({
197
- position: "absolute",
198
- inset: 0,
199
- display: "flex",
200
- flexDirection: "column",
201
- justifyContent: "end",
202
- alignItems: "start",
203
- padding: "4px",
204
- pointerEvents: "none",
205
- overflow: "hidden",
206
- textOverflow: "ellipsis",
207
- whiteSpace: "nowrap",
208
- gap: "2px",
209
- });
77
+ }
210
78
 
211
- const shimmer = keyframes({
212
- "0%": {
213
- backgroundPosition: "-200% 0",
214
- },
215
- "100%": {
216
- backgroundPosition: "200% 0",
217
- },
218
- });
79
+ const ItemDescription = ({showBackground, children}: {showBackground?: boolean, children?: React.ReactNode}) => {
80
+ return (
81
+ <span
82
+ className={`font-sans text-heading5 font-normal leading-[1] text-[0.7rem] text-text-muted select-none whitespace-pre overflow-hidden text-ellipsis ${
83
+ showBackground &&
84
+ "bg-sidebar-background border border-dividerSubtle rounded-[2px] backdrop-blur-[4px] p-[2px_4px]"
85
+ }`}
86
+ >
87
+ {children}
88
+ </span>
89
+ );
90
+ };
219
91
 
220
- const Shimmer = styled.div`
221
- pointer-events: none;
222
- position: absolute;
223
- inset: 0;
224
- animation: ${shimmer} 6s infinite linear;
225
- background: linear-gradient(
226
- 90deg,
227
- rgba(255, 255, 255, 0),
228
- rgba(226, 232, 240, 0.5),
229
- rgba(255, 255, 255, 0)
92
+ const SectionTitle = ({last = false, children}: { last?: boolean; children?: React.ReactNode }) => {
93
+ return (
94
+ <span
95
+ className={`font-sans text-heading3 font-medium user-select-none whitespace-pre overflow-hidden text-ellipsis ${last ? "text-text" : "text-text-muted"}`}
96
+ >
97
+ {children}
98
+ </span>
230
99
  );
231
- background-size: 200% 100%;
232
- display: flex;
233
- flex-direction: column;
234
- justify-content: start;
235
- align-items: end;
236
- padding: 4px;
237
- `;
100
+ };
238
101
 
239
102
  interface ItemProps<MenuItemType extends string = string> {
240
103
  id: string;
@@ -311,48 +174,54 @@ const GridViewItem = forwardRef(function GridViewItem<
311
174
  );
312
175
 
313
176
  let element = (
314
- <ItemContainer
177
+ <div
178
+ className="flex flex-col relative focus:shadow-[0px_0px_0px_1px_var(--sidebar-background),_0px_0px_0px_3px_var(--primary)] focus:outline-none"
315
179
  id={id}
316
180
  ref={forwardedRef}
317
181
  {...hoverProps}
318
182
  tabIndex={disabled ? undefined : 0}
319
183
  onKeyDown={handleKeyDown}
320
184
  >
321
- <ContentContainer
322
- $disabled={disabled}
323
- $bordered={bordered}
324
- $selected={selected}
325
- $hovered={!disabled && hovered}
185
+ <div
186
+ className={cn(
187
+ "flex flex-1 items-center justify-center",
188
+ "bg-sidebar-background rounded-[2px] overflow-hidden",
189
+ "cursor-pointer",
190
+ selected
191
+ ? "border border-primary"
192
+ : bordered
193
+ ? "border border-divider"
194
+ : "border border-transparent",
195
+ disabled ? "opacity-50" : "hover:opacity-85 active:opacity-70"
196
+ )}
326
197
  onClick={handleClick}
327
198
  onDoubleClick={onDoubleClick}
328
199
  onContextMenu={onContextMenu}
329
200
  style={style}
330
201
  >
331
202
  {children}
332
- </ContentContainer>
203
+ </div>
333
204
  {textPosition === "below" && (
334
205
  <>
335
206
  <Spacer.Vertical size={8} />
336
- <ItemTitle $showBackground={false}>{title || " "}</ItemTitle>
337
- <ItemDescription $showBackground={false}>
338
- {subtitle || " "}
339
- </ItemDescription>
207
+ <ItemTitle>{title || " "}</ItemTitle>
208
+ <ItemDescription>{subtitle || " "}</ItemDescription>
340
209
  </>
341
210
  )}
342
211
  {textPosition === "overlay" && hovered && (title || subtitle) && (
343
- <TextOverlay>
344
- {title && <ItemTitle $showBackground>{title}</ItemTitle>}
212
+ <div className="absolute inset-0 flex flex-col justify-end items-start p-1 pointer-events-none truncate g-0.5">
213
+ {title && <ItemTitle showBackground>{title}</ItemTitle>}
345
214
  {subtitle && (
346
- <ItemDescription $showBackground>{subtitle}</ItemDescription>
215
+ <ItemDescription showBackground>{subtitle}</ItemDescription>
347
216
  )}
348
- </TextOverlay>
217
+ </div>
349
218
  )}
350
219
  {loading && (
351
- <Shimmer>
220
+ <div className="flex flex-col justify-start items-end p-1 pointer-events-none animate-shimmer absolute inset-0 bg-gradient-to-r from-white/0 via-[rgb(226,232,240)]/50 to-white/0 bg-length:200%_100%]">
352
221
  <ActivityIndicator opacity={0.5} size={13} />
353
- </Shimmer>
222
+ </div>
354
223
  )}
355
- </ItemContainer>
224
+ </div>
356
225
  );
357
226
 
358
227
  if (menuItems && onSelectMenuItem) {
@@ -367,12 +236,12 @@ const GridViewItem = forwardRef(function GridViewItem<
367
236
  element = (
368
237
  <Tooltip
369
238
  content={
370
- <Stack.V gap={2}>
371
- <ItemTitle $showBackground={false}>{title}</ItemTitle>
372
- <ItemDescription $showBackground={false}>
239
+ <div className="flex flex-col gap-0.5">
240
+ <ItemTitle >{title}</ItemTitle>
241
+ <ItemDescription>
373
242
  {subtitle}
374
243
  </ItemDescription>
375
- </Stack.V>
244
+ </div>
376
245
  }
377
246
  >
378
247
  {element}
@@ -434,26 +303,27 @@ function GridViewRoot({
434
303
 
435
304
  return (
436
305
  <GridViewContext.Provider value={contextValue}>
437
- <Container onClick={handleClick} $scrollable={scrollable}>
306
+ <div onClick={handleClick} className={`flex flex-col ${scrollable ? "flex-1" : "flex-[0_0_auto]"}`}>
438
307
  {scrollable ? <ScrollArea>{children}</ScrollArea> : children}
439
- </Container>
308
+ </div>
440
309
  </GridViewContext.Provider>
441
310
  );
442
311
  }
443
312
 
444
313
  function GridViewSection({
445
314
  children,
446
- padding = "20px",
315
+ className,
447
316
  }: {
448
317
  children?: ReactNode;
449
- padding?: CSSProperties["padding"];
318
+ className?: string;
450
319
  }) {
451
320
  const { size } = useContext(GridViewContext);
321
+ const gapStyle = { gap: `${sizes[size].gap}px` };
452
322
 
453
323
  return (
454
- <Grid $size={size} $padding={padding}>
324
+ <div className={cn(className, "text-text grid", `grid-cols-[auto-fill,_minmax(${sizes[size].itemWidth}px,_1fr)]`)} style={gapStyle}>
455
325
  {children}
456
- </Grid>
326
+ </div>
457
327
  );
458
328
  }
459
329
 
@@ -461,7 +331,7 @@ function GridViewSectionHeader({ title }: { title: string }) {
461
331
  const grouped = title.split("/");
462
332
 
463
333
  return (
464
- <SectionHeaderContainer>
334
+ <div className="px-5">
465
335
  <Spacer.Vertical size={24} />
466
336
  {withSeparatorElements(
467
337
  grouped.map((title, index) => (
@@ -471,7 +341,7 @@ function GridViewSectionHeader({ title }: { title: string }) {
471
341
  )),
472
342
  <SectionTitle> / </SectionTitle>
473
343
  )}
474
- </SectionHeaderContainer>
344
+ </div>
475
345
  );
476
346
  }
477
347
 
@@ -5,7 +5,6 @@ import React, {
5
5
  memo,
6
6
  useMemo,
7
7
  } from "react";
8
- import { useTheme } from "styled-components";
9
8
  import { Button, ButtonRootProps } from "./Button";
10
9
  import { IconName, Icons } from "./Icons";
11
10
 
@@ -23,9 +22,6 @@ export const IconButton = memo(
23
22
  { selected, iconName, color, size, contentStyle, ...props }: Props,
24
23
  forwardedRef: ForwardedRef<HTMLButtonElement>
25
24
  ) {
26
- const { icon: iconColor, iconSelected: iconSelectedColor } =
27
- useTheme().colors;
28
-
29
25
  const Icon = Icons[iconName];
30
26
 
31
27
  const style = useMemo((): CSSProperties => {
@@ -39,7 +35,7 @@ export const IconButton = memo(
39
35
  return (
40
36
  <Button ref={forwardedRef} {...props} variant="none" contentStyle={style}>
41
37
  <Icon
42
- color={color ?? (selected ? iconSelectedColor : iconColor)}
38
+ color={color ?? (selected ? "var(--icon-selected)" : "var(--icon)")}
43
39
  {...(size && { width: size, height: size })}
44
40
  />
45
41
  </Button>