@arcfusionz/arc-primitive-ui 0.3.2 → 0.3.4

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.
@@ -55,6 +55,13 @@ interface ComboboxInputGroupProps extends Omit<ComponentPropsWithoutRef<typeof C
55
55
  clearLabel?: string;
56
56
  /** Accessible name for the folded chevron button — override with localized copy. */
57
57
  triggerLabel?: string;
58
+ /**
59
+ * Leading static badge before the input. Pass the existing `<Badge>`
60
+ * component to use its variants, appearances, sizes, icons, dots, and
61
+ * custom classes. Keep it non-interactive so clicking the adornment can
62
+ * continue to focus the input.
63
+ */
64
+ badge?: ReactNode;
58
65
  className?: string;
59
66
  }
60
67
  /**
@@ -107,6 +114,13 @@ interface ComboboxTriggerProps extends Omit<BaseTriggerProps, "className"> {
107
114
  * convenience prop.
108
115
  */
109
116
  anchorWidth?: CSSProperties["width"];
117
+ /**
118
+ * Leading static badge before the selected value. Pass the existing
119
+ * `<Badge>` component to use its variants, appearances, sizes, icons, dots,
120
+ * and custom classes. Keep it non-interactive: links and delete buttons
121
+ * cannot be nested inside the trigger button.
122
+ */
123
+ badge?: ReactNode;
110
124
  /** Replaces the up-down carets. Decorative — hidden from assistive technology. */
111
125
  icon?: ReactNode;
112
126
  className?: string;
@@ -112,13 +112,17 @@ function comboboxInputGroupVariants({ size = "md", className } = {}) {
112
112
  * this frame. Give the input an accessible name: a native `<label htmlFor>`,
113
113
  * a composed `FieldLabel`, or `aria-label` on `ComboboxInput`.
114
114
  */
115
- const ComboboxInputGroup = forwardRef(({ size = "md", showTrigger = true, showClear = false, clearLabel = "Clear selection", triggerLabel = "Show options", className, children, ...rest }, ref) => /* @__PURE__ */ jsx(ComboboxInputGroupContext.Provider, {
115
+ const ComboboxInputGroup = forwardRef(({ size = "md", showTrigger = true, showClear = false, clearLabel = "Clear selection", triggerLabel = "Show options", badge, className, children, ...rest }, ref) => /* @__PURE__ */ jsx(ComboboxInputGroupContext.Provider, {
116
116
  value: size,
117
117
  children: /* @__PURE__ */ jsxs(Combobox.InputGroup, {
118
118
  ref,
119
119
  className: cn(comboboxInputGroupVariants({ size }), className),
120
120
  ...rest,
121
121
  children: [
122
+ badge != null && /* @__PURE__ */ jsx("span", {
123
+ className: "flex shrink-0",
124
+ children: badge
125
+ }),
122
126
  children,
123
127
  showClear && /* @__PURE__ */ jsx(ComboboxClear, {
124
128
  "aria-label": clearLabel,
@@ -186,7 +190,7 @@ function mergeAnchorWidth(anchorWidth, style) {
186
190
  * `ComboboxLabel` (or a composed `FieldLabel`); without one, pass
187
191
  * `aria-label`.
188
192
  */
189
- const ComboboxTrigger = forwardRef(({ variant = "outline", size = "md", fullWidth = false, anchorWidth, icon, style, className, children, ...rest }, ref) => /* @__PURE__ */ jsxs(Combobox.Trigger, {
193
+ const ComboboxTrigger = forwardRef(({ variant = "outline", size = "md", fullWidth = false, anchorWidth, badge, icon, style, className, children, ...rest }, ref) => /* @__PURE__ */ jsxs(Combobox.Trigger, {
190
194
  ref,
191
195
  className: cn("group/combobox-trigger", selectTriggerVariants({
192
196
  variant,
@@ -195,7 +199,16 @@ const ComboboxTrigger = forwardRef(({ variant = "outline", size = "md", fullWidt
195
199
  }), className),
196
200
  style: mergeAnchorWidth(anchorWidth, style),
197
201
  ...rest,
198
- children: [/* @__PURE__ */ jsx("span", {
202
+ children: [badge != null ? /* @__PURE__ */ jsxs("span", {
203
+ className: "flex min-w-0 flex-1 items-center gap-2",
204
+ children: [/* @__PURE__ */ jsx("span", {
205
+ className: "flex shrink-0",
206
+ children: badge
207
+ }), /* @__PURE__ */ jsx("span", {
208
+ className: "min-w-0 truncate text-primary group-data-placeholder/combobox-trigger:text-muted-foreground",
209
+ children
210
+ })]
211
+ }) : /* @__PURE__ */ jsx("span", {
199
212
  className: "min-w-0 truncate text-primary group-data-placeholder/combobox-trigger:text-muted-foreground",
200
213
  children
201
214
  }), /* @__PURE__ */ jsx(Combobox.Icon, {
@@ -51,6 +51,13 @@ interface SelectTriggerProps extends Omit<BaseTriggerProps, "className"> {
51
51
  * A consumer `style.width` can override this convenience prop.
52
52
  */
53
53
  anchorWidth?: CSSProperties["width"];
54
+ /**
55
+ * Leading static badge before the selected value. Pass the existing
56
+ * `<Badge>` component to use its variants, appearances, sizes, icons, dots,
57
+ * and custom classes. Keep it non-interactive: links and delete buttons
58
+ * cannot be nested inside the trigger button.
59
+ */
60
+ badge?: ReactNode;
54
61
  /** Replaces the dropdown chevron. Decorative — hidden from assistive technology. */
55
62
  icon?: ReactNode;
56
63
  className?: string;
@@ -99,7 +99,7 @@ function mergeAnchorWidth(anchorWidth, style) {
99
99
  * `SelectLabel` (or a composed `Field.Label`); without one, pass
100
100
  * `aria-label`.
101
101
  */
102
- const SelectTrigger = forwardRef(({ variant = "outline", size = "md", fullWidth = false, anchorWidth, icon, style, className, children, ...rest }, ref) => /* @__PURE__ */ jsxs(Select.Trigger, {
102
+ const SelectTrigger = forwardRef(({ variant = "outline", size = "md", fullWidth = false, anchorWidth, badge, icon, style, className, children, ...rest }, ref) => /* @__PURE__ */ jsxs(Select.Trigger, {
103
103
  ref,
104
104
  className: cn(selectTriggerVariants({
105
105
  variant,
@@ -108,7 +108,13 @@ const SelectTrigger = forwardRef(({ variant = "outline", size = "md", fullWidth
108
108
  }), className),
109
109
  style: mergeAnchorWidth(anchorWidth, style),
110
110
  ...rest,
111
- children: [children, /* @__PURE__ */ jsx(Select.Icon, {
111
+ children: [badge != null ? /* @__PURE__ */ jsxs("span", {
112
+ className: "flex min-w-0 flex-1 items-center gap-2",
113
+ children: [/* @__PURE__ */ jsx("span", {
114
+ className: "flex shrink-0",
115
+ children: badge
116
+ }), children]
117
+ }) : children, /* @__PURE__ */ jsx(Select.Icon, {
112
118
  "aria-hidden": "true",
113
119
  className: "flex text-muted-foreground",
114
120
  children: icon ?? /* @__PURE__ */ jsx(ChevronDownIcon, {})
@@ -16,6 +16,8 @@ interface TableRenderState extends Record<string, unknown> {
16
16
  hoverable: boolean;
17
17
  /** Whether column headers stay pinned inside a scrolling container. */
18
18
  stickyHeader: boolean;
19
+ /** Whether the first column stays pinned while the container scrolls horizontally. */
20
+ stickyFirstColumn: boolean;
19
21
  /** Whether adjacent cells are visually separated. */
20
22
  showColumnBorders: boolean;
21
23
  }
@@ -51,6 +53,8 @@ interface TableProps extends Omit<ComponentPropsWithoutRef<"table">, "className"
51
53
  hoverable?: boolean;
52
54
  /** Pin column headers to the top of the nearest scrolling `TableContainer`; give the container a max height for vertical scrolling. */
53
55
  stickyHeader?: boolean;
56
+ /** Pin the first column to the left edge of the nearest scrolling `TableContainer` so each row keeps its identifying cell in view. Only visible once the table is wider than the container — give the table a minimum width or enough columns to overflow. Put the row's label in the first column; a checkbox or drag handle should not be what stays pinned. */
57
+ stickyFirstColumn?: boolean;
54
58
  /** Draw semantic-border separators between adjacent columns. */
55
59
  showColumnBorders?: boolean;
56
60
  /** Replace the rendered `table` or inspect the visual state in a render callback. Preserve native table semantics. */
@@ -21,10 +21,11 @@ const tableLayoutClasses = {
21
21
  const tableHeaderClasses = "bg-surface [&_tr]:border-b [&_tr]:border-border [&_th]:border-b [&_th]:border-border";
22
22
  const tableBodyClasses = "[&_tr:last-child]:border-b-0";
23
23
  const tableFooterClasses = "border-t border-border bg-surface font-sans font-semibold text-foreground [&>tr]:border-b-0";
24
- const tableRowClasses = "border-b border-border transition-colors duration-150 data-selected:bg-secondary data-selected:hover:bg-secondary";
25
- const tableHeadClasses = "whitespace-nowrap text-left align-middle font-sans text-xs font-semibold uppercase tracking-widest text-muted-foreground";
24
+ const tableRowClasses = "border-b border-border transition-colors duration-150 data-selected:bg-primary-50 data-selected:hover:bg-primary-100";
25
+ const tableHeadClasses = "whitespace-nowrap text-left align-middle font-sans text-xs font-semibold capitalize text-muted-foreground";
26
26
  const tableCellClasses = "align-middle font-sans text-sm text-foreground";
27
27
  const tableCaptionClasses = "px-4 py-3 text-left font-sans text-xs text-muted-foreground";
28
+ const stickyFirstColumnClasses = "[&_thead_tr]:bg-surface [&_tfoot_tr]:bg-surface [&_tbody_tr]:bg-background [&_tr>*:first-child]:sticky [&_tr>*:first-child]:left-0 [&_tr>*:first-child]:bg-inherit [&_tr>*:first-child]:shadow-[inset_-1px_0_0_var(--color-border)] [&_tbody_tr>*:first-child]:z-10 [&_tfoot_tr>*:first-child]:z-10 [&_thead_tr>*:first-child]:z-20";
28
29
  const captionSideClasses = {
29
30
  top: "caption-top border-b border-border",
30
31
  bottom: "caption-bottom border-t border-border"
@@ -42,7 +43,7 @@ const TableContainer = forwardRef(({ variant = "elevated", render, className, ..
42
43
  });
43
44
  });
44
45
  TableContainer.displayName = "TableContainer";
45
- const Table = forwardRef(({ size = "md", layout = "auto", striped = false, hoverable = true, stickyHeader = false, showColumnBorders = false, render, className, ...rest }, ref) => {
46
+ const Table = forwardRef(({ size = "md", layout = "auto", striped = false, hoverable = true, stickyHeader = false, stickyFirstColumn = false, showColumnBorders = false, render, className, ...rest }, ref) => {
46
47
  return useRender({
47
48
  defaultTagName: "table",
48
49
  render,
@@ -53,11 +54,12 @@ const Table = forwardRef(({ size = "md", layout = "auto", striped = false, hover
53
54
  striped,
54
55
  hoverable,
55
56
  stickyHeader,
57
+ stickyFirstColumn,
56
58
  showColumnBorders
57
59
  },
58
60
  props: {
59
61
  ...rest,
60
- className: cn(tableClasses, tableSizeClasses[size], tableLayoutClasses[layout], striped && "[&_tbody_tr:nth-child(even)]:bg-surface", hoverable && "[&_tbody_tr]:hover:bg-muted", stickyHeader && "[&_thead_th]:sticky [&_thead_th]:top-0 [&_thead_th]:z-10 [&_thead_th]:bg-surface", showColumnBorders && "[&_tr>*+*]:border-l [&_tr>*+*]:border-border", className)
62
+ className: cn(tableClasses, tableSizeClasses[size], tableLayoutClasses[layout], striped && "[&_tbody_tr:nth-child(even)]:bg-surface", hoverable && "[&_tbody_tr]:hover:bg-slate-50", stickyHeader && "[&_thead_th]:sticky [&_thead_th]:top-0 [&_thead_th]:z-10 [&_thead_th]:bg-surface", stickyFirstColumn && stickyFirstColumnClasses, showColumnBorders && "[&_tr>*+*]:border-l [&_tr>*+*]:border-border", className)
61
63
  }
62
64
  });
63
65
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcfusionz/arc-primitive-ui",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "ArcFusion primitive UI components",
5
5
  "license": "MIT",
6
6
  "type": "module",