@noya-app/noya-designsystem 0.1.63 → 0.1.65
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/.turbo/turbo-build.log +13 -10
- package/CHANGELOG.md +25 -0
- package/dist/index.css +1 -1
- package/dist/index.d.mts +648 -333
- package/dist/index.d.ts +648 -333
- package/dist/index.js +13813 -9157
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13949 -9269
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -22
- package/src/__tests__/validateDropIndicator.test.ts +26 -41
- package/src/__tests__/workspaceLayout.test.ts +281 -0
- package/src/components/ActionMenu.tsx +2 -0
- package/src/components/ActivityIndicator.tsx +13 -6
- package/src/components/ActivityLog.tsx +197 -0
- package/src/components/AnimatePresence.tsx +43 -26
- package/src/components/Avatar.tsx +45 -26
- package/src/components/Banner.tsx +57 -11
- package/src/components/BaseToolbar.tsx +67 -34
- package/src/components/Breadcrumbs.tsx +4 -2
- package/src/components/Button.tsx +28 -23
- package/src/components/Checkbox.tsx +6 -35
- package/src/components/Chip.tsx +47 -33
- package/src/components/Collection.tsx +20 -12
- package/src/components/ColorSwatch.tsx +42 -22
- package/src/components/ColorSwatchControl.tsx +7 -5
- package/src/components/Combobox.tsx +8 -6
- package/src/components/ComboboxMenu.tsx +6 -5
- package/src/components/CommandPalette.tsx +3 -1
- package/src/components/ContextMenu.tsx +3 -1
- package/src/components/Dialog.tsx +9 -13
- package/src/components/DimensionInput.tsx +2 -0
- package/src/components/Divider.tsx +18 -14
- package/src/components/DraggableMenuButton.tsx +11 -5
- package/src/components/Drawer.tsx +14 -6
- package/src/components/DropdownMenu.tsx +4 -2
- package/src/components/EditableText.tsx +4 -2
- package/src/components/Fade.tsx +13 -13
- package/src/components/FileUploadIndicator.tsx +108 -0
- package/src/components/FloatingWindow.tsx +4 -2
- package/src/components/Grid.tsx +58 -42
- package/src/components/GridView.tsx +65 -36
- package/src/components/IVirtualizedList.tsx +5 -0
- package/src/components/IconButton.tsx +2 -0
- package/src/components/Icons.tsx +24 -4
- package/src/components/InputField.tsx +21 -19
- package/src/components/InspectorContainer.tsx +2 -2
- package/src/components/InspectorPrimitives.tsx +15 -9
- package/src/components/Label.tsx +4 -3
- package/src/components/LabeledElementView.tsx +9 -5
- package/src/components/LabeledField.tsx +8 -6
- package/src/components/List.tsx +112 -46
- package/src/components/ListMenu.tsx +91 -0
- package/src/components/ListNavigator.tsx +106 -0
- package/src/components/ListView.tsx +22 -1147
- package/src/components/MediaThumbnail.tsx +84 -14
- package/src/components/Message.tsx +11 -12
- package/src/components/Navigator.tsx +461 -0
- package/src/components/NoyaLogo.tsx +1 -1
- package/src/components/Popover.tsx +12 -6
- package/src/components/Progress.tsx +31 -8
- package/src/components/ResizableContainer.tsx +187 -0
- package/src/components/RingProgress.tsx +128 -0
- package/src/components/ScrollArea.tsx +7 -5
- package/src/components/ScrollableSidebar.tsx +10 -0
- package/src/components/SearchCompletionMenu.tsx +5 -3
- package/src/components/Section.tsx +109 -57
- package/src/components/SegmentedControl.tsx +51 -25
- package/src/components/SelectMenu.tsx +16 -21
- package/src/components/SelectionToolbar.tsx +7 -4
- package/src/components/Slider.tsx +12 -10
- package/src/components/Spacer.tsx +2 -2
- package/src/components/StackNavigator.tsx +378 -0
- package/src/components/Stepper.tsx +88 -0
- package/src/components/Switch.tsx +7 -5
- package/src/components/Tabs.tsx +6 -4
- package/src/components/Text.tsx +29 -18
- package/src/components/TextArea.tsx +5 -3
- package/src/components/Toast.tsx +5 -5
- package/src/components/Toolbar.tsx +57 -10
- package/src/components/ToolbarDrawer.tsx +29 -0
- package/src/components/Tooltip.tsx +2 -2
- package/src/components/TreeView.tsx +13 -4
- package/src/components/UserPointer.tsx +6 -4
- package/src/components/ai-assistant/AIAssistantLayout.tsx +10 -8
- package/src/components/blocks/ImageBlockComponent.tsx +162 -0
- package/src/components/connected-users-menu/ConnectedUsersMenuLayout.tsx +6 -4
- package/src/components/file-explorer/FileExplorerLayout.tsx +22 -8
- package/src/components/internal/Checkmark.tsx +24 -0
- package/src/components/internal/Menu.tsx +24 -19
- package/src/components/internal/MenuViewport.tsx +15 -6
- package/src/components/internal/SelectItem.tsx +7 -26
- package/src/components/internal/TextInput.tsx +7 -1
- package/src/components/listView/ListViewContexts.tsx +68 -0
- package/src/components/listView/ListViewEditableRowTitle.tsx +55 -0
- package/src/components/listView/ListViewRoot.tsx +521 -0
- package/src/components/listView/ListViewRow.tsx +475 -0
- package/src/components/listView/ListViewRowTitle.tsx +21 -0
- package/src/components/listView/types.ts +11 -0
- package/src/components/pipeline/PipelineResultLayout.tsx +6 -6
- package/src/components/sorting/DragRegistration.tsx +10 -5
- package/src/components/sorting/SharedDragProvider.tsx +134 -27
- package/src/components/sorting/Sortable.tsx +90 -27
- package/src/components/sorting/createSharedDrag.tsx +7 -6
- package/src/components/sorting/sorting.ts +6 -9
- package/src/components/workspace/DrawerWorkspaceLayout.tsx +110 -29
- package/src/components/workspace/PanelWorkspaceLayout.tsx +148 -99
- package/src/components/workspace/VerticalTabMenu.tsx +46 -0
- package/src/components/workspace/WorkspaceLayout.tsx +76 -63
- package/src/components/workspace/constants.ts +4 -0
- package/src/components/workspace/panelStorage.ts +216 -0
- package/src/components/workspace/types.ts +11 -4
- package/src/contexts/DesignSystemConfiguration.tsx +12 -5
- package/src/contexts/DialogContext.tsx +19 -5
- package/src/contexts/FloatingWindowContext.tsx +2 -0
- package/src/contexts/GlobalInputBlurContext.tsx +2 -0
- package/src/contexts/ImageDataContext.tsx +2 -0
- package/src/contexts/LinkComponentContext.tsx +17 -0
- package/src/contexts/OpenPortalsContext.tsx +2 -0
- package/src/contexts/PortalScopeContext.tsx +2 -0
- package/src/hooks/mergeEventHandlers.ts +1 -1
- package/src/hooks/useHover.ts +30 -17
- package/src/hooks/useIndent.ts +5 -8
- package/src/hooks/useLabel.ts +2 -0
- package/src/hooks/useObjectURL.ts +5 -3
- package/src/hooks/usePlatform.ts +5 -3
- package/src/hooks/useTheme.ts +3 -1
- package/src/index.css +43 -10
- package/src/index.tsx +15 -7
- package/src/utils/classNames.ts +56 -9
- package/src/utils/combobox.ts +2 -0
- package/src/utils/editableBlockStyles.ts +2 -2
- package/src/utils/formatByteSize.ts +9 -0
- package/src/utils/inputs.ts +8 -6
- package/src/utils/sketchColor.ts +0 -34
- package/src/utils/withSeparatorElements.ts +1 -1
- package/tailwind.config.ts +1 -0
- package/src/components/FillInputField.tsx +0 -37
- package/src/components/FillPreviewBackground.tsx +0 -132
- package/src/components/GradientPicker.tsx +0 -88
- package/src/hooks/usePreservePanelSize.tsx +0 -183
- package/src/mediaQuery.ts +0 -13
- package/src/utils/getGradientBackground.tsx +0 -31
|
@@ -68,7 +68,7 @@ export const separator: SeparatorItem = {
|
|
|
68
68
|
|
|
69
69
|
type FalsyReactNode = false | "" | null | undefined;
|
|
70
70
|
|
|
71
|
-
export type MenuItemIcon = IconName | React.ReactElement | FalsyReactNode;
|
|
71
|
+
export type MenuItemIcon = IconName | React.ReactElement<any> | FalsyReactNode;
|
|
72
72
|
|
|
73
73
|
type BaseMenuItem = {
|
|
74
74
|
checked?: boolean;
|
|
@@ -93,6 +93,7 @@ export type SelectableMenuItem<T extends string> = BaseMenuItem & {
|
|
|
93
93
|
value: T;
|
|
94
94
|
testSelected?: boolean;
|
|
95
95
|
tooltip?: ReactNode;
|
|
96
|
+
drawer?: ReactNode;
|
|
96
97
|
};
|
|
97
98
|
|
|
98
99
|
export type SubMenuItem<T extends string> = BaseMenuItem & {
|
|
@@ -147,6 +148,10 @@ export const isMenuItemSectionHeader = (
|
|
|
147
148
|
item: MenuItem<string>
|
|
148
149
|
): item is SectionHeaderMenuItem => item.type === "sectionHeader";
|
|
149
150
|
|
|
151
|
+
export const isSubMenuItem = <T extends string>(
|
|
152
|
+
item: MenuItem<T>
|
|
153
|
+
): item is SubMenuItem<T> => item.type === "submenu";
|
|
154
|
+
|
|
150
155
|
export const isSelectableMenuItemWithScore = (
|
|
151
156
|
item: MenuItem<string>
|
|
152
157
|
): item is ScoredSelectableMenuItem<string> =>
|
|
@@ -179,27 +184,27 @@ export const CHECKBOX_RIGHT_INSET = 6;
|
|
|
179
184
|
export const CHECKBOX_INDENT_WIDTH = 6;
|
|
180
185
|
|
|
181
186
|
export const styles = {
|
|
182
|
-
separatorStyle: "h-px bg-divider mx-3 my-1",
|
|
187
|
+
separatorStyle: "n-h-px n-bg-divider n-mx-3 n-my-1",
|
|
183
188
|
selectedItemStyle:
|
|
184
|
-
"focus:outline-none focus:text-selected-list-item-text focus:bg-selected-list-item-background focus:kbd:text-selected-list-item-text",
|
|
189
|
+
"focus:n-outline-none focus:n-text-selected-list-item-text focus:n-bg-selected-list-item-background focus:kbd:n-text-selected-list-item-text",
|
|
185
190
|
testSelectedItemStyle:
|
|
186
|
-
"outline-none text-selected-list-item-text bg-selected-list-item-background kbd:text-selected-list-item-text",
|
|
191
|
+
"n-outline-none n-text-selected-list-item-text n-bg-selected-list-item-background kbd:n-text-selected-list-item-text",
|
|
187
192
|
itemStyle: ({ disabled }: { disabled?: boolean }) => `
|
|
188
|
-
flex-none select-none cursor-pointer rounded
|
|
189
|
-
py-1.5 px-2
|
|
190
|
-
transition-colors
|
|
191
|
-
flex items-center
|
|
192
|
-
font-sans text-button font-medium
|
|
193
|
-
${disabled ? "text-text-disabled" : ""}
|
|
193
|
+
n-flex-none n-select-none n-cursor-pointer n-rounded
|
|
194
|
+
n-py-1.5 n-px-2
|
|
195
|
+
n-transition-colors
|
|
196
|
+
n-flex n-items-center
|
|
197
|
+
n-font-sans n-text-button n-font-medium
|
|
198
|
+
${disabled ? "n-text-text-disabled" : ""}
|
|
194
199
|
`,
|
|
195
200
|
itemIndicator: {
|
|
196
|
-
className: "flex items-center relative -left-2.5",
|
|
201
|
+
className: "n-flex n-items-center n-relative -n-left-2.5",
|
|
197
202
|
style: {
|
|
198
203
|
marginRight: -CHECKBOX_RIGHT_INSET,
|
|
199
204
|
},
|
|
200
205
|
},
|
|
201
206
|
contentStyle:
|
|
202
|
-
"rounded bg-popover-background text-text shadow-popover z-menu py-1",
|
|
207
|
+
"n-rounded n-bg-popover-background n-text-text n-shadow-popover n-z-menu n-py-1",
|
|
203
208
|
};
|
|
204
209
|
|
|
205
210
|
function getKeyboardShortcuts<T extends string>(
|
|
@@ -237,8 +242,8 @@ const ShortcutElement = ({
|
|
|
237
242
|
<kbd
|
|
238
243
|
className={cx(
|
|
239
244
|
textStyles.small,
|
|
240
|
-
"text-inherit opacity-60 tabular-nums",
|
|
241
|
-
fixedWidth && "w-[0.9rem] text-center"
|
|
245
|
+
"n-text-inherit n-opacity-60 n-tabular-nums",
|
|
246
|
+
fixedWidth && "n-w-[0.9rem] n-text-center"
|
|
242
247
|
)}
|
|
243
248
|
>
|
|
244
249
|
{children}
|
|
@@ -275,7 +280,7 @@ export const KeyboardShortcut = memo(function KeyboardShortcut({
|
|
|
275
280
|
);
|
|
276
281
|
});
|
|
277
282
|
|
|
278
|
-
export const
|
|
283
|
+
export const SectionHeaderMenuItem = memo(function SectionHeaderMenuItem({
|
|
279
284
|
title,
|
|
280
285
|
variant = "normal",
|
|
281
286
|
id,
|
|
@@ -291,10 +296,10 @@ export const SectionHeader = memo(function SectionHeader({
|
|
|
291
296
|
className={mergeConflictingClassNames(
|
|
292
297
|
[
|
|
293
298
|
variant === "label"
|
|
294
|
-
?
|
|
295
|
-
: "font-sans text-heading5 font-normal",
|
|
296
|
-
"bg-listview-raised-background flex items-center py-1.5 px-3",
|
|
297
|
-
isFirst && "-mt-1",
|
|
299
|
+
? `${textStyles.label} n-font-bold n-text-text-disabled`
|
|
300
|
+
: "n-font-sans n-text-heading5 n-font-normal",
|
|
301
|
+
"n-bg-listview-raised-background n-flex n-items-center n-py-1.5 n-px-3",
|
|
302
|
+
isFirst && "-n-mt-1",
|
|
298
303
|
],
|
|
299
304
|
{
|
|
300
305
|
categories: ["font"],
|
|
@@ -1,13 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { ChevronRightIcon } from "@noya-app/noya-icons";
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
+
import {
|
|
5
|
+
ContextMenu as RadixContextMenu,
|
|
6
|
+
DropdownMenu as RadixDropdownMenu,
|
|
7
|
+
} from "radix-ui";
|
|
4
8
|
import React from "react";
|
|
5
9
|
import {
|
|
6
10
|
portalScopeProps,
|
|
7
11
|
usePortalScopeId,
|
|
8
12
|
} from "../../contexts/PortalScopeContext";
|
|
9
13
|
import { cx } from "../../utils/classNames";
|
|
10
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
isSelectableMenuItem,
|
|
16
|
+
MenuItem,
|
|
17
|
+
SectionHeaderMenuItem,
|
|
18
|
+
styles,
|
|
19
|
+
} from "./Menu";
|
|
11
20
|
import { SelectItem } from "./SelectItem";
|
|
12
21
|
|
|
13
22
|
type MenuSeparatorComponent = React.FC<{ className?: string }>;
|
|
@@ -83,7 +92,7 @@ export const MenuViewport = <T extends string>({
|
|
|
83
92
|
|
|
84
93
|
case "sectionHeader":
|
|
85
94
|
return (
|
|
86
|
-
<
|
|
95
|
+
<SectionHeaderMenuItem
|
|
87
96
|
isFirst={index === 0}
|
|
88
97
|
key={item.id}
|
|
89
98
|
{...item}
|
|
@@ -123,10 +132,10 @@ export const MenuViewport = <T extends string>({
|
|
|
123
132
|
indented={hasCheckedItem}
|
|
124
133
|
disabled={item.disabled}
|
|
125
134
|
>
|
|
126
|
-
<div className="flex items-center flex-1">
|
|
135
|
+
<div className="n-flex n-items-center n-flex-1">
|
|
127
136
|
{item.title}
|
|
128
137
|
</div>
|
|
129
|
-
<ChevronRightIcon className="-mr-1" />
|
|
138
|
+
<ChevronRightIcon className="-n-mr-1" />
|
|
130
139
|
</SelectItem>
|
|
131
140
|
</Components.SubTrigger>
|
|
132
141
|
<Components.Portal>
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { renderIcon } from "../Icons";
|
|
2
4
|
|
|
3
|
-
import
|
|
5
|
+
import { Select } from "radix-ui";
|
|
4
6
|
import React, { useCallback } from "react";
|
|
5
7
|
import { cx } from "../../utils/classNames";
|
|
6
8
|
import { Spacer } from "../Spacer";
|
|
9
|
+
import { Checkmark } from "./Checkmark";
|
|
7
10
|
import {
|
|
8
11
|
CHECKBOX_INDENT_WIDTH,
|
|
9
12
|
CHECKBOX_RIGHT_INSET,
|
|
@@ -53,7 +56,7 @@ export const SelectItem = React.forwardRef(
|
|
|
53
56
|
|
|
54
57
|
if (checked && Components.CheckboxItem) {
|
|
55
58
|
return (
|
|
56
|
-
<div className="px-1">
|
|
59
|
+
<div className="n-px-1">
|
|
57
60
|
<Components.CheckboxItem
|
|
58
61
|
checked={checked}
|
|
59
62
|
disabled={disabled}
|
|
@@ -90,7 +93,7 @@ export const SelectItem = React.forwardRef(
|
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
return (
|
|
93
|
-
<div className="px-1">
|
|
96
|
+
<div className="n-px-1">
|
|
94
97
|
<Components.Item
|
|
95
98
|
className={cx(
|
|
96
99
|
styles.itemStyle({ disabled }),
|
|
@@ -104,7 +107,7 @@ export const SelectItem = React.forwardRef(
|
|
|
104
107
|
onSelect={handleSelectItem}
|
|
105
108
|
{...props}
|
|
106
109
|
>
|
|
107
|
-
<div className="flex flex-1 items-center">
|
|
110
|
+
<div className="n-flex n-flex-1 n-items-center">
|
|
108
111
|
{indented && <Spacer.Horizontal size={CHECKBOX_INDENT_WIDTH} />}
|
|
109
112
|
{checked ? (
|
|
110
113
|
<div {...styles.itemIndicator}>
|
|
@@ -133,25 +136,3 @@ export const SelectItem = React.forwardRef(
|
|
|
133
136
|
);
|
|
134
137
|
}
|
|
135
138
|
);
|
|
136
|
-
|
|
137
|
-
function Checkmark() {
|
|
138
|
-
return (
|
|
139
|
-
<svg
|
|
140
|
-
viewBox="0 0 15 15"
|
|
141
|
-
fill="none"
|
|
142
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
143
|
-
aria-hidden="true"
|
|
144
|
-
width={15}
|
|
145
|
-
height={15}
|
|
146
|
-
>
|
|
147
|
-
<path
|
|
148
|
-
className="scale-90 origin-center"
|
|
149
|
-
d="M3 8L6 11L12 5"
|
|
150
|
-
strokeWidth="1.1"
|
|
151
|
-
strokeLinecap="round"
|
|
152
|
-
strokeLinejoin="round"
|
|
153
|
-
stroke="currentColor"
|
|
154
|
-
/>
|
|
155
|
-
</svg>
|
|
156
|
-
);
|
|
157
|
-
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { composeRefs } from "@radix-ui/react-compose-refs";
|
|
2
4
|
import React, {
|
|
3
5
|
AriaRole,
|
|
@@ -53,7 +55,7 @@ const ReadOnlyTextInput = forwardRef(function ReadOnlyTextInput(
|
|
|
53
55
|
value={value}
|
|
54
56
|
onKeyDown={onKeyDown}
|
|
55
57
|
readOnly
|
|
56
|
-
className="focus:z-interactable"
|
|
58
|
+
className="focus:n-z-interactable"
|
|
57
59
|
/>
|
|
58
60
|
);
|
|
59
61
|
});
|
|
@@ -296,6 +298,10 @@ export default forwardRef(function TextInput(
|
|
|
296
298
|
(event: React.MouseEvent) => event.stopPropagation(),
|
|
297
299
|
[]
|
|
298
300
|
),
|
|
301
|
+
onDoubleClick: useCallback(
|
|
302
|
+
(event: React.MouseEvent) => event.stopPropagation(),
|
|
303
|
+
[]
|
|
304
|
+
),
|
|
299
305
|
autoComplete: "off",
|
|
300
306
|
autoCapitalize: "off",
|
|
301
307
|
autoCorrect: "off",
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { createContext, ReactNode } from "react";
|
|
4
|
+
import {
|
|
5
|
+
ListColorScheme,
|
|
6
|
+
ListRowMarginType,
|
|
7
|
+
ListRowPosition,
|
|
8
|
+
ListViewSectionHeaderVariant,
|
|
9
|
+
ListViewVariant,
|
|
10
|
+
PressEventName,
|
|
11
|
+
} from "./types";
|
|
12
|
+
|
|
13
|
+
export type ListViewContextValue = {
|
|
14
|
+
pressEventName: PressEventName;
|
|
15
|
+
colorScheme: ListColorScheme;
|
|
16
|
+
gap: number;
|
|
17
|
+
sectionHeaderVariant: ListViewSectionHeaderVariant;
|
|
18
|
+
variant: ListViewVariant;
|
|
19
|
+
divider: boolean;
|
|
20
|
+
sortable: boolean;
|
|
21
|
+
expandable: boolean; // Used only by TreeView
|
|
22
|
+
indentation: number;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const ListViewContext = createContext<ListViewContextValue>({
|
|
26
|
+
pressEventName: "onClick",
|
|
27
|
+
colorScheme: "primary",
|
|
28
|
+
gap: 0,
|
|
29
|
+
sectionHeaderVariant: "normal",
|
|
30
|
+
variant: "normal",
|
|
31
|
+
divider: false,
|
|
32
|
+
sortable: false,
|
|
33
|
+
expandable: true,
|
|
34
|
+
indentation: 12,
|
|
35
|
+
});
|
|
36
|
+
(ListViewContext as any).displayName = "ListViewContext";
|
|
37
|
+
|
|
38
|
+
// TODO: Some of these could be passed in a single context value that's
|
|
39
|
+
// the same for all rows. But doing this seems to cause an infinite loop and
|
|
40
|
+
// prevents drag and drop from working.
|
|
41
|
+
export type ListRowContextValue = {
|
|
42
|
+
marginType: ListRowMarginType;
|
|
43
|
+
selectedPosition: ListRowPosition;
|
|
44
|
+
isSectionHeader: boolean;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// The dragged item isn't passed a context value (doing so causes an infinite loop),
|
|
48
|
+
// so we pass this separately. Rows need the indentation to look correct when dragging,
|
|
49
|
+
// and the dragged row doesn't have a ListRowContextValue.
|
|
50
|
+
export type ListViewDraggingContextValue = {
|
|
51
|
+
isDragOverlay?: boolean;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const ListViewDraggingContext =
|
|
55
|
+
createContext<ListViewDraggingContextValue>({});
|
|
56
|
+
(ListViewDraggingContext as any).displayName = "ListViewDraggingContext";
|
|
57
|
+
|
|
58
|
+
export const ListRowContext = createContext<ListRowContextValue>({
|
|
59
|
+
marginType: "none",
|
|
60
|
+
selectedPosition: "only",
|
|
61
|
+
isSectionHeader: false,
|
|
62
|
+
});
|
|
63
|
+
(ListRowContext as any).displayName = "ListRowContext";
|
|
64
|
+
|
|
65
|
+
export const RenderItemContext = createContext<(index: number) => ReactNode>(
|
|
66
|
+
() => null
|
|
67
|
+
);
|
|
68
|
+
(RenderItemContext as any).displayName = "RenderItemContext";
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React, { memo, useLayoutEffect, useRef } from "react";
|
|
4
|
+
import { cx } from "../../utils/classNames";
|
|
5
|
+
import { InputField } from "../InputField";
|
|
6
|
+
|
|
7
|
+
export interface EditableRowTitleProps {
|
|
8
|
+
value: string;
|
|
9
|
+
onSubmitEditing: (value: string) => void;
|
|
10
|
+
autoFocus: boolean;
|
|
11
|
+
placeholder?: string;
|
|
12
|
+
className?: string;
|
|
13
|
+
onKeyDown?: (e: React.KeyboardEvent) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const ListViewEditableRowTitle = memo(function ListViewEditableRowTitle({
|
|
17
|
+
value,
|
|
18
|
+
onSubmitEditing,
|
|
19
|
+
autoFocus,
|
|
20
|
+
placeholder,
|
|
21
|
+
className,
|
|
22
|
+
onKeyDown,
|
|
23
|
+
}: EditableRowTitleProps) {
|
|
24
|
+
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
25
|
+
|
|
26
|
+
useLayoutEffect(() => {
|
|
27
|
+
const element = inputRef.current;
|
|
28
|
+
|
|
29
|
+
if (!element || !autoFocus) return;
|
|
30
|
+
|
|
31
|
+
// Calling `focus` is necessary, in addition to `select`, to ensure
|
|
32
|
+
// the `onBlur` fires correctly.
|
|
33
|
+
element.focus();
|
|
34
|
+
|
|
35
|
+
// must be a delay of 1ms or more to ensure any radix ui components have finished any focus behaviors
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
element.select();
|
|
38
|
+
}, 1);
|
|
39
|
+
}, [autoFocus]);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<InputField.Input
|
|
43
|
+
ref={inputRef}
|
|
44
|
+
value={value}
|
|
45
|
+
placeholder={placeholder}
|
|
46
|
+
onSubmit={onSubmitEditing}
|
|
47
|
+
allowSubmittingWithSameValue
|
|
48
|
+
className={cx(
|
|
49
|
+
"-n-mx-1.5 -n-my-1 n-bg-listview-editing-background",
|
|
50
|
+
className
|
|
51
|
+
)}
|
|
52
|
+
onKeyDown={onKeyDown}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
});
|