minka-ds 0.1.1 → 0.1.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minka-ds",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Minka product design system — tokenized component library",
5
5
  "license": "MIT",
6
6
  "files": ["src", "tokens"],
@@ -7,7 +7,6 @@ import {
7
7
  VisibilityState,
8
8
  flexRender,
9
9
  getCoreRowModel,
10
- getPaginationRowModel,
11
10
  getSortedRowModel,
12
11
  useReactTable,
13
12
  type Table as TanstackTable,
@@ -16,15 +15,6 @@ import { ChevronsUpDown, ChevronUp, ChevronDown, Columns3Cog } from "lucide-reac
16
15
 
17
16
  import { cn } from "../../lib/utils"
18
17
  import { Button } from "./button"
19
- import {
20
- Pagination,
21
- PaginationContent,
22
- PaginationEllipsis,
23
- PaginationItem,
24
- PaginationLink,
25
- PaginationNext,
26
- PaginationPrevious,
27
- } from "./pagination"
28
18
  import {
29
19
  DropdownMenu,
30
20
  DropdownMenuCheckboxItem,
@@ -44,12 +34,6 @@ import {
44
34
 
45
35
  // ── Column header with sort control ──────────────────────────────────────────
46
36
 
47
- interface DataTableColumnHeaderProps<TData, TValue>
48
- extends React.HTMLAttributes<HTMLDivElement> {
49
- column: TanstackTable<TData>["getColumn"] extends (id: string) => infer C ? NonNullable<C> : never
50
- title: string
51
- }
52
-
53
37
  function DataTableColumnHeader<TData, TValue>({
54
38
  column,
55
39
  title,
@@ -117,108 +101,61 @@ function DataTableColumnToggle<TData>({
117
101
  )
118
102
  }
119
103
 
120
- // ── Pagination ────────────────────────────────────────────────────────────────
121
-
122
- function getPageNumbers(currentPage: number, totalPages: number): (number | "ellipsis")[] {
123
- if (totalPages <= 7) return Array.from({ length: totalPages }, (_, i) => i + 1)
124
- const pages: (number | "ellipsis")[] = [1]
125
- if (currentPage > 3) pages.push("ellipsis")
126
- const start = Math.max(2, currentPage - 1)
127
- const end = Math.min(totalPages - 1, currentPage + 1)
128
- for (let i = start; i <= end; i++) pages.push(i)
129
- if (currentPage < totalPages - 2) pages.push("ellipsis")
130
- pages.push(totalPages)
131
- return pages
132
- }
133
-
134
- function DataTablePagination<TData>({
135
- table,
136
- }: {
137
- table: TanstackTable<TData>
138
- }) {
139
- const currentPage = table.getState().pagination.pageIndex + 1
140
- const totalPages = table.getPageCount()
141
- const pages = getPageNumbers(currentPage, totalPages)
142
-
143
- return (
144
- <div className="flex items-center justify-between">
145
- <p className="text-body-sm text-[var(--color-text-muted)]">
146
- Page {currentPage} of {totalPages}
147
- </p>
148
- <Pagination className="mx-0 w-auto justify-end">
149
- <PaginationContent>
150
- <PaginationItem>
151
- <PaginationPrevious
152
- onClick={() => table.previousPage()}
153
- aria-disabled={!table.getCanPreviousPage()}
154
- className={cn(!table.getCanPreviousPage() && "pointer-events-none opacity-50")}
155
- />
156
- </PaginationItem>
157
- {pages.map((page, i) =>
158
- page === "ellipsis" ? (
159
- <PaginationItem key={`ellipsis-${i}`}>
160
- <PaginationEllipsis />
161
- </PaginationItem>
162
- ) : (
163
- <PaginationItem key={page}>
164
- <PaginationLink
165
- isActive={page === currentPage}
166
- onClick={() => table.setPageIndex(page - 1)}
167
- className="cursor-pointer"
168
- >
169
- {page}
170
- </PaginationLink>
171
- </PaginationItem>
172
- )
173
- )}
174
- <PaginationItem>
175
- <PaginationNext
176
- onClick={() => table.nextPage()}
177
- aria-disabled={!table.getCanNextPage()}
178
- className={cn(!table.getCanNextPage() && "pointer-events-none opacity-50")}
179
- />
180
- </PaginationItem>
181
- </PaginationContent>
182
- </Pagination>
183
- </div>
184
- )
185
- }
186
-
187
104
  // ── DataTable ─────────────────────────────────────────────────────────────────
188
105
 
189
106
  interface DataTableProps<TData, TValue> {
190
107
  columns: ColumnDef<TData, TValue>[]
191
108
  data: TData[]
192
- pageSize?: number
109
+ batchSize?: number
193
110
  onRowClick?: (row: TData) => void
111
+ className?: string
194
112
  }
195
113
 
196
114
  function DataTable<TData, TValue>({
197
115
  columns,
198
116
  data,
199
- pageSize = 10,
117
+ batchSize = 20,
200
118
  onRowClick,
119
+ className,
201
120
  }: DataTableProps<TData, TValue>) {
202
121
  const [sorting, setSorting] = React.useState<SortingState>([])
203
122
  const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({})
123
+ const [displayCount, setDisplayCount] = React.useState(batchSize)
124
+ const [hasMore, setHasMore] = React.useState(data.length > batchSize)
125
+
126
+ const displayedData = React.useMemo(
127
+ () => data.slice(0, displayCount),
128
+ [data, displayCount]
129
+ )
204
130
 
205
131
  const table = useReactTable({
206
- data,
132
+ data: displayedData,
207
133
  columns,
208
134
  getCoreRowModel: getCoreRowModel(),
209
- getPaginationRowModel: getPaginationRowModel(),
210
135
  getSortedRowModel: getSortedRowModel(),
211
136
  onSortingChange: setSorting,
212
137
  onColumnVisibilityChange: setColumnVisibility,
213
- initialState: { pagination: { pageSize } },
214
138
  state: { sorting, columnVisibility },
215
139
  })
216
140
 
141
+ function handleScroll(e: React.UIEvent<HTMLDivElement>) {
142
+ const { scrollTop, scrollHeight, clientHeight } = e.currentTarget
143
+ const remaining = scrollHeight - scrollTop - clientHeight
144
+ setHasMore(remaining > 2 || displayCount < data.length)
145
+ if (remaining < 120) {
146
+ setDisplayCount((c) => Math.min(c + batchSize, data.length))
147
+ }
148
+ }
149
+
217
150
  return (
218
- <div className="space-y-4">
219
- <div className="rounded-[var(--radius-card)] border border-[var(--color-border-default)] bg-[var(--color-bg-raised)] overflow-hidden">
151
+ <div className={cn("relative flex flex-col min-h-0", className)}>
152
+ <div
153
+ onScroll={handleScroll}
154
+ className="flex-1 min-h-0 overflow-auto rounded-[var(--radius-card)] border border-[var(--color-border-default)] bg-[var(--color-bg-raised)] [&_[data-slot=table-container]]:overflow-visible"
155
+ >
156
+
220
157
  <Table className="[&_th:first-child]:pl-4 [&_td:first-child]:pl-4">
221
- <TableHeader className="bg-[var(--color-bg-base)]">
158
+ <TableHeader className="sticky top-0 z-10 bg-[var(--color-bg-base)]">
222
159
  {table.getHeaderGroups().map((headerGroup) => (
223
160
  <TableRow key={headerGroup.id}>
224
161
  {headerGroup.headers.map((header, index) => (
@@ -265,15 +202,15 @@ function DataTable<TData, TValue>({
265
202
  </TableBody>
266
203
  </Table>
267
204
  </div>
268
- <DataTablePagination table={table} />
205
+ {hasMore && (
206
+ <div className="pointer-events-none absolute bottom-0 left-0 right-0 h-16 rounded-b-[var(--radius-card)] bg-gradient-to-t from-[var(--color-bg-raised)] to-transparent" />
207
+ )}
269
208
  </div>
270
209
  )
271
-
272
210
  }
273
211
 
274
212
  export {
275
213
  DataTable,
276
214
  DataTableColumnHeader,
277
215
  DataTableColumnToggle,
278
- DataTablePagination,
279
216
  }
@@ -0,0 +1,15 @@
1
+ import * as React from "react"
2
+ import { cn } from "../../lib/utils"
3
+
4
+ export function Kbd({ children, className }: { children: React.ReactNode; className?: string }) {
5
+ return (
6
+ <kbd
7
+ className={cn(
8
+ "inline-flex items-center gap-1 h-5 font-sans [border-radius:var(--radius-tooltip)] border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] px-1.5 text-caption text-[var(--color-text-muted)]",
9
+ className
10
+ )}
11
+ >
12
+ {children}
13
+ </kbd>
14
+ )
15
+ }
@@ -0,0 +1,11 @@
1
+ import * as React from "react"
2
+
3
+ export function usePlatform() {
4
+ const [isMac, setIsMac] = React.useState(true)
5
+
6
+ React.useEffect(() => {
7
+ setIsMac(navigator.userAgent.includes("Mac"))
8
+ }, [])
9
+
10
+ return { isMac }
11
+ }
package/src/index.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  // Utilities
2
2
  export { cn } from "./lib/utils"
3
3
 
4
+ // Hooks
5
+ export { usePlatform } from "./hooks/use-platform"
6
+
4
7
  // Components
5
8
  export * from "./components/ui/badge"
6
9
  export * from "./components/ui/cell"
@@ -15,6 +18,7 @@ export * from "./components/ui/dialog"
15
18
  export * from "./components/ui/dropdown-menu"
16
19
  export * from "./components/ui/input"
17
20
  export * from "./components/ui/input-group"
21
+ export * from "./components/ui/kbd"
18
22
  export * from "./components/ui/label"
19
23
  export * from "./components/ui/pagination"
20
24
  export * from "./components/ui/select"