@koobiq/react-components 0.12.0 → 0.13.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.
@@ -4,7 +4,7 @@ export declare const columnPropAlign: readonly ["left", "right", "center"];
4
4
  export declare const columnPropVerticalAlign: readonly ["baseline", "top", "middle", "bottom", "sub", "text-top"];
5
5
  export type ColumnPropAlign = (typeof columnPropAlign)[number];
6
6
  export type ColumnPropVerticalAlign = (typeof columnPropVerticalAlign)[number];
7
- export type ColumnProps<T> = Omit<AriaColumnProps<T>, 'allowsResizing' | 'allowsSorting' | 'width' | 'defaultWidth' | 'minWidth' | 'maxWidth'> & {
7
+ export type ColumnProps<T> = Omit<AriaColumnProps<T>, 'allowsResizing' | 'width' | 'defaultWidth' | 'minWidth' | 'maxWidth'> & {
8
8
  /** Additional CSS-classes. */
9
9
  className?: string;
10
10
  /** Inline styles. */
@@ -27,6 +27,7 @@ function TableRender(props, ref) {
27
27
  slotProps,
28
28
  selectionMode,
29
29
  selectionBehavior,
30
+ renderSortIcon,
30
31
  className,
31
32
  style
32
33
  } = props;
@@ -51,24 +52,25 @@ function TableRender(props, ref) {
51
52
  slotProps?.root
52
53
  );
53
54
  return /* @__PURE__ */ jsxs("table", { ...tableProps, children: [
54
- /* @__PURE__ */ jsx(TableRowGroup, { type: "thead", ref: theadRef, children: collection.headerRows.map((headerRow) => /* @__PURE__ */ jsx(TableHeaderRow, { item: headerRow, state, children: [...headerRow.childNodes].map(
55
+ /* @__PURE__ */ jsx(TableRowGroup, { type: "thead", ref: theadRef, theadProps: slotProps?.header, children: collection.headerRows.map((headerRow) => /* @__PURE__ */ jsx(TableHeaderRow, { item: headerRow, state, children: [...headerRow.childNodes].map(
55
56
  (column) => column.props.isSelectionCell ? /* @__PURE__ */ jsx(
56
57
  TableSelectAllCell,
57
58
  {
58
- column,
59
- state
59
+ state,
60
+ column
60
61
  },
61
62
  column.key
62
63
  ) : /* @__PURE__ */ jsx(
63
64
  TableColumnHeader,
64
65
  {
66
+ state,
65
67
  column,
66
- state
68
+ renderSortIcon
67
69
  },
68
70
  column.key
69
71
  )
70
72
  ) }, headerRow.key)) }),
71
- /* @__PURE__ */ jsx(TableRowGroup, { type: "tbody", children: [...collection.body.childNodes].map((row) => /* @__PURE__ */ jsx(TableRow, { item: row, state, children: [...row.childNodes].map(
73
+ /* @__PURE__ */ jsx(TableRowGroup, { type: "tbody", tbodyProps: slotProps?.body, children: [...collection.body.childNodes].map((row) => /* @__PURE__ */ jsx(TableRow, { item: row, state, children: [...row.childNodes].map(
72
74
  (cell) => cell.props.isSelectionCell ? /* @__PURE__ */ jsx(TableCheckboxCell, { cell, state }, cell.key) : /* @__PURE__ */ jsx(TableCell, { cell, state }, cell.key)
73
75
  ) }, row.key)) })
74
76
  ] });
@@ -1,7 +1,9 @@
1
1
  import type { TableState, AriaTableColumnHeaderProps } from '@koobiq/react-primitives';
2
+ import type { TableProps } from '../../types';
2
3
  type TableColumnHeaderProps<T> = {
3
4
  column: AriaTableColumnHeaderProps<T>['node'];
4
5
  state: TableState<T>;
6
+ renderSortIcon?: TableProps<T>['renderSortIcon'];
5
7
  };
6
- export declare function TableColumnHeader<T>({ column, state, }: TableColumnHeaderProps<T>): import("react/jsx-runtime").JSX.Element;
8
+ export declare function TableColumnHeader<T>({ column, state, renderSortIcon, }: TableColumnHeaderProps<T>): import("react/jsx-runtime").JSX.Element;
7
9
  export {};
@@ -1,14 +1,16 @@
1
1
  "use client";
2
- import { jsx } from "react/jsx-runtime";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useRef } from "react";
4
4
  import { useFocusRing, mergeProps, clsx } from "@koobiq/react-core";
5
+ import { IconChevronUpS16, IconChevronDownS16 } from "@koobiq/react-icons";
5
6
  import { useTableColumnHeader } from "@koobiq/react-primitives";
6
7
  import { utilClasses } from "../../../../styles/utility.js";
7
8
  import s from "./TableColumnHeader.module.css.js";
8
9
  const textNormal = utilClasses.typography["text-normal"];
9
10
  function TableColumnHeader({
10
11
  column,
11
- state
12
+ state,
13
+ renderSortIcon
12
14
  }) {
13
15
  const ref = useRef(null);
14
16
  const { columnHeaderProps } = useTableColumnHeader(
@@ -23,6 +25,11 @@ function TableColumnHeader({
23
25
  valign = "middle"
24
26
  } = column.props;
25
27
  const { isFocusVisible, focusProps } = useFocusRing();
28
+ const isActive = state.sortDescriptor?.column === column.key;
29
+ const { allowsSorting } = column.props;
30
+ const direction = isActive ? state.sortDescriptor?.direction : void 0;
31
+ const defaultIcon = direction === "ascending" ? /* @__PURE__ */ jsx(IconChevronUpS16, {}) : /* @__PURE__ */ jsx(IconChevronDownS16, {});
32
+ const iconToRender = renderSortIcon?.({ direction, isActive }) ?? defaultIcon;
26
33
  return /* @__PURE__ */ jsx(
27
34
  "th",
28
35
  {
@@ -31,13 +38,24 @@ function TableColumnHeader({
31
38
  s.base,
32
39
  valign && s[valign],
33
40
  isFocusVisible && s.focusVisible,
41
+ allowsSorting && s.sortable,
34
42
  textNormal,
35
43
  className
36
44
  ),
37
45
  style,
38
46
  ...mergeProps(columnHeaderProps, focusProps),
39
47
  ref,
40
- children: column.rendered
48
+ children: /* @__PURE__ */ jsxs("div", { className: s.content, children: [
49
+ /* @__PURE__ */ jsx("span", { children: column.rendered }),
50
+ allowsSorting && /* @__PURE__ */ jsx(
51
+ "span",
52
+ {
53
+ "aria-hidden": "true",
54
+ className: clsx(s.sortIcon, isActive && s.active),
55
+ children: iconToRender
56
+ }
57
+ )
58
+ ] })
41
59
  }
42
60
  );
43
61
  }
@@ -5,6 +5,10 @@ const middle = "kbq-tablecolumnheader-middle-22b85a";
5
5
  const bottom = "kbq-tablecolumnheader-bottom-1f6f2d";
6
6
  const sub = "kbq-tablecolumnheader-sub-c48ac7";
7
7
  const focusVisible = "kbq-tablecolumnheader-focusVisible-21814b";
8
+ const sortable = "kbq-tablecolumnheader-sortable-038383";
9
+ const content = "kbq-tablecolumnheader-content-2b6a20";
10
+ const sortIcon = "kbq-tablecolumnheader-sortIcon-b98bf4";
11
+ const active = "kbq-tablecolumnheader-active-f9b640";
8
12
  const s = {
9
13
  base,
10
14
  top,
@@ -13,15 +17,23 @@ const s = {
13
17
  bottom,
14
18
  sub,
15
19
  "text-top": "kbq-tablecolumnheader-text-top-7013fa",
16
- focusVisible
20
+ focusVisible,
21
+ sortable,
22
+ content,
23
+ sortIcon,
24
+ active
17
25
  };
18
26
  export {
27
+ active,
19
28
  base,
20
29
  baseline,
21
30
  bottom,
31
+ content,
22
32
  s as default,
23
33
  focusVisible,
24
34
  middle,
35
+ sortIcon,
36
+ sortable,
25
37
  sub,
26
38
  top
27
39
  };
@@ -1,6 +1,8 @@
1
- import { type ReactNode } from 'react';
1
+ import type { ComponentPropsWithRef, ReactNode } from 'react';
2
2
  export type TableRowGroupProps = {
3
3
  children: ReactNode;
4
4
  type: 'thead' | 'tbody';
5
+ theadProps?: ComponentPropsWithRef<'thead'>;
6
+ tbodyProps?: ComponentPropsWithRef<'tbody'>;
5
7
  };
6
8
  export declare const TableRowGroup: import("react").ForwardRefExoticComponent<TableRowGroupProps & import("react").RefAttributes<any>>;
@@ -1,12 +1,17 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { forwardRef } from "react";
4
+ import { mergeProps } from "@koobiq/react-core";
4
5
  import { useTableRowGroup } from "@koobiq/react-primitives";
5
6
  const TableRowGroup = forwardRef(
6
- ({ type = "thead", children }, ref) => {
7
+ ({ type = "thead", children, theadProps, tbodyProps }, ref) => {
7
8
  const Element = type;
8
9
  const { rowGroupProps } = useTableRowGroup();
9
- return /* @__PURE__ */ jsx(Element, { ...rowGroupProps, ref, children });
10
+ const elementProps = mergeProps(
11
+ { ...rowGroupProps, ref },
12
+ type === "thead" ? theadProps : tbodyProps
13
+ );
14
+ return /* @__PURE__ */ jsx(Element, { ...elementProps, children });
10
15
  }
11
16
  );
12
17
  TableRowGroup.displayName = "TableRowGroup";
@@ -1,10 +1,14 @@
1
- import type { ComponentPropsWithRef, ComponentRef, CSSProperties, ReactElement, Ref } from 'react';
1
+ import type { ComponentPropsWithRef, ComponentRef, CSSProperties, ReactElement, ReactNode, Ref } from 'react';
2
2
  import type { TableStateProps } from '@koobiq/react-primitives';
3
3
  import type { Key } from '@react-types/shared';
4
4
  export declare const tablePropDivider: readonly ["none", "row"];
5
5
  export type TablePropDivider = (typeof tablePropDivider)[number];
6
6
  export type TablePropChildren<T> = TableStateProps<T>['children'];
7
- export type TableProps<T> = Pick<TableStateProps<T>, 'selectionBehavior' | 'selectionMode' | 'selectedKeys' | 'defaultSelectedKeys' | 'onSelectionChange' | 'disabledKeys' | 'disabledBehavior'> & {
7
+ type TablePropSortIconRender = (args: {
8
+ direction: 'ascending' | 'descending' | undefined;
9
+ isActive: boolean;
10
+ }) => ReactNode;
11
+ export type TableProps<T> = Pick<TableStateProps<T>, 'selectionBehavior' | 'selectionMode' | 'selectedKeys' | 'defaultSelectedKeys' | 'onSelectionChange' | 'disabledKeys' | 'disabledBehavior' | 'sortDescriptor' | 'onSortChange'> & {
8
12
  /** Handler that is called when a user performs an action on the row. */
9
13
  onRowAction?: (key: Key) => void;
10
14
  /** Handler that is called when a user performs an action on the cell. */
@@ -30,13 +34,18 @@ export type TableProps<T> = Pick<TableStateProps<T>, 'selectionBehavior' | 'sele
30
34
  * The elements that make up the table.
31
35
  * Includes the Table.Header, Table.Body, Table.Column, and Table.Row.
32
36
  */
37
+ /** Render function for a custom sort icon for the column */
38
+ renderSortIcon?: TablePropSortIconRender;
33
39
  children?: TablePropChildren<T>;
34
40
  /** Ref to the control. */
35
41
  ref?: Ref<HTMLTableElement>;
36
42
  /** The props used for each slot inside. */
37
43
  slotProps?: {
38
44
  root?: ComponentPropsWithRef<'table'>;
45
+ header?: ComponentPropsWithRef<'thead'>;
46
+ body?: ComponentPropsWithRef<'tbody'>;
39
47
  };
40
48
  };
41
49
  export type TableComponent = <T>(props: TableProps<T>) => ReactElement | null;
42
50
  export type TableRef = ComponentRef<'table'>;
51
+ export {};
@@ -38,5 +38,5 @@ export * from './TimePicker';
38
38
  export * from './SearchInput';
39
39
  export * from './Form';
40
40
  export * from './layout';
41
- export { useListData, type ListData, type ListOptions, type TimeValue, type DateValue, } from '@koobiq/react-primitives';
42
- export { useRouter, useLocale, type Locale, RouterProvider, useDateFormatter, } from '@koobiq/react-core';
41
+ export { useListData, useAsyncList, type ListData, type ListOptions, type AsyncListData, type AsyncListOptions, type AsyncListLoadFunction, type AsyncListLoadOptions, type TimeValue, type DateValue, } from '@koobiq/react-primitives';
42
+ export { useRouter, useLocale, type Locale, type SortDescriptor, type Selection, RouterProvider, useDateFormatter, } from '@koobiq/react-core';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /* empty css */
2
- import { useListData } from "@koobiq/react-primitives";
2
+ import { useAsyncList, useListData } from "@koobiq/react-primitives";
3
3
  import { RouterProvider, useDateFormatter, useLocale, useRouter } from "@koobiq/react-core";
4
4
  import { Provider, defaultBreakpoints } from "./components/Provider/Provider.js";
5
5
  import { BreakpointsProvider } from "./components/Provider/BreakpointsProvider.js";
@@ -245,6 +245,7 @@ export {
245
245
  typographyPropColor,
246
246
  typographyPropDisplay,
247
247
  typographyPropVariant,
248
+ useAsyncList,
248
249
  useBreakpoints,
249
250
  useDateFormatter,
250
251
  useForm,
package/dist/style.css CHANGED
@@ -3808,6 +3808,33 @@
3808
3808
  outline-offset: -2px;
3809
3809
  outline: 2px solid var(--kbq-states-line-focus-theme);
3810
3810
  }
3811
+
3812
+ .kbq-tablecolumnheader-sortable-038383 {
3813
+ cursor: pointer;
3814
+ }
3815
+
3816
+ .kbq-tablecolumnheader-content-2b6a20 {
3817
+ gap: var(--kbq-size-s);
3818
+ display: flex;
3819
+ }
3820
+
3821
+ .kbq-tablecolumnheader-sortIcon-b98bf4 {
3822
+ visibility: hidden;
3823
+ display: flex;
3824
+ }
3825
+
3826
+ .kbq-tablecolumnheader-sortIcon-b98bf4:after {
3827
+ content: " ";
3828
+ font-size: 0;
3829
+ }
3830
+
3831
+ .kbq-tablecolumnheader-sortIcon-b98bf4 > * {
3832
+ margin: auto;
3833
+ }
3834
+
3835
+ .kbq-tablecolumnheader-active-f9b640 {
3836
+ visibility: visible;
3837
+ }
3811
3838
  .kbq-tablerow-4a268c {
3812
3839
  box-sizing: border-box;
3813
3840
  cursor: default;
package/dist/types.d.ts CHANGED
@@ -1,2 +1 @@
1
1
  export type { PressEvent } from '@koobiq/react-core';
2
- export type Selection = 'all' | Set<string | number>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koobiq/react-components",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "license": "MIT",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -28,10 +28,10 @@
28
28
  "@koobiq/design-tokens": "^3.14.0",
29
29
  "@types/react-transition-group": "^4.4.12",
30
30
  "react-transition-group": "^4.4.5",
31
- "@koobiq/logger": "0.12.0",
32
- "@koobiq/react-icons": "0.12.0",
33
- "@koobiq/react-primitives": "0.12.0",
34
- "@koobiq/react-core": "0.12.0"
31
+ "@koobiq/react-primitives": "0.13.0",
32
+ "@koobiq/react-icons": "0.13.0",
33
+ "@koobiq/logger": "0.13.0",
34
+ "@koobiq/react-core": "0.13.0"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@koobiq/design-tokens": "^3.14.0",