tembro 3.1.10 → 3.1.11

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/components/charts/demo.cjs +1 -0
  3. package/dist/components/charts/demo.d.ts +6 -0
  4. package/dist/components/charts/demo.js +1 -0
  5. package/dist/components/data-table/data-table.d.ts +3 -1
  6. package/dist/showcase/package-meta.d.ts +2 -2
  7. package/dist/src/components/charts/demo.cjs +1 -0
  8. package/dist/src/components/charts/demo.js +5 -0
  9. package/dist/src/components/data-table/data-table.cjs +1 -1
  10. package/dist/src/components/data-table/data-table.js +146 -111
  11. package/dist/src/components/display/kanban.cjs +1 -1
  12. package/dist/src/components/display/kanban.js +1 -1
  13. package/dist/src/showcase/index.cjs +1 -1
  14. package/dist/src/showcase/index.js +18 -16
  15. package/dist/src/showcase/package-meta.cjs +1 -1
  16. package/dist/src/showcase/package-meta.js +1 -1
  17. package/dist/src/showcase/preview-registry.cjs +1 -1
  18. package/dist/src/showcase/preview-registry.js +290 -288
  19. package/dist/src/showcase/render-registry-preview.cjs +1 -1
  20. package/dist/src/showcase/render-registry-preview.js +257 -182
  21. package/dist/src/showcase/site-data.cjs +1 -1
  22. package/dist/src/showcase/site-data.js +1 -1
  23. package/dist/src/showcase/tembro-registry.json.cjs +1 -1
  24. package/dist/src/showcase/tembro-registry.json.js +2 -2
  25. package/package.json +1 -1
  26. package/packages/cli/dist/index.cjs +14 -14
  27. package/packages/cli/vendor/src/components/charts/demo.tsx +5 -0
  28. package/packages/cli/vendor/src/components/data-table/data-table.tsx +112 -41
  29. package/packages/cli/vendor/src/components/display/kanban.tsx +4 -4
  30. package/packages/cli/vendor/src/showcase/index.ts +6 -4
  31. package/packages/cli/vendor/src/showcase/package-meta.ts +1 -1
  32. package/packages/cli/vendor/src/showcase/preview-registry.tsx +2 -0
  33. package/packages/cli/vendor/src/showcase/render-registry-preview.tsx +36 -0
  34. package/packages/cli/vendor/src/showcase/tembro-registry.json +5 -2
  35. package/packages/cli/vendor/templates/showcase/src/App.tsx +1 -1
  36. package/packages/cli/vendor/templates/showcase/src/showcase/layout/HeroSection.tsx +3 -3
  37. package/packages/cli/vendor/templates/showcase/src/showcase/layout/WorkbenchSidebar.tsx +1 -1
  38. package/packages/cli/vendor/templates/showcase/src/showcase/sections/CalendarSection.tsx +1 -1
  39. package/packages/cli/vendor/templates/showcase/src/showcase/sections/ComponentLivePreview.tsx +1 -1
  40. package/packages/cli/vendor/templates/showcase/src/showcase/sections/CoreUiSection.tsx +2 -2
  41. package/packages/cli/vendor/templates/showcase/src/showcase/sections/FormsSection.tsx +1 -1
  42. package/packages/cli/vendor/templates/showcase/src/showcase/sections/OverlaySection.tsx +1 -1
  43. package/packages/cli/vendor/templates/showcase/src/showcase/sections/PatternsSection.tsx +1 -1
  44. package/packages/cli/vendor/templates/showcase/src/showcase/sections/VerificationSection.tsx +1 -1
  45. package/packages/cli/vendor/templates/showcase/src/showcase/sections/WizardSection.tsx +1 -1
  46. package/registry.json +5 -2
@@ -0,0 +1,5 @@
1
+ import { component, createShowcaseDemoRegistry } from "@/showcase/create-demo"
2
+
3
+ export const chartsShowcaseDemoRegistry = createShowcaseDemoRegistry([
4
+ component("charts", "ChartFrame", "display", "Chart primitives for dashboard metrics, distribution and trend views.", "ChartFrame"),
5
+ ])
@@ -28,9 +28,10 @@ import { DataTablePagination, type DataTablePaginationProps } from "@/components
28
28
  import { type DataTableRowAction } from "@/components/data-table/data-table-row-actions"
29
29
  import { DataTableToolbar, type DataTableToolbarProps } from "@/components/data-table/data-table-toolbar"
30
30
  import { DataState, type DataStateProps } from "@/components/display/data-state"
31
- import { LoadingState, type LoadingStateProps } from "@/components/feedback/loading-state"
32
- import { Button } from "@/components/ui/button"
33
- import { Input, type InputSearchProps } from "@/components/ui/input"
31
+ import { LoadingState, type LoadingStateProps } from "@/components/feedback/loading-state"
32
+ import { Button } from "@/components/ui/button"
33
+ import { Input, type InputSearchProps } from "@/components/ui/input"
34
+ import { useIsMobile } from "@/hooks/use-is-mobile"
34
35
  import {
35
36
  Table,
36
37
  TableBody,
@@ -42,7 +43,8 @@ import {
42
43
  import { cn } from "@/lib/utils"
43
44
 
44
45
  export type DataTableDensity = "compact" | "default" | "comfortable"
45
- export type DataTableLoadingVariant = "skeleton" | "state"
46
+ export type DataTableLoadingVariant = "skeleton" | "state"
47
+ export type DataTableMobileLayout = "auto" | "cards" | "scroll"
46
48
 
47
49
  export type DataTableVirtualizationRange = {
48
50
  startIndex: number
@@ -139,9 +141,10 @@ export type DataTableProps<TData, TValue = unknown> = Omit<
139
141
  onColumnVisibilityChange?: OnChangeFn<VisibilityState>
140
142
  rowSelection?: RowSelectionState
141
143
  onRowSelectionChange?: OnChangeFn<RowSelectionState>
142
- enableRowSelection?: boolean | ((row: Row<TData>) => boolean)
143
- renderMobileCard?: (row: Row<TData>) => React.ReactNode
144
- onRowClick?: (row: Row<TData>) => void
144
+ enableRowSelection?: boolean | ((row: Row<TData>) => boolean)
145
+ renderMobileCard?: (row: Row<TData>) => React.ReactNode
146
+ mobileLayout?: DataTableMobileLayout
147
+ onRowClick?: (row: Row<TData>) => void
145
148
  onRowDoubleClick?: (row: Row<TData>) => void
146
149
  getRowDisabled?: (row: Row<TData>) => boolean
147
150
  density?: DataTableDensity
@@ -200,9 +203,18 @@ function getCellClassName<TData>(
200
203
  return typeof cellClassName === "function" ? cellClassName(cell) : cellClassName
201
204
  }
202
205
 
203
- function isEmptyCellContent(content: React.ReactNode) {
204
- return content === null || content === undefined || content === ""
205
- }
206
+ function isEmptyCellContent(content: React.ReactNode) {
207
+ return content === null || content === undefined || content === ""
208
+ }
209
+
210
+ function getMobileCellLabel<TData>(cell: Cell<TData, unknown>) {
211
+ const header = cell.column.columnDef.header
212
+
213
+ if (typeof header === "string") return header
214
+ if (typeof header === "number") return String(header)
215
+
216
+ return cell.column.id === "actions" ? "Actions" : cell.column.id
217
+ }
206
218
 
207
219
  function DataTable<TData, TValue = unknown>({
208
220
  className,
@@ -237,9 +249,10 @@ function DataTable<TData, TValue = unknown>({
237
249
  onColumnVisibilityChange,
238
250
  rowSelection,
239
251
  onRowSelectionChange,
240
- enableRowSelection,
241
- renderMobileCard,
242
- onRowClick,
252
+ enableRowSelection,
253
+ renderMobileCard,
254
+ mobileLayout = "auto",
255
+ onRowClick,
243
256
  onRowDoubleClick,
244
257
  getRowDisabled,
245
258
  density = "default",
@@ -449,8 +462,10 @@ function DataTable<TData, TValue = unknown>({
449
462
  defaultSelectionActions
450
463
  )
451
464
  const hasToolbar = Boolean(resolvedToolbar || resolvedToolbarProps || hasDefaultToolbarContent)
452
- const showPagination = Boolean(paginationConfig && !paginationConfig.hidden)
453
- const shouldRenderSkeleton = isLoading && loadingVariant === "skeleton"
465
+ const showPagination = Boolean(paginationConfig && !paginationConfig.hidden)
466
+ const shouldRenderSkeleton = isLoading && loadingVariant === "skeleton"
467
+ const isMobileViewport = useIsMobile()
468
+ const shouldUseMobileCards = mobileLayout !== "scroll" && isMobileViewport
454
469
 
455
470
  const renderVirtualSpacer = (key: string, height: number) =>
456
471
  height > 0 ? (
@@ -503,7 +518,7 @@ function DataTable<TData, TValue = unknown>({
503
518
  <DataState status="empty" variant="plain" {...emptyState} />
504
519
  ) : null
505
520
 
506
- const renderDataRow = (row: Row<TData>, rowIndex: number, virtualRow?: VirtualItem) => {
521
+ const renderDataRow = (row: Row<TData>, rowIndex: number, virtualRow?: VirtualItem) => {
507
522
  const rowDisabled = getRowDisabled?.(row) ?? false
508
523
 
509
524
  return (
@@ -566,7 +581,58 @@ function DataTable<TData, TValue = unknown>({
566
581
  ) : null}
567
582
  </React.Fragment>
568
583
  )
569
- }
584
+ }
585
+
586
+ const renderDefaultMobileCard = (row: Row<TData>) => {
587
+ const rowDisabled = getRowDisabled?.(row) ?? false
588
+ const cells = row.getVisibleCells()
589
+
590
+ return (
591
+ <article
592
+ key={row.id}
593
+ data-slot="data-table-mobile-card"
594
+ data-state={row.getIsSelected() ? "selected" : undefined}
595
+ data-disabled={rowDisabled || undefined}
596
+ className={cn(
597
+ "grid gap-3 rounded-[var(--aui-card-radius,var(--radius-lg))] border border-[color:var(--aui-card-border,var(--border))] bg-card p-3 shadow-[var(--aui-card-shadow,0_10px_24px_rgba(15,23,42,0.07))]",
598
+ onRowClick && !rowDisabled && "cursor-pointer transition-colors hover:bg-[color:color-mix(in_oklch,var(--primary),transparent_96%)]",
599
+ rowDisabled && "pointer-events-none opacity-55",
600
+ getRowClassName(row, rowClassName)
601
+ )}
602
+ role={onRowClick && !rowDisabled ? "button" : undefined}
603
+ tabIndex={onRowClick && !rowDisabled ? 0 : undefined}
604
+ onClick={() => {
605
+ if (!rowDisabled) onRowClick?.(row)
606
+ }}
607
+ onKeyDown={(event) => {
608
+ if (event.target !== event.currentTarget || rowDisabled || !onRowClick) return
609
+ if (event.key === "Enter" || event.key === " ") {
610
+ event.preventDefault()
611
+ onRowClick(row)
612
+ }
613
+ }}
614
+ >
615
+ {cells.map((cell) => {
616
+ const renderedCell = flexRender(cell.column.columnDef.cell, cell.getContext())
617
+
618
+ return (
619
+ <div
620
+ key={cell.id}
621
+ data-slot="data-table-mobile-cell"
622
+ className="grid grid-cols-[minmax(7rem,0.42fr)_minmax(0,1fr)] items-start gap-3 text-sm"
623
+ >
624
+ <span className="min-w-0 text-xs font-semibold uppercase tracking-wide text-muted-foreground">
625
+ {getMobileCellLabel(cell)}
626
+ </span>
627
+ <div className="min-w-0 text-right text-foreground/92 [&>*]:ml-auto">
628
+ {isEmptyCellContent(renderedCell) ? cellFallback : renderedCell}
629
+ </div>
630
+ </div>
631
+ )
632
+ })}
633
+ </article>
634
+ )
635
+ }
570
636
 
571
637
  return (
572
638
  <div data-slot="data-table" className={cn("grid gap-3", className)} {...props}>
@@ -587,29 +653,33 @@ function DataTable<TData, TValue = unknown>({
587
653
  />
588
654
  ))}
589
655
 
590
- {renderMobileCard && (
591
- <div className="grid gap-3 md:hidden">
592
- {stateContent ??
593
- (shouldRenderSkeleton ? (
594
- <LoadingState label="Loading data..." {...loadingState} />
595
- ) : (
596
- rows.map((row) => <React.Fragment key={row.id}>{renderMobileCard(row)}</React.Fragment>)
597
- ))}
598
- </div>
599
- )}
600
-
601
- <div
602
- data-slot="data-table-wrapper"
603
- data-density={density}
604
- data-striped={striped || undefined}
605
- data-bordered={bordered || undefined}
606
- data-virtualized={virtualizationEnabled || undefined}
607
- className={cn(
608
- "overflow-hidden rounded-[var(--aui-card-radius,var(--radius-lg))] border border-[color:var(--aui-card-border,var(--border))] bg-card shadow-[var(--aui-card-shadow,0_10px_24px_rgba(15,23,42,0.07))] backdrop-blur",
609
- renderMobileCard && "hidden md:block",
610
- tableWrapperClassName
611
- )}
612
- >
656
+ {shouldUseMobileCards && (
657
+ <div className="grid gap-3">
658
+ {stateContent ??
659
+ (shouldRenderSkeleton ? (
660
+ <LoadingState label="Loading data..." {...loadingState} />
661
+ ) : (
662
+ rows.map((row) => (
663
+ <React.Fragment key={row.id}>
664
+ {renderMobileCard ? renderMobileCard(row) : renderDefaultMobileCard(row)}
665
+ </React.Fragment>
666
+ ))
667
+ ))}
668
+ </div>
669
+ )}
670
+
671
+ {!shouldUseMobileCards && (
672
+ <div
673
+ data-slot="data-table-wrapper"
674
+ data-density={density}
675
+ data-striped={striped || undefined}
676
+ data-bordered={bordered || undefined}
677
+ data-virtualized={virtualizationEnabled || undefined}
678
+ className={cn(
679
+ "overflow-hidden rounded-[var(--aui-card-radius,var(--radius-lg))] border border-[color:var(--aui-card-border,var(--border))] bg-card shadow-[var(--aui-card-shadow,0_10px_24px_rgba(15,23,42,0.07))] backdrop-blur",
680
+ tableWrapperClassName
681
+ )}
682
+ >
613
683
  <Table
614
684
  containerRef={tableScrollRef}
615
685
  containerStyle={
@@ -691,7 +761,8 @@ function DataTable<TData, TValue = unknown>({
691
761
  onPageSizeChange={paginationConfig.onPageSizeChange}
692
762
  />
693
763
  )}
694
- </div>
764
+ </div>
765
+ )}
695
766
  </div>
696
767
  )
697
768
  }
@@ -413,10 +413,10 @@ function KanbanBoard({
413
413
  role="group"
414
414
  aria-label={ariaLabel}
415
415
  data-slot="kanban-board"
416
- className={cn(
417
- "grid auto-cols-[minmax(280px,1fr)] grid-flow-col gap-4 overflow-x-auto pb-2",
418
- className
419
- )}
416
+ className={cn(
417
+ "grid gap-4 sm:auto-cols-[minmax(280px,1fr)] sm:grid-flow-col sm:overflow-x-auto sm:pb-2",
418
+ className
419
+ )}
420
420
  >
421
421
  {renderedColumns.map((column) => (
422
422
  <KanbanColumnView
@@ -1,6 +1,7 @@
1
1
  import { actionsShowcaseDemoRegistry } from "@/components/actions/demo"
2
- import { calendarShowcaseDemoRegistry } from "@/components/calendar/demo"
3
- import { dataTableShowcaseDemoRegistry } from "@/components/data-table/demo"
2
+ import { calendarShowcaseDemoRegistry } from "@/components/calendar/demo"
3
+ import { chartsShowcaseDemoRegistry } from "@/components/charts/demo"
4
+ import { dataTableShowcaseDemoRegistry } from "@/components/data-table/demo"
4
5
  import { displayShowcaseDemoRegistry } from "@/components/display/demo"
5
6
  import { feedbackShowcaseDemoRegistry } from "@/components/feedback/demo"
6
7
  import { filtersShowcaseDemoRegistry } from "@/components/filters/demo"
@@ -32,8 +33,9 @@ export * from "./supplemental"
32
33
 
33
34
  export const showcaseDemoRegistry = {
34
35
  ...actionsShowcaseDemoRegistry,
35
- ...calendarShowcaseDemoRegistry,
36
- ...dataTableShowcaseDemoRegistry,
36
+ ...calendarShowcaseDemoRegistry,
37
+ ...chartsShowcaseDemoRegistry,
38
+ ...dataTableShowcaseDemoRegistry,
37
39
  ...displayShowcaseDemoRegistry,
38
40
  ...feedbackShowcaseDemoRegistry,
39
41
  ...filtersShowcaseDemoRegistry,
@@ -1,4 +1,4 @@
1
- export const PACKAGE_LATEST_VERSION = "3.1.10"
1
+ export const PACKAGE_LATEST_VERSION = "3.1.11"
2
2
  export const PACKAGE_LATEST_RELEASE_DATE = "July 15, 2026"
3
3
  export const PACKAGE_DEPENDENCY_RANGE = PACKAGE_LATEST_VERSION
4
4
 
@@ -2,6 +2,7 @@ import type { ReactElement } from "react"
2
2
 
3
3
  import { actionsShowcaseDemoRegistry } from "@/components/actions/demo"
4
4
  import { calendarShowcaseDemoRegistry } from "@/components/calendar/demo"
5
+ import { chartsShowcaseDemoRegistry } from "@/components/charts/demo"
5
6
  import { dataTableShowcaseDemoRegistry } from "@/components/data-table/demo"
6
7
  import { displayShowcaseDemoRegistry } from "@/components/display/demo"
7
8
  import { feedbackShowcaseDemoRegistry } from "@/components/feedback/demo"
@@ -57,6 +58,7 @@ const darkPanelClassName =
57
58
  const componentPreviewRegistry = {
58
59
  ...actionsShowcaseDemoRegistry,
59
60
  ...calendarShowcaseDemoRegistry,
61
+ ...chartsShowcaseDemoRegistry,
60
62
  ...dataTableShowcaseDemoRegistry,
61
63
  ...displayShowcaseDemoRegistry,
62
64
  ...feedbackShowcaseDemoRegistry,
@@ -16,11 +16,15 @@ import {
16
16
  Alert,
17
17
  AlertDialog,
18
18
  Badge,
19
+ BarChart,
19
20
  Button,
20
21
  ButtonGroup,
21
22
  Calendar,
23
+ ChartFrame,
24
+ ChartLegend,
22
25
  CommandPalette,
23
26
  DescriptionList,
27
+ DonutChart,
24
28
  Drawer,
25
29
  FileUpload,
26
30
  FilterBar,
@@ -333,6 +337,38 @@ function DisplayPreview({ slug }: { slug: string }) {
333
337
  )
334
338
  }
335
339
 
340
+ if (slug === "charts") {
341
+ const channelData = [
342
+ { label: "Organic", value: 42, color: "var(--aui-brand)" },
343
+ { label: "Paid", value: 28, color: "var(--aui-success)" },
344
+ { label: "Referral", value: 18, color: "var(--aui-warning)" },
345
+ { label: "Direct", value: 12, color: "var(--aui-danger)" },
346
+ ]
347
+
348
+ return (
349
+ <div className="grid items-start gap-4 lg:grid-cols-[1.2fr_0.8fr]">
350
+ <ChartFrame title="Pipeline by week" description="BarChart inside the shared chart frame.">
351
+ <BarChart
352
+ data={[
353
+ { label: "Mon", value: 18 },
354
+ { label: "Tue", value: 26 },
355
+ { label: "Wed", value: 21 },
356
+ { label: "Thu", value: 34 },
357
+ { label: "Fri", value: 29 },
358
+ ]}
359
+ valueFormatter={(value) => `$${value}k`}
360
+ />
361
+ </ChartFrame>
362
+ <ChartFrame title="Traffic mix" description="DonutChart with legend and center value.">
363
+ <div className="grid justify-items-center gap-4">
364
+ <DonutChart data={channelData} centerValue="88k" centerLabel="Visitors" />
365
+ <ChartLegend data={channelData} />
366
+ </div>
367
+ </ChartFrame>
368
+ </div>
369
+ )
370
+ }
371
+
336
372
  return (
337
373
  <InfoCard
338
374
  title="Azamat Jurayev"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://tembro.dev/registry.schema.json",
3
3
  "name": "tembro",
4
- "version": "3.1.10",
4
+ "version": "3.1.11",
5
5
  "description": "Reusable React + TypeScript UI kit registry",
6
6
  "groups": {
7
7
  "ui": [
@@ -161,7 +161,10 @@
161
161
  "wizard-kit",
162
162
  "all"
163
163
  ],
164
- "charts": []
164
+ "charts": [
165
+ "charts",
166
+ "progress-circle"
167
+ ]
165
168
  },
166
169
  "recommended": [
167
170
  "button",
@@ -84,7 +84,7 @@ function App() {
84
84
  <div className="min-w-0">
85
85
  <HeroSection />
86
86
 
87
- <div className="mx-auto grid max-w-7xl gap-10 px-6 py-10 lg:px-8">
87
+ <div className="grid w-full gap-10 px-6 py-10 lg:px-8 2xl:px-10">
88
88
  {selection.type === "overview" ? <OverviewContent /> : null}
89
89
  {selection.type === "category" ? (
90
90
  <CategorySection group={selection.group} onSelect={setSelectedKey} />
@@ -9,7 +9,7 @@ import { moduleCount, registryGroups } from "@/showcase/data/registry"
9
9
  export function HeroSection() {
10
10
  return (
11
11
  <section className="border-b bg-card">
12
- <div className="mx-auto max-w-7xl px-6 py-8 lg:px-8">
12
+ <div className="w-full px-6 py-8 lg:px-8 2xl:px-10">
13
13
  <div className="flex flex-wrap items-start justify-between gap-6">
14
14
  <div className="max-w-3xl">
15
15
  <div className="mb-3 flex flex-wrap gap-2">
@@ -25,7 +25,7 @@ export function HeroSection() {
25
25
  <div className="flex flex-wrap gap-2">
26
26
  <Button leftIcon={<PlusIcon className="size-4" />}>Create</Button>
27
27
  <Button variant="outline" leftIcon={<SettingsIcon className="size-4" />}>Settings</Button>
28
- <CopyButton value="npx tembro@3.1.10 list --json">Copy list command</CopyButton>
28
+ <CopyButton value="npx tembro@3.1.11 list --json">Copy list command</CopyButton>
29
29
  </div>
30
30
  </div>
31
31
 
@@ -33,7 +33,7 @@ export function HeroSection() {
33
33
  <StatisticCard label="Registry components" value={moduleCount} change="visible below" trend="up" description="tembro add <name>" />
34
34
  <StatisticCard label="Local source files" value="152" change="with hooks/lib" trend="up" description="installed by CLI" />
35
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.10" />
36
+ <StatisticCard label="Build" value="Pass" change="doctor pass" trend="up" description="tembro@3.1.11" />
37
37
  </StatisticGrid>
38
38
  </div>
39
39
  </section>
@@ -72,7 +72,7 @@ export function WorkbenchSidebar({ selectedKey, onSelect }: WorkbenchSidebarProp
72
72
  }),
73
73
  ]}
74
74
  footerAccount={{
75
- label: "tembro@3.1.10",
75
+ label: "tembro@3.1.11",
76
76
  description: `${moduleCount} registry components`,
77
77
  }}
78
78
  activeIndicator="bar"
@@ -10,7 +10,7 @@ export function CalendarSection() {
10
10
  const [page, setPage] = useState(2)
11
11
 
12
12
  return (
13
- <div className="grid gap-4 lg:grid-cols-[1fr_0.8fr]">
13
+ <div className="grid items-start gap-4 lg:grid-cols-[1fr_0.8fr]">
14
14
  <Card>
15
15
  <CardHeader>
16
16
  <CardTitle>Calendar</CardTitle>
@@ -227,7 +227,7 @@ function SidebarPreview() {
227
227
 
228
228
  function DisplayPreview() {
229
229
  return (
230
- <div className="grid gap-4 lg:grid-cols-2">
230
+ <div className="grid items-start gap-4 lg:grid-cols-2">
231
231
  <ProgressCard title="ProgressCard" description="display/progress" value={72} tone="success" />
232
232
  <StatusLegend
233
233
  title="StatusLegend"
@@ -16,7 +16,7 @@ import { registryGroups } from "@/showcase/data/registry"
16
16
 
17
17
  export function CoreUiSection() {
18
18
  return (
19
- <div className="grid gap-4 xl:grid-cols-[1.35fr_0.65fr]">
19
+ <div className="grid items-start gap-4 xl:grid-cols-[1.35fr_0.65fr]">
20
20
  <Card>
21
21
  <CardHeader>
22
22
  <CardTitle>UI controls and variants</CardTitle>
@@ -53,7 +53,7 @@ export function CoreUiSection() {
53
53
  }))}
54
54
  />
55
55
  </div>
56
- <div className="grid gap-4 md:grid-cols-2">
56
+ <div className="grid items-start gap-4 md:grid-cols-2">
57
57
  <Textarea defaultValue="Textarea with helper text, counter and Tembro theme." helperText="Textarea helper text" maxLength={140} showCharacterCount />
58
58
  <div className="grid content-start gap-4 rounded-lg border bg-muted/25 p-4">
59
59
  <Switch defaultChecked label="Enable preview" description="Switch with label and description" />
@@ -7,7 +7,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
7
7
 
8
8
  export function FormsSection() {
9
9
  return (
10
- <div className="grid gap-4 lg:grid-cols-3">
10
+ <div className="grid items-start gap-4 lg:grid-cols-3">
11
11
  <Card>
12
12
  <CardHeader>
13
13
  <CardTitle>Advanced inputs</CardTitle>
@@ -12,7 +12,7 @@ export function OverlaySection() {
12
12
  const [confirmOpen, setConfirmOpen] = useState(false)
13
13
 
14
14
  return (
15
- <div className="grid gap-4 lg:grid-cols-3">
15
+ <div className="grid items-start gap-4 lg:grid-cols-3">
16
16
  <Card>
17
17
  <CardHeader>
18
18
  <CardTitle>Drawer</CardTitle>
@@ -4,7 +4,7 @@ import { EmptyState } from "@/components/patterns/empty-state"
4
4
 
5
5
  export function PatternsSection() {
6
6
  return (
7
- <div className="grid gap-4 lg:grid-cols-3">
7
+ <div className="grid items-start gap-4 lg:grid-cols-3">
8
8
  <EmptyState
9
9
  title="EmptyState pattern"
10
10
  description="Pattern components are installed: resource pages, settings pages, page toolbar, data view and form builder."
@@ -8,7 +8,7 @@ export function VerificationSection() {
8
8
  return (
9
9
  <section>
10
10
  <SectionTitle title="Verification" description="Package va project setup holati." />
11
- <div className="grid gap-4 md:grid-cols-3">
11
+ <div className="grid items-start gap-4 md:grid-cols-3">
12
12
  <Card>
13
13
  <CardContent className="flex items-start gap-3 pt-6">
14
14
  <CheckCircle2Icon className="mt-1 size-5 text-emerald-600" />
@@ -9,7 +9,7 @@ export function WizardSection() {
9
9
  const [step, setStep] = useState("test")
10
10
 
11
11
  return (
12
- <div className="grid gap-4 lg:grid-cols-[1fr_0.8fr]">
12
+ <div className="grid items-start gap-4 lg:grid-cols-[1fr_0.8fr]">
13
13
  <Card>
14
14
  <CardHeader>
15
15
  <CardTitle>Stepper</CardTitle>
package/registry.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://tembro.dev/registry.schema.json",
3
3
  "name": "tembro",
4
- "version": "3.1.10",
4
+ "version": "3.1.11",
5
5
  "description": "Reusable React + TypeScript UI kit registry",
6
6
  "groups": {
7
7
  "ui": [
@@ -161,7 +161,10 @@
161
161
  "wizard-kit",
162
162
  "all"
163
163
  ],
164
- "charts": []
164
+ "charts": [
165
+ "charts",
166
+ "progress-circle"
167
+ ]
165
168
  },
166
169
  "recommended": [
167
170
  "button",