react-better-html 1.1.68 → 1.1.69

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.
@@ -14,6 +14,6 @@ function PageHeader({ imageUrl, imageSize = 60, title, titleAs, titleRightElemen
14
14
  const theme = (0, BetterHtmlProvider_1.useTheme)();
15
15
  const { app } = (0, BetterHtmlProvider_1.useBetterHtmlContext)();
16
16
  const mediaQuery = (0, hooks_1.useMediaQuery)();
17
- return ((0, jsx_runtime_1.jsxs)(Div_1.default.row, { alignItems: "center", gap: theme.styles.space, marginBottom: marginBottom ?? theme.styles.space * 2, children: [imageUrl && (0, jsx_runtime_1.jsx)(Image_1.default.profileImage, { src: imageUrl, size: imageSize ?? (mediaQuery.size600 ? 46 : 60) }), (0, jsx_runtime_1.jsxs)(Div_1.default.column, { flex: 1, gap: theme.styles.gap / 2, children: [(0, jsx_runtime_1.jsxs)(Div_1.default.row, { alignItems: "center", justifyContent: textAlign === "center" ? "center" : textAlign === "right" ? "flex-end" : undefined, gap: theme.styles.space, children: [(0, jsx_runtime_1.jsx)(Text_1.default, { as: titleAs ?? "h1", textAlign: textAlign, color: lightMode ? theme.colors.base : theme.colors.textPrimary, children: title }), titleRightElement] }), description && ((0, jsx_runtime_1.jsx)(Text_1.default, { maxWidth: !mediaQuery.size600 ? app.contentMaxWidth * 0.6 : undefined, textAlign: textAlign, color: lightMode ? theme.colors.base : theme.colors.textSecondary, opacity: lightMode ? 0.7 : undefined, children: description }))] }), rightElement] }));
17
+ return ((0, jsx_runtime_1.jsxs)(Div_1.default.row, { alignItems: "center", gap: theme.styles.space, marginBottom: marginBottom ?? theme.styles.space * 2, children: [imageUrl && (0, jsx_runtime_1.jsx)(Image_1.default.profileImage, { src: imageUrl, size: imageSize ?? (mediaQuery.size600 ? 46 : 60) }), (0, jsx_runtime_1.jsxs)(Div_1.default.column, { justifyContent: textAlign === "center" ? "center" : textAlign === "right" ? "flex-end" : undefined, flex: 1, gap: theme.styles.gap / 2, children: [(0, jsx_runtime_1.jsxs)(Div_1.default.row, { alignItems: "center", justifyContent: textAlign === "center" ? "center" : textAlign === "right" ? "flex-end" : undefined, gap: theme.styles.space, children: [(0, jsx_runtime_1.jsx)(Text_1.default, { as: titleAs ?? "h1", textAlign: textAlign, color: lightMode ? theme.colors.base : theme.colors.textPrimary, children: title }), titleRightElement] }), description && ((0, jsx_runtime_1.jsx)(Text_1.default, { maxWidth: !mediaQuery.size600 ? app.contentMaxWidth * 0.6 : undefined, textAlign: textAlign, color: lightMode ? theme.colors.base : theme.colors.textSecondary, opacity: lightMode ? 0.7 : undefined, children: description }))] }), rightElement] }));
18
18
  }
19
19
  exports.default = (0, react_1.memo)(PageHeader);
@@ -4,26 +4,27 @@ import { ToggleInputProps } from "./ToggleInput";
4
4
  import { ImageProps } from "./Image";
5
5
  type TextColumn<DataItem> = {
6
6
  type: "text";
7
- keyName: keyof DataItem;
8
- format?: (value: any) => string;
7
+ keyName?: keyof DataItem;
8
+ format?: (item: DataItem, index: number) => string;
9
9
  };
10
10
  type ElementColumn<DataItem> = {
11
11
  type: "element";
12
- render: (item: DataItem, index: number) => ReactNode;
12
+ render?: (item: DataItem, index: number) => ReactNode;
13
13
  };
14
14
  type ImageColumn<DataItem> = {
15
15
  type: "image";
16
16
  keyName?: keyof DataItem;
17
17
  } & ImageProps;
18
- type CheckboxColumn<DataItem> = {
18
+ type CheckboxColumn = {
19
19
  type: "checkbox";
20
- keyName?: keyof DataItem;
21
20
  } & ToggleInputProps<boolean>;
22
21
  export type TableColumn<DataItem> = {
23
22
  label?: string;
24
23
  width?: string | number;
24
+ minWidth?: string | number;
25
+ maxWidth?: string | number;
25
26
  align?: "left" | "center" | "right";
26
- } & (TextColumn<DataItem> | ElementColumn<DataItem> | ImageColumn<DataItem> | CheckboxColumn<DataItem>);
27
+ } & (TextColumn<DataItem> | ElementColumn<DataItem> | ImageColumn<DataItem> | CheckboxColumn);
27
28
  export type TableProps<DataItem> = {
28
29
  columns: TableColumn<DataItem>[];
29
30
  data: DataItem[];
@@ -34,7 +35,7 @@ export type TableProps<DataItem> = {
34
35
  /** @default "No data available" */
35
36
  noDataItemsMessage?: string;
36
37
  onClickRow?: (item: DataItem, index: number) => void;
37
- onClickAllCheckboxes?: () => void;
38
+ onClickAllCheckboxes?: (checked: boolean) => void;
38
39
  } & ComponentMarginProps;
39
40
  type TableComponentType = {
40
41
  <DataItem>(props: ComponentPropWithRef<HTMLDivElement, TableProps<DataItem>>): React.ReactElement;
@@ -100,9 +100,11 @@ const TableStyledComponent = styled_components_1.default.table.withConfig({
100
100
  }
101
101
  `;
102
102
  const ThStyledComponent = styled_components_1.default.th.withConfig({
103
- shouldForwardProp: (prop) => !["width", "textAlign"].includes(prop),
103
+ shouldForwardProp: (prop) => !["width", "minWidth", "maxWidth", "textAlign"].includes(prop),
104
104
  }) `
105
105
  ${(props) => (props.width ? `width: ${props.width}px;` : "")}
106
+ ${(props) => (props.minWidth ? `min-width: ${props.minWidth}px;` : "")}
107
+ ${(props) => (props.maxWidth ? `max-width: ${props.maxWidth}px;` : "")}
106
108
  ${(props) => (props.textAlign ? `text-align: ${props.textAlign} !important;` : "")}
107
109
  `;
108
110
  const TdStyledComponent = styled_components_1.default.td.withConfig({
@@ -112,14 +114,15 @@ const TdStyledComponent = styled_components_1.default.td.withConfig({
112
114
  `;
113
115
  const TableComponent = (0, react_1.forwardRef)(function Table({ columns, data, isStriped, withStickyHeader, noDataItemsMessage = "No data available", onClickRow, onClickAllCheckboxes, ...props }, ref) {
114
116
  const theme = (0, BetterHtmlProvider_1.useTheme)();
117
+ const [checkedItems, setCheckedItems] = (0, react_1.useState)([]);
115
118
  const renderCellContent = (0, react_1.useCallback)((column, item, index) => {
116
119
  switch (column.type) {
117
120
  case "text": {
118
- const value = item[column.keyName];
119
- return column.format ? column.format(value) : String(value ?? "");
121
+ const value = column.keyName ? item[column.keyName] : undefined;
122
+ return column.format ? column.format(item, index) : String(value ?? "");
120
123
  }
121
124
  case "element": {
122
- return column.render(item, index);
125
+ return column.render?.(item, index) ?? (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
123
126
  }
124
127
  case "image": {
125
128
  const { type, keyName, ...props } = column;
@@ -127,28 +130,30 @@ const TableComponent = (0, react_1.forwardRef)(function Table({ columns, data, i
127
130
  return ((0, jsx_runtime_1.jsx)(Image_1.default, { src: src, width: defaultImageWidth, borderRadius: theme.styles.borderRadius / 2, ...props }));
128
131
  }
129
132
  case "checkbox": {
130
- const { type, keyName, ...props } = column;
131
- const checked = keyName ? item[keyName] : false;
132
- return (0, jsx_runtime_1.jsx)(ToggleInput_1.default.checkbox, { checked: checked, ...props });
133
+ const { type, onChange, ...props } = column;
134
+ const checkedValue = checkedItems[index];
135
+ return ((0, jsx_runtime_1.jsx)(ToggleInput_1.default.checkbox, { checked: checkedValue, onChange: (checked, value) => {
136
+ setCheckedItems((oldValue) => oldValue.map((isChecked, internalIndex) => (internalIndex === index ? checked : isChecked)));
137
+ onChange?.(checked, value);
138
+ }, ...props }));
133
139
  }
134
140
  default: {
135
141
  return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
136
142
  }
137
143
  }
138
- }, [theme]);
144
+ }, [theme, checkedItems]);
139
145
  const onClickRowElement = (0, react_1.useCallback)((item, index) => {
140
146
  onClickRow?.(item, index);
141
147
  }, [onClickRow]);
148
+ const onClickAllCheckboxesElement = (0, react_1.useCallback)((checked) => {
149
+ onClickAllCheckboxes?.(checked);
150
+ setCheckedItems(data.map(() => checked));
151
+ }, [onClickAllCheckboxes, data]);
142
152
  const everythingIsChecked = (0, react_1.useMemo)(() => {
143
- if (!columns.some((column) => column.type === "checkbox"))
144
- return false;
145
- const keyName = columns.find((column) => column.type === "checkbox")?.keyName;
146
- if (!keyName)
147
- return false;
148
- return data.every((item) => item[keyName]);
149
- }, [data]);
150
- return ((0, jsx_runtime_1.jsx)(Div_1.default, { border: `1px solid ${theme.colors.border}`, borderRadius: theme.styles.borderRadius * 2, overflow: "auto", ...props, ref: ref, children: (0, jsx_runtime_1.jsxs)(TableStyledComponent, { isStriped: isStriped, withHover: onClickRow !== undefined, withStickyHeader: withStickyHeader, theme: theme, children: [(0, jsx_runtime_1.jsx)("thead", { children: (0, jsx_runtime_1.jsx)("tr", { className: "isHeader", children: columns.map((column, index) => ((0, jsx_runtime_1.jsx)(ThStyledComponent, { width: column.type === "image" ? defaultImageWidth : column.type === "checkbox" ? 26 : column.width, textAlign: column.align, children: column.label ??
151
- (column.type === "checkbox" && onClickAllCheckboxes ? ((0, jsx_runtime_1.jsx)(ToggleInput_1.default.checkbox, { checked: everythingIsChecked, onChange: onClickAllCheckboxes })) : ("")) }, column.type + column.label + index))) }) }), (0, jsx_runtime_1.jsx)("tbody", { children: data.length > 0 ? (data.map((item, rowIndex) => ((0, jsx_runtime_1.jsx)("tr", { className: onClickRow ? "isClickable" : undefined, onClick: () => onClickRowElement(item, rowIndex), children: columns.map((column, colIndex) => ((0, jsx_runtime_1.jsx)(TdStyledComponent, { textAlign: column.align, children: renderCellContent(column, item, rowIndex) }, column.type + column.label + colIndex))) }, JSON.stringify(item) + rowIndex)))) : ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", { className: "noData", colSpan: columns.length, children: (0, jsx_runtime_1.jsx)(Text_1.default.unknown, { children: noDataItemsMessage }) }) })) })] }) }));
153
+ return checkedItems.every((checked) => checked) && checkedItems.length === data.length;
154
+ }, [data, checkedItems]);
155
+ return ((0, jsx_runtime_1.jsx)(Div_1.default, { border: `1px solid ${theme.colors.border}`, borderRadius: theme.styles.borderRadius * 2, overflow: "auto", ...props, ref: ref, children: (0, jsx_runtime_1.jsxs)(TableStyledComponent, { isStriped: isStriped, withHover: onClickRow !== undefined, withStickyHeader: withStickyHeader, theme: theme, children: [(0, jsx_runtime_1.jsx)("thead", { children: (0, jsx_runtime_1.jsx)("tr", { className: "isHeader", children: columns.map((column, index) => ((0, jsx_runtime_1.jsx)(ThStyledComponent, { width: column.type === "image" ? defaultImageWidth : column.type === "checkbox" ? 26 : column.width, minWidth: column.minWidth, maxWidth: column.maxWidth, textAlign: column.align, children: column.label ??
156
+ (column.type === "checkbox" && onClickAllCheckboxes ? ((0, jsx_runtime_1.jsx)(ToggleInput_1.default.checkbox, { checked: everythingIsChecked, onChange: onClickAllCheckboxesElement })) : ("")) }, column.type + column.label + index))) }) }), (0, jsx_runtime_1.jsx)("tbody", { children: data.length > 0 ? (data.map((item, rowIndex) => ((0, jsx_runtime_1.jsx)("tr", { className: onClickRow ? "isClickable" : undefined, onClick: () => onClickRowElement(item, rowIndex), children: columns.map((column, colIndex) => ((0, jsx_runtime_1.jsx)(TdStyledComponent, { textAlign: column.align, children: renderCellContent(column, item, rowIndex) }, column.type + column.label + colIndex))) }, JSON.stringify(item) + rowIndex)))) : ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", { className: "noData", colSpan: columns.length, children: (0, jsx_runtime_1.jsx)(Text_1.default.unknown, { children: noDataItemsMessage }) }) })) })] }) }));
152
157
  });
153
158
  const Table = (0, react_1.memo)(TableComponent);
154
159
  exports.default = Table;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-better-html",
3
- "version": "1.1.68",
3
+ "version": "1.1.69",
4
4
  "description": "A component library for react that is as close to plane html as possible",
5
5
  "main": "dist/index.js",
6
6
  "files": [