@nexub/react 7.4.0 → 7.6.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 (37) hide show
  1. package/accessibility.json +1 -1
  2. package/dist/components/Badge/Badge.d.ts +9 -0
  3. package/dist/components/Badge/Badge.js +40 -2
  4. package/dist/components/Button/Button.d.ts +1 -1
  5. package/dist/components/Combobox/Combobox.d.ts +6 -9
  6. package/dist/components/Combobox/Combobox.js +30 -9
  7. package/dist/components/CommandPalette/CommandPalette.d.ts +34 -13
  8. package/dist/components/CommandPalette/CommandPalette.js +174 -40
  9. package/dist/components/CommandPalette/index.d.ts +1 -1
  10. package/dist/components/DatePicker/DatePicker.d.ts +16 -1
  11. package/dist/components/DatePicker/DatePicker.js +100 -26
  12. package/dist/components/Dialog/Dialog.d.ts +7 -0
  13. package/dist/components/Dialog/Dialog.js +35 -8
  14. package/dist/components/EmptyState/EmptyState.d.ts +7 -1
  15. package/dist/components/EmptyState/EmptyState.js +21 -5
  16. package/dist/components/EmptyState/EmptyStatePreset.d.ts +2 -1
  17. package/dist/components/FileUpload/FileUpload.js +86 -32
  18. package/dist/components/Heading/Heading.d.ts +1 -1
  19. package/dist/components/IconButton/IconButton.d.ts +5 -1
  20. package/dist/components/IconButton/IconButton.js +14 -3
  21. package/dist/components/Input/Input.d.ts +6 -0
  22. package/dist/components/Input/Input.js +47 -5
  23. package/dist/components/Select/Select.d.ts +18 -3
  24. package/dist/components/Select/Select.js +170 -71
  25. package/dist/components/Slider/Slider.d.ts +10 -0
  26. package/dist/components/Slider/Slider.js +48 -3
  27. package/dist/components/Slider/index.d.ts +1 -1
  28. package/dist/components/Switch/Switch.d.ts +6 -0
  29. package/dist/components/Switch/Switch.js +29 -2
  30. package/dist/components/Tabs/Tabs.d.ts +5 -1
  31. package/dist/components/Tabs/Tabs.js +98 -35
  32. package/dist/components/Text/Text.d.ts +1 -1
  33. package/dist/components/Tooltip/Tooltip.d.ts +10 -3
  34. package/dist/components/Tooltip/Tooltip.js +16 -4
  35. package/dist/index.d.ts +3 -1
  36. package/dist/styles.css +1 -1
  37. package/package.json +6 -6
@@ -9,63 +9,126 @@ const Root = React.forwardRef(
9
9
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(RadixTabs.Root, { ref, className: cn("flex flex-col gap-3 data-[orientation=vertical]:flex-row", className), ...props })
10
10
  );
11
11
  Root.displayName = "Tabs.Root";
12
+ const VariantContext = React.createContext("line");
12
13
  const List = React.forwardRef(
13
- ({ className, children, ...props }, forwardedRef) => {
14
+ ({ className, children, variant = "line", ...props }, forwardedRef) => {
14
15
  const ref = React.useRef(null);
15
16
  useSlidingIndicator(ref, '[data-state="active"]');
16
- return /* @__PURE__ */ jsxs(
17
+ useOverflow(ref);
18
+ const pill = variant === "pill";
19
+ return /* @__PURE__ */ jsx(VariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsxs(
17
20
  RadixTabs.List,
18
21
  {
19
22
  ref: useMergedRefs(ref, forwardedRef),
23
+ "data-variant": variant,
20
24
  className: cn(
21
- "group/tabs relative flex w-full items-stretch justify-start overflow-x-auto",
22
- "border-b border-[var(--color-outline-variant)]",
25
+ // nx-scroll-fade: edge fades while more tabs hide past an edge (@nexub/themes core).
26
+ "nx-scroll-fade group/tabs relative flex w-full items-stretch justify-start overflow-x-auto",
23
27
  // Vertical: a column with the rule on the inline-end side.
24
28
  "data-[orientation=vertical]:w-auto data-[orientation=vertical]:shrink-0 data-[orientation=vertical]:flex-col",
25
29
  "data-[orientation=vertical]:overflow-x-visible data-[orientation=vertical]:overflow-y-auto",
26
- "data-[orientation=vertical]:border-b-0 data-[orientation=vertical]:border-e",
30
+ pill ? "w-fit max-w-full rounded-shape-control bg-[var(--color-surface-container-high)] p-0.5" : "border-b border-[var(--color-outline-variant)] data-[orientation=vertical]:border-b-0 data-[orientation=vertical]:border-e",
27
31
  className
28
32
  ),
29
33
  ...props,
30
34
  children: [
31
35
  children,
32
- /* @__PURE__ */ jsx(
33
- "span",
34
- {
35
- "aria-hidden": "true",
36
- className: cn(
37
- "pointer-events-none absolute bottom-0 left-0 h-[3px] rounded-t-full bg-[var(--color-primary)]",
38
- "w-[var(--nx-ind-w,0px)] translate-x-[var(--nx-ind-x,0px)] opacity-[var(--nx-ind-o,0)]",
39
- "group-data-[orientation=vertical]/tabs:top-0 group-data-[orientation=vertical]/tabs:bottom-auto group-data-[orientation=vertical]/tabs:left-auto group-data-[orientation=vertical]/tabs:end-0",
40
- "group-data-[orientation=vertical]/tabs:h-[var(--nx-ind-h,0px)] group-data-[orientation=vertical]/tabs:w-[3px] group-data-[orientation=vertical]/tabs:rounded-none group-data-[orientation=vertical]/tabs:rounded-s-full",
41
- "group-data-[orientation=vertical]/tabs:translate-x-0 group-data-[orientation=vertical]/tabs:translate-y-[var(--nx-ind-y,0px)]",
42
- "[[data-nx-indicator=ready]>&]:transition-[transform,width,height] [[data-nx-indicator=ready]>&]:duration-spatial-default [[data-nx-indicator=ready]>&]:ease-spatial-default"
43
- )
44
- }
36
+ pill ? (
37
+ /* The thumb (as SegmentedControl): one raised surface behind the active tab, either orientation. */
38
+ /* @__PURE__ */ jsx(
39
+ "span",
40
+ {
41
+ "aria-hidden": "true",
42
+ className: cn(
43
+ "pointer-events-none absolute left-0 top-0 rounded-shape-control",
44
+ "bg-[var(--color-surface-container-lowest)] shadow-elevation-1",
45
+ "h-[var(--nx-ind-h,0px)] w-[var(--nx-ind-w,0px)] translate-x-[var(--nx-ind-x,0px)] translate-y-[var(--nx-ind-y,0px)] opacity-[var(--nx-ind-o,0)]",
46
+ "[[data-nx-indicator=ready]>&]:transition-[transform,width,height] [[data-nx-indicator=ready]>&]:duration-spatial-default [[data-nx-indicator=ready]>&]:ease-spatial-default"
47
+ )
48
+ }
49
+ )
50
+ ) : (
51
+ /* The indicator: a 3px primary bar that slides under (or beside) the active tab. */
52
+ /* @__PURE__ */ jsx(
53
+ "span",
54
+ {
55
+ "aria-hidden": "true",
56
+ className: cn(
57
+ "pointer-events-none absolute bottom-0 left-0 h-[3px] rounded-t-full bg-[var(--color-primary)]",
58
+ "w-[var(--nx-ind-w,0px)] translate-x-[var(--nx-ind-x,0px)] opacity-[var(--nx-ind-o,0)]",
59
+ "group-data-[orientation=vertical]/tabs:top-0 group-data-[orientation=vertical]/tabs:bottom-auto group-data-[orientation=vertical]/tabs:left-auto group-data-[orientation=vertical]/tabs:end-0",
60
+ "group-data-[orientation=vertical]/tabs:h-[var(--nx-ind-h,0px)] group-data-[orientation=vertical]/tabs:w-[3px] group-data-[orientation=vertical]/tabs:rounded-none group-data-[orientation=vertical]/tabs:rounded-s-full",
61
+ "group-data-[orientation=vertical]/tabs:translate-x-0 group-data-[orientation=vertical]/tabs:translate-y-[var(--nx-ind-y,0px)]",
62
+ "[[data-nx-indicator=ready]>&]:transition-[transform,width,height] [[data-nx-indicator=ready]>&]:duration-spatial-default [[data-nx-indicator=ready]>&]:ease-spatial-default"
63
+ )
64
+ }
65
+ )
45
66
  )
46
67
  ]
47
68
  }
48
- );
69
+ ) });
49
70
  }
50
71
  );
51
72
  List.displayName = "Tabs.List";
73
+ function useOverflow(ref) {
74
+ React.useEffect(() => {
75
+ const root = ref.current;
76
+ if (!root) return;
77
+ const sync = () => {
78
+ const v = root.dataset.orientation === "vertical";
79
+ const pos = Math.abs(v ? root.scrollTop : root.scrollLeft);
80
+ const max = v ? root.scrollHeight - root.clientHeight : root.scrollWidth - root.clientWidth;
81
+ const edges = [pos > 1 && "start", pos < max - 1 && "end"].filter(Boolean).join(" ");
82
+ if (edges) root.dataset.nxOverflow = edges;
83
+ else delete root.dataset.nxOverflow;
84
+ };
85
+ const reveal = (records) => {
86
+ const tab = records.map((r2) => r2.target).find((t2) => t2.getAttribute("role") === "tab" && t2.dataset.state === "active");
87
+ if (!tab) return;
88
+ const r = root.getBoundingClientRect();
89
+ const t = tab.getBoundingClientRect();
90
+ const left = t.left < r.left ? t.left - r.left : t.right > r.right ? t.right - r.right : 0;
91
+ const top = t.top < r.top ? t.top - r.top : t.bottom > r.bottom ? t.bottom - r.bottom : 0;
92
+ if (!left && !top) return;
93
+ const reduce = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
94
+ root.scrollBy?.({ left, top, behavior: reduce ? "auto" : "smooth" });
95
+ };
96
+ sync();
97
+ root.addEventListener("scroll", sync, { passive: true });
98
+ const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
99
+ ro?.observe(root);
100
+ const mo = new MutationObserver(reveal);
101
+ mo.observe(root, { subtree: true, attributes: true, attributeFilter: ["data-state"] });
102
+ return () => {
103
+ root.removeEventListener("scroll", sync);
104
+ ro?.disconnect();
105
+ mo.disconnect();
106
+ };
107
+ }, [ref]);
108
+ }
52
109
  const Trigger = React.forwardRef(
53
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
54
- RadixTabs.Trigger,
55
- {
56
- ref,
57
- className: cn(
58
- // State layer for hover/press; focus = the global ring.
59
- "nx-state-layer relative inline-flex h-control-md items-center justify-center whitespace-nowrap rounded-t-[var(--shape-field)] px-4 text-label-lg select-none",
60
- "text-[var(--color-on-surface-variant)] transition-colors duration-effects-fast ease-effects-fast",
61
- "data-[state=active]:text-[var(--color-primary)]",
62
- "group-data-[orientation=vertical]/tabs:justify-start group-data-[orientation=vertical]/tabs:rounded-none group-data-[orientation=vertical]/tabs:rounded-s-[var(--shape-field)]",
63
- "disabled:pointer-events-none disabled:text-[var(--color-text-disabled)]",
64
- className
65
- ),
66
- ...props
67
- }
68
- )
110
+ ({ className, ...props }, ref) => {
111
+ const pill = React.useContext(VariantContext) === "pill";
112
+ return /* @__PURE__ */ jsx(
113
+ RadixTabs.Trigger,
114
+ {
115
+ ref,
116
+ className: cn(
117
+ // State layer for hover/press; focus = the global ring.
118
+ "nx-state-layer relative inline-flex h-control-md items-center justify-center whitespace-nowrap px-4 text-label-lg select-none",
119
+ "group-data-[orientation=vertical]/tabs:justify-start",
120
+ "text-[var(--color-on-surface-variant)] transition-colors duration-effects-fast ease-effects-fast",
121
+ pill ? "z-10 rounded-shape-control hover:text-[var(--color-on-surface)] data-[state=active]:text-[var(--color-on-surface)]" : cn(
122
+ "rounded-t-[var(--shape-field)] data-[state=active]:text-[var(--color-primary)]",
123
+ "group-data-[orientation=vertical]/tabs:rounded-none group-data-[orientation=vertical]/tabs:rounded-s-[var(--shape-field)]"
124
+ ),
125
+ "disabled:pointer-events-none disabled:text-[var(--color-text-disabled)]",
126
+ className
127
+ ),
128
+ ...props
129
+ }
130
+ );
131
+ }
69
132
  );
70
133
  Trigger.displayName = "Tabs.Trigger";
71
134
  const Content = React.forwardRef(
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { type VariantProps } from 'class-variance-authority';
3
3
  export declare const textVariants: (props?: ({
4
4
  size?: "body" | "label" | "caption" | "body-lg" | "body-sm" | null | undefined;
5
- tone?: "default" | "subtle" | "secondary" | "muted" | "inverse" | null | undefined;
5
+ tone?: "default" | "secondary" | "subtle" | "muted" | "inverse" | null | undefined;
6
6
  weight?: "bold" | "regular" | "medium" | "semibold" | null | undefined;
7
7
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
8
  export interface TextProps extends React.HTMLAttributes<HTMLParagraphElement>, VariantProps<typeof textVariants> {
@@ -4,11 +4,18 @@ declare function Provider({ delayDuration, skipDelayDuration, ...props }: RadixT
4
4
  declare const Root: React.FC<RadixTooltip.TooltipProps>;
5
5
  declare const Trigger: React.ForwardRefExoticComponent<RadixTooltip.TooltipTriggerProps & React.RefAttributes<HTMLButtonElement>>;
6
6
  declare const Content: React.ForwardRefExoticComponent<RadixTooltip.TooltipContentProps & React.RefAttributes<HTMLDivElement>>;
7
- interface TooltipProps {
8
- label: string;
7
+ export interface TooltipProps {
8
+ /** The tip, or the title when `description` is set. */
9
+ label: React.ReactNode;
10
+ /** Secondary line under the title (rich tooltip). */
11
+ description?: React.ReactNode;
12
+ /** Keyboard shortcut, shown as a Kbd at the end, e.g. "⌘S". */
13
+ shortcut?: React.ReactNode;
14
+ /** Point at the trigger with a small arrow. */
15
+ arrow?: boolean;
9
16
  side?: 'top' | 'right' | 'bottom' | 'left';
10
17
  delayDuration?: number;
11
18
  children: React.ReactElement;
12
19
  }
13
- declare function Tooltip({ label, side, delayDuration, children }: TooltipProps): React.JSX.Element;
20
+ declare function Tooltip({ label, description, shortcut, arrow, side, delayDuration, children }: TooltipProps): React.JSX.Element;
14
21
  export { Provider, Root, Trigger, Content, Tooltip };
@@ -3,8 +3,10 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import * as RadixTooltip from "@radix-ui/react-tooltip";
5
5
  import { cn } from "../../utils/cn.js";
6
+ import { Kbd } from "../Kbd/Kbd.js";
7
+ const InProvider = React.createContext(false);
6
8
  function Provider({ delayDuration = 400, skipDelayDuration = 300, ...props }) {
7
- return /* @__PURE__ */ jsx(RadixTooltip.Provider, { delayDuration, skipDelayDuration, ...props });
9
+ return /* @__PURE__ */ jsx(InProvider.Provider, { value: true, children: /* @__PURE__ */ jsx(RadixTooltip.Provider, { delayDuration, skipDelayDuration, ...props }) });
8
10
  }
9
11
  const Root = RadixTooltip.Root;
10
12
  const Trigger = RadixTooltip.Trigger;
@@ -26,11 +28,21 @@ const Content = React.forwardRef(
26
28
  }
27
29
  );
28
30
  Content.displayName = "Tooltip.Content";
29
- function Tooltip({ label, side = "top", delayDuration = 400, children }) {
30
- return /* @__PURE__ */ jsxs(Root, { delayDuration, children: [
31
+ function Tooltip({ label, description, shortcut, arrow, side = "top", delayDuration = 400, children }) {
32
+ const tip = /* @__PURE__ */ jsxs(Root, { delayDuration, children: [
31
33
  /* @__PURE__ */ jsx(Trigger, { asChild: true, children }),
32
- /* @__PURE__ */ jsx(RadixTooltip.Portal, { children: /* @__PURE__ */ jsx(Content, { side, children: label }) })
34
+ /* @__PURE__ */ jsx(RadixTooltip.Portal, { children: /* @__PURE__ */ jsxs(Content, { side, className: cn(description != null && "max-w-xs"), children: [
35
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-3", children: [
36
+ description == null ? label : /* @__PURE__ */ jsxs("span", { className: "flex flex-col gap-0.5", children: [
37
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: label }),
38
+ /* @__PURE__ */ jsx("span", { className: "text-body-sm", children: description })
39
+ ] }),
40
+ shortcut != null && /* @__PURE__ */ jsx(Kbd, { className: "ms-auto border-current bg-transparent text-inherit shadow-none", children: shortcut })
41
+ ] }),
42
+ arrow && /* @__PURE__ */ jsx(RadixTooltip.Arrow, { className: "fill-[var(--color-inverse-surface)]" })
43
+ ] }) })
33
44
  ] });
45
+ return React.useContext(InProvider) ? tip : /* @__PURE__ */ jsx(Provider, { children: tip });
34
46
  }
35
47
  export {
36
48
  Content,
package/dist/index.d.ts CHANGED
@@ -180,7 +180,7 @@ export { Checkbox } from './components/Checkbox/index.js';
180
180
  export type { CheckboxProps } from './components/Checkbox/index.js';
181
181
  export { RadioGroup } from './components/RadioGroup/index.js';
182
182
  export { Slider } from './components/Slider/index.js';
183
- export type { SliderProps } from './components/Slider/index.js';
183
+ export type { SliderProps, SliderMark } from './components/Slider/index.js';
184
184
  export { Toggle, toggleVariants } from './components/Toggle/index.js';
185
185
  export type { ToggleProps } from './components/Toggle/index.js';
186
186
  export { ToggleGroup } from './components/ToggleGroup/index.js';
@@ -259,3 +259,5 @@ export type { FadeProps, SlideProps, SlideDirection, ScaleProps, CollapseProps,
259
259
  export type { DataTableColumn } from './components/DataTable/index.js';
260
260
  export type { TableRootProps } from './components/Table/index.js';
261
261
  export type { PromiseToastOptions } from './components/Toast/index.js';
262
+ export type { CommandPaletteItemProps, CommandPalettePageProps } from './components/CommandPalette/index.js';
263
+ export type { EmptyStateRootProps } from './components/EmptyState/EmptyState.js';