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,313 @@
|
|
|
1
|
+
import { storiesOf } from "@storybook/react";
|
|
2
|
+
import React, { useRef, useState } from "react";
|
|
3
|
+
import { FlexTable, FlexTableItem } from ".";
|
|
4
|
+
import { StorySection } from "../../storyUtils";
|
|
5
|
+
import { Button } from "../../action/button";
|
|
6
|
+
import { DataStructure, FlexMathQuery } from "../../data/dataTemplate/model";
|
|
7
|
+
import { Form } from "../../input/form";
|
|
8
|
+
import README from "./README.md";
|
|
9
|
+
|
|
10
|
+
const stories = storiesOf("Display", module);
|
|
11
|
+
|
|
12
|
+
stories.addParameters({
|
|
13
|
+
readme: {
|
|
14
|
+
content: README,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const researchCategories = [
|
|
19
|
+
{
|
|
20
|
+
title: "Test 1",
|
|
21
|
+
description: "Principal investigator and research staff salaries",
|
|
22
|
+
},
|
|
23
|
+
{ title: "Test 2", description: "Travel and transportation expenses" },
|
|
24
|
+
{ title: "Test 3", description: "Facility and space rental costs" },
|
|
25
|
+
// { title: "Test 4", description: "Laboratory supplies and materials" },
|
|
26
|
+
// { title: "Test 5", description: "Equipment maintenance and calibration" },
|
|
27
|
+
// { title: "Test 6", description: "Consulting and professional services" },
|
|
28
|
+
// {
|
|
29
|
+
// title: "Test 7",
|
|
30
|
+
// description: "Major equipment purchases and capital items",
|
|
31
|
+
// },
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const sampleData: FlexTableItem[] = [
|
|
35
|
+
{
|
|
36
|
+
id: "1",
|
|
37
|
+
title: "Principal Investigator Salary",
|
|
38
|
+
category: "Test 1",
|
|
39
|
+
year1: 50000,
|
|
40
|
+
year2: 52000,
|
|
41
|
+
year3: 54000,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "2",
|
|
45
|
+
title: "Research Assistant Salary",
|
|
46
|
+
category: "Test 1",
|
|
47
|
+
year1: 30000,
|
|
48
|
+
year2: 31000,
|
|
49
|
+
year3: 32000,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "3",
|
|
53
|
+
title: "Conference Travel",
|
|
54
|
+
category: "Test 2",
|
|
55
|
+
year1: 5000,
|
|
56
|
+
year2: 5500,
|
|
57
|
+
year3: 6000,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "4",
|
|
61
|
+
title: "Field Work Travel",
|
|
62
|
+
category: "Test 2",
|
|
63
|
+
year1: 8000,
|
|
64
|
+
year2: 8500,
|
|
65
|
+
year3: 9000,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: "5",
|
|
69
|
+
title: "Laboratory Rent",
|
|
70
|
+
category: "Test 3",
|
|
71
|
+
year1: 12000,
|
|
72
|
+
year2: 12000,
|
|
73
|
+
year3: 12000,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: "6",
|
|
77
|
+
title: "Chemicals and Reagents",
|
|
78
|
+
category: "Test 4",
|
|
79
|
+
year1: 15000,
|
|
80
|
+
year2: 16000,
|
|
81
|
+
year3: 17000,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: "7",
|
|
85
|
+
title: "Equipment Calibration",
|
|
86
|
+
category: "Test 5",
|
|
87
|
+
year1: 3000,
|
|
88
|
+
year2: 3200,
|
|
89
|
+
year3: 3400,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: "8",
|
|
93
|
+
title: "Statistical Analysis Consultant",
|
|
94
|
+
category: "Test 6",
|
|
95
|
+
year1: 5000,
|
|
96
|
+
year2: 5000,
|
|
97
|
+
year3: 5000,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: "9",
|
|
101
|
+
title: "Microscope",
|
|
102
|
+
category: "Test 7",
|
|
103
|
+
year1: 25000,
|
|
104
|
+
year2: 0,
|
|
105
|
+
year3: 0,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: "10",
|
|
109
|
+
title: "Computer Workstation",
|
|
110
|
+
category: "Test 7",
|
|
111
|
+
year1: 8000,
|
|
112
|
+
year2: 0,
|
|
113
|
+
year3: 4000,
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
const baseColumns: DataStructure[] = [
|
|
118
|
+
{ id: "year1", name: "Year 1", type: "number" },
|
|
119
|
+
{ id: "year2", name: "Year 2", type: "number" },
|
|
120
|
+
{ id: "year3", name: "Year 3", type: "number" },
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
const columnsWithMath: DataStructure[] = [
|
|
124
|
+
...baseColumns,
|
|
125
|
+
{
|
|
126
|
+
id: "year4",
|
|
127
|
+
name: "Year 4",
|
|
128
|
+
type: "list",
|
|
129
|
+
listSelection: ["Option 1", "Option 2", "Option 3"],
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: "conditionalYear",
|
|
133
|
+
name: "Conditional Year",
|
|
134
|
+
type: "math",
|
|
135
|
+
mathExpression: "year4 == 'Option 1' ? year2 * 2 + 1 : year3 * 3",
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
const flexMathQueries: FlexMathQuery[] = [
|
|
140
|
+
{ type: "categoryPercentage", targetCategory: "Test 2", maxPercentage: 50 },
|
|
141
|
+
{
|
|
142
|
+
type: "columnPercentage",
|
|
143
|
+
targetColumn: "year1",
|
|
144
|
+
maxPercentage: 70,
|
|
145
|
+
subtotalColumns: ["year2", "year3"],
|
|
146
|
+
},
|
|
147
|
+
];
|
|
148
|
+
|
|
149
|
+
stories.add("FlexTable", () => {
|
|
150
|
+
const [data, setData] = useState<FlexTableItem[]>(sampleData);
|
|
151
|
+
const [viewOnlyData] = useState<FlexTableItem[]>(sampleData);
|
|
152
|
+
|
|
153
|
+
const formRef = useRef<any>(null);
|
|
154
|
+
const tableRef = useRef<any>(null);
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<>
|
|
158
|
+
<StorySection
|
|
159
|
+
title="Default (Editable)"
|
|
160
|
+
description="Basic editable table with category subtotals. Each category row shows a subtotal. onChangeData fires whenever a cell value changes."
|
|
161
|
+
>
|
|
162
|
+
<div className="w-full">
|
|
163
|
+
<FlexTable
|
|
164
|
+
label="Research Budget"
|
|
165
|
+
data={data}
|
|
166
|
+
columns={baseColumns}
|
|
167
|
+
categoryList={researchCategories}
|
|
168
|
+
onChangeData={setData}
|
|
169
|
+
/>
|
|
170
|
+
</div>
|
|
171
|
+
</StorySection>
|
|
172
|
+
|
|
173
|
+
<StorySection
|
|
174
|
+
title="With Grand Total"
|
|
175
|
+
description="showGrandTotal=true adds a grand total row summing all numeric columns across all categories."
|
|
176
|
+
>
|
|
177
|
+
<div className="w-full">
|
|
178
|
+
<FlexTable
|
|
179
|
+
label="Research Budget with Grand Total"
|
|
180
|
+
data={data}
|
|
181
|
+
columns={baseColumns}
|
|
182
|
+
categoryList={researchCategories}
|
|
183
|
+
showGrandTotal={true}
|
|
184
|
+
onChangeData={setData}
|
|
185
|
+
/>
|
|
186
|
+
</div>
|
|
187
|
+
</StorySection>
|
|
188
|
+
|
|
189
|
+
<StorySection
|
|
190
|
+
title="Without Total Row"
|
|
191
|
+
description="showTotal=false hides the per-category subtotal rows."
|
|
192
|
+
>
|
|
193
|
+
<div className="w-full">
|
|
194
|
+
<FlexTable
|
|
195
|
+
label="Research Budget (No Subtotals)"
|
|
196
|
+
data={data}
|
|
197
|
+
columns={baseColumns}
|
|
198
|
+
categoryList={researchCategories}
|
|
199
|
+
showTotal={false}
|
|
200
|
+
onChangeData={setData}
|
|
201
|
+
/>
|
|
202
|
+
</div>
|
|
203
|
+
</StorySection>
|
|
204
|
+
|
|
205
|
+
<StorySection
|
|
206
|
+
title="Math & List Columns"
|
|
207
|
+
description="Columns with type='math' compute values from a mathExpression using other column values. type='list' renders a dropdown. The math column here evaluates conditionally based on the list selection."
|
|
208
|
+
>
|
|
209
|
+
<div className="w-full">
|
|
210
|
+
<FlexTable
|
|
211
|
+
label="Budget with Computed Columns"
|
|
212
|
+
data={data}
|
|
213
|
+
columns={columnsWithMath}
|
|
214
|
+
categoryList={researchCategories}
|
|
215
|
+
onChangeData={setData}
|
|
216
|
+
/>
|
|
217
|
+
</div>
|
|
218
|
+
</StorySection>
|
|
219
|
+
|
|
220
|
+
<StorySection
|
|
221
|
+
title="FlexMathQueries Validation"
|
|
222
|
+
description="flexMathQueries adds validation rules. categoryPercentage checks that a category's total does not exceed a percentage of the grand total. columnPercentage checks that one column does not exceed a percentage of the sum of other columns."
|
|
223
|
+
>
|
|
224
|
+
<div className="w-full space-y-3">
|
|
225
|
+
<Button
|
|
226
|
+
text="Submit & Validate"
|
|
227
|
+
size="small"
|
|
228
|
+
type="normal"
|
|
229
|
+
onClick={() => formRef.current?.handleSubmit()}
|
|
230
|
+
/>
|
|
231
|
+
<Form ref={formRef} refList={[tableRef]}>
|
|
232
|
+
<FlexTable
|
|
233
|
+
label="Budget with Validation Rules"
|
|
234
|
+
ref={tableRef}
|
|
235
|
+
data={data}
|
|
236
|
+
columns={columnsWithMath}
|
|
237
|
+
categoryList={researchCategories}
|
|
238
|
+
flexMathQueries={flexMathQueries}
|
|
239
|
+
onChangeData={setData}
|
|
240
|
+
onAddColumn={(col) => console.log("column added", col)}
|
|
241
|
+
onRemoveColumn={(key) => console.log("column removed", key)}
|
|
242
|
+
/>
|
|
243
|
+
</Form>
|
|
244
|
+
</div>
|
|
245
|
+
</StorySection>
|
|
246
|
+
|
|
247
|
+
<StorySection
|
|
248
|
+
title="Max Rows per Category"
|
|
249
|
+
description="maxRows limits how many rows can be added per category. The add-row button is hidden once the limit is reached."
|
|
250
|
+
>
|
|
251
|
+
<div className="w-full">
|
|
252
|
+
<FlexTable
|
|
253
|
+
label="Budget (Max 2 rows per category)"
|
|
254
|
+
data={data}
|
|
255
|
+
columns={baseColumns}
|
|
256
|
+
categoryList={researchCategories}
|
|
257
|
+
maxRows={2}
|
|
258
|
+
onChangeData={setData}
|
|
259
|
+
/>
|
|
260
|
+
</div>
|
|
261
|
+
</StorySection>
|
|
262
|
+
|
|
263
|
+
<StorySection
|
|
264
|
+
title="Hide Category Column"
|
|
265
|
+
description="hideCategory=true removes the category grouping and renders a flat list of rows."
|
|
266
|
+
>
|
|
267
|
+
<div className="w-full">
|
|
268
|
+
<FlexTable
|
|
269
|
+
label="Flat Budget Table"
|
|
270
|
+
data={data}
|
|
271
|
+
columns={baseColumns}
|
|
272
|
+
hideCategory={true}
|
|
273
|
+
onChangeData={setData}
|
|
274
|
+
/>
|
|
275
|
+
</div>
|
|
276
|
+
</StorySection>
|
|
277
|
+
|
|
278
|
+
<StorySection
|
|
279
|
+
title="View Only (disabled)"
|
|
280
|
+
description="disabled=true removes all editing controls — no add/remove row, no cell editing, no add column."
|
|
281
|
+
>
|
|
282
|
+
<div className="w-full">
|
|
283
|
+
<FlexTable
|
|
284
|
+
label="Budget (Read Only)"
|
|
285
|
+
data={viewOnlyData}
|
|
286
|
+
columns={baseColumns}
|
|
287
|
+
categoryList={researchCategories}
|
|
288
|
+
showGrandTotal={true}
|
|
289
|
+
disabled={true}
|
|
290
|
+
/>
|
|
291
|
+
</div>
|
|
292
|
+
</StorySection>
|
|
293
|
+
|
|
294
|
+
<StorySection
|
|
295
|
+
title="Dark Mode"
|
|
296
|
+
description="Pass darkMode=true and optionally darkModeBg to customise the background."
|
|
297
|
+
dark
|
|
298
|
+
>
|
|
299
|
+
<div className="w-full">
|
|
300
|
+
<FlexTable
|
|
301
|
+
label="Budget (Dark Mode)"
|
|
302
|
+
data={data}
|
|
303
|
+
columns={baseColumns}
|
|
304
|
+
categoryList={researchCategories}
|
|
305
|
+
darkMode={true}
|
|
306
|
+
darkModeBg="bg-gray-900"
|
|
307
|
+
onChangeData={setData}
|
|
308
|
+
/>
|
|
309
|
+
</div>
|
|
310
|
+
</StorySection>
|
|
311
|
+
</>
|
|
312
|
+
);
|
|
313
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Grid
|
|
2
|
+
|
|
3
|
+
<!-- STORY -->
|
|
4
|
+
|
|
5
|
+
<hr>
|
|
6
|
+
|
|
7
|
+
A card grid with pagination, horizontal scroll, infinity scroll, drag-and-drop, custom card slots, and dark mode support.
|
|
8
|
+
|
|
9
|
+
##### Import
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import { Grid, GridClass } from "blixify-ui-web/display/grid";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
##### Usage
|
|
16
|
+
|
|
17
|
+
Cursor pagination with horizontal scroll:
|
|
18
|
+
|
|
19
|
+
```jsx
|
|
20
|
+
const [pageIndex, setPageIndex] = useState(0);
|
|
21
|
+
|
|
22
|
+
<Grid
|
|
23
|
+
data={data}
|
|
24
|
+
limit={5}
|
|
25
|
+
loading={false}
|
|
26
|
+
paginationType="cursor"
|
|
27
|
+
cursor={cursor}
|
|
28
|
+
pageIndex={pageIndex}
|
|
29
|
+
size={data.length}
|
|
30
|
+
itemClassName="shadow-md rounded"
|
|
31
|
+
horizontalScroll={true}
|
|
32
|
+
infinityScroll
|
|
33
|
+
handleUpdatePageIndex={(value) => {
|
|
34
|
+
if (typeof value === "number") setPageIndex(value);
|
|
35
|
+
else setPageIndex((p) => (value === "next" ? p + 1 : p - 1));
|
|
36
|
+
}}
|
|
37
|
+
/>;
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Page pagination with custom column layout:
|
|
41
|
+
|
|
42
|
+
```jsx
|
|
43
|
+
<Grid
|
|
44
|
+
data={data}
|
|
45
|
+
limit={5}
|
|
46
|
+
loading={false}
|
|
47
|
+
paginationType="page"
|
|
48
|
+
size={data.length}
|
|
49
|
+
pageIndex={pageIndex}
|
|
50
|
+
gridColClassName="sm:grid-cols-2 sm:gap-x-6 lg:grid-cols-3"
|
|
51
|
+
handleUpdatePageIndex={handlePagination}
|
|
52
|
+
/>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Custom ribbon on card image:
|
|
56
|
+
|
|
57
|
+
```jsx
|
|
58
|
+
<Grid
|
|
59
|
+
data={data}
|
|
60
|
+
loading={false}
|
|
61
|
+
renderImgRibbon={(id) => {
|
|
62
|
+
if (id === "1")
|
|
63
|
+
return (
|
|
64
|
+
<div className="absolute top-5 -left-9 w-[50%] bg-yellow-500 text-white text-xs font-bold p-2 text-center transform -rotate-45">
|
|
65
|
+
WINNER
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
return null;
|
|
69
|
+
}}
|
|
70
|
+
/>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
##### Required props
|
|
74
|
+
|
|
75
|
+
| Name | Type | Description |
|
|
76
|
+
| --------- | ------------- | ------------------------------------- |
|
|
77
|
+
| `data` | `GridClass[]` | Array of card data items |
|
|
78
|
+
| `loading` | `boolean` | Shows a loading indicator when `true` |
|
|
79
|
+
|
|
80
|
+
##### Optional props
|
|
81
|
+
|
|
82
|
+
| Name | Type | Default | Description |
|
|
83
|
+
| ----------------------- | ------------------------------------------ | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
84
|
+
| `paginationType` | `"cursor" \| "page"` | — | Enables pagination. `"cursor"` for token-based, `"page"` for numbered pages |
|
|
85
|
+
| `limit` | `number` | `5` | Cards per page. Required when `paginationType` is set |
|
|
86
|
+
| `pageIndex` | `number` | — | Current page index (0-based). Required when `paginationType` is set |
|
|
87
|
+
| `cursor` | `any` | — | Pass a truthy value while more pages exist; falsy on the last page. Required when `paginationType="cursor"` |
|
|
88
|
+
| `size` | `number` | — | Total record count. Required when `paginationType="page"` to calculate page count |
|
|
89
|
+
| `hidePagination` | `boolean` | `false` | Hide the pagination bar |
|
|
90
|
+
| `horizontalScroll` | `boolean` | `false` | Render cards in a horizontally scrollable row instead of a grid |
|
|
91
|
+
| `infinityScroll` | `boolean` | `false` | Auto-load the next page when the user scrolls to the end. Requires `horizontalScroll=true` and `paginationType="cursor"` |
|
|
92
|
+
| `gridColClassName` | `string` | `"sm:grid-cols-2 sm:gap-x-6 lg:grid-cols-3 lg:gap-x-8"` | Tailwind grid column classes |
|
|
93
|
+
| `className` | `string` | — | Tailwind classes for the outer container |
|
|
94
|
+
| `itemClassName` | `string` | — | Tailwind classes applied to each card, e.g. `"shadow-md rounded"` |
|
|
95
|
+
| `selectedItemClassName` | `string` | — | Tailwind classes applied to cards whose id is in `selectedItemsId` |
|
|
96
|
+
| `selectedItemsId` | `string[]` | — | IDs of cards to highlight with `selectedItemClassName` |
|
|
97
|
+
| `customGridItems` | `{ [id: string]: ReactElement }` | — | Replace a specific card with custom JSX. The key must match the item's `id` in `data` |
|
|
98
|
+
| `imgContain` | `boolean` | `false` | Use `object-contain` instead of `object-cover` for card images |
|
|
99
|
+
| `darkMode` | `boolean` | `false` | Enable dark mode card styling |
|
|
100
|
+
| `darkModeBg` | `string` | — | Tailwind bg class for dark mode cards, e.g. `"bg-gray-800"` |
|
|
101
|
+
| `newTabUrl` | `string` | — | Prepends a link to each card. The card `id` is appended to this URL |
|
|
102
|
+
| `addNewTabUrl` | `string` | — | URL appended to the add-card action link |
|
|
103
|
+
| `draggable` | `boolean` | `false` | Enable drag-and-drop reordering of cards |
|
|
104
|
+
| `droppable` | `boolean` | `false` | Allow cards to be dropped onto other cards |
|
|
105
|
+
| `renderImgRibbon` | `(id: string) => ReactElement \| null` | — | Return a ReactElement to overlay on the card image (e.g. a ribbon badge), or `null` for no ribbon |
|
|
106
|
+
| `onClickData` | `(id: string) => void` | — | Called with the card id when a card is clicked |
|
|
107
|
+
| `onDropData` | `(dragId: string, dropId: string) => void` | — | Called when a card is dropped onto another card |
|
|
108
|
+
| `handleUpdatePageIndex` | `(value: string \| number) => void` | — | Called with `"next"`, `"prev"`, or a page number when the user navigates |
|
|
109
|
+
|
|
110
|
+
##### GridClass
|
|
111
|
+
|
|
112
|
+
| Name | Type | Required | Description |
|
|
113
|
+
| -------------- | ------------------------ | -------- | --------------------------------------------------- |
|
|
114
|
+
| `id` | `string` | yes | Unique card identifier |
|
|
115
|
+
| `title` | `string` | yes | Card heading |
|
|
116
|
+
| `description` | `string \| ReactElement` | yes | Card body text or custom JSX |
|
|
117
|
+
| `tags` | `string[]` | no | Tag badges shown on the card |
|
|
118
|
+
| `imageUrl` | `string` | no | URL for the card image |
|
|
119
|
+
| `imageElement` | `ReactElement` | no | Custom image element — overrides `imageUrl` |
|
|
120
|
+
| `ribbonText` | `string` | no | Built-in ribbon badge text shown on the card image |
|
|
121
|
+
| `extra` | `any` | no | Additional data passed through for custom rendering |
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { storiesOf } from "@storybook/react";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import { Grid, GridClass } from ".";
|
|
4
|
+
import { StorySection } from "../../storyUtils";
|
|
5
|
+
import README from "./README.md";
|
|
6
|
+
|
|
7
|
+
const stories = storiesOf("Display", module);
|
|
8
|
+
|
|
9
|
+
stories.addParameters({
|
|
10
|
+
readme: {
|
|
11
|
+
content: README,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const data: GridClass[] = [
|
|
16
|
+
{
|
|
17
|
+
id: "1",
|
|
18
|
+
title: "Nike Court Vision",
|
|
19
|
+
description: "Nike Men's Court Vision Low Next Nature Shoes - Black",
|
|
20
|
+
tags: ["Sports"],
|
|
21
|
+
imageUrl: "https://cf.shopee.com.my/file/fef57a9b0d40a0626def6fdc993c442a",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "2",
|
|
25
|
+
title: "Nike Air Max 2X",
|
|
26
|
+
description: "Nike Men's Air Max 2X Shoes - White",
|
|
27
|
+
tags: ["Sports", "Promotions"],
|
|
28
|
+
imageUrl: "https://cf.shopee.com.my/file/6df4da8ff019bfa08c1bcba4bbe3c983",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "3",
|
|
32
|
+
title: "Nike Air Max 2X",
|
|
33
|
+
description: "Nike Men's Air Max 2X Shoes - White",
|
|
34
|
+
tags: ["Sports", "Promotions"],
|
|
35
|
+
imageUrl: "https://cf.shopee.com.my/file/6df4da8ff019bfa08c1bcba4bbe3c983",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: "4",
|
|
39
|
+
title: "Nike Air Max 2X",
|
|
40
|
+
description: "Nike Men's Air Max 2X Shoes - White",
|
|
41
|
+
tags: ["Sports", "Promotions"],
|
|
42
|
+
ribbonText: "SALE",
|
|
43
|
+
imageUrl: "https://cf.shopee.com.my/file/6df4da8ff019bfa08c1bcba4bbe3c983",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: "5",
|
|
47
|
+
title: "Nike Air Max 2X",
|
|
48
|
+
description: "Nike Men's Air Max 2X Shoes - White",
|
|
49
|
+
tags: ["Sports"],
|
|
50
|
+
imageUrl: "https://cf.shopee.com.my/file/6df4da8ff019bfa08c1bcba4bbe3c983",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "6",
|
|
54
|
+
title: "Nike Air Max 2X",
|
|
55
|
+
description: "Nike Men's Air Max 2X Shoes - White",
|
|
56
|
+
tags: ["Sports", "Promotions"],
|
|
57
|
+
imageUrl: "https://cf.shopee.com.my/file/6df4da8ff019bfa08c1bcba4bbe3c983",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "7",
|
|
61
|
+
title: "Nike Air Max 2X",
|
|
62
|
+
description: "Nike Men's Air Max 2X Shoes - White",
|
|
63
|
+
tags: ["Sports"],
|
|
64
|
+
imageUrl: "https://cf.shopee.com.my/file/6df4da8ff019bfa08c1bcba4bbe3c983",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "8",
|
|
68
|
+
title: "Nike Air Max 2X",
|
|
69
|
+
description: "Nike Men's Air Max 2X Shoes - White",
|
|
70
|
+
tags: ["Sports", "Promotions"],
|
|
71
|
+
imageUrl: "https://cf.shopee.com.my/file/6df4da8ff019bfa08c1bcba4bbe3c983",
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
const renderImgRibbon = (id: string) => {
|
|
76
|
+
if (id === "1" || id === "2") {
|
|
77
|
+
return (
|
|
78
|
+
<div className="absolute top-5 -left-9 w-[50%] bg-yellow-500 text-white text-xs font-bold p-2 text-center transform -rotate-45">
|
|
79
|
+
<span>WINNER</span>
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
stories.add("Grid", () => {
|
|
87
|
+
const [pageIndex, setPageIndex] = useState(0);
|
|
88
|
+
const limit = 5;
|
|
89
|
+
const cursor = true;
|
|
90
|
+
|
|
91
|
+
const handlePagination = (value: string | number) => {
|
|
92
|
+
if (typeof value === "number") {
|
|
93
|
+
setPageIndex(value);
|
|
94
|
+
} else {
|
|
95
|
+
setPageIndex((prev) => (value === "next" ? prev + 1 : prev - 1));
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<>
|
|
101
|
+
<StorySection
|
|
102
|
+
title="Cursor Pagination"
|
|
103
|
+
description="Use paginationType='cursor' for token-based pagination (e.g. Firestore). Pass a truthy cursor while more data exists. infinityScroll combined with horizontalScroll auto-loads the next page when the user scrolls to the end."
|
|
104
|
+
>
|
|
105
|
+
<div className="w-full">
|
|
106
|
+
<Grid
|
|
107
|
+
data={data}
|
|
108
|
+
limit={limit}
|
|
109
|
+
loading={false}
|
|
110
|
+
paginationType="cursor"
|
|
111
|
+
cursor={cursor}
|
|
112
|
+
pageIndex={pageIndex}
|
|
113
|
+
size={data.length}
|
|
114
|
+
itemClassName="shadow-md rounded"
|
|
115
|
+
horizontalScroll={true}
|
|
116
|
+
infinityScroll
|
|
117
|
+
handleUpdatePageIndex={handlePagination}
|
|
118
|
+
renderImgRibbon={renderImgRibbon}
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
</StorySection>
|
|
122
|
+
|
|
123
|
+
<StorySection
|
|
124
|
+
title="Custom Grid Item"
|
|
125
|
+
description="Pass customGridItems with a map of id → ReactElement to replace a specific card with fully custom content. The key must match the item's id in data."
|
|
126
|
+
>
|
|
127
|
+
<div className="w-full">
|
|
128
|
+
<Grid
|
|
129
|
+
data={data}
|
|
130
|
+
limit={limit}
|
|
131
|
+
loading={false}
|
|
132
|
+
paginationType="cursor"
|
|
133
|
+
cursor={cursor}
|
|
134
|
+
pageIndex={pageIndex}
|
|
135
|
+
size={data.length}
|
|
136
|
+
itemClassName="shadow-md rounded"
|
|
137
|
+
horizontalScroll={true}
|
|
138
|
+
handleUpdatePageIndex={handlePagination}
|
|
139
|
+
customGridItems={{
|
|
140
|
+
"2": (
|
|
141
|
+
<div className="w-48 h-full flex flex-col justify-center items-center bg-primary-700 text-white p-4 font-thin">
|
|
142
|
+
<h1 className="text-3xl">Custom item</h1>
|
|
143
|
+
<p className="mt-6 text-sm">
|
|
144
|
+
This card replaces the default grid item for id="2".
|
|
145
|
+
</p>
|
|
146
|
+
</div>
|
|
147
|
+
),
|
|
148
|
+
}}
|
|
149
|
+
/>
|
|
150
|
+
</div>
|
|
151
|
+
</StorySection>
|
|
152
|
+
|
|
153
|
+
<StorySection
|
|
154
|
+
title="Page Pagination"
|
|
155
|
+
description="Use paginationType='page' for numbered page navigation. Pass size (total record count) so the component can calculate the page count. gridColClassName overrides the default 3-column layout."
|
|
156
|
+
>
|
|
157
|
+
<div className="w-full">
|
|
158
|
+
<Grid
|
|
159
|
+
data={data}
|
|
160
|
+
limit={limit}
|
|
161
|
+
loading={false}
|
|
162
|
+
paginationType="page"
|
|
163
|
+
size={data.length}
|
|
164
|
+
pageIndex={pageIndex}
|
|
165
|
+
gridColClassName="sm:grid-cols-2 sm:gap-x-6 lg:grid-cols-3"
|
|
166
|
+
handleUpdatePageIndex={handlePagination}
|
|
167
|
+
renderImgRibbon={renderImgRibbon}
|
|
168
|
+
/>
|
|
169
|
+
</div>
|
|
170
|
+
</StorySection>
|
|
171
|
+
|
|
172
|
+
<StorySection
|
|
173
|
+
title="Dark Mode"
|
|
174
|
+
description="Pass darkMode=true and darkModeBg to customise the card background colour."
|
|
175
|
+
dark
|
|
176
|
+
>
|
|
177
|
+
<div className="w-full">
|
|
178
|
+
<Grid
|
|
179
|
+
data={data}
|
|
180
|
+
limit={limit}
|
|
181
|
+
loading={false}
|
|
182
|
+
paginationType="page"
|
|
183
|
+
size={data.length}
|
|
184
|
+
pageIndex={pageIndex}
|
|
185
|
+
gridColClassName="sm:grid-cols-2 sm:gap-x-6 lg:grid-cols-3"
|
|
186
|
+
darkMode={true}
|
|
187
|
+
darkModeBg="bg-gray-800"
|
|
188
|
+
handleUpdatePageIndex={handlePagination}
|
|
189
|
+
renderImgRibbon={renderImgRibbon}
|
|
190
|
+
/>
|
|
191
|
+
</div>
|
|
192
|
+
</StorySection>
|
|
193
|
+
|
|
194
|
+
<StorySection
|
|
195
|
+
title="Ribbon Text"
|
|
196
|
+
description="Set ribbonText on a GridClass item to show a built-in ribbon badge on the card image. Use renderImgRibbon for a fully custom ribbon element."
|
|
197
|
+
>
|
|
198
|
+
<div className="w-full">
|
|
199
|
+
<Grid
|
|
200
|
+
data={data.slice(0, 4)}
|
|
201
|
+
limit={limit}
|
|
202
|
+
loading={false}
|
|
203
|
+
renderImgRibbon={renderImgRibbon}
|
|
204
|
+
/>
|
|
205
|
+
</div>
|
|
206
|
+
</StorySection>
|
|
207
|
+
|
|
208
|
+
<StorySection
|
|
209
|
+
title="Selected Items"
|
|
210
|
+
description="Pass selectedItemsId and selectedItemClassName to highlight specific cards. Useful for multi-select UIs."
|
|
211
|
+
>
|
|
212
|
+
<div className="w-full">
|
|
213
|
+
<Grid
|
|
214
|
+
data={data.slice(0, 4)}
|
|
215
|
+
limit={limit}
|
|
216
|
+
loading={false}
|
|
217
|
+
selectedItemsId={["1", "3"]}
|
|
218
|
+
selectedItemClassName="ring-2 ring-primary-500"
|
|
219
|
+
onClickData={(id) => console.log("clicked", id)}
|
|
220
|
+
/>
|
|
221
|
+
</div>
|
|
222
|
+
</StorySection>
|
|
223
|
+
|
|
224
|
+
<StorySection
|
|
225
|
+
title="Loading State"
|
|
226
|
+
description="Pass loading=true to show a loading indicator while data is being fetched."
|
|
227
|
+
>
|
|
228
|
+
<div className="w-full">
|
|
229
|
+
<Grid data={[]} loading={true} />
|
|
230
|
+
</div>
|
|
231
|
+
</StorySection>
|
|
232
|
+
</>
|
|
233
|
+
);
|
|
234
|
+
});
|