@koobiq/react-components 0.12.0 → 0.13.1

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.
@@ -1,6 +1,6 @@
1
1
  import type { CSSProperties } from 'react';
2
2
  import type { CellProps as AriaCellProps } from '@koobiq/react-primitives';
3
- export declare const cellPropAlign: readonly ["left", "right", "center"];
3
+ export declare const cellPropAlign: readonly ["start", "end", "center", "left", "right"];
4
4
  export declare const cellPropVerticalAlign: readonly ["baseline", "top", "middle", "bottom", "sub", "text-top"];
5
5
  export type CellPropAlign = (typeof cellPropAlign)[number];
6
6
  export type CellPropVerticalAlign = (typeof cellPropVerticalAlign)[number];
@@ -13,12 +13,12 @@ export type CellProps = AriaCellProps & {
13
13
  'data-testid'?: string | number;
14
14
  /**
15
15
  * Horizontal alignment of the cell content.
16
- * @default left
16
+ * @default 'start'
17
17
  */
18
18
  align?: CellPropAlign;
19
19
  /**
20
20
  * Vertical alignment of the cell content.
21
- * @default middle
21
+ * @default 'middle'
22
22
  */
23
23
  valign?: CellPropVerticalAlign;
24
24
  };
@@ -1,10 +1,10 @@
1
1
  import type { CSSProperties } from 'react';
2
2
  import type { ColumnProps as AriaColumnProps } from '@koobiq/react-primitives';
3
- export declare const columnPropAlign: readonly ["left", "right", "center"];
3
+ export declare const columnPropAlign: readonly ["start", "end", "center", "left", "right"];
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. */
@@ -13,12 +13,12 @@ export type ColumnProps<T> = Omit<AriaColumnProps<T>, 'allowsResizing' | 'allows
13
13
  'data-testid'?: string | number;
14
14
  /**
15
15
  * Horizontal alignment of the cell content.
16
- * @default left
16
+ * @default 'start'
17
17
  */
18
18
  align?: ColumnPropAlign;
19
19
  /**
20
20
  * Vertical alignment of the cell content.
21
- * @default middle
21
+ * @default 'middle'
22
22
  */
23
23
  valign?: ColumnPropVerticalAlign;
24
24
  };
@@ -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
  ] });
@@ -13,21 +13,23 @@ function TableCell({ cell, state }) {
13
13
  const {
14
14
  style,
15
15
  className,
16
- align = "left",
16
+ align = "start",
17
17
  valign = "middle"
18
18
  } = cell.props;
19
19
  return /* @__PURE__ */ jsx(
20
20
  "td",
21
21
  {
22
- align,
23
22
  ...mergeProps(gridCellProps, focusProps),
24
23
  className: clsx(
25
24
  s.base,
26
25
  textNormal,
26
+ align && s[align],
27
27
  valign && s[valign],
28
28
  isFocusVisible && s.focusVisible,
29
29
  className
30
30
  ),
31
+ "data-align": align || void 0,
32
+ "data-valign": valign || void 0,
31
33
  style,
32
34
  ref,
33
35
  children: cell.rendered
@@ -1,4 +1,9 @@
1
1
  const base = "kbq-tablecell-7b64ee";
2
+ const start = "kbq-tablecell-start-a210ad";
3
+ const left = "kbq-tablecell-left-c76817";
4
+ const center = "kbq-tablecell-center-cde2ea";
5
+ const end = "kbq-tablecell-end-684866";
6
+ const right = "kbq-tablecell-right-407770";
2
7
  const top = "kbq-tablecell-top-c83311";
3
8
  const baseline = "kbq-tablecell-baseline-9a695f";
4
9
  const middle = "kbq-tablecell-middle-61ce62";
@@ -7,6 +12,11 @@ const sub = "kbq-tablecell-sub-422152";
7
12
  const focusVisible = "kbq-tablecell-focusVisible-401e7c";
8
13
  const s = {
9
14
  base,
15
+ start,
16
+ left,
17
+ center,
18
+ end,
19
+ right,
10
20
  top,
11
21
  baseline,
12
22
  middle,
@@ -19,9 +29,14 @@ export {
19
29
  base,
20
30
  baseline,
21
31
  bottom,
32
+ center,
22
33
  s as default,
34
+ end,
23
35
  focusVisible,
36
+ left,
24
37
  middle,
38
+ right,
39
+ start,
25
40
  sub,
26
41
  top
27
42
  };
@@ -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(
@@ -19,25 +21,44 @@ function TableColumnHeader({
19
21
  const {
20
22
  style,
21
23
  className,
22
- align = "left",
24
+ align = "start",
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
  {
29
- align,
30
36
  className: clsx(
31
37
  s.base,
38
+ align && s[align],
32
39
  valign && s[valign],
33
40
  isFocusVisible && s.focusVisible,
41
+ allowsSorting && s.sortable,
34
42
  textNormal,
35
43
  className
36
44
  ),
45
+ "data-align": align || void 0,
46
+ "data-valign": valign || void 0,
47
+ "data-allows-sorting": allowsSorting || void 0,
37
48
  style,
38
49
  ...mergeProps(columnHeaderProps, focusProps),
39
50
  ref,
40
- children: column.rendered
51
+ children: /* @__PURE__ */ jsxs("span", { className: s.content, children: [
52
+ column.rendered,
53
+ allowsSorting && /* @__PURE__ */ jsx(
54
+ "span",
55
+ {
56
+ "aria-hidden": "true",
57
+ className: clsx(s.sortIcon, isActive && s.active),
58
+ children: iconToRender
59
+ }
60
+ )
61
+ ] })
41
62
  }
42
63
  );
43
64
  }
@@ -1,27 +1,54 @@
1
1
  const base = "kbq-tablecolumnheader-236616";
2
+ const start = "kbq-tablecolumnheader-start-25f77f";
3
+ const left = "kbq-tablecolumnheader-left-c0faf1";
4
+ const center = "kbq-tablecolumnheader-center-264aa0";
5
+ const end = "kbq-tablecolumnheader-end-a10062";
6
+ const right = "kbq-tablecolumnheader-right-e8f5b6";
2
7
  const top = "kbq-tablecolumnheader-top-70b78e";
3
8
  const baseline = "kbq-tablecolumnheader-baseline-9772f1";
4
9
  const middle = "kbq-tablecolumnheader-middle-22b85a";
5
10
  const bottom = "kbq-tablecolumnheader-bottom-1f6f2d";
6
11
  const sub = "kbq-tablecolumnheader-sub-c48ac7";
7
12
  const focusVisible = "kbq-tablecolumnheader-focusVisible-21814b";
13
+ const sortable = "kbq-tablecolumnheader-sortable-038383";
14
+ const content = "kbq-tablecolumnheader-content-2b6a20";
15
+ const sortIcon = "kbq-tablecolumnheader-sortIcon-b98bf4";
16
+ const active = "kbq-tablecolumnheader-active-f9b640";
8
17
  const s = {
9
18
  base,
19
+ start,
20
+ left,
21
+ center,
22
+ end,
23
+ right,
10
24
  top,
11
25
  baseline,
12
26
  middle,
13
27
  bottom,
14
28
  sub,
15
29
  "text-top": "kbq-tablecolumnheader-text-top-7013fa",
16
- focusVisible
30
+ focusVisible,
31
+ sortable,
32
+ content,
33
+ sortIcon,
34
+ active
17
35
  };
18
36
  export {
37
+ active,
19
38
  base,
20
39
  baseline,
21
40
  bottom,
41
+ center,
42
+ content,
22
43
  s as default,
44
+ end,
23
45
  focusVisible,
46
+ left,
24
47
  middle,
48
+ right,
49
+ sortIcon,
50
+ sortable,
51
+ start,
25
52
  sub,
26
53
  top
27
54
  };
@@ -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
@@ -3780,6 +3780,18 @@
3780
3780
  outline: none;
3781
3781
  }
3782
3782
 
3783
+ .kbq-tablecolumnheader-start-25f77f, .kbq-tablecolumnheader-left-c0faf1 {
3784
+ text-align: start;
3785
+ }
3786
+
3787
+ .kbq-tablecolumnheader-center-264aa0 {
3788
+ text-align: center;
3789
+ }
3790
+
3791
+ .kbq-tablecolumnheader-end-a10062, .kbq-tablecolumnheader-right-e8f5b6 {
3792
+ text-align: end;
3793
+ }
3794
+
3783
3795
  .kbq-tablecolumnheader-top-70b78e {
3784
3796
  vertical-align: top;
3785
3797
  }
@@ -3808,6 +3820,33 @@
3808
3820
  outline-offset: -2px;
3809
3821
  outline: 2px solid var(--kbq-states-line-focus-theme);
3810
3822
  }
3823
+
3824
+ .kbq-tablecolumnheader-sortable-038383 {
3825
+ cursor: pointer;
3826
+ }
3827
+
3828
+ .kbq-tablecolumnheader-content-2b6a20 {
3829
+ gap: var(--kbq-size-s);
3830
+ display: inline-flex;
3831
+ }
3832
+
3833
+ .kbq-tablecolumnheader-sortIcon-b98bf4 {
3834
+ visibility: hidden;
3835
+ display: flex;
3836
+ }
3837
+
3838
+ .kbq-tablecolumnheader-sortIcon-b98bf4:after {
3839
+ content: " ";
3840
+ font-size: 0;
3841
+ }
3842
+
3843
+ .kbq-tablecolumnheader-sortIcon-b98bf4 > * {
3844
+ margin: auto;
3845
+ }
3846
+
3847
+ .kbq-tablecolumnheader-active-f9b640 {
3848
+ visibility: visible;
3849
+ }
3811
3850
  .kbq-tablerow-4a268c {
3812
3851
  box-sizing: border-box;
3813
3852
  cursor: default;
@@ -3873,6 +3912,18 @@
3873
3912
  outline: none;
3874
3913
  }
3875
3914
 
3915
+ .kbq-tablecell-start-a210ad, .kbq-tablecell-left-c76817 {
3916
+ text-align: start;
3917
+ }
3918
+
3919
+ .kbq-tablecell-center-cde2ea {
3920
+ text-align: center;
3921
+ }
3922
+
3923
+ .kbq-tablecell-end-684866, .kbq-tablecell-right-407770 {
3924
+ text-align: end;
3925
+ }
3926
+
3876
3927
  .kbq-tablecell-top-c83311 {
3877
3928
  vertical-align: top;
3878
3929
  }
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.1",
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/logger": "0.13.1",
32
+ "@koobiq/react-icons": "0.13.1",
33
+ "@koobiq/react-primitives": "0.13.1",
34
+ "@koobiq/react-core": "0.13.1"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@koobiq/design-tokens": "^3.14.0",