tembro 3.1.6 → 3.1.8
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/CHANGELOG.md +1 -1
- package/README.md +241 -91
- package/dist/components/ui/dialog/index.d.ts +3 -1
- package/dist/components/ui/select/index.d.ts +6 -3
- package/dist/showcase/package-meta.d.ts +3 -3
- package/dist/showcase/premium/wizard/index.cjs +1 -0
- package/dist/showcase/premium/wizard/index.d.ts +2 -0
- package/dist/showcase/premium/wizard/index.js +1 -0
- package/dist/showcase/premium/wizard/mock.cjs +1 -0
- package/dist/showcase/premium/wizard/mock.d.ts +2 -0
- package/dist/showcase/premium/wizard/mock.js +1 -0
- package/dist/showcase/premium/wizard/showcase.cjs +1 -0
- package/dist/showcase/premium/wizard/showcase.d.ts +2 -0
- package/dist/showcase/premium/wizard/showcase.js +1 -0
- package/dist/showcase/search-utils.d.ts +1 -1
- package/dist/showcase/site-data.d.ts +6 -6
- package/dist/src/components/layout/app-sidebar.cjs +1 -1
- package/dist/src/components/layout/app-sidebar.js +59 -41
- package/dist/src/components/theme-provider.cjs +1 -1
- package/dist/src/components/theme-provider.js +1 -1
- package/dist/src/components/ui/dialog/index.cjs +1 -1
- package/dist/src/components/ui/dialog/index.js +14 -7
- package/dist/src/components/ui/select/index.cjs +1 -1
- package/dist/src/components/ui/select/index.js +30 -29
- package/dist/src/index.cjs +1 -1
- package/dist/src/index.js +101 -101
- package/dist/src/showcase/component-api-schema.cjs +1 -1
- package/dist/src/showcase/component-api-schema.js +868 -9
- package/dist/src/showcase/demo-snippets/forms/index.cjs +1 -1
- package/dist/src/showcase/demo-snippets/forms/index.js +1 -1
- package/dist/src/showcase/fallback.cjs +4 -4
- package/dist/src/showcase/fallback.js +354 -181
- package/dist/src/showcase/index.cjs +1 -1
- package/dist/src/showcase/index.js +2 -2
- package/dist/src/showcase/package-meta.cjs +1 -1
- package/dist/src/showcase/package-meta.js +1 -1
- package/dist/src/showcase/premium/app-sidebar/mock.cjs +3 -2
- package/dist/src/showcase/premium/app-sidebar/mock.js +1 -1
- package/dist/src/showcase/premium/app-sidebar/showcase.cjs +1 -1
- package/dist/src/showcase/premium/app-sidebar/showcase.js +1 -1
- package/dist/src/showcase/premium/async-select/showcase.cjs +1 -1
- package/dist/src/showcase/premium/async-select/showcase.js +118 -74
- package/dist/src/showcase/premium/avatar/showcase.cjs +1 -1
- package/dist/src/showcase/premium/avatar/showcase.js +5 -5
- package/dist/src/showcase/premium/dialog/mock.cjs +6 -1
- package/dist/src/showcase/premium/dialog/mock.js +1 -1
- package/dist/src/showcase/premium/dialog/showcase.cjs +1 -1
- package/dist/src/showcase/premium/dialog/showcase.js +101 -39
- package/dist/src/showcase/premium/form-wrapper/mock.cjs +2 -2
- package/dist/src/showcase/premium/form-wrapper/mock.js +2 -2
- package/dist/src/showcase/premium/form-wrapper/showcase.cjs +1 -1
- package/dist/src/showcase/premium/form-wrapper/showcase.js +1 -1
- package/dist/src/showcase/premium/index.cjs +1 -1
- package/dist/src/showcase/premium/index.js +9 -3
- package/dist/src/showcase/premium/input/showcase.cjs +1 -1
- package/dist/src/showcase/premium/input/showcase.js +1 -1
- package/dist/src/showcase/premium/json-input/showcase.cjs +1 -1
- package/dist/src/showcase/premium/json-input/showcase.js +1 -1
- package/dist/src/showcase/premium/select/showcase.cjs +1 -1
- package/dist/src/showcase/premium/select/showcase.js +53 -0
- package/dist/src/showcase/premium/table/mock.cjs +1 -1
- package/dist/src/showcase/premium/table/mock.js +1 -1
- package/dist/src/showcase/premium/types.cjs +1 -1
- package/dist/src/showcase/premium/types.js +1 -1
- package/dist/src/showcase/premium/wizard/index.cjs +1 -0
- package/dist/src/showcase/premium/wizard/index.js +3 -0
- package/dist/src/showcase/premium/wizard/mock.cjs +25 -0
- package/dist/src/showcase/premium/wizard/mock.js +32 -0
- package/dist/src/showcase/premium/wizard/showcase.cjs +1 -0
- package/dist/src/showcase/premium/wizard/showcase.js +130 -0
- package/dist/src/showcase/preview-registry.cjs +1 -1
- package/dist/src/showcase/preview-registry.js +6 -6
- package/dist/src/showcase/registry-quality.cjs +1 -1
- package/dist/src/showcase/registry-quality.js +5 -0
- package/dist/src/showcase/registry-specific.cjs +1 -1
- package/dist/src/showcase/registry-specific.js +2 -2
- package/dist/src/showcase/render-registry-preview.cjs +1 -1
- package/dist/src/showcase/render-registry-preview.js +2 -2
- package/dist/src/showcase/site-data.cjs +1 -1
- package/dist/src/showcase/site-data.js +198 -44
- package/dist/src/showcase/tembro-registry.json.cjs +1 -1
- package/dist/src/showcase/tembro-registry.json.js +1 -1
- package/dist/src/showcase/types.cjs +1 -1
- package/dist/src/showcase/types.js +1 -1
- package/package.json +7 -3
- package/packages/cli/dist/index.cjs +127 -127
- package/packages/cli/vendor/src/components/layout/app-sidebar.tsx +50 -20
- package/packages/cli/vendor/src/components/theme-provider.tsx +1 -1
- package/packages/cli/vendor/src/components/ui/dialog/index.tsx +15 -3
- package/packages/cli/vendor/src/components/ui/select/index.tsx +17 -9
- package/packages/cli/vendor/src/showcase/component-api-schema.ts +269 -39
- package/packages/cli/vendor/src/showcase/demo-snippets/forms/index.ts +1 -1
- package/packages/cli/vendor/src/showcase/fallback.tsx +202 -39
- package/packages/cli/vendor/src/showcase/index.ts +6 -6
- package/packages/cli/vendor/src/showcase/package-meta.ts +3 -3
- package/packages/cli/vendor/src/showcase/premium/app-sidebar/mock.ts +3 -2
- package/packages/cli/vendor/src/showcase/premium/app-sidebar/showcase.tsx +1 -1
- package/packages/cli/vendor/src/showcase/premium/async-select/showcase.tsx +50 -4
- package/packages/cli/vendor/src/showcase/premium/avatar/showcase.tsx +5 -5
- package/packages/cli/vendor/src/showcase/premium/dialog/mock.ts +6 -1
- package/packages/cli/vendor/src/showcase/premium/dialog/showcase.tsx +53 -1
- package/packages/cli/vendor/src/showcase/premium/form-wrapper/mock.ts +2 -2
- package/packages/cli/vendor/src/showcase/premium/form-wrapper/showcase.tsx +1 -1
- package/packages/cli/vendor/src/showcase/premium/index.ts +5 -3
- package/packages/cli/vendor/src/showcase/premium/input/showcase.tsx +1 -1
- package/packages/cli/vendor/src/showcase/premium/json-input/showcase.tsx +1 -1
- package/packages/cli/vendor/src/showcase/premium/select/showcase.tsx +38 -0
- package/packages/cli/vendor/src/showcase/premium/table/mock.ts +1 -1
- package/packages/cli/vendor/src/showcase/premium/types.ts +1 -1
- package/packages/cli/vendor/src/showcase/premium/wizard/index.ts +2 -0
- package/packages/cli/vendor/src/showcase/premium/wizard/mock.ts +41 -0
- package/packages/cli/vendor/src/showcase/premium/wizard/showcase.tsx +88 -0
- package/packages/cli/vendor/src/showcase/preview-registry.tsx +6 -6
- package/packages/cli/vendor/src/showcase/registry-quality.ts +5 -0
- package/packages/cli/vendor/src/showcase/registry-specific.tsx +2 -2
- package/packages/cli/vendor/src/showcase/render-registry-preview.tsx +2 -2
- package/packages/cli/vendor/src/showcase/site-data.tsx +89 -32
- package/packages/cli/vendor/src/showcase/tembro-registry.json +1 -1
- package/packages/cli/vendor/src/showcase/types.ts +1 -1
- package/packages/cli/vendor/templates/showcase/src/App.tsx +107 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/data/registry.ts +273 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/layout/HeroSection.tsx +41 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/layout/WorkbenchSidebar.tsx +82 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/CalendarSection.tsx +35 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/CategorySection.tsx +48 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/ComponentDetailSection.tsx +68 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/CoreUiSection.tsx +100 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/DataTableSection.tsx +45 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/FormsSection.tsx +26 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/InventorySection.tsx +38 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/KanbanSection.tsx +42 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/OverlaySection.tsx +62 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/PatternsSection.tsx +36 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/VerificationSection.tsx +42 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/WizardSection.tsx +44 -0
- package/packages/cli/vendor/templates/showcase/src/showcase/shared/SectionTitle.tsx +13 -0
- package/registry.json +1 -1
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
export type ComponentStatus = "stable" | "preview" | "experimental" | "internal"
|
|
2
|
+
|
|
3
|
+
export type RegistryComponent = {
|
|
4
|
+
name: string
|
|
5
|
+
status: ComponentStatus
|
|
6
|
+
sourcePath: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type RegistryGroup = {
|
|
10
|
+
name: string
|
|
11
|
+
components: RegistryComponent[]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type ComponentRow = {
|
|
15
|
+
id: string
|
|
16
|
+
component: string
|
|
17
|
+
category: string
|
|
18
|
+
status: "Ready" | "Testing" | "Review"
|
|
19
|
+
props: number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const component = (name: string, status: ComponentStatus, sourcePath: string): RegistryComponent => ({
|
|
23
|
+
name,
|
|
24
|
+
status,
|
|
25
|
+
sourcePath,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
export const registryGroups: RegistryGroup[] = [
|
|
29
|
+
{
|
|
30
|
+
name: "ui",
|
|
31
|
+
components: [
|
|
32
|
+
component("button", "stable", "src/components/ui/button"),
|
|
33
|
+
component("input", "stable", "src/components/ui/input"),
|
|
34
|
+
component("textarea", "stable", "src/components/ui/textarea"),
|
|
35
|
+
component("checkbox", "stable", "src/components/ui/checkbox"),
|
|
36
|
+
component("switch", "stable", "src/components/ui/switch"),
|
|
37
|
+
component("badge", "stable", "src/components/ui/badge"),
|
|
38
|
+
component("card", "stable", "src/components/ui/card"),
|
|
39
|
+
component("skeleton", "preview", "src/components/ui/skeleton"),
|
|
40
|
+
component("tabs", "preview", "src/components/ui/tabs"),
|
|
41
|
+
component("dialog", "stable", "src/components/ui/dialog"),
|
|
42
|
+
component("dropdown-menu", "stable", "src/components/ui/dropdown-menu"),
|
|
43
|
+
component("popover", "stable", "src/components/ui/popover"),
|
|
44
|
+
component("tooltip", "preview", "src/components/ui/tooltip"),
|
|
45
|
+
component("select", "stable", "src/components/ui/select"),
|
|
46
|
+
component("table", "stable", "src/components/ui/table"),
|
|
47
|
+
component("segmented-control", "preview", "src/components/ui/segmented-control"),
|
|
48
|
+
component("radio-group", "stable", "src/components/ui/radio-group"),
|
|
49
|
+
component("accordion", "stable", "src/components/ui/accordion"),
|
|
50
|
+
component("kbd", "stable", "src/components/ui/kbd"),
|
|
51
|
+
component("scroll-box", "stable", "src/components/ui/scroll-box"),
|
|
52
|
+
component("right-click-menu", "stable", "src/components/ui/right-click-menu"),
|
|
53
|
+
component("collapse", "preview", "src/components/ui/collapse"),
|
|
54
|
+
component("command", "preview", "src/components/ui/command"),
|
|
55
|
+
component("divider", "preview", "src/components/ui/divider"),
|
|
56
|
+
component("spinner", "preview", "src/components/ui/spinner"),
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "actions",
|
|
61
|
+
components: [
|
|
62
|
+
component("action-menu", "stable", "src/components/actions/action-menu.tsx"),
|
|
63
|
+
component("button-group", "preview", "src/components/actions/button-group.tsx"),
|
|
64
|
+
component("copy-button", "preview", "src/components/actions/copy-button.tsx"),
|
|
65
|
+
component("quick-action-grid", "preview", "src/components/actions/quick-action-grid.tsx"),
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "inputs",
|
|
70
|
+
components: [
|
|
71
|
+
component("tag-input", "preview", "src/components/inputs/tag-input.tsx"),
|
|
72
|
+
component("async-select", "preview", "src/components/inputs/async-select.tsx"),
|
|
73
|
+
component("otp-input", "preview", "src/components/inputs/otp-input.tsx"),
|
|
74
|
+
component("color-picker", "stable", "src/components/inputs/color-picker.tsx"),
|
|
75
|
+
component("signature-pad", "preview", "src/components/inputs/signature-pad.tsx"),
|
|
76
|
+
component("rating", "preview", "src/components/inputs/rating.tsx"),
|
|
77
|
+
component("slider", "preview", "src/components/inputs/slider.tsx"),
|
|
78
|
+
component("inline-editable", "preview", "src/components/inputs/inline-editable.tsx"),
|
|
79
|
+
component("json-input", "preview", "src/components/inputs/json-input.tsx"),
|
|
80
|
+
component("time-picker", "preview", "src/components/inputs/time-picker.tsx"),
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: "form",
|
|
85
|
+
components: [
|
|
86
|
+
component("form-field-shell", "preview", "src/components/form/form-field-shell.tsx"),
|
|
87
|
+
component("form-input", "preview", "src/components/form/form-input.tsx"),
|
|
88
|
+
component("form-select", "preview", "src/components/form/form-select.tsx"),
|
|
89
|
+
component("form-textarea", "preview", "src/components/form/form-textarea.tsx"),
|
|
90
|
+
component("form-switch", "preview", "src/components/form/form-switch.tsx"),
|
|
91
|
+
component("form-date-range-input", "preview", "src/components/form/form-date-range-input.tsx"),
|
|
92
|
+
component("form-date-picker", "preview", "src/components/form/form-date-picker.tsx"),
|
|
93
|
+
component("form-date-range-picker", "preview", "src/components/form/form-date-range-picker.tsx"),
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "display",
|
|
98
|
+
components: [
|
|
99
|
+
component("activity-feed", "stable", "src/components/display/activity-feed.tsx"),
|
|
100
|
+
component("avatar", "preview", "src/components/display/avatar.tsx"),
|
|
101
|
+
component("code-block", "preview", "src/components/display/code-block.tsx"),
|
|
102
|
+
component("carousel", "preview", "src/components/display/carousel.tsx"),
|
|
103
|
+
component("tag", "preview", "src/components/display/tag.tsx"),
|
|
104
|
+
component("typography", "preview", "src/components/display/typography.tsx"),
|
|
105
|
+
component("data-state", "preview", "src/components/display/data-state.tsx"),
|
|
106
|
+
component("description-list", "stable", "src/components/display/description-list.tsx"),
|
|
107
|
+
component("kanban", "preview", "src/components/display/kanban.tsx"),
|
|
108
|
+
component("list", "preview", "src/components/display/list.tsx"),
|
|
109
|
+
component("progress", "stable", "src/components/display/progress.tsx"),
|
|
110
|
+
component("info-card", "stable", "src/components/display/info-card.tsx"),
|
|
111
|
+
component("statistic", "preview", "src/components/display/statistic.tsx"),
|
|
112
|
+
component("status-dot", "preview", "src/components/display/status-dot.tsx"),
|
|
113
|
+
component("status-legend", "preview", "src/components/display/status-legend.tsx"),
|
|
114
|
+
component("timeline", "stable", "src/components/display/timeline.tsx"),
|
|
115
|
+
component("tree-view", "preview", "src/components/display/tree-view.tsx"),
|
|
116
|
+
component("qr-code", "stable", "src/components/display/qr-code.tsx"),
|
|
117
|
+
component("virtual-list", "preview", "src/components/display/virtual-list.tsx"),
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
{ name: "data-table", components: [component("data-table", "preview", "src/components/data-table/data-table.tsx")] },
|
|
121
|
+
{
|
|
122
|
+
name: "calendar",
|
|
123
|
+
components: [
|
|
124
|
+
component("calendar", "preview", "src/components/calendar/calendar.tsx"),
|
|
125
|
+
component("date-picker", "preview", "src/components/calendar/date-picker.tsx"),
|
|
126
|
+
component("date-range-picker", "preview", "src/components/calendar/date-range-picker.tsx"),
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "overlay",
|
|
131
|
+
components: [
|
|
132
|
+
component("confirm-dialog", "stable", "src/components/overlay/confirm-dialog.tsx"),
|
|
133
|
+
component("alert-dialog", "stable", "src/components/overlay/alert-dialog.tsx"),
|
|
134
|
+
component("drawer", "stable", "src/components/overlay/drawer.tsx"),
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "feedback",
|
|
139
|
+
components: [
|
|
140
|
+
component("loading-state", "stable", "src/components/feedback/loading-state.tsx"),
|
|
141
|
+
component("page-state", "preview", "src/components/feedback/page-state.tsx"),
|
|
142
|
+
component("alert", "preview", "src/components/feedback/alert.tsx"),
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: "layout",
|
|
147
|
+
components: [
|
|
148
|
+
component("sidebar", "stable", "src/components/layout/app-sidebar.tsx"),
|
|
149
|
+
component("breadcrumbs", "stable", "src/components/layout/breadcrumbs.tsx"),
|
|
150
|
+
component("section", "preview", "src/components/layout/section.tsx"),
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: "patterns",
|
|
155
|
+
components: [
|
|
156
|
+
component("bulk-action-bar", "preview", "src/components/patterns/bulk-action-bar.tsx"),
|
|
157
|
+
component("data-view", "preview", "src/components/patterns/data-view.tsx"),
|
|
158
|
+
component("detail-layout", "preview", "src/components/patterns/detail-layout.tsx"),
|
|
159
|
+
component("empty-state", "preview", "src/components/patterns/empty-state.tsx"),
|
|
160
|
+
component("form-builder", "preview", "src/components/patterns/form-builder.tsx"),
|
|
161
|
+
component("resource-detail-page", "preview", "src/components/patterns/resource-detail-page.tsx"),
|
|
162
|
+
component("resource-page", "preview", "src/components/patterns/resource-page.tsx"),
|
|
163
|
+
component("page-toolbar", "preview", "src/components/patterns/page-toolbar.tsx"),
|
|
164
|
+
component("settings-page", "preview", "src/components/patterns/settings-page.tsx"),
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: "modern",
|
|
169
|
+
components: [
|
|
170
|
+
component("calendar-scheduler", "preview", "src/components/modern/calendar-scheduler.tsx"),
|
|
171
|
+
component("dual-list-picker", "preview", "src/components/modern/dual-list-picker.tsx"),
|
|
172
|
+
component("resizable-panel", "preview", "src/components/modern/resizable-panel.tsx"),
|
|
173
|
+
component("rich-text-editor", "preview", "src/components/modern/rich-text-editor.tsx"),
|
|
174
|
+
component("image-cropper", "preview", "src/components/modern/image-cropper.tsx"),
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: "upload",
|
|
179
|
+
components: [
|
|
180
|
+
component("file-upload", "preview", "src/components/upload/file-upload.tsx"),
|
|
181
|
+
component("image-upload", "preview", "src/components/upload/image-upload.tsx"),
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: "filters",
|
|
186
|
+
components: [
|
|
187
|
+
component("filter-bar", "stable", "src/components/filters/filter-bar.tsx"),
|
|
188
|
+
component("saved-filter-select", "preview", "src/components/filters/saved-filter-select.tsx"),
|
|
189
|
+
],
|
|
190
|
+
},
|
|
191
|
+
{ name: "navigation", components: [component("pagination", "stable", "src/components/navigation/pagination.tsx")] },
|
|
192
|
+
{ name: "charts", components: [component("progress-circle", "stable", "src/components/charts/progress-circle.tsx")] },
|
|
193
|
+
{
|
|
194
|
+
name: "wizard",
|
|
195
|
+
components: [
|
|
196
|
+
component("stepper", "preview", "src/components/wizard/stepper.tsx"),
|
|
197
|
+
component("wizard", "preview", "src/components/wizard/wizard.tsx"),
|
|
198
|
+
],
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
name: "notifications",
|
|
202
|
+
components: [
|
|
203
|
+
component("toast", "preview", "src/components/notifications/toast.tsx"),
|
|
204
|
+
component("notification-center", "preview", "src/components/notifications/notification-center.tsx"),
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
{ name: "command", components: [component("command-palette", "preview", "src/components/command/command-palette.tsx")] },
|
|
208
|
+
{ name: "dnd", components: [component("sortable-list", "preview", "src/components/dnd/sortable-list.tsx")] },
|
|
209
|
+
]
|
|
210
|
+
|
|
211
|
+
export const componentRows: ComponentRow[] = [
|
|
212
|
+
{ id: "cmp-001", component: "sidebar", category: "layout", status: "Ready", props: 34 },
|
|
213
|
+
{ id: "cmp-002", component: "kanban", category: "display", status: "Ready", props: 13 },
|
|
214
|
+
{ id: "cmp-003", component: "data-table", category: "data-table", status: "Testing", props: 50 },
|
|
215
|
+
{ id: "cmp-004", component: "calendar", category: "calendar", status: "Ready", props: 22 },
|
|
216
|
+
{ id: "cmp-005", component: "drawer", category: "overlay", status: "Ready", props: 14 },
|
|
217
|
+
{ id: "cmp-006", component: "wizard", category: "wizard", status: "Review", props: 12 },
|
|
218
|
+
{ id: "cmp-007", component: "button", category: "ui", status: "Ready", props: 9 },
|
|
219
|
+
{ id: "cmp-008", component: "input", category: "ui", status: "Ready", props: 11 },
|
|
220
|
+
]
|
|
221
|
+
|
|
222
|
+
export const wizardSteps = [
|
|
223
|
+
{ id: "setup", title: "Setup", description: "init + theme", completed: true },
|
|
224
|
+
{ id: "add", title: "Add", description: "105 registry components", completed: true },
|
|
225
|
+
{ id: "test", title: "Test", description: "visible workbench" },
|
|
226
|
+
]
|
|
227
|
+
|
|
228
|
+
export const moduleCount = registryGroups.reduce((sum, group) => sum + group.components.length, 0)
|
|
229
|
+
|
|
230
|
+
export type WorkbenchSelection =
|
|
231
|
+
| { type: "overview"; key: "overview" }
|
|
232
|
+
| { type: "category"; key: string; group: RegistryGroup }
|
|
233
|
+
| { type: "module"; key: string; group: RegistryGroup; component: RegistryComponent }
|
|
234
|
+
|
|
235
|
+
export function getCategoryKey(groupName: string) {
|
|
236
|
+
return `category:${groupName}`
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export function getModuleKey(groupName: string, componentName: string) {
|
|
240
|
+
return `component:${groupName}/${componentName}`
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export function getModuleLabel(componentName: string) {
|
|
244
|
+
return componentName
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export function getModuleSourcePath(component: RegistryComponent) {
|
|
248
|
+
return component.sourcePath
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function resolveWorkbenchSelection(key: string): WorkbenchSelection {
|
|
252
|
+
if (key === "overview") return { type: "overview", key: "overview" }
|
|
253
|
+
|
|
254
|
+
if (key.startsWith("category:")) {
|
|
255
|
+
const groupName = key.slice("category:".length)
|
|
256
|
+
const group = registryGroups.find((item) => item.name === groupName)
|
|
257
|
+
if (group) return { type: "category", key, group }
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (key.startsWith("component:")) {
|
|
261
|
+
const value = key.slice("component:".length)
|
|
262
|
+
const slashIndex = value.indexOf("/")
|
|
263
|
+
const groupName = value.slice(0, slashIndex)
|
|
264
|
+
const componentName = value.slice(slashIndex + 1)
|
|
265
|
+
const group = registryGroups.find((item) => item.name === groupName)
|
|
266
|
+
const selectedComponent = group?.components.find((item) => item.name === componentName)
|
|
267
|
+
if (group && selectedComponent) {
|
|
268
|
+
return { type: "module", key, group, component: selectedComponent }
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return { type: "overview", key: "overview" }
|
|
273
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { PlusIcon, SettingsIcon } from "lucide-react"
|
|
2
|
+
|
|
3
|
+
import { CopyButton } from "@/components/actions/copy-button"
|
|
4
|
+
import { StatisticCard, StatisticGrid } from "@/components/display/statistic"
|
|
5
|
+
import { Badge } from "@/components/ui/badge"
|
|
6
|
+
import { Button } from "@/components/ui/button"
|
|
7
|
+
import { moduleCount, registryGroups } from "@/showcase/data/registry"
|
|
8
|
+
|
|
9
|
+
export function HeroSection() {
|
|
10
|
+
return (
|
|
11
|
+
<section className="border-b bg-card">
|
|
12
|
+
<div className="mx-auto max-w-7xl px-6 py-8 lg:px-8">
|
|
13
|
+
<div className="flex flex-wrap items-start justify-between gap-6">
|
|
14
|
+
<div className="max-w-3xl">
|
|
15
|
+
<div className="mb-3 flex flex-wrap gap-2">
|
|
16
|
+
<Badge status="success" label="tembro init done" variant="soft" />
|
|
17
|
+
<Badge status="info" label={`${moduleCount} registry components`} variant="soft" />
|
|
18
|
+
<Badge status="warning" label="real local components" variant="soft" />
|
|
19
|
+
</div>
|
|
20
|
+
<h1 className="text-4xl font-semibold tracking-tight">All Tembro Components Test Surface</h1>
|
|
21
|
+
<p className="mt-3 text-base leading-7 text-muted-foreground">
|
|
22
|
+
Vite starter olib tashlandi. Bu ekran `tembro add showcase` orqali o‘rnatilgan aniq registry componentlardan qurildi.
|
|
23
|
+
</p>
|
|
24
|
+
</div>
|
|
25
|
+
<div className="flex flex-wrap gap-2">
|
|
26
|
+
<Button leftIcon={<PlusIcon className="size-4" />}>Create</Button>
|
|
27
|
+
<Button variant="outline" leftIcon={<SettingsIcon className="size-4" />}>Settings</Button>
|
|
28
|
+
<CopyButton value="npx tembro@3.1.8 list --json">Copy list command</CopyButton>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<StatisticGrid columns={4} className="mt-8">
|
|
33
|
+
<StatisticCard label="Registry components" value={moduleCount} change="visible below" trend="up" description="tembro add <name>" />
|
|
34
|
+
<StatisticCard label="Local source files" value="152" change="with hooks/lib" trend="up" description="installed by CLI" />
|
|
35
|
+
<StatisticCard label="Categories" value={registryGroups.length} change="all shown" trend="up" description="actions to wizard" />
|
|
36
|
+
<StatisticCard label="Build" value="Pass" change="doctor pass" trend="up" description="tembro@3.1.8" />
|
|
37
|
+
</StatisticGrid>
|
|
38
|
+
</div>
|
|
39
|
+
</section>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CalendarDaysIcon,
|
|
3
|
+
ClipboardListIcon,
|
|
4
|
+
DatabaseIcon,
|
|
5
|
+
FolderKanbanIcon,
|
|
6
|
+
Layers3Icon,
|
|
7
|
+
LayoutDashboardIcon,
|
|
8
|
+
SparklesIcon,
|
|
9
|
+
UploadCloudIcon,
|
|
10
|
+
WandSparklesIcon,
|
|
11
|
+
} from "lucide-react"
|
|
12
|
+
|
|
13
|
+
import { Sidebar } from "@/components/layout/app-sidebar"
|
|
14
|
+
import { Badge } from "@/components/ui/badge"
|
|
15
|
+
import { getCategoryKey, getModuleKey, getModuleLabel, moduleCount, registryGroups } from "@/showcase/data/registry"
|
|
16
|
+
|
|
17
|
+
type WorkbenchSidebarProps = {
|
|
18
|
+
selectedKey: string
|
|
19
|
+
onSelect: (key: string) => void
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function WorkbenchSidebar({ selectedKey, onSelect }: WorkbenchSidebarProps) {
|
|
23
|
+
return (
|
|
24
|
+
<aside className="border-r bg-sidebar p-3 lg:sticky lg:top-0 lg:h-screen lg:overflow-y-auto">
|
|
25
|
+
<Sidebar
|
|
26
|
+
width="100%"
|
|
27
|
+
header={
|
|
28
|
+
<div className="flex items-center gap-3 rounded-xl border bg-card p-3">
|
|
29
|
+
<div className="flex size-10 items-center justify-center rounded-lg bg-primary text-primary-foreground">
|
|
30
|
+
<WandSparklesIcon className="size-5" />
|
|
31
|
+
</div>
|
|
32
|
+
<div className="min-w-0">
|
|
33
|
+
<div className="truncate font-semibold">Tembro Workbench</div>
|
|
34
|
+
<div className="text-xs text-muted-foreground">local copied components</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
}
|
|
38
|
+
items={[
|
|
39
|
+
{ key: "overview", label: "Overview", icon: <LayoutDashboardIcon className="size-4" />, active: selectedKey === "overview", badge: <Badge label="live" status="success" />, onSelect: () => onSelect("overview") },
|
|
40
|
+
...registryGroups.map((group) => {
|
|
41
|
+
const categoryKey = getCategoryKey(group.name)
|
|
42
|
+
return {
|
|
43
|
+
key: categoryKey,
|
|
44
|
+
label: group.name,
|
|
45
|
+
icon: group.name === "ui"
|
|
46
|
+
? <SparklesIcon className="size-4" />
|
|
47
|
+
: group.name === "data-table"
|
|
48
|
+
? <DatabaseIcon className="size-4" />
|
|
49
|
+
: group.name === "display"
|
|
50
|
+
? <FolderKanbanIcon className="size-4" />
|
|
51
|
+
: group.name === "calendar"
|
|
52
|
+
? <CalendarDaysIcon className="size-4" />
|
|
53
|
+
: group.name === "overlay"
|
|
54
|
+
? <Layers3Icon className="size-4" />
|
|
55
|
+
: group.name === "upload"
|
|
56
|
+
? <UploadCloudIcon className="size-4" />
|
|
57
|
+
: <ClipboardListIcon className="size-4" />,
|
|
58
|
+
active: selectedKey === categoryKey || selectedKey.startsWith(`component:${group.name}/`),
|
|
59
|
+
badge: <Badge label={group.components.length} variant="secondary" />,
|
|
60
|
+
defaultExpanded: ["ui", "display", "data-table", "inputs", "layout", "overlay"].includes(group.name),
|
|
61
|
+
onSelect: () => onSelect(categoryKey),
|
|
62
|
+
items: group.components.map((component) => {
|
|
63
|
+
const moduleKey = getModuleKey(group.name, component.name)
|
|
64
|
+
return {
|
|
65
|
+
key: moduleKey,
|
|
66
|
+
label: getModuleLabel(component.name),
|
|
67
|
+
active: selectedKey === moduleKey,
|
|
68
|
+
onSelect: () => onSelect(moduleKey),
|
|
69
|
+
}
|
|
70
|
+
}),
|
|
71
|
+
}
|
|
72
|
+
}),
|
|
73
|
+
]}
|
|
74
|
+
footerAccount={{
|
|
75
|
+
label: "tembro@3.1.8",
|
|
76
|
+
description: `${moduleCount} registry components`,
|
|
77
|
+
}}
|
|
78
|
+
activeIndicator="bar"
|
|
79
|
+
/>
|
|
80
|
+
</aside>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useState } from "react"
|
|
2
|
+
|
|
3
|
+
import { Calendar } from "@/components/calendar/calendar"
|
|
4
|
+
import { DatePicker } from "@/components/calendar/date-picker"
|
|
5
|
+
import { Pagination } from "@/components/navigation/pagination"
|
|
6
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
|
7
|
+
|
|
8
|
+
export function CalendarSection() {
|
|
9
|
+
const [date, setDate] = useState("2026-07-15")
|
|
10
|
+
const [page, setPage] = useState(2)
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div className="grid gap-4 lg:grid-cols-[1fr_0.8fr]">
|
|
14
|
+
<Card>
|
|
15
|
+
<CardHeader>
|
|
16
|
+
<CardTitle>Calendar</CardTitle>
|
|
17
|
+
<CardDescription>Single/range capable calendar module.</CardDescription>
|
|
18
|
+
</CardHeader>
|
|
19
|
+
<CardContent>
|
|
20
|
+
<Calendar value={date} onValueChange={setDate} showTodayShortcut showClearShortcut showSelectionSummary />
|
|
21
|
+
</CardContent>
|
|
22
|
+
</Card>
|
|
23
|
+
<Card>
|
|
24
|
+
<CardHeader>
|
|
25
|
+
<CardTitle>DatePicker and pagination</CardTitle>
|
|
26
|
+
<CardDescription>Popover date picker plus navigation pagination.</CardDescription>
|
|
27
|
+
</CardHeader>
|
|
28
|
+
<CardContent className="grid gap-5">
|
|
29
|
+
<DatePicker value={date} onValueChange={setDate} />
|
|
30
|
+
<Pagination page={page} pageCount={9} onPageChange={setPage} showSummary totalCount={90} pageSize={10} />
|
|
31
|
+
</CardContent>
|
|
32
|
+
</Card>
|
|
33
|
+
</div>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Button } from "@/components/ui/button"
|
|
2
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
|
3
|
+
import { Badge } from "@/components/ui/badge"
|
|
4
|
+
import { getModuleKey, getModuleLabel, getModuleSourcePath, type RegistryGroup } from "@/showcase/data/registry"
|
|
5
|
+
|
|
6
|
+
type CategorySectionProps = {
|
|
7
|
+
group: RegistryGroup
|
|
8
|
+
onSelect: (key: string) => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function CategorySection({ group, onSelect }: CategorySectionProps) {
|
|
12
|
+
return (
|
|
13
|
+
<section className="grid gap-4">
|
|
14
|
+
<Card>
|
|
15
|
+
<CardHeader>
|
|
16
|
+
<div className="flex flex-wrap items-start justify-between gap-3">
|
|
17
|
+
<div>
|
|
18
|
+
<CardTitle>{group.name}</CardTitle>
|
|
19
|
+
<CardDescription>{group.components.length} registry component. Sidebar ichidan bittasini tanlab alohida test qilasiz.</CardDescription>
|
|
20
|
+
</div>
|
|
21
|
+
<Badge label={`${group.components.length} components`} variant="secondary" />
|
|
22
|
+
</div>
|
|
23
|
+
</CardHeader>
|
|
24
|
+
<CardContent>
|
|
25
|
+
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
|
|
26
|
+
{group.components.map((component) => (
|
|
27
|
+
<button
|
|
28
|
+
key={component.name}
|
|
29
|
+
type="button"
|
|
30
|
+
className="rounded-lg border bg-card p-4 text-left transition hover:border-primary/40 hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
31
|
+
onClick={() => onSelect(getModuleKey(group.name, component.name))}
|
|
32
|
+
>
|
|
33
|
+
<div className="flex items-center justify-between gap-3">
|
|
34
|
+
<div className="font-medium">{getModuleLabel(component.name)}</div>
|
|
35
|
+
<Badge label={component.status} status={component.status === "stable" ? "success" : "info"} variant="soft" />
|
|
36
|
+
</div>
|
|
37
|
+
<div className="mt-1 text-xs text-muted-foreground">{getModuleSourcePath(component)}</div>
|
|
38
|
+
</button>
|
|
39
|
+
))}
|
|
40
|
+
</div>
|
|
41
|
+
</CardContent>
|
|
42
|
+
</Card>
|
|
43
|
+
<div className="flex justify-end">
|
|
44
|
+
<Button variant="outline" onClick={() => onSelect("overview")}>Back to overview</Button>
|
|
45
|
+
</div>
|
|
46
|
+
</section>
|
|
47
|
+
)
|
|
48
|
+
}
|
package/packages/cli/vendor/templates/showcase/src/showcase/sections/ComponentDetailSection.tsx
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { FolderOpenIcon } from "lucide-react"
|
|
2
|
+
|
|
3
|
+
import { Badge } from "@/components/ui/badge"
|
|
4
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
|
5
|
+
import { getModuleLabel, getModuleSourcePath, type RegistryComponent, type RegistryGroup } from "@/showcase/data/registry"
|
|
6
|
+
import { CalendarSection } from "@/showcase/sections/CalendarSection"
|
|
7
|
+
import { CoreUiSection } from "@/showcase/sections/CoreUiSection"
|
|
8
|
+
import { DataTableSection } from "@/showcase/sections/DataTableSection"
|
|
9
|
+
import { FormsSection } from "@/showcase/sections/FormsSection"
|
|
10
|
+
import { KanbanSection } from "@/showcase/sections/KanbanSection"
|
|
11
|
+
import { OverlaySection } from "@/showcase/sections/OverlaySection"
|
|
12
|
+
import { PatternsSection } from "@/showcase/sections/PatternsSection"
|
|
13
|
+
import { WizardSection } from "@/showcase/sections/WizardSection"
|
|
14
|
+
|
|
15
|
+
type ComponentDetailSectionProps = {
|
|
16
|
+
group: RegistryGroup
|
|
17
|
+
component: RegistryComponent
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function RelatedPreview({ groupName, componentName }: { groupName: string; componentName: string }) {
|
|
21
|
+
if (groupName === "ui" || ["actions", "command"].includes(groupName)) return <CoreUiSection />
|
|
22
|
+
if (groupName === "inputs" || groupName === "form" || groupName === "feedback") return <FormsSection />
|
|
23
|
+
if (groupName === "data-table") return <DataTableSection />
|
|
24
|
+
if (groupName === "display" && componentName === "kanban") return <KanbanSection />
|
|
25
|
+
if (groupName === "calendar" || groupName === "navigation") return <CalendarSection />
|
|
26
|
+
if (groupName === "overlay") return <OverlaySection />
|
|
27
|
+
if (groupName === "wizard") return <WizardSection />
|
|
28
|
+
if (["patterns", "layout", "modern", "notifications", "filters", "upload", "charts", "dnd", "display"].includes(groupName)) {
|
|
29
|
+
return <PatternsSection />
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return <PatternsSection />
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function ComponentDetailSection({ group, component }: ComponentDetailSectionProps) {
|
|
36
|
+
const sourcePath = getModuleSourcePath(component)
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<section className="grid gap-5">
|
|
40
|
+
<Card>
|
|
41
|
+
<CardHeader>
|
|
42
|
+
<div className="flex flex-wrap items-start justify-between gap-3">
|
|
43
|
+
<div>
|
|
44
|
+
<CardTitle>{getModuleLabel(component.name)}</CardTitle>
|
|
45
|
+
<CardDescription>Tanlangan registry component test paneli.</CardDescription>
|
|
46
|
+
</div>
|
|
47
|
+
<div className="flex flex-wrap gap-2">
|
|
48
|
+
<Badge label={group.name} status="info" />
|
|
49
|
+
<Badge label={component.status} status={component.status === "stable" ? "success" : "info"} />
|
|
50
|
+
<Badge label="local source" status="success" />
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</CardHeader>
|
|
54
|
+
<CardContent className="grid gap-3 text-sm">
|
|
55
|
+
<div className="flex items-center gap-2 rounded-lg border bg-muted/30 p-3">
|
|
56
|
+
<FolderOpenIcon className="size-4 text-muted-foreground" />
|
|
57
|
+
<code className="min-w-0 break-all">{sourcePath}</code>
|
|
58
|
+
</div>
|
|
59
|
+
<p className="text-muted-foreground">
|
|
60
|
+
Sidebar orqali har bir registry component alohida tanlanadi. Quyidagi preview shu component tegishli category test surfaceini ko‘rsatadi.
|
|
61
|
+
</p>
|
|
62
|
+
</CardContent>
|
|
63
|
+
</Card>
|
|
64
|
+
|
|
65
|
+
<RelatedPreview groupName={group.name} componentName={component.name} />
|
|
66
|
+
</section>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { ChevronRightIcon, CommandIcon, SearchIcon, SparklesIcon } from "lucide-react"
|
|
2
|
+
|
|
3
|
+
import { AvatarGroup } from "@/components/display/avatar"
|
|
4
|
+
import { Progress } from "@/components/display/progress"
|
|
5
|
+
import { Tag, TagGroup } from "@/components/display/tag"
|
|
6
|
+
import { Alert } from "@/components/feedback/alert"
|
|
7
|
+
import { Badge } from "@/components/ui/badge"
|
|
8
|
+
import { Button } from "@/components/ui/button"
|
|
9
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
|
10
|
+
import { Checkbox } from "@/components/ui/checkbox"
|
|
11
|
+
import { Input } from "@/components/ui/input"
|
|
12
|
+
import { Select } from "@/components/ui/select"
|
|
13
|
+
import { Switch } from "@/components/ui/switch"
|
|
14
|
+
import { Textarea } from "@/components/ui/textarea"
|
|
15
|
+
import { registryGroups } from "@/showcase/data/registry"
|
|
16
|
+
|
|
17
|
+
export function CoreUiSection() {
|
|
18
|
+
return (
|
|
19
|
+
<div className="grid gap-4 xl:grid-cols-[1.35fr_0.65fr]">
|
|
20
|
+
<Card>
|
|
21
|
+
<CardHeader>
|
|
22
|
+
<CardTitle>UI controls and variants</CardTitle>
|
|
23
|
+
<CardDescription>Button, Badge, Card, Input, Select, Checkbox, Switch, Tabs, Textarea.</CardDescription>
|
|
24
|
+
</CardHeader>
|
|
25
|
+
<CardContent className="grid gap-5">
|
|
26
|
+
<div className="flex flex-wrap gap-2">
|
|
27
|
+
<Button leftIcon={<SparklesIcon className="size-4" />}>Default</Button>
|
|
28
|
+
<Button variant="secondary">Secondary</Button>
|
|
29
|
+
<Button variant="outline">Outline</Button>
|
|
30
|
+
<Button variant="ghost">Ghost</Button>
|
|
31
|
+
<Button variant="warning">Warning</Button>
|
|
32
|
+
<Button variant="destructive">Destructive</Button>
|
|
33
|
+
<Button iconOnly aria-label="Command"><CommandIcon className="size-4" /></Button>
|
|
34
|
+
</div>
|
|
35
|
+
<div className="flex flex-wrap gap-2">
|
|
36
|
+
<Badge label="default" />
|
|
37
|
+
<Badge label="info" status="info" />
|
|
38
|
+
<Badge label="success" status="success" />
|
|
39
|
+
<Badge label="warning" status="warning" />
|
|
40
|
+
<Badge label="danger" status="danger" removable />
|
|
41
|
+
</div>
|
|
42
|
+
<div className="grid gap-3 md:grid-cols-3">
|
|
43
|
+
<Input kind="search" placeholder="Search components" searchIcon={<SearchIcon className="size-4" />} />
|
|
44
|
+
<Input kind="password" placeholder="Password input" />
|
|
45
|
+
<Select
|
|
46
|
+
placeholder="Pick category"
|
|
47
|
+
searchable
|
|
48
|
+
clearable
|
|
49
|
+
options={registryGroups.slice(0, 8).map((group) => ({
|
|
50
|
+
label: group.name,
|
|
51
|
+
value: group.name,
|
|
52
|
+
description: `${group.components.length} components`,
|
|
53
|
+
}))}
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
<div className="grid gap-4 md:grid-cols-2">
|
|
57
|
+
<Textarea defaultValue="Textarea with helper text, counter and Tembro theme." helperText="Textarea helper text" maxLength={140} showCharacterCount />
|
|
58
|
+
<div className="grid content-start gap-4 rounded-lg border bg-muted/25 p-4">
|
|
59
|
+
<Switch defaultChecked label="Enable preview" description="Switch with label and description" />
|
|
60
|
+
<div className="flex items-center gap-3">
|
|
61
|
+
<Checkbox defaultChecked />
|
|
62
|
+
<span className="text-sm">Checkbox selected state</span>
|
|
63
|
+
</div>
|
|
64
|
+
<AvatarGroup
|
|
65
|
+
items={[
|
|
66
|
+
{ key: "az", name: "Azamat Jurayev", status: "online" },
|
|
67
|
+
{ key: "qa", name: "QA Tester", status: "busy" },
|
|
68
|
+
{ key: "ux", name: "UX Review", status: "away" },
|
|
69
|
+
{ key: "tm", name: "Tembro Maintainer", status: "offline" },
|
|
70
|
+
]}
|
|
71
|
+
max={3}
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</CardContent>
|
|
76
|
+
</Card>
|
|
77
|
+
<Card
|
|
78
|
+
variant="elevated"
|
|
79
|
+
tone="info"
|
|
80
|
+
eyebrow="Card surface props"
|
|
81
|
+
title="Surface API"
|
|
82
|
+
description="title, description, badge, action, content, footer props."
|
|
83
|
+
badge={<Badge label="styled" status="info" />}
|
|
84
|
+
action={<Button size="sm" variant="outline" rightIcon={<ChevronRightIcon className="size-4" />}>Open</Button>}
|
|
85
|
+
content={
|
|
86
|
+
<div className="grid gap-4">
|
|
87
|
+
<Progress value={78} label="Style coverage" showValue tone="info" />
|
|
88
|
+
<TagGroup>
|
|
89
|
+
<Tag tone="success" selected>Selected</Tag>
|
|
90
|
+
<Tag tone="info">Info</Tag>
|
|
91
|
+
<Tag tone="warning" removable>Removable</Tag>
|
|
92
|
+
</TagGroup>
|
|
93
|
+
<Alert tone="success" title="Styled by Tembro tokens" description="This card uses copied local component code." />
|
|
94
|
+
</div>
|
|
95
|
+
}
|
|
96
|
+
footer={<span className="text-sm text-muted-foreground">No Vite starter component here.</span>}
|
|
97
|
+
/>
|
|
98
|
+
</div>
|
|
99
|
+
)
|
|
100
|
+
}
|