@kjaniec-dev/ui 0.7.0 → 0.7.2

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/index.cjs CHANGED
@@ -587,7 +587,10 @@ var TabsList = React18__namespace.forwardRef(
587
587
  ref,
588
588
  role: "tablist",
589
589
  onKeyDown: handleKeyDown,
590
- className: cn("flex gap-1 border-b border-border", className),
590
+ className: cn(
591
+ "flex gap-1 border-b border-border overflow-x-auto whitespace-nowrap [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
592
+ className
593
+ ),
591
594
  ...props
592
595
  }
593
596
  );
@@ -610,7 +613,7 @@ var TabsTrigger = React18__namespace.forwardRef(
610
613
  tabIndex: active ? 0 : -1,
611
614
  onClick: () => setValue(value),
612
615
  className: cn(
613
- "relative px-[0.9rem] py-2.5 text-sm font-semibold cursor-pointer transition-colors duration-150 outline-none",
616
+ "relative px-[0.9rem] py-2.5 text-sm font-semibold cursor-pointer transition-colors duration-150 outline-none shrink-0 whitespace-nowrap",
614
617
  "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:rounded-sm",
615
618
  "after:content-[''] after:absolute after:left-[0.9rem] after:right-[0.9rem] after:-bottom-px after:h-0.5 after:rounded-sm after:transition-colors",
616
619
  active ? "text-foreground after:bg-primary" : "text-muted-foreground hover:text-foreground after:bg-transparent",
@@ -1363,23 +1366,39 @@ function DataTable({
1363
1366
  }[col.align || "left"];
1364
1367
  const isSortable = col.sortable && onSort && col.sortKey;
1365
1368
  const isSortedActive = sortBy && col.sortKey === sortBy;
1369
+ const ariaSort = isSortable ? isSortedActive ? sortDirection === "asc" ? "ascending" : "descending" : "none" : void 0;
1366
1370
  return /* @__PURE__ */ jsxRuntime.jsx(
1367
1371
  TableHead,
1368
1372
  {
1369
1373
  className: cn(
1370
1374
  alignClass,
1371
- isSortable && "cursor-pointer select-none hover:bg-muted/30 transition-colors",
1375
+ isSortable && "p-0 hover:bg-muted/30 transition-colors",
1372
1376
  col.className
1373
1377
  ),
1374
- onClick: () => {
1375
- if (!isSortable || !col.sortKey) return;
1376
- const nextDirection = isSortedActive && sortDirection === "asc" ? "desc" : "asc";
1377
- onSort(col.sortKey, nextDirection);
1378
- },
1379
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("inline-flex items-center gap-1.5", alignClass === "text-right" && "justify-end w-full"), children: [
1380
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: col.header }),
1381
- isSortable && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground shrink-0 select-none", children: isSortedActive ? sortDirection === "asc" ? "\u25B2" : "\u25BC" : "\u21C5" })
1382
- ] })
1378
+ "aria-sort": ariaSort,
1379
+ children: isSortable ? /* @__PURE__ */ jsxRuntime.jsxs(
1380
+ "button",
1381
+ {
1382
+ type: "button",
1383
+ onClick: () => {
1384
+ if (!col.sortKey) return;
1385
+ const nextDirection = isSortedActive && sortDirection === "asc" ? "desc" : "asc";
1386
+ onSort(col.sortKey, nextDirection);
1387
+ },
1388
+ className: cn(
1389
+ "w-full px-4 py-3 flex items-center gap-1.5 font-semibold text-[0.72rem] uppercase tracking-[0.05em] text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 transition-colors cursor-pointer",
1390
+ {
1391
+ "justify-start text-left": col.align === "left" || !col.align,
1392
+ "justify-center text-center": col.align === "center",
1393
+ "justify-end text-right": col.align === "right"
1394
+ }
1395
+ ),
1396
+ children: [
1397
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: col.header }),
1398
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground shrink-0 select-none", children: isSortedActive ? sortDirection === "asc" ? "\u25B2" : "\u25BC" : "\u21C5" })
1399
+ ]
1400
+ }
1401
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("inline-flex items-center gap-1.5", alignClass === "text-right" && "justify-end w-full"), children: col.header })
1383
1402
  },
1384
1403
  idx
1385
1404
  );
@@ -1892,7 +1911,7 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1892
1911
  }, [open, filteredItems, activeIndex, onClose]);
1893
1912
  React18__namespace.useEffect(() => {
1894
1913
  if (listRef.current) {
1895
- const activeEl = listRef.current.children[activeIndex];
1914
+ const activeEl = listRef.current.querySelector('[aria-selected="true"]');
1896
1915
  if (activeEl) {
1897
1916
  activeEl.scrollIntoView({ block: "nearest" });
1898
1917
  }
@@ -1915,6 +1934,9 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1915
1934
  "div",
1916
1935
  {
1917
1936
  ref: containerRef,
1937
+ role: "dialog",
1938
+ "aria-modal": "true",
1939
+ "aria-label": "Command palette",
1918
1940
  className: "w-[95vw] max-w-lg bg-surface border border-border rounded-kj-xl shadow-kj-lg flex flex-col overflow-hidden max-h-[500px]",
1919
1941
  children: [
1920
1942
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 border-b border-border flex items-center gap-2", children: [
@@ -1923,6 +1945,11 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1923
1945
  "input",
1924
1946
  {
1925
1947
  type: "text",
1948
+ role: "combobox",
1949
+ "aria-expanded": open,
1950
+ "aria-autocomplete": "list",
1951
+ "aria-controls": "command-palette-listbox",
1952
+ "aria-activedescendant": filteredItems.length > 0 ? `cmd-item-${activeIndex}` : void 0,
1926
1953
  placeholder,
1927
1954
  value: search,
1928
1955
  onChange: (e) => setSearch(e.target.value),
@@ -1935,44 +1962,64 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1935
1962
  'No results found for "',
1936
1963
  search,
1937
1964
  '"'
1938
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { ref: listRef, className: "space-y-4", children: Object.entries(groups).map(([cat, itemsInCat]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
1939
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1 text-[0.65rem] font-bold uppercase tracking-wider text-muted-foreground", children: cat }),
1940
- itemsInCat.map((item) => {
1941
- const currentIdx = absoluteItemIndex++;
1942
- const isActive = currentIdx === activeIndex;
1943
- return /* @__PURE__ */ jsxRuntime.jsxs(
1944
- "div",
1945
- {
1946
- onClick: () => {
1947
- item.action();
1948
- onClose();
1949
- },
1950
- className: cn(
1951
- "flex items-center justify-between gap-3 px-3 py-2.5 rounded-kj-md cursor-pointer select-none transition-colors",
1952
- isActive ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
1953
- ),
1954
- children: [
1955
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
1956
- item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground [&_svg]:h-[1.1rem] [&_svg]:w-[1.1rem]", children: item.icon }),
1957
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex flex-col", children: [
1958
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[0.85rem] font-semibold", isActive ? "text-primary" : "text-foreground"), children: item.title }),
1959
- item.subtitle && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.75rem] text-muted-foreground truncate", children: item.subtitle })
1960
- ] })
1961
- ] }),
1962
- item.shortcut && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: item.shortcut.map((sc, scIdx) => /* @__PURE__ */ jsxRuntime.jsx(
1963
- "kbd",
1964
- {
1965
- className: "px-1.5 py-0.5 rounded border border-border bg-subtle text-[10px] font-mono leading-none shadow-kj-xs text-muted-foreground",
1966
- children: sc
1965
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
1966
+ "div",
1967
+ {
1968
+ ref: listRef,
1969
+ id: "command-palette-listbox",
1970
+ role: "listbox",
1971
+ "aria-label": "Commands",
1972
+ className: "space-y-4",
1973
+ children: Object.entries(groups).map(([cat, itemsInCat]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-labelledby": `cmd-cat-${cat}`, className: "space-y-1", children: [
1974
+ /* @__PURE__ */ jsxRuntime.jsx(
1975
+ "div",
1976
+ {
1977
+ id: `cmd-cat-${cat}`,
1978
+ className: "px-3 py-1 text-[0.65rem] font-bold uppercase tracking-wider text-muted-foreground",
1979
+ children: cat
1980
+ }
1981
+ ),
1982
+ itemsInCat.map((item) => {
1983
+ const currentIdx = absoluteItemIndex++;
1984
+ const isActive = currentIdx === activeIndex;
1985
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1986
+ "div",
1987
+ {
1988
+ id: `cmd-item-${currentIdx}`,
1989
+ role: "option",
1990
+ "aria-selected": isActive,
1991
+ onClick: () => {
1992
+ item.action();
1993
+ onClose();
1967
1994
  },
1968
- scIdx
1969
- )) })
1970
- ]
1971
- },
1972
- item.id
1973
- );
1974
- })
1975
- ] }, cat)) }) }),
1995
+ className: cn(
1996
+ "flex items-center justify-between gap-3 px-3 py-2.5 rounded-kj-md cursor-pointer select-none transition-colors",
1997
+ isActive ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
1998
+ ),
1999
+ children: [
2000
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
2001
+ item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground [&_svg]:h-[1.1rem] [&_svg]:w-[1.1rem]", children: item.icon }),
2002
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex flex-col", children: [
2003
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[0.85rem] font-semibold", isActive ? "text-primary" : "text-foreground"), children: item.title }),
2004
+ item.subtitle && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.75rem] text-muted-foreground truncate", children: item.subtitle })
2005
+ ] })
2006
+ ] }),
2007
+ item.shortcut && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: item.shortcut.map((sc, scIdx) => /* @__PURE__ */ jsxRuntime.jsx(
2008
+ "kbd",
2009
+ {
2010
+ className: "px-1.5 py-0.5 rounded border border-border bg-subtle text-[10px] font-mono leading-none shadow-kj-xs text-muted-foreground",
2011
+ children: sc
2012
+ },
2013
+ scIdx
2014
+ )) })
2015
+ ]
2016
+ },
2017
+ item.id
2018
+ );
2019
+ })
2020
+ ] }, cat))
2021
+ }
2022
+ ) }),
1976
2023
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-2.5 border-t border-border bg-subtle flex items-center justify-between text-[11px] text-muted-foreground font-medium", children: [
1977
2024
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
1978
2025
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [