@wallarm-org/design-system 1.20.4 → 1.22.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 +3 -3
- package/dist/components/CodeSnippet/CodeSnippetCopyButton.d.ts +1 -1
- package/dist/components/CodeSnippet/CodeSnippetCopyButton.js +14 -7
- package/dist/components/CodeSnippet/InlineCodeSnippet.js +7 -25
- package/dist/components/Copyable/Copyable.d.ts +39 -0
- package/dist/components/Copyable/Copyable.js +85 -0
- package/dist/components/Copyable/CopyableContext.d.ts +11 -0
- package/dist/components/Copyable/CopyableContext.js +9 -0
- package/dist/components/Copyable/CopyableIcon.d.ts +9 -0
- package/dist/components/Copyable/CopyableIcon.js +13 -0
- package/dist/components/Copyable/CopyableLabel.d.ts +18 -0
- package/dist/components/Copyable/CopyableLabel.js +24 -0
- package/dist/components/Copyable/index.d.ts +4 -0
- package/dist/components/Copyable/index.js +4 -0
- package/dist/components/SearchInput/SearchInput.d.ts +18 -0
- package/dist/components/SearchInput/SearchInput.js +54 -0
- package/dist/components/SearchInput/index.d.ts +1 -0
- package/dist/components/SearchInput/index.js +1 -0
- package/dist/components/SearchModal/SearchModalInput.js +16 -3
- package/dist/components/SegmentedControl/classes.js +1 -1
- package/dist/components/Select/Select.d.ts +3 -1
- package/dist/components/Select/Select.js +6 -3
- package/dist/components/Select/SelectSearchInput.js +6 -19
- package/dist/components/SettingsHeader/SettingsHeader.d.ts +7 -0
- package/dist/components/SettingsHeader/SettingsHeader.js +16 -0
- package/dist/components/SettingsHeader/SettingsHeaderActions.d.ts +6 -0
- package/dist/components/SettingsHeader/SettingsHeaderActions.js +16 -0
- package/dist/components/SettingsHeader/SettingsHeaderBreadcrumbs.d.ts +6 -0
- package/dist/components/SettingsHeader/SettingsHeaderBreadcrumbs.js +16 -0
- package/dist/components/SettingsHeader/SettingsHeaderDescription.d.ts +5 -0
- package/dist/components/SettingsHeader/SettingsHeaderDescription.js +16 -0
- package/dist/components/SettingsHeader/SettingsHeaderFilters.d.ts +6 -0
- package/dist/components/SettingsHeader/SettingsHeaderFilters.js +16 -0
- package/dist/components/SettingsHeader/SettingsHeaderHeading.d.ts +6 -0
- package/dist/components/SettingsHeader/SettingsHeaderHeading.js +16 -0
- package/dist/components/SettingsHeader/SettingsHeaderTitle.d.ts +5 -0
- package/dist/components/SettingsHeader/SettingsHeaderTitle.js +16 -0
- package/dist/components/SettingsHeader/index.d.ts +7 -0
- package/dist/components/SettingsHeader/index.js +7 -0
- package/dist/components/Table/EditableCell/EditableSelectCell.d.ts +1 -1
- package/dist/components/Table/EditableCell/EditableSelectCell.js +12 -1
- package/dist/components/Table/StickyGroupParent.js +7 -8
- package/dist/components/Table/TableBody/TableBodyCell.d.ts +3 -1
- package/dist/components/Table/TableBody/TableBodyCell.js +6 -2
- package/dist/components/Table/TableBody/TableBodyRowDndContext.d.ts +5 -0
- package/dist/components/Table/TableBody/TableBodyRowDndContext.js +65 -21
- package/dist/components/Table/TableBody/TableRowOverlay.js +2 -1
- package/dist/components/Table/TableColGroup.js +20 -17
- package/dist/components/Table/TableContext/TableProvider.js +3 -1
- package/dist/components/Table/TableContext/types.d.ts +1 -0
- package/dist/components/Table/TableHead.js +13 -8
- package/dist/components/Table/TableLoadingState.js +19 -13
- package/dist/components/Table/TableMasterCellActions.js +2 -5
- package/dist/components/Table/TableRow.js +42 -12
- package/dist/components/Table/TableRowExpanded.js +3 -2
- package/dist/components/Table/classes.d.ts +5 -0
- package/dist/components/Table/classes.js +2 -1
- package/dist/components/Table/hooks/useStickyGroupParent.js +3 -1
- package/dist/components/Table/lib/constants.d.ts +1 -1
- package/dist/components/Table/lib/constants.js +1 -1
- package/dist/components/Table/lib/createDragHandleColumn.js +3 -3
- package/dist/components/Table/lib/useRowDnd.js +3 -13
- package/dist/components/Table/types.d.ts +8 -0
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/index.js +0 -1
- package/dist/hooks/useCopyToClipboard.d.ts +9 -10
- package/dist/hooks/useCopyToClipboard.js +6 -18
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/metadata/components.json +12502 -9142
- package/package.json +1 -1
- package/dist/components/CopyButton/CopyButton.d.ts +0 -16
- package/dist/components/CopyButton/CopyButton.js +0 -63
- package/dist/components/CopyButton/index.d.ts +0 -1
- package/dist/components/CopyButton/index.js +0 -1
- package/dist/hooks/useCopyTooltip.d.ts +0 -12
- package/dist/hooks/useCopyTooltip.js +0 -63
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "react";
|
|
3
|
-
import { Building,
|
|
3
|
+
import { Building, CircleDashed, Plus } from "../../../icons/index.js";
|
|
4
4
|
import { Button } from "../../Button/index.js";
|
|
5
5
|
import { Code } from "../../Code/index.js";
|
|
6
6
|
import { EmptyState, EmptyStateDescription, EmptyStateMessage } from "../../EmptyState/index.js";
|
|
@@ -184,7 +184,7 @@ const StorySearchModal = ()=>{
|
|
|
184
184
|
filteredRecent.map((item)=>/*#__PURE__*/ jsxs(SearchModalItem, {
|
|
185
185
|
onSelect: ()=>{},
|
|
186
186
|
children: [
|
|
187
|
-
/*#__PURE__*/ jsx(
|
|
187
|
+
/*#__PURE__*/ jsx(CircleDashed, {
|
|
188
188
|
className: "text-text-primary shrink-0 !icon-md"
|
|
189
189
|
}),
|
|
190
190
|
/*#__PURE__*/ jsxs(Text, {
|
|
@@ -230,7 +230,7 @@ const StorySearchModal = ()=>{
|
|
|
230
230
|
filteredJumpTo.map((item)=>/*#__PURE__*/ jsxs(SearchModalItem, {
|
|
231
231
|
onSelect: ()=>{},
|
|
232
232
|
children: [
|
|
233
|
-
/*#__PURE__*/ jsx(
|
|
233
|
+
/*#__PURE__*/ jsx(CircleDashed, {
|
|
234
234
|
className: "text-text-primary shrink-0 !icon-md"
|
|
235
235
|
}),
|
|
236
236
|
/*#__PURE__*/ jsx(Text, {
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useTestId } from "../../utils/testId.js";
|
|
3
|
-
import {
|
|
3
|
+
import { Button } from "../Button/index.js";
|
|
4
|
+
import { Copyable, CopyableIcon } from "../Copyable/index.js";
|
|
4
5
|
import { useCodeSnippet } from "./hooks/index.js";
|
|
5
6
|
const CodeSnippetCopyButton = ({ ref, ...props })=>{
|
|
6
7
|
const testId = useTestId('copy-button');
|
|
7
8
|
const { code } = useCodeSnippet();
|
|
8
|
-
return /*#__PURE__*/ jsx(
|
|
9
|
-
ref: ref,
|
|
9
|
+
return /*#__PURE__*/ jsx(Copyable, {
|
|
10
10
|
text: code,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
tooltip: true,
|
|
12
|
+
children: /*#__PURE__*/ jsx(Button, {
|
|
13
|
+
ref: ref,
|
|
14
|
+
variant: "ghost",
|
|
15
|
+
color: "neutral",
|
|
16
|
+
size: "small",
|
|
17
|
+
"aria-label": "Copy code",
|
|
18
|
+
"data-testid": testId,
|
|
19
|
+
...props,
|
|
20
|
+
children: /*#__PURE__*/ jsx(CopyableIcon, {})
|
|
21
|
+
})
|
|
15
22
|
});
|
|
16
23
|
};
|
|
17
24
|
CodeSnippetCopyButton.displayName = 'CodeSnippetCopyButton';
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { jsx
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cloneElement, isValidElement } from "react";
|
|
3
3
|
import { Slot } from "@radix-ui/react-slot";
|
|
4
4
|
import { cva } from "class-variance-authority";
|
|
5
|
-
import { useCopyTooltip } from "../../hooks/index.js";
|
|
6
5
|
import { cn } from "../../utils/cn.js";
|
|
7
|
-
import {
|
|
6
|
+
import { Copyable } from "../Copyable/index.js";
|
|
8
7
|
const inlineCodeSnippetVariants = cva("inline-flex items-center code-snippet-bg rounded-6 font-mono font-normal text-syntax-no-syntax", {
|
|
9
8
|
variants: {
|
|
10
9
|
size: {
|
|
@@ -21,14 +20,6 @@ const inlineCodeSnippetVariants = cva("inline-flex items-center code-snippet-bg
|
|
|
21
20
|
});
|
|
22
21
|
const InlineCodeSnippet = (props)=>{
|
|
23
22
|
const { code, size = 'inherit', asChild = false, copyable = true, className, onClick, ref, children, ...otherProps } = props;
|
|
24
|
-
const { copied, tooltipOpen, onTooltipOpenChange, handleCopy } = useCopyTooltip({
|
|
25
|
-
text: code,
|
|
26
|
-
enabled: copyable
|
|
27
|
-
});
|
|
28
|
-
const handleClick = (event)=>{
|
|
29
|
-
handleCopy();
|
|
30
|
-
onClick?.(event);
|
|
31
|
-
};
|
|
32
23
|
const sharedProps = {
|
|
33
24
|
ref,
|
|
34
25
|
'data-slot': 'inline-code-snippet',
|
|
@@ -38,7 +29,7 @@ const InlineCodeSnippet = (props)=>{
|
|
|
38
29
|
copyable
|
|
39
30
|
}), className),
|
|
40
31
|
...otherProps,
|
|
41
|
-
onClick
|
|
32
|
+
onClick
|
|
42
33
|
};
|
|
43
34
|
const codeElement = asChild && /*#__PURE__*/ isValidElement(children) ? /*#__PURE__*/ jsx(Slot, {
|
|
44
35
|
...sharedProps,
|
|
@@ -48,19 +39,10 @@ const InlineCodeSnippet = (props)=>{
|
|
|
48
39
|
children: code
|
|
49
40
|
});
|
|
50
41
|
if (!copyable) return codeElement;
|
|
51
|
-
return /*#__PURE__*/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
children: [
|
|
56
|
-
/*#__PURE__*/ jsx(TooltipTrigger, {
|
|
57
|
-
asChild: true,
|
|
58
|
-
children: codeElement
|
|
59
|
-
}),
|
|
60
|
-
/*#__PURE__*/ jsx(TooltipContent, {
|
|
61
|
-
children: copied ? 'Copied' : 'Click to copy'
|
|
62
|
-
})
|
|
63
|
-
]
|
|
42
|
+
return /*#__PURE__*/ jsx(Copyable, {
|
|
43
|
+
text: code,
|
|
44
|
+
tooltip: true,
|
|
45
|
+
children: codeElement
|
|
64
46
|
});
|
|
65
47
|
};
|
|
66
48
|
InlineCodeSnippet.displayName = 'InlineCodeSnippet';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type FC, type ReactNode } from 'react';
|
|
2
|
+
export interface CopyableProps {
|
|
3
|
+
/** The text to copy to the clipboard. */
|
|
4
|
+
text: string;
|
|
5
|
+
/**
|
|
6
|
+
* Show a tooltip with copy feedback.
|
|
7
|
+
*
|
|
8
|
+
* - `true` — "Click to copy" / "Copied"
|
|
9
|
+
* - `string` — custom idle text; copied text stays "Copied"
|
|
10
|
+
* - `{ idle: string; copied: string }` — fully custom tooltip text
|
|
11
|
+
*/
|
|
12
|
+
tooltip?: boolean | string | {
|
|
13
|
+
idle: string;
|
|
14
|
+
copied: string;
|
|
15
|
+
};
|
|
16
|
+
/** Fired after a successful copy. Use for toast feedback. */
|
|
17
|
+
onCopied?: () => void;
|
|
18
|
+
/** Time in ms before the `copied` state resets (default: 2000). */
|
|
19
|
+
resetDelay?: number;
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Headless click-to-copy behaviour wrapper.
|
|
24
|
+
*
|
|
25
|
+
* Renders **no DOM node of its own** — it injects an `onClick` handler onto
|
|
26
|
+
* its child via `@radix-ui/react-slot` and exposes a `copied` flag through
|
|
27
|
+
* React context so descendants like `<CopyableIcon>` and `<CopyableLabel>`
|
|
28
|
+
* can react to the copy state.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <Copyable text={value} tooltip>
|
|
33
|
+
* <Button variant="ghost" size="small">
|
|
34
|
+
* <CopyableIcon />
|
|
35
|
+
* </Button>
|
|
36
|
+
* </Copyable>
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare const Copyable: FC<CopyableProps>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
4
|
+
import { useCopyToClipboard } from "../../hooks/useCopyToClipboard.js";
|
|
5
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "../Tooltip/index.js";
|
|
6
|
+
import { CopyableProvider } from "./CopyableContext.js";
|
|
7
|
+
const Copyable = ({ text, tooltip, onCopied, resetDelay = 2000, children })=>{
|
|
8
|
+
const { copied, copy } = useCopyToClipboard(resetDelay);
|
|
9
|
+
const [hovering, setHovering] = useState(false);
|
|
10
|
+
const [keepOpen, setKeepOpen] = useState(false);
|
|
11
|
+
const keepOpenTimerRef = useRef(void 0);
|
|
12
|
+
const tooltipOpen = hovering || keepOpen;
|
|
13
|
+
const handleClick = useCallback((_event)=>{
|
|
14
|
+
copy(text);
|
|
15
|
+
onCopied?.();
|
|
16
|
+
if (tooltip) {
|
|
17
|
+
setKeepOpen(true);
|
|
18
|
+
clearTimeout(keepOpenTimerRef.current);
|
|
19
|
+
keepOpenTimerRef.current = setTimeout(()=>{
|
|
20
|
+
setKeepOpen(false);
|
|
21
|
+
}, resetDelay);
|
|
22
|
+
}
|
|
23
|
+
}, [
|
|
24
|
+
copy,
|
|
25
|
+
text,
|
|
26
|
+
onCopied,
|
|
27
|
+
tooltip,
|
|
28
|
+
resetDelay
|
|
29
|
+
]);
|
|
30
|
+
const handleTooltipOpenChange = useCallback((open)=>{
|
|
31
|
+
setHovering(open);
|
|
32
|
+
}, []);
|
|
33
|
+
useEffect(()=>{
|
|
34
|
+
if (!keepOpen) return;
|
|
35
|
+
let listenerAdded = false;
|
|
36
|
+
const dismiss = ()=>{
|
|
37
|
+
setKeepOpen(false);
|
|
38
|
+
clearTimeout(keepOpenTimerRef.current);
|
|
39
|
+
};
|
|
40
|
+
const frame = requestAnimationFrame(()=>{
|
|
41
|
+
document.addEventListener('pointerdown', dismiss);
|
|
42
|
+
listenerAdded = true;
|
|
43
|
+
});
|
|
44
|
+
return ()=>{
|
|
45
|
+
cancelAnimationFrame(frame);
|
|
46
|
+
if (listenerAdded) document.removeEventListener('pointerdown', dismiss);
|
|
47
|
+
};
|
|
48
|
+
}, [
|
|
49
|
+
keepOpen
|
|
50
|
+
]);
|
|
51
|
+
const tooltipIdle = 'string' == typeof tooltip ? tooltip : 'object' == typeof tooltip ? tooltip.idle : 'Click to copy';
|
|
52
|
+
const tooltipCopied = 'object' == typeof tooltip ? tooltip.copied : 'Copied';
|
|
53
|
+
const ctx = useMemo(()=>({
|
|
54
|
+
copied
|
|
55
|
+
}), [
|
|
56
|
+
copied
|
|
57
|
+
]);
|
|
58
|
+
const slotted = /*#__PURE__*/ jsx(Slot, {
|
|
59
|
+
onClick: handleClick,
|
|
60
|
+
children: children
|
|
61
|
+
});
|
|
62
|
+
if (!tooltip) return /*#__PURE__*/ jsx(CopyableProvider, {
|
|
63
|
+
value: ctx,
|
|
64
|
+
children: slotted
|
|
65
|
+
});
|
|
66
|
+
return /*#__PURE__*/ jsx(CopyableProvider, {
|
|
67
|
+
value: ctx,
|
|
68
|
+
children: /*#__PURE__*/ jsxs(Tooltip, {
|
|
69
|
+
open: tooltipOpen,
|
|
70
|
+
onOpenChange: handleTooltipOpenChange,
|
|
71
|
+
closeOnPointerDown: false,
|
|
72
|
+
children: [
|
|
73
|
+
/*#__PURE__*/ jsx(TooltipTrigger, {
|
|
74
|
+
asChild: true,
|
|
75
|
+
children: slotted
|
|
76
|
+
}),
|
|
77
|
+
/*#__PURE__*/ jsx(TooltipContent, {
|
|
78
|
+
children: copied ? tooltipCopied : tooltipIdle
|
|
79
|
+
})
|
|
80
|
+
]
|
|
81
|
+
})
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
Copyable.displayName = 'Copyable';
|
|
85
|
+
export { Copyable };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface CopyableContextValue {
|
|
2
|
+
copied: boolean;
|
|
3
|
+
}
|
|
4
|
+
export declare const CopyableProvider: import("react").Provider<CopyableContextValue | null>;
|
|
5
|
+
/**
|
|
6
|
+
* Read the `copied` state from the nearest `<Copyable>` ancestor.
|
|
7
|
+
*
|
|
8
|
+
* @throws when called outside a `<Copyable>` tree.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useCopyable(): CopyableContextValue;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
const CopyableContext = createContext(null);
|
|
3
|
+
const CopyableProvider = CopyableContext.Provider;
|
|
4
|
+
function useCopyable() {
|
|
5
|
+
const ctx = useContext(CopyableContext);
|
|
6
|
+
if (!ctx) throw new Error('useCopyable must be used within a <Copyable> component');
|
|
7
|
+
return ctx;
|
|
8
|
+
}
|
|
9
|
+
export { CopyableProvider, useCopyable };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
import type { SvgIconProps } from '../../icons/SvgIcon';
|
|
3
|
+
export type CopyableIconProps = SvgIconProps;
|
|
4
|
+
/**
|
|
5
|
+
* Swaps between `Copy` and `Check` icons based on the parent `<Copyable>` state.
|
|
6
|
+
*
|
|
7
|
+
* Must be rendered inside a `<Copyable>` tree.
|
|
8
|
+
*/
|
|
9
|
+
export declare const CopyableIcon: FC<CopyableIconProps>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Check, Copy } from "../../icons/index.js";
|
|
3
|
+
import { useCopyable } from "./CopyableContext.js";
|
|
4
|
+
const CopyableIcon = (props)=>{
|
|
5
|
+
const { copied } = useCopyable();
|
|
6
|
+
return copied ? /*#__PURE__*/ jsx(Check, {
|
|
7
|
+
...props
|
|
8
|
+
}) : /*#__PURE__*/ jsx(Copy, {
|
|
9
|
+
...props
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
CopyableIcon.displayName = 'CopyableIcon';
|
|
13
|
+
export { CopyableIcon };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
export interface CopyableLabelProps {
|
|
3
|
+
/** Label shown in the idle state */
|
|
4
|
+
idle: string;
|
|
5
|
+
/** Label shown after a successful copy (default: "Copied") */
|
|
6
|
+
copied?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Width-stable label swap driven by the parent `<Copyable>` state.
|
|
11
|
+
*
|
|
12
|
+
* Both labels are rendered in the same CSS-grid cell so the element always
|
|
13
|
+
* occupies the width of the wider string. The inactive label is visually
|
|
14
|
+
* hidden but still contributes to layout.
|
|
15
|
+
*
|
|
16
|
+
* Must be rendered inside a `<Copyable>` tree.
|
|
17
|
+
*/
|
|
18
|
+
export declare const CopyableLabel: FC<CopyableLabelProps>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../utils/cn.js";
|
|
3
|
+
import { useCopyable } from "./CopyableContext.js";
|
|
4
|
+
const CopyableLabel = ({ idle, copied: copiedText = 'Copied', className })=>{
|
|
5
|
+
const { copied } = useCopyable();
|
|
6
|
+
return /*#__PURE__*/ jsxs("span", {
|
|
7
|
+
"data-slot": "copyable-label",
|
|
8
|
+
className: cn('inline-grid [&>*]:col-start-1 [&>*]:row-start-1', className),
|
|
9
|
+
children: [
|
|
10
|
+
/*#__PURE__*/ jsx("span", {
|
|
11
|
+
"aria-hidden": copied || void 0,
|
|
12
|
+
className: copied ? 'invisible' : void 0,
|
|
13
|
+
children: idle
|
|
14
|
+
}),
|
|
15
|
+
/*#__PURE__*/ jsx("span", {
|
|
16
|
+
"aria-hidden": !copied || void 0,
|
|
17
|
+
className: copied ? void 0 : 'invisible',
|
|
18
|
+
children: copiedText
|
|
19
|
+
})
|
|
20
|
+
]
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
CopyableLabel.displayName = 'CopyableLabel';
|
|
24
|
+
export { CopyableLabel };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FC, InputHTMLAttributes, Ref } from 'react';
|
|
2
|
+
import type { TestableProps } from '../../utils/testId';
|
|
3
|
+
type SearchInputSize = 'default' | 'medium' | 'small';
|
|
4
|
+
export interface SearchInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange'>, TestableProps {
|
|
5
|
+
/** Current search value (controlled). */
|
|
6
|
+
value: string;
|
|
7
|
+
/** Called when the value changes (typing or clearing). */
|
|
8
|
+
onChange: (value: string) => void;
|
|
9
|
+
/** Called when the clear button is clicked. Fires before onChange(''). */
|
|
10
|
+
onClear?: () => void;
|
|
11
|
+
/** Input size variant. @default 'default' */
|
|
12
|
+
size?: SearchInputSize;
|
|
13
|
+
/** @default false */
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
ref?: Ref<HTMLInputElement>;
|
|
16
|
+
}
|
|
17
|
+
export declare const SearchInput: FC<SearchInputProps>;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Search, X } from "../../icons/index.js";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
import { Input } from "../Input/index.js";
|
|
5
|
+
import { InputGroup } from "../InputGroup/InputGroup.js";
|
|
6
|
+
import { InputGroupAddon } from "../InputGroup/InputGroupAddon.js";
|
|
7
|
+
const SearchInput = ({ value, onChange, onClear, size = 'default', disabled = false, placeholder = 'Search', className, ref, 'data-testid': testId, ...rest })=>{
|
|
8
|
+
const handleChange = (event)=>{
|
|
9
|
+
onChange(event.target.value);
|
|
10
|
+
};
|
|
11
|
+
const handleClear = ()=>{
|
|
12
|
+
onClear?.();
|
|
13
|
+
onChange('');
|
|
14
|
+
};
|
|
15
|
+
const showClear = value.length > 0 && !disabled;
|
|
16
|
+
return /*#__PURE__*/ jsxs(InputGroup, {
|
|
17
|
+
size: size,
|
|
18
|
+
className: className,
|
|
19
|
+
"data-slot": "search-input",
|
|
20
|
+
"data-testid": testId,
|
|
21
|
+
children: [
|
|
22
|
+
/*#__PURE__*/ jsx(InputGroupAddon, {
|
|
23
|
+
children: /*#__PURE__*/ jsx(Search, {})
|
|
24
|
+
}),
|
|
25
|
+
/*#__PURE__*/ jsx(Input, {
|
|
26
|
+
...rest,
|
|
27
|
+
type: "text",
|
|
28
|
+
value: value,
|
|
29
|
+
onChange: handleChange,
|
|
30
|
+
placeholder: placeholder,
|
|
31
|
+
disabled: disabled,
|
|
32
|
+
size: size,
|
|
33
|
+
ref: ref
|
|
34
|
+
}),
|
|
35
|
+
/*#__PURE__*/ jsx(InputGroupAddon, {
|
|
36
|
+
align: "inline-end",
|
|
37
|
+
children: /*#__PURE__*/ jsx("button", {
|
|
38
|
+
type: "button",
|
|
39
|
+
tabIndex: showClear ? -1 : void 0,
|
|
40
|
+
disabled: !showClear,
|
|
41
|
+
onClick: handleClear,
|
|
42
|
+
"aria-label": "Clear",
|
|
43
|
+
"aria-hidden": !showClear,
|
|
44
|
+
className: cn('flex text-icon-secondary', showClear ? 'cursor-pointer' : 'invisible'),
|
|
45
|
+
children: /*#__PURE__*/ jsx(X, {
|
|
46
|
+
size: "md"
|
|
47
|
+
})
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
]
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
SearchInput.displayName = 'SearchInput';
|
|
54
|
+
export { SearchInput };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SearchInput, type SearchInputProps } from './SearchInput';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SearchInput } from "./SearchInput.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Search } from "../../icons/index.js";
|
|
2
|
+
import { Search, X } from "../../icons/index.js";
|
|
3
3
|
import { cn } from "../../utils/cn.js";
|
|
4
4
|
import { mergeRefs } from "../../utils/mergeRefs.js";
|
|
5
5
|
import { useTestId } from "../../utils/testId.js";
|
|
@@ -31,14 +31,27 @@ const SearchModalInput = ({ ref, loading = false, className, ...props })=>{
|
|
|
31
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
|
+
query && /*#__PURE__*/ jsx("button", {
|
|
35
|
+
type: "button",
|
|
36
|
+
tabIndex: -1,
|
|
37
|
+
onClick: ()=>{
|
|
38
|
+
setQuery('');
|
|
39
|
+
inputRef.current?.focus();
|
|
40
|
+
},
|
|
41
|
+
className: "shrink-0 cursor-pointer text-text-secondary hover:text-text-primary transition-colors",
|
|
42
|
+
"aria-label": "Clear search",
|
|
43
|
+
children: /*#__PURE__*/ jsx(X, {
|
|
44
|
+
className: "!icon-md"
|
|
45
|
+
})
|
|
46
|
+
}),
|
|
34
47
|
/*#__PURE__*/ jsx("button", {
|
|
35
48
|
type: "button",
|
|
36
49
|
tabIndex: -1,
|
|
37
50
|
onClick: close,
|
|
38
|
-
className: "shrink-0 cursor-pointer",
|
|
51
|
+
className: "flex shrink-0 cursor-pointer",
|
|
39
52
|
"aria-label": "Close",
|
|
40
53
|
children: /*#__PURE__*/ jsx(Kbd, {
|
|
41
|
-
size: "
|
|
54
|
+
size: "small",
|
|
42
55
|
children: "ESC"
|
|
43
56
|
})
|
|
44
57
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cva } from "class-variance-authority";
|
|
2
2
|
import { cn } from "../../utils/cn.js";
|
|
3
|
-
const segmentedControlVariants = cva('overflow-visible flex bg-bg-primary p-4 gap-0 items-center rounded-12
|
|
3
|
+
const segmentedControlVariants = cva('overflow-visible flex bg-bg-primary p-4 gap-0 items-center rounded-12', {
|
|
4
4
|
variants: {
|
|
5
5
|
fullWidth: {
|
|
6
6
|
true: 'w-full [&_label]:flex-1',
|
|
@@ -3,9 +3,11 @@ import { type TestableProps } from '../../utils/testId';
|
|
|
3
3
|
type SelectNativeProps<T extends CollectionItem> = Omit<SelectRootProps<T>, 'positioning' | 'lazyMount' | 'unmountOnExit'>;
|
|
4
4
|
export interface SelectBaseProps {
|
|
5
5
|
loading?: boolean;
|
|
6
|
+
/** Override default floating positioning (merged with DS defaults). */
|
|
7
|
+
positioning?: SelectRootProps<CollectionItem>['positioning'];
|
|
6
8
|
}
|
|
7
9
|
type SelectProps<T extends CollectionItem> = SelectNativeProps<T> & SelectBaseProps & TestableProps;
|
|
8
|
-
export declare function Select<T extends CollectionItem>({ children, loading, disabled, 'data-testid': testId, ...props }: SelectProps<T>): import("react").JSX.Element;
|
|
10
|
+
export declare function Select<T extends CollectionItem>({ children, loading, disabled, positioning: positioningOverride, 'data-testid': testId, ...props }: SelectProps<T>): import("react").JSX.Element;
|
|
9
11
|
export declare namespace Select {
|
|
10
12
|
var displayName: string;
|
|
11
13
|
}
|
|
@@ -3,14 +3,17 @@ import { useMemo } from "react";
|
|
|
3
3
|
import { Select } from "@ark-ui/react/select";
|
|
4
4
|
import { TestIdProvider } from "../../utils/testId.js";
|
|
5
5
|
import { SelectSharedProvider } from "./SelectSharedContext/index.js";
|
|
6
|
-
const Select_Select = ({ children, loading = false, disabled = false, 'data-testid': testId, ...props })=>{
|
|
6
|
+
const Select_Select = ({ children, loading = false, disabled = false, positioning: positioningOverride, 'data-testid': testId, ...props })=>{
|
|
7
7
|
const positioning = useMemo(()=>({
|
|
8
8
|
offset: {
|
|
9
9
|
mainAxis: 4
|
|
10
10
|
},
|
|
11
11
|
gutter: 4,
|
|
12
|
-
overflowPadding: 4
|
|
13
|
-
|
|
12
|
+
overflowPadding: 4,
|
|
13
|
+
...positioningOverride
|
|
14
|
+
}), [
|
|
15
|
+
positioningOverride
|
|
16
|
+
]);
|
|
14
17
|
return /*#__PURE__*/ jsx(TestIdProvider, {
|
|
15
18
|
value: testId,
|
|
16
19
|
children: /*#__PURE__*/ jsx(SelectSharedProvider, {
|
|
@@ -1,26 +1,13 @@
|
|
|
1
|
-
import { jsx
|
|
2
|
-
import { Search } from "../../icons/index.js";
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
2
|
import { useTestId } from "../../utils/testId.js";
|
|
4
|
-
import {
|
|
5
|
-
import { InputGroup, InputGroupAddon } from "../InputGroup/index.js";
|
|
3
|
+
import { SearchInput } from "../SearchInput/index.js";
|
|
6
4
|
const SelectSearchInput = ({ value, onChange, 'data-testid': testIdProp, ...rest })=>{
|
|
7
5
|
const testId = useTestId('search-input', testIdProp);
|
|
8
|
-
|
|
9
|
-
onChange(event.target.value);
|
|
10
|
-
};
|
|
11
|
-
return /*#__PURE__*/ jsxs(InputGroup, {
|
|
6
|
+
return /*#__PURE__*/ jsx(SearchInput, {
|
|
12
7
|
...rest,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
children: /*#__PURE__*/ jsx(Search, {})
|
|
17
|
-
}),
|
|
18
|
-
/*#__PURE__*/ jsx(Input, {
|
|
19
|
-
placeholder: "Search",
|
|
20
|
-
value: value,
|
|
21
|
-
onChange: handleChange
|
|
22
|
-
})
|
|
23
|
-
]
|
|
8
|
+
value: value,
|
|
9
|
+
onChange: onChange,
|
|
10
|
+
"data-testid": testId
|
|
24
11
|
});
|
|
25
12
|
};
|
|
26
13
|
SelectSearchInput.displayName = 'SelectSearchInput';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
|
+
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
export interface SettingsHeaderProps extends HTMLAttributes<HTMLDivElement>, TestableProps {
|
|
4
|
+
ref?: Ref<HTMLDivElement>;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare const SettingsHeader: FC<SettingsHeaderProps>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../utils/cn.js";
|
|
3
|
+
import { TestIdProvider } from "../../utils/testId.js";
|
|
4
|
+
const SettingsHeader = ({ ref, className, children, 'data-testid': testId, ...props })=>/*#__PURE__*/ jsx(TestIdProvider, {
|
|
5
|
+
value: testId,
|
|
6
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
7
|
+
...props,
|
|
8
|
+
ref: ref,
|
|
9
|
+
"data-testid": testId,
|
|
10
|
+
"data-slot": "settings-header",
|
|
11
|
+
className: cn('flex flex-col gap-6 pb-12 pt-8 px-24', className),
|
|
12
|
+
children: children
|
|
13
|
+
})
|
|
14
|
+
});
|
|
15
|
+
SettingsHeader.displayName = 'SettingsHeader';
|
|
16
|
+
export { SettingsHeader };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
|
+
export interface SettingsHeaderActionsProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
ref?: Ref<HTMLDivElement>;
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare const SettingsHeaderActions: FC<SettingsHeaderActionsProps>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../utils/cn.js";
|
|
3
|
+
import { useTestId } from "../../utils/testId.js";
|
|
4
|
+
const SettingsHeaderActions = ({ ref, children, className, ...props })=>{
|
|
5
|
+
const testId = useTestId('actions');
|
|
6
|
+
return /*#__PURE__*/ jsx("div", {
|
|
7
|
+
...props,
|
|
8
|
+
ref: ref,
|
|
9
|
+
"data-testid": testId,
|
|
10
|
+
"data-slot": "settings-header-actions",
|
|
11
|
+
className: cn('flex items-center gap-8 shrink-0 ml-auto', className),
|
|
12
|
+
children: children
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
SettingsHeaderActions.displayName = 'SettingsHeaderActions';
|
|
16
|
+
export { SettingsHeaderActions };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
|
+
export interface SettingsHeaderBreadcrumbsProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
ref?: Ref<HTMLDivElement>;
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare const SettingsHeaderBreadcrumbs: FC<SettingsHeaderBreadcrumbsProps>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../utils/cn.js";
|
|
3
|
+
import { useTestId } from "../../utils/testId.js";
|
|
4
|
+
const SettingsHeaderBreadcrumbs = ({ ref, children, className, ...props })=>{
|
|
5
|
+
const testId = useTestId('breadcrumbs');
|
|
6
|
+
return /*#__PURE__*/ jsx("div", {
|
|
7
|
+
...props,
|
|
8
|
+
ref: ref,
|
|
9
|
+
"data-testid": testId,
|
|
10
|
+
"data-slot": "settings-header-breadcrumbs",
|
|
11
|
+
className: cn(className),
|
|
12
|
+
children: children
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
SettingsHeaderBreadcrumbs.displayName = 'SettingsHeaderBreadcrumbs';
|
|
16
|
+
export { SettingsHeaderBreadcrumbs };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, Ref } from 'react';
|
|
2
|
+
export interface SettingsHeaderDescriptionProps extends HTMLAttributes<HTMLParagraphElement> {
|
|
3
|
+
ref?: Ref<HTMLParagraphElement>;
|
|
4
|
+
}
|
|
5
|
+
export declare const SettingsHeaderDescription: FC<SettingsHeaderDescriptionProps>;
|