@tcn/ui-table 2.3.7 → 2.3.8

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 (43) hide show
  1. package/dist/components/table_filter_panel/field_filters/clear_button.d.ts +5 -0
  2. package/dist/components/table_filter_panel/field_filters/clear_button.d.ts.map +1 -0
  3. package/dist/components/table_filter_panel/field_filters/clear_button.js +15 -0
  4. package/dist/components/table_filter_panel/field_filters/clear_button.js.map +1 -0
  5. package/dist/components/table_filter_panel/field_filters/clearable_field.d.ts +9 -0
  6. package/dist/components/table_filter_panel/field_filters/clearable_field.d.ts.map +1 -0
  7. package/dist/components/table_filter_panel/field_filters/clearable_field.js +28 -0
  8. package/dist/components/table_filter_panel/field_filters/clearable_field.js.map +1 -0
  9. package/dist/components/table_filter_panel/field_filters/date_field_filter.d.ts.map +1 -1
  10. package/dist/components/table_filter_panel/field_filters/date_field_filter.js +45 -54
  11. package/dist/components/table_filter_panel/field_filters/date_field_filter.js.map +1 -1
  12. package/dist/components/table_filter_panel/field_filters/mulit_select_field_filter.d.ts.map +1 -1
  13. package/dist/components/table_filter_panel/field_filters/mulit_select_field_filter.js +25 -28
  14. package/dist/components/table_filter_panel/field_filters/mulit_select_field_filter.js.map +1 -1
  15. package/dist/components/table_filter_panel/field_filters/number_field_filter.d.ts.map +1 -1
  16. package/dist/components/table_filter_panel/field_filters/number_field_filter.js +37 -44
  17. package/dist/components/table_filter_panel/field_filters/number_field_filter.js.map +1 -1
  18. package/dist/components/table_filter_panel/field_filters/number_range_field_filter.d.ts.map +1 -1
  19. package/dist/components/table_filter_panel/field_filters/number_range_field_filter.js +46 -55
  20. package/dist/components/table_filter_panel/field_filters/number_range_field_filter.js.map +1 -1
  21. package/dist/components/table_filter_panel/field_filters/select_field_filter.d.ts.map +1 -1
  22. package/dist/components/table_filter_panel/field_filters/select_field_filter.js +19 -22
  23. package/dist/components/table_filter_panel/field_filters/select_field_filter.js.map +1 -1
  24. package/dist/components/table_filter_panel/field_filters/string_field_filter.d.ts.map +1 -1
  25. package/dist/components/table_filter_panel/field_filters/string_field_filter.js +45 -53
  26. package/dist/components/table_filter_panel/field_filters/string_field_filter.js.map +1 -1
  27. package/dist/components/table_filter_panel/table_filter_panel.d.ts +4 -3
  28. package/dist/components/table_filter_panel/table_filter_panel.d.ts.map +1 -1
  29. package/dist/components/table_filter_panel/table_filter_panel.js +38 -10
  30. package/dist/components/table_filter_panel/table_filter_panel.js.map +1 -1
  31. package/dist/table_filter_panel.css +1 -0
  32. package/package.json +4 -4
  33. package/src/__stories__/table.stories.tsx +5 -2
  34. package/src/components/table_filter_panel/field_filters/clear_button.tsx +17 -0
  35. package/src/components/table_filter_panel/field_filters/clearable_field.tsx +33 -0
  36. package/src/components/table_filter_panel/field_filters/date_field_filter.tsx +26 -50
  37. package/src/components/table_filter_panel/field_filters/mulit_select_field_filter.tsx +3 -9
  38. package/src/components/table_filter_panel/field_filters/number_field_filter.tsx +10 -20
  39. package/src/components/table_filter_panel/field_filters/number_range_field_filter.tsx +29 -48
  40. package/src/components/table_filter_panel/field_filters/select_field_filter.tsx +3 -9
  41. package/src/components/table_filter_panel/field_filters/string_field_filter.tsx +10 -21
  42. package/src/components/table_filter_panel/table_filter_panel.module.css +11 -0
  43. package/src/components/table_filter_panel/table_filter_panel.tsx +33 -4
@@ -1,12 +1,9 @@
1
- import { CrossCircleIcon } from '@tcn/icons/cross_circle_icon.js';
2
1
  import { useSignalValue } from '@tcn/state';
3
- import { Button } from '@tcn/ui/actions';
4
2
  import { Input } from '@tcn/ui/inputs';
5
- import { Box, HStack, VStack } from '@tcn/ui/stacks';
6
- import { BodyText, Title } from '@tcn/ui/typography';
7
- import React from 'react';
8
3
  import { useFieldFilterStrategy } from './use_field_filter_strategy.js';
9
4
  import { NumberRangeFieldFilterPresenter } from './number_range_field_filter_presenter.js';
5
+ import { FieldSet } from '@tcn/ui/form';
6
+ import { ClearableField } from './clearable_field.js';
10
7
 
11
8
  export function NumberRangeFieldFilter({
12
9
  fieldName,
@@ -21,48 +18,32 @@ export function NumberRangeFieldFilter({
21
18
  const maxValue = useSignalValue(presenter.broadcasts.maxValue);
22
19
 
23
20
  return (
24
- <VStack gap="4px">
25
- <Box width="flex">
26
- <Title size="md">{label}</Title>
27
- </Box>
28
- <HStack gap="4px">
29
- <Box width="auto">
30
- <BodyText size="lg">Min</BodyText>
31
- </Box>
32
- <Box width="flex">
33
- <Input
34
- type="number"
35
- value={String(minValue ?? '')}
36
- onChange={value => presenter.setMinValue(Number(value))}
37
- />
38
- </Box>
39
- <Button
40
- onClick={() => presenter.setMinValue(null)}
41
- hierarchy="tertiary"
42
- disabled={minValue == null}
43
- >
44
- <CrossCircleIcon />
45
- </Button>
46
- </HStack>
47
- <HStack gap="4px">
48
- <Box width="auto">
49
- <BodyText size="lg">Max</BodyText>
50
- </Box>
51
- <Box width="flex">
52
- <Input
53
- type="number"
54
- value={String(maxValue ?? '')}
55
- onChange={value => presenter.setMaxValue(Number(value))}
56
- />
57
- </Box>
58
- <Button
59
- onClick={() => presenter.setMaxValue(null)}
60
- hierarchy="tertiary"
61
- disabled={maxValue == null}
62
- >
63
- <CrossCircleIcon />
64
- </Button>
65
- </HStack>
66
- </VStack>
21
+ <FieldSet legend={label} gap="4px">
22
+ <ClearableField
23
+ label="Min"
24
+ onClear={() => presenter.setMinValue(null)}
25
+ isClearable={minValue == null}
26
+ inline
27
+ >
28
+ <Input
29
+ type="number"
30
+ value={String(minValue ?? '')}
31
+ onChange={value => presenter.setMinValue(Number(value))}
32
+ />
33
+ </ClearableField>
34
+
35
+ <ClearableField
36
+ label="Max"
37
+ onClear={() => presenter.setMaxValue(null)}
38
+ isClearable={maxValue == null}
39
+ inline
40
+ >
41
+ <Input
42
+ type="number"
43
+ value={String(maxValue ?? '')}
44
+ onChange={value => presenter.setMaxValue(Number(value))}
45
+ />
46
+ </ClearableField>
47
+ </FieldSet>
67
48
  );
68
49
  }
@@ -1,14 +1,11 @@
1
- import React from 'react';
2
-
3
- import { CrossCircleIcon } from '@tcn/icons/cross_circle_icon.js';
4
1
  import { useSignalValue } from '@tcn/state';
5
- import { Button } from '@tcn/ui/actions';
6
2
  import { Option, Select } from '@tcn/ui/inputs';
7
3
  import { Box, HStack, VStack } from '@tcn/ui/stacks';
8
4
  import { Title } from '@tcn/ui/typography';
9
5
  import { FieldFilterProps } from './field_filter_props.js';
10
6
  import { SelectFieldFilterPresenter } from './select_field_filter_presenter.js';
11
7
  import { useFieldFilterStrategy } from './use_field_filter_strategy.js';
8
+ import { ClearFilterButton } from './clear_button.js';
12
9
 
13
10
  export type SelectFieldFilterProps = FieldFilterProps & {
14
11
  options: { label: string; value: string | boolean | number }[];
@@ -44,13 +41,10 @@ export function SelectFieldFilter({ fieldName, label, options }: SelectFieldFilt
44
41
  </Option>
45
42
  ))}
46
43
  </Select>
47
- <Button
44
+ <ClearFilterButton
48
45
  onClick={() => presenter.setValue(null)}
49
- hierarchy="tertiary"
50
46
  disabled={value == null}
51
- >
52
- <CrossCircleIcon />
53
- </Button>
47
+ />
54
48
  </HStack>
55
49
  </VStack>
56
50
  );
@@ -1,15 +1,11 @@
1
- import { CrossCircleIcon } from '@tcn/icons/cross_circle_icon.js';
2
1
  import { useSignalValue } from '@tcn/state';
3
- import { Button } from '@tcn/ui/actions';
4
- import { Input, Option, Select } from '@tcn/ui/inputs';
5
- import { Box, HStack, VStack } from '@tcn/ui/stacks';
6
- import { Title } from '@tcn/ui/typography';
7
- import React from 'react';
2
+ import { Input, Option, Select, InputGroup } from '@tcn/ui/inputs';
8
3
  import { FieldFilterProps } from './field_filter_props.js';
9
4
  import { StringFieldFilterPresenter } from './string_field_filter_presenter.js';
10
5
  import { ComparisonOperator } from '../types.js';
11
6
 
12
7
  import { useFieldFilterStrategy } from './use_field_filter_strategy.js';
8
+ import { ClearableField } from './clearable_field.js';
13
9
 
14
10
  const allOperators: ('is' | 'isNot' | 'has')[] = ['is', 'isNot', 'has'];
15
11
  const operatorSymbols: Record<'is' | 'isNot' | 'has', string> = {
@@ -32,11 +28,12 @@ export function StringFieldFilter({ fieldName, label, operators }: FieldFilterPr
32
28
  const availableOperators = operators || allOperators;
33
29
 
34
30
  return (
35
- <VStack gap="4px">
36
- <Box width="flex">
37
- <Title size="md">{label}</Title>
38
- </Box>
39
- <HStack width="flex">
31
+ <ClearableField
32
+ label={label}
33
+ onClear={() => presenter.setValue(null)}
34
+ isClearable={value == null}
35
+ >
36
+ <InputGroup>
40
37
  <Select
41
38
  value={operator}
42
39
  onChange={value => presenter.setOperator(value as ComparisonOperator)}
@@ -57,15 +54,7 @@ export function StringFieldFilter({ fieldName, label, operators }: FieldFilterPr
57
54
  value={value ?? ''}
58
55
  onChange={value => presenter.setValue(value)}
59
56
  />
60
- <Button
61
- onClick={() => presenter.setValue(null)}
62
- hierarchy="tertiary"
63
- utility
64
- disabled={value == null}
65
- >
66
- <CrossCircleIcon />
67
- </Button>
68
- </HStack>
69
- </VStack>
57
+ </InputGroup>
58
+ </ClearableField>
70
59
  );
71
60
  }
@@ -0,0 +1,11 @@
1
+ .table-filter-panel {
2
+ --material: #fafafa;
3
+ background: var(--material);
4
+ }
5
+
6
+ .table-filter-panel-body {
7
+ padding-block: 8px;
8
+ .table-filter-panel-section {
9
+ gap: 8px;
10
+ }
11
+ }
@@ -1,22 +1,51 @@
1
1
  import { DataSource } from '@tcn/resource-store';
2
- import { VStack } from '@tcn/ui/stacks';
3
- import React, { ReactElement, useState, createContext } from 'react';
2
+ import { ReactElement, useState, createContext } from 'react';
4
3
  import { FieldFilterProps } from './field_filters/field_filter_props.js';
5
4
  import { TableFilterPanelPresenter } from './table_filter_panel_presenter.js';
5
+ import { Panel } from '@tcn/ui/surfaces';
6
+ import { Header, Section, VBody } from '@tcn/ui/layouts';
7
+ import styles from './table_filter_panel.module.css';
8
+ import { Spacer } from '@tcn/ui/stacks';
9
+ import { Button } from '@tcn/ui/actions';
10
+ import { CrossIcon } from '@tcn/icons/cross_icon.js';
6
11
 
7
12
  export type TableFilterPanelProps = {
8
13
  children: ReactElement<FieldFilterProps>[] | ReactElement<FieldFilterProps>;
9
14
  dataSource: DataSource<any>;
15
+ onClose?: () => void;
10
16
  };
11
17
 
12
- export function TableFilterPanel({ children, dataSource }: TableFilterPanelProps) {
18
+ export function TableFilterPanel({
19
+ children,
20
+ dataSource,
21
+ onClose,
22
+ }: TableFilterPanelProps) {
13
23
  const [presenter] = useState(() => {
14
24
  return new TableFilterPanelPresenter(dataSource);
15
25
  });
16
26
 
17
27
  return (
18
28
  <TableFilterPanelContext.Provider value={presenter}>
19
- <VStack gap="16px">{children}</VStack>
29
+ <Panel className={`${styles['table-filter-panel']} tcn-table-filter-panel`}>
30
+ <Header>
31
+ Table Filters
32
+ <Spacer />
33
+ {onClose && (
34
+ <Button utility hierarchy="tertiary" onClick={onClose}>
35
+ <CrossIcon />
36
+ </Button>
37
+ )}
38
+ </Header>
39
+ <VBody
40
+ className={`${styles['table-filter-panel-body']} tcn-table-filter-panel-body`}
41
+ >
42
+ <Section
43
+ className={`${styles['table-filter-panel-section']} tcn-table-filter-panel-section`}
44
+ >
45
+ {children}
46
+ </Section>
47
+ </VBody>
48
+ </Panel>
20
49
  </TableFilterPanelContext.Provider>
21
50
  );
22
51
  }