@noya-app/noya-designsystem 0.1.68 → 0.1.69

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noya-app/noya-designsystem",
3
- "version": "0.1.68",
3
+ "version": "0.1.69",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -23,12 +23,12 @@
23
23
  "@base-ui-components/react": "1.0.0-beta.4",
24
24
  "@dnd-kit/core": "6.3.1",
25
25
  "@dnd-kit/sortable": "10.0.0",
26
- "@noya-app/noya-colorpicker": "0.1.29",
27
- "@noya-app/noya-utils": "0.1.8",
28
- "@noya-app/noya-geometry": "0.1.15",
26
+ "@noya-app/noya-colorpicker": "0.1.30",
27
+ "@noya-app/noya-utils": "0.1.9",
28
+ "@noya-app/noya-geometry": "0.1.16",
29
29
  "@noya-app/noya-icons": "0.1.14",
30
30
  "@noya-app/noya-keymap": "0.1.4",
31
- "@noya-app/noya-tailwind-config": "0.1.7",
31
+ "@noya-app/noya-tailwind-config": "0.1.8",
32
32
  "radix-ui": "1.4.2",
33
33
  "@radix-ui/react-compose-refs": "^1.0.0",
34
34
  "@radix-ui/primitive": "^1.0.1",
@@ -82,6 +82,10 @@ export interface CollectionProps<T, M extends string = string> {
82
82
  scrollable?: boolean;
83
83
  itemStyle?: CSSProperties;
84
84
  itemClassName?: string;
85
+ /** Optional per-item style */
86
+ getItemStyle?: (item: T, selected: boolean) => CSSProperties | undefined;
87
+ /** Optional per-item className */
88
+ getItemClassName?: (item: T, selected: boolean) => string | undefined;
85
89
  itemRoleDescription?: string;
86
90
  /** Position of the detail content. Defaults to 'end'. */
87
91
  detailPosition?: "end" | "below";
@@ -89,6 +93,11 @@ export interface CollectionProps<T, M extends string = string> {
89
93
  size?: CollectionItemSize;
90
94
  /** Size of the thumbnail. Defaults to 'auto', which will be based on the size prop. */
91
95
  thumbnailSize?: CollectionThumbnailSize;
96
+ /**
97
+ * Position of the disclosure chevron for expandable lists.
98
+ * @default 'start'
99
+ */
100
+ chevronPosition?: "start" | "end";
92
101
  /** For testing: Override the hover state with a specific item ID */
93
102
  testHoveredId?: string;
94
103
  /** For testing: Override the renaming state with a specific item ID */
@@ -552,8 +552,8 @@ function InputFieldRoot({
552
552
  [onFocusChange]
553
553
  );
554
554
 
555
- const startWidth = measuredStartSize?.width ?? startWidthProp;
556
- const endWidth = measuredEndSize?.width ?? endWidthProp;
555
+ const startWidth = startWidthProp ?? measuredStartSize?.width;
556
+ const endWidth = endWidthProp ?? measuredEndSize?.width;
557
557
 
558
558
  const contextValue = useMemo(
559
559
  (): InputFieldContextValue => ({
@@ -88,6 +88,9 @@ export const List = memoGeneric(
88
88
  sharedDragProps,
89
89
  virtualized,
90
90
  renameSelectsBeforeDot,
91
+ chevronPosition = "start",
92
+ getItemStyle,
93
+ getItemClassName,
91
94
  } = props;
92
95
 
93
96
  const [internalHoveredId, setHoveredId] = useState<string>();
@@ -249,6 +252,9 @@ export const List = memoGeneric(
249
252
  </div>
250
253
  );
251
254
  }
255
+ const perItemStyle = getItemStyle?.(item, isSelected);
256
+ const perItemClassName = getItemClassName?.(item, isSelected);
257
+
252
258
  return (
253
259
  <ViewComponent.Row
254
260
  as={typeof href === "string" ? LinkComponent : undefined}
@@ -260,13 +266,18 @@ export const List = memoGeneric(
260
266
  aria-roledescription={itemRoleDescription}
261
267
  aria-label={getName(item)}
262
268
  aria-selected={isSelected}
263
- className={itemClassName}
269
+ className={cx(itemClassName, perItemClassName)}
264
270
  testRelativeDropPosition={
265
271
  testShowDropIndicatorId === id ? "inside" : undefined
266
272
  }
267
- chevronClassName={cx(expandable && "n-relative n-left-2")}
273
+ chevronClassName={cx(
274
+ expandable && chevronPosition !== "end" && "n-relative n-left-2"
275
+ )}
268
276
  chevronAs={href ? "div" : undefined}
269
- style={itemStyle}
277
+ {...(expandable ? { chevronPosition } : {})}
278
+ style={
279
+ perItemStyle ? { ...itemStyle, ...perItemStyle } : itemStyle
280
+ }
270
281
  hovered={isHovered}
271
282
  selected={isSelected}
272
283
  expanded={expanded}
@@ -3,8 +3,9 @@
3
3
  import { clamp } from "@noya-app/noya-utils";
4
4
  import React, { FocusEventHandler, memo, useCallback, useMemo } from "react";
5
5
  import { useLabel } from "../hooks/useLabel";
6
+ import { cssVars } from "../theme";
6
7
  import { cx } from "../utils/classNames";
7
- import { Button } from "./Button";
8
+ import { IconButton } from "./IconButton";
8
9
  import { InputField } from "./InputField";
9
10
 
10
11
  type ColorScheme = "primary" | "secondary";
@@ -65,12 +66,39 @@ export const Stepper = memo(function Stepper({
65
66
  onFocus={onFocus}
66
67
  onBlur={onBlur}
67
68
  >
68
- <Button
69
- icon="MinusIcon"
70
- disabled={readOnly}
71
- onClick={() => handleValueChange(value - step)}
72
- />
73
- <InputField.Root className="n-flex-1">
69
+ <InputField.Root
70
+ className="n-flex-1"
71
+ startWidth={17}
72
+ startClassName="-n-ml-[3px]"
73
+ endWidth={17}
74
+ endClassName="-n-mr-[3px]"
75
+ start={
76
+ <IconButton
77
+ iconName="MinusIcon"
78
+ disabled={readOnly}
79
+ onClick={() => handleValueChange(value - step)}
80
+ className="n-w-[21px] n-h-[21px]"
81
+ style={{
82
+ outline: `1px solid ${cssVars.colors.dividerStrong}`,
83
+ outlineOffset: "-1px",
84
+ background: cssVars.colors.background,
85
+ }}
86
+ />
87
+ }
88
+ end={
89
+ <IconButton
90
+ iconName="PlusIcon"
91
+ disabled={readOnly}
92
+ onClick={() => handleValueChange(value + step)}
93
+ className="n-w-[21px] n-h-[21px]"
94
+ style={{
95
+ outline: `1px solid ${cssVars.colors.dividerStrong}`,
96
+ outlineOffset: "-1px",
97
+ background: cssVars.colors.background,
98
+ }}
99
+ />
100
+ }
101
+ >
74
102
  <InputField.NumberInput
75
103
  value={value}
76
104
  onChange={handleValueChange}
@@ -78,11 +106,6 @@ export const Stepper = memo(function Stepper({
78
106
  readOnly={readOnly}
79
107
  />
80
108
  </InputField.Root>
81
- <Button
82
- icon="PlusIcon"
83
- disabled={readOnly}
84
- onClick={() => handleValueChange(value + step)}
85
- />
86
109
  </div>
87
110
  );
88
111
  });
@@ -21,6 +21,7 @@ type TreeRowBaseProps = {
21
21
  expanded?: boolean;
22
22
  chevronClassName?: string;
23
23
  chevronAs?: React.ElementType;
24
+ chevronPosition?: "start" | "end";
24
25
  onClickChevron?: ({ altKey }: { altKey: boolean }) => void;
25
26
  onDoubleClick?: () => void;
26
27
  };
@@ -35,6 +36,7 @@ const TreeRow = forwardRefGeneric(function TreeRow<MenuItemType extends string>(
35
36
  onClickChevron,
36
37
  chevronClassName,
37
38
  chevronAs,
39
+ chevronPosition = "start",
38
40
  children,
39
41
  ...rest
40
42
  }: TreeViewRowProps<MenuItemType>,
@@ -55,7 +57,7 @@ const TreeRow = forwardRefGeneric(function TreeRow<MenuItemType extends string>(
55
57
 
56
58
  return (
57
59
  <ListView.Row ref={forwardedRef} {...rest}>
58
- {expandable && (
60
+ {expandable && chevronPosition !== "end" && (
59
61
  <>
60
62
  {expanded === undefined ? (
61
63
  <Spacer.Horizontal size={19} />
@@ -78,6 +80,30 @@ const TreeRow = forwardRefGeneric(function TreeRow<MenuItemType extends string>(
78
80
  </>
79
81
  )}
80
82
  {children}
83
+ {expandable && chevronPosition === "end" && (
84
+ <>
85
+ <Spacer.Horizontal size={6} />
86
+ {expanded === undefined ? (
87
+ <>
88
+ <Spacer.Horizontal size={19} />
89
+ {/* Right-side padding for end chevron */}
90
+ <Spacer.Horizontal size={8} />
91
+ </>
92
+ ) : (
93
+ <>
94
+ <IconButton
95
+ as={chevronAs}
96
+ className={chevronClassName}
97
+ iconName={expanded ? "ChevronDownIcon2" : "ChevronRightIcon2"}
98
+ onClick={handleClickChevron}
99
+ selected={rest.selected}
100
+ />
101
+ {/* Right-side padding for end chevron */}
102
+ <Spacer.Horizontal size={8} />
103
+ </>
104
+ )}
105
+ </>
106
+ )}
81
107
  </ListView.Row>
82
108
  );
83
109
  });
@@ -31,7 +31,7 @@ export const VerticalTabMenu = memoGeneric(function VerticalTabMenu<
31
31
 
32
32
  return (
33
33
  <div
34
- className="n-w-[47px] n-h-full n-bg-sidebar-background n-flex n-flex-col n-items-center n-py-3 n-gap-3"
34
+ className="n-w-[calc(var(--n-toolbar-height)+1px)] n-h-full n-bg-sidebar-background n-flex n-flex-col n-items-center n-py-3 n-gap-3"
35
35
  style={style}
36
36
  >
37
37
  <ToolbarMenu