@godxjp/ui 14.0.0 → 15.0.0

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.
@@ -1,402 +0,0 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import * as React from "react";
3
- import {
4
- flexRender,
5
- getCoreRowModel,
6
- getFilteredRowModel,
7
- getPaginationRowModel,
8
- getSortedRowModel,
9
- useReactTable
10
- } from "@tanstack/react-table";
11
- import {
12
- ArrowDown,
13
- ArrowUp,
14
- ChevronLeft,
15
- ChevronRight,
16
- ChevronsUpDown,
17
- Layers,
18
- Layers2,
19
- SlidersHorizontal
20
- } from "lucide-react";
21
- import { useTranslation } from "../../i18n/use-translation";
22
- import { cn } from "../../lib/utils";
23
- import { densityClass } from "../../lib/variants";
24
- import { tableCellPaddingClass, tableRowHeightClass } from "../../lib/control-styles";
25
- import { Flex } from "../layout/flex";
26
- import { Button } from "../general/button";
27
- import { Checkbox } from "../data-entry/checkbox";
28
- import { SearchInput } from "../data-entry/search-input";
29
- import {
30
- Select,
31
- SelectContent,
32
- SelectItem,
33
- SelectTrigger,
34
- SelectValue
35
- } from "../data-entry/select";
36
- import {
37
- DropdownMenu,
38
- DropdownMenuCheckboxItem,
39
- DropdownMenuContent,
40
- DropdownMenuLabel,
41
- DropdownMenuSeparator,
42
- DropdownMenuTrigger
43
- } from "../navigation/dropdown-menu";
44
- import { EmptyState } from "../data-display/empty-state";
45
- import {
46
- Table,
47
- TableBody,
48
- TableCell,
49
- TableHead,
50
- TableHeader,
51
- TableRow
52
- } from "../data-display/table";
53
- const DataGridContext = React.createContext(null);
54
- function useDataGrid() {
55
- const ctx = React.useContext(DataGridContext);
56
- if (!ctx) throw new Error("DataGrid.* must be used inside <DataGrid>");
57
- return ctx;
58
- }
59
- const DataGrid = function DataGridRoot({
60
- columns,
61
- data,
62
- getRowId,
63
- rowIdKey = "id",
64
- sorting,
65
- onSortingChange,
66
- columnFilters,
67
- onColumnFiltersChange,
68
- globalFilter,
69
- onGlobalFilterChange,
70
- pagination,
71
- onPaginationChange,
72
- rowCount,
73
- rowSelection,
74
- onRowSelectionChange,
75
- enableRowSelection = false,
76
- columnVisibility: columnVisibilityProp,
77
- onColumnVisibilityChange,
78
- manualSorting = true,
79
- manualFiltering = true,
80
- manualPagination = true,
81
- density: densityProp,
82
- onDensityChange,
83
- loading = false,
84
- empty,
85
- onRowClick,
86
- className,
87
- children
88
- }) {
89
- const [internalDensity, setInternalDensity] = React.useState("comfortable");
90
- const density = densityProp ?? internalDensity;
91
- const setDensity = (d) => {
92
- if (!densityProp) setInternalDensity(d);
93
- onDensityChange?.(d);
94
- };
95
- const [internalSorting, setInternalSorting] = React.useState([]);
96
- const [internalFilters, setInternalFilters] = React.useState([]);
97
- const [internalGlobal, setInternalGlobal] = React.useState("");
98
- const [internalPagination, setInternalPagination] = React.useState({
99
- pageIndex: 0,
100
- pageSize: 10
101
- });
102
- const [internalSelection, setInternalSelection] = React.useState({});
103
- const [internalVisibility, setInternalVisibility] = React.useState({});
104
- const resolveRowId = React.useCallback(
105
- (row) => getRowId ? getRowId(row) : String(row[rowIdKey]),
106
- [getRowId, rowIdKey]
107
- );
108
- const table = useReactTable({
109
- data,
110
- columns,
111
- getRowId: resolveRowId,
112
- getCoreRowModel: getCoreRowModel(),
113
- ...manualSorting ? {} : { getSortedRowModel: getSortedRowModel() },
114
- ...manualFiltering ? {} : { getFilteredRowModel: getFilteredRowModel() },
115
- ...manualPagination ? {} : { getPaginationRowModel: getPaginationRowModel() },
116
- manualSorting,
117
- manualFiltering,
118
- manualPagination,
119
- rowCount,
120
- enableRowSelection,
121
- state: {
122
- sorting: sorting ?? internalSorting,
123
- columnFilters: columnFilters ?? internalFilters,
124
- globalFilter: globalFilter ?? internalGlobal,
125
- pagination: pagination ?? internalPagination,
126
- rowSelection: rowSelection ?? internalSelection,
127
- columnVisibility: columnVisibilityProp ?? internalVisibility
128
- },
129
- onSortingChange: onSortingChange ?? setInternalSorting,
130
- onColumnFiltersChange: onColumnFiltersChange ?? setInternalFilters,
131
- onGlobalFilterChange: onGlobalFilterChange ?? setInternalGlobal,
132
- onPaginationChange: onPaginationChange ?? setInternalPagination,
133
- onRowSelectionChange: onRowSelectionChange ?? setInternalSelection,
134
- onColumnVisibilityChange: onColumnVisibilityChange ?? setInternalVisibility
135
- });
136
- const ctx = {
137
- table,
138
- density,
139
- setDensity,
140
- loading,
141
- empty,
142
- onRowClick
143
- };
144
- return /* @__PURE__ */ jsx(DataGridContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
145
- "div",
146
- {
147
- className: cn(
148
- "ui-data-table-root",
149
- densityClass[density === "compact" ? "compact" : "comfortable"],
150
- className
151
- ),
152
- children: children ?? /* @__PURE__ */ jsx(DataGrid.Content, {})
153
- }
154
- ) });
155
- };
156
- DataGrid.displayName = "DataGrid";
157
- DataGrid.Toolbar = function DataGridToolbar({ children, className }) {
158
- return /* @__PURE__ */ jsx(
159
- Flex,
160
- {
161
- direction: "row",
162
- align: "center",
163
- justify: "between",
164
- gap: "sm",
165
- wrap: true,
166
- className: cn("ui-data-table-toolbar", className),
167
- children
168
- }
169
- );
170
- };
171
- DataGrid.Toolbar.displayName = "DataGrid.Toolbar";
172
- DataGrid.Search = function DataGridSearch({ placeholder, className }) {
173
- const { table } = useDataGrid();
174
- const { t } = useTranslation();
175
- const value = table.getState().globalFilter ?? "";
176
- return /* @__PURE__ */ jsx(
177
- SearchInput,
178
- {
179
- value,
180
- onValueChange: (q) => table.setGlobalFilter(q),
181
- onSearch: (q) => table.setGlobalFilter(q),
182
- placeholder: placeholder ?? t("dataGrid.searchPlaceholder"),
183
- ariaLabel: t("dataGrid.search"),
184
- className
185
- }
186
- );
187
- };
188
- DataGrid.Search.displayName = "DataGrid.Search";
189
- DataGrid.ViewOptions = function DataGridViewOptions({ className }) {
190
- const { table } = useDataGrid();
191
- const { t } = useTranslation();
192
- const hideable = table.getAllLeafColumns().filter((c) => c.getCanHide());
193
- if (hideable.length === 0) return null;
194
- return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
195
- /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className, children: [
196
- /* @__PURE__ */ jsx(SlidersHorizontal, { className: "size-4 shrink-0", "aria-hidden": "true" }),
197
- t("dataGrid.view")
198
- ] }) }),
199
- /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", children: [
200
- /* @__PURE__ */ jsx(DropdownMenuLabel, { children: t("dataGrid.toggleColumns") }),
201
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
202
- hideable.map((column) => /* @__PURE__ */ jsx(
203
- DropdownMenuCheckboxItem,
204
- {
205
- checked: column.getIsVisible(),
206
- onCheckedChange: (v) => column.toggleVisibility(!!v),
207
- children: columnLabel(column)
208
- },
209
- column.id
210
- ))
211
- ] })
212
- ] });
213
- };
214
- DataGrid.ViewOptions.displayName = "DataGrid.ViewOptions";
215
- function columnLabel(column) {
216
- const meta = column.columnDef.meta;
217
- if (meta?.label) return meta.label;
218
- if (typeof column.columnDef.header === "string") return column.columnDef.header;
219
- return column.id;
220
- }
221
- DataGrid.BulkActions = function DataGridBulkActions({ children }) {
222
- const { table } = useDataGrid();
223
- const count = table.getSelectedRowModel().rows.length;
224
- if (count === 0) return null;
225
- return /* @__PURE__ */ jsx(Flex, { direction: "row", align: "center", gap: "sm", children: children(count) });
226
- };
227
- DataGrid.BulkActions.displayName = "DataGrid.BulkActions";
228
- DataGrid.DensityToggle = function DataGridDensityToggle() {
229
- const { density, setDensity } = useDataGrid();
230
- const { t } = useTranslation();
231
- const next = density === "compact" ? "comfortable" : "compact";
232
- const Icon = density === "compact" ? Layers : Layers2;
233
- const nextLabel = next === "compact" ? t("dataTable.densityCompact") : t("dataTable.densityComfortable");
234
- return /* @__PURE__ */ jsxs(
235
- Button,
236
- {
237
- variant: "outline",
238
- size: "sm",
239
- onClick: () => setDensity(next),
240
- "aria-label": t("dataTable.densitySwitch", { density: nextLabel }),
241
- children: [
242
- /* @__PURE__ */ jsx(Icon, { className: "size-4 shrink-0", "aria-hidden": "true" }),
243
- density === "compact" ? t("dataTable.densityCompact") : t("dataTable.densityComfortable")
244
- ]
245
- }
246
- );
247
- };
248
- DataGrid.DensityToggle.displayName = "DataGrid.DensityToggle";
249
- DataGrid.Content = function DataGridContent() {
250
- const { table, loading, empty, onRowClick } = useDataGrid();
251
- const { t } = useTranslation();
252
- const leafCount = table.getVisibleLeafColumns().length;
253
- const enableSelection = table.options.enableRowSelection;
254
- const colSpan = leafCount + (enableSelection ? 1 : 0);
255
- const isInteractive = (target) => !!target.closest("button, a, input, select, textarea, [role=menuitem], [role=checkbox]");
256
- return /* @__PURE__ */ jsx("div", { className: "ui-data-table-scroll", "aria-busy": loading, children: /* @__PURE__ */ jsx("div", { className: "ui-data-table-surface min-w-[640px] sm:min-w-0", children: /* @__PURE__ */ jsxs(Table, { children: [
257
- /* @__PURE__ */ jsx(TableHeader, { className: "bg-secondary sticky top-0 z-10", children: table.getHeaderGroups().map((hg) => /* @__PURE__ */ jsxs(TableRow, { children: [
258
- enableSelection && /* @__PURE__ */ jsx(TableHead, { className: "w-10", children: /* @__PURE__ */ jsx(
259
- Checkbox,
260
- {
261
- checked: table.getIsAllPageRowsSelected() ? true : table.getIsSomePageRowsSelected() ? "indeterminate" : false,
262
- onCheckedChange: (v) => table.toggleAllPageRowsSelected(!!v),
263
- "aria-label": t("dataTable.selectAll")
264
- }
265
- ) }),
266
- hg.headers.map((header) => {
267
- const canSort = header.column.getCanSort();
268
- const sorted = header.column.getIsSorted();
269
- return /* @__PURE__ */ jsx(
270
- TableHead,
271
- {
272
- "aria-sort": canSort ? sorted === "asc" ? "ascending" : sorted === "desc" ? "descending" : "none" : void 0,
273
- className: cn(canSort && "select-none"),
274
- children: header.isPlaceholder ? null : canSort ? /* @__PURE__ */ jsxs(
275
- "button",
276
- {
277
- type: "button",
278
- className: "ui-data-table-sort-button focus-visible:ring-ring inline-flex items-center gap-1 rounded-sm focus-visible:ring-2",
279
- onClick: header.column.getToggleSortingHandler(),
280
- children: [
281
- flexRender(header.column.columnDef.header, header.getContext()),
282
- sorted === "asc" ? /* @__PURE__ */ jsx(ArrowUp, { className: "size-3", "aria-hidden": "true" }) : sorted === "desc" ? /* @__PURE__ */ jsx(ArrowDown, { className: "size-3", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(
283
- ChevronsUpDown,
284
- {
285
- className: "text-muted-foreground size-3",
286
- "aria-hidden": "true"
287
- }
288
- )
289
- ]
290
- }
291
- ) : flexRender(header.column.columnDef.header, header.getContext())
292
- },
293
- header.id
294
- );
295
- })
296
- ] }, hg.id)) }),
297
- /* @__PURE__ */ jsx(TableBody, { children: loading ? /* @__PURE__ */ jsx(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ jsx(TableCell, { colSpan, className: "h-32 text-center", "aria-live": "polite", children: /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: t("dataTable.loading") }) }) }) : table.getRowModel().rows.length === 0 ? /* @__PURE__ */ jsx(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ jsx(TableCell, { colSpan, className: "ui-data-table-empty", "aria-live": "polite", children: empty ?? /* @__PURE__ */ jsx(EmptyState, { title: t("dataTable.empty") }) }) }) : table.getRowModel().rows.map((row) => {
298
- const selected = row.getIsSelected();
299
- return /* @__PURE__ */ jsxs(
300
- TableRow,
301
- {
302
- "data-state": selected ? "selected" : void 0,
303
- tabIndex: onRowClick ? 0 : void 0,
304
- onClick: (e) => {
305
- if (isInteractive(e.target)) return;
306
- onRowClick?.(row.original);
307
- },
308
- onKeyDown: onRowClick ? (e) => {
309
- if (e.key !== "Enter" && e.key !== " ") return;
310
- if (e.target !== e.currentTarget) return;
311
- e.preventDefault();
312
- onRowClick(row.original);
313
- } : void 0,
314
- className: cn(
315
- tableRowHeightClass,
316
- onRowClick && "hover:bg-muted/50 focus-visible:ring-ring cursor-pointer focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-inset",
317
- selected && "bg-muted/30"
318
- ),
319
- children: [
320
- enableSelection && /* @__PURE__ */ jsx(TableCell, { className: tableCellPaddingClass, children: /* @__PURE__ */ jsx(
321
- Checkbox,
322
- {
323
- checked: selected,
324
- onCheckedChange: (v) => row.toggleSelected(!!v),
325
- "aria-label": t("dataTable.selectRow", { id: row.id }),
326
- onClick: (e) => e.stopPropagation()
327
- }
328
- ) }),
329
- row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, { className: tableCellPaddingClass, children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))
330
- ]
331
- },
332
- row.id
333
- );
334
- }) })
335
- ] }) }) });
336
- };
337
- DataGrid.Content.displayName = "DataGrid.Content";
338
- DataGrid.Pagination = function DataGridPagination({
339
- pageSizeOptions = [10, 20, 50, 100],
340
- className
341
- }) {
342
- const { table } = useDataGrid();
343
- const { t } = useTranslation();
344
- const { pageIndex, pageSize } = table.getState().pagination;
345
- const pageCount = table.getPageCount();
346
- return /* @__PURE__ */ jsxs(
347
- Flex,
348
- {
349
- direction: "row",
350
- align: "center",
351
- justify: "between",
352
- gap: "md",
353
- wrap: true,
354
- className: cn("ui-data-table-pagination", className),
355
- children: [
356
- /* @__PURE__ */ jsxs(Flex, { direction: "row", align: "center", gap: "sm", children: [
357
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: t("dataGrid.rowsPerPage") }),
358
- /* @__PURE__ */ jsxs(
359
- Select,
360
- {
361
- value: String(pageSize),
362
- onValueChange: (v) => table.setPageSize(Number(v)),
363
- children: [
364
- /* @__PURE__ */ jsx(SelectTrigger, { size: "sm", "aria-label": t("dataGrid.rowsPerPage"), className: "tabular-nums", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
365
- /* @__PURE__ */ jsx(SelectContent, { children: pageSizeOptions.map((n) => /* @__PURE__ */ jsx(SelectItem, { value: String(n), className: "tabular-nums", children: n }, n)) })
366
- ]
367
- }
368
- )
369
- ] }),
370
- /* @__PURE__ */ jsxs(Flex, { direction: "row", align: "center", gap: "sm", children: [
371
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm tabular-nums", children: t("dataGrid.pageOf", { page: pageIndex + 1, total: Math.max(1, pageCount) }) }),
372
- /* @__PURE__ */ jsx(
373
- Button,
374
- {
375
- variant: "outline",
376
- size: "icon",
377
- disabled: !table.getCanPreviousPage(),
378
- onClick: () => table.previousPage(),
379
- "aria-label": t("common.previous") ?? "Previous",
380
- children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4", "aria-hidden": "true" })
381
- }
382
- ),
383
- /* @__PURE__ */ jsx(
384
- Button,
385
- {
386
- variant: "outline",
387
- size: "icon",
388
- disabled: !table.getCanNextPage(),
389
- onClick: () => table.nextPage(),
390
- "aria-label": t("common.next") ?? "Next",
391
- children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-4", "aria-hidden": "true" })
392
- }
393
- )
394
- ] })
395
- ]
396
- }
397
- );
398
- };
399
- DataGrid.Pagination.displayName = "DataGrid.Pagination";
400
- export {
401
- DataGrid
402
- };
@@ -1,2 +0,0 @@
1
- export { DataGrid } from "./data-grid";
2
- export type { DataGridProps, DataGridDensity, ColumnDef } from "./data-grid";
@@ -1,4 +0,0 @@
1
- import { DataGrid } from "./data-grid";
2
- export {
3
- DataGrid
4
- };
@@ -1,28 +0,0 @@
1
- import * as React from "react";
2
- import type { ShapeProp } from "../../props/vocabulary";
3
- declare const logoVariants: (props?: ({
4
- size?: "xs" | "sm" | "md" | "lg" | null | undefined;
5
- shape?: "default" | "pill" | "sharp" | null | undefined;
6
- } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
- export interface LogoProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
8
- /**
9
- * Accessible product name. When set, the mark exposes `role="img"` + `aria-label` (use this when
10
- * the Logo IS the accessible name — e.g. a home link). When omitted the mark is `aria-hidden`
11
- * (decorative — assume an adjacent wordmark provides the name).
12
- */
13
- label?: string;
14
- /** Box size — maps to the square size scale. Default `md`. */
15
- size?: "xs" | "sm" | "md" | "lg";
16
- /** Corner shape — `default` (--logo-radius) · `pill` (fully rounded) · `sharp` (square). */
17
- shape?: ShapeProp;
18
- /** The mark — a short lettermark string (default `"G"`) or a custom SVG/image node. */
19
- glyph?: React.ReactNode;
20
- }
21
- /**
22
- * Logo — the product brand-mark primitive. Use it INSTEAD of a hand-rolled
23
- * `<span className="flex size-[2rem] rounded-md bg-primary font-bold …">g</span>` (typography-on-span,
24
- * literal size/radius — cardinal rules #42/#46). Renders the lettermark (or a custom SVG) in a
25
- * tokenized box that a service rethemes via `--primary` (fill) and `--logo-radius` (corner).
26
- */
27
- export declare const Logo: React.ForwardRefExoticComponent<LogoProps & React.RefAttributes<HTMLSpanElement>>;
28
- export { logoVariants };
@@ -1,45 +0,0 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import * as React from "react";
3
- import { cva } from "class-variance-authority";
4
- import { cn } from "../../lib/utils";
5
- const logoVariants = cva(
6
- "inline-flex shrink-0 select-none items-center justify-center bg-primary font-bold leading-none text-primary-foreground [&_svg]:size-[60%]",
7
- {
8
- variants: {
9
- size: {
10
- xs: "size-[var(--logo-size-xs)] text-xs",
11
- sm: "size-[var(--logo-size-sm)] text-sm",
12
- md: "size-[var(--logo-size)] text-base",
13
- lg: "size-[var(--logo-size-lg)] text-lg"
14
- },
15
- shape: {
16
- default: "rounded-[var(--logo-radius)]",
17
- pill: "rounded-[var(--radius-pill)]",
18
- sharp: "rounded-[var(--radius-sharp)]"
19
- }
20
- },
21
- defaultVariants: { size: "md", shape: "default" }
22
- }
23
- );
24
- const Logo = React.forwardRef(
25
- ({ glyph = "G", label, size, shape, className, ...props }, ref) => /* @__PURE__ */ jsx(
26
- "span",
27
- {
28
- ref,
29
- "data-slot": "logo",
30
- "data-size": size ?? "md",
31
- "data-shape": shape ?? "default",
32
- role: label ? "img" : void 0,
33
- "aria-label": label,
34
- "aria-hidden": label ? void 0 : true,
35
- className: cn(logoVariants({ size, shape }), className),
36
- ...props,
37
- children: glyph
38
- }
39
- )
40
- );
41
- Logo.displayName = "Logo";
42
- export {
43
- Logo,
44
- logoVariants
45
- };
@@ -1,11 +0,0 @@
1
- /* Logo (brand mark) component tokens. Box size and corner radius are knobs (#45) so a service can
2
- * match its own grid without forking the mark; brand fill follows --primary. The `size` prop picks
3
- * the step; a service retunes the steps globally here. (Not a --control-height tier — the mark is
4
- * decorative, not a density-aware interactive control.) */
5
- :root {
6
- --logo-size: 2rem; /* md */
7
- --logo-size-xs: 1.5rem;
8
- --logo-size-sm: 1.75rem;
9
- --logo-size-lg: 2.5rem;
10
- --logo-radius: var(--radius);
11
- }