@wallarm-org/design-system 1.18.2 → 1.20.0
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/dist/components/AppShell/story-content/_storySearchModal.js +6 -5
- package/dist/components/CopyButton/CopyButton.js +3 -1
- package/dist/components/Resizable/ResizableHandle.d.ts +0 -2
- package/dist/components/Resizable/ResizableHandle.js +3 -11
- package/dist/components/Resizable/classes.d.ts +0 -1
- package/dist/components/Resizable/classes.js +3 -4
- package/dist/components/ScrollArea/ScrollArea.d.ts +5 -2
- package/dist/components/ScrollArea/ScrollArea.js +2 -3
- package/dist/components/ScrollArea/ScrollAreaContent.d.ts +5 -2
- package/dist/components/ScrollArea/ScrollAreaContent.js +3 -2
- package/dist/components/ScrollArea/ScrollAreaCorner.d.ts +5 -2
- package/dist/components/ScrollArea/ScrollAreaCorner.js +3 -2
- package/dist/components/ScrollArea/ScrollAreaScrollbar.d.ts +5 -2
- package/dist/components/ScrollArea/ScrollAreaScrollbar.js +3 -2
- package/dist/components/ScrollArea/ScrollAreaViewport.d.ts +2 -1
- package/dist/components/ScrollArea/ScrollAreaViewport.js +3 -2
- package/dist/components/ScrollArea/index.d.ts +1 -1
- package/dist/components/SearchModal/SearchModalEmpty.js +1 -1
- package/dist/components/SearchModal/SearchModalFooter.js +16 -6
- package/dist/components/SearchModal/SearchModalInput.js +13 -6
- package/dist/components/SearchModal/classes.js +6 -6
- package/dist/components/SimpleCharts/AreaChart/AreaChartArea.js +2 -5
- package/dist/components/SimpleCharts/AreaChart/constants.d.ts +3 -1
- package/dist/components/SimpleCharts/AreaChart/constants.js +3 -2
- package/dist/components/SimpleCharts/LineChart/LineChartLegendItem.js +3 -1
- package/dist/components/SimpleCharts/LineChart/LineChartLine.js +2 -5
- package/dist/components/SimpleCharts/LineChart/classes.d.ts +1 -0
- package/dist/components/SimpleCharts/LineChart/classes.js +14 -2
- package/dist/index.d.ts +1 -1
- package/dist/metadata/components.json +310 -26
- package/dist/theme/components/chart.css +8 -0
- package/dist/theme/index.css +1 -0
- package/package.json +1 -1
|
@@ -7,6 +7,7 @@ import { EmptyState, EmptyStateDescription, EmptyStateMessage } from "../../Empt
|
|
|
7
7
|
import { Kbd } from "../../Kbd/index.js";
|
|
8
8
|
import { SearchModal, SearchModalBody, SearchModalContent, SearchModalEmpty, SearchModalFooter, SearchModalGroup, SearchModalGroupLabel, SearchModalInput, SearchModalItem, SearchModalTrigger } from "../../SearchModal/index.js";
|
|
9
9
|
import { Text } from "../../Text/index.js";
|
|
10
|
+
import { WallyIcon } from "../../WallyIcon/index.js";
|
|
10
11
|
const recentItems = [
|
|
11
12
|
{
|
|
12
13
|
page: 'Attacks',
|
|
@@ -130,9 +131,9 @@ const StorySearchModal = ()=>{
|
|
|
130
131
|
/*#__PURE__*/ jsxs(SearchModalItem, {
|
|
131
132
|
onSelect: ()=>{},
|
|
132
133
|
children: [
|
|
133
|
-
/*#__PURE__*/ jsx(
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
/*#__PURE__*/ jsx(WallyIcon, {
|
|
135
|
+
variant: "circle",
|
|
136
|
+
size: "sm"
|
|
136
137
|
}),
|
|
137
138
|
/*#__PURE__*/ jsx(Text, {
|
|
138
139
|
size: "sm",
|
|
@@ -184,7 +185,7 @@ const StorySearchModal = ()=>{
|
|
|
184
185
|
onSelect: ()=>{},
|
|
185
186
|
children: [
|
|
186
187
|
/*#__PURE__*/ jsx(LoaderCircle, {
|
|
187
|
-
className: "text-text-
|
|
188
|
+
className: "text-text-primary shrink-0 !icon-md"
|
|
188
189
|
}),
|
|
189
190
|
/*#__PURE__*/ jsxs(Text, {
|
|
190
191
|
size: "sm",
|
|
@@ -230,7 +231,7 @@ const StorySearchModal = ()=>{
|
|
|
230
231
|
onSelect: ()=>{},
|
|
231
232
|
children: [
|
|
232
233
|
/*#__PURE__*/ jsx(LoaderCircle, {
|
|
233
|
-
className: "text-text-
|
|
234
|
+
className: "text-text-primary shrink-0 !icon-md"
|
|
234
235
|
}),
|
|
235
236
|
/*#__PURE__*/ jsx(Text, {
|
|
236
237
|
size: "sm",
|
|
@@ -2,10 +2,11 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useLayoutEffect, useRef, useState } from "react";
|
|
3
3
|
import { useCopyTooltip } from "../../hooks/index.js";
|
|
4
4
|
import { Check, Copy } from "../../icons/index.js";
|
|
5
|
+
import { cn } from "../../utils/cn.js";
|
|
5
6
|
import { mergeRefs } from "../../utils/mergeRefs.js";
|
|
6
7
|
import { Button } from "../Button/index.js";
|
|
7
8
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../Tooltip/index.js";
|
|
8
|
-
const CopyButton = ({ text, label, copiedLabel = 'Copied', tooltipText = 'Click to copy', copiedTooltipText = 'Copied', onClick, variant = 'ghost', color = 'neutral', size, style, ref, ...props })=>{
|
|
9
|
+
const CopyButton = ({ text, label, copiedLabel = 'Copied', tooltipText = 'Click to copy', copiedTooltipText = 'Copied', onClick, variant = 'ghost', color = 'neutral', size, style, className, ref, ...props })=>{
|
|
9
10
|
const { copied, tooltipOpen, onTooltipOpenChange, handleCopy } = useCopyTooltip({
|
|
10
11
|
text
|
|
11
12
|
});
|
|
@@ -36,6 +37,7 @@ const CopyButton = ({ text, label, copiedLabel = 'Copied', tooltipText = 'Click
|
|
|
36
37
|
color: color,
|
|
37
38
|
size: resolvedSize,
|
|
38
39
|
"aria-label": label ?? 'Copy',
|
|
40
|
+
className: cn(label ? 'justify-start px-12' : 'px-3', className),
|
|
39
41
|
"data-slot": "copy-button",
|
|
40
42
|
...props,
|
|
41
43
|
onClick: handleClick,
|
|
@@ -3,7 +3,5 @@ import { type SeparatorProps } from 'react-resizable-panels';
|
|
|
3
3
|
import { type TestableProps } from '../../utils/testId';
|
|
4
4
|
export interface ResizableHandleProps extends Omit<HTMLAttributes<HTMLDivElement>, 'id' | 'role' | 'tabIndex'>, Pick<SeparatorProps, 'disabled' | 'disableDoubleClick'>, TestableProps {
|
|
5
5
|
ref?: Ref<HTMLDivElement>;
|
|
6
|
-
/** Show a visible grip icon on the handle. */
|
|
7
|
-
withHandle?: boolean;
|
|
8
6
|
}
|
|
9
7
|
export declare const ResizableHandle: FC<ResizableHandleProps>;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Separator } from "react-resizable-panels";
|
|
3
|
-
import { GripVertical } from "../../icons/index.js";
|
|
4
3
|
import { cn } from "../../utils/cn.js";
|
|
5
4
|
import { useTestId } from "../../utils/testId.js";
|
|
6
|
-
import {
|
|
5
|
+
import { resizableHandleVariants } from "./classes.js";
|
|
7
6
|
import { useResizableContext } from "./ResizableContext.js";
|
|
8
|
-
const ResizableHandle = ({ ref, className,
|
|
7
|
+
const ResizableHandle = ({ ref, className, 'data-testid': testIdProp, ...props })=>{
|
|
9
8
|
const testId = useTestId('handle', testIdProp);
|
|
10
9
|
const { orientation } = useResizableContext();
|
|
11
10
|
return /*#__PURE__*/ jsx(Separator, {
|
|
@@ -15,14 +14,7 @@ const ResizableHandle = ({ ref, className, withHandle = false, 'data-testid': te
|
|
|
15
14
|
"data-testid": testId,
|
|
16
15
|
className: cn(resizableHandleVariants({
|
|
17
16
|
orientation
|
|
18
|
-
}), className)
|
|
19
|
-
children: withHandle && /*#__PURE__*/ jsx("div", {
|
|
20
|
-
className: resizableHandleGripVariants(),
|
|
21
|
-
"data-slot": "resizable-handle-grip",
|
|
22
|
-
children: /*#__PURE__*/ jsx(GripVertical, {
|
|
23
|
-
className: "size-10"
|
|
24
|
-
})
|
|
25
|
-
})
|
|
17
|
+
}), className)
|
|
26
18
|
});
|
|
27
19
|
};
|
|
28
20
|
ResizableHandle.displayName = 'ResizableHandle';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export declare const resizableHandleVariants: (props?: ({
|
|
2
2
|
orientation?: "horizontal" | "vertical" | null | undefined;
|
|
3
3
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
4
|
-
export declare const resizableHandleGripVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
@@ -3,13 +3,12 @@ import { cn } from "../../utils/cn.js";
|
|
|
3
3
|
const resizableHandleVariants = cva(cn('relative', 'flex items-center justify-center', 'outline-none', 'bg-border-primary', 'before:absolute before:content-[""]', 'before:rounded-full', 'before:bg-bg-fill-brand', 'before:opacity-0', 'before:transition-opacity before:duration-150', 'after:absolute after:content-[""]', 'after:z-10', 'hover:before:opacity-100', 'data-[separator=active]:before:opacity-100', 'focus-visible:before:opacity-100', 'focus-visible:ring-2 focus-visible:ring-focus-primary focus-visible:ring-offset-0'), {
|
|
4
4
|
variants: {
|
|
5
5
|
orientation: {
|
|
6
|
-
horizontal: cn('w-px', 'cursor-col-resize', 'before:w-3 before:inset-y-0', 'after:inset-y-0 after:-inset-x-6'
|
|
7
|
-
vertical: cn('h-px', 'cursor-row-resize', 'before:h-3 before:inset-x-0', 'after:inset-x-0 after:-inset-y-6'
|
|
6
|
+
horizontal: cn('w-px', 'cursor-col-resize', 'before:w-3 before:inset-y-0', 'after:inset-y-0 after:-inset-x-6'),
|
|
7
|
+
vertical: cn('h-px', 'cursor-row-resize', 'before:h-3 before:inset-x-0', 'after:inset-x-0 after:-inset-y-6')
|
|
8
8
|
}
|
|
9
9
|
},
|
|
10
10
|
defaultVariants: {
|
|
11
11
|
orientation: 'horizontal'
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
|
-
|
|
15
|
-
export { resizableHandleGripVariants, resizableHandleVariants };
|
|
14
|
+
export { resizableHandleVariants };
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import type { FC, Ref } from 'react';
|
|
1
2
|
import { ScrollArea as ArkUiScrollArea } from '@ark-ui/react/scroll-area';
|
|
2
3
|
import { type TestableProps } from '../../utils/testId';
|
|
3
|
-
export type ScrollAreaProps = ArkUiScrollArea.RootProps & TestableProps
|
|
4
|
-
|
|
4
|
+
export type ScrollAreaProps = ArkUiScrollArea.RootProps & TestableProps & {
|
|
5
|
+
ref?: Ref<HTMLDivElement>;
|
|
6
|
+
};
|
|
7
|
+
export declare const ScrollArea: FC<ScrollAreaProps>;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef } from "react";
|
|
3
2
|
import { ScrollArea } from "@ark-ui/react/scroll-area";
|
|
4
3
|
import { cn } from "../../utils/cn.js";
|
|
5
4
|
import { TestIdProvider } from "../../utils/testId.js";
|
|
6
|
-
const ScrollArea_ScrollArea =
|
|
5
|
+
const ScrollArea_ScrollArea = ({ className, ref, 'data-testid': testId, children, ...props })=>/*#__PURE__*/ jsx(ScrollArea.Root, {
|
|
7
6
|
...props,
|
|
8
7
|
ref: ref,
|
|
9
8
|
"data-testid": testId,
|
|
@@ -12,6 +11,6 @@ const ScrollArea_ScrollArea = /*#__PURE__*/ forwardRef(({ className, 'data-testi
|
|
|
12
11
|
value: testId,
|
|
13
12
|
children: children
|
|
14
13
|
})
|
|
15
|
-
})
|
|
14
|
+
});
|
|
16
15
|
ScrollArea_ScrollArea.displayName = 'ScrollArea';
|
|
17
16
|
export { ScrollArea_ScrollArea as ScrollArea };
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type { FC } from 'react';
|
|
1
|
+
import type { FC, Ref } from 'react';
|
|
2
2
|
import { ScrollArea as ArkUiScrollArea } from '@ark-ui/react/scroll-area';
|
|
3
|
-
|
|
3
|
+
import { type TestableProps } from '../../utils/testId';
|
|
4
|
+
export type ScrollAreaContentProps = ArkUiScrollArea.ContentProps & TestableProps & {
|
|
5
|
+
ref?: Ref<HTMLDivElement>;
|
|
6
|
+
};
|
|
4
7
|
export declare const ScrollAreaContent: FC<ScrollAreaContentProps>;
|
|
@@ -2,10 +2,11 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { ScrollArea } from "@ark-ui/react/scroll-area";
|
|
3
3
|
import { cn } from "../../utils/cn.js";
|
|
4
4
|
import { useTestId } from "../../utils/testId.js";
|
|
5
|
-
const ScrollAreaContent = ({ className, ...props })=>{
|
|
6
|
-
const testId = useTestId('content');
|
|
5
|
+
const ScrollAreaContent = ({ className, ref, 'data-testid': testIdProp, ...props })=>{
|
|
6
|
+
const testId = useTestId('content', testIdProp);
|
|
7
7
|
return /*#__PURE__*/ jsx(ScrollArea.Content, {
|
|
8
8
|
...props,
|
|
9
|
+
ref: ref,
|
|
9
10
|
"data-testid": testId,
|
|
10
11
|
className: cn('h-full outline-none', className)
|
|
11
12
|
});
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type { FC } from 'react';
|
|
1
|
+
import type { FC, Ref } from 'react';
|
|
2
2
|
import { ScrollArea as ArkUiScrollArea } from '@ark-ui/react/scroll-area';
|
|
3
|
-
|
|
3
|
+
import { type TestableProps } from '../../utils/testId';
|
|
4
|
+
export type ScrollAreaCornerProps = ArkUiScrollArea.CornerProps & TestableProps & {
|
|
5
|
+
ref?: Ref<HTMLDivElement>;
|
|
6
|
+
};
|
|
4
7
|
export declare const ScrollAreaCorner: FC<ScrollAreaCornerProps>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { ScrollArea } from "@ark-ui/react/scroll-area";
|
|
3
3
|
import { useTestId } from "../../utils/testId.js";
|
|
4
|
-
const ScrollAreaCorner = (props)=>{
|
|
5
|
-
const testId = useTestId('corner');
|
|
4
|
+
const ScrollAreaCorner = ({ ref, 'data-testid': testIdProp, ...props })=>{
|
|
5
|
+
const testId = useTestId('corner', testIdProp);
|
|
6
6
|
return /*#__PURE__*/ jsx(ScrollArea.Corner, {
|
|
7
7
|
...props,
|
|
8
|
+
ref: ref,
|
|
8
9
|
"data-testid": testId
|
|
9
10
|
});
|
|
10
11
|
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { type FC } from 'react';
|
|
1
|
+
import { type FC, type Ref } from 'react';
|
|
2
2
|
import { ScrollArea as ArkUiScrollArea } from '@ark-ui/react/scroll-area';
|
|
3
|
-
|
|
3
|
+
import { type TestableProps } from '../../utils/testId';
|
|
4
|
+
export type ScrollAreaScrollbarProps = Omit<ArkUiScrollArea.ScrollbarProps, 'className' | 'style'> & TestableProps & {
|
|
5
|
+
ref?: Ref<HTMLDivElement>;
|
|
6
|
+
};
|
|
4
7
|
export declare const ScrollAreaScrollbar: FC<ScrollAreaScrollbarProps>;
|
|
@@ -20,8 +20,8 @@ const scrollAreaScrollbarThumbVariants = cva('bg-badge-slate-dark-alt opacity-0
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
|
-
const ScrollAreaScrollbar = ({ orientation = 'vertical', ...props })=>{
|
|
24
|
-
const testId = useTestId('scrollbar');
|
|
23
|
+
const ScrollAreaScrollbar = ({ orientation = 'vertical', ref, 'data-testid': testIdProp, ...props })=>{
|
|
24
|
+
const testId = useTestId('scrollbar', testIdProp);
|
|
25
25
|
const scrollbarStyle = useMemo(()=>{
|
|
26
26
|
if ('horizontal' === orientation) return {
|
|
27
27
|
left: 4,
|
|
@@ -37,6 +37,7 @@ const ScrollAreaScrollbar = ({ orientation = 'vertical', ...props })=>{
|
|
|
37
37
|
]);
|
|
38
38
|
return /*#__PURE__*/ jsx(ScrollArea.Scrollbar, {
|
|
39
39
|
...props,
|
|
40
|
+
ref: ref,
|
|
40
41
|
style: scrollbarStyle,
|
|
41
42
|
"data-testid": testId,
|
|
42
43
|
orientation: orientation,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { FC, Ref } from 'react';
|
|
2
2
|
import { ScrollArea as ArkUiScrollArea } from '@ark-ui/react/scroll-area';
|
|
3
|
-
|
|
3
|
+
import { type TestableProps } from '../../utils/testId';
|
|
4
|
+
export type ScrollAreaViewportProps = Omit<ArkUiScrollArea.ViewportProps, 'className'> & TestableProps & {
|
|
4
5
|
ref?: Ref<HTMLDivElement>;
|
|
5
6
|
};
|
|
6
7
|
export declare const ScrollAreaViewport: FC<ScrollAreaViewportProps>;
|
|
@@ -2,10 +2,11 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { ScrollArea } from "@ark-ui/react/scroll-area";
|
|
3
3
|
import { cn } from "../../utils/cn.js";
|
|
4
4
|
import { useTestId } from "../../utils/testId.js";
|
|
5
|
-
const ScrollAreaViewport = (props)=>{
|
|
6
|
-
const testId = useTestId('viewport');
|
|
5
|
+
const ScrollAreaViewport = ({ ref, 'data-testid': testIdProp, ...props })=>{
|
|
6
|
+
const testId = useTestId('viewport', testIdProp);
|
|
7
7
|
return /*#__PURE__*/ jsx(ScrollArea.Viewport, {
|
|
8
8
|
...props,
|
|
9
|
+
ref: ref,
|
|
9
10
|
"data-testid": testId,
|
|
10
11
|
className: cn('h-full outline-none')
|
|
11
12
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ScrollArea, type ScrollAreaProps } from './ScrollArea';
|
|
2
2
|
export { ScrollAreaContent, type ScrollAreaContentProps, } from './ScrollAreaContent';
|
|
3
|
-
export { ScrollAreaCorner } from './ScrollAreaCorner';
|
|
3
|
+
export { ScrollAreaCorner, type ScrollAreaCornerProps } from './ScrollAreaCorner';
|
|
4
4
|
export { ScrollAreaScrollbar, type ScrollAreaScrollbarProps, } from './ScrollAreaScrollbar';
|
|
5
5
|
export { ScrollAreaViewport, type ScrollAreaViewportProps, } from './ScrollAreaViewport';
|
|
@@ -2,6 +2,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { ArrowDown, ArrowUp, CornerDownLeft } from "../../icons/index.js";
|
|
3
3
|
import { cn } from "../../utils/cn.js";
|
|
4
4
|
import { useTestId } from "../../utils/testId.js";
|
|
5
|
+
import { Kbd } from "../Kbd/index.js";
|
|
5
6
|
import { Text } from "../Text/index.js";
|
|
6
7
|
import { searchModalFooterVariants } from "./classes.js";
|
|
7
8
|
const SearchModalFooter = ({ ref, children, className, ...props })=>{
|
|
@@ -17,11 +18,17 @@ const SearchModalFooter = ({ ref, children, className, ...props })=>{
|
|
|
17
18
|
/*#__PURE__*/ jsxs("span", {
|
|
18
19
|
className: "inline-flex items-center gap-4",
|
|
19
20
|
children: [
|
|
20
|
-
/*#__PURE__*/ jsx(
|
|
21
|
-
|
|
21
|
+
/*#__PURE__*/ jsx(Kbd, {
|
|
22
|
+
size: "xsmall",
|
|
23
|
+
children: /*#__PURE__*/ jsx(ArrowUp, {
|
|
24
|
+
className: "!icon-xs"
|
|
25
|
+
})
|
|
22
26
|
}),
|
|
23
|
-
/*#__PURE__*/ jsx(
|
|
24
|
-
|
|
27
|
+
/*#__PURE__*/ jsx(Kbd, {
|
|
28
|
+
size: "xsmall",
|
|
29
|
+
children: /*#__PURE__*/ jsx(ArrowDown, {
|
|
30
|
+
className: "!icon-xs"
|
|
31
|
+
})
|
|
25
32
|
}),
|
|
26
33
|
/*#__PURE__*/ jsx(Text, {
|
|
27
34
|
size: "xs",
|
|
@@ -33,8 +40,11 @@ const SearchModalFooter = ({ ref, children, className, ...props })=>{
|
|
|
33
40
|
/*#__PURE__*/ jsxs("span", {
|
|
34
41
|
className: "inline-flex items-center gap-4",
|
|
35
42
|
children: [
|
|
36
|
-
/*#__PURE__*/ jsx(
|
|
37
|
-
|
|
43
|
+
/*#__PURE__*/ jsx(Kbd, {
|
|
44
|
+
size: "xsmall",
|
|
45
|
+
children: /*#__PURE__*/ jsx(CornerDownLeft, {
|
|
46
|
+
className: "!icon-xs"
|
|
47
|
+
})
|
|
38
48
|
}),
|
|
39
49
|
/*#__PURE__*/ jsx(Text, {
|
|
40
50
|
size: "xs",
|
|
@@ -9,7 +9,7 @@ import { searchModalInputVariants } from "./classes.js";
|
|
|
9
9
|
import { useSearchModalContext } from "./SearchModalContext/index.js";
|
|
10
10
|
const SearchModalInput = ({ ref, loading = false, className, ...props })=>{
|
|
11
11
|
const testId = useTestId('input');
|
|
12
|
-
const { query, setQuery, inputRef } = useSearchModalContext();
|
|
12
|
+
const { query, setQuery, inputRef, close } = useSearchModalContext();
|
|
13
13
|
return /*#__PURE__*/ jsxs("div", {
|
|
14
14
|
"data-slot": "search-modal-input",
|
|
15
15
|
"data-testid": testId,
|
|
@@ -21,19 +21,26 @@ const SearchModalInput = ({ ref, loading = false, className, ...props })=>{
|
|
|
21
21
|
size: "sm"
|
|
22
22
|
})
|
|
23
23
|
}) : /*#__PURE__*/ jsx(Search, {
|
|
24
|
-
className: "text-text-
|
|
24
|
+
className: "text-text-secondary shrink-0 !icon-md"
|
|
25
25
|
}),
|
|
26
26
|
/*#__PURE__*/ jsx("input", {
|
|
27
27
|
...props,
|
|
28
28
|
ref: mergeRefs(inputRef, ref),
|
|
29
29
|
value: query,
|
|
30
30
|
onChange: (e)=>setQuery(e.target.value),
|
|
31
|
-
className: cn('flex-1 h-48 bg-transparent text-text-primary text-base', 'placeholder:text-text-
|
|
31
|
+
className: cn('flex-1 h-48 bg-transparent text-text-primary text-base', 'placeholder:text-text-hint outline-none', className),
|
|
32
32
|
autoComplete: "off"
|
|
33
33
|
}),
|
|
34
|
-
/*#__PURE__*/ jsx(
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
/*#__PURE__*/ jsx("button", {
|
|
35
|
+
type: "button",
|
|
36
|
+
tabIndex: -1,
|
|
37
|
+
onClick: close,
|
|
38
|
+
className: "shrink-0 cursor-pointer",
|
|
39
|
+
"aria-label": "Close",
|
|
40
|
+
children: /*#__PURE__*/ jsx(Kbd, {
|
|
41
|
+
size: "xsmall",
|
|
42
|
+
children: "ESC"
|
|
43
|
+
})
|
|
37
44
|
})
|
|
38
45
|
]
|
|
39
46
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { cva } from "class-variance-authority";
|
|
2
2
|
import { cn } from "../../utils/cn.js";
|
|
3
|
-
const searchModalContentVariants = cva(cn('w-[560px] max-h-[70vh]', 'bg-bg-surface-
|
|
4
|
-
const searchModalInputVariants = cva(cn('flex items-center gap-
|
|
5
|
-
const searchModalItemVariants = cva(cn('flex items-center gap-
|
|
3
|
+
const searchModalContentVariants = cva(cn('w-[560px] max-h-[70vh]', 'bg-bg-surface-2', 'rounded-12', 'shadow-xl', 'border border-border-primary-light', 'overflow-hidden', 'flex flex-col', 'outline-none', 'data-[state=open]:animate-in data-[state=closed]:animate-out', 'data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0', 'data-[state=open]:slide-in-from-bottom-[25%]', 'data-[state=closed]:slide-out-to-bottom-[25%]', 'data-[state=open]:duration-300 data-[state=closed]:duration-150'));
|
|
4
|
+
const searchModalInputVariants = cva(cn('flex items-center gap-12 px-16', 'border-b border-border-primary-light'));
|
|
5
|
+
const searchModalItemVariants = cva(cn('flex items-center gap-8 w-full', 'px-8 py-6 rounded-6', 'cursor-pointer text-left no-underline', 'transition-colors'), {
|
|
6
6
|
variants: {
|
|
7
7
|
active: {
|
|
8
8
|
true: 'bg-states-primary-hover',
|
|
@@ -18,7 +18,7 @@ const searchModalItemVariants = cva(cn('flex items-center gap-12 w-full', 'px-16
|
|
|
18
18
|
disabled: false
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
|
-
const searchModalBodyVariants = cva(cn('overflow-y-auto flex-1 py-8'));
|
|
22
|
-
const searchModalGroupLabelVariants = cva(cn('px-
|
|
23
|
-
const searchModalFooterVariants = cva(cn('flex items-center gap-16 px-16 py-8', 'border-t border-border-primary'));
|
|
21
|
+
const searchModalBodyVariants = cva(cn('overflow-y-auto flex-1 px-8 py-8'));
|
|
22
|
+
const searchModalGroupLabelVariants = cva(cn('px-8 pt-8 pb-2'));
|
|
23
|
+
const searchModalFooterVariants = cva(cn('flex items-center gap-16 px-16 py-8', 'border-t border-border-primary-light'));
|
|
24
24
|
export { searchModalBodyVariants, searchModalContentVariants, searchModalFooterVariants, searchModalGroupLabelVariants, searchModalInputVariants, searchModalItemVariants };
|
|
@@ -4,7 +4,7 @@ import { Area } from "recharts";
|
|
|
4
4
|
import { LineChartActiveContext, LineChartDataContext } from "../LineChart/LineChartContext.js";
|
|
5
5
|
import { warnLineChartLine } from "../LineChart/lib/warn.js";
|
|
6
6
|
import { AreaChartVariantContext } from "./AreaChartContext.js";
|
|
7
|
-
import {
|
|
7
|
+
import { AREA_FILL_OPACITY, AREA_INACTIVE_OPACITY, AREA_STROKE_FILL, AREA_STROKE_WIDTH, resolveSeriesColor } from "./constants.js";
|
|
8
8
|
const AreaChartArea = ({ seriesKey, curve = 'monotone', disableAnimation = false, connectNulls = false, strokeWidth = AREA_STROKE_WIDTH })=>{
|
|
9
9
|
const dataCtx = useContext(LineChartDataContext);
|
|
10
10
|
const { activeKey } = useContext(LineChartActiveContext);
|
|
@@ -40,10 +40,7 @@ const AreaChartArea = ({ seriesKey, curve = 'monotone', disableAnimation = false
|
|
|
40
40
|
opacity: opacity,
|
|
41
41
|
connectNulls: connectNulls,
|
|
42
42
|
stackId: 'stacked' === variant ? 'area-stack' : void 0,
|
|
43
|
-
isAnimationActive:
|
|
44
|
-
animationBegin: AREA_ANIMATION_BEGIN,
|
|
45
|
-
animationDuration: AREA_ANIMATION_DURATION,
|
|
46
|
-
animationEasing: "ease-out",
|
|
43
|
+
isAnimationActive: false,
|
|
47
44
|
"data-slot": "area-chart-area",
|
|
48
45
|
"data-key": seriesKey,
|
|
49
46
|
"data-active": isActive ? 'true' : void 0
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { LINE_CARD_HEIGHT as AREA_CARD_HEIGHT, LINE_DEFAULT_BODY_MARGIN as AREA_DEFAULT_BODY_MARGIN, LINE_HEADER_HEIGHT as AREA_HEADER_HEIGHT, LINE_INACTIVE_OPACITY as AREA_INACTIVE_OPACITY, } from '../LineChart/constants';
|
|
2
|
+
/** 1.5px stroke per Figma spec — thinner than LineChart's 2px. */
|
|
3
|
+
export declare const AREA_STROKE_WIDTH = 1.5;
|
|
2
4
|
export { CHART_PALETTE_FILL as AREA_STROKE_FILL, resolveChartColor as resolveSeriesColor, } from '../lib/chartPalette';
|
|
3
5
|
/** 20% fill opacity per Figma spec — semi-transparent bands. */
|
|
4
6
|
export declare const AREA_FILL_OPACITY = 0.2;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
const AREA_STROKE_WIDTH = 1.5;
|
|
1
2
|
const AREA_FILL_OPACITY = 0.2;
|
|
2
|
-
export {
|
|
3
|
+
export { LINE_CARD_HEIGHT as AREA_CARD_HEIGHT, LINE_DEFAULT_BODY_MARGIN as AREA_DEFAULT_BODY_MARGIN, LINE_HEADER_HEIGHT as AREA_HEADER_HEIGHT, LINE_INACTIVE_OPACITY as AREA_INACTIVE_OPACITY } from "../LineChart/constants.js";
|
|
3
4
|
export { CHART_PALETTE_FILL as AREA_STROKE_FILL, resolveChartColor as resolveSeriesColor } from "../lib/chartPalette.js";
|
|
4
|
-
export { AREA_FILL_OPACITY };
|
|
5
|
+
export { AREA_FILL_OPACITY, AREA_STROKE_WIDTH };
|
|
@@ -14,6 +14,7 @@ const LineChartLegendItem = ({ seriesKey, selected: selectedProp, className, chi
|
|
|
14
14
|
const active = activeKey === seriesKey;
|
|
15
15
|
const selected = selectedProp ?? !hiddenSet.has(seriesKey);
|
|
16
16
|
const dimmed = !selected && !active && hiddenSet.size > 0;
|
|
17
|
+
const filtering = hiddenSet.size > 0;
|
|
17
18
|
const color = series?.color;
|
|
18
19
|
const label = series?.label;
|
|
19
20
|
const itemValue = useMemo(()=>({
|
|
@@ -102,7 +103,8 @@ const LineChartLegendItem = ({ seriesKey, selected: selectedProp, className, chi
|
|
|
102
103
|
interactive,
|
|
103
104
|
active,
|
|
104
105
|
selected,
|
|
105
|
-
dimmed
|
|
106
|
+
dimmed,
|
|
107
|
+
filtering
|
|
106
108
|
}), className),
|
|
107
109
|
children: children
|
|
108
110
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useContext, useEffect } from "react";
|
|
3
3
|
import { Line } from "recharts";
|
|
4
|
-
import {
|
|
4
|
+
import { LINE_DASH_DASHARRAY, LINE_INACTIVE_OPACITY, LINE_STROKE_FILL, LINE_STROKE_WIDTH, resolveSeriesColor } from "./constants.js";
|
|
5
5
|
import { LineChartActiveContext, LineChartDataContext } from "./LineChartContext.js";
|
|
6
6
|
import { warnLineChartLine } from "./lib/warn.js";
|
|
7
7
|
const wrap = (cb)=>cb ? (_props, event)=>cb(event) : void 0;
|
|
@@ -37,10 +37,7 @@ const LineChartLine = ({ seriesKey, curve = 'monotone', disableAnimation = false
|
|
|
37
37
|
activeDot: false,
|
|
38
38
|
opacity: opacity,
|
|
39
39
|
connectNulls: connectNulls,
|
|
40
|
-
isAnimationActive:
|
|
41
|
-
animationBegin: LINE_ANIMATION_BEGIN,
|
|
42
|
-
animationDuration: LINE_ANIMATION_DURATION,
|
|
43
|
-
animationEasing: "ease-out",
|
|
40
|
+
isAnimationActive: false,
|
|
44
41
|
onClick: wrap(onClick),
|
|
45
42
|
onMouseEnter: wrap(onMouseEnter),
|
|
46
43
|
onMouseLeave: wrap(onMouseLeave),
|
|
@@ -11,6 +11,7 @@ export declare const lineChartLegendItemVariants: (props?: ({
|
|
|
11
11
|
active?: boolean | null | undefined;
|
|
12
12
|
selected?: boolean | null | undefined;
|
|
13
13
|
dimmed?: boolean | null | undefined;
|
|
14
|
+
filtering?: boolean | null | undefined;
|
|
14
15
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
15
16
|
export declare const lineChartHoverPopoverTimestampClasses: string;
|
|
16
17
|
export declare const lineChartZoomPopoverClasses: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cva } from "class-variance-authority";
|
|
2
2
|
const lineChartRootClasses = "relative w-full flex flex-col min-h-0";
|
|
3
|
-
const lineChartBodyClasses = "relative flex-1 min-h-0 min-w-0 [&_*]:outline-none";
|
|
3
|
+
const lineChartBodyClasses = "relative flex-1 min-h-0 min-w-0 [&_*]:outline-none [&_.recharts-line]:animate-[ds-chart-fade-in_400ms_ease-out] [&_.recharts-area]:animate-[ds-chart-fade-in_400ms_ease-out] motion-reduce:[&_.recharts-line]:animate-none motion-reduce:[&_.recharts-area]:animate-none";
|
|
4
4
|
const lineChartBodyZoomEnabledClasses = "select-none [&_.recharts-wrapper]:cursor-crosshair!";
|
|
5
5
|
const lineChartZoomCursorPopoverClasses = "fixed z-30 pointer-events-none";
|
|
6
6
|
const lineChartLegendVariants = cva('flex', {
|
|
@@ -69,13 +69,25 @@ const lineChartLegendItemVariants = cva("group/line-chart-legend-item relative f
|
|
|
69
69
|
dimmed: {
|
|
70
70
|
true: 'opacity-60',
|
|
71
71
|
false: ''
|
|
72
|
+
},
|
|
73
|
+
filtering: {
|
|
74
|
+
true: '',
|
|
75
|
+
false: ''
|
|
72
76
|
}
|
|
73
77
|
},
|
|
78
|
+
compoundVariants: [
|
|
79
|
+
{
|
|
80
|
+
filtering: true,
|
|
81
|
+
selected: true,
|
|
82
|
+
class: 'bg-states-primary-active'
|
|
83
|
+
}
|
|
84
|
+
],
|
|
74
85
|
defaultVariants: {
|
|
75
86
|
interactive: false,
|
|
76
87
|
active: false,
|
|
77
88
|
selected: true,
|
|
78
|
-
dimmed: false
|
|
89
|
+
dimmed: false,
|
|
90
|
+
filtering: false
|
|
79
91
|
}
|
|
80
92
|
});
|
|
81
93
|
const lineChartHoverPopoverTimestampClasses = "text-xs font-medium text-text-primary";
|
package/dist/index.d.ts
CHANGED
|
@@ -67,7 +67,7 @@ export { Radio, RadioDescription, type RadioDescriptionProps, RadioGroup, type R
|
|
|
67
67
|
export { type BreadcrumbSegment, findFirstLinkPath, type NavConfig, type NavConfigDrill, type NavConfigGroup, type NavConfigLink, type NavConfigNode, type NavStackEntry, pushPathname, RemoteShell, RemoteShellBreadcrumb, type RemoteShellBreadcrumbProps, RemoteShellContent, type RemoteShellContentProps, type RemoteShellContextValue, RemoteShellPanel, type RemoteShellPanelProps, type RemoteShellProps, useLocationPathname, useRemoteShellContext, } from './components/RemoteShell';
|
|
68
68
|
export { ResizableHandle, type ResizableHandleProps, ResizablePanel, ResizablePanelGroup, type ResizablePanelGroupProps, type ResizablePanelProps, } from './components/Resizable';
|
|
69
69
|
export { getResponseCodeCategory, RESPONSE_CODE_COLOR, ResponseCode, type ResponseCodeCategory, type ResponseCodeProps, } from './components/ResponseCode';
|
|
70
|
-
export { ScrollArea, ScrollAreaContent, type ScrollAreaContentProps, ScrollAreaCorner, type ScrollAreaProps, ScrollAreaScrollbar, type ScrollAreaScrollbarProps, ScrollAreaViewport, type ScrollAreaViewportProps, } from './components/ScrollArea';
|
|
70
|
+
export { ScrollArea, ScrollAreaContent, type ScrollAreaContentProps, ScrollAreaCorner, type ScrollAreaCornerProps, type ScrollAreaProps, ScrollAreaScrollbar, type ScrollAreaScrollbarProps, ScrollAreaViewport, type ScrollAreaViewportProps, } from './components/ScrollArea';
|
|
71
71
|
export { SearchModal, SearchModalBody, type SearchModalBodyProps, SearchModalContent, type SearchModalContentProps, SearchModalEmpty, type SearchModalEmptyProps, SearchModalFooter, type SearchModalFooterProps, SearchModalGroup, SearchModalGroupLabel, type SearchModalGroupLabelProps, type SearchModalGroupProps, SearchModalInput, type SearchModalInputProps, SearchModalItem, type SearchModalItemProps, type SearchModalProps, SearchModalTrigger, type SearchModalTriggerProps, useSearchModalContext, } from './components/SearchModal';
|
|
72
72
|
export { SegmentedControl, SegmentedControlButton, type SegmentedControlButtonProps, SegmentedControlItem, type SegmentedControlItemProps, type SegmentedControlProps, SegmentedControlSeparator, type SegmentedControlSeparatorProps, } from './components/SegmentedControl';
|
|
73
73
|
export { SegmentedTabs, SegmentedTabsButton, SegmentedTabsContent, SegmentedTabsList, SegmentedTabsSeparator, SegmentedTabsTrigger, SegmentedTabsTriggerButton, } from './components/SegmentedTabs';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
3
|
-
"generatedAt": "2026-09-
|
|
2
|
+
"version": "1.19.0",
|
|
3
|
+
"generatedAt": "2026-09-09T09:55:16.853Z",
|
|
4
4
|
"components": [
|
|
5
5
|
{
|
|
6
6
|
"name": "Accordion",
|
|
@@ -22832,7 +22832,7 @@
|
|
|
22832
22832
|
},
|
|
22833
22833
|
{
|
|
22834
22834
|
"name": "WithToast",
|
|
22835
|
-
"code": "() => {\n const toast = useToast();\n\n const handleCopy = () => {\n toast.create({ title: 'Copied', type: '
|
|
22835
|
+
"code": "() => {\n const toast = useToast();\n\n const handleCopy = () => {\n toast.create({ title: 'Copied', type: 'default', variant: 'simple' });\n };\n\n return (\n <>\n <Toaster />\n <CopyButton\n text={SAMPLE_TEXT}\n label='Copy code'\n copiedLabel='Copied'\n size='medium'\n onClick={handleCopy}\n />\n </>\n );\n}",
|
|
22836
22836
|
"description": "When the button itself cannot transform (e.g. a context menu item), show a\ntoast to confirm the copy. Click the button to see the \"Copied\" toast."
|
|
22837
22837
|
}
|
|
22838
22838
|
]
|
|
@@ -53925,13 +53925,6 @@
|
|
|
53925
53925
|
{
|
|
53926
53926
|
"name": "ResizableHandle",
|
|
53927
53927
|
"props": [
|
|
53928
|
-
{
|
|
53929
|
-
"name": "withHandle",
|
|
53930
|
-
"type": "boolean | undefined",
|
|
53931
|
-
"required": false,
|
|
53932
|
-
"description": "Show a visible grip icon on the handle.",
|
|
53933
|
-
"defaultValue": "false"
|
|
53934
|
-
},
|
|
53935
53928
|
{
|
|
53936
53929
|
"name": "defaultChecked",
|
|
53937
53930
|
"type": "boolean | undefined",
|
|
@@ -54838,11 +54831,6 @@
|
|
|
54838
54831
|
"code": "() => (\n <div className='h-[400px] w-[400px] rounded-8 border border-border-primary'>\n <ResizablePanelGroup orientation='vertical'>\n <ResizablePanel id='top' defaultSize='50%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Top</span>\n </div>\n </ResizablePanel>\n <ResizableHandle />\n <ResizablePanel id='bottom' defaultSize='50%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Bottom</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n)",
|
|
54839
54832
|
"description": "Two panels stacked vertically."
|
|
54840
54833
|
},
|
|
54841
|
-
{
|
|
54842
|
-
"name": "WithHandle",
|
|
54843
|
-
"code": "() => (\n <div className='h-[320px] w-[600px] rounded-8 border border-border-primary'>\n <ResizablePanelGroup orientation='horizontal'>\n <ResizablePanel id='left' defaultSize='50%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Panel A</span>\n </div>\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel id='right' defaultSize='50%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Panel B</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n)",
|
|
54844
|
-
"description": "A visible grip icon on the resize handle."
|
|
54845
|
-
},
|
|
54846
54834
|
{
|
|
54847
54835
|
"name": "ThreePanels",
|
|
54848
54836
|
"code": "() => (\n <div className='h-[320px] w-[800px] rounded-8 border border-border-primary'>\n <ResizablePanelGroup orientation='horizontal'>\n <ResizablePanel id='left' defaultSize='25%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Sidebar</span>\n </div>\n </ResizablePanel>\n <ResizableHandle />\n <ResizablePanel id='center' defaultSize='50%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Content</span>\n </div>\n </ResizablePanel>\n <ResizableHandle />\n <ResizablePanel id='right' defaultSize='25%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Inspector</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n)",
|
|
@@ -54850,18 +54838,28 @@
|
|
|
54850
54838
|
},
|
|
54851
54839
|
{
|
|
54852
54840
|
"name": "Nested",
|
|
54853
|
-
"code": "() => (\n <div className='h-[400px] w-[700px] rounded-8 border border-border-primary'>\n <ResizablePanelGroup orientation='horizontal'>\n <ResizablePanel id='left' defaultSize='40%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Sidebar</span>\n </div>\n </ResizablePanel>\n <ResizableHandle
|
|
54841
|
+
"code": "() => (\n <div className='h-[400px] w-[700px] rounded-8 border border-border-primary'>\n <ResizablePanelGroup orientation='horizontal'>\n <ResizablePanel id='left' defaultSize='40%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Sidebar</span>\n </div>\n </ResizablePanel>\n <ResizableHandle />\n <ResizablePanel id='right' defaultSize='60%'>\n <ResizablePanelGroup orientation='vertical'>\n <ResizablePanel id='top' defaultSize='60%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Editor</span>\n </div>\n </ResizablePanel>\n <ResizableHandle />\n <ResizablePanel id='bottom' defaultSize='40%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Terminal</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n)",
|
|
54854
54842
|
"description": "A horizontal group with a vertical sub-group nested inside one panel."
|
|
54855
54843
|
},
|
|
54856
54844
|
{
|
|
54857
54845
|
"name": "Collapsible",
|
|
54858
|
-
"code": "() => (\n <div className='h-[320px] w-[600px] rounded-8 border border-border-primary'>\n <ResizablePanelGroup orientation='horizontal'>\n <ResizablePanel id='sidebar' defaultSize='30%' collapsible minSize='15%' collapsedSize='0%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Collapsible</span>\n </div>\n </ResizablePanel>\n <ResizableHandle
|
|
54846
|
+
"code": "() => (\n <div className='h-[320px] w-[600px] rounded-8 border border-border-primary'>\n <ResizablePanelGroup orientation='horizontal'>\n <ResizablePanel id='sidebar' defaultSize='30%' collapsible minSize='15%' collapsedSize='0%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Collapsible</span>\n </div>\n </ResizablePanel>\n <ResizableHandle />\n <ResizablePanel id='content' defaultSize='70%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Content</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n)",
|
|
54859
54847
|
"description": "A panel that can be collapsed by dragging past its minimum size. Double-click the handle to reset."
|
|
54860
54848
|
},
|
|
54861
54849
|
{
|
|
54862
54850
|
"name": "WithConstraints",
|
|
54863
|
-
"code": "() => (\n <div className='h-[320px] w-[600px] rounded-8 border border-border-primary'>\n <ResizablePanelGroup orientation='horizontal'>\n <ResizablePanel id='constrained' defaultSize='40%' minSize='20%' maxSize='60%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Min 20% / Max 60%</span>\n </div>\n </ResizablePanel>\n <ResizableHandle
|
|
54851
|
+
"code": "() => (\n <div className='h-[320px] w-[600px] rounded-8 border border-border-primary'>\n <ResizablePanelGroup orientation='horizontal'>\n <ResizablePanel id='constrained' defaultSize='40%' minSize='20%' maxSize='60%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Min 20% / Max 60%</span>\n </div>\n </ResizablePanel>\n <ResizableHandle />\n <ResizablePanel id='flexible' defaultSize='60%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Flexible</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n)",
|
|
54864
54852
|
"description": "Panels with minimum and maximum size constraints."
|
|
54853
|
+
},
|
|
54854
|
+
{
|
|
54855
|
+
"name": "WithTooltip",
|
|
54856
|
+
"code": "() => (\n <div className='h-[320px] w-[600px] rounded-8 border border-border-primary'>\n <ResizablePanelGroup orientation='horizontal'>\n <ResizablePanel id='left' defaultSize='50%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Panel A</span>\n </div>\n </ResizablePanel>\n <Tooltip positioning={{ placement: 'right' }}>\n <TooltipTrigger asChild>\n <ResizableHandle />\n </TooltipTrigger>\n <TooltipContent>Drag to resize</TooltipContent>\n </Tooltip>\n <ResizablePanel id='right' defaultSize='50%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Panel B</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n)",
|
|
54857
|
+
"description": "A \"Drag to resize\" tooltip appears on hover, like the Drawer resize handle."
|
|
54858
|
+
},
|
|
54859
|
+
{
|
|
54860
|
+
"name": "WithOverflowList",
|
|
54861
|
+
"code": "() => (\n <div className='h-[320px] w-[600px] rounded-8 border border-border-primary'>\n <ResizablePanelGroup orientation='horizontal'>\n <ResizablePanel id='tags' defaultSize='50%' minSize='20%'>\n <div className='flex h-full items-center p-16'>\n <OverflowList\n className='gap-4'\n items={OVERFLOW_TAGS}\n itemRenderer={item => <Tag key={item}>{item}</Tag>}\n overflowRenderer={renderOverflow}\n />\n </div>\n </ResizablePanel>\n <ResizableHandle />\n <ResizablePanel id='content' defaultSize='50%'>\n <div className='flex h-full items-center justify-center p-24'>\n <span className='text-text-secondary'>Content</span>\n </div>\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n)",
|
|
54862
|
+
"description": "Resizing with content that reflows — the tag list adapts live as the panel width changes. Overflow items appear in a popover."
|
|
54865
54863
|
}
|
|
54866
54864
|
]
|
|
54867
54865
|
},
|
|
@@ -55759,6 +55757,287 @@
|
|
|
55759
55757
|
}
|
|
55760
55758
|
]
|
|
55761
55759
|
},
|
|
55760
|
+
{
|
|
55761
|
+
"name": "ScrollAreaCorner",
|
|
55762
|
+
"props": [
|
|
55763
|
+
{
|
|
55764
|
+
"name": "slot",
|
|
55765
|
+
"type": "string | undefined",
|
|
55766
|
+
"required": false
|
|
55767
|
+
},
|
|
55768
|
+
{
|
|
55769
|
+
"name": "title",
|
|
55770
|
+
"type": "string | undefined",
|
|
55771
|
+
"required": false
|
|
55772
|
+
},
|
|
55773
|
+
{
|
|
55774
|
+
"name": "defaultChecked",
|
|
55775
|
+
"type": "boolean | undefined",
|
|
55776
|
+
"required": false
|
|
55777
|
+
},
|
|
55778
|
+
{
|
|
55779
|
+
"name": "defaultValue",
|
|
55780
|
+
"type": "string | number | readonly string[] | undefined",
|
|
55781
|
+
"required": false
|
|
55782
|
+
},
|
|
55783
|
+
{
|
|
55784
|
+
"name": "suppressContentEditableWarning",
|
|
55785
|
+
"type": "boolean | undefined",
|
|
55786
|
+
"required": false
|
|
55787
|
+
},
|
|
55788
|
+
{
|
|
55789
|
+
"name": "suppressHydrationWarning",
|
|
55790
|
+
"type": "boolean | undefined",
|
|
55791
|
+
"required": false
|
|
55792
|
+
},
|
|
55793
|
+
{
|
|
55794
|
+
"name": "accessKey",
|
|
55795
|
+
"type": "string | undefined",
|
|
55796
|
+
"required": false
|
|
55797
|
+
},
|
|
55798
|
+
{
|
|
55799
|
+
"name": "autoCapitalize",
|
|
55800
|
+
"type": "\"off\" | \"none\" | \"on\" | \"sentences\" | \"words\" | \"characters\" | (string & {}) | undefined",
|
|
55801
|
+
"required": false
|
|
55802
|
+
},
|
|
55803
|
+
{
|
|
55804
|
+
"name": "autoFocus",
|
|
55805
|
+
"type": "boolean | undefined",
|
|
55806
|
+
"required": false
|
|
55807
|
+
},
|
|
55808
|
+
{
|
|
55809
|
+
"name": "contentEditable",
|
|
55810
|
+
"type": "Booleanish | \"inherit\" | \"plaintext-only\" | undefined",
|
|
55811
|
+
"required": false
|
|
55812
|
+
},
|
|
55813
|
+
{
|
|
55814
|
+
"name": "contextMenu",
|
|
55815
|
+
"type": "string | undefined",
|
|
55816
|
+
"required": false
|
|
55817
|
+
},
|
|
55818
|
+
{
|
|
55819
|
+
"name": "dir",
|
|
55820
|
+
"type": "string | undefined",
|
|
55821
|
+
"required": false
|
|
55822
|
+
},
|
|
55823
|
+
{
|
|
55824
|
+
"name": "draggable",
|
|
55825
|
+
"type": "Booleanish | undefined",
|
|
55826
|
+
"required": false
|
|
55827
|
+
},
|
|
55828
|
+
{
|
|
55829
|
+
"name": "enterKeyHint",
|
|
55830
|
+
"type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
|
|
55831
|
+
"required": false
|
|
55832
|
+
},
|
|
55833
|
+
{
|
|
55834
|
+
"name": "hidden",
|
|
55835
|
+
"type": "boolean | undefined",
|
|
55836
|
+
"required": false
|
|
55837
|
+
},
|
|
55838
|
+
{
|
|
55839
|
+
"name": "id",
|
|
55840
|
+
"type": "string | undefined",
|
|
55841
|
+
"required": false
|
|
55842
|
+
},
|
|
55843
|
+
{
|
|
55844
|
+
"name": "lang",
|
|
55845
|
+
"type": "string | undefined",
|
|
55846
|
+
"required": false
|
|
55847
|
+
},
|
|
55848
|
+
{
|
|
55849
|
+
"name": "nonce",
|
|
55850
|
+
"type": "string | undefined",
|
|
55851
|
+
"required": false
|
|
55852
|
+
},
|
|
55853
|
+
{
|
|
55854
|
+
"name": "spellCheck",
|
|
55855
|
+
"type": "Booleanish | undefined",
|
|
55856
|
+
"required": false
|
|
55857
|
+
},
|
|
55858
|
+
{
|
|
55859
|
+
"name": "tabIndex",
|
|
55860
|
+
"type": "number | undefined",
|
|
55861
|
+
"required": false
|
|
55862
|
+
},
|
|
55863
|
+
{
|
|
55864
|
+
"name": "translate",
|
|
55865
|
+
"type": "\"yes\" | \"no\" | undefined",
|
|
55866
|
+
"required": false
|
|
55867
|
+
},
|
|
55868
|
+
{
|
|
55869
|
+
"name": "radioGroup",
|
|
55870
|
+
"type": "string | undefined",
|
|
55871
|
+
"required": false
|
|
55872
|
+
},
|
|
55873
|
+
{
|
|
55874
|
+
"name": "role",
|
|
55875
|
+
"type": "AriaRole | undefined",
|
|
55876
|
+
"required": false
|
|
55877
|
+
},
|
|
55878
|
+
{
|
|
55879
|
+
"name": "about",
|
|
55880
|
+
"type": "string | undefined",
|
|
55881
|
+
"required": false
|
|
55882
|
+
},
|
|
55883
|
+
{
|
|
55884
|
+
"name": "content",
|
|
55885
|
+
"type": "string | undefined",
|
|
55886
|
+
"required": false
|
|
55887
|
+
},
|
|
55888
|
+
{
|
|
55889
|
+
"name": "datatype",
|
|
55890
|
+
"type": "string | undefined",
|
|
55891
|
+
"required": false
|
|
55892
|
+
},
|
|
55893
|
+
{
|
|
55894
|
+
"name": "inlist",
|
|
55895
|
+
"type": "any",
|
|
55896
|
+
"required": false
|
|
55897
|
+
},
|
|
55898
|
+
{
|
|
55899
|
+
"name": "prefix",
|
|
55900
|
+
"type": "string | undefined",
|
|
55901
|
+
"required": false
|
|
55902
|
+
},
|
|
55903
|
+
{
|
|
55904
|
+
"name": "property",
|
|
55905
|
+
"type": "string | undefined",
|
|
55906
|
+
"required": false
|
|
55907
|
+
},
|
|
55908
|
+
{
|
|
55909
|
+
"name": "rel",
|
|
55910
|
+
"type": "string | undefined",
|
|
55911
|
+
"required": false
|
|
55912
|
+
},
|
|
55913
|
+
{
|
|
55914
|
+
"name": "resource",
|
|
55915
|
+
"type": "string | undefined",
|
|
55916
|
+
"required": false
|
|
55917
|
+
},
|
|
55918
|
+
{
|
|
55919
|
+
"name": "rev",
|
|
55920
|
+
"type": "string | undefined",
|
|
55921
|
+
"required": false
|
|
55922
|
+
},
|
|
55923
|
+
{
|
|
55924
|
+
"name": "typeof",
|
|
55925
|
+
"type": "string | undefined",
|
|
55926
|
+
"required": false
|
|
55927
|
+
},
|
|
55928
|
+
{
|
|
55929
|
+
"name": "vocab",
|
|
55930
|
+
"type": "string | undefined",
|
|
55931
|
+
"required": false
|
|
55932
|
+
},
|
|
55933
|
+
{
|
|
55934
|
+
"name": "autoCorrect",
|
|
55935
|
+
"type": "string | undefined",
|
|
55936
|
+
"required": false
|
|
55937
|
+
},
|
|
55938
|
+
{
|
|
55939
|
+
"name": "autoSave",
|
|
55940
|
+
"type": "string | undefined",
|
|
55941
|
+
"required": false
|
|
55942
|
+
},
|
|
55943
|
+
{
|
|
55944
|
+
"name": "color",
|
|
55945
|
+
"type": "string | undefined",
|
|
55946
|
+
"required": false
|
|
55947
|
+
},
|
|
55948
|
+
{
|
|
55949
|
+
"name": "itemProp",
|
|
55950
|
+
"type": "string | undefined",
|
|
55951
|
+
"required": false
|
|
55952
|
+
},
|
|
55953
|
+
{
|
|
55954
|
+
"name": "itemScope",
|
|
55955
|
+
"type": "boolean | undefined",
|
|
55956
|
+
"required": false
|
|
55957
|
+
},
|
|
55958
|
+
{
|
|
55959
|
+
"name": "itemType",
|
|
55960
|
+
"type": "string | undefined",
|
|
55961
|
+
"required": false
|
|
55962
|
+
},
|
|
55963
|
+
{
|
|
55964
|
+
"name": "itemID",
|
|
55965
|
+
"type": "string | undefined",
|
|
55966
|
+
"required": false
|
|
55967
|
+
},
|
|
55968
|
+
{
|
|
55969
|
+
"name": "itemRef",
|
|
55970
|
+
"type": "string | undefined",
|
|
55971
|
+
"required": false
|
|
55972
|
+
},
|
|
55973
|
+
{
|
|
55974
|
+
"name": "results",
|
|
55975
|
+
"type": "number | undefined",
|
|
55976
|
+
"required": false
|
|
55977
|
+
},
|
|
55978
|
+
{
|
|
55979
|
+
"name": "security",
|
|
55980
|
+
"type": "string | undefined",
|
|
55981
|
+
"required": false
|
|
55982
|
+
},
|
|
55983
|
+
{
|
|
55984
|
+
"name": "unselectable",
|
|
55985
|
+
"type": "\"off\" | \"on\" | undefined",
|
|
55986
|
+
"required": false
|
|
55987
|
+
},
|
|
55988
|
+
{
|
|
55989
|
+
"name": "popover",
|
|
55990
|
+
"type": "\"\" | \"auto\" | \"manual\" | \"hint\" | undefined",
|
|
55991
|
+
"required": false
|
|
55992
|
+
},
|
|
55993
|
+
{
|
|
55994
|
+
"name": "popoverTargetAction",
|
|
55995
|
+
"type": "\"toggle\" | \"show\" | \"hide\" | undefined",
|
|
55996
|
+
"required": false
|
|
55997
|
+
},
|
|
55998
|
+
{
|
|
55999
|
+
"name": "popoverTarget",
|
|
56000
|
+
"type": "string | undefined",
|
|
56001
|
+
"required": false
|
|
56002
|
+
},
|
|
56003
|
+
{
|
|
56004
|
+
"name": "inert",
|
|
56005
|
+
"type": "boolean | undefined",
|
|
56006
|
+
"required": false,
|
|
56007
|
+
"description": "@see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/inert}"
|
|
56008
|
+
},
|
|
56009
|
+
{
|
|
56010
|
+
"name": "inputMode",
|
|
56011
|
+
"type": "\"search\" | \"text\" | \"none\" | \"tel\" | \"url\" | \"email\" | \"numeric\" | \"decimal\" | undefined",
|
|
56012
|
+
"required": false,
|
|
56013
|
+
"description": "Hints at the type of data that might be entered by the user while editing the element or its contents"
|
|
56014
|
+
},
|
|
56015
|
+
{
|
|
56016
|
+
"name": "is",
|
|
56017
|
+
"type": "string | undefined",
|
|
56018
|
+
"required": false,
|
|
56019
|
+
"description": "Specify that a standard HTML element should behave like a defined custom built-in element"
|
|
56020
|
+
},
|
|
56021
|
+
{
|
|
56022
|
+
"name": "exportparts",
|
|
56023
|
+
"type": "string | undefined",
|
|
56024
|
+
"required": false,
|
|
56025
|
+
"description": "@see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/exportparts}"
|
|
56026
|
+
},
|
|
56027
|
+
{
|
|
56028
|
+
"name": "part",
|
|
56029
|
+
"type": "string | undefined",
|
|
56030
|
+
"required": false,
|
|
56031
|
+
"description": "@see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/part}"
|
|
56032
|
+
},
|
|
56033
|
+
{
|
|
56034
|
+
"name": "asChild",
|
|
56035
|
+
"type": "boolean | undefined",
|
|
56036
|
+
"required": false,
|
|
56037
|
+
"description": "Use the provided child element as the default rendered element, combining their props and behavior."
|
|
56038
|
+
}
|
|
56039
|
+
]
|
|
56040
|
+
},
|
|
55762
56041
|
{
|
|
55763
56042
|
"name": "ScrollAreaScrollbar",
|
|
55764
56043
|
"props": [
|
|
@@ -56338,6 +56617,11 @@
|
|
|
56338
56617
|
"name": "Horizontal",
|
|
56339
56618
|
"code": "() => (\n <div className='w-320 h-320 overflow-hidden'>\n <ScrollArea>\n <ScrollAreaViewport>\n <ScrollAreaContent>\n <HStack>\n {new Array(50).fill(null).map((_, index) => {\n const value = `${index + 1}`;\n\n return (\n <Box key={value} className='h-320 w-40'>\n {value}\n </Box>\n );\n })}\n </HStack>\n </ScrollAreaContent>\n </ScrollAreaViewport>\n\n <ScrollAreaScrollbar orientation='horizontal' />\n\n <ScrollAreaCorner />\n </ScrollArea>\n </div>\n)",
|
|
56340
56619
|
"description": "`orientation='horizontal'` puts the bar along the bottom edge, for a row that runs past its container rather than a column that runs below it."
|
|
56620
|
+
},
|
|
56621
|
+
{
|
|
56622
|
+
"name": "Virtualized",
|
|
56623
|
+
"code": "() => {\n const scrollRef = useRef<HTMLDivElement>(null);\n const virtualizer = useVirtualizer({\n count: 10_000,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => 44,\n overscan: 8,\n });\n\n return (\n <div className='w-320 h-320 overflow-hidden'>\n <ScrollArea>\n <ScrollAreaViewport ref={scrollRef}>\n <ScrollAreaContent className='h-auto min-h-full'>\n <div className='relative w-full' style={{ height: virtualizer.getTotalSize() }}>\n {virtualizer.getVirtualItems().map(item => (\n <div\n key={item.key}\n className='absolute top-0 left-0 w-full pb-4'\n style={{ height: item.size, transform: `translateY(${item.start}px)` }}\n >\n <Box className='h-full w-full'>{item.index + 1}</Box>\n </div>\n ))}\n </div>\n </ScrollAreaContent>\n </ScrollAreaViewport>\n\n <ScrollAreaScrollbar />\n\n <ScrollAreaCorner />\n </ScrollArea>\n </div>\n );\n}",
|
|
56624
|
+
"description": "`ScrollAreaViewport` forwards its `ref` to the scrolling element itself, so a row\nvirtualiser such as `@tanstack/react-virtual` can track scroll position inside the\nhouse scrollbar instead of falling back to a bare `overflow-y: auto` div. Ten thousand\nrows here, a few dozen in the DOM.\n\nTwo things this story is deliberately showing:\n\n- `useVirtualizer` is called in the same component that declares the ref. Called from a\n component rendered *inside* the viewport, `getScrollElement()` runs once — before React\n has attached the host element's ref — returns `null`, and nothing ever re-runs it, so the\n list stays permanently empty.\n- `ScrollAreaContent` gets `h-auto min-h-full` so it grows with the virtual sizer. The\n scrollbar is only rendered while the viewport reports `data-overflow-y`, and that flag is\n recomputed from a `ResizeObserver` watching the content box — which at its default `h-full`\n stays the height of the viewport. A list that grows *after* mount therefore keeps its\n scrollbar hidden until something else forces a remeasure."
|
|
56341
56625
|
}
|
|
56342
56626
|
]
|
|
56343
56627
|
},
|
|
@@ -59119,42 +59403,42 @@
|
|
|
59119
59403
|
"examples": [
|
|
59120
59404
|
{
|
|
59121
59405
|
"name": "Basic",
|
|
59122
|
-
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const filteredRecents = useMemo(() => filterItems(RECENT_ITEMS, query), [query]);\n const filteredJumpTo = useMemo(() => filterItems(JUMP_TO_ITEMS, query), [query]);\n const hasResults = filteredRecents.length > 0 || filteredJumpTo.length > 0;\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery} data-testid='search'>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Search products, features, and more\\u2026' />\n <SearchModalBody>\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Quick actions\n </Text>\n </SearchModalGroupLabel>\n <SearchModalItem onSelect={noop}>\n <WallyIcon size='sm' />\n <Text size='sm'>{query ? `Ask Wally \"${query}\"` : 'Ask Wally'}</Text>\n </SearchModalItem>\n {!query && (\n <>\n <SearchModalItem onSelect={noop}>\n <Users className='!icon-md' />\n <Text size='sm'>Switch tenant</Text>\n </SearchModalItem>\n <SearchModalItem onSelect={noop}>\n <Plus className='!icon-md' />\n <Text size='sm'>Create…</Text>\n </SearchModalItem>\n </>\n )}\n </SearchModalGroup>\n\n {filteredRecents.length > 0 && (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Recent\n </Text>\n </SearchModalGroupLabel>\n {filteredRecents.map(item => (\n <SearchModalItem key={item.id} onSelect={noop}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n <span className='ml-auto'>\n <Text size='xs' color='secondary'>\n {item.date}\n </Text>\n </span>\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n )}\n\n {(hasResults || !query) && (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n {query ? 'Go to' : 'Jump to'}\n </Text>\n </SearchModalGroupLabel>\n {(query ? filteredJumpTo : JUMP_TO_ITEMS).map(item => (\n <SearchModalItem key={item.id} onSelect={noop}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n <ChevronRight className='text-text-tertiary ml-auto !icon-sm' />\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n )}\n\n {query && !hasResults && (\n <SearchModalGroup>\n <SearchModalEmpty
|
|
59406
|
+
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const filteredRecents = useMemo(() => filterItems(RECENT_ITEMS, query), [query]);\n const filteredJumpTo = useMemo(() => filterItems(JUMP_TO_ITEMS, query), [query]);\n const hasResults = filteredRecents.length > 0 || filteredJumpTo.length > 0;\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery} data-testid='search'>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Search products, features, and more\\u2026' />\n <SearchModalBody>\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Quick actions\n </Text>\n </SearchModalGroupLabel>\n <SearchModalItem onSelect={noop}>\n <WallyIcon variant='circle' size='sm' />\n <Text size='sm'>{query ? `Ask Wally \"${query}\"` : 'Ask Wally'}</Text>\n </SearchModalItem>\n {!query && (\n <>\n <SearchModalItem onSelect={noop}>\n <Users className='!icon-md' />\n <Text size='sm'>Switch tenant</Text>\n </SearchModalItem>\n <SearchModalItem onSelect={noop}>\n <Plus className='!icon-md' />\n <Text size='sm'>Create…</Text>\n </SearchModalItem>\n </>\n )}\n </SearchModalGroup>\n\n {filteredRecents.length > 0 && (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Recent\n </Text>\n </SearchModalGroupLabel>\n {filteredRecents.map(item => (\n <SearchModalItem key={item.id} onSelect={noop}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n <span className='ml-auto'>\n <Text size='xs' color='secondary'>\n {item.date}\n </Text>\n </span>\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n )}\n\n {(hasResults || !query) && (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n {query ? 'Go to' : 'Jump to'}\n </Text>\n </SearchModalGroupLabel>\n {(query ? filteredJumpTo : JUMP_TO_ITEMS).map(item => (\n <SearchModalItem key={item.id} onSelect={noop}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n <ChevronRight className='text-text-tertiary ml-auto !icon-sm' />\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n )}\n\n {query && !hasResults && (\n <SearchModalGroup>\n <SearchModalEmpty>\n <Text size='sm' color='secondary'>\n No results\n </Text>\n </SearchModalEmpty>\n </SearchModalGroup>\n )}\n </SearchModalBody>\n <SearchModalFooter />\n </SearchModalContent>\n </SearchModal>\n );\n}",
|
|
59123
59407
|
"description": "The full palette with recent history. Type to filter: \"Jump to\" relabels to\n\"Go to\", recents hide when nothing matches, and a no-results fallback offers\nAsk Wally. Covers PRD states 1, 3, 4 and 5."
|
|
59124
59408
|
},
|
|
59125
59409
|
{
|
|
59126
59410
|
"name": "EmptyRecents",
|
|
59127
|
-
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const filteredJumpTo = useMemo(() => filterItems(JUMP_TO_ITEMS, query), [query]);\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Search products, features, and more\\u2026' />\n <SearchModalBody>\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Quick actions\n </Text>\n </SearchModalGroupLabel>\n <SearchModalItem onSelect={noop}>\n <WallyIcon size='sm' />\n <Text size='sm'>{query ? `Ask Wally \"${query}\"` : 'Ask Wally'}</Text>\n </SearchModalItem>\n {!query && (\n <>\n <SearchModalItem onSelect={noop}>\n <Users className='!icon-md' />\n <Text size='sm'>Switch tenant</Text>\n </SearchModalItem>\n <SearchModalItem onSelect={noop}>\n <Plus className='!icon-md' />\n <Text size='sm'>Create…</Text>\n </SearchModalItem>\n </>\n )}\n </SearchModalGroup>\n\n {!query && (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Recent\n </Text>\n </SearchModalGroupLabel>\n <SearchModalEmpty
|
|
59411
|
+
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const filteredJumpTo = useMemo(() => filterItems(JUMP_TO_ITEMS, query), [query]);\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Search products, features, and more\\u2026' />\n <SearchModalBody>\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Quick actions\n </Text>\n </SearchModalGroupLabel>\n <SearchModalItem onSelect={noop}>\n <WallyIcon variant='circle' size='sm' />\n <Text size='sm'>{query ? `Ask Wally \"${query}\"` : 'Ask Wally'}</Text>\n </SearchModalItem>\n {!query && (\n <>\n <SearchModalItem onSelect={noop}>\n <Users className='!icon-md' />\n <Text size='sm'>Switch tenant</Text>\n </SearchModalItem>\n <SearchModalItem onSelect={noop}>\n <Plus className='!icon-md' />\n <Text size='sm'>Create…</Text>\n </SearchModalItem>\n </>\n )}\n </SearchModalGroup>\n\n {!query && (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Recent\n </Text>\n </SearchModalGroupLabel>\n <SearchModalEmpty>\n <Text size='sm' color='secondary'>\n Nothing recent yet\n </Text>\n </SearchModalEmpty>\n </SearchModalGroup>\n )}\n\n {filteredJumpTo.length > 0 && (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n {query ? 'Go to' : 'Jump to'}\n </Text>\n </SearchModalGroupLabel>\n {filteredJumpTo.map(item => (\n <SearchModalItem key={item.id} onSelect={noop}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n <ChevronRight className='text-text-tertiary ml-auto !icon-sm' />\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n )}\n\n {query && filteredJumpTo.length === 0 && (\n <SearchModalGroup>\n <SearchModalEmpty>\n <Text size='sm' color='secondary'>\n No results\n </Text>\n </SearchModalEmpty>\n </SearchModalGroup>\n )}\n </SearchModalBody>\n <SearchModalFooter />\n </SearchModalContent>\n </SearchModal>\n );\n}",
|
|
59128
59412
|
"description": "A new user with no history. The Recent section shows \"Nothing recent yet\"\ninstead of items. Matches PRD state 2."
|
|
59129
59413
|
},
|
|
59130
59414
|
{
|
|
59131
59415
|
"name": "SubList",
|
|
59132
|
-
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const filtered = useMemo(() => filterItems(CREATE_ITEMS, query), [query]);\n const grouped = useMemo(() => {\n const map = new Map<string, NavItem[]>();\n for (const item of filtered) {\n const key = item.section ?? 'Other';\n const list = map.get(key);\n if (list) list.push(item);\n else map.set(key, [item]);\n }\n return map;\n }, [filtered]);\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Filter creatable items\\u2026' />\n <SearchModalBody>\n {filtered.length > 0 ? (\n [...grouped.entries()].map(([section, items]) => (\n <SearchModalGroup key={section}>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n {section}\n </Text>\n </SearchModalGroupLabel>\n {items.map(item => (\n <SearchModalItem key={item.id} onSelect={noop}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n ))\n ) : (\n <SearchModalGroup>\n <SearchModalEmpty
|
|
59416
|
+
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const filtered = useMemo(() => filterItems(CREATE_ITEMS, query), [query]);\n const grouped = useMemo(() => {\n const map = new Map<string, NavItem[]>();\n for (const item of filtered) {\n const key = item.section ?? 'Other';\n const list = map.get(key);\n if (list) list.push(item);\n else map.set(key, [item]);\n }\n return map;\n }, [filtered]);\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Filter creatable items\\u2026' />\n <SearchModalBody>\n {filtered.length > 0 ? (\n [...grouped.entries()].map(([section, items]) => (\n <SearchModalGroup key={section}>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n {section}\n </Text>\n </SearchModalGroupLabel>\n {items.map(item => (\n <SearchModalItem key={item.id} onSelect={noop}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n ))\n ) : (\n <SearchModalGroup>\n <SearchModalEmpty>\n <Text size='sm' color='secondary'>\n No results\n </Text>\n </SearchModalEmpty>\n </SearchModalGroup>\n )}\n </SearchModalBody>\n <SearchModalFooter>\n <span className='inline-flex items-center gap-4'>\n <Kbd size='xsmall'>esc</Kbd>\n <Text size='xs' color='secondary'>\n back\n </Text>\n </span>\n <span className='inline-flex items-center gap-4'>\n <Kbd size='xsmall'>↵</Kbd>\n <Text size='xs' color='secondary'>\n to select\n </Text>\n </span>\n </SearchModalFooter>\n </SearchModalContent>\n </SearchModal>\n );\n}",
|
|
59133
59417
|
"description": "A sub-list page pushed in place of the main body. Used for \"Create\\u2026\" and\n\"Switch tenant\". The footer changes to show \"esc back\" and \"enter to select\".\nDemonstrates PRD states 6 and 7."
|
|
59134
59418
|
},
|
|
59135
59419
|
{
|
|
59136
59420
|
"name": "ItemsAsLinks",
|
|
59137
|
-
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const filtered = useMemo(() => filterItems(JUMP_TO_ITEMS, query), [query]);\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Search products, features, and more\\u2026' />\n <SearchModalBody>\n {filtered.length > 0 ? (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n {query ? 'Go to' : 'Jump to'}\n </Text>\n </SearchModalGroupLabel>\n {filtered.map(item => (\n <SearchModalItem key={item.id} asChild onSelect={noop}>\n <a href={`#${item.id}`}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n <ChevronRight className='text-text-tertiary ml-auto !icon-sm' />\n </a>\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n ) : (\n <SearchModalGroup>\n <SearchModalEmpty
|
|
59421
|
+
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const filtered = useMemo(() => filterItems(JUMP_TO_ITEMS, query), [query]);\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Search products, features, and more\\u2026' />\n <SearchModalBody>\n {filtered.length > 0 ? (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n {query ? 'Go to' : 'Jump to'}\n </Text>\n </SearchModalGroupLabel>\n {filtered.map(item => (\n <SearchModalItem key={item.id} asChild onSelect={noop}>\n <a href={`#${item.id}`}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n <ChevronRight className='text-text-tertiary ml-auto !icon-sm' />\n </a>\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n ) : (\n <SearchModalGroup>\n <SearchModalEmpty>\n <Text size='sm' color='secondary'>\n No results\n </Text>\n </SearchModalEmpty>\n </SearchModalGroup>\n )}\n </SearchModalBody>\n <SearchModalFooter />\n </SearchModalContent>\n </SearchModal>\n );\n}",
|
|
59138
59422
|
"description": "Items rendered as links via `asChild`, for cases where results navigate to a URL."
|
|
59139
59423
|
},
|
|
59140
59424
|
{
|
|
59141
59425
|
"name": "DisabledItems",
|
|
59142
|
-
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const actions = useMemo(\n () =>\n filterItems(\n [\n { id: 'ask-wally', label: 'Ask Wally', icon: <WallyIcon size='sm' /> },\n { id: 'switch-tenant', label: 'Switch tenant', icon: <Users className='!icon-md' /> },\n { id: 'create', label: 'Create\\u2026', icon: <Plus className='!icon-md' /> },\n ],\n query,\n ),\n [query],\n );\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Search products, features, and more\\u2026' />\n <SearchModalBody>\n {actions.length > 0 ? (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Quick actions\n </Text>\n </SearchModalGroupLabel>\n {actions.map(item => (\n <SearchModalItem\n key={item.id}\n onSelect={item.id === 'switch-tenant' ? undefined : noop}\n disabled={item.id === 'switch-tenant'}\n >\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n {item.id === 'switch-tenant' && (\n <span className='ml-auto'>\n <Text size='xs' color='secondary'>\n Unavailable\n </Text>\n </span>\n )}\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n ) : (\n <SearchModalGroup>\n <SearchModalEmpty
|
|
59426
|
+
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const actions = useMemo(\n () =>\n filterItems(\n [\n { id: 'ask-wally', label: 'Ask Wally', icon: <WallyIcon variant='circle' size='sm' /> },\n { id: 'switch-tenant', label: 'Switch tenant', icon: <Users className='!icon-md' /> },\n { id: 'create', label: 'Create\\u2026', icon: <Plus className='!icon-md' /> },\n ],\n query,\n ),\n [query],\n );\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Search products, features, and more\\u2026' />\n <SearchModalBody>\n {actions.length > 0 ? (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Quick actions\n </Text>\n </SearchModalGroupLabel>\n {actions.map(item => (\n <SearchModalItem\n key={item.id}\n onSelect={item.id === 'switch-tenant' ? undefined : noop}\n disabled={item.id === 'switch-tenant'}\n >\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n {item.id === 'switch-tenant' && (\n <span className='ml-auto'>\n <Text size='xs' color='secondary'>\n Unavailable\n </Text>\n </span>\n )}\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n ) : (\n <SearchModalGroup>\n <SearchModalEmpty>\n <Text size='sm' color='secondary'>\n No results\n </Text>\n </SearchModalEmpty>\n </SearchModalGroup>\n )}\n </SearchModalBody>\n <SearchModalFooter />\n </SearchModalContent>\n </SearchModal>\n );\n}",
|
|
59143
59427
|
"description": "Disabled items are excluded from keyboard navigation and cannot be selected."
|
|
59144
59428
|
},
|
|
59145
59429
|
{
|
|
59146
59430
|
"name": "CloseOnSelectFalse",
|
|
59147
|
-
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [selected, setSelected] = useState<string[]>([]);\n\n const filtered = useMemo(() => filterItems(JUMP_TO_ITEMS, query), [query]);\n\n const toggleItem = useCallback(\n (id: string) =>\n setSelected(prev => (prev.includes(id) ? prev.filter(v => v !== id) : [...prev, id])),\n [],\n );\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Pick items (modal stays open)\\u2026' />\n <SearchModalBody>\n {filtered.length > 0 ? (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Products {selected.length > 0 && `(${selected.length} selected)`}\n </Text>\n </SearchModalGroupLabel>\n {filtered.map(item => (\n <SearchModalItem\n key={item.id}\n closeOnSelect={false}\n onSelect={() => toggleItem(item.id)}\n >\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n {selected.includes(item.id) && (\n <span className='ml-auto'>\n <Text size='xs' color='primary-alt'>\n Selected\n </Text>\n </span>\n )}\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n ) : (\n <SearchModalGroup>\n <SearchModalEmpty
|
|
59431
|
+
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [selected, setSelected] = useState<string[]>([]);\n\n const filtered = useMemo(() => filterItems(JUMP_TO_ITEMS, query), [query]);\n\n const toggleItem = useCallback(\n (id: string) =>\n setSelected(prev => (prev.includes(id) ? prev.filter(v => v !== id) : [...prev, id])),\n [],\n );\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Pick items (modal stays open)\\u2026' />\n <SearchModalBody>\n {filtered.length > 0 ? (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n Products {selected.length > 0 && `(${selected.length} selected)`}\n </Text>\n </SearchModalGroupLabel>\n {filtered.map(item => (\n <SearchModalItem\n key={item.id}\n closeOnSelect={false}\n onSelect={() => toggleItem(item.id)}\n >\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n {selected.includes(item.id) && (\n <span className='ml-auto'>\n <Text size='xs' color='primary-alt'>\n Selected\n </Text>\n </span>\n )}\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n ) : (\n <SearchModalGroup>\n <SearchModalEmpty>\n <Text size='sm' color='secondary'>\n No results\n </Text>\n </SearchModalEmpty>\n </SearchModalGroup>\n )}\n </SearchModalBody>\n <SearchModalFooter />\n </SearchModalContent>\n </SearchModal>\n );\n}",
|
|
59148
59432
|
"description": "`closeOnSelect={false}` keeps the modal open after selecting an item, useful\nfor multi-step flows like the sub-list mechanic."
|
|
59149
59433
|
},
|
|
59150
59434
|
{
|
|
59151
59435
|
"name": "Controlled",
|
|
59152
|
-
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const filtered = useMemo(() => filterItems(JUMP_TO_ITEMS, query), [query]);\n\n return (\n <>\n <Button variant='outline' color='neutral' onClick={() => setOpen(true)}>\n Open Programmatically\n </Button>\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchModalContent>\n <SearchModalInput placeholder='Search products, features, and more\\u2026' />\n <SearchModalBody>\n {filtered.length > 0 ? (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n {query ? 'Go to' : 'Jump to'}\n </Text>\n </SearchModalGroupLabel>\n {filtered.map(item => (\n <SearchModalItem key={item.id} onSelect={noop}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n ) : (\n <SearchModalGroup>\n <SearchModalEmpty
|
|
59436
|
+
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const filtered = useMemo(() => filterItems(JUMP_TO_ITEMS, query), [query]);\n\n return (\n <>\n <Button variant='outline' color='neutral' onClick={() => setOpen(true)}>\n Open Programmatically\n </Button>\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchModalContent>\n <SearchModalInput placeholder='Search products, features, and more\\u2026' />\n <SearchModalBody>\n {filtered.length > 0 ? (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n {query ? 'Go to' : 'Jump to'}\n </Text>\n </SearchModalGroupLabel>\n {filtered.map(item => (\n <SearchModalItem key={item.id} onSelect={noop}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n ) : (\n <SearchModalGroup>\n <SearchModalEmpty>\n <Text size='sm' color='secondary'>\n No results\n </Text>\n </SearchModalEmpty>\n </SearchModalGroup>\n )}\n </SearchModalBody>\n <SearchModalFooter />\n </SearchModalContent>\n </SearchModal>\n </>\n );\n}",
|
|
59153
59437
|
"description": "Controlled open state, driven entirely from outside the component.\nNo `SearchModalTrigger` — the button calls `setOpen` directly."
|
|
59154
59438
|
},
|
|
59155
59439
|
{
|
|
59156
59440
|
"name": "Scrollable",
|
|
59157
|
-
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const allItems = useMemo(\n () =>\n Array.from({ length: 30 }, (_, i) => ({\n id: `item-${i}`,\n label: `Feature ${i + 1}`,\n icon: <Compass className='text-text-
|
|
59441
|
+
"code": "() => {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const allItems = useMemo(\n () =>\n Array.from({ length: 30 }, (_, i) => ({\n id: `item-${i}`,\n label: `Feature ${i + 1}`,\n icon: <Compass className='text-text-primary !icon-md' />,\n })),\n [],\n );\n\n const filtered = useMemo(() => filterItems(allItems, query), [allItems, query]);\n\n return (\n <SearchModal open={open} onOpenChange={setOpen} onQueryChange={setQuery}>\n <SearchTriggerButton />\n <SearchModalContent>\n <SearchModalInput placeholder='Search products, features, and more\\u2026' />\n <SearchModalBody>\n {filtered.length > 0 ? (\n <SearchModalGroup>\n <SearchModalGroupLabel>\n <Text size='xs' color='secondary' weight='medium'>\n All features\n </Text>\n </SearchModalGroupLabel>\n {filtered.map(item => (\n <SearchModalItem key={item.id} onSelect={noop}>\n {item.icon}\n <Text size='sm'>{item.label}</Text>\n </SearchModalItem>\n ))}\n </SearchModalGroup>\n ) : (\n <SearchModalGroup>\n <SearchModalEmpty>\n <Text size='sm' color='secondary'>\n No results\n </Text>\n </SearchModalEmpty>\n </SearchModalGroup>\n )}\n </SearchModalBody>\n <SearchModalFooter />\n </SearchModalContent>\n </SearchModal>\n );\n}",
|
|
59158
59442
|
"description": "The scrollable body when there are many items. The input and footer stay fixed\nwhile the body scrolls."
|
|
59159
59443
|
}
|
|
59160
59444
|
]
|
package/dist/theme/index.css
CHANGED