@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.js CHANGED
@@ -565,7 +565,10 @@ var TabsList = React18.forwardRef(
565
565
  ref,
566
566
  role: "tablist",
567
567
  onKeyDown: handleKeyDown,
568
- className: cn("flex gap-1 border-b border-border", className),
568
+ className: cn(
569
+ "flex gap-1 border-b border-border overflow-x-auto whitespace-nowrap [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
570
+ className
571
+ ),
569
572
  ...props
570
573
  }
571
574
  );
@@ -588,7 +591,7 @@ var TabsTrigger = React18.forwardRef(
588
591
  tabIndex: active ? 0 : -1,
589
592
  onClick: () => setValue(value),
590
593
  className: cn(
591
- "relative px-[0.9rem] py-2.5 text-sm font-semibold cursor-pointer transition-colors duration-150 outline-none",
594
+ "relative px-[0.9rem] py-2.5 text-sm font-semibold cursor-pointer transition-colors duration-150 outline-none shrink-0 whitespace-nowrap",
592
595
  "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:rounded-sm",
593
596
  "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",
594
597
  active ? "text-foreground after:bg-primary" : "text-muted-foreground hover:text-foreground after:bg-transparent",
@@ -1341,23 +1344,39 @@ function DataTable({
1341
1344
  }[col.align || "left"];
1342
1345
  const isSortable = col.sortable && onSort && col.sortKey;
1343
1346
  const isSortedActive = sortBy && col.sortKey === sortBy;
1347
+ const ariaSort = isSortable ? isSortedActive ? sortDirection === "asc" ? "ascending" : "descending" : "none" : void 0;
1344
1348
  return /* @__PURE__ */ jsx(
1345
1349
  TableHead,
1346
1350
  {
1347
1351
  className: cn(
1348
1352
  alignClass,
1349
- isSortable && "cursor-pointer select-none hover:bg-muted/30 transition-colors",
1353
+ isSortable && "p-0 hover:bg-muted/30 transition-colors",
1350
1354
  col.className
1351
1355
  ),
1352
- onClick: () => {
1353
- if (!isSortable || !col.sortKey) return;
1354
- const nextDirection = isSortedActive && sortDirection === "asc" ? "desc" : "asc";
1355
- onSort(col.sortKey, nextDirection);
1356
- },
1357
- children: /* @__PURE__ */ jsxs("div", { className: cn("inline-flex items-center gap-1.5", alignClass === "text-right" && "justify-end w-full"), children: [
1358
- /* @__PURE__ */ jsx("span", { children: col.header }),
1359
- isSortable && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground shrink-0 select-none", children: isSortedActive ? sortDirection === "asc" ? "\u25B2" : "\u25BC" : "\u21C5" })
1360
- ] })
1356
+ "aria-sort": ariaSort,
1357
+ children: isSortable ? /* @__PURE__ */ jsxs(
1358
+ "button",
1359
+ {
1360
+ type: "button",
1361
+ onClick: () => {
1362
+ if (!col.sortKey) return;
1363
+ const nextDirection = isSortedActive && sortDirection === "asc" ? "desc" : "asc";
1364
+ onSort(col.sortKey, nextDirection);
1365
+ },
1366
+ className: cn(
1367
+ "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",
1368
+ {
1369
+ "justify-start text-left": col.align === "left" || !col.align,
1370
+ "justify-center text-center": col.align === "center",
1371
+ "justify-end text-right": col.align === "right"
1372
+ }
1373
+ ),
1374
+ children: [
1375
+ /* @__PURE__ */ jsx("span", { children: col.header }),
1376
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground shrink-0 select-none", children: isSortedActive ? sortDirection === "asc" ? "\u25B2" : "\u25BC" : "\u21C5" })
1377
+ ]
1378
+ }
1379
+ ) : /* @__PURE__ */ jsx("div", { className: cn("inline-flex items-center gap-1.5", alignClass === "text-right" && "justify-end w-full"), children: col.header })
1361
1380
  },
1362
1381
  idx
1363
1382
  );
@@ -1870,7 +1889,7 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1870
1889
  }, [open, filteredItems, activeIndex, onClose]);
1871
1890
  React18.useEffect(() => {
1872
1891
  if (listRef.current) {
1873
- const activeEl = listRef.current.children[activeIndex];
1892
+ const activeEl = listRef.current.querySelector('[aria-selected="true"]');
1874
1893
  if (activeEl) {
1875
1894
  activeEl.scrollIntoView({ block: "nearest" });
1876
1895
  }
@@ -1893,6 +1912,9 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1893
1912
  "div",
1894
1913
  {
1895
1914
  ref: containerRef,
1915
+ role: "dialog",
1916
+ "aria-modal": "true",
1917
+ "aria-label": "Command palette",
1896
1918
  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]",
1897
1919
  children: [
1898
1920
  /* @__PURE__ */ jsxs("div", { className: "p-4 border-b border-border flex items-center gap-2", children: [
@@ -1901,6 +1923,11 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1901
1923
  "input",
1902
1924
  {
1903
1925
  type: "text",
1926
+ role: "combobox",
1927
+ "aria-expanded": open,
1928
+ "aria-autocomplete": "list",
1929
+ "aria-controls": "command-palette-listbox",
1930
+ "aria-activedescendant": filteredItems.length > 0 ? `cmd-item-${activeIndex}` : void 0,
1904
1931
  placeholder,
1905
1932
  value: search,
1906
1933
  onChange: (e) => setSearch(e.target.value),
@@ -1913,44 +1940,64 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1913
1940
  'No results found for "',
1914
1941
  search,
1915
1942
  '"'
1916
- ] }) : /* @__PURE__ */ jsx("div", { ref: listRef, className: "space-y-4", children: Object.entries(groups).map(([cat, itemsInCat]) => /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
1917
- /* @__PURE__ */ jsx("div", { className: "px-3 py-1 text-[0.65rem] font-bold uppercase tracking-wider text-muted-foreground", children: cat }),
1918
- itemsInCat.map((item) => {
1919
- const currentIdx = absoluteItemIndex++;
1920
- const isActive = currentIdx === activeIndex;
1921
- return /* @__PURE__ */ jsxs(
1922
- "div",
1923
- {
1924
- onClick: () => {
1925
- item.action();
1926
- onClose();
1927
- },
1928
- className: cn(
1929
- "flex items-center justify-between gap-3 px-3 py-2.5 rounded-kj-md cursor-pointer select-none transition-colors",
1930
- isActive ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
1931
- ),
1932
- children: [
1933
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
1934
- item.icon && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground [&_svg]:h-[1.1rem] [&_svg]:w-[1.1rem]", children: item.icon }),
1935
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex flex-col", children: [
1936
- /* @__PURE__ */ jsx("span", { className: cn("text-[0.85rem] font-semibold", isActive ? "text-primary" : "text-foreground"), children: item.title }),
1937
- item.subtitle && /* @__PURE__ */ jsx("span", { className: "text-[0.75rem] text-muted-foreground truncate", children: item.subtitle })
1938
- ] })
1939
- ] }),
1940
- item.shortcut && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: item.shortcut.map((sc, scIdx) => /* @__PURE__ */ jsx(
1941
- "kbd",
1942
- {
1943
- 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",
1944
- children: sc
1943
+ ] }) : /* @__PURE__ */ jsx(
1944
+ "div",
1945
+ {
1946
+ ref: listRef,
1947
+ id: "command-palette-listbox",
1948
+ role: "listbox",
1949
+ "aria-label": "Commands",
1950
+ className: "space-y-4",
1951
+ children: Object.entries(groups).map(([cat, itemsInCat]) => /* @__PURE__ */ jsxs("div", { role: "group", "aria-labelledby": `cmd-cat-${cat}`, className: "space-y-1", children: [
1952
+ /* @__PURE__ */ jsx(
1953
+ "div",
1954
+ {
1955
+ id: `cmd-cat-${cat}`,
1956
+ className: "px-3 py-1 text-[0.65rem] font-bold uppercase tracking-wider text-muted-foreground",
1957
+ children: cat
1958
+ }
1959
+ ),
1960
+ itemsInCat.map((item) => {
1961
+ const currentIdx = absoluteItemIndex++;
1962
+ const isActive = currentIdx === activeIndex;
1963
+ return /* @__PURE__ */ jsxs(
1964
+ "div",
1965
+ {
1966
+ id: `cmd-item-${currentIdx}`,
1967
+ role: "option",
1968
+ "aria-selected": isActive,
1969
+ onClick: () => {
1970
+ item.action();
1971
+ onClose();
1945
1972
  },
1946
- scIdx
1947
- )) })
1948
- ]
1949
- },
1950
- item.id
1951
- );
1952
- })
1953
- ] }, cat)) }) }),
1973
+ className: cn(
1974
+ "flex items-center justify-between gap-3 px-3 py-2.5 rounded-kj-md cursor-pointer select-none transition-colors",
1975
+ isActive ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
1976
+ ),
1977
+ children: [
1978
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
1979
+ item.icon && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground [&_svg]:h-[1.1rem] [&_svg]:w-[1.1rem]", children: item.icon }),
1980
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex flex-col", children: [
1981
+ /* @__PURE__ */ jsx("span", { className: cn("text-[0.85rem] font-semibold", isActive ? "text-primary" : "text-foreground"), children: item.title }),
1982
+ item.subtitle && /* @__PURE__ */ jsx("span", { className: "text-[0.75rem] text-muted-foreground truncate", children: item.subtitle })
1983
+ ] })
1984
+ ] }),
1985
+ item.shortcut && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: item.shortcut.map((sc, scIdx) => /* @__PURE__ */ jsx(
1986
+ "kbd",
1987
+ {
1988
+ 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",
1989
+ children: sc
1990
+ },
1991
+ scIdx
1992
+ )) })
1993
+ ]
1994
+ },
1995
+ item.id
1996
+ );
1997
+ })
1998
+ ] }, cat))
1999
+ }
2000
+ ) }),
1954
2001
  /* @__PURE__ */ 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: [
1955
2002
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1956
2003
  /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [