@dxos/react-ui-table 0.6.12-main.7907542 → 0.6.12-main.ac23639

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.
Files changed (36) hide show
  1. package/dist/lib/browser/index.mjs +12 -85
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/ColumnMenu/ColumnMenu.d.ts +6 -3
  5. package/dist/types/src/components/ColumnMenu/ColumnMenu.d.ts.map +1 -1
  6. package/dist/types/src/components/ColumnMenu/ColumnMenu.stories.d.ts +3 -3
  7. package/dist/types/src/components/ColumnMenu/ColumnMenu.stories.d.ts.map +1 -1
  8. package/dist/types/src/components/ColumnMenu/ColumnSettings.d.ts +6 -3
  9. package/dist/types/src/components/ColumnMenu/ColumnSettings.d.ts.map +1 -1
  10. package/dist/types/src/components/ColumnMenu/ColumnSettings.stories.d.ts +7 -6
  11. package/dist/types/src/components/ColumnMenu/ColumnSettings.stories.d.ts.map +1 -1
  12. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  13. package/dist/types/src/schema/index.d.ts +0 -2
  14. package/dist/types/src/schema/index.d.ts.map +1 -1
  15. package/dist/types/src/schema/types.d.ts +4 -4
  16. package/dist/types/src/schema/types.d.ts.map +1 -1
  17. package/package.json +18 -19
  18. package/src/components/ColumnMenu/ColumnMenu.stories.tsx +7 -6
  19. package/src/components/ColumnMenu/ColumnMenu.tsx +6 -3
  20. package/src/components/ColumnMenu/ColumnSettings.stories.tsx +9 -8
  21. package/src/components/ColumnMenu/ColumnSettings.tsx +9 -5
  22. package/src/components/Table/Table.tsx +5 -6
  23. package/src/components/Table/props.ts +4 -4
  24. package/src/schema/column-utils.ts +7 -7
  25. package/src/schema/index.ts +0 -2
  26. package/src/schema/types.ts +7 -7
  27. package/src/translations.ts +1 -1
  28. package/dist/types/src/components/Form/Form.stories.d.ts +0 -42
  29. package/dist/types/src/components/Form/Form.stories.d.ts.map +0 -1
  30. package/dist/types/src/schema/schema.d.ts +0 -4
  31. package/dist/types/src/schema/schema.d.ts.map +0 -1
  32. package/dist/types/src/schema/schema.test.d.ts +0 -2
  33. package/dist/types/src/schema/schema.test.d.ts.map +0 -1
  34. package/src/components/Form/Form.stories.tsx +0 -69
  35. package/src/schema/schema.test.ts +0 -76
  36. package/src/schema/schema.ts +0 -86
@@ -16,13 +16,13 @@ import {
16
16
  } from '@tanstack/react-table';
17
17
  import React, {
18
18
  type ComponentPropsWithoutRef,
19
+ type ReactNode,
19
20
  Fragment,
21
+ memo,
20
22
  useCallback,
21
23
  useEffect,
22
24
  useState,
23
25
  useContext,
24
- type ReactNode,
25
- memo,
26
26
  } from 'react';
27
27
 
28
28
  import { DensityProvider, type ThemedClassName, useDefaultValue } from '@dxos/react-ui';
@@ -55,7 +55,6 @@ const TableViewport = ({ children, classNames, asChild, ...props }: TableViewpor
55
55
  const { scrollContextRef } = useContext(TableRootContext);
56
56
 
57
57
  const classes = mx(classNames, 'overflow-auto');
58
-
59
58
  return asChild ? (
60
59
  <Slot ref={scrollContextRef} className={classes} {...props}>
61
60
  {children}
@@ -70,13 +69,13 @@ const TableViewport = ({ children, classNames, asChild, ...props }: TableViewpor
70
69
  export const TablePrimitive = <TData extends RowData>(props: TableProps<TData>) => {
71
70
  const {
72
71
  role,
73
- onColumnResize,
74
- columnVisibility,
75
72
  header = true,
76
73
  rowsSelectable,
77
74
  debug,
78
- onDataSelectionChange,
79
75
  pinLastRow,
76
+ columnVisibility,
77
+ onColumnResize,
78
+ onDataSelectionChange,
80
79
  } = props;
81
80
 
82
81
  const columns = useDefaultValue(props.columns, () => []);
@@ -25,7 +25,7 @@ export type TableFlags = Partial<{
25
25
  * This is ‘current’ in the `aria-current` sense.
26
26
  */
27
27
  export type TableCurrent<TData extends RowData> = Partial<{
28
- // App state
28
+ // App state.
29
29
  currentDatum: TData;
30
30
  onDatumClick: (datum: TData) => void;
31
31
  }>;
@@ -39,13 +39,13 @@ export type TableProps<TData extends RowData> = TableFlags &
39
39
  onColumnResize: (state: Record<string, number>) => void;
40
40
  onColumnReorder: (columnId: string, direction: 'left' | 'right') => void;
41
41
  columnVisibility: VisibilityState;
42
- // Controllable row selection
42
+ // Controllable row selection.
43
43
  rowSelection: RowSelectionState;
44
44
  defaultRowSelection: RowSelectionState;
45
45
  onRowSelectionChange: (rowSelection: RowSelectionState) => void;
46
- // Derived from row selection
46
+ // Derived from row selection.
47
47
  onDataSelectionChange: (dataSelection: TData[]) => void;
48
- // `table` element props
48
+ // `table` element props.
49
49
  classNames: ClassNameValue;
50
50
  pinLastRow: boolean;
51
51
  }>;
@@ -5,36 +5,36 @@
5
5
  import { type ColumnDef } from '@tanstack/react-table';
6
6
 
7
7
  import { type S } from '@dxos/echo-schema';
8
+ import { FieldValueType, mapSchemaToFields } from '@dxos/schema';
8
9
 
9
- import { getColumnTypes } from './schema';
10
10
  import { createColumnBuilder } from '../helpers';
11
11
 
12
12
  export const schemaToColumnDefs = <T>(schema: S.Schema<T, any>): ColumnDef<T, any>[] => {
13
13
  const { helper, builder } = createColumnBuilder<T>();
14
14
 
15
- const classified = getColumnTypes(schema);
15
+ const classified = mapSchemaToFields(schema);
16
16
  return classified.map(([name, type]) => {
17
17
  const propertyKey = name.toString();
18
18
 
19
19
  let column: Partial<ColumnDef<any, any>> | undefined;
20
20
  switch (type) {
21
- case 'string': {
21
+ case FieldValueType.String: {
22
22
  column = builder.string({ label: propertyKey });
23
23
  break;
24
24
  }
25
- case 'number': {
25
+ case FieldValueType.Number: {
26
26
  column = builder.number({ label: propertyKey });
27
27
  break;
28
28
  }
29
- case 'boolean': {
29
+ case FieldValueType.Boolean: {
30
30
  column = builder.switch({ label: propertyKey });
31
31
  break;
32
32
  }
33
- case 'date': {
33
+ case FieldValueType.Date: {
34
34
  column = builder.date({ label: propertyKey });
35
35
  break;
36
36
  }
37
- case 'json': {
37
+ case FieldValueType.JSON: {
38
38
  column = builder.json({ label: propertyKey, id: propertyKey });
39
39
  break;
40
40
  }
@@ -3,6 +3,4 @@
3
3
  //
4
4
 
5
5
  export * from './column-utils';
6
- export * from './schema';
7
6
  export * from './types';
8
- export * from './schema';
@@ -2,20 +2,20 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { type FieldValueType } from '@dxos/schema';
6
+
7
+ // TODO(burdon): Reconcile with @dxos/schema/View.
5
8
  export type TableDef = {
6
9
  id: string;
7
10
  name?: string;
8
- columns: ColumnProps[];
11
+ columns: ColumnDef[];
9
12
  };
10
13
 
11
- // TODO(burdon): Use Effect defs?
12
- export type ColumnType = 'number' | 'boolean' | 'date' | 'string' | 'json' | 'ref';
13
-
14
- // TODO(burdon): Effect schema?
15
- export type ColumnProps = {
14
+ // TODO(burdon): Reconcile with @dxos/schema/Field.
15
+ export type ColumnDef = {
16
16
  id: string;
17
17
  prop: string;
18
- type: ColumnType;
18
+ type: FieldValueType;
19
19
  size?: number;
20
20
  label?: string;
21
21
 
@@ -10,7 +10,7 @@ export default [
10
10
  [translationKey]: {
11
11
  'no selection label': ' ',
12
12
  'number column type label': 'Number',
13
- 'boolean column type label': 'Toggle',
13
+ 'boolean column type label': 'Boolean',
14
14
  'date column type label': 'Date',
15
15
  'string column type label': 'Text',
16
16
  'ref column type label': 'Reference',
@@ -1,42 +0,0 @@
1
- import '@dxos-theme';
2
- import React from 'react';
3
- import { S } from '@dxos/echo-schema';
4
- type FormProps = {
5
- schema: S.Schema<any>;
6
- };
7
- declare const _default: {
8
- title: string;
9
- decorators: import("@storybook/react/*").Decorator[];
10
- parameters: {
11
- translations: {
12
- 'en-US': {
13
- table: {
14
- 'no selection label': string;
15
- 'number column type label': string;
16
- 'boolean column type label': string;
17
- 'date column type label': string;
18
- 'string column type label': string;
19
- 'ref column type label': string;
20
- 'digits label': string;
21
- 'save label': string;
22
- 'delete label': string;
23
- 'column label label': string;
24
- 'property key label': string;
25
- 'column type label': string;
26
- };
27
- };
28
- }[];
29
- };
30
- render: (props: FormProps) => React.JSX.Element;
31
- };
32
- export default _default;
33
- export declare const Default: {
34
- args: {
35
- schema: S.Struct<{
36
- name: S.SchemaClass<string, string, never>;
37
- email: typeof S.String;
38
- age: typeof S.Number;
39
- }>;
40
- };
41
- };
42
- //# sourceMappingURL=Form.stories.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Form.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/Form/Form.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAO,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAY3C,KAAK,SAAS,GAAG;IACf,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;CACvB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;oBARoB,SAAS;;AAyC/B,wBAOE;AAEF,eAAO,MAAM,OAAO;;;;;;;;CAInB,CAAC"}
@@ -1,4 +0,0 @@
1
- import { type S } from '@dxos/effect';
2
- import { type ColumnType } from './types';
3
- export declare const getColumnTypes: (schema: S.Schema<any, any>) => [string, ColumnType][];
4
- //# sourceMappingURL=schema.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/schema/schema.ts"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,CAAC,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1C,eAAO,MAAM,cAAc,WAAY,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,KAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAwB/E,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=schema.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema.test.d.ts","sourceRoot":"","sources":["../../../../src/schema/schema.test.ts"],"names":[],"mappings":""}
@@ -1,69 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import '@dxos-theme';
6
-
7
- import React from 'react';
8
-
9
- import { AST, S } from '@dxos/echo-schema';
10
- import { Input } from '@dxos/react-ui';
11
- import { withTheme, withLayout } from '@dxos/storybook-utils';
12
-
13
- import translations from '../../translations';
14
-
15
- const Story = (props: FormProps) => (
16
- <div className='flex w-[240px] m-2 p-2 border border-separator rounded'>
17
- <Form {...props} />
18
- </div>
19
- );
20
-
21
- type FormProps = {
22
- schema: S.Schema<any>;
23
- };
24
-
25
- const Form = ({ schema }: FormProps) => {
26
- // const types = getColumnTypes(schema);
27
- const props = AST.getPropertySignatures(schema.ast);
28
-
29
- return (
30
- <div className='flex flex-col w-full gap-2'>
31
- {props.map((prop, i) => {
32
- const { name, annotations } = prop;
33
- const a = AST.getDescriptionAnnotation(prop);
34
- console.log(a, annotations);
35
- return (
36
- <Input.Root key={i}>
37
- <Input.Label>{name.toString()}</Input.Label>
38
- <Input.TextInput
39
- placeholder={name.toString()}
40
- // value={formState.label ?? ''}
41
- // onChange={(event) => setFormState((prevState) => ({ ...prevState, label: event.target.value }))}
42
- />
43
- </Input.Root>
44
- );
45
- })}
46
- </div>
47
- );
48
- };
49
-
50
- const schema = S.Struct({
51
- name: S.String.annotations({ [AST.DescriptionAnnotationId]: 'Name' }),
52
- email: S.String,
53
- age: S.Number,
54
- });
55
-
56
- export default {
57
- title: 'react-ui-table/Form',
58
- decorators: [withTheme, withLayout()],
59
- parameters: {
60
- translations,
61
- },
62
- render: Story,
63
- };
64
-
65
- export const Default = {
66
- args: {
67
- schema,
68
- },
69
- };
@@ -1,76 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { Schema as S } from '@effect/schema';
6
- import { describe, expect, test } from 'vitest';
7
-
8
- import { getColumnTypes } from './schema';
9
-
10
- // TODO(burdon): Realistic data.
11
-
12
- describe('getColumnTypes', () => {
13
- test('basic', () => {
14
- const schema = S.Struct({
15
- field1: S.String,
16
- field2: S.Number,
17
- field3: S.Date,
18
- });
19
-
20
- const columns = getColumnTypes(schema);
21
- expect(columns).to.deep.equal([
22
- ['field1', 'string'],
23
- ['field2', 'number'],
24
- ['field3', 'date'],
25
- ]);
26
- });
27
-
28
- test('optional properties', () => {
29
- const schema = S.Struct({
30
- field1: S.optional(S.String),
31
- field2: S.optional(S.Number),
32
- });
33
-
34
- const columns = getColumnTypes(schema);
35
- expect(columns).to.deep.equal([
36
- ['field1', 'string'],
37
- ['field2', 'number'],
38
- ]);
39
- });
40
-
41
- test('piped validators', () => {
42
- const schema = S.Struct({
43
- name: S.optional(S.String.pipe(S.nonEmptyString(), S.maxLength(10))),
44
- age: S.Number.pipe(S.negative()),
45
- });
46
-
47
- const columns = getColumnTypes(schema);
48
- expect(columns).to.deep.equal([
49
- ['name', 'string'],
50
- ['age', 'number'],
51
- ]);
52
- });
53
-
54
- test('nested schema', () => {
55
- const schema = S.Struct({
56
- name: S.String,
57
- nested1: S.Struct({
58
- age: S.Number,
59
- deeplyNested: S.Struct({
60
- height: S.optional(S.Number),
61
- }),
62
- }),
63
- nested2: S.Struct({
64
- height: S.Number,
65
- }),
66
- });
67
-
68
- const columns = getColumnTypes(schema);
69
- expect(columns).to.deep.equal([
70
- ['name', 'string'],
71
- ['nested1.age', 'number'],
72
- ['nested1.deeplyNested.height', 'number'],
73
- ['nested2.height', 'number'],
74
- ]);
75
- });
76
- });
@@ -1,86 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { AST, type S } from '@dxos/effect';
6
-
7
- import { type ColumnType } from './types';
8
-
9
- // TODO(burdon): Factor out to @dxos/effect?
10
- // TODO(burdon): Return struct (with prop metadata).
11
- export const getColumnTypes = (schema: S.Schema<any, any>): [string, ColumnType][] => {
12
- const visitNode = (node: AST.AST, path: string[] = [], acc: [string, ColumnType][] = []) => {
13
- const props = AST.getPropertySignatures(node);
14
- props.forEach((prop) => {
15
- const propName = prop.name.toString();
16
-
17
- if (prop.isOptional) {
18
- const unwrappedAst = unwrapOptionProperty(prop);
19
- if (isStruct(unwrappedAst)) {
20
- return visitNode(unwrappedAst, [...path, propName], acc);
21
- }
22
- }
23
-
24
- if (isStruct(prop.type)) {
25
- visitNode(prop.type, [...path, propName], acc);
26
- } else {
27
- acc.push([path.concat(propName).join('.'), propertyToColumn(prop)]);
28
- }
29
- });
30
-
31
- return acc;
32
- };
33
-
34
- return visitNode(schema.ast);
35
- };
36
-
37
- // TODO(burdon): Document AST?
38
- const isStruct = (node: AST.AST) => AST.isTypeLiteral(node);
39
-
40
- const propertyToColumn = (prop: AST.PropertySignature): ColumnType => {
41
- let type = prop.type;
42
- if (prop.isOptional) {
43
- type = unwrapOptionProperty(prop);
44
- }
45
-
46
- return typeToColumn(type);
47
- };
48
-
49
- const unwrapOptionProperty = (prop: AST.PropertySignature) => {
50
- if (!AST.isUnion(prop.type)) {
51
- throw new Error(`Not a union type: ${String(prop.name)}`);
52
- }
53
-
54
- const [type] = prop.type.types;
55
- return type;
56
- };
57
-
58
- const typeToColumn = (type: AST.AST): ColumnType => {
59
- if (AST.isStringKeyword(type)) {
60
- return 'string';
61
- } else if (AST.isNumberKeyword(type)) {
62
- return 'number';
63
- } else if (AST.isBooleanKeyword(type)) {
64
- return 'boolean';
65
- }
66
-
67
- if (AST.isRefinement(type)) {
68
- return typeToColumn(type.from);
69
- }
70
-
71
- // TODO(zan): How should we be thinking about transformations?
72
- // - Which of these are we storing in the database?
73
- // - For types that aren't the 'DateFromString' transformation, should we be using the 'from' or 'to' type?
74
-
75
- if (AST.isTransformation(type)) {
76
- const identifier = AST.getIdentifierAnnotation(type);
77
- if (identifier._tag === 'Some') {
78
- if (identifier.value === 'DateFromString') {
79
- return 'date';
80
- }
81
- }
82
- }
83
-
84
- // TODO(burdon): Better fallback?
85
- return 'json';
86
- };