@idealyst/components 1.2.142 → 1.2.144

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idealyst/components",
3
- "version": "1.2.142",
3
+ "version": "1.2.144",
4
4
  "description": "Shared component library for React and React Native",
5
5
  "documentation": "https://github.com/IdealystIO/idealyst-framework/tree/main/packages/components#readme",
6
6
  "readme": "README.md",
@@ -56,7 +56,7 @@
56
56
  "publish:npm": "npm publish"
57
57
  },
58
58
  "peerDependencies": {
59
- "@idealyst/theme": "^1.2.142",
59
+ "@idealyst/theme": "^1.2.144",
60
60
  "@mdi/js": ">=7.0.0",
61
61
  "@mdi/react": ">=1.0.0",
62
62
  "@react-native-vector-icons/common": ">=12.0.0",
@@ -111,8 +111,8 @@
111
111
  },
112
112
  "devDependencies": {
113
113
  "@idealyst/blur": "^1.2.40",
114
- "@idealyst/theme": "^1.2.142",
115
- "@idealyst/tooling": "^1.2.142",
114
+ "@idealyst/theme": "^1.2.144",
115
+ "@idealyst/tooling": "^1.2.144",
116
116
  "@mdi/react": "^1.6.1",
117
117
  "@types/react": "^19.1.0",
118
118
  "react": "^19.1.0",
@@ -49,6 +49,7 @@ export const switchStyles = defineStyle('Switch', (theme: Theme) => ({
49
49
 
50
50
  switchContainer: (_props: SwitchDynamicProps) => ({
51
51
  justifyContent: 'center' as const,
52
+ alignItems: 'center' as const,
52
53
  variants: {
53
54
  disabled: {
54
55
  true: { _web: { cursor: 'not-allowed' } },
@@ -56,10 +57,12 @@ export const switchStyles = defineStyle('Switch', (theme: Theme) => ({
56
57
  },
57
58
  },
58
59
  _web: {
60
+ display: 'inline-flex',
59
61
  border: 'none',
60
62
  padding: 0,
61
63
  backgroundColor: 'transparent',
62
64
  width: 'fit-content',
65
+ verticalAlign: 'middle',
63
66
  },
64
67
  }),
65
68
 
@@ -13,6 +13,8 @@ interface TRProps {
13
13
  size?: TableSizeVariant;
14
14
  type?: TableType;
15
15
  clickable?: boolean;
16
+ dividers?: boolean;
17
+ even?: boolean;
16
18
  onPress?: () => void;
17
19
  testID?: string;
18
20
  }
@@ -42,6 +44,8 @@ function TR({
42
44
  size = 'md',
43
45
  type = 'standard',
44
46
  clickable = false,
47
+ dividers = false,
48
+ even = false,
45
49
  onPress,
46
50
  testID,
47
51
  }: TRProps) {
@@ -49,6 +53,8 @@ function TR({
49
53
  size,
50
54
  type,
51
55
  clickable,
56
+ dividers,
57
+ even,
52
58
  });
53
59
 
54
60
  const rowStyle = (tableStyles.row as any)({});
@@ -187,6 +193,7 @@ function TableInner<T = any>({
187
193
  size = 'md',
188
194
  stickyHeader: _stickyHeader = false,
189
195
  onRowPress,
196
+ dividers = false,
190
197
  emptyState,
191
198
  // Spacing variants from ContainerStyleProps
192
199
  gap,
@@ -289,6 +296,8 @@ function TableInner<T = any>({
289
296
  size={size}
290
297
  type={type}
291
298
  clickable={isClickable}
299
+ dividers={dividers && rowIndex < data.length - 1}
300
+ even={rowIndex % 2 === 1}
292
301
  onPress={() => onRowPress?.(row, rowIndex)}
293
302
  testID={testID ? `${testID}-row-${rowIndex}` : undefined}
294
303
  >
@@ -12,13 +12,15 @@ void StyleSheet;
12
12
  // Wrap theme for $iterator support
13
13
  type Theme = ThemeStyleWrapper<BaseTheme>;
14
14
 
15
- type TableType = 'standard' | 'bordered' | 'striped';
15
+ type TableType = 'standard' | 'striped';
16
16
  type CellAlign = 'left' | 'center' | 'right';
17
17
 
18
18
  export type TableDynamicProps = {
19
19
  size?: Size;
20
20
  type?: TableType;
21
21
  clickable?: boolean;
22
+ dividers?: boolean;
23
+ even?: boolean;
22
24
  sticky?: boolean;
23
25
  align?: CellAlign;
24
26
  gap?: ViewStyleSize;
@@ -92,70 +94,72 @@ export const tableStyles = defineStyle('Table', (theme: Theme) => ({
92
94
  backgroundColor: theme.colors.surface.secondary,
93
95
  }),
94
96
 
95
- footerCell: ({ type = 'standard', align = 'left' }: TableDynamicProps) => {
96
- const alignStyles = {
97
- left: { textAlign: 'left' as const, justifyContent: 'flex-start' as const },
98
- center: { textAlign: 'center' as const, justifyContent: 'center' as const },
99
- right: { textAlign: 'right' as const, justifyContent: 'flex-end' as const },
100
- }[align];
101
-
102
- const borderStyles = type === 'bordered' ? {
103
- borderRightWidth: 1,
104
- borderRightColor: theme.colors.border.primary,
105
- } : {};
97
+ footerCell: (_props: TableDynamicProps) => ({
98
+ flexDirection: 'row' as const,
99
+ alignItems: 'center' as const,
100
+ fontWeight: '600' as const,
101
+ color: theme.colors.text.primary,
102
+ borderTopWidth: 1,
103
+ borderTopColor: theme.colors.border.primary,
104
+ variants: {
105
+ align: {
106
+ left: { textAlign: 'left' as const, justifyContent: 'flex-start' as const },
107
+ center: { textAlign: 'center' as const, justifyContent: 'center' as const },
108
+ right: { textAlign: 'right' as const, justifyContent: 'flex-end' as const },
109
+ },
110
+ size: {
111
+ padding: theme.sizes.$table.padding,
112
+ fontSize: theme.sizes.$table.headerFontSize,
113
+ lineHeight: theme.sizes.$table.headerLineHeight,
114
+ },
115
+ },
116
+ _web: {
117
+ borderTop: `1px solid ${theme.colors.border.primary}`,
118
+ },
119
+ }),
106
120
 
107
- return {
108
- flexDirection: 'row' as const,
109
- alignItems: 'center' as const,
110
- fontWeight: '600' as const,
111
- color: theme.colors.text.primary,
112
- borderTopWidth: 2,
113
- borderTopColor: theme.colors.border.primary,
114
- ...alignStyles,
115
- ...borderStyles,
116
- variants: {
117
- size: {
118
- padding: theme.sizes.$table.padding,
119
- fontSize: theme.sizes.$table.fontSize,
120
- lineHeight: theme.sizes.$table.lineHeight,
121
+ row: (_props: TableDynamicProps) => ({
122
+ variants: {
123
+ type: {
124
+ striped: {
125
+ _web: {
126
+ ':nth-child(even)': {
127
+ backgroundColor: theme.colors.surface.secondary,
128
+ },
129
+ },
121
130
  },
122
131
  },
123
- _web: {
124
- borderTop: `2px solid ${theme.colors.border.primary}`,
125
- borderRight: type === 'bordered' ? `1px solid ${theme.colors.border.primary}` : undefined,
126
- ':last-child': type === 'bordered' ? { borderRight: 'none' } : {},
132
+ clickable: {
133
+ true: { _web: { cursor: 'pointer' } },
127
134
  },
128
- } as const;
129
- },
130
-
131
- row: ({ type = 'standard', clickable = false }: TableDynamicProps) => {
132
- const typeStyles = type === 'bordered' || type === 'striped' ? {
133
- borderBottomWidth: 1,
134
- borderBottomColor: theme.colors.border.primary,
135
- } : {};
136
-
137
- return {
138
- ...typeStyles,
139
- _web: {
140
- transition: 'background-color 0.15s ease',
141
- borderBottom: (type === 'bordered' || type === 'striped')
142
- ? `1px solid ${theme.colors.border.primary}`
143
- : undefined,
144
- cursor: clickable ? 'pointer' : undefined,
145
- _hover: {
135
+ dividers: {
136
+ true: {
137
+ borderBottomWidth: 1,
138
+ borderBottomColor: theme.colors.border.primary,
139
+ _web: {
140
+ borderBottom: `1px solid ${theme.colors.border.primary}`,
141
+ },
142
+ },
143
+ },
144
+ },
145
+ compoundVariants: [
146
+ {
147
+ type: 'striped',
148
+ even: true,
149
+ styles: {
146
150
  backgroundColor: theme.colors.surface.secondary,
147
151
  },
148
- // Striped rows handled via CSS pseudo-selector
149
- ...(type === 'striped' ? {
150
- ':nth-child(even)': {
151
- backgroundColor: theme.colors.surface.secondary,
152
- },
153
- } : {}),
154
152
  },
155
- } as const;
156
- },
153
+ ],
154
+ _web: {
155
+ transition: 'background-color 0.15s ease',
156
+ _hover: {
157
+ backgroundColor: theme.colors.surface.hover,
158
+ },
159
+ },
160
+ }),
157
161
 
158
- headerCell: ({ type = 'standard', align: _align = 'left' }: TableDynamicProps) => ({
162
+ headerCell: (_props: TableDynamicProps) => ({
159
163
  flexDirection: 'row' as const,
160
164
  alignItems: 'center' as const,
161
165
  fontWeight: '600' as const,
@@ -163,9 +167,6 @@ export const tableStyles = defineStyle('Table', (theme: Theme) => ({
163
167
  borderBottomWidth: 1,
164
168
  borderBottomColor: theme.colors.border.primary,
165
169
  variants: {
166
- type: {
167
- bordered: { borderRightWidth: 1, borderRightColor: theme.colors.border.primary },
168
- },
169
170
  align: {
170
171
  left: { textAlign: 'left' as const, justifyContent: 'flex-start' as const },
171
172
  center: { textAlign: 'center' as const, justifyContent: 'center' as const },
@@ -173,47 +174,31 @@ export const tableStyles = defineStyle('Table', (theme: Theme) => ({
173
174
  },
174
175
  size: {
175
176
  padding: theme.sizes.$table.padding,
176
- fontSize: theme.sizes.$table.fontSize,
177
- lineHeight: theme.sizes.$table.lineHeight,
177
+ fontSize: theme.sizes.$table.headerFontSize,
178
+ lineHeight: theme.sizes.$table.headerLineHeight,
178
179
  },
179
180
  },
180
181
  _web: {
181
182
  position: 'relative',
182
- borderBottom: `2px solid ${theme.colors.border.primary}`,
183
- borderRight: type === 'bordered' ? `1px solid ${theme.colors.border.primary}` : undefined,
184
- ':last-child': type === 'bordered' ? { borderRight: 'none' } : {},
183
+ borderBottom: `1px solid ${theme.colors.border.primary}`,
185
184
  },
186
185
  }),
187
186
 
188
- cell: ({ type = 'standard', align = 'left' }: TableDynamicProps) => {
189
- const alignStyles = {
190
- left: { textAlign: 'left' as const, justifyContent: 'flex-start' as const },
191
- center: { textAlign: 'center' as const, justifyContent: 'center' as const },
192
- right: { textAlign: 'right' as const, justifyContent: 'flex-end' as const },
193
- }[align];
194
-
195
- const borderStyles = type === 'bordered' ? {
196
- borderRightWidth: 1,
197
- borderRightColor: theme.colors.border.primary,
198
- } : {};
199
-
200
- return {
201
- flexDirection: 'row' as const,
202
- alignItems: 'center' as const,
203
- color: theme.colors.text.primary,
204
- ...alignStyles,
205
- ...borderStyles,
206
- variants: {
207
- size: {
208
- padding: theme.sizes.$table.padding,
209
- fontSize: theme.sizes.$table.fontSize,
210
- lineHeight: theme.sizes.$table.lineHeight,
211
- },
187
+ cell: (_props: TableDynamicProps) => ({
188
+ flexDirection: 'row' as const,
189
+ alignItems: 'center' as const,
190
+ color: theme.colors.text.primary,
191
+ variants: {
192
+ align: {
193
+ left: { textAlign: 'left' as const, justifyContent: 'flex-start' as const },
194
+ center: { textAlign: 'center' as const, justifyContent: 'center' as const },
195
+ right: { textAlign: 'right' as const, justifyContent: 'flex-end' as const },
212
196
  },
213
- _web: {
214
- borderRight: type === 'bordered' ? `1px solid ${theme.colors.border.primary}` : undefined,
215
- ':last-child': type === 'bordered' ? { borderRight: 'none' } : {},
197
+ size: {
198
+ padding: theme.sizes.$table.padding,
199
+ fontSize: theme.sizes.$table.fontSize,
200
+ lineHeight: theme.sizes.$table.lineHeight,
216
201
  },
217
- } as const;
218
- },
202
+ },
203
+ }),
219
204
  }));
@@ -32,6 +32,7 @@ interface TRProps {
32
32
  size?: TableSizeVariant;
33
33
  type?: TableType;
34
34
  clickable?: boolean;
35
+ dividers?: boolean;
35
36
  onClick?: () => void;
36
37
  testID?: string;
37
38
  }
@@ -69,6 +70,7 @@ function TR({
69
70
  size = 'md',
70
71
  type = 'standard',
71
72
  clickable = false,
73
+ dividers = false,
72
74
  onClick,
73
75
  testID,
74
76
  }: TRProps) {
@@ -76,6 +78,7 @@ function TR({
76
78
  size,
77
79
  type,
78
80
  clickable,
81
+ dividers,
79
82
  });
80
83
 
81
84
  const rowProps = getWebProps([(tableStyles.row as any)({})]);
@@ -263,6 +266,7 @@ function Table<T = any>({
263
266
  stickyHeader = false,
264
267
  onRowPress,
265
268
  onColumnResize,
269
+ dividers = false,
266
270
  emptyState,
267
271
  // Spacing variants from ContainerStyleProps
268
272
  gap,
@@ -394,6 +398,7 @@ function Table<T = any>({
394
398
  size={size}
395
399
  type={type}
396
400
  clickable={isClickable}
401
+ dividers={dividers && rowIndex < data.length - 1}
397
402
  onClick={() => onRowPress?.(row, rowIndex)}
398
403
  testID={testID ? `${testID}-row-${rowIndex}` : undefined}
399
404
  >
@@ -6,7 +6,7 @@ import { AccessibilityProps, SortableAccessibilityProps } from '../utils/accessi
6
6
 
7
7
  // Component-specific type aliases for future extensibility
8
8
  export type TableSizeVariant = Size;
9
- export type TableType = 'standard' | 'bordered' | 'striped';
9
+ export type TableType = 'standard' | 'striped';
10
10
  export type TableAlignVariant = 'left' | 'center' | 'right';
11
11
 
12
12
  export interface TableColumn<T = any> extends SortableAccessibilityProps {
@@ -47,6 +47,11 @@ export interface TableProps<T = any> extends ContainerStyleProps, AccessibilityP
47
47
  type?: TableType;
48
48
  size?: TableSizeVariant;
49
49
  stickyHeader?: boolean;
50
+ /**
51
+ * Show dividers (horizontal borders) between rows.
52
+ * Works with any table `type`.
53
+ */
54
+ dividers?: boolean;
50
55
  onRowPress?: (row: T, index: number) => void;
51
56
  /**
52
57
  * Called when a column is resized via drag handle.
@@ -156,19 +156,34 @@ export const TableExamples: React.FC = () => {
156
156
  />
157
157
  </View>
158
158
  <View gap="xs">
159
- <Text typography="body2">Bordered</Text>
159
+ <Text typography="body2">Striped</Text>
160
+ <Table
161
+ columns={userColumns}
162
+ data={users}
163
+ type="striped"
164
+ />
165
+ </View>
166
+ </View>
167
+ </View>
168
+
169
+ <View gap="md">
170
+ <Text typography="h5">With Dividers</Text>
171
+ <View gap="sm">
172
+ <View gap="xs">
173
+ <Text typography="body2">Standard + Dividers</Text>
160
174
  <Table
161
175
  columns={userColumns}
162
176
  data={users}
163
- type="bordered"
177
+ dividers
164
178
  />
165
179
  </View>
166
180
  <View gap="xs">
167
- <Text typography="body2">Striped</Text>
181
+ <Text typography="body2">Striped + Dividers</Text>
168
182
  <Table
169
183
  columns={userColumns}
170
184
  data={users}
171
185
  type="striped"
186
+ dividers
172
187
  />
173
188
  </View>
174
189
  </View>
@@ -183,7 +198,7 @@ export const TableExamples: React.FC = () => {
183
198
  columns={userColumns}
184
199
  data={users.slice(0, 2)}
185
200
  size="sm"
186
- type="bordered"
201
+ dividers
187
202
  />
188
203
  </View>
189
204
  <View gap="xs">
@@ -192,7 +207,7 @@ export const TableExamples: React.FC = () => {
192
207
  columns={userColumns}
193
208
  data={users.slice(0, 2)}
194
209
  size="md"
195
- type="bordered"
210
+ dividers
196
211
  />
197
212
  </View>
198
213
  <View gap="xs">
@@ -201,7 +216,7 @@ export const TableExamples: React.FC = () => {
201
216
  columns={userColumns}
202
217
  data={users.slice(0, 2)}
203
218
  size="lg"
204
- type="bordered"
219
+ dividers
205
220
  />
206
221
  </View>
207
222
  </View>