blixify-ui-web-mcp 0.1.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.
- package/README.md +5 -0
- package/lib/components/action/button/README.md +75 -0
- package/lib/components/action/button/button.stories.tsx +138 -0
- package/lib/components/action/buttonGroup/README.md +79 -0
- package/lib/components/action/buttonGroup/buttonGroup.stories.tsx +104 -0
- package/lib/components/action/iconButton/README.md +39 -0
- package/lib/components/action/iconButton/iconButton.stories.tsx +22 -0
- package/lib/components/action/radioList/README.md +98 -0
- package/lib/components/action/radioList/radioList.stories.tsx +181 -0
- package/lib/components/action/slider/README.md +86 -0
- package/lib/components/action/slider/slider.stories.tsx +133 -0
- package/lib/components/action/textButton/README.md +34 -0
- package/lib/components/action/textButton/textButton.stories.tsx +16 -0
- package/lib/components/action/toggle/README.md +39 -0
- package/lib/components/action/toggle/toggle.stories.tsx +23 -0
- package/lib/components/advanced/collapse/README.md +106 -0
- package/lib/components/advanced/collapse/collapse.stories.tsx +165 -0
- package/lib/components/advanced/infoWindow/README.md +69 -0
- package/lib/components/advanced/infoWindow/infoWindow.stories.tsx +112 -0
- package/lib/components/advanced/popUp/README.md +95 -0
- package/lib/components/advanced/popUp/popUp.stories.tsx +189 -0
- package/lib/components/auth/bareSignIn/README.md +78 -0
- package/lib/components/auth/bareSignIn/bareSignIn.stories.tsx +141 -0
- package/lib/components/auth/bareSignUp/README.md +130 -0
- package/lib/components/auth/bareSignUp/bareSignUp.stories.tsx +159 -0
- package/lib/components/auth/signIn/README.md +53 -0
- package/lib/components/auth/signIn/signIn.stories.tsx +120 -0
- package/lib/components/auth/signUp/README.md +136 -0
- package/lib/components/auth/signUp/signUp.stories.tsx +193 -0
- package/lib/components/chart/README.md +13 -0
- package/lib/components/chart/areaChart/README.md +133 -0
- package/lib/components/chart/areaChart/areaChart.stories.tsx +199 -0
- package/lib/components/chart/barChart/README.md +193 -0
- package/lib/components/chart/barChart/barChart.stories.tsx +318 -0
- package/lib/components/chart/boxPlotChart/README.md +124 -0
- package/lib/components/chart/boxPlotChart/boxPlotChart.stories.tsx +104 -0
- package/lib/components/chart/bubbleChart/README.md +166 -0
- package/lib/components/chart/bubbleChart/bubbleChart.stories.tsx +144 -0
- package/lib/components/chart/card/README.md +107 -0
- package/lib/components/chart/card/card.stories.tsx +89 -0
- package/lib/components/chart/ganttChart/README.md +142 -0
- package/lib/components/chart/ganttChart/ganttChart.stories.tsx +138 -0
- package/lib/components/chart/heatmapChart/README.md +125 -0
- package/lib/components/chart/heatmapChart/heatmapChart.stories.tsx +106 -0
- package/lib/components/chart/lineChart/README.md +140 -0
- package/lib/components/chart/lineChart/lineChart.stories.tsx +152 -0
- package/lib/components/chart/pieChart/README.md +117 -0
- package/lib/components/chart/pieChart/pieChart.stories.tsx +180 -0
- package/lib/components/chart/polarAreaChart/README.md +126 -0
- package/lib/components/chart/polarAreaChart/polarAreaChart.stories.tsx +106 -0
- package/lib/components/chart/radarChart/README.md +57 -0
- package/lib/components/chart/radarChart/radarChart.stories.tsx +36 -0
- package/lib/components/chart/radialBar/README.md +152 -0
- package/lib/components/chart/radialBar/radialChart.stories.tsx +136 -0
- package/lib/components/chart/rangeBarChart/README.md +323 -0
- package/lib/components/chart/rangeBarChart/rangeBarChart.stories.tsx +208 -0
- package/lib/components/chart/statsCard/README.md +97 -0
- package/lib/components/chart/statsCard/statsCard.stories.tsx +183 -0
- package/lib/components/chart/treemapChart/README.md +142 -0
- package/lib/components/chart/treemapChart/treemapChart.stories.tsx +122 -0
- package/lib/components/chat/chatAnchor/README.md +113 -0
- package/lib/components/chat/chatAnchor/chatAnchor.stories.tsx +156 -0
- package/lib/components/chat/chatBase/README.md +223 -0
- package/lib/components/chat/chatBase/chatBase.stories.tsx +306 -0
- package/lib/components/chat/chatDashboard/README.md +161 -0
- package/lib/components/chat/chatDashboard/chatDashboard.stories.tsx +154 -0
- package/lib/components/data/dataGraph/README.md +13 -0
- package/lib/components/data/dataGraph/dataGraph.stories.tsx +84 -0
- package/lib/components/data/dataReference/README.md +62 -0
- package/lib/components/data/dataReference/dataReference.stories.tsx +53 -0
- package/lib/components/data/dataTemplate/README.md +903 -0
- package/lib/components/data/dataTemplate/dataModule.stories.tsx +196 -0
- package/lib/components/data/dataTemplate/dataTemplate.stories.tsx +337 -0
- package/lib/components/data/dataWrapper/README.md +1077 -0
- package/lib/components/data/dataWrapper/dataWrapper.stories.tsx +831 -0
- package/lib/components/data/queryForm/README.md +56 -0
- package/lib/components/data/queryForm/queryForm.stories.tsx +85 -0
- package/lib/components/data/readQuery/README.md +282 -0
- package/lib/components/data/readQuery/readQuery.stories.tsx +256 -0
- package/lib/components/data/readQueryHoc/README.md +89 -0
- package/lib/components/data/readQueryHoc/readQueryHoc.stories.tsx +33 -0
- package/lib/components/data/writeQuery/README.md +178 -0
- package/lib/components/data/writeQuery/writeQuery.stories.tsx +209 -0
- package/lib/components/design/actionSection/README.md +47 -0
- package/lib/components/design/actionSection/actionSection.stories.tsx +74 -0
- package/lib/components/design/banner/README.md +43 -0
- package/lib/components/design/banner/banner.stories.tsx +34 -0
- package/lib/components/design/bannerAction/README.md +44 -0
- package/lib/components/design/bannerAction/bannerAction.stories.tsx +25 -0
- package/lib/components/design/blogSection/README.md +111 -0
- package/lib/components/design/blogSection/blogSection.stories.tsx +72 -0
- package/lib/components/design/carouselSection/README.md +82 -0
- package/lib/components/design/carouselSection/carouselSection.stories.tsx +52 -0
- package/lib/components/design/designList/README.md +60 -0
- package/lib/components/design/designList/designList.stories.tsx +44 -0
- package/lib/components/design/faq/README.md +121 -0
- package/lib/components/design/faq/faq.stories.tsx +103 -0
- package/lib/components/design/fileGrid/README.md +87 -0
- package/lib/components/design/fileGrid/fileGrid.stories.tsx +110 -0
- package/lib/components/design/fileViewer/README.md +40 -0
- package/lib/components/design/fileViewer/fileViewer.stories.tsx +28 -0
- package/lib/components/design/footerSection/README.md +62 -0
- package/lib/components/design/footerSection/footerSection.stories.tsx +84 -0
- package/lib/components/design/googleReview/README.md +45 -0
- package/lib/components/design/googleReview/googleReview.stories.tsx +33 -0
- package/lib/components/design/heroSection/README.md +48 -0
- package/lib/components/design/heroSection/heroSection.stories.tsx +85 -0
- package/lib/components/design/iconList/README.md +60 -0
- package/lib/components/design/iconList/iconList.stories.tsx +41 -0
- package/lib/components/design/imageGallery/README.md +56 -0
- package/lib/components/design/imageGallery/imageGallery.stories.tsx +45 -0
- package/lib/components/design/imageZoom/README.md +47 -0
- package/lib/components/design/imageZoom/imageZoom.stories.tsx +30 -0
- package/lib/components/design/leftContent/README.md +47 -0
- package/lib/components/design/leftContent/leftContent.stories.tsx +32 -0
- package/lib/components/design/logoCloud/README.md +42 -0
- package/lib/components/design/logoCloud/logoCloud.stories.tsx +44 -0
- package/lib/components/design/onboarding/README.md +100 -0
- package/lib/components/design/onboarding/onboarding.stories.tsx +113 -0
- package/lib/components/design/pricing/README.md +112 -0
- package/lib/components/design/pricing/pricing.stories.tsx +86 -0
- package/lib/components/design/rightContent/README.md +47 -0
- package/lib/components/design/rightContent/rightContent.stories.tsx +32 -0
- package/lib/components/design/sectionList/README.md +51 -0
- package/lib/components/design/sectionList/sectionList.stories.tsx +35 -0
- package/lib/components/design/teams/README.md +62 -0
- package/lib/components/design/teams/teams.stories.tsx +61 -0
- package/lib/components/display/alert/README.md +82 -0
- package/lib/components/display/alert/alert.stories.tsx +71 -0
- package/lib/components/display/calendar/README.md +113 -0
- package/lib/components/display/calendar/calendar.stories.tsx +159 -0
- package/lib/components/display/clipboard/README.md +36 -0
- package/lib/components/display/clipboard/clipboard.stories.tsx +32 -0
- package/lib/components/display/detailList/README.md +61 -0
- package/lib/components/display/detailList/detailList.stories.tsx +131 -0
- package/lib/components/display/drawer/README.md +74 -0
- package/lib/components/display/drawer/drawer.stories.tsx +66 -0
- package/lib/components/display/emptyState/README.md +38 -0
- package/lib/components/display/emptyState/emptyState.stories.tsx +22 -0
- package/lib/components/display/feeds/README.md +80 -0
- package/lib/components/display/feeds/feeds.stories.tsx +75 -0
- package/lib/components/display/flexTable/README.md +160 -0
- package/lib/components/display/flexTable/flexTable.stories.tsx +313 -0
- package/lib/components/display/grid/README.md +121 -0
- package/lib/components/display/grid/grid.stories.tsx +234 -0
- package/lib/components/display/kanban/README.md +78 -0
- package/lib/components/display/kanban/kanban.stories.tsx +133 -0
- package/lib/components/display/list/README.md +109 -0
- package/lib/components/display/list/list.stories.tsx +188 -0
- package/lib/components/display/loading/README.md +25 -0
- package/lib/components/display/loading/loading.stories.tsx +15 -0
- package/lib/components/display/mapView/README.md +99 -0
- package/lib/components/display/mapView/mapView.stories.tsx +225 -0
- package/lib/components/display/modal/README.md +43 -0
- package/lib/components/display/modal/modal.stories.tsx +81 -0
- package/lib/components/display/notification/README.md +43 -0
- package/lib/components/display/notification/notification.stories.tsx +30 -0
- package/lib/components/display/progress/README.md +25 -0
- package/lib/components/display/progress/progress.stories.tsx +15 -0
- package/lib/components/display/stepper/README.md +96 -0
- package/lib/components/display/stepper/stepper.stories.tsx +175 -0
- package/lib/components/display/table/README.md +176 -0
- package/lib/components/display/table/table.stories.tsx +330 -0
- package/lib/components/display/tag/README.md +74 -0
- package/lib/components/display/tag/tag.stories.tsx +79 -0
- package/lib/components/input/address/README.md +132 -0
- package/lib/components/input/address/address.stories.tsx +147 -0
- package/lib/components/input/canvas/README.md +131 -0
- package/lib/components/input/canvas/canvas.stories.tsx +165 -0
- package/lib/components/input/checkbox/README.md +61 -0
- package/lib/components/input/checkbox/checkbox.stories.tsx +30 -0
- package/lib/components/input/datePicker/README.md +124 -0
- package/lib/components/input/datePicker/datePicker.stories.tsx +197 -0
- package/lib/components/input/form/README.md +55 -0
- package/lib/components/input/form/form.stories.tsx +143 -0
- package/lib/components/input/markdown/README.md +146 -0
- package/lib/components/input/markdown/markdown.stories.tsx +40 -0
- package/lib/components/input/monthYearPicker/README.md +69 -0
- package/lib/components/input/monthYearPicker/monthYearPicker.stories.tsx +47 -0
- package/lib/components/input/netPromoterScore/README.md +52 -0
- package/lib/components/input/netPromoterScore/netPromoterScore.stories.tsx +30 -0
- package/lib/components/input/rating/README.md +51 -0
- package/lib/components/input/rating/rating.stories.tsx +30 -0
- package/lib/components/input/select/README.md +108 -0
- package/lib/components/input/select/select.stories.tsx +286 -0
- package/lib/components/input/signature/README.md +106 -0
- package/lib/components/input/signature/signature.stories.tsx +188 -0
- package/lib/components/input/textArea/README.md +55 -0
- package/lib/components/input/textArea/textArea.stories.tsx +30 -0
- package/lib/components/input/textInput/README.md +81 -0
- package/lib/components/input/textInput/textinput.stories.tsx +231 -0
- package/lib/components/input/uploadInput/README.md +134 -0
- package/lib/components/input/uploadInput/uploadInput.stories.tsx +193 -0
- package/lib/components/navigation/bars/README.md +40 -0
- package/lib/components/navigation/bars/bars.stories.tsx +85 -0
- package/lib/components/navigation/bottomTab/README.md +53 -0
- package/lib/components/navigation/bottomTab/bottomTab.stories.tsx +32 -0
- package/lib/components/navigation/breadcrumb/README.md +48 -0
- package/lib/components/navigation/breadcrumb/breadcrumb.stories.tsx +27 -0
- package/lib/components/navigation/header/README.md +149 -0
- package/lib/components/navigation/header/header.stories.tsx +107 -0
- package/lib/components/navigation/leftNav/README.md +91 -0
- package/lib/components/navigation/leftNav/leftNav.stories.tsx +106 -0
- package/lib/components/navigation/tabs/README.md +75 -0
- package/lib/components/navigation/tabs/tabs.stories.tsx +60 -0
- package/lib/components/structure/column/README.md +40 -0
- package/lib/components/structure/column/column.stories.tsx +26 -0
- package/lib/components/structure/container/README.md +34 -0
- package/lib/components/structure/container/container.stories.tsx +19 -0
- package/lib/components/structure/link/README.md +55 -0
- package/lib/components/structure/link/link.stories.tsx +30 -0
- package/lib/components/structure/text/README.md +42 -0
- package/lib/components/structure/text/text.stories.tsx +39 -0
- package/lib/components/template/authPage/authPage.stories.tsx +68 -0
- package/lib/components/template/landingPage/landingPage.stories.tsx +288 -0
- package/lib/components/template/productListing/productListing.stories.tsx +297 -0
- package/lib/components/template/productOverview/productOverview.stories.tsx +194 -0
- package/lib/components/template/shoppingCart/shoppingCart.stories.tsx +252 -0
- package/lib/components/template/userHomePage/userHomePage.stories.tsx +605 -0
- package/lib/components/template/userRankingDashboard/userRankingDashboard.stories.tsx +481 -0
- package/lib/mcp/server.d.ts +2 -0
- package/lib/mcp/server.d.ts.map +1 -0
- package/lib/mcp/server.js +33 -0
- package/lib/mcp/server.js.map +1 -0
- package/lib/mcp/tools/getBackendComponent.d.ts +13 -0
- package/lib/mcp/tools/getBackendComponent.d.ts.map +1 -0
- package/lib/mcp/tools/getBackendComponent.js +119 -0
- package/lib/mcp/tools/getBackendComponent.js.map +1 -0
- package/lib/mcp/tools/getComponent.d.ts +17 -0
- package/lib/mcp/tools/getComponent.d.ts.map +1 -0
- package/lib/mcp/tools/getComponent.js +118 -0
- package/lib/mcp/tools/getComponent.js.map +1 -0
- package/lib/mcp/tools/listComponents.d.ts +13 -0
- package/lib/mcp/tools/listComponents.d.ts.map +1 -0
- package/lib/mcp/tools/listComponents.js +113 -0
- package/lib/mcp/tools/listComponents.js.map +1 -0
- package/lib/mcp/tools/listTemplates.d.ts +13 -0
- package/lib/mcp/tools/listTemplates.d.ts.map +1 -0
- package/lib/mcp/tools/listTemplates.js +68 -0
- package/lib/mcp/tools/listTemplates.js.map +1 -0
- package/lib/mcp/tools/suggestTemplate.d.ts +17 -0
- package/lib/mcp/tools/suggestTemplate.d.ts.map +1 -0
- package/lib/mcp/tools/suggestTemplate.js +212 -0
- package/lib/mcp/tools/suggestTemplate.js.map +1 -0
- package/package.json +23 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { storiesOf } from "@storybook/react";
|
|
2
|
+
import React, { useRef } from "react";
|
|
3
|
+
import { Canvas } from ".";
|
|
4
|
+
import { StorySection } from "../../storyUtils";
|
|
5
|
+
import { Button } from "../../action/button";
|
|
6
|
+
import { Form } from "../form";
|
|
7
|
+
import README from "./README.md";
|
|
8
|
+
|
|
9
|
+
const stories = storiesOf("Input", module);
|
|
10
|
+
|
|
11
|
+
stories.addParameters({
|
|
12
|
+
readme: {
|
|
13
|
+
content: README,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const backgroundImageUrl =
|
|
18
|
+
"https://plus.unsplash.com/premium_vector-1736525291885-ace93f581fa9?q=80&w=880&auto=format&fit=crop&ixlib=rb-4.1.0";
|
|
19
|
+
|
|
20
|
+
const dummyDrawings = [
|
|
21
|
+
{
|
|
22
|
+
id: "drawing-1",
|
|
23
|
+
color: "green",
|
|
24
|
+
lineWidth: 3,
|
|
25
|
+
points: [
|
|
26
|
+
{ x: 350, y: 100 },
|
|
27
|
+
{ x: 400, y: 150 },
|
|
28
|
+
{ x: 450, y: 100 },
|
|
29
|
+
{ x: 400, y: 50 },
|
|
30
|
+
{ x: 350, y: 100 },
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
stories.add("Canvas", () => {
|
|
36
|
+
const formRef = useRef<any>(null);
|
|
37
|
+
const canvasRef = useRef<any>(null);
|
|
38
|
+
const canvasDrawRef = useRef<any>(null);
|
|
39
|
+
const canvasImageRef = useRef<any>(null);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<>
|
|
43
|
+
<StorySection
|
|
44
|
+
title="Text Input"
|
|
45
|
+
description="Click anywhere on the canvas to open a text modal and place text at that position. Text entries are stored as TextEntry objects with position, color, and size."
|
|
46
|
+
>
|
|
47
|
+
<div className="w-full max-w-[500px]">
|
|
48
|
+
<Canvas
|
|
49
|
+
id="canvas-text"
|
|
50
|
+
ref={canvasRef}
|
|
51
|
+
label="Canvas (Text)"
|
|
52
|
+
canvasHeight={300}
|
|
53
|
+
onChange={(texts) => console.log("texts:", texts)}
|
|
54
|
+
onSubmit={(texts, drawings) =>
|
|
55
|
+
console.log("submit", texts, drawings)
|
|
56
|
+
}
|
|
57
|
+
/>
|
|
58
|
+
</div>
|
|
59
|
+
</StorySection>
|
|
60
|
+
|
|
61
|
+
<StorySection
|
|
62
|
+
title="With Background Image"
|
|
63
|
+
description="Pass backgroundImageUrl to load an image onto the canvas. The image is fetched and drawn as the canvas background."
|
|
64
|
+
>
|
|
65
|
+
<div className="w-full max-w-[500px]">
|
|
66
|
+
<Canvas
|
|
67
|
+
id="canvas-bg"
|
|
68
|
+
label="Canvas (Background Image)"
|
|
69
|
+
canvasHeight={300}
|
|
70
|
+
backgroundImageUrl={backgroundImageUrl}
|
|
71
|
+
onChange={(texts) => console.log("texts:", texts)}
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
</StorySection>
|
|
75
|
+
|
|
76
|
+
<StorySection
|
|
77
|
+
title="Draw Mode"
|
|
78
|
+
description="enableDraw=true adds Draw, Erase, and Clear All toolbar buttons. Use Draw to toggle between text and draw mode. Pre-populate drawings via the drawings prop."
|
|
79
|
+
>
|
|
80
|
+
<div className="w-full max-w-[500px]">
|
|
81
|
+
<Canvas
|
|
82
|
+
id="canvas-draw"
|
|
83
|
+
ref={canvasDrawRef}
|
|
84
|
+
label="Canvas (Draw)"
|
|
85
|
+
canvasHeight={300}
|
|
86
|
+
backgroundImageUrl={backgroundImageUrl}
|
|
87
|
+
drawings={dummyDrawings}
|
|
88
|
+
enableDraw
|
|
89
|
+
onChange={(texts) => console.log("texts:", texts)}
|
|
90
|
+
onDrawingsChange={(d) => console.log("drawings:", d)}
|
|
91
|
+
/>
|
|
92
|
+
</div>
|
|
93
|
+
</StorySection>
|
|
94
|
+
|
|
95
|
+
<StorySection
|
|
96
|
+
title="Image Upload"
|
|
97
|
+
description="enableImageUpload=true adds an Images button that lets the user upload a local image and set it as the canvas background."
|
|
98
|
+
>
|
|
99
|
+
<div className="w-full max-w-[500px]">
|
|
100
|
+
<Canvas
|
|
101
|
+
id="canvas-image"
|
|
102
|
+
ref={canvasImageRef}
|
|
103
|
+
label="Canvas (Image Upload)"
|
|
104
|
+
canvasHeight={300}
|
|
105
|
+
enableDraw
|
|
106
|
+
enableImageUpload
|
|
107
|
+
onChange={(texts) => console.log("texts:", texts)}
|
|
108
|
+
onDrawingsChange={(d) => console.log("drawings:", d)}
|
|
109
|
+
onBackgroundImageChange={(img) => console.log("bg image:", img)}
|
|
110
|
+
/>
|
|
111
|
+
</div>
|
|
112
|
+
</StorySection>
|
|
113
|
+
|
|
114
|
+
<StorySection
|
|
115
|
+
title="Form Validation"
|
|
116
|
+
description="When used inside a Form with a ref, handleSubmit validates that the canvas is not empty. optional=true skips this check."
|
|
117
|
+
>
|
|
118
|
+
<div className="w-full max-w-[500px] space-y-3">
|
|
119
|
+
<Form ref={formRef} refList={[canvasRef]}>
|
|
120
|
+
<Canvas
|
|
121
|
+
id="canvas-form"
|
|
122
|
+
ref={canvasRef}
|
|
123
|
+
label="Canvas (Required)"
|
|
124
|
+
canvasHeight={300}
|
|
125
|
+
enableDraw
|
|
126
|
+
onSubmit={(texts, drawings) =>
|
|
127
|
+
console.log("submitted", texts, drawings)
|
|
128
|
+
}
|
|
129
|
+
/>
|
|
130
|
+
</Form>
|
|
131
|
+
<Button
|
|
132
|
+
text="Submit"
|
|
133
|
+
size="small"
|
|
134
|
+
type="normal"
|
|
135
|
+
onClick={() => formRef.current?.handleSubmit()}
|
|
136
|
+
/>
|
|
137
|
+
</div>
|
|
138
|
+
</StorySection>
|
|
139
|
+
|
|
140
|
+
<StorySection
|
|
141
|
+
title="Read Only"
|
|
142
|
+
description="readOnly=true disables all editing interactions but keeps the default cursor. disabled=true additionally shows a not-allowed cursor and reduces opacity."
|
|
143
|
+
>
|
|
144
|
+
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 w-full">
|
|
145
|
+
<Canvas
|
|
146
|
+
id="canvas-readonly"
|
|
147
|
+
label="Read Only"
|
|
148
|
+
canvasHeight={200}
|
|
149
|
+
backgroundImageUrl={backgroundImageUrl}
|
|
150
|
+
drawings={dummyDrawings}
|
|
151
|
+
readOnly
|
|
152
|
+
/>
|
|
153
|
+
<Canvas
|
|
154
|
+
id="canvas-disabled"
|
|
155
|
+
label="Disabled"
|
|
156
|
+
canvasHeight={200}
|
|
157
|
+
backgroundImageUrl={backgroundImageUrl}
|
|
158
|
+
drawings={dummyDrawings}
|
|
159
|
+
disabled
|
|
160
|
+
/>
|
|
161
|
+
</div>
|
|
162
|
+
</StorySection>
|
|
163
|
+
</>
|
|
164
|
+
);
|
|
165
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Checkbox
|
|
2
|
+
|
|
3
|
+
<!-- STORY -->
|
|
4
|
+
|
|
5
|
+
<hr>
|
|
6
|
+
|
|
7
|
+
Check box to select data
|
|
8
|
+
|
|
9
|
+
##### Import
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import { Checkbox } from "blixify-ui-web/components/input/checkbox";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
##### Usage
|
|
16
|
+
|
|
17
|
+
```jsx
|
|
18
|
+
const itemList = ["Default Checkbox", "Checked State"];
|
|
19
|
+
const [selectItemList, setSelectItemList] = useState<string[]>([]);
|
|
20
|
+
const handleSelectItemList = (item: string) => {
|
|
21
|
+
setSelectItemList((prevSelectItemList) => {
|
|
22
|
+
if (selectItemList.includes(item)) {
|
|
23
|
+
return prevSelectItemList.filter(
|
|
24
|
+
(selectedItem) => selectedItem !== item
|
|
25
|
+
);
|
|
26
|
+
} else {
|
|
27
|
+
return [...prevSelectItemList, item];
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div>
|
|
34
|
+
<Checkbox
|
|
35
|
+
itemList={itemList}
|
|
36
|
+
selectItemList={selectItemList}
|
|
37
|
+
onChange={handleSelectItemList}
|
|
38
|
+
labelClassName="text-primary-500 ml-3 font-semibold"
|
|
39
|
+
inputClassName=" rounded mr-2 focus:ring-gray-50 focus:ring-offset-0 focus:outline-offset-0 border-gray-300 checked:text-gray-400"
|
|
40
|
+
className="flex mb-4 align-top items-center"
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Required Props
|
|
49
|
+
|
|
50
|
+
| Name | Type | Default | Description |
|
|
51
|
+
| ---------------- | -------- | ------- | ----------------------------- |
|
|
52
|
+
| `itemList` | `Option` | "" | Determine your item list. |
|
|
53
|
+
| `selectItemList` | `string` | "" | Determine your item selected. |
|
|
54
|
+
|
|
55
|
+
##### Optional props
|
|
56
|
+
|
|
57
|
+
| Name | Type | Default | Description |
|
|
58
|
+
| ---------------- | ---------------- | -------------------- | ------------------------- |
|
|
59
|
+
| `onChange` | `function` | (item: string) => {} | Handle selected |
|
|
60
|
+
| `className` | `tailwind class` | "" | Tailwind class for parent |
|
|
61
|
+
| `inputClassName` | `tailwind class` | "" | Tailwind class for input |
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { storiesOf } from "@storybook/react";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import { Checkbox } from ".";
|
|
4
|
+
import README from "./README.md";
|
|
5
|
+
|
|
6
|
+
const stories = storiesOf("Input", module);
|
|
7
|
+
|
|
8
|
+
stories.addParameters({
|
|
9
|
+
readme: {
|
|
10
|
+
content: README,
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
stories.add("Checkbox", () => {
|
|
15
|
+
const itemList = [
|
|
16
|
+
{ key: "Default Checkbox", label: "Default Checkbox" },
|
|
17
|
+
{ key: "Checked State", label: "Checked State" },
|
|
18
|
+
];
|
|
19
|
+
const [selectItemList, setSelectItemList] = useState<string[]>([]);
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Checkbox
|
|
23
|
+
itemList={itemList}
|
|
24
|
+
selectItemList={selectItemList}
|
|
25
|
+
onChange={(itemList) => setSelectItemList(itemList)}
|
|
26
|
+
className="mb-2"
|
|
27
|
+
inputClassName=""
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
});
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Date Picker
|
|
2
|
+
|
|
3
|
+
<!-- STORY -->
|
|
4
|
+
|
|
5
|
+
<hr>
|
|
6
|
+
|
|
7
|
+
A date (and optional time) picker supporting single date, date+time, date range, day filtering, and custom time slot modes.
|
|
8
|
+
|
|
9
|
+
### Import
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import { InputDatePicker } from "blixify-ui-web/input/datePicker";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Usage
|
|
16
|
+
|
|
17
|
+
```jsx
|
|
18
|
+
const [date, setDate] = useState(new Date());
|
|
19
|
+
|
|
20
|
+
<InputDatePicker
|
|
21
|
+
title="Select Date"
|
|
22
|
+
value={date}
|
|
23
|
+
onChange={(_id, value) => setDate(value)}
|
|
24
|
+
/>;
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Date Range
|
|
28
|
+
|
|
29
|
+
```jsx
|
|
30
|
+
const [startDate, setStartDate] = useState(new Date());
|
|
31
|
+
const [endDate, setEndDate] = useState(new Date());
|
|
32
|
+
|
|
33
|
+
<InputDatePicker
|
|
34
|
+
range={true}
|
|
35
|
+
startDate={startDate}
|
|
36
|
+
endDate={endDate}
|
|
37
|
+
onChange={(_id, value, type) => {
|
|
38
|
+
if (type === "start") setStartDate(value);
|
|
39
|
+
else if (type === "end") setEndDate(value);
|
|
40
|
+
}}
|
|
41
|
+
/>;
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Validation via ref
|
|
45
|
+
|
|
46
|
+
```jsx
|
|
47
|
+
const ref = useRef(null);
|
|
48
|
+
|
|
49
|
+
<InputDatePicker ref={ref} title="Date" value={date} onChange={...} />
|
|
50
|
+
<Button text="Submit" onClick={() => ref.current?.handleSubmit()} />
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`handleSubmit()` returns a `Promise<boolean>`. For range mode it also validates that start is not after end.
|
|
54
|
+
|
|
55
|
+
### Optional props
|
|
56
|
+
|
|
57
|
+
| Name | Type | Default | Description |
|
|
58
|
+
| ---------------- | --------------------------------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
59
|
+
| `id` | `string` | `""` | Passed back as the first argument of `onChange` |
|
|
60
|
+
| `title` | `string` | `"Select Date"` | Label shown above the picker (non-range mode) |
|
|
61
|
+
| `startDateTitle` | `string` | `"Start Date"` | Label for the start picker (range mode) |
|
|
62
|
+
| `endDateTitle` | `string` | `"End Date"` | Label for the end picker (range mode) |
|
|
63
|
+
| `subLabel` | `string` | — | Secondary label shown below the title |
|
|
64
|
+
| `labelExtra` | `ReactElement` | — | Extra element rendered inline with the label |
|
|
65
|
+
| `infoElement` | `ReactElement` | — | Content shown in an InfoWindow tooltip next to the label |
|
|
66
|
+
| `customElement` | `ReactElement` | — | Custom element rendered to the right of the label row |
|
|
67
|
+
| `value` | `Date` | — | Selected date (non-range mode) |
|
|
68
|
+
| `startDate` | `Date` | — | Selected start date (range mode) |
|
|
69
|
+
| `endDate` | `Date` | — | Selected end date (range mode) |
|
|
70
|
+
| `minDate` | `Date` | — | Earliest selectable date |
|
|
71
|
+
| `maxDate` | `Date` | — | Latest selectable date |
|
|
72
|
+
| `range` | `boolean` | `false` | Renders two pickers for a start/end date range |
|
|
73
|
+
| `showTime` | `boolean` | `false` | Adds a time selector alongside the calendar |
|
|
74
|
+
| `hideDate` | `boolean` | `false` | Shows only the time picker (hides the calendar) |
|
|
75
|
+
| `timeInterval` | `number` | `5` | Minute step for the time picker |
|
|
76
|
+
| `timeSlots` | `TimeSlot[]` | — | Renders a custom time panel with fixed slots instead of a scrollable time list |
|
|
77
|
+
| `filterDate` | `number[] \| Date[] \| ((date: Date) => boolean)` | — | Restrict selectable dates. Number array: weekday indices (0=Sun). Date array: blocked specific dates. Function: return `true` to allow a date. |
|
|
78
|
+
| `optional` | `boolean` | `false` | Skips validation and shows a Clear button when a date is selected |
|
|
79
|
+
| `disabled` | `boolean` | `false` | Disables the picker |
|
|
80
|
+
| `autoFocus` | `boolean` | `false` | Opens the calendar on mount |
|
|
81
|
+
| `staticDropdown` | `boolean` | `false` | Renders the calendar inline (takes up space) instead of as an absolute overlay |
|
|
82
|
+
| `mobileView` | `boolean` | `false` | Renders a compact inline layout for mobile (label left, value right) |
|
|
83
|
+
| `darkMode` | `boolean` | `false` | Applies dark colour scheme to labels |
|
|
84
|
+
| `className` | `tailwind class` | — | Class applied to the outer container |
|
|
85
|
+
| `onChange` | `(id: string, value: Date \| undefined, type?: string) => void` | — | Called on date selection. `type` is `"start"` or `"end"` in range mode |
|
|
86
|
+
| `cellInput` | `CellInput` | — | Refer to Input Utils — enables cell/table editing mode |
|
|
87
|
+
|
|
88
|
+
### TimeSlot
|
|
89
|
+
|
|
90
|
+
| Name | Type | Description |
|
|
91
|
+
| ---------- | --------- | ---------------------------------- |
|
|
92
|
+
| `start` | `Date` | The time slot date/time |
|
|
93
|
+
| `disabled` | `boolean` | Renders the slot as non-selectable |
|
|
94
|
+
|
|
95
|
+
### Advanced Examples
|
|
96
|
+
|
|
97
|
+
```jsx
|
|
98
|
+
// Filter by function — weekdays only, within next 14 days
|
|
99
|
+
<InputDatePicker
|
|
100
|
+
title="Available Dates"
|
|
101
|
+
value={date}
|
|
102
|
+
filterDate={(date) => {
|
|
103
|
+
const day = date.getDay();
|
|
104
|
+
const twoWeeksAhead = new Date();
|
|
105
|
+
twoWeeksAhead.setDate(twoWeeksAhead.getDate() + 14);
|
|
106
|
+
return day !== 0 && day !== 6 && date <= twoWeeksAhead;
|
|
107
|
+
}}
|
|
108
|
+
minDate={new Date()}
|
|
109
|
+
onChange={(_id, value) => setDate(value)}
|
|
110
|
+
/>
|
|
111
|
+
|
|
112
|
+
// Time slots
|
|
113
|
+
<InputDatePicker
|
|
114
|
+
title="Book a Slot"
|
|
115
|
+
value={date}
|
|
116
|
+
showTime={true}
|
|
117
|
+
timeSlots={[
|
|
118
|
+
{ start: new Date(new Date().setHours(9, 0, 0, 0)) },
|
|
119
|
+
{ start: new Date(new Date().setHours(11, 15, 0, 0)), disabled: true },
|
|
120
|
+
{ start: new Date(new Date().setHours(14, 30, 0, 0)) },
|
|
121
|
+
]}
|
|
122
|
+
onChange={(_id, value) => setDate(value)}
|
|
123
|
+
/>
|
|
124
|
+
```
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { storiesOf } from "@storybook/react";
|
|
2
|
+
import React, { useRef, useState } from "react";
|
|
3
|
+
import { InputDatePicker } from ".";
|
|
4
|
+
import { Button } from "../../action/button";
|
|
5
|
+
import { StorySection } from "../../storyUtils";
|
|
6
|
+
import README from "./README.md";
|
|
7
|
+
|
|
8
|
+
const stories = storiesOf("Input", module);
|
|
9
|
+
|
|
10
|
+
stories.addParameters({
|
|
11
|
+
readme: {
|
|
12
|
+
content: README,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
stories.add("DatePicker", () => {
|
|
17
|
+
const ref = useRef<any>(null);
|
|
18
|
+
const currentDate = new Date();
|
|
19
|
+
|
|
20
|
+
const [date, setDate] = useState<Date | undefined>(currentDate);
|
|
21
|
+
const [startDate, setStartDate] = useState<Date | undefined>(currentDate);
|
|
22
|
+
const [endDate, setEndDate] = useState<Date | undefined>(currentDate);
|
|
23
|
+
const [timeDate, setTimeDate] = useState<Date | undefined>(currentDate);
|
|
24
|
+
const [slotDate, setSlotDate] = useState<Date | undefined>(currentDate);
|
|
25
|
+
const [filterDate, setFilterDate] = useState<Date | undefined>(currentDate);
|
|
26
|
+
const [optionalDate, setOptionalDate] = useState<Date | undefined>(undefined);
|
|
27
|
+
|
|
28
|
+
const handleChange =
|
|
29
|
+
(setter: React.Dispatch<React.SetStateAction<Date | undefined>>) =>
|
|
30
|
+
(_id: string, value: Date | undefined, _type?: string) =>
|
|
31
|
+
setter(value);
|
|
32
|
+
|
|
33
|
+
const handleRangeChange = (
|
|
34
|
+
_id: string,
|
|
35
|
+
value: Date | undefined,
|
|
36
|
+
type?: string
|
|
37
|
+
) => {
|
|
38
|
+
if (type === "start") setStartDate(value);
|
|
39
|
+
else if (type === "end") setEndDate(value);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<>
|
|
44
|
+
<StorySection
|
|
45
|
+
title="Default"
|
|
46
|
+
description="Basic date picker with a title label. Displays date in DD/MM/YY format."
|
|
47
|
+
>
|
|
48
|
+
<div className="w-64">
|
|
49
|
+
<InputDatePicker
|
|
50
|
+
title="Select Date"
|
|
51
|
+
value={date}
|
|
52
|
+
onChange={handleChange(setDate)}
|
|
53
|
+
/>
|
|
54
|
+
</div>
|
|
55
|
+
</StorySection>
|
|
56
|
+
|
|
57
|
+
<StorySection
|
|
58
|
+
title="Date + Time"
|
|
59
|
+
description="showTime=true adds a time selector alongside the calendar. timeInterval controls the minute step (default 5)."
|
|
60
|
+
>
|
|
61
|
+
<div className="w-64">
|
|
62
|
+
<InputDatePicker
|
|
63
|
+
title="Date & Time"
|
|
64
|
+
value={timeDate}
|
|
65
|
+
showTime={true}
|
|
66
|
+
timeInterval={15}
|
|
67
|
+
onChange={handleChange(setTimeDate)}
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
</StorySection>
|
|
71
|
+
|
|
72
|
+
<StorySection
|
|
73
|
+
title="Date Range"
|
|
74
|
+
description="range=true renders two pickers (Start Date / End Date). startDateTitle and endDateTitle customise the labels."
|
|
75
|
+
>
|
|
76
|
+
<div className="w-full max-w-md">
|
|
77
|
+
<InputDatePicker
|
|
78
|
+
range={true}
|
|
79
|
+
startDate={startDate}
|
|
80
|
+
endDate={endDate}
|
|
81
|
+
startDateTitle="From"
|
|
82
|
+
endDateTitle="To"
|
|
83
|
+
onChange={handleRangeChange}
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
</StorySection>
|
|
87
|
+
|
|
88
|
+
<StorySection
|
|
89
|
+
title="Disabled"
|
|
90
|
+
description="Basic date picker with a title label. Displays date in DD/MM/YY format."
|
|
91
|
+
>
|
|
92
|
+
<div className="w-64">
|
|
93
|
+
<InputDatePicker
|
|
94
|
+
title="Select Date"
|
|
95
|
+
value={date}
|
|
96
|
+
onChange={handleChange(setDate)}
|
|
97
|
+
disabled
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
</StorySection>
|
|
101
|
+
|
|
102
|
+
<StorySection
|
|
103
|
+
title="Filter Date (weekdays only)"
|
|
104
|
+
description="filterDate as a number array restricts selectable days. 0=Sunday, 1=Monday … 6=Saturday. Here only Mon–Fri are selectable."
|
|
105
|
+
>
|
|
106
|
+
<div className="w-64">
|
|
107
|
+
<InputDatePicker
|
|
108
|
+
title="Weekdays Only"
|
|
109
|
+
value={filterDate}
|
|
110
|
+
filterDate={[1, 2, 3, 4, 5]}
|
|
111
|
+
onChange={handleChange(setFilterDate)}
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
</StorySection>
|
|
115
|
+
|
|
116
|
+
<StorySection
|
|
117
|
+
title="Filter Date (function)"
|
|
118
|
+
description="filterDate as a function gives full control. Here weekends and dates more than 14 days ahead are blocked."
|
|
119
|
+
>
|
|
120
|
+
<div className="w-64">
|
|
121
|
+
<InputDatePicker
|
|
122
|
+
title="Custom Filter"
|
|
123
|
+
value={filterDate}
|
|
124
|
+
filterDate={(date) => {
|
|
125
|
+
const day = date.getDay();
|
|
126
|
+
const isWeekend = day === 0 || day === 6;
|
|
127
|
+
const twoWeeksAhead = new Date();
|
|
128
|
+
twoWeeksAhead.setDate(twoWeeksAhead.getDate() + 14);
|
|
129
|
+
return !isWeekend && date <= twoWeeksAhead;
|
|
130
|
+
}}
|
|
131
|
+
minDate={new Date()}
|
|
132
|
+
onChange={handleChange(setFilterDate)}
|
|
133
|
+
/>
|
|
134
|
+
</div>
|
|
135
|
+
</StorySection>
|
|
136
|
+
|
|
137
|
+
<StorySection
|
|
138
|
+
title="Time Slots"
|
|
139
|
+
description="timeSlots renders a custom time panel alongside the calendar. Disabled slots are shown but not selectable."
|
|
140
|
+
>
|
|
141
|
+
<div className="w-64">
|
|
142
|
+
<InputDatePicker
|
|
143
|
+
title="Time Slots"
|
|
144
|
+
value={slotDate}
|
|
145
|
+
showTime={true}
|
|
146
|
+
timeSlots={[
|
|
147
|
+
{ start: new Date(new Date().setHours(9, 0, 0, 0)) },
|
|
148
|
+
{
|
|
149
|
+
start: new Date(new Date().setHours(11, 15, 0, 0)),
|
|
150
|
+
disabled: true,
|
|
151
|
+
},
|
|
152
|
+
{ start: new Date(new Date().setHours(14, 30, 0, 0)) },
|
|
153
|
+
{ start: new Date(new Date().setHours(16, 45, 0, 0)) },
|
|
154
|
+
]}
|
|
155
|
+
onChange={handleChange(setSlotDate)}
|
|
156
|
+
/>
|
|
157
|
+
</div>
|
|
158
|
+
</StorySection>
|
|
159
|
+
|
|
160
|
+
<StorySection
|
|
161
|
+
title="Optional + Form Validation"
|
|
162
|
+
description="optional=true shows a Clear button and skips validation. Call handleSubmit() via ref to trigger validation on required pickers."
|
|
163
|
+
>
|
|
164
|
+
<div className="w-64">
|
|
165
|
+
<InputDatePicker
|
|
166
|
+
ref={ref}
|
|
167
|
+
title="Optional Date"
|
|
168
|
+
value={optionalDate}
|
|
169
|
+
optional={true}
|
|
170
|
+
onChange={handleChange(setOptionalDate)}
|
|
171
|
+
/>
|
|
172
|
+
<Button
|
|
173
|
+
className="mt-3"
|
|
174
|
+
size="small"
|
|
175
|
+
text="Validate"
|
|
176
|
+
type="normal"
|
|
177
|
+
onClick={() => ref.current?.handleSubmit()}
|
|
178
|
+
/>
|
|
179
|
+
</div>
|
|
180
|
+
</StorySection>
|
|
181
|
+
|
|
182
|
+
<StorySection
|
|
183
|
+
title="Static Dropdown"
|
|
184
|
+
description="staticDropdown=true renders the calendar inline (takes up space below) instead of as an absolute overlay."
|
|
185
|
+
>
|
|
186
|
+
<div className="w-64">
|
|
187
|
+
<InputDatePicker
|
|
188
|
+
title="Static Calendar"
|
|
189
|
+
value={date}
|
|
190
|
+
staticDropdown={true}
|
|
191
|
+
onChange={handleChange(setDate)}
|
|
192
|
+
/>
|
|
193
|
+
</div>
|
|
194
|
+
</StorySection>
|
|
195
|
+
</>
|
|
196
|
+
);
|
|
197
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Form
|
|
2
|
+
|
|
3
|
+
<!-- STORY -->
|
|
4
|
+
|
|
5
|
+
<hr>
|
|
6
|
+
|
|
7
|
+
A form wrapper that coordinates validation across multiple input refs. Calling `handleSubmit()` runs `handleSubmit()` on every ref in `refList` in parallel and only calls `handleComplete` if all pass.
|
|
8
|
+
|
|
9
|
+
### Import
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import { Form } from "blixify-ui-web/input/form";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Usage
|
|
16
|
+
|
|
17
|
+
```jsx
|
|
18
|
+
const formRef = useRef(null);
|
|
19
|
+
const emailRef = useRef(null);
|
|
20
|
+
const passwordRef = useRef(null);
|
|
21
|
+
|
|
22
|
+
<Form
|
|
23
|
+
ref={formRef}
|
|
24
|
+
refList={[emailRef, passwordRef]}
|
|
25
|
+
handleComplete={() => console.log("All valid")}
|
|
26
|
+
>
|
|
27
|
+
<TextInput ref={emailRef} id="email" type="email" label="Email" value={email} placeholder="..." onChange={...} />
|
|
28
|
+
<TextInput ref={passwordRef} id="password" type="password" label="Password" value={password} placeholder="..." onChange={...} containerClassName="mt-3" />
|
|
29
|
+
<Button className="mt-4" text="Submit" type="normal" onClick={() => formRef.current?.handleSubmit()} />
|
|
30
|
+
</Form>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Methods (via ref)
|
|
34
|
+
|
|
35
|
+
| Method | Returns | Description |
|
|
36
|
+
| ------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
37
|
+
| `handleSubmit()` | `Promise<void>` | Validates all refs. Calls `handleComplete()` on success, `handleOnFailValidation(ids)` on failure |
|
|
38
|
+
| `handleCheckValidation()` | `Promise<boolean>` | Same validation logic but returns `true`/`false` without calling `handleComplete` |
|
|
39
|
+
| `handleSave()` | `Promise<void>` | Calls `handleSubmit()` on all refs to capture data (e.g. signatures) but ignores validation failures. Calls `handleComplete(true)` |
|
|
40
|
+
|
|
41
|
+
### Required props
|
|
42
|
+
|
|
43
|
+
| Name | Type | Description |
|
|
44
|
+
| ---------- | ----------- | -------------------------------------------------------------- |
|
|
45
|
+
| `children` | `ReactNode` | Input components to render inside the form |
|
|
46
|
+
| `refList` | `any[]` | Refs to child components that expose a `handleSubmit()` method |
|
|
47
|
+
|
|
48
|
+
### Optional props
|
|
49
|
+
|
|
50
|
+
| Name | Type | Default | Description |
|
|
51
|
+
| ------------------------ | ----------------------------- | ------- | ---------------------------------------------------------------------------------------- |
|
|
52
|
+
| `className` | `tailwind class` | — | Class applied to the `<form>` element |
|
|
53
|
+
| `handleComplete` | `(isDraft?: boolean) => void` | — | Called when all inputs pass validation. `isDraft=true` when triggered via `handleSave()` |
|
|
54
|
+
| `handleOnFailValidation` | `(ids: string[]) => void` | — | Called when one or more inputs fail. Receives an array of the failed input `id` values |
|
|
55
|
+
| `disabledOnEnter` | `boolean` | `false` | When `true`, pressing Enter does not trigger form submission |
|