@kjaniec-dev/ui 0.7.1 → 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
@@ -1366,23 +1366,39 @@ function DataTable({
1366
1366
  }[col.align || "left"];
1367
1367
  const isSortable = col.sortable && onSort && col.sortKey;
1368
1368
  const isSortedActive = sortBy && col.sortKey === sortBy;
1369
+ const ariaSort = isSortable ? isSortedActive ? sortDirection === "asc" ? "ascending" : "descending" : "none" : void 0;
1369
1370
  return /* @__PURE__ */ jsxRuntime.jsx(
1370
1371
  TableHead,
1371
1372
  {
1372
1373
  className: cn(
1373
1374
  alignClass,
1374
- isSortable && "cursor-pointer select-none hover:bg-muted/30 transition-colors",
1375
+ isSortable && "p-0 hover:bg-muted/30 transition-colors",
1375
1376
  col.className
1376
1377
  ),
1377
- onClick: () => {
1378
- if (!isSortable || !col.sortKey) return;
1379
- const nextDirection = isSortedActive && sortDirection === "asc" ? "desc" : "asc";
1380
- onSort(col.sortKey, nextDirection);
1381
- },
1382
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("inline-flex items-center gap-1.5", alignClass === "text-right" && "justify-end w-full"), children: [
1383
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: col.header }),
1384
- isSortable && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground shrink-0 select-none", children: isSortedActive ? sortDirection === "asc" ? "\u25B2" : "\u25BC" : "\u21C5" })
1385
- ] })
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 })
1386
1402
  },
1387
1403
  idx
1388
1404
  );
@@ -1895,7 +1911,7 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1895
1911
  }, [open, filteredItems, activeIndex, onClose]);
1896
1912
  React18__namespace.useEffect(() => {
1897
1913
  if (listRef.current) {
1898
- const activeEl = listRef.current.children[activeIndex];
1914
+ const activeEl = listRef.current.querySelector('[aria-selected="true"]');
1899
1915
  if (activeEl) {
1900
1916
  activeEl.scrollIntoView({ block: "nearest" });
1901
1917
  }
@@ -1918,6 +1934,9 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1918
1934
  "div",
1919
1935
  {
1920
1936
  ref: containerRef,
1937
+ role: "dialog",
1938
+ "aria-modal": "true",
1939
+ "aria-label": "Command palette",
1921
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]",
1922
1941
  children: [
1923
1942
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 border-b border-border flex items-center gap-2", children: [
@@ -1926,6 +1945,11 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1926
1945
  "input",
1927
1946
  {
1928
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,
1929
1953
  placeholder,
1930
1954
  value: search,
1931
1955
  onChange: (e) => setSearch(e.target.value),
@@ -1938,44 +1962,64 @@ function CommandPalette({ open, onClose, items, placeholder = "Type a command or
1938
1962
  'No results found for "',
1939
1963
  search,
1940
1964
  '"'
1941
- ] }) : /* @__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: [
1942
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1 text-[0.65rem] font-bold uppercase tracking-wider text-muted-foreground", children: cat }),
1943
- itemsInCat.map((item) => {
1944
- const currentIdx = absoluteItemIndex++;
1945
- const isActive = currentIdx === activeIndex;
1946
- return /* @__PURE__ */ jsxRuntime.jsxs(
1947
- "div",
1948
- {
1949
- onClick: () => {
1950
- item.action();
1951
- onClose();
1952
- },
1953
- className: cn(
1954
- "flex items-center justify-between gap-3 px-3 py-2.5 rounded-kj-md cursor-pointer select-none transition-colors",
1955
- isActive ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
1956
- ),
1957
- children: [
1958
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
1959
- item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground [&_svg]:h-[1.1rem] [&_svg]:w-[1.1rem]", children: item.icon }),
1960
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex flex-col", children: [
1961
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[0.85rem] font-semibold", isActive ? "text-primary" : "text-foreground"), children: item.title }),
1962
- item.subtitle && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.75rem] text-muted-foreground truncate", children: item.subtitle })
1963
- ] })
1964
- ] }),
1965
- item.shortcut && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: item.shortcut.map((sc, scIdx) => /* @__PURE__ */ jsxRuntime.jsx(
1966
- "kbd",
1967
- {
1968
- 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",
1969
- 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();
1970
1994
  },
1971
- scIdx
1972
- )) })
1973
- ]
1974
- },
1975
- item.id
1976
- );
1977
- })
1978
- ] }, 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
+ ) }),
1979
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: [
1980
2024
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
1981
2025
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [