@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.
Files changed (77) hide show
  1. package/dist/components/AppShell/story-content/_storySearchModal.js +3 -3
  2. package/dist/components/CodeSnippet/CodeSnippetCopyButton.d.ts +1 -1
  3. package/dist/components/CodeSnippet/CodeSnippetCopyButton.js +14 -7
  4. package/dist/components/CodeSnippet/InlineCodeSnippet.js +7 -25
  5. package/dist/components/Copyable/Copyable.d.ts +39 -0
  6. package/dist/components/Copyable/Copyable.js +85 -0
  7. package/dist/components/Copyable/CopyableContext.d.ts +11 -0
  8. package/dist/components/Copyable/CopyableContext.js +9 -0
  9. package/dist/components/Copyable/CopyableIcon.d.ts +9 -0
  10. package/dist/components/Copyable/CopyableIcon.js +13 -0
  11. package/dist/components/Copyable/CopyableLabel.d.ts +18 -0
  12. package/dist/components/Copyable/CopyableLabel.js +24 -0
  13. package/dist/components/Copyable/index.d.ts +4 -0
  14. package/dist/components/Copyable/index.js +4 -0
  15. package/dist/components/SearchInput/SearchInput.d.ts +18 -0
  16. package/dist/components/SearchInput/SearchInput.js +54 -0
  17. package/dist/components/SearchInput/index.d.ts +1 -0
  18. package/dist/components/SearchInput/index.js +1 -0
  19. package/dist/components/SearchModal/SearchModalInput.js +16 -3
  20. package/dist/components/SegmentedControl/classes.js +1 -1
  21. package/dist/components/Select/Select.d.ts +3 -1
  22. package/dist/components/Select/Select.js +6 -3
  23. package/dist/components/Select/SelectSearchInput.js +6 -19
  24. package/dist/components/SettingsHeader/SettingsHeader.d.ts +7 -0
  25. package/dist/components/SettingsHeader/SettingsHeader.js +16 -0
  26. package/dist/components/SettingsHeader/SettingsHeaderActions.d.ts +6 -0
  27. package/dist/components/SettingsHeader/SettingsHeaderActions.js +16 -0
  28. package/dist/components/SettingsHeader/SettingsHeaderBreadcrumbs.d.ts +6 -0
  29. package/dist/components/SettingsHeader/SettingsHeaderBreadcrumbs.js +16 -0
  30. package/dist/components/SettingsHeader/SettingsHeaderDescription.d.ts +5 -0
  31. package/dist/components/SettingsHeader/SettingsHeaderDescription.js +16 -0
  32. package/dist/components/SettingsHeader/SettingsHeaderFilters.d.ts +6 -0
  33. package/dist/components/SettingsHeader/SettingsHeaderFilters.js +16 -0
  34. package/dist/components/SettingsHeader/SettingsHeaderHeading.d.ts +6 -0
  35. package/dist/components/SettingsHeader/SettingsHeaderHeading.js +16 -0
  36. package/dist/components/SettingsHeader/SettingsHeaderTitle.d.ts +5 -0
  37. package/dist/components/SettingsHeader/SettingsHeaderTitle.js +16 -0
  38. package/dist/components/SettingsHeader/index.d.ts +7 -0
  39. package/dist/components/SettingsHeader/index.js +7 -0
  40. package/dist/components/Table/EditableCell/EditableSelectCell.d.ts +1 -1
  41. package/dist/components/Table/EditableCell/EditableSelectCell.js +12 -1
  42. package/dist/components/Table/StickyGroupParent.js +7 -8
  43. package/dist/components/Table/TableBody/TableBodyCell.d.ts +3 -1
  44. package/dist/components/Table/TableBody/TableBodyCell.js +6 -2
  45. package/dist/components/Table/TableBody/TableBodyRowDndContext.d.ts +5 -0
  46. package/dist/components/Table/TableBody/TableBodyRowDndContext.js +65 -21
  47. package/dist/components/Table/TableBody/TableRowOverlay.js +2 -1
  48. package/dist/components/Table/TableColGroup.js +20 -17
  49. package/dist/components/Table/TableContext/TableProvider.js +3 -1
  50. package/dist/components/Table/TableContext/types.d.ts +1 -0
  51. package/dist/components/Table/TableHead.js +13 -8
  52. package/dist/components/Table/TableLoadingState.js +19 -13
  53. package/dist/components/Table/TableMasterCellActions.js +2 -5
  54. package/dist/components/Table/TableRow.js +42 -12
  55. package/dist/components/Table/TableRowExpanded.js +3 -2
  56. package/dist/components/Table/classes.d.ts +5 -0
  57. package/dist/components/Table/classes.js +2 -1
  58. package/dist/components/Table/hooks/useStickyGroupParent.js +3 -1
  59. package/dist/components/Table/lib/constants.d.ts +1 -1
  60. package/dist/components/Table/lib/constants.js +1 -1
  61. package/dist/components/Table/lib/createDragHandleColumn.js +3 -3
  62. package/dist/components/Table/lib/useRowDnd.js +3 -13
  63. package/dist/components/Table/types.d.ts +8 -0
  64. package/dist/hooks/index.d.ts +0 -1
  65. package/dist/hooks/index.js +0 -1
  66. package/dist/hooks/useCopyToClipboard.d.ts +9 -10
  67. package/dist/hooks/useCopyToClipboard.js +6 -18
  68. package/dist/index.d.ts +3 -1
  69. package/dist/index.js +3 -1
  70. package/dist/metadata/components.json +12502 -9142
  71. package/package.json +1 -1
  72. package/dist/components/CopyButton/CopyButton.d.ts +0 -16
  73. package/dist/components/CopyButton/CopyButton.js +0 -63
  74. package/dist/components/CopyButton/index.d.ts +0 -1
  75. package/dist/components/CopyButton/index.js +0 -1
  76. package/dist/hooks/useCopyTooltip.d.ts +0 -12
  77. 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, LoaderCircle, Plus } from "../../../icons/index.js";
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(LoaderCircle, {
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(LoaderCircle, {
233
+ /*#__PURE__*/ jsx(CircleDashed, {
234
234
  className: "text-text-primary shrink-0 !icon-md"
235
235
  }),
236
236
  /*#__PURE__*/ jsx(Text, {
@@ -1,5 +1,5 @@
1
1
  import type { FC, Ref } from 'react';
2
- import type { ButtonProps } from '../Button';
2
+ import { type ButtonProps } from '../Button';
3
3
  export type CodeSnippetCopyButtonProps = Omit<ButtonProps, 'children'> & {
4
4
  ref?: Ref<HTMLButtonElement>;
5
5
  };
@@ -1,17 +1,24 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useTestId } from "../../utils/testId.js";
3
- import { CopyButton } from "../CopyButton/index.js";
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(CopyButton, {
9
- ref: ref,
9
+ return /*#__PURE__*/ jsx(Copyable, {
10
10
  text: code,
11
- size: "small",
12
- "aria-label": "Copy code",
13
- "data-testid": testId,
14
- ...props
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, jsxs } from "react/jsx-runtime";
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 { Tooltip, TooltipContent, TooltipTrigger } from "../Tooltip/index.js";
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: handleClick
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__*/ jsxs(Tooltip, {
52
- open: tooltipOpen,
53
- onOpenChange: onTooltipOpenChange,
54
- closeOnPointerDown: false,
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,4 @@
1
+ export { Copyable, type CopyableProps } from './Copyable';
2
+ export { useCopyable } from './CopyableContext';
3
+ export { CopyableIcon, type CopyableIconProps } from './CopyableIcon';
4
+ export { CopyableLabel, type CopyableLabelProps } from './CopyableLabel';
@@ -0,0 +1,4 @@
1
+ export { Copyable } from "./Copyable.js";
2
+ export { useCopyable } from "./CopyableContext.js";
3
+ export { CopyableIcon } from "./CopyableIcon.js";
4
+ export { CopyableLabel } from "./CopyableLabel.js";
@@ -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: "xsmall",
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 mb-8', {
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, jsxs } from "react/jsx-runtime";
2
- import { Search } from "../../icons/index.js";
1
+ import { jsx } from "react/jsx-runtime";
3
2
  import { useTestId } from "../../utils/testId.js";
4
- import { Input } from "../Input/index.js";
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
- const handleChange = (event)=>{
9
- onChange(event.target.value);
10
- };
11
- return /*#__PURE__*/ jsxs(InputGroup, {
6
+ return /*#__PURE__*/ jsx(SearchInput, {
12
7
  ...rest,
13
- "data-testid": testId,
14
- children: [
15
- /*#__PURE__*/ jsx(InputGroupAddon, {
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>;