@etsoo/materialui 1.2.48 → 1.2.50

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/lib/DnDList.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { UniqueIdentifier } from "@dnd-kit/core";
1
+ import type { UniqueIdentifier } from "@dnd-kit/core";
2
2
  import { DataTypes } from "@etsoo/shared";
3
3
  import { Theme } from "@mui/material";
4
4
  import React, { CSSProperties } from "react";
@@ -56,6 +56,10 @@ export interface DnDListPros<D extends object, K extends DataTypes.Keys<D>> {
56
56
  * Item renderer
57
57
  */
58
58
  itemRenderer: (item: D, index: number, nodeRef: React.ComponentProps<any>, actionNodeRef: React.ComponentProps<any>) => React.ReactElement;
59
+ /**
60
+ * Height
61
+ */
62
+ height?: string | number;
59
63
  /**
60
64
  * List items
61
65
  */
package/lib/DnDList.js CHANGED
@@ -1,16 +1,13 @@
1
- import { DndContext } from "@dnd-kit/core";
2
- import { SortableContext, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
3
- import { CSS } from "@dnd-kit/utilities";
4
- import { useTheme } from "@mui/material";
1
+ import { Skeleton, useTheme } from "@mui/material";
5
2
  import React from "react";
6
3
  function SortableItem(props) {
7
4
  // Destruct
8
- const { id, itemRenderer, style = {} } = props;
5
+ const { id, useSortableType, CSSType, itemRenderer, style = {} } = props;
9
6
  // Use sortable
10
- const { attributes, listeners, setNodeRef, transform, transition, setActivatorNodeRef } = useSortable({ id });
7
+ const { attributes, listeners, setNodeRef, transform, transition, setActivatorNodeRef } = useSortableType({ id });
11
8
  const allStyle = {
12
9
  ...style,
13
- transform: CSS.Transform.toString(transform),
10
+ transform: CSSType.Transform.toString(transform),
14
11
  transition
15
12
  };
16
13
  const nodeRef = {
@@ -47,52 +44,27 @@ export const DnDItemStyle = (index, isDragging, theme) => ({
47
44
  */
48
45
  export function DnDList(props) {
49
46
  // Destruct
50
- const { keyField, itemRenderer, labelField, mRef, onChange, onFormChange, onDragEnd } = props;
51
- let getItemStyle = props.getItemStyle;
52
- if (getItemStyle == null) {
53
- // Theme
54
- const theme = useTheme();
55
- getItemStyle = (index, isDragging) => DnDItemStyle(index, isDragging, theme);
56
- }
47
+ const { keyField, height = 360, itemRenderer, labelField, mRef, onChange, onFormChange, onDragEnd } = props;
48
+ // Theme
49
+ const theme = useTheme();
57
50
  // States
58
51
  const [items, setItems] = React.useState([]);
59
52
  const [activeId, setActiveId] = React.useState();
60
- const doFormChange = (newItems) => {
53
+ React.useEffect(() => {
54
+ setItems(props.items);
55
+ }, [props.items]);
56
+ const doFormChange = React.useCallback((newItems) => {
61
57
  if (onFormChange)
62
58
  onFormChange(newItems !== null && newItems !== void 0 ? newItems : items);
63
- };
64
- const changeItems = (newItems) => {
59
+ }, [items, onFormChange]);
60
+ const changeItems = React.useCallback((newItems) => {
65
61
  // Possible to alter items with the handler
66
62
  if (onChange)
67
63
  onChange(newItems);
68
64
  doFormChange(newItems);
69
65
  // Update state
70
66
  setItems(newItems);
71
- };
72
- // Drag event handlers
73
- function handleDragStart(event) {
74
- const { active } = event;
75
- setActiveId(active.id);
76
- }
77
- function handleDragEnd(event) {
78
- const { active, over } = event;
79
- if (over && active.id !== over.id) {
80
- // Indices
81
- const oldIndex = items.findIndex((item) => item.id === active.id);
82
- const newIndex = items.findIndex((item) => item.id === over.id);
83
- // Clone
84
- const newItems = [...items];
85
- // Removed item
86
- const [removed] = newItems.splice(oldIndex, 1);
87
- // Insert to the destination index
88
- newItems.splice(newIndex, 0, removed);
89
- changeItems(newItems);
90
- // Drag end handler
91
- if (onDragEnd)
92
- onDragEnd(newItems);
93
- }
94
- setActiveId(undefined);
95
- }
67
+ }, [onChange, doFormChange]);
96
68
  // Methods
97
69
  React.useImperativeHandle(mRef, () => {
98
70
  return {
@@ -149,7 +121,56 @@ export function DnDList(props) {
149
121
  return items;
150
122
  }
151
123
  };
152
- }, [items]);
124
+ }, [items, labelField, changeItems]);
125
+ // Dynamic import library
126
+ const [dnd, setDnd] = React.useState();
127
+ React.useEffect(() => {
128
+ Promise.all([
129
+ import("@dnd-kit/core"),
130
+ import("@dnd-kit/sortable"),
131
+ import("@dnd-kit/utilities")
132
+ ]).then(([{ DndContext }, { SortableContext, useSortable, verticalListSortingStrategy }, { CSS }]) => {
133
+ setDnd([
134
+ DndContext,
135
+ SortableContext,
136
+ useSortable,
137
+ verticalListSortingStrategy,
138
+ CSS
139
+ ]);
140
+ });
141
+ }, []);
142
+ if (dnd == null) {
143
+ return React.createElement(Skeleton, { variant: "rectangular", width: "100%", height: height });
144
+ }
145
+ const [DndContextType, SortableContextType, useSortableType, verticalListSortingStrategyType, CSSType] = dnd;
146
+ let getItemStyle = props.getItemStyle;
147
+ if (getItemStyle == null) {
148
+ getItemStyle = (index, isDragging) => DnDItemStyle(index, isDragging, theme);
149
+ }
150
+ // Drag event handlers
151
+ function handleDragStart(event) {
152
+ const { active } = event;
153
+ setActiveId(active.id);
154
+ }
155
+ function handleDragEnd(event) {
156
+ const { active, over } = event;
157
+ if (over && active.id !== over.id) {
158
+ // Indices
159
+ const oldIndex = items.findIndex((item) => item.id === active.id);
160
+ const newIndex = items.findIndex((item) => item.id === over.id);
161
+ // Clone
162
+ const newItems = [...items];
163
+ // Removed item
164
+ const [removed] = newItems.splice(oldIndex, 1);
165
+ // Insert to the destination index
166
+ newItems.splice(newIndex, 0, removed);
167
+ changeItems(newItems);
168
+ // Drag end handler
169
+ if (onDragEnd)
170
+ onDragEnd(newItems);
171
+ }
172
+ setActiveId(undefined);
173
+ }
153
174
  const setupDiv = (div) => {
154
175
  // Inputs
155
176
  div
@@ -164,13 +185,10 @@ export function DnDList(props) {
164
185
  .querySelectorAll("select")
165
186
  .forEach((input) => input.addEventListener("change", () => doFormChange()));
166
187
  };
167
- React.useEffect(() => {
168
- setItems(props.items);
169
- }, [props.items]);
170
- const children = (React.createElement(DndContext, { onDragStart: handleDragStart, onDragEnd: handleDragEnd },
171
- React.createElement(SortableContext, { items: items, strategy: verticalListSortingStrategy }, items.map((item, index) => {
188
+ const children = (React.createElement(DndContextType, { onDragStart: handleDragStart, onDragEnd: handleDragEnd },
189
+ React.createElement(SortableContextType, { items: items, strategy: verticalListSortingStrategyType }, items.map((item, index) => {
172
190
  const id = item[keyField];
173
- return (React.createElement(SortableItem, { id: id, key: id, style: getItemStyle(index, id === activeId), itemRenderer: (nodeRef, actionNodeRef) => itemRenderer(item, index, nodeRef, actionNodeRef) }));
191
+ return (React.createElement(SortableItem, { id: id, useSortableType: useSortableType, CSSType: CSSType, key: id, style: getItemStyle(index, id === activeId), itemRenderer: (nodeRef, actionNodeRef) => itemRenderer(item, index, nodeRef, actionNodeRef) }));
174
192
  }))));
175
193
  if (onFormChange) {
176
194
  return (React.createElement("div", { style: { width: "100%" }, ref: (div) => {
@@ -0,0 +1,29 @@
1
+ import React from "react";
2
+ import type { ChartData, LineControllerChartOptions } from "chart.js";
3
+ /**
4
+ * Line chart
5
+ */
6
+ export type LineChartProps = {
7
+ /**
8
+ * Chart data
9
+ */
10
+ data: ChartData<"line">;
11
+ /**
12
+ * Options
13
+ */
14
+ options?: LineControllerChartOptions;
15
+ /**
16
+ * Subtitle
17
+ */
18
+ subtitle?: string;
19
+ /**
20
+ * Title
21
+ */
22
+ title?: string;
23
+ };
24
+ /**
25
+ * Line chart
26
+ * @param props Props
27
+ * @returns Component
28
+ */
29
+ export declare function LineChart(props: LineChartProps): React.JSX.Element;
@@ -0,0 +1,51 @@
1
+ import { LinearProgress } from "@mui/material";
2
+ import React from "react";
3
+ /**
4
+ * Line chart
5
+ * @param props Props
6
+ * @returns Component
7
+ */
8
+ export function LineChart(props) {
9
+ // Destruct
10
+ const { data, options, subtitle, title } = props;
11
+ // State
12
+ const [LineType, setLineType] = React.useState();
13
+ React.useEffect(() => {
14
+ Promise.all([
15
+ import("react-chartjs-2"),
16
+ import("chart.js"),
17
+ import("chartjs-plugin-datalabels")
18
+ ]).then(([{ Line }, { Chart: ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend }, ChartDataLabels]) => {
19
+ // https://www.chartjs.org/docs/latest/getting-started/
20
+ ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, ChartDataLabels);
21
+ setLineType(Line);
22
+ });
23
+ }, []);
24
+ return LineType == null ? (React.createElement(LinearProgress, null)) : (React.createElement(LineType, { options: {
25
+ scales: {
26
+ x: {
27
+ ticks: {
28
+ display: false //this will remove only the label
29
+ }
30
+ }
31
+ },
32
+ responsive: true,
33
+ plugins: {
34
+ datalabels: {
35
+ display: (context) => context.dataset.data.length <= 31,
36
+ align: "end"
37
+ },
38
+ legend: {
39
+ position: "top"
40
+ },
41
+ subtitle: subtitle ? { text: subtitle, display: true } : undefined,
42
+ title: title
43
+ ? {
44
+ text: title,
45
+ display: true
46
+ }
47
+ : undefined
48
+ },
49
+ ...options
50
+ }, data: data }));
51
+ }
package/lib/index.d.ts CHANGED
@@ -56,6 +56,7 @@ export * from "./InputField";
56
56
  export * from "./InputTipField";
57
57
  export * from "./IntInputField";
58
58
  export * from "./ItemList";
59
+ export * from "./LineChart";
59
60
  export * from "./ListChooser";
60
61
  export * from "./ListItemRightIcon";
61
62
  export * from "./ListMoreDisplay";
package/lib/index.js CHANGED
@@ -56,6 +56,7 @@ export * from "./InputField";
56
56
  export * from "./InputTipField";
57
57
  export * from "./IntInputField";
58
58
  export * from "./ItemList";
59
+ export * from "./LineChart";
59
60
  export * from "./ListChooser";
60
61
  export * from "./ListItemRightIcon";
61
62
  export * from "./ListMoreDisplay";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.2.48",
3
+ "version": "1.2.50",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -63,10 +63,13 @@
63
63
  "@types/react-avatar-editor": "^13.0.0",
64
64
  "@types/react-dom": "^18.2.4",
65
65
  "@types/react-input-mask": "^3.0.2",
66
+ "chart.js": "^4.3.0",
67
+ "chartjs-plugin-datalabels": "^2.2.0",
66
68
  "pica": "^9.0.1",
67
69
  "pulltorefreshjs": "^0.1.22",
68
70
  "react": "^18.2.0",
69
71
  "react-avatar-editor": "^13.0.0",
72
+ "react-chartjs-2": "^5.2.0",
70
73
  "react-dom": "^18.2.0",
71
74
  "react-draggable": "^4.4.5",
72
75
  "react-imask": "^6.6.1"
package/src/DnDList.tsx CHANGED
@@ -1,21 +1,23 @@
1
- import {
1
+ import type {
2
2
  DndContext,
3
3
  DragEndEvent,
4
4
  DragStartEvent,
5
5
  UniqueIdentifier
6
6
  } from "@dnd-kit/core";
7
- import {
7
+ import type {
8
8
  SortableContext,
9
9
  useSortable,
10
10
  verticalListSortingStrategy
11
11
  } from "@dnd-kit/sortable";
12
- import { CSS } from "@dnd-kit/utilities";
12
+ import type { CSS } from "@dnd-kit/utilities";
13
13
  import { DataTypes } from "@etsoo/shared";
14
- import { Theme, useTheme } from "@mui/material";
14
+ import { Skeleton, Theme, useTheme } from "@mui/material";
15
15
  import React, { CSSProperties } from "react";
16
16
 
17
17
  function SortableItem(props: {
18
18
  id: UniqueIdentifier;
19
+ useSortableType: typeof useSortable;
20
+ CSSType: typeof CSS;
19
21
  itemRenderer: (
20
22
  nodeRef: React.ComponentProps<any>,
21
23
  actionNodeRef: React.ComponentProps<any>
@@ -23,7 +25,7 @@ function SortableItem(props: {
23
25
  style?: React.CSSProperties;
24
26
  }) {
25
27
  // Destruct
26
- const { id, itemRenderer, style = {} } = props;
28
+ const { id, useSortableType, CSSType, itemRenderer, style = {} } = props;
27
29
 
28
30
  // Use sortable
29
31
  const {
@@ -33,11 +35,11 @@ function SortableItem(props: {
33
35
  transform,
34
36
  transition,
35
37
  setActivatorNodeRef
36
- } = useSortable({ id });
38
+ } = useSortableType({ id });
37
39
 
38
40
  const allStyle = {
39
41
  ...style,
40
- transform: CSS.Transform.toString(transform),
42
+ transform: CSSType.Transform.toString(transform),
41
43
  transition
42
44
  };
43
45
 
@@ -130,6 +132,11 @@ export interface DnDListPros<D extends object, K extends DataTypes.Keys<D>> {
130
132
  actionNodeRef: React.ComponentProps<any>
131
133
  ) => React.ReactElement;
132
134
 
135
+ /**
136
+ * Height
137
+ */
138
+ height?: string | number;
139
+
133
140
  /**
134
141
  * List items
135
142
  */
@@ -181,6 +188,7 @@ export function DnDList<
181
188
  // Destruct
182
189
  const {
183
190
  keyField,
191
+ height = 360,
184
192
  itemRenderer,
185
193
  labelField,
186
194
  mRef,
@@ -189,63 +197,36 @@ export function DnDList<
189
197
  onDragEnd
190
198
  } = props;
191
199
 
192
- let getItemStyle = props.getItemStyle;
193
- if (getItemStyle == null) {
194
- // Theme
195
- const theme = useTheme();
196
- getItemStyle = (index, isDragging) =>
197
- DnDItemStyle(index, isDragging, theme);
198
- }
200
+ // Theme
201
+ const theme = useTheme();
199
202
 
200
203
  // States
201
204
  const [items, setItems] = React.useState<D[]>([]);
202
205
  const [activeId, setActiveId] = React.useState<UniqueIdentifier>();
203
206
 
204
- const doFormChange = (newItems?: D[]) => {
205
- if (onFormChange) onFormChange(newItems ?? items);
206
- };
207
-
208
- const changeItems = (newItems: D[]) => {
209
- // Possible to alter items with the handler
210
- if (onChange) onChange(newItems);
211
-
212
- doFormChange(newItems);
213
-
214
- // Update state
215
- setItems(newItems);
216
- };
217
-
218
- // Drag event handlers
219
- function handleDragStart(event: DragStartEvent) {
220
- const { active } = event;
221
- setActiveId(active.id);
222
- }
223
-
224
- function handleDragEnd(event: DragEndEvent) {
225
- const { active, over } = event;
226
-
227
- if (over && active.id !== over.id) {
228
- // Indices
229
- const oldIndex = items.findIndex((item) => item.id === active.id);
230
- const newIndex = items.findIndex((item) => item.id === over.id);
231
-
232
- // Clone
233
- const newItems = [...items];
234
-
235
- // Removed item
236
- const [removed] = newItems.splice(oldIndex, 1);
207
+ React.useEffect(() => {
208
+ setItems(props.items);
209
+ }, [props.items]);
237
210
 
238
- // Insert to the destination index
239
- newItems.splice(newIndex, 0, removed);
211
+ const doFormChange = React.useCallback(
212
+ (newItems?: D[]) => {
213
+ if (onFormChange) onFormChange(newItems ?? items);
214
+ },
215
+ [items, onFormChange]
216
+ );
240
217
 
241
- changeItems(newItems);
218
+ const changeItems = React.useCallback(
219
+ (newItems: D[]) => {
220
+ // Possible to alter items with the handler
221
+ if (onChange) onChange(newItems);
242
222
 
243
- // Drag end handler
244
- if (onDragEnd) onDragEnd(newItems);
245
- }
223
+ doFormChange(newItems);
246
224
 
247
- setActiveId(undefined);
248
- }
225
+ // Update state
226
+ setItems(newItems);
227
+ },
228
+ [onChange, doFormChange]
229
+ );
249
230
 
250
231
  // Methods
251
232
  React.useImperativeHandle(
@@ -327,9 +308,93 @@ export function DnDList<
327
308
  }
328
309
  };
329
310
  },
330
- [items]
311
+ [items, labelField, changeItems]
331
312
  );
332
313
 
314
+ // Dynamic import library
315
+ const [dnd, setDnd] =
316
+ React.useState<
317
+ [
318
+ typeof DndContext,
319
+ typeof SortableContext,
320
+ typeof useSortable,
321
+ typeof verticalListSortingStrategy,
322
+ typeof CSS
323
+ ]
324
+ >();
325
+
326
+ React.useEffect(() => {
327
+ Promise.all([
328
+ import("@dnd-kit/core"),
329
+ import("@dnd-kit/sortable"),
330
+ import("@dnd-kit/utilities")
331
+ ]).then(
332
+ ([
333
+ { DndContext },
334
+ { SortableContext, useSortable, verticalListSortingStrategy },
335
+ { CSS }
336
+ ]) => {
337
+ setDnd([
338
+ DndContext,
339
+ SortableContext,
340
+ useSortable,
341
+ verticalListSortingStrategy,
342
+ CSS
343
+ ]);
344
+ }
345
+ );
346
+ }, []);
347
+
348
+ if (dnd == null) {
349
+ return <Skeleton variant="rectangular" width="100%" height={height} />;
350
+ }
351
+
352
+ const [
353
+ DndContextType,
354
+ SortableContextType,
355
+ useSortableType,
356
+ verticalListSortingStrategyType,
357
+ CSSType
358
+ ] = dnd;
359
+
360
+ let getItemStyle = props.getItemStyle;
361
+ if (getItemStyle == null) {
362
+ getItemStyle = (index, isDragging) =>
363
+ DnDItemStyle(index, isDragging, theme);
364
+ }
365
+
366
+ // Drag event handlers
367
+ function handleDragStart(event: DragStartEvent) {
368
+ const { active } = event;
369
+ setActiveId(active.id);
370
+ }
371
+
372
+ function handleDragEnd(event: DragEndEvent) {
373
+ const { active, over } = event;
374
+
375
+ if (over && active.id !== over.id) {
376
+ // Indices
377
+ const oldIndex = items.findIndex((item) => item.id === active.id);
378
+ const newIndex = items.findIndex((item) => item.id === over.id);
379
+
380
+ // Clone
381
+ const newItems = [...items];
382
+
383
+ // Removed item
384
+ const [removed] = newItems.splice(oldIndex, 1);
385
+
386
+ // Insert to the destination index
387
+ newItems.splice(newIndex, 0, removed);
388
+
389
+ changeItems(newItems);
390
+
391
+ // Drag end handler
392
+ if (onDragEnd) onDragEnd(newItems);
393
+ }
394
+
395
+ setActiveId(undefined);
396
+ }
397
+
333
398
  const setupDiv = (div: HTMLDivElement) => {
334
399
  // Inputs
335
400
  div
@@ -353,18 +418,19 @@ export function DnDList<
353
418
  );
354
419
  };
355
420
 
356
- React.useEffect(() => {
357
- setItems(props.items);
358
- }, [props.items]);
359
-
360
421
  const children = (
361
- <DndContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
362
- <SortableContext items={items} strategy={verticalListSortingStrategy}>
422
+ <DndContextType onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
423
+ <SortableContextType
424
+ items={items}
425
+ strategy={verticalListSortingStrategyType}
426
+ >
363
427
  {items.map((item, index) => {
364
428
  const id = item[keyField] as unknown as UniqueIdentifier;
365
429
  return (
366
430
  <SortableItem
367
431
  id={id}
432
+ useSortableType={useSortableType}
433
+ CSSType={CSSType}
368
434
  key={id}
369
435
  style={getItemStyle!(index, id === activeId)}
370
436
  itemRenderer={(nodeRef, actionNodeRef) =>
@@ -373,8 +439,8 @@ export function DnDList<
373
439
  />
374
440
  );
375
441
  })}
376
- </SortableContext>
377
- </DndContext>
442
+ </SortableContextType>
443
+ </DndContextType>
378
444
  );
379
445
 
380
446
  if (onFormChange) {
@@ -0,0 +1,115 @@
1
+ import { LinearProgress } from "@mui/material";
2
+ import React from "react";
3
+ import type { ChartData, LineControllerChartOptions } from "chart.js";
4
+ import type { Line } from "react-chartjs-2";
5
+
6
+ /**
7
+ * Line chart
8
+ */
9
+ export type LineChartProps = {
10
+ /**
11
+ * Chart data
12
+ */
13
+ data: ChartData<"line">;
14
+
15
+ /**
16
+ * Options
17
+ */
18
+ options?: LineControllerChartOptions;
19
+
20
+ /**
21
+ * Subtitle
22
+ */
23
+ subtitle?: string;
24
+
25
+ /**
26
+ * Title
27
+ */
28
+ title?: string;
29
+ };
30
+
31
+ /**
32
+ * Line chart
33
+ * @param props Props
34
+ * @returns Component
35
+ */
36
+ export function LineChart(props: LineChartProps) {
37
+ // Destruct
38
+ const { data, options, subtitle, title } = props;
39
+
40
+ // State
41
+ const [LineType, setLineType] = React.useState<typeof Line>();
42
+
43
+ React.useEffect(() => {
44
+ Promise.all([
45
+ import("react-chartjs-2"),
46
+ import("chart.js"),
47
+ import("chartjs-plugin-datalabels")
48
+ ]).then(
49
+ ([
50
+ { Line },
51
+ {
52
+ Chart: ChartJS,
53
+ CategoryScale,
54
+ LinearScale,
55
+ PointElement,
56
+ LineElement,
57
+ Title,
58
+ Tooltip,
59
+ Legend
60
+ },
61
+ ChartDataLabels
62
+ ]) => {
63
+ // https://www.chartjs.org/docs/latest/getting-started/
64
+ ChartJS.register(
65
+ CategoryScale,
66
+ LinearScale,
67
+ PointElement,
68
+ LineElement,
69
+ Title,
70
+ Tooltip,
71
+ Legend,
72
+
73
+ ChartDataLabels
74
+ );
75
+
76
+ setLineType(Line);
77
+ }
78
+ );
79
+ }, []);
80
+
81
+ return LineType == null ? (
82
+ <LinearProgress />
83
+ ) : (
84
+ <LineType
85
+ options={{
86
+ scales: {
87
+ x: {
88
+ ticks: {
89
+ display: false //this will remove only the label
90
+ }
91
+ }
92
+ },
93
+ responsive: true,
94
+ plugins: {
95
+ datalabels: {
96
+ display: (context) => context.dataset.data.length <= 31,
97
+ align: "end"
98
+ },
99
+ legend: {
100
+ position: "top" as const
101
+ },
102
+ subtitle: subtitle ? { text: subtitle, display: true } : undefined,
103
+ title: title
104
+ ? {
105
+ text: title,
106
+ display: true
107
+ }
108
+ : undefined
109
+ },
110
+ ...options
111
+ }}
112
+ data={data}
113
+ />
114
+ );
115
+ }
package/src/index.ts CHANGED
@@ -59,6 +59,7 @@ export * from "./InputField";
59
59
  export * from "./InputTipField";
60
60
  export * from "./IntInputField";
61
61
  export * from "./ItemList";
62
+ export * from "./LineChart";
62
63
  export * from "./ListChooser";
63
64
  export * from "./ListItemRightIcon";
64
65
  export * from "./ListMoreDisplay";