@kanda-libs/ks-design-library-new 0.0.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.
Files changed (90) hide show
  1. package/LICENSE +21 -0
  2. package/dist/fonts/GalanoGrotesque/italic/GalanoGrotesqueBlackItalic.woff +0 -0
  3. package/dist/fonts/GalanoGrotesque/italic/GalanoGrotesqueBoldItalic.woff +0 -0
  4. package/dist/fonts/GalanoGrotesque/italic/GalanoGrotesqueExtraBoldItalic.woff +0 -0
  5. package/dist/fonts/GalanoGrotesque/italic/GalanoGrotesqueExtraLightItalic.woff +0 -0
  6. package/dist/fonts/GalanoGrotesque/italic/GalanoGrotesqueHeavyItalic.woff +0 -0
  7. package/dist/fonts/GalanoGrotesque/italic/GalanoGrotesqueLightItalic.woff +0 -0
  8. package/dist/fonts/GalanoGrotesque/italic/GalanoGrotesqueMediumItalic.woff +0 -0
  9. package/dist/fonts/GalanoGrotesque/italic/GalanoGrotesqueRegularItalic.woff +0 -0
  10. package/dist/fonts/GalanoGrotesque/italic/GalanoGrotesqueSemiBoldItalic.woff +0 -0
  11. package/dist/fonts/GalanoGrotesque/italic/GalanoGrotesqueThinItalic.woff +0 -0
  12. package/dist/fonts/GalanoGrotesque/regular/GalanoGrotesqueBlack.woff +0 -0
  13. package/dist/fonts/GalanoGrotesque/regular/GalanoGrotesqueBold.woff +0 -0
  14. package/dist/fonts/GalanoGrotesque/regular/GalanoGrotesqueExtraBold.woff +0 -0
  15. package/dist/fonts/GalanoGrotesque/regular/GalanoGrotesqueExtraLight.woff +0 -0
  16. package/dist/fonts/GalanoGrotesque/regular/GalanoGrotesqueHeavy.woff +0 -0
  17. package/dist/fonts/GalanoGrotesque/regular/GalanoGrotesqueLight.woff +0 -0
  18. package/dist/fonts/GalanoGrotesque/regular/GalanoGrotesqueMedium.woff +0 -0
  19. package/dist/fonts/GalanoGrotesque/regular/GalanoGrotesqueRegular.woff +0 -0
  20. package/dist/fonts/GalanoGrotesque/regular/GalanoGrotesqueSemiBold.woff +0 -0
  21. package/dist/fonts/GalanoGrotesque/regular/GalanoGrotesqueThin.woff +0 -0
  22. package/dist/index.d.ts +17 -0
  23. package/dist/index.esm.mjs +2 -0
  24. package/dist/index.esm.mjs.map +7 -0
  25. package/dist/library.css +2053 -0
  26. package/package.json +117 -0
  27. package/src/.DS_Store +0 -0
  28. package/src/@types/assets/index.d.ts +26 -0
  29. package/src/@types/index.d.ts +207 -0
  30. package/src/common/helpers.ts +15 -0
  31. package/src/components/Table/components/Cell/constants.ts +11 -0
  32. package/src/components/Table/components/Cell/index.tsx +36 -0
  33. package/src/components/Table/components/Cell/useCellClassNames.ts +23 -0
  34. package/src/components/Table/components/HeaderButton/Button.tsx +18 -0
  35. package/src/components/Table/components/HeaderButton/Wrapper.tsx +22 -0
  36. package/src/components/Table/components/HeaderButton/constants.ts +24 -0
  37. package/src/components/Table/components/HeaderButton/index.tsx +7 -0
  38. package/src/components/Table/components/HeaderButton/useWrapperProps.ts +31 -0
  39. package/src/components/Table/components/HeaderColumn/constants.ts +26 -0
  40. package/src/components/Table/components/HeaderColumn/index.tsx +38 -0
  41. package/src/components/Table/components/HeaderColumn/useHeaderColumnProps.ts +31 -0
  42. package/src/components/Table/components/HeaderGroup/constants.ts +3 -0
  43. package/src/components/Table/components/HeaderGroup/index.tsx +40 -0
  44. package/src/components/Table/components/HeaderGroup/useHeaderGroupProps.ts +27 -0
  45. package/src/components/Table/components/Row/constants.ts +7 -0
  46. package/src/components/Table/components/Row/index.tsx +40 -0
  47. package/src/components/Table/components/Row/useRowClassNames.ts +19 -0
  48. package/src/components/Table/components/SearchInput/index.tsx +22 -0
  49. package/src/components/Table/components/SearchInput/useSearchInput.ts +30 -0
  50. package/src/components/Table/helpers/search.ts +96 -0
  51. package/src/components/Table/index.tsx +64 -0
  52. package/src/components/Table/useTableProps.ts +54 -0
  53. package/src/components/index.tsx +1 -0
  54. package/src/index.ts +2 -0
  55. package/src/moduleTypes.d.ts +1 -0
  56. package/src/styles/fonts/GalanoGrotesque/italic/GalanoGrotesqueBlackItalic.woff +0 -0
  57. package/src/styles/fonts/GalanoGrotesque/italic/GalanoGrotesqueBoldItalic.woff +0 -0
  58. package/src/styles/fonts/GalanoGrotesque/italic/GalanoGrotesqueExtraBoldItalic.woff +0 -0
  59. package/src/styles/fonts/GalanoGrotesque/italic/GalanoGrotesqueExtraLightItalic.woff +0 -0
  60. package/src/styles/fonts/GalanoGrotesque/italic/GalanoGrotesqueHeavyItalic.woff +0 -0
  61. package/src/styles/fonts/GalanoGrotesque/italic/GalanoGrotesqueLightItalic.woff +0 -0
  62. package/src/styles/fonts/GalanoGrotesque/italic/GalanoGrotesqueMediumItalic.woff +0 -0
  63. package/src/styles/fonts/GalanoGrotesque/italic/GalanoGrotesqueRegularItalic.woff +0 -0
  64. package/src/styles/fonts/GalanoGrotesque/italic/GalanoGrotesqueSemiBoldItalic.woff +0 -0
  65. package/src/styles/fonts/GalanoGrotesque/italic/GalanoGrotesqueThinItalic.woff +0 -0
  66. package/src/styles/fonts/GalanoGrotesque/regular/GalanoGrotesqueBlack.woff +0 -0
  67. package/src/styles/fonts/GalanoGrotesque/regular/GalanoGrotesqueBold.woff +0 -0
  68. package/src/styles/fonts/GalanoGrotesque/regular/GalanoGrotesqueExtraBold.woff +0 -0
  69. package/src/styles/fonts/GalanoGrotesque/regular/GalanoGrotesqueExtraLight.woff +0 -0
  70. package/src/styles/fonts/GalanoGrotesque/regular/GalanoGrotesqueHeavy.woff +0 -0
  71. package/src/styles/fonts/GalanoGrotesque/regular/GalanoGrotesqueLight.woff +0 -0
  72. package/src/styles/fonts/GalanoGrotesque/regular/GalanoGrotesqueMedium.woff +0 -0
  73. package/src/styles/fonts/GalanoGrotesque/regular/GalanoGrotesqueRegular.woff +0 -0
  74. package/src/styles/fonts/GalanoGrotesque/regular/GalanoGrotesqueSemiBold.woff +0 -0
  75. package/src/styles/fonts/GalanoGrotesque/regular/GalanoGrotesqueThin.woff +0 -0
  76. package/src/styles/index.css +2236 -0
  77. package/src/styles/ks-design-library.css +2236 -0
  78. package/src/styles/library.css +2053 -0
  79. package/src/styles/tailwind.css +915 -0
  80. package/src/theme/plugins/tailwind.plugin.caret-color.js +32 -0
  81. package/src/theme/plugins/tailwind.plugin.field-error.js +10 -0
  82. package/src/theme/plugins/tailwind.plugin.field-focus.js +10 -0
  83. package/src/theme/plugins/tailwind.plugin.field-loading.js +10 -0
  84. package/src/theme/plugins/tailwind.plugin.group-active.js +10 -0
  85. package/src/theme/plugins/tailwind.plugin.important.js +14 -0
  86. package/src/theme/plugins/tailwind.plugin.label-check.js +10 -0
  87. package/src/theme/plugins/tailwind.plugin.text-style.js +213 -0
  88. package/src/theme/postcss/tailwind.postcss.config.js +7 -0
  89. package/src/theme/themeConfig.js +339 -0
  90. package/src/types.d.ts +58 -0
@@ -0,0 +1,40 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ import type {
3
+ ColumnInstance,
4
+ HeaderGroup as HeaderGroupType,
5
+ } from 'react-table';
6
+ import HeaderColumn from '../HeaderColumn';
7
+ import { CLASS_NAMES } from './constants';
8
+ import useHeaderGroupProps from './useHeaderGroupProps';
9
+
10
+ export interface HeaderGroupProps<T extends Object> {
11
+ headerGroup: HeaderGroupType<T>;
12
+ columns: ColumnInstance<T>[];
13
+ isLoading?: boolean;
14
+ }
15
+
16
+ function HeaderGroup<T extends Object>({
17
+ headerGroup,
18
+ columns,
19
+ isLoading,
20
+ }: PropsWithChildren<HeaderGroupProps<T>>) {
21
+ const { headerGroupProps, headers } = useHeaderGroupProps(
22
+ headerGroup,
23
+ columns,
24
+ );
25
+
26
+ return (
27
+ <div {...headerGroupProps} className={CLASS_NAMES.base}>
28
+ {headers.map((column, index) => (
29
+ <HeaderColumn
30
+ index={index}
31
+ label={column.render('Header')}
32
+ isLoading={isLoading}
33
+ {...column.getHeaderProps(column.getSortByToggleProps())}
34
+ />
35
+ ))}
36
+ </div>
37
+ );
38
+ }
39
+
40
+ export default HeaderGroup;
@@ -0,0 +1,27 @@
1
+ import type {
2
+ ColumnInstance,
3
+ HeaderGroup,
4
+ TableHeaderProps,
5
+ } from 'react-table';
6
+
7
+ export interface HeaderGroupPropsHook<T extends Object> {
8
+ headers: ColumnInstance<T>[];
9
+ headerGroupProps: TableHeaderProps;
10
+ totalVisible: number;
11
+ }
12
+
13
+ export default function useHeaderGroupProps<T extends Object>(
14
+ headerGroup: HeaderGroup<T>,
15
+ columns: ColumnInstance<T>[],
16
+ ): HeaderGroupPropsHook<T> {
17
+ const { headers, getHeaderGroupProps } = headerGroup;
18
+ const headerGroupProps = getHeaderGroupProps({});
19
+
20
+ const totalVisible = columns.filter((column) => column.isVisible).length;
21
+
22
+ return {
23
+ headers,
24
+ headerGroupProps,
25
+ totalVisible,
26
+ };
27
+ }
@@ -0,0 +1,7 @@
1
+ export const CLASS_NAMES = {
2
+ base: 'relative h-16',
3
+ compact: 'relative h-8',
4
+ border: 'border-b border-neutral-200',
5
+ hover: 'group hover:bg-neutral-50 cursor-pointer',
6
+ button: 'hidden group-hover:block',
7
+ };
@@ -0,0 +1,40 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ import type { Row as RowType, TableRowProps } from 'react-table';
3
+ import Cell from '../Cell';
4
+ import useRowClassNames from './useRowClassNames';
5
+
6
+ export interface RowProps<T extends Object> extends TableRowProps {
7
+ cells: RowType<T>['cells'];
8
+ index: number;
9
+ compact?: boolean;
10
+ isLoading?: boolean;
11
+ }
12
+
13
+ function Row<T extends Object>({
14
+ cells,
15
+ index,
16
+ compact = false,
17
+ isLoading = false,
18
+ ...props
19
+ }: PropsWithChildren<RowProps<T>>) {
20
+ const classNames = useRowClassNames(index);
21
+
22
+ console.log({
23
+ props,
24
+ });
25
+
26
+ return (
27
+ <div {...props} className={compact ? classNames.compact : classNames.base}>
28
+ {cells.map((cell, cellIndex) => (
29
+ <Cell
30
+ {...cell.getCellProps()}
31
+ index={cellIndex}
32
+ isLoading={isLoading}
33
+ render={() => cell.render('Cell')}
34
+ />
35
+ ))}
36
+ </div>
37
+ );
38
+ }
39
+
40
+ export default Row;
@@ -0,0 +1,19 @@
1
+ import { useClasses } from '@kanda-libs/ks-design-library';
2
+ import { CLASS_NAMES } from './constants';
3
+
4
+ export interface RowClassNamesHook {
5
+ base: string;
6
+ compact: string;
7
+ border: string;
8
+ hover: string;
9
+ button: string;
10
+ }
11
+
12
+ export default function useRowClassNames(index: number): RowClassNamesHook {
13
+ const classNames = useClasses(CLASS_NAMES, {
14
+ base: ['.base', index === 9 ? '' : '.border', '.hover'],
15
+ button: ['.button'],
16
+ });
17
+
18
+ return classNames as RowClassNamesHook;
19
+ }
@@ -0,0 +1,22 @@
1
+ import type { FunctionComponent } from 'react';
2
+ import useSearchInput from './useSearchInput';
3
+
4
+ export interface SearchInputProps {
5
+ onSearch: (search: string) => void;
6
+ }
7
+
8
+ const SearchInput: FunctionComponent<SearchInputProps> = function ({
9
+ onSearch,
10
+ }) {
11
+ const { search, onChange, onSubmit } = useSearchInput(onSearch);
12
+
13
+ return (
14
+ <div className="flex flex-row gap-x-2">
15
+ <span>Search:</span>
16
+ <input type="text" value={search} onChange={onChange} />
17
+ <button onClick={onSubmit}>Search</button>
18
+ </div>
19
+ );
20
+ };
21
+
22
+ export default SearchInput;
@@ -0,0 +1,30 @@
1
+ import { FormEvent, useCallback, useState } from 'react';
2
+
3
+ export interface SearchInputHook {
4
+ search: string;
5
+ onChange: (e: FormEvent<HTMLInputElement>) => void;
6
+ onSubmit: () => void;
7
+ }
8
+
9
+ export default function useSearchInput(
10
+ onSearch: (search: string) => void,
11
+ ): SearchInputHook {
12
+ const [search, setSearch] = useState('');
13
+
14
+ const onChange = useCallback(
15
+ (e: FormEvent<HTMLInputElement>) => {
16
+ setSearch(e.currentTarget.value);
17
+ },
18
+ [setSearch],
19
+ );
20
+
21
+ const onSubmit = useCallback(() => {
22
+ onSearch(search);
23
+ }, [search, onSearch]);
24
+
25
+ return {
26
+ search,
27
+ onChange,
28
+ onSubmit,
29
+ };
30
+ }
@@ -0,0 +1,96 @@
1
+ import type { IdType } from 'react-table';
2
+ import type { Row } from '../../../@types/index';
3
+ import Fuse from 'fuse.js';
4
+ import type { StringIndexedObject } from '~/types';
5
+
6
+ const exactMatchSearch = <T extends StringIndexedObject<unknown>>(
7
+ rows: Row<T>[],
8
+ filterValue: string,
9
+ ) => {
10
+ return rows.filter((row) => {
11
+ // Take all values from the row, and add them together in a string
12
+ // for the purposes of searching
13
+ const rowValues = Object.values(row.values).join(', ');
14
+
15
+ return rowValues.toLowerCase().includes(filterValue.toLowerCase());
16
+ });
17
+ };
18
+
19
+ const excludeExactMatches = <T extends StringIndexedObject<unknown>>(
20
+ rows: Row<T>[],
21
+ exactMatchRows: Row<T>[],
22
+ ) =>
23
+ rows.filter(
24
+ ({ id }) => exactMatchRows.filter((p) => p.id === id).length === 0,
25
+ );
26
+
27
+ const fuzzySearch = <T extends StringIndexedObject<unknown>>(
28
+ rows: Row<T>[],
29
+ filterValue: string,
30
+ searchKeys: string[],
31
+ numberOfRows: number,
32
+ exactMatchRows: Row<T>[],
33
+ ): Row<T>[] => {
34
+ const currentRows = rows.map((row) => {
35
+ return row.values;
36
+ });
37
+
38
+ const fuse = new Fuse(currentRows, {
39
+ keys: searchKeys.map((key) => ({
40
+ name: key,
41
+ // Because FuseJS allows for dot notation,
42
+ // we need to use a function to get the value
43
+ // as the object returned from the table is flat,
44
+ // rather than nested
45
+ getFn: (obj: StringIndexedObject) => obj[key],
46
+ })),
47
+ });
48
+
49
+ const results = fuse
50
+ .search(filterValue)
51
+ .map(({ item }) => item)
52
+ .slice(0, numberOfRows);
53
+
54
+ const filteredResults = results
55
+ .map((result) => rows.find((row) => row.values.cid === result.cid))
56
+ .filter(Boolean) as Row<T>[];
57
+
58
+ return excludeExactMatches(filteredResults, exactMatchRows);
59
+ };
60
+
61
+ export const globalFilter = <T extends StringIndexedObject<unknown>>(
62
+ rows: Row<T>[],
63
+ searchKeys: IdType<T>[],
64
+ filterValue: string,
65
+ pageSize = 10,
66
+ ): Row<T>[] => {
67
+ if (filterValue.length < 1) {
68
+ return rows;
69
+ }
70
+
71
+ // Get the first 10 exact matches. The reason for this is that exact matching
72
+ // should take presedence over fuzzy matching. An exact match is more useful
73
+ // but also less expensive to compute. So there's no need to do a fuzzy search
74
+ // if there are >= 10 exact matches.
75
+ const exactMatches = exactMatchSearch(rows, filterValue).slice(0, pageSize);
76
+ const currentRowsExcludingExactMatches = excludeExactMatches(
77
+ rows,
78
+ exactMatches,
79
+ );
80
+
81
+ const fuzzyMatches = fuzzySearch(
82
+ currentRowsExcludingExactMatches,
83
+ filterValue,
84
+ searchKeys,
85
+ pageSize - exactMatches.length,
86
+ exactMatches,
87
+ );
88
+
89
+ const results = [...exactMatches, ...fuzzyMatches];
90
+
91
+ // Return the rows in the same order as the original rows
92
+ // to preserve sorting, which happens before fuzzy matching
93
+ return rows
94
+ .map(({ id }) => results.find((row) => row.id === id))
95
+ .filter(Boolean) as Row<T>[];
96
+ };
@@ -0,0 +1,64 @@
1
+ import type { StringIndexedObject } from '@kanda-libs/ks-design-library';
2
+ import type { FunctionComponent, PropsWithChildren } from 'react';
3
+ import type { Column } from 'react-table';
4
+ import HeaderGroup from './components/HeaderGroup';
5
+ import Row from './components/Row';
6
+ import SearchInput from './components/SearchInput';
7
+ import useTableProps from './useTableProps';
8
+
9
+ export interface TableProps<T extends StringIndexedObject<unknown>> {
10
+ columns: Readonly<Column<T>[]>;
11
+ data: T[];
12
+ filter?: string;
13
+ pageSize?: number;
14
+ compact?: boolean;
15
+ isLoading?: boolean;
16
+ }
17
+
18
+ export type TableFunctionComponent<
19
+ T extends StringIndexedObject<unknown> = any,
20
+ > = FunctionComponent<TableProps<T>>;
21
+
22
+ function Table<T extends StringIndexedObject<unknown>>({
23
+ compact = false,
24
+ isLoading = false,
25
+ ...props
26
+ }: PropsWithChildren<TableProps<T>>) {
27
+ const { onSearch, page, prepareRow, columns, getTableProps, headerGroups } =
28
+ useTableProps(props);
29
+
30
+ return (
31
+ <>
32
+ <SearchInput
33
+ onSearch={(currentSearch) => {
34
+ onSearch(currentSearch);
35
+ }}
36
+ />
37
+ <div {...getTableProps()} className="w-full">
38
+ <div>
39
+ {headerGroups.map((headerGroup) => (
40
+ <HeaderGroup
41
+ headerGroup={headerGroup}
42
+ columns={columns}
43
+ isLoading={isLoading}
44
+ />
45
+ ))}
46
+ </div>
47
+ {page.map((row, index) => {
48
+ prepareRow(row);
49
+ return (
50
+ <Row
51
+ {...row.getRowProps()}
52
+ index={index}
53
+ cells={row.cells}
54
+ compact={compact}
55
+ isLoading={isLoading}
56
+ />
57
+ );
58
+ })}
59
+ </div>
60
+ </>
61
+ );
62
+ }
63
+
64
+ export default Table;
@@ -0,0 +1,54 @@
1
+ import type { TableInstance, Row } from '../../@types/index';
2
+ import {
3
+ useTable,
4
+ useGlobalFilter,
5
+ usePagination,
6
+ useSortBy,
7
+ useFlexLayout,
8
+ type IdType,
9
+ TableOptions,
10
+ } from 'react-table';
11
+ import type { TableProps } from '.';
12
+ import { globalFilter } from './helpers/search';
13
+ import type { StringIndexedObject } from '@kanda-libs/ks-design-library';
14
+
15
+ export interface TablePropsHook<T extends StringIndexedObject<unknown>>
16
+ extends TableInstance<T> {
17
+ onSearch: (value: string) => void;
18
+ }
19
+
20
+ export default function useTableProps<T extends StringIndexedObject<unknown>>({
21
+ columns,
22
+ data,
23
+ pageSize = 10,
24
+ }: TableProps<T>): TablePropsHook<T> {
25
+ const table = useTable<T>(
26
+ {
27
+ columns,
28
+ data,
29
+ initialState: {
30
+ pageSize: 10,
31
+ pageIndex: 0,
32
+ },
33
+ autoResetGlobalFilter: false,
34
+ globalFilter: (
35
+ rows: Row<T>[],
36
+ searchKeys: IdType<T>[],
37
+ filterValue: string,
38
+ ) => globalFilter(rows, searchKeys, filterValue, pageSize),
39
+ } as unknown as TableOptions<T>,
40
+ useGlobalFilter,
41
+ useSortBy,
42
+ usePagination,
43
+ useFlexLayout,
44
+ );
45
+
46
+ const onSearch = (search: string) => {
47
+ table.setGlobalFilter(search);
48
+ };
49
+
50
+ return {
51
+ onSearch,
52
+ ...table,
53
+ };
54
+ }
@@ -0,0 +1 @@
1
+ export { default as Table } from './Table';
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ import './@types/index.d.ts';
2
+ export * from './components';
@@ -0,0 +1 @@
1
+ declare module '*.svg';