@jakubmazanec/ui 0.4.2 → 0.5.0-next.7fc14073

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 (116) hide show
  1. package/build/components/Button.js +8 -5
  2. package/build/components/Button.js.map +2 -2
  3. package/build/components/Checkbox.js +2 -2
  4. package/build/components/Checkbox.js.map +1 -1
  5. package/build/components/Combobox.js +1 -1
  6. package/build/components/Combobox.js.map +1 -1
  7. package/build/components/DialogPanel.js +1 -1
  8. package/build/components/DialogPanel.js.map +1 -1
  9. package/build/components/DialogTitle.js +1 -1
  10. package/build/components/DialogTitle.js.map +1 -1
  11. package/build/components/Heading.d.ts +21 -0
  12. package/build/components/Heading.js +48 -0
  13. package/build/components/Heading.js.map +7 -0
  14. package/build/components/Icon.js +1 -1
  15. package/build/components/Icon.js.map +1 -1
  16. package/build/components/Input.js +4 -4
  17. package/build/components/Input.js.map +2 -2
  18. package/build/components/Legend.js +1 -1
  19. package/build/components/Legend.js.map +1 -1
  20. package/build/components/ListboxOption.js +1 -1
  21. package/build/components/ListboxOption.js.map +1 -1
  22. package/build/components/Radio.js +2 -2
  23. package/build/components/Radio.js.map +1 -1
  24. package/build/components/Spinner.js +1 -1
  25. package/build/components/Spinner.js.map +1 -1
  26. package/build/components/TableHead.js +1 -1
  27. package/build/components/TableHead.js.map +1 -1
  28. package/build/components/TableHeader.js +1 -1
  29. package/build/components/TableHeader.js.map +2 -2
  30. package/build/components/Textarea.js +2 -2
  31. package/build/components/Textarea.js.map +1 -1
  32. package/build/components/data-table/DataTable.d.ts +2 -1
  33. package/build/components/data-table/DataTable.js +78 -76
  34. package/build/components/data-table/DataTable.js.map +2 -2
  35. package/build/components/data-table/internals/DataTableFilter.d.ts +12 -0
  36. package/build/components/data-table/internals/DataTableFilter.js +275 -0
  37. package/build/components/data-table/internals/DataTableFilter.js.map +7 -0
  38. package/build/components/data-table/internals/DataTableFilters.d.ts +11 -0
  39. package/build/components/data-table/internals/DataTableFilters.js +40 -0
  40. package/build/components/data-table/internals/DataTableFilters.js.map +7 -0
  41. package/build/components/data-table/internals/DataTableHeader.d.ts +2 -11
  42. package/build/components/data-table/internals/DataTableHeader.js +18 -112
  43. package/build/components/data-table/internals/DataTableHeader.js.map +2 -2
  44. package/build/components/data-table/internals/DataTableMenu.d.ts +11 -0
  45. package/build/components/data-table/internals/DataTableMenu.js +34 -0
  46. package/build/components/data-table/internals/DataTableMenu.js.map +7 -0
  47. package/build/components/data-table/internals/DataTablePagination.js +2 -2
  48. package/build/components/data-table/internals/DataTablePagination.js.map +2 -2
  49. package/build/components/data-table/internals/DataTableRow.d.ts +6 -0
  50. package/build/components/data-table/internals/DataTableRow.js +26 -0
  51. package/build/components/data-table/internals/DataTableRow.js.map +7 -0
  52. package/build/components/data-table/internals/DataTableSetting.d.ts +10 -0
  53. package/build/components/data-table/internals/DataTableSetting.js +111 -0
  54. package/build/components/data-table/internals/DataTableSetting.js.map +7 -0
  55. package/build/components/data-table/internals/DataTableSettings.d.ts +9 -0
  56. package/build/components/data-table/internals/DataTableSettings.js +63 -0
  57. package/build/components/data-table/internals/DataTableSettings.js.map +7 -0
  58. package/build/components/data-table/internals/constants.d.ts +1 -1
  59. package/build/components/data-table/internals/constants.js +1 -1
  60. package/build/components/data-table/internals/constants.js.map +2 -2
  61. package/build/components/data-table/internals.d.ts +5 -0
  62. package/build/components/data-table/internals.js +5 -0
  63. package/build/components/data-table/internals.js.map +2 -2
  64. package/build/components.d.ts +1 -0
  65. package/build/components.js +1 -0
  66. package/build/components.js.map +2 -2
  67. package/build/development/createTailwindConfig.d.ts +79 -2
  68. package/build/development/createTailwindConfig.js +10 -55
  69. package/build/development/createTailwindConfig.js.map +2 -2
  70. package/build/development/internals/createTailwindThemeColors.d.ts +2 -0
  71. package/build/development/internals/createTailwindThemeColors.js +51 -0
  72. package/build/development/internals/createTailwindThemeColors.js.map +7 -0
  73. package/build/development/internals.d.ts +1 -0
  74. package/build/development/internals.js +1 -0
  75. package/build/development/internals.js.map +2 -2
  76. package/build/styles.css +15 -1
  77. package/build/styles.css.map +2 -2
  78. package/build/theme/Theme.d.ts +3 -0
  79. package/build/theme/defaultTheme.js +2 -0
  80. package/build/theme/defaultTheme.js.map +2 -2
  81. package/build/theme/internals/themeContext.d.ts +10 -0
  82. package/build/theme/internals/useTheme.d.ts +10 -0
  83. package/package.json +1 -1
  84. package/source/components/Button.tsx +12 -5
  85. package/source/components/Checkbox.tsx +2 -2
  86. package/source/components/Combobox.tsx +1 -1
  87. package/source/components/DialogPanel.tsx +1 -1
  88. package/source/components/DialogTitle.tsx +1 -1
  89. package/source/components/Heading.ts +69 -0
  90. package/source/components/Icon.tsx +1 -1
  91. package/source/components/Input.tsx +5 -5
  92. package/source/components/Legend.tsx +1 -1
  93. package/source/components/ListboxOption.tsx +1 -1
  94. package/source/components/Radio.tsx +2 -2
  95. package/source/components/Spinner.tsx +1 -1
  96. package/source/components/TableHead.ts +1 -1
  97. package/source/components/TableHeader.ts +2 -1
  98. package/source/components/Textarea.tsx +2 -2
  99. package/source/components/data-table/DataTable.tsx +97 -82
  100. package/source/components/data-table/internals/DataTableFilter.tsx +354 -0
  101. package/source/components/data-table/internals/DataTableFilters.tsx +56 -0
  102. package/source/components/data-table/internals/DataTableHeader.tsx +7 -145
  103. package/source/components/data-table/internals/DataTableMenu.tsx +60 -0
  104. package/source/components/data-table/internals/DataTablePagination.tsx +79 -77
  105. package/source/components/data-table/internals/DataTableRow.tsx +40 -0
  106. package/source/components/data-table/internals/DataTableSetting.tsx +142 -0
  107. package/source/components/data-table/internals/DataTableSettings.tsx +83 -0
  108. package/source/components/data-table/internals/constants.ts +1 -1
  109. package/source/components/data-table/internals.ts +5 -0
  110. package/source/components.ts +1 -0
  111. package/source/development/createTailwindConfig.ts +11 -57
  112. package/source/development/internals/createTailwindThemeColors.ts +53 -0
  113. package/source/development/internals.ts +1 -0
  114. package/source/styles.css +19 -3
  115. package/source/theme/Theme.ts +2 -0
  116. package/source/theme/defaultTheme.ts +2 -0
@@ -134,87 +134,89 @@ export const DataTablePagination = memo(
134
134
  );
135
135
 
136
136
  return (
137
- <Container align="center" justify="center">
138
- <Container spacing="small">
139
- <Button
140
- aria-label="First page"
141
- disabled={isFirstPage}
142
- variant="outline"
143
- onClick={handleFirstPageClick}
144
- >
145
- <Icon name="ChevronDoubleLeft" />
146
- </Button>
147
- <Button
148
- aria-label="Previous page"
149
- disabled={isFirstPage}
150
- variant="outline"
151
- onClick={handlePreviousPageClick}
152
- >
153
- <Icon name="ChevronLeft" />
154
- </Button>
155
-
156
- {pageCount <= MAX_PAGE_BUTTONS_COUNT ?
157
- Array.from({length: pageCount}).map((_, index) => (
158
- <DataTablePageButton
159
- // eslint-disable-next-line react/no-array-index-key -- needed, there is no other value
160
- key={index}
161
- isSelected={page === index + 1}
162
- page={index + 1}
163
- onClick={handlePageClick}
137
+ <div>
138
+ <Container align="center" className="flex-wrap" justify="center" spacing="small">
139
+ <Container spacing="small">
140
+ <Button
141
+ aria-label="First page"
142
+ disabled={isFirstPage}
143
+ variant="outline"
144
+ onClick={handleFirstPageClick}
145
+ >
146
+ <Icon name="ChevronDoubleLeft" />
147
+ </Button>
148
+ <Button
149
+ aria-label="Previous page"
150
+ disabled={isFirstPage}
151
+ variant="outline"
152
+ onClick={handlePreviousPageClick}
153
+ >
154
+ <Icon name="ChevronLeft" />
155
+ </Button>
156
+
157
+ {pageCount <= MAX_PAGE_BUTTONS_COUNT ?
158
+ Array.from({length: pageCount}).map((_, index) => (
159
+ <DataTablePageButton
160
+ // eslint-disable-next-line react/no-array-index-key -- needed, there is no other value
161
+ key={index}
162
+ isSelected={page === index + 1}
163
+ page={index + 1}
164
+ onClick={handlePageClick}
165
+ />
166
+ ))
167
+ : null}
168
+
169
+ <Button
170
+ aria-label="Next page"
171
+ disabled={isLastPage}
172
+ variant="outline"
173
+ onClick={handleNextPageClick}
174
+ >
175
+ <Icon name="ChevronRight" />
176
+ </Button>
177
+ <Button
178
+ aria-label="Last page"
179
+ disabled={isLastPage}
180
+ variant="outline"
181
+ onClick={handleLastPageClick}
182
+ >
183
+ <Icon name="ChevronDoubleRight" />
184
+ </Button>
185
+ </Container>
186
+ {pageCount > MAX_PAGE_BUTTONS_COUNT ?
187
+ <Container spacing="extra-small">
188
+ <Text>
189
+ Page {page} of {pageCount}
190
+ </Text>
191
+ </Container>
192
+ : null}
193
+ {pageCount > MAX_PAGE_BUTTONS_COUNT ?
194
+ <Container align="center" spacing="extra-small">
195
+ <Text>Go to page:</Text>
196
+ <Input
197
+ className="w-12"
198
+ defaultValue={page}
199
+ pattern="[0-9]*"
200
+ type="text"
201
+ onChange={handlePageChange}
164
202
  />
165
- ))
203
+ </Container>
166
204
  : null}
167
-
168
- <Button
169
- aria-label="Next page"
170
- disabled={isLastPage}
171
- variant="outline"
172
- onClick={handleNextPageClick}
173
- >
174
- <Icon name="ChevronRight" />
175
- </Button>
176
- <Button
177
- aria-label="Last page"
178
- disabled={isLastPage}
179
- variant="outline"
180
- onClick={handleLastPageClick}
181
- >
182
- <Icon name="ChevronDoubleRight" />
183
- </Button>
184
- </Container>
185
- {pageCount > MAX_PAGE_BUTTONS_COUNT ?
186
- <Container spacing="extra-small">
187
- <Text>
188
- Page {page} of {pageCount}
189
- </Text>
190
- </Container>
191
- : null}
192
- {pageCount > MAX_PAGE_BUTTONS_COUNT ?
193
- <Container align="center" spacing="extra-small">
194
- <Text>Go to page:</Text>
195
- <Input
196
- className="w-12"
197
- defaultValue={page}
198
- pattern="[0-9]*"
199
- type="text"
200
- onChange={handlePageChange}
201
- />
205
+ <Container>
206
+ <Listbox
207
+ className="w-auto min-w-min"
208
+ value={String(pageSize)}
209
+ onChange={handlePageSizeChange}
210
+ >
211
+ {PAGE_SIZES.map((pageSize) => (
212
+ <ListboxOption key={pageSize} value={String(pageSize)}>
213
+ Show {pageSize}
214
+ </ListboxOption>
215
+ ))}
216
+ </Listbox>
202
217
  </Container>
203
- : null}
204
- <Container>
205
- <Listbox
206
- className="w-auto min-w-min"
207
- value={String(pageSize)}
208
- onChange={handlePageSizeChange}
209
- >
210
- {PAGE_SIZES.map((pageSize) => (
211
- <ListboxOption key={pageSize} value={String(pageSize)}>
212
- Show {pageSize}
213
- </ListboxOption>
214
- ))}
215
- </Listbox>
216
218
  </Container>
217
- </Container>
219
+ </div>
218
220
  );
219
221
  },
220
222
  );
@@ -0,0 +1,40 @@
1
+ import {flexRender, type Row} from '@tanstack/react-table';
2
+ import {useCallback} from 'react';
3
+
4
+ import {TableCell} from '../../TableCell.js';
5
+ import {TableRow} from '../../TableRow.js';
6
+ import {getCommonPinningClasses, getCommonPinningStyles} from '../internals.js';
7
+
8
+ export type DataTableRowProps = {
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
10
+ row: Row<any>;
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
12
+ onClick?: ((row: Row<any>) => void) | undefined;
13
+ };
14
+
15
+ export function DataTableRow({row, onClick}: DataTableRowProps) {
16
+ let handleClick = useCallback(() => {
17
+ onClick?.(row);
18
+ }, [onClick, row]);
19
+
20
+ return (
21
+ <TableRow className={onClick ? 'cursor-pointer' : undefined} onClick={handleClick}>
22
+ {row.getVisibleCells().map((cell) => {
23
+ let value = cell.getValue();
24
+
25
+ return (
26
+ <TableCell
27
+ key={cell.id}
28
+ className={
29
+ getCommonPinningClasses(cell.column) + (onClick ? ' **:pointer-events-none' : '')
30
+ }
31
+ style={{...getCommonPinningStyles(cell.column)}}
32
+ title={value === null || value === undefined ? undefined : String(value)}
33
+ >
34
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
35
+ </TableCell>
36
+ );
37
+ })}
38
+ </TableRow>
39
+ );
40
+ }
@@ -0,0 +1,142 @@
1
+ import {useSortable} from '@dnd-kit/sortable';
2
+ import {CSS} from '@dnd-kit/utilities';
3
+ import {type Column, flexRender, type Header, type Table} from '@tanstack/react-table';
4
+ import {useCallback} from 'react';
5
+
6
+ import {Button} from '../../Button.js';
7
+ import {Checkbox} from '../../Checkbox.js';
8
+ import {CheckboxField} from '../../CheckboxField.js';
9
+ import {Container} from '../../Container.js';
10
+ import {Icon} from '../../Icon.js';
11
+ import {Label} from '../../Label.js';
12
+ import {type DataTableProps} from '../DataTable.js';
13
+
14
+ export type DataTableSettingProps = {
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
16
+ table: Table<any>;
17
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
18
+ column: Column<any>;
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
20
+ hideColumnVisibility: DataTableProps<any, any>['hideColumnVisibility'];
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
22
+ hideColumnOrder: DataTableProps<any, any>['hideColumnOrder'];
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
24
+ hideColumnPinning: DataTableProps<any, any>['hideColumnPinning'];
25
+ };
26
+
27
+ export function DataTableSetting({
28
+ table,
29
+ // header,
30
+ column,
31
+ hideColumnVisibility = false,
32
+ hideColumnOrder = false,
33
+ hideColumnPinning = false,
34
+ }: DataTableSettingProps) {
35
+ let {attributes, isDragging, listeners, setNodeRef, transform, setActivatorNodeRef} = useSortable(
36
+ {
37
+ id: column.id,
38
+ },
39
+ );
40
+
41
+ let handleChange = useCallback(
42
+ (checked: boolean) => {
43
+ if (!checked && table.getFlatHeaders().length >= 2) {
44
+ column.toggleVisibility(checked);
45
+ } else if (checked) {
46
+ column.toggleVisibility(checked);
47
+ }
48
+ },
49
+ [column, table],
50
+ );
51
+
52
+ let handlePinLeftClick = useCallback(() => {
53
+ column.pin('left');
54
+ }, [column]);
55
+
56
+ let handlePinRightClick = useCallback(() => {
57
+ column.pin('right');
58
+ }, [column]);
59
+
60
+ let handleUnpinClick = useCallback(() => {
61
+ column.pin(false);
62
+ }, [column]);
63
+
64
+ let resolvedHideColumnPinning = hideColumnPinning || !column.getCanPin();
65
+
66
+ return (
67
+ <div
68
+ ref={setNodeRef}
69
+ style={{
70
+ transform: CSS.Translate.toString(transform),
71
+ transition: 'width transform 0.2s ease-in-out',
72
+ zIndex: isDragging ? 20 : undefined,
73
+ }}
74
+ className="flex items-center gap-4"
75
+ >
76
+ {hideColumnOrder ? null : (
77
+ <Button
78
+ ref={setActivatorNodeRef}
79
+ aria-label="Resize"
80
+ className="cursor-move"
81
+ size="small"
82
+ variant="invisible"
83
+ {...attributes}
84
+ {...listeners}
85
+ >
86
+ <Icon name="Bars4" size="small" />
87
+ </Button>
88
+ )}
89
+ {hideColumnVisibility ?
90
+ <span className="mr-auto font-sans text-sm font-medium">
91
+ {flexRender(column.columnDef.header, {
92
+ table,
93
+ column,
94
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/consistent-type-assertions -- needed
95
+ header: {column} as Header<any, any>,
96
+ })}
97
+ </span>
98
+ : <CheckboxField className="mr-auto">
99
+ <Checkbox checked={column.getIsVisible()} onChange={handleChange} />
100
+ <Label className="flex">
101
+ {flexRender(column.columnDef.header, {
102
+ table,
103
+ column,
104
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/consistent-type-assertions -- needed
105
+ header: {column} as Header<any, any>,
106
+ })}
107
+ </Label>
108
+ </CheckboxField>
109
+ }
110
+
111
+ {resolvedHideColumnPinning ? null : (
112
+ <Container spacing="extra-small">
113
+ {column.getIsPinned() === 'left' ? null : (
114
+ <Button
115
+ aria-label="Pin to left"
116
+ size="small"
117
+ variant="outline"
118
+ onClick={handlePinLeftClick}
119
+ >
120
+ <Icon name="ArrowLeftEndOnRectangle" size="small" />
121
+ </Button>
122
+ )}
123
+ {column.getIsPinned() ?
124
+ <Button aria-label="Unpin" size="small" variant="outline" onClick={handleUnpinClick}>
125
+ <Icon name="XMark" size="small" />
126
+ </Button>
127
+ : null}
128
+ {column.getIsPinned() === 'right' ? null : (
129
+ <Button
130
+ aria-label="Pin to right"
131
+ size="small"
132
+ variant="outline"
133
+ onClick={handlePinRightClick}
134
+ >
135
+ <Icon name="ArrowRightEndOnRectangle" size="small" />
136
+ </Button>
137
+ )}
138
+ </Container>
139
+ )}
140
+ </div>
141
+ );
142
+ }
@@ -0,0 +1,83 @@
1
+ import {
2
+ closestCenter,
3
+ DndContext,
4
+ type DragEndEvent,
5
+ KeyboardSensor,
6
+ MouseSensor,
7
+ TouchSensor,
8
+ useSensor,
9
+ useSensors,
10
+ } from '@dnd-kit/core';
11
+ import {restrictToVerticalAxis} from '@dnd-kit/modifiers';
12
+ import {arrayMove, SortableContext, verticalListSortingStrategy} from '@dnd-kit/sortable';
13
+ import {type Table} from '@tanstack/react-table';
14
+ import {useCallback, useId} from 'react';
15
+
16
+ import {Container} from '../../Container.js';
17
+ import {type DataTableProps} from '../DataTable.js';
18
+ import {DataTableSetting} from './DataTableSetting.js';
19
+
20
+ export type DataTableSettingsProps = {
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
22
+ table: Table<any>;
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
24
+ hideColumnVisibility: DataTableProps<any, any>['hideColumnVisibility'];
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
26
+ hideColumnOrder: DataTableProps<any, any>['hideColumnOrder'];
27
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- needed
28
+ hideColumnPinning: DataTableProps<any, any>['hideColumnPinning'];
29
+ };
30
+
31
+ export function DataTableSettings({
32
+ table,
33
+ hideColumnVisibility = false,
34
+ hideColumnOrder = false,
35
+ hideColumnPinning = false,
36
+ }: DataTableSettingsProps) {
37
+ let sensors = useSensors(
38
+ useSensor(MouseSensor),
39
+ useSensor(TouchSensor),
40
+ useSensor(KeyboardSensor),
41
+ );
42
+
43
+ let id = useId();
44
+
45
+ let handleDragEnd = useCallback(
46
+ ({active, over}: DragEndEvent) => {
47
+ if (over && active.id !== over.id) {
48
+ table.setColumnOrder((previousColumnOrder) => {
49
+ let oldIndex = previousColumnOrder.indexOf(active.id as string);
50
+ let newIndex = previousColumnOrder.indexOf(over.id as string);
51
+
52
+ return arrayMove(previousColumnOrder, oldIndex, newIndex);
53
+ });
54
+ }
55
+ },
56
+ [table],
57
+ );
58
+
59
+ return (
60
+ <DndContext
61
+ collisionDetection={closestCenter}
62
+ id={id}
63
+ modifiers={[restrictToVerticalAxis]}
64
+ sensors={sensors}
65
+ onDragEnd={handleDragEnd}
66
+ >
67
+ <SortableContext items={table.getState().columnOrder} strategy={verticalListSortingStrategy}>
68
+ <Container direction="column" spacing="small">
69
+ {table.getAllLeafColumns().map((column) => (
70
+ <DataTableSetting
71
+ key={column.id}
72
+ column={column}
73
+ hideColumnOrder={hideColumnOrder}
74
+ hideColumnPinning={hideColumnPinning}
75
+ hideColumnVisibility={hideColumnVisibility}
76
+ table={table}
77
+ />
78
+ ))}
79
+ </Container>
80
+ </SortableContext>
81
+ </DndContext>
82
+ );
83
+ }
@@ -1,3 +1,3 @@
1
1
  export const MAX_PAGE_BUTTONS_COUNT = 10;
2
2
  export const PAGE_SIZES = [10, 25, 50, 75, 100] as const;
3
- export const DEFAULT_PAGE_SIZE = 50;
3
+ export const DEFAULT_PAGE_SIZE = PAGE_SIZES[2];
@@ -1,11 +1,16 @@
1
1
  export * from './internals/addFilter.js';
2
2
  export * from './internals/constants.js';
3
+ export * from './internals/DataTableFilter.js';
4
+ export * from './internals/DataTableFilters.js';
3
5
  export * from './internals/DataTableHeader.js';
4
6
  export * from './internals/DataTableHeaderColumnCheckbox.js';
5
7
  export * from './internals/DataTableHeaderFilter.js';
8
+ export * from './internals/DataTableMenu.js';
6
9
  export * from './internals/DataTablePageButton.js';
7
10
  export * from './internals/DataTablePagination.js';
8
11
  export * from './internals/DataTableSearch.js';
12
+ export * from './internals/DataTableSetting.js';
13
+ export * from './internals/DataTableSettings.js';
9
14
  export * from './internals/fromPinningState.js';
10
15
  export * from './internals/fuzzyFilter.js';
11
16
  export * from './internals/getCommonPinningClasses.js';
@@ -14,6 +14,7 @@ export * from './components/Error.js';
14
14
  export * from './components/Field.js';
15
15
  export * from './components/Fieldset.js';
16
16
  export * from './components/Form.js';
17
+ export * from './components/Heading.js';
17
18
  export * from './components/Icon.js';
18
19
  export * from './components/Input.js';
19
20
  export * from './components/Label.js';
@@ -1,10 +1,10 @@
1
1
  import {type Config as BaseTailwindConfig} from 'tailwindcss';
2
2
  import plugin from 'tailwindcss/plugin';
3
3
 
4
- import {DEFAULT_STOP, type DEFAULT_STOPS} from './internals/constants.js';
5
- import {createPalette} from './internals/createPalette.js';
4
+ import {createTailwindThemeColors} from './internals.js';
5
+ import {type DEFAULT_STOPS} from './internals/constants.js';
6
6
 
7
- let defaultCreateTailwindConfigOptions = {
7
+ export const defaultCreateTailwindConfigOptions = {
8
8
  colors: {
9
9
  gray: '#6c6e79',
10
10
  neutral: '#6c6e79', // copy of "gray"
@@ -55,7 +55,6 @@ let defaultCreateTailwindConfigOptions = {
55
55
  } satisfies CreateTailwindConfigOptions;
56
56
 
57
57
  export type CreateTailwindConfigOptions = {
58
- content?: string[] | undefined;
59
58
  colors?: Record<
60
59
  string,
61
60
  | {hex: string; hueShift?: number; saturationShift?: number}
@@ -75,65 +74,20 @@ export type TailwindConfig = {
75
74
  };
76
75
 
77
76
  export function createTailwindConfig({
78
- content,
79
77
  colors,
80
78
  }: CreateTailwindConfigOptions = defaultCreateTailwindConfigOptions): TailwindConfig {
81
- let themeColors: Record<string, Record<string, string> | string> = {
82
- transparent: 'transparent',
83
- current: 'currentColor',
84
- white: '#fff',
85
- black: '#000',
86
- };
87
-
88
- for (let [name, color] of Object.entries(colors ?? {})) {
89
- if (typeof color === 'string') {
90
- themeColors = {
91
- ...themeColors,
92
- ...createPalette({
93
- name,
94
- swatches: [
95
- {
96
- hex: color,
97
- stop: DEFAULT_STOP,
98
- },
99
- ],
100
- hueShift: 0,
101
- saturationShift: 0,
102
- }),
103
- };
104
- } else if ('swatches' in color) {
105
- themeColors = {
106
- ...themeColors,
107
- ...createPalette({
108
- name,
109
- swatches: color.swatches,
110
- hueShift: color.hueShift ?? 0,
111
- saturationShift: color.saturationShift ?? 0,
112
- }),
113
- };
114
- } else if ('hex' in color) {
115
- themeColors = {
116
- ...themeColors,
117
- ...createPalette({
118
- name,
119
- swatches: [{hex: color.hex, stop: DEFAULT_STOP}],
120
- hueShift: color.hueShift ?? 0,
121
- saturationShift: color.saturationShift ?? 0,
122
- }),
123
- };
124
- }
125
- }
79
+ let themeColors = createTailwindThemeColors(colors);
126
80
 
127
81
  // TODO: find another solution; following is needed because of this: https://github.com/tailwindlabs/tailwindcss/issues/18237
128
82
  let root: Record<string, Record<string, string> | string> = {
129
83
  '--radius-none': '0',
130
- '--radius-0_5': '0.125rem',
131
- '--radius-1': '0.25rem',
132
- '--radius-1_5': '0.375rem',
133
- '--radius-2': '0.5rem',
134
- '--radius-2_5': '0.625rem',
135
- '--radius-3': '0.75rem',
136
- '--radius-4': '1rem',
84
+ '--radius-0_5': '2px',
85
+ '--radius-1': '4px',
86
+ '--radius-1_5': '6px',
87
+ '--radius-2': '8px',
88
+ '--radius-2_5': '10px',
89
+ '--radius-3': '12px',
90
+ '--radius-4': '16px',
137
91
  '--radius-full': '9999px',
138
92
  '--font-sans':
139
93
  'InterVariable, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
@@ -0,0 +1,53 @@
1
+ import {type CreateTailwindConfigOptions} from '../createTailwindConfig.js';
2
+ import {DEFAULT_STOP} from './constants.js';
3
+ import {createPalette} from './createPalette.js';
4
+
5
+ export function createTailwindThemeColors(colors: CreateTailwindConfigOptions['colors']) {
6
+ let themeColors: Record<string, Record<string, string> | string> = {
7
+ transparent: 'transparent',
8
+ current: 'currentColor',
9
+ white: '#fff',
10
+ black: '#000',
11
+ };
12
+
13
+ for (let [name, color] of Object.entries(colors ?? {})) {
14
+ if (typeof color === 'string') {
15
+ themeColors = {
16
+ ...themeColors,
17
+ ...createPalette({
18
+ name,
19
+ swatches: [
20
+ {
21
+ hex: color,
22
+ stop: DEFAULT_STOP,
23
+ },
24
+ ],
25
+ hueShift: 0,
26
+ saturationShift: 0,
27
+ }),
28
+ };
29
+ } else if ('swatches' in color) {
30
+ themeColors = {
31
+ ...themeColors,
32
+ ...createPalette({
33
+ name,
34
+ swatches: color.swatches,
35
+ hueShift: color.hueShift ?? 0,
36
+ saturationShift: color.saturationShift ?? 0,
37
+ }),
38
+ };
39
+ } else if ('hex' in color) {
40
+ themeColors = {
41
+ ...themeColors,
42
+ ...createPalette({
43
+ name,
44
+ swatches: [{hex: color.hex, stop: DEFAULT_STOP}],
45
+ hueShift: color.hueShift ?? 0,
46
+ saturationShift: color.saturationShift ?? 0,
47
+ }),
48
+ };
49
+ }
50
+ }
51
+
52
+ return themeColors;
53
+ }
@@ -6,6 +6,7 @@ export * from './internals/createHueScale.js';
6
6
  export * from './internals/createPalette.js';
7
7
  export * from './internals/createSaturationScale.js';
8
8
  export * from './internals/createSwatches.js';
9
+ export * from './internals/createTailwindThemeColors.js';
9
10
  export * from './internals/hexToHsl.js';
10
11
  export * from './internals/hexToRgb.js';
11
12
  export * from './internals/hslToHex.js';
package/source/styles.css CHANGED
@@ -14,6 +14,10 @@
14
14
  src: url('./inter-variable-italic.woff2') format('woff2');
15
15
  }
16
16
 
17
+ @theme {
18
+ --spacing: 4px;
19
+ }
20
+
17
21
  @layer base {
18
22
  html {
19
23
  font-family: var(--font-sans);
@@ -22,11 +26,23 @@
22
26
 
23
27
  * {
24
28
  scrollbar-color: var(--color-neutral-200) var(--color-transparent);
29
+ outline-color: transparent;
25
30
  }
26
- }
27
31
 
28
- @theme {
29
- --spacing: 4px;
32
+ *:focus {
33
+ outline-style: none;
34
+ outline-width: 0;
35
+ }
36
+
37
+ *:focus-visible {
38
+ outline-style: solid;
39
+ outline-width: 2px;
40
+ outline-offset: calc(var(--spacing) * 0.5);
41
+ outline-color: color-mix(in oklab, var(--color-blue-400) 50%, transparent);
42
+ transition-property: outline-color;
43
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
44
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
45
+ }
30
46
  }
31
47
 
32
48
  @source "./";
@@ -15,6 +15,7 @@ import {type useErrorTheme} from '../components/Error.js';
15
15
  import {type useFieldTheme} from '../components/Field.js';
16
16
  import {type useFieldsetTheme} from '../components/Fieldset.js';
17
17
  import {type useFormTheme} from '../components/Form.js';
18
+ import {type useHeadingTheme} from '../components/Heading.js';
18
19
  import {type useIconTheme} from '../components/Icon.js';
19
20
  import {type useInputTheme} from '../components/Input.js';
20
21
  import {type useLabelTheme} from '../components/Label.js';
@@ -65,6 +66,7 @@ export type Theme = Simplify<
65
66
  ComponentTheme<typeof useFieldsetTheme, {outputComponentName: true}> &
66
67
  ComponentTheme<typeof useFieldTheme, {outputComponentName: true}> &
67
68
  ComponentTheme<typeof useFormTheme, {outputComponentName: true}> &
69
+ ComponentTheme<typeof useHeadingTheme, {outputComponentName: true}> &
68
70
  ComponentTheme<typeof useIconTheme, {outputComponentName: true}> &
69
71
  ComponentTheme<typeof useInputTheme, {outputComponentName: true}> &
70
72
  ComponentTheme<typeof useLabelTheme, {outputComponentName: true}> &