@krizaka/ui 3.16.0 → 3.17.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.
- package/dist/blocks.css +8 -0
- package/dist/catalogue-page.d.ts +6 -1
- package/dist/catalogue-page.js +2 -2
- package/dist/catalogue-page.js.map +1 -1
- package/dist/{chunk-SKMJRM5K.js → chunk-53LQPYQZ.js} +2 -2
- package/dist/chunk-53LQPYQZ.js.map +1 -0
- package/dist/data-table.d.ts +76 -3
- package/dist/data-table.js +168 -23
- package/dist/data-table.js.map +1 -1
- package/dist/nav-bar.js +1 -1
- package/dist/site-footer.js +1 -1
- package/dist/sites.js +1 -1
- package/dist/sites.js.map +1 -1
- package/package.json +6 -6
- package/registry/catalogue-page.json +15 -1
- package/registry/data-table.json +89 -6
- package/registry/examples/data-table/catalogue.d.ts +4 -0
- package/registry/examples/data-table/catalogue.js +30 -0
- package/registry/examples/data-table/catalogue.tsx +30 -0
- package/registry/examples/data-table/invoices.d.ts +4 -0
- package/registry/examples/data-table/invoices.js +27 -0
- package/registry/examples/data-table/invoices.tsx +26 -0
- package/registry/examples/data-table/runs.d.ts +4 -0
- package/registry/examples/data-table/runs.js +35 -0
- package/registry/examples/data-table/runs.tsx +28 -0
- package/registry/index.json +6 -5
- package/registry/map.json +1 -1
- package/registry/nav-bar.json +1 -1
- package/registry/site-footer.json +1 -1
- package/registry/sites.json +1 -1
- package/dist/chunk-SKMJRM5K.js.map +0 -1
package/dist/blocks.css
CHANGED
|
@@ -720,6 +720,14 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
720
720
|
.kz-tpl-catalogue-filters > summary::-webkit-details-marker { display: none; }
|
|
721
721
|
.kz-tpl-catalogue-filters > div { padding: 0 14px 14px; }
|
|
722
722
|
}
|
|
723
|
+
@media (max-width: 1279px) {
|
|
724
|
+
.kz-tpl-catalogue[data-rail="wide"] { grid-template-columns: minmax(0, 1fr); gap: 16px; }
|
|
725
|
+
.kz-tpl-catalogue[data-rail="wide"] .kz-tpl-catalogue-filters { position: static; border-radius: 14px; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1); }
|
|
726
|
+
.kz-tpl-catalogue[data-rail="wide"] .kz-tpl-catalogue-filters > summary { display: flex; align-items: center; justify-content: space-between; min-height: 44px; padding: 0 14px; cursor: pointer; list-style: none;
|
|
727
|
+
font-size: 14px; font-weight: 650; color: var(--kz-text-primary); }
|
|
728
|
+
.kz-tpl-catalogue[data-rail="wide"] .kz-tpl-catalogue-filters > summary::-webkit-details-marker { display: none; }
|
|
729
|
+
.kz-tpl-catalogue[data-rail="wide"] .kz-tpl-catalogue-filters > div { padding: 0 14px 14px; }
|
|
730
|
+
}
|
|
723
731
|
|
|
724
732
|
/* A long read: chapters with their big numbers, pull quotes in the margin, figures that break out. */
|
|
725
733
|
.kz-tpl-chapters { display: grid; gap: clamp(40px, 7vw, 88px); }
|
package/dist/catalogue-page.d.ts
CHANGED
|
@@ -27,8 +27,13 @@ type CataloguePageProps = Omit<React.HTMLAttributes<HTMLElement>, "title"> & {
|
|
|
27
27
|
children: React.ReactNode;
|
|
28
28
|
/** The app's link component (Next's `Link`). */
|
|
29
29
|
linkAs?: LinkComponent;
|
|
30
|
+
/**
|
|
31
|
+
* From which window width the filters stay in their column beside the results. `default`: 900 px and above. `wide`:
|
|
32
|
+
* 1280 px and above — a wide table (DataTable) needs the room; under it the filters are a bar above the results.
|
|
33
|
+
*/
|
|
34
|
+
railFrom?: "default" | "wide";
|
|
30
35
|
};
|
|
31
36
|
/** A catalogue: hero, sticky filters beside the results (folded on a phone), the count, the results. */
|
|
32
|
-
declare function CataloguePage({ back, eyebrow, title, lead, search, filters, filtersLabel, count, toolbar, linkAs, children, ...props }: CataloguePageProps): React.JSX.Element;
|
|
37
|
+
declare function CataloguePage({ back, eyebrow, title, lead, search, filters, filtersLabel, count, toolbar, linkAs, railFrom, children, ...props }: CataloguePageProps): React.JSX.Element;
|
|
33
38
|
|
|
34
39
|
export { CataloguePage, type CataloguePageProps };
|
package/dist/catalogue-page.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import { Page } from "@krizaka/ui/page";
|
|
3
3
|
import { PageHero } from "@krizaka/ui/page-hero";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
function CataloguePage({ back, eyebrow, title, lead, search, filters, filtersLabel, count, toolbar, linkAs, children, ...props }) {
|
|
5
|
+
function CataloguePage({ back, eyebrow, title, lead, search, filters, filtersLabel, count, toolbar, linkAs, railFrom = "default", children, ...props }) {
|
|
6
6
|
return /* @__PURE__ */ jsxs("div", { ...props, children: [
|
|
7
7
|
/* @__PURE__ */ jsx(PageHero, { back, linkAs, eyebrow, title, lead, backdrop: "plain", children: search }),
|
|
8
|
-
/* @__PURE__ */ jsx(Page, { className: "kz-tpl-catalogue-frame", children: /* @__PURE__ */ jsxs("div", { className: "kz-tpl-catalogue", children: [
|
|
8
|
+
/* @__PURE__ */ jsx(Page, { className: "kz-tpl-catalogue-frame", children: /* @__PURE__ */ jsxs("div", { className: "kz-tpl-catalogue", "data-rail": railFrom, children: [
|
|
9
9
|
/* @__PURE__ */ jsxs("details", { className: "kz-tpl-catalogue-filters", open: true, children: [
|
|
10
10
|
/* @__PURE__ */ jsx("summary", { children: filtersLabel }),
|
|
11
11
|
/* @__PURE__ */ jsx("div", { children: filters })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/catalogue-page/catalogue-page.tsx"],"sourcesContent":["// Server-safe. A catalogue or an index (blocks.css `.kz-tpl-catalogue`): the hero, then the filters in a sticky column\n// beside the results — folded into a disclosure above them on a phone — the count of what matches and the sort, and\n// the results (a CardGrid of LinkCards, a list). The filters live in the address: a link per choice, no client state.\nimport { Page } from \"@krizaka/ui/page\";\nimport type { LinkComponent } from \"@krizaka/ui/page-hero\";\nimport { PageHero } from \"@krizaka/ui/page-hero\";\nimport type * as React from \"react\";\n\nexport type CataloguePageProps = Omit<React.HTMLAttributes<HTMLElement>, \"title\"> & {\n /** The way back. */\n back?: { href: string; label: string };\n /** A mono line above the title. */\n eyebrow?: React.ReactNode;\n /** The page's `h1`. */\n title: React.ReactNode;\n /** One sentence under it. */\n lead?: React.ReactNode;\n /** In the hero: a search field. */\n search?: React.ReactNode;\n /** The filters (groups of ChipLinks, a FilterBar): sticky on a desktop. */\n filters: React.ReactNode;\n /** On a phone, the words that open the filters (`Filters`). */\n filtersLabel: string;\n /** What matches, in words (`24 components`). */\n count?: React.ReactNode;\n /** On the right of the count: the sort, a view switch. */\n toolbar?: React.ReactNode;\n /** The results: a CardGrid, a list, an empty state. */\n children: React.ReactNode;\n /** The app's link component (Next's `Link`). */\n linkAs?: LinkComponent;\n};\n\n/** A catalogue: hero, sticky filters beside the results (folded on a phone), the count, the results. */\nexport function CataloguePage({ back, eyebrow, title, lead, search, filters, filtersLabel, count, toolbar, linkAs, children, ...props }: CataloguePageProps) {\n return (\n <div {...props}>\n <PageHero back={back} linkAs={linkAs} eyebrow={eyebrow} title={title} lead={lead} backdrop=\"plain\">\n {search}\n </PageHero>\n <Page className=\"kz-tpl-catalogue-frame\">\n <div className=\"kz-tpl-catalogue\">\n <details className=\"kz-tpl-catalogue-filters\" open>\n <summary>{filtersLabel}</summary>\n <div>{filters}</div>\n </details>\n <div className=\"min-w-0\">\n {(count || toolbar) && (\n <div className=\"kz-tpl-catalogue-head\">\n {count && (\n <p className=\"kz-tpl-count\" aria-live=\"polite\">\n {count}\n </p>\n )}\n {toolbar}\n </div>\n )}\n {children}\n </div>\n </div>\n </Page>\n </div>\n );\n}\n"],"mappings":";AAGA,SAAS,YAAY;AAErB,SAAS,gBAAgB;
|
|
1
|
+
{"version":3,"sources":["../src/catalogue-page/catalogue-page.tsx"],"sourcesContent":["// Server-safe. A catalogue or an index (blocks.css `.kz-tpl-catalogue`): the hero, then the filters in a sticky column\n// beside the results — folded into a disclosure above them on a phone — the count of what matches and the sort, and\n// the results (a CardGrid of LinkCards, a list). The filters live in the address: a link per choice, no client state.\nimport { Page } from \"@krizaka/ui/page\";\nimport type { LinkComponent } from \"@krizaka/ui/page-hero\";\nimport { PageHero } from \"@krizaka/ui/page-hero\";\nimport type * as React from \"react\";\n\nexport type CataloguePageProps = Omit<React.HTMLAttributes<HTMLElement>, \"title\"> & {\n /** The way back. */\n back?: { href: string; label: string };\n /** A mono line above the title. */\n eyebrow?: React.ReactNode;\n /** The page's `h1`. */\n title: React.ReactNode;\n /** One sentence under it. */\n lead?: React.ReactNode;\n /** In the hero: a search field. */\n search?: React.ReactNode;\n /** The filters (groups of ChipLinks, a FilterBar): sticky on a desktop. */\n filters: React.ReactNode;\n /** On a phone, the words that open the filters (`Filters`). */\n filtersLabel: string;\n /** What matches, in words (`24 components`). */\n count?: React.ReactNode;\n /** On the right of the count: the sort, a view switch. */\n toolbar?: React.ReactNode;\n /** The results: a CardGrid, a list, an empty state. */\n children: React.ReactNode;\n /** The app's link component (Next's `Link`). */\n linkAs?: LinkComponent;\n /**\n * From which window width the filters stay in their column beside the results. `default`: 900 px and above. `wide`:\n * 1280 px and above — a wide table (DataTable) needs the room; under it the filters are a bar above the results.\n */\n railFrom?: \"default\" | \"wide\";\n};\n\n/** A catalogue: hero, sticky filters beside the results (folded on a phone), the count, the results. */\nexport function CataloguePage({ back, eyebrow, title, lead, search, filters, filtersLabel, count, toolbar, linkAs, railFrom = \"default\", children, ...props }: CataloguePageProps) {\n return (\n <div {...props}>\n <PageHero back={back} linkAs={linkAs} eyebrow={eyebrow} title={title} lead={lead} backdrop=\"plain\">\n {search}\n </PageHero>\n <Page className=\"kz-tpl-catalogue-frame\">\n <div className=\"kz-tpl-catalogue\" data-rail={railFrom}>\n <details className=\"kz-tpl-catalogue-filters\" open>\n <summary>{filtersLabel}</summary>\n <div>{filters}</div>\n </details>\n <div className=\"min-w-0\">\n {(count || toolbar) && (\n <div className=\"kz-tpl-catalogue-head\">\n {count && (\n <p className=\"kz-tpl-count\" aria-live=\"polite\">\n {count}\n </p>\n )}\n {toolbar}\n </div>\n )}\n {children}\n </div>\n </div>\n </Page>\n </div>\n );\n}\n"],"mappings":";AAGA,SAAS,YAAY;AAErB,SAAS,gBAAgB;AAqCnB,cAKI,YALJ;AAHC,SAAS,cAAc,EAAE,MAAM,SAAS,OAAO,MAAM,QAAQ,SAAS,cAAc,OAAO,SAAS,QAAQ,WAAW,WAAW,UAAU,GAAG,MAAM,GAAuB;AACjL,SACE,qBAAC,SAAK,GAAG,OACP;AAAA,wBAAC,YAAS,MAAY,QAAgB,SAAkB,OAAc,MAAY,UAAS,SACxF,kBACH;AAAA,IACA,oBAAC,QAAK,WAAU,0BACd,+BAAC,SAAI,WAAU,oBAAmB,aAAW,UAC3C;AAAA,2BAAC,aAAQ,WAAU,4BAA2B,MAAI,MAChD;AAAA,4BAAC,aAAS,wBAAa;AAAA,QACvB,oBAAC,SAAK,mBAAQ;AAAA,SAChB;AAAA,MACA,qBAAC,SAAI,WAAU,WACX;AAAA,kBAAS,YACT,qBAAC,SAAI,WAAU,yBACZ;AAAA,mBACC,oBAAC,OAAE,WAAU,gBAAe,aAAU,UACnC,iBACH;AAAA,UAED;AAAA,WACH;AAAA,QAED;AAAA,SACH;AAAA,OACF,GACF;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -21,7 +21,7 @@ var sites = [
|
|
|
21
21
|
site({ id: "orochia", name: "Orochia", url: "https://dev.orochia.com", kind: "product", group: "products", status: "released", mark: "orochia", repo: "https://github.com/krizaka/orochia" }),
|
|
22
22
|
site({ id: "yasakia", name: "Yasakia", url: "https://dev.yasakia.com", kind: "product", group: "products", status: "upcoming", mark: "yasakia", repo: "https://github.com/krizaka/yasakia" }),
|
|
23
23
|
site({ id: "yororis", name: "Yororis", url: "https://dev.yororis.com", kind: "product", group: "products", status: "construction", mark: "yororis", repo: "https://github.com/krizaka/yororis" }),
|
|
24
|
-
site({ id: "yomizaka", name: "Yomizaka", url: "https://dev.yomizaka.com", kind: "product", group: "products", status: "
|
|
24
|
+
site({ id: "yomizaka", name: "Yomizaka", url: "https://dev.yomizaka.com", kind: "product", group: "products", status: "development", mark: "yomizaka", repo: "https://github.com/krizaka/yomizaka" }),
|
|
25
25
|
// In development: nothing deployed yet, so the address is the repository (never a dead link to an unborn dev site).
|
|
26
26
|
site({ id: "kachizaka", name: "Kachizaka", url: "https://github.com/krizaka/kachizaka", kind: "product", group: "products", status: "development", mark: "kachizaka", repo: "https://github.com/krizaka/kachizaka" }),
|
|
27
27
|
site({ id: "akinaza", name: "Akinaza", url: "https://github.com/krizaka/akinaza", kind: "product", group: "products", status: "development", mark: "akinaza", repo: "https://github.com/krizaka/akinaza" }),
|
|
@@ -92,4 +92,4 @@ export {
|
|
|
92
92
|
sitesByGroup,
|
|
93
93
|
familyLabels
|
|
94
94
|
};
|
|
95
|
-
//# sourceMappingURL=chunk-
|
|
95
|
+
//# sourceMappingURL=chunk-53LQPYQZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/family-mark.tsx","../src/sites/sites.ts"],"sourcesContent":["// The mark of a site of the family (`@krizaka/ui/sites`): its brand's `ProductLogo`, still (a list of marks never\n// moves), or GitHub's, in the text colour. Shared by `NavBar.Family` and `SiteFooter` — not an entry of its own.\nimport type * as React from \"react\";\n\nimport { ProductLogo } from \"./marks/ProductLogo\";\nimport type { SiteMark } from \"./sites/sites\";\n\n/** GitHub's mark, in the text colour (both themes). */\nexport function GitHubGlyph({ size = 16, className }: { size?: number; className?: string }) {\n return (\n <svg viewBox=\"0 0 16 16\" width={size} height={size} fill=\"currentColor\" aria-hidden className={className}>\n <path d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8Z\" />\n </svg>\n );\n}\n\n/** A site's mark, decorative (its name is always written beside it). */\nexport function FamilyMark({ mark, size }: { mark: SiteMark; size: number }): React.ReactElement {\n if (mark === \"github\") return <GitHubGlyph size={Math.round(size * 0.8)} />;\n return <ProductLogo id={mark} size={size} animated={false} />;\n}\n","// Server-safe: plain data. The Krizaka family — every site Krizaka runs, once. The family switcher of the bar\n// (`NavBar.Family`) and the common footer (`SiteFooter`) both read it, so adding a site is one release of this package:\n// every bar and every footer of the family follow.\n//\n// The words of the family (a site's one line, the groups, the statuses, the footer's signature) are brand data, written\n// here in English and French (`familyLabels`) — a site passes the set of its locale, or its own translation.\n\n/** A site of the family. */\nexport type SiteId = \"krizaka\" | \"orazaka\" | \"orochia\" | \"yasakia\" | \"yororis\" | \"yomizaka\" | \"kachizaka\" | \"akinaza\" | \"ui\" | \"java\" | \"github\";\n\n/** What a site is: the company, a product, or an open-source project. It chooses the footer's signature line. */\nexport type SiteKind = \"company\" | \"product\" | \"open-source\";\n\n/**\n * `released`: open to visit. `upcoming`: announced, not released yet (said \"Coming soon\"). `construction`: under\n * construction — nothing deployed beyond its page, nothing offered. `development`: being built in the open, nothing\n * deployed yet — its address is its repository (said \"In development\").\n */\nexport type SiteStatus = \"released\" | \"upcoming\" | \"construction\" | \"development\";\n\n/** The groups of the family, in reading order: Krizaka · Products · Open source · GitHub. */\nexport type SiteGroup = \"krizaka\" | \"products\" | \"open-source\" | \"github\";\n\n/** The mark a site wears: a brand of `ProductLogo` (Krizaka UI and Krizaka Java wear Krizaka's), or GitHub's. */\nexport type SiteMark = \"krizaka\" | \"orazaka\" | \"orochia\" | \"yasakia\" | \"yororis\" | \"yomizaka\" | \"kachizaka\" | \"akinaza\" | \"github\";\n\nexport interface Site {\n readonly id: SiteId;\n /** The name, never translated. */\n readonly name: string;\n /** The address of the site (its home). */\n readonly url: string;\n /** The address without the scheme, as people say it (`ui.krizaka.com`). */\n readonly host: string;\n readonly kind: SiteKind;\n readonly group: SiteGroup;\n readonly status: SiteStatus;\n readonly mark: SiteMark;\n /** The repository the site is built from. */\n readonly repo: string;\n}\n\nconst site = (s: Omit<Site, \"host\">): Site => ({ ...s, host: s.url.replace(/^https?:\\/\\//, \"\").replace(/\\/$/, \"\") });\n\n/** Every site of the family, in reading order (the group order, then the order inside each group). */\nexport const sites: readonly Site[] = [\n site({ id: \"krizaka\", name: \"Krizaka\", url: \"https://www.krizaka.com\", kind: \"company\", group: \"krizaka\", status: \"released\", mark: \"krizaka\", repo: \"https://github.com/krizaka/krizaka-com\" }),\n site({ id: \"orazaka\", name: \"Orazaka\", url: \"https://dev.orazaka.com\", kind: \"product\", group: \"products\", status: \"released\", mark: \"orazaka\", repo: \"https://github.com/krizaka/orazaka\" }),\n site({ id: \"orochia\", name: \"Orochia\", url: \"https://dev.orochia.com\", kind: \"product\", group: \"products\", status: \"released\", mark: \"orochia\", repo: \"https://github.com/krizaka/orochia\" }),\n site({ id: \"yasakia\", name: \"Yasakia\", url: \"https://dev.yasakia.com\", kind: \"product\", group: \"products\", status: \"upcoming\", mark: \"yasakia\", repo: \"https://github.com/krizaka/yasakia\" }),\n site({ id: \"yororis\", name: \"Yororis\", url: \"https://dev.yororis.com\", kind: \"product\", group: \"products\", status: \"construction\", mark: \"yororis\", repo: \"https://github.com/krizaka/yororis\" }),\n site({ id: \"yomizaka\", name: \"Yomizaka\", url: \"https://dev.yomizaka.com\", kind: \"product\", group: \"products\", status: \"development\", mark: \"yomizaka\", repo: \"https://github.com/krizaka/yomizaka\" }),\n // In development: nothing deployed yet, so the address is the repository (never a dead link to an unborn dev site).\n site({ id: \"kachizaka\", name: \"Kachizaka\", url: \"https://github.com/krizaka/kachizaka\", kind: \"product\", group: \"products\", status: \"development\", mark: \"kachizaka\", repo: \"https://github.com/krizaka/kachizaka\" }),\n site({ id: \"akinaza\", name: \"Akinaza\", url: \"https://github.com/krizaka/akinaza\", kind: \"product\", group: \"products\", status: \"development\", mark: \"akinaza\", repo: \"https://github.com/krizaka/akinaza\" }),\n site({ id: \"ui\", name: \"Krizaka UI\", url: \"https://ui.krizaka.com\", kind: \"open-source\", group: \"open-source\", status: \"released\", mark: \"krizaka\", repo: \"https://github.com/krizaka/krizaka-ui\" }),\n site({ id: \"java\", name: \"Krizaka Java\", url: \"https://java.krizaka.com\", kind: \"open-source\", group: \"open-source\", status: \"released\", mark: \"krizaka\", repo: \"https://github.com/krizaka/krizaka-build\" }),\n site({ id: \"github\", name: \"GitHub\", url: \"https://github.com/krizaka\", kind: \"open-source\", group: \"github\", status: \"released\", mark: \"github\", repo: \"https://github.com/krizaka\" }),\n];\n\n/** The groups, in reading order. */\nexport const siteGroups: readonly SiteGroup[] = [\"krizaka\", \"products\", \"open-source\", \"github\"];\n\n/** A site by id. */\nexport function siteById(id: SiteId): Site {\n const found = sites.find((s) => s.id === id);\n if (!found) throw new Error(`Unknown Krizaka site \"${id}\".`);\n return found;\n}\n\n/** The family grouped, in reading order: `[{ group, sites }]`, empty groups left out. */\nexport function sitesByGroup(): { group: SiteGroup; sites: Site[] }[] {\n return siteGroups.map((group) => ({ group, sites: sites.filter((s) => s.group === group) })).filter((g) => g.sites.length > 0);\n}\n\n/** The languages the family's words are written in. */\nexport type SiteLocale = \"en\" | \"fr\";\n\n/** The words of the family: the switcher, the footer, each site's one line. */\nexport interface FamilyLabels {\n /** The family's name: the switcher's navigation and its button, the footer's navigation (“Krizaka family”). */\n family: string;\n /** The heading of each group. */\n groups: Record<SiteGroup, string>;\n /** The badge of a site that is not released. */\n status: Record<Exclude<SiteStatus, \"released\">, string>;\n /** Says which site is the current one (“You are here”). */\n current: string;\n /** One line per site: what it is. */\n descriptions: Record<SiteId, string>;\n /** The footer's signature, by the kind of the current site (“A Krizaka product”). */\n signature: Record<SiteKind, string>;\n /** The footer's place line (“Made in Montréal”). */\n place: string;\n /** The accessible name of the version (“Version”). */\n version: string;\n}\n\n/** The family's words in English and French. Pass `familyLabels[locale]`, or your own translation of the same shape. */\nexport const familyLabels: Record<SiteLocale, FamilyLabels> = {\n en: {\n family: \"Krizaka family\",\n groups: { krizaka: \"Krizaka\", products: \"Products\", \"open-source\": \"Open source\", github: \"GitHub\" },\n status: { upcoming: \"Coming soon\", construction: \"Under construction\", development: \"In development\" },\n current: \"You are here\",\n descriptions: {\n krizaka: \"The company: our products, our open source, our story.\",\n orazaka: \"Sovereign AI, on your own servers.\",\n orochia: \"A video platform for creators.\",\n yasakia: \"The dating app where you talk first.\",\n yororis: \"A listening space with a face and a voice.\",\n yomizaka: \"Your documents, read and checked by Orazaka.\",\n kachizaka: \"Predictions among friends — live data, in real time.\",\n akinaza: \"Running a shop in Québec, for less — Loi 25 by design.\",\n ui: \"Components, tokens, icons and charts — web and React Native.\",\n java: \"Spring Boot building blocks on Maven Central.\",\n github: \"Every repository, in the open.\",\n },\n signature: { company: \"A Krizaka company\", product: \"A Krizaka product\", \"open-source\": \"A Krizaka open-source project\" },\n place: \"Made in Montréal\",\n version: \"Version\",\n },\n fr: {\n family: \"Famille Krizaka\",\n groups: { krizaka: \"Krizaka\", products: \"Produits\", \"open-source\": \"Open source\", github: \"GitHub\" },\n status: { upcoming: \"Bientôt\", construction: \"En construction\", development: \"En développement\" },\n current: \"Vous êtes ici\",\n descriptions: {\n krizaka: \"La compagnie : nos produits, notre open source, notre histoire.\",\n orazaka: \"L’IA souveraine, sur vos propres serveurs.\",\n orochia: \"Une plateforme vidéo pour les créateurs.\",\n yasakia: \"L’app de rencontre où l’on se parle d’abord.\",\n yororis: \"Un espace d’écoute avec un visage et une voix.\",\n yomizaka: \"Vos documents, lus et vérifiés par Orazaka.\",\n kachizaka: \"Les pronostics entre amis — des données en direct.\",\n akinaza: \"Tenir une boutique au Québec, pour moins cher — Loi 25 dès la conception.\",\n ui: \"Composants, jetons, icônes et graphiques — web et React Native.\",\n java: \"Des briques Spring Boot sur Maven Central.\",\n github: \"Tous les dépôts, au grand jour.\",\n },\n signature: { company: \"Une compagnie Krizaka\", product: \"Un produit Krizaka\", \"open-source\": \"Un projet open source de Krizaka\" },\n place: \"Fait à Montréal\",\n version: \"Version\",\n },\n};\n"],"mappings":"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","names":[]}
|
package/dist/data-table.d.ts
CHANGED
|
@@ -97,6 +97,18 @@ declare const dataTable: tailwind_variants.TVReturnType<{
|
|
|
97
97
|
td: string;
|
|
98
98
|
};
|
|
99
99
|
};
|
|
100
|
+
sticky: {
|
|
101
|
+
true: {};
|
|
102
|
+
false: {};
|
|
103
|
+
};
|
|
104
|
+
striped: {
|
|
105
|
+
true: {};
|
|
106
|
+
false: {};
|
|
107
|
+
};
|
|
108
|
+
typed: {
|
|
109
|
+
true: {};
|
|
110
|
+
false: {};
|
|
111
|
+
};
|
|
100
112
|
}, {
|
|
101
113
|
root: string;
|
|
102
114
|
toolbar: string;
|
|
@@ -157,6 +169,18 @@ declare const dataTable: tailwind_variants.TVReturnType<{
|
|
|
157
169
|
td: string;
|
|
158
170
|
};
|
|
159
171
|
};
|
|
172
|
+
sticky: {
|
|
173
|
+
true: {};
|
|
174
|
+
false: {};
|
|
175
|
+
};
|
|
176
|
+
striped: {
|
|
177
|
+
true: {};
|
|
178
|
+
false: {};
|
|
179
|
+
};
|
|
180
|
+
typed: {
|
|
181
|
+
true: {};
|
|
182
|
+
false: {};
|
|
183
|
+
};
|
|
160
184
|
}, {
|
|
161
185
|
root: string;
|
|
162
186
|
toolbar: string;
|
|
@@ -217,6 +241,18 @@ declare const dataTable: tailwind_variants.TVReturnType<{
|
|
|
217
241
|
td: string;
|
|
218
242
|
};
|
|
219
243
|
};
|
|
244
|
+
sticky: {
|
|
245
|
+
true: {};
|
|
246
|
+
false: {};
|
|
247
|
+
};
|
|
248
|
+
striped: {
|
|
249
|
+
true: {};
|
|
250
|
+
false: {};
|
|
251
|
+
};
|
|
252
|
+
typed: {
|
|
253
|
+
true: {};
|
|
254
|
+
false: {};
|
|
255
|
+
};
|
|
220
256
|
}, {
|
|
221
257
|
root: string;
|
|
222
258
|
toolbar: string;
|
|
@@ -240,6 +276,7 @@ declare const dataTable: tailwind_variants.TVReturnType<{
|
|
|
240
276
|
skeleton: string;
|
|
241
277
|
footer: string;
|
|
242
278
|
}>>;
|
|
279
|
+
type DataTableColumnType = "title" | "badge" | "number" | "link" | "date" | "status" | "text";
|
|
243
280
|
type SortDirection = "ascending" | "descending";
|
|
244
281
|
type DataTableSort = {
|
|
245
282
|
column: string;
|
|
@@ -283,7 +320,7 @@ type DataTableColumn<T> = {
|
|
|
283
320
|
align?: "start" | "center" | "end";
|
|
284
321
|
/** The width, in px (the starting width when `resizing`). */
|
|
285
322
|
width?: number;
|
|
286
|
-
/** The narrowest
|
|
323
|
+
/** The narrowest the column may be, in px (also what a resized one may shrink to). Default 64. */
|
|
287
324
|
minWidth?: number;
|
|
288
325
|
/** In a card: `title` (the heading of the card), `label` (default: "Header value"), `hidden`. */
|
|
289
326
|
card?: "title" | "label" | "hidden";
|
|
@@ -291,6 +328,29 @@ type DataTableColumn<T> = {
|
|
|
291
328
|
headerHidden?: boolean;
|
|
292
329
|
/** Listed in `DataTableColumnsMenu`, so a person can hide it. Default `true`. */
|
|
293
330
|
hideable?: boolean;
|
|
331
|
+
/**
|
|
332
|
+
* What the column holds, which sizes and aligns it: `title` (the name, takes the slack, truncated, `subtitle` under it in
|
|
333
|
+
* mono — and the card's heading), `badge` · `status` (as wide as the badge, never stretched), `number` (end-aligned,
|
|
334
|
+
* tabular), `date`, `link` (truncated, `href`), `text` (wraps, two lines). Untyped: as before.
|
|
335
|
+
*/
|
|
336
|
+
type?: DataTableColumnType;
|
|
337
|
+
/**
|
|
338
|
+
* 1 (default) always in the row; 2 to 7 leave it when the table is narrower than 42 · 48 · 56 · 64 · 72 · 80 rem and
|
|
339
|
+
* go to the row's detail (a chevron opens it); under 36 rem (cards) 2 stays on the card, 3+ go to its detail.
|
|
340
|
+
*/
|
|
341
|
+
priority?: 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
|
342
|
+
/** `title`: the line under the name (an id), in mono. */
|
|
343
|
+
subtitle?: (row: T) => React.ReactNode;
|
|
344
|
+
/** `link`: where the value leads. */
|
|
345
|
+
href?: (row: T) => string | undefined;
|
|
346
|
+
/** `number`: the unit after the value (muted). */
|
|
347
|
+
unit?: string;
|
|
348
|
+
/** The widest the column may be in the table layouts, in px; longer text is clamped, the full value on hover. */
|
|
349
|
+
maxWidth?: number;
|
|
350
|
+
/** One line only, truncated (the full value on hover). */
|
|
351
|
+
nowrap?: boolean;
|
|
352
|
+
/** Lines of text kept before the ellipsis (default 2 for `text`). */
|
|
353
|
+
clamp?: 1 | 2 | 3;
|
|
294
354
|
};
|
|
295
355
|
type DataTableLabels = {
|
|
296
356
|
/** The checkbox of the header ("Select all rows"). */
|
|
@@ -327,6 +387,8 @@ type DataTableLabels = {
|
|
|
327
387
|
rangeTo: (header: string) => string;
|
|
328
388
|
/** The button of the columns menu ("Columns"). */
|
|
329
389
|
columns: string;
|
|
390
|
+
/** The button that opens what left the row: `(name) => "Show more about " + name`. */
|
|
391
|
+
showMore: (name: string) => string;
|
|
330
392
|
/** The export button ("Export CSV"). */
|
|
331
393
|
export: string;
|
|
332
394
|
/** The words of the pagination under the table. */
|
|
@@ -429,8 +491,19 @@ type DataTableProps<T> = {
|
|
|
429
491
|
empty?: React.ReactNode;
|
|
430
492
|
/** `auto` (default): a table, cards below 36rem of container width. `table` or `cards` to force one. */
|
|
431
493
|
layout?: "auto" | "table" | "cards";
|
|
432
|
-
/** comfortable (default) · compact. */
|
|
494
|
+
/** comfortable (default) · compact — one row height per density. */
|
|
433
495
|
density?: "comfortable" | "compact";
|
|
496
|
+
/** The header stays at the top of the window while the page scrolls (`--dt-top` on the table, or a number of px, clears a fixed bar). */
|
|
497
|
+
stickyHeader?: boolean | number;
|
|
498
|
+
/** Zebra rows. */
|
|
499
|
+
striped?: boolean;
|
|
500
|
+
/**
|
|
501
|
+
* The table never scrolls sideways by default once its columns have a `type` or a `priority`: what does not fit goes to
|
|
502
|
+
* the row's detail, then to cards. `true` opts in to a sideways scroll instead, with fades at the edges.
|
|
503
|
+
*/
|
|
504
|
+
scroll?: boolean;
|
|
505
|
+
/** Keeps the first column in view while the table scrolls sideways (with `scroll`). */
|
|
506
|
+
stickyFirstColumn?: boolean;
|
|
434
507
|
/** Renders only the rows in view, in a scrolling body of `height` px; rows are measured (`estimateRowHeight` is a guess). Forces the table layout. */
|
|
435
508
|
virtualized?: {
|
|
436
509
|
height: number;
|
|
@@ -468,7 +541,7 @@ declare function useDataTable<T extends RowData = object>(): Omit<Context, "tabl
|
|
|
468
541
|
exportRows: () => readonly T[];
|
|
469
542
|
};
|
|
470
543
|
/** A table of records — sort, filters and facets, groups, details, pages, selection, visibility, pinning, resizing — on the client or the server, cards on a phone, windowing for long lists. */
|
|
471
|
-
declare function DataTable<T extends RowData>({ rows, columns, getRowId, caption, showCaption, sort: sortProp, defaultSort, onSortChange, filters: filtersProp, defaultFilters, onFiltersChange, selectable, selected: selectedProp, defaultSelected, onSelectedChange, rowLabel, groupBy: groupByProp, defaultGroupBy, onGroupByChange, columnVisibility: visibilityProp, defaultColumnVisibility, onColumnVisibilityChange, pinning, resizing, getSubRows, renderDetail, expanded: expandedProp, defaultExpanded, onExpandedChange, pageSize: pageSizeProp, defaultPageSize, onPageSizeChange, pageSizeOptions, page: pageProp, defaultPage, onPageChange, manual, rowCount, onStateChange, loading, loadingRows, error, empty, layout, density, virtualized, toolbar, footer, labels: given, className, }: DataTableProps<T>): React.JSX.Element;
|
|
544
|
+
declare function DataTable<T extends RowData>({ rows, columns, getRowId, caption, showCaption, sort: sortProp, defaultSort, onSortChange, filters: filtersProp, defaultFilters, onFiltersChange, selectable, selected: selectedProp, defaultSelected, onSelectedChange, rowLabel, groupBy: groupByProp, defaultGroupBy, onGroupByChange, columnVisibility: visibilityProp, defaultColumnVisibility, onColumnVisibilityChange, pinning, resizing, getSubRows, renderDetail, expanded: expandedProp, defaultExpanded, onExpandedChange, pageSize: pageSizeProp, defaultPageSize, onPageSizeChange, pageSizeOptions, page: pageProp, defaultPage, onPageChange, manual, rowCount, onStateChange, loading, loadingRows, error, empty, layout, density, stickyHeader, striped, scroll, stickyFirstColumn, virtualized, toolbar, footer, labels: given, className, }: DataTableProps<T>): React.JSX.Element;
|
|
472
545
|
|
|
473
546
|
type DataTableFiltersProps = {
|
|
474
547
|
/** The search's wait after the last key, in ms, before the filter applies (a request, in server mode). Default 250. */
|
package/dist/data-table.js
CHANGED
|
@@ -22,7 +22,9 @@ import {
|
|
|
22
22
|
SearchField
|
|
23
23
|
} from "./chunk-REPTKUJ6.js";
|
|
24
24
|
import "./chunk-ZIXB33X7.js";
|
|
25
|
-
import
|
|
25
|
+
import {
|
|
26
|
+
cn
|
|
27
|
+
} from "./chunk-2FRWNSRO.js";
|
|
26
28
|
import {
|
|
27
29
|
useControllable
|
|
28
30
|
} from "./chunk-FZBWEDQI.js";
|
|
@@ -257,7 +259,7 @@ var FILTERS = { text: filterText, facet: filterFacet, range: filterRange };
|
|
|
257
259
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
258
260
|
var dataTable = tv2({
|
|
259
261
|
slots: {
|
|
260
|
-
root: "@container w-full overflow-
|
|
262
|
+
root: "@container w-full overflow-clip rounded-xl border border-border-default bg-surface-1",
|
|
261
263
|
toolbar: "border-b border-border-default p-3",
|
|
262
264
|
scroller: "w-full overflow-x-auto",
|
|
263
265
|
table: "w-full border-collapse text-left text-sm text-fg",
|
|
@@ -314,10 +316,63 @@ var dataTable = tv2({
|
|
|
314
316
|
density: {
|
|
315
317
|
comfortable: {},
|
|
316
318
|
compact: { th: "py-2", td: "py-1.5" }
|
|
317
|
-
}
|
|
319
|
+
},
|
|
320
|
+
// The header stays in view while the page scrolls (table layouts only; `--dt-top` clears a fixed bar).
|
|
321
|
+
sticky: { true: {}, false: {} },
|
|
322
|
+
// Zebra rows (the table layouts); the cards keep their frame.
|
|
323
|
+
striped: { true: {}, false: {} },
|
|
324
|
+
// Typed columns: one height per row (`typed`); untyped tables keep the height of their content.
|
|
325
|
+
typed: { true: {}, false: {} }
|
|
318
326
|
},
|
|
319
|
-
|
|
327
|
+
compoundVariants: [
|
|
328
|
+
{ layout: "table", sticky: true, class: { th: "sticky top-(--dt-top,0px) z-[3] bg-surface-2" } },
|
|
329
|
+
{ layout: "auto", sticky: true, class: { th: "@xl:sticky @xl:top-(--dt-top,0px) @xl:z-[3] @xl:bg-surface-2" } },
|
|
330
|
+
{ layout: "table", striped: true, class: { tr: "even:bg-surface-2/40" } },
|
|
331
|
+
{ layout: "auto", striped: true, class: { tr: "@xl:even:bg-surface-2/40" } },
|
|
332
|
+
// One row height per density (a two-line row — a name and its id — is the tallest).
|
|
333
|
+
{ layout: "table", density: "comfortable", typed: true, class: { td: "h-15" } },
|
|
334
|
+
{ layout: "auto", density: "comfortable", typed: true, class: { td: "@xl:h-15" } },
|
|
335
|
+
{ layout: "table", density: "compact", typed: true, class: { td: "h-12" } },
|
|
336
|
+
{ layout: "auto", density: "compact", typed: true, class: { td: "@xl:h-12" } }
|
|
337
|
+
],
|
|
338
|
+
defaultVariants: { layout: "auto", density: "comfortable", sticky: false, striped: false, typed: false }
|
|
320
339
|
});
|
|
340
|
+
var NO_CLASS = { 2: "", 3: "", 4: "", 5: "", 6: "", 7: "" };
|
|
341
|
+
var LEAVES = {
|
|
342
|
+
auto: { 2: "@xl:@max-2xl:hidden!", 3: "@max-3xl:hidden!", 4: "@max-4xl:hidden!", 5: "@max-5xl:hidden!", 6: "@max-6xl:hidden!", 7: "@max-7xl:hidden!" },
|
|
343
|
+
table: { 2: "@max-2xl:hidden!", 3: "@max-3xl:hidden!", 4: "@max-4xl:hidden!", 5: "@max-5xl:hidden!", 6: "@max-6xl:hidden!", 7: "@max-7xl:hidden!" },
|
|
344
|
+
cards: { 2: "", 3: "hidden!", 4: "hidden!", 5: "hidden!", 6: "hidden!", 7: "hidden!" }
|
|
345
|
+
};
|
|
346
|
+
var LEAVES_HEAD = {
|
|
347
|
+
auto: { 2: "@xl:@max-2xl:hidden!", 3: "@xl:@max-3xl:hidden!", 4: "@xl:@max-4xl:hidden!", 5: "@xl:@max-5xl:hidden!", 6: "@xl:@max-6xl:hidden!", 7: "@xl:@max-7xl:hidden!" },
|
|
348
|
+
table: LEAVES.table,
|
|
349
|
+
cards: NO_CLASS
|
|
350
|
+
};
|
|
351
|
+
var IN_DETAIL = {
|
|
352
|
+
auto: { 2: "hidden @xl:@max-2xl:grid", 3: "hidden @max-3xl:grid", 4: "hidden @max-4xl:grid", 5: "hidden @max-5xl:grid", 6: "hidden @max-6xl:grid", 7: "hidden @max-7xl:grid" },
|
|
353
|
+
table: { 2: "hidden @max-2xl:grid", 3: "hidden @max-3xl:grid", 4: "hidden @max-4xl:grid", 5: "hidden @max-5xl:grid", 6: "hidden @max-6xl:grid", 7: "hidden @max-7xl:grid" },
|
|
354
|
+
cards: { 2: "hidden", 3: "grid", 4: "grid", 5: "grid", 6: "grid", 7: "grid" }
|
|
355
|
+
};
|
|
356
|
+
var TOGGLE = {
|
|
357
|
+
auto: { 2: "hidden @xl:@max-2xl:inline-flex", 3: "hidden @max-3xl:inline-flex", 4: "hidden @max-4xl:inline-flex", 5: "hidden @max-5xl:inline-flex", 6: "hidden @max-6xl:inline-flex", 7: "hidden @max-7xl:inline-flex" },
|
|
358
|
+
table: { 2: "hidden @max-2xl:inline-flex", 3: "hidden @max-3xl:inline-flex", 4: "hidden @max-4xl:inline-flex", 5: "hidden @max-5xl:inline-flex", 6: "hidden @max-6xl:inline-flex", 7: "hidden @max-7xl:inline-flex" },
|
|
359
|
+
cards: { 2: "hidden", 3: "inline-flex", 4: "inline-flex", 5: "inline-flex", 6: "inline-flex", 7: "inline-flex" }
|
|
360
|
+
};
|
|
361
|
+
var PANEL = {
|
|
362
|
+
auto: { 2: "hidden @xl:@max-2xl:block", 3: "hidden @max-3xl:block", 4: "hidden @max-4xl:block", 5: "hidden @max-5xl:block", 6: "hidden @max-6xl:block", 7: "hidden @max-7xl:block" },
|
|
363
|
+
table: { 2: "hidden @max-2xl:block", 3: "hidden @max-3xl:block", 4: "hidden @max-4xl:block", 5: "hidden @max-5xl:block", 6: "hidden @max-6xl:block", 7: "hidden @max-7xl:block" },
|
|
364
|
+
cards: { 2: "hidden", 3: "block", 4: "block", 5: "block", 6: "block", 7: "block" }
|
|
365
|
+
};
|
|
366
|
+
var TYPE_CELL = {
|
|
367
|
+
title: { auto: "@xl:w-full @xl:max-w-0 @xl:min-w-44", table: "w-full max-w-0 min-w-44", cards: "" },
|
|
368
|
+
badge: { auto: "@xl:w-px", table: "w-px", cards: "" },
|
|
369
|
+
status: { auto: "@xl:w-px @xl:whitespace-nowrap", table: "w-px whitespace-nowrap", cards: "" },
|
|
370
|
+
number: { auto: "@xl:w-px @xl:whitespace-nowrap tabular-nums", table: "w-px whitespace-nowrap tabular-nums", cards: "tabular-nums" },
|
|
371
|
+
date: { auto: "@xl:w-px @xl:whitespace-nowrap tabular-nums", table: "w-px whitespace-nowrap tabular-nums", cards: "tabular-nums" },
|
|
372
|
+
link: { auto: "@xl:min-w-28 @xl:max-w-56", table: "min-w-28 max-w-56", cards: "" },
|
|
373
|
+
text: { auto: "@xl:min-w-36", table: "min-w-36", cards: "" }
|
|
374
|
+
};
|
|
375
|
+
var CLAMP = { 1: "line-clamp-1", 2: "line-clamp-2", 3: "line-clamp-3" };
|
|
321
376
|
var dataTableLabels = {
|
|
322
377
|
selectAll: "Select all rows",
|
|
323
378
|
selectRow: (name) => `Select ${name}`,
|
|
@@ -336,6 +391,7 @@ var dataTableLabels = {
|
|
|
336
391
|
rangeFrom: (header) => `${header} from`,
|
|
337
392
|
rangeTo: (header) => `${header} to`,
|
|
338
393
|
columns: "Columns",
|
|
394
|
+
showMore: (name) => `Show more about ${name}`,
|
|
339
395
|
export: "Export CSV"
|
|
340
396
|
};
|
|
341
397
|
var DataTableContext = React.createContext(null);
|
|
@@ -344,6 +400,10 @@ function useDataTable() {
|
|
|
344
400
|
if (!context) throw new Error("useDataTable: call it inside a DataTable (its `toolbar`, `footer` or a cell)");
|
|
345
401
|
return context;
|
|
346
402
|
}
|
|
403
|
+
var TRUNCATE = { auto: "@xl:truncate", table: "truncate", cards: "" };
|
|
404
|
+
var MIN = { auto: "@xl:min-w-(--dt-min)!", table: "min-w-(--dt-min)!", cards: "" };
|
|
405
|
+
var MAX = { auto: "@xl:max-w-(--dt-max)!", table: "max-w-(--dt-max)!", cards: "" };
|
|
406
|
+
var SHADOWS = "[background:linear-gradient(to_right,var(--kz-surface-1),transparent)_left/24px_100%_no-repeat_local,linear-gradient(to_left,var(--kz-surface-1),transparent)_right/24px_100%_no-repeat_local,linear-gradient(to_right,rgb(0_0_0/0.18),transparent)_left/10px_100%_no-repeat_scroll,linear-gradient(to_left,rgb(0_0_0/0.18),transparent)_right/10px_100%_no-repeat_scroll]";
|
|
347
407
|
var ALIGN = { start: "text-left", center: "text-center", end: "text-right" };
|
|
348
408
|
var NONE = [];
|
|
349
409
|
var NO_RECORD = {};
|
|
@@ -396,6 +456,10 @@ function DataTable({
|
|
|
396
456
|
empty: empty2,
|
|
397
457
|
layout = "auto",
|
|
398
458
|
density,
|
|
459
|
+
stickyHeader,
|
|
460
|
+
striped,
|
|
461
|
+
scroll,
|
|
462
|
+
stickyFirstColumn,
|
|
399
463
|
virtualized,
|
|
400
464
|
toolbar,
|
|
401
465
|
footer,
|
|
@@ -404,7 +468,9 @@ function DataTable({
|
|
|
404
468
|
}) {
|
|
405
469
|
const labels = { ...dataTableLabels, ...given };
|
|
406
470
|
const effectiveLayout = virtualized ? "table" : layout;
|
|
407
|
-
const
|
|
471
|
+
const L = effectiveLayout;
|
|
472
|
+
const typed = columns.some((c) => c.type || c.priority);
|
|
473
|
+
const s2 = dataTable({ layout: L, density, sticky: Boolean(stickyHeader), striped: Boolean(striped), typed });
|
|
408
474
|
const [sort, setSort] = useControllable(sortProp, defaultSort, onSortChange);
|
|
409
475
|
const [filters, setFiltersState] = useControllable(filtersProp, defaultFilters, onFiltersChange);
|
|
410
476
|
const [selected, setSelected] = useControllable(selectedProp, defaultSelected, onSelectedChange);
|
|
@@ -437,6 +503,10 @@ function DataTable({
|
|
|
437
503
|
announce({ pageSize: next, page: 1 });
|
|
438
504
|
};
|
|
439
505
|
const hasExpander = Boolean(renderDetail || getSubRows);
|
|
506
|
+
const priorityOf = (column) => column.priority && column.priority > 1 ? column.priority : 1;
|
|
507
|
+
const maxPriority = columns.reduce((max, column) => priorityOf(column) > max ? priorityOf(column) : max, 1);
|
|
508
|
+
const inlineToggle = maxPriority > 1 && !hasExpander;
|
|
509
|
+
const detailed = Boolean(renderDetail) || inlineToggle;
|
|
440
510
|
const defs = React.useMemo(
|
|
441
511
|
() => columns.map((column) => ({
|
|
442
512
|
id: column.id,
|
|
@@ -455,6 +525,8 @@ function DataTable({
|
|
|
455
525
|
})),
|
|
456
526
|
[columns, resizing]
|
|
457
527
|
);
|
|
528
|
+
const firstId = columns[0]?.id;
|
|
529
|
+
const pinned = stickyFirstColumn && firstId && !pinning?.start?.length ? { ...pinning, start: [firstId] } : pinning;
|
|
458
530
|
const pageIndex = Math.max(0, page - 1);
|
|
459
531
|
const table = useTable({
|
|
460
532
|
features,
|
|
@@ -462,7 +534,7 @@ function DataTable({
|
|
|
462
534
|
data: rows,
|
|
463
535
|
getRowId: (row) => getRowId(row),
|
|
464
536
|
getSubRows: getSubRows ? (row) => getSubRows(row) : void 0,
|
|
465
|
-
getRowCanExpand:
|
|
537
|
+
getRowCanExpand: detailed ? () => true : void 0,
|
|
466
538
|
state: {
|
|
467
539
|
sorting: sort ? [{ id: sort.column, desc: sort.direction === "descending" }] : [],
|
|
468
540
|
columnFilters: Object.entries(filters).map(([id, value]) => ({ id, value })),
|
|
@@ -471,7 +543,7 @@ function DataTable({
|
|
|
471
543
|
columnVisibility: { ...visibility },
|
|
472
544
|
expanded: { ...expanded },
|
|
473
545
|
pagination: { pageIndex, pageSize: paginated ? pageSize : Math.max(1, rows.length) },
|
|
474
|
-
columnPinning: { start: [...
|
|
546
|
+
columnPinning: { start: [...pinned?.start ?? []], end: [...pinned?.end ?? []] },
|
|
475
547
|
columnSizing: sizing,
|
|
476
548
|
...resizeState ? { columnResizing: resizeState } : {}
|
|
477
549
|
},
|
|
@@ -521,7 +593,8 @@ function DataTable({
|
|
|
521
593
|
const someChosen = selectableIds.some((id) => chosen.has(id));
|
|
522
594
|
const toggleAll = () => setSelected(allChosen ? selected.filter((id) => !selectableIds.includes(id)) : [.../* @__PURE__ */ new Set([...selected, ...selectableIds])]);
|
|
523
595
|
const span = visibleColumns.length + (selectable ? 1 : 0) + (hasExpander ? 1 : 0);
|
|
524
|
-
const fixedLayout = Boolean(resizing ||
|
|
596
|
+
const fixedLayout = Boolean(resizing || pinned?.start?.length || pinned?.end?.length);
|
|
597
|
+
const sideways = scroll ?? (!typed && !stickyHeader);
|
|
525
598
|
const nameOf = (row) => rowLabel ? rowLabel(row.original) : row.id;
|
|
526
599
|
const scroller = React.useRef(null);
|
|
527
600
|
const fallbacks = useLayoutFallbacks(virtualized?.height ?? 0, virtualized?.estimateRowHeight ?? 44);
|
|
@@ -546,11 +619,40 @@ function DataTable({
|
|
|
546
619
|
};
|
|
547
620
|
const width = (column) => fixedLayout || byId.get(column.id)?.width ? { width: column.getSize() } : void 0;
|
|
548
621
|
const message = (content, alert) => /* @__PURE__ */ jsx2("tr", { role: "row", className: s2.tr({ className: "hover:bg-transparent" }), children: /* @__PURE__ */ jsx2("td", { role: "cell", colSpan: span, "data-card": "message", className: s2.td({ className: s2.message() }), children: alert ? /* @__PURE__ */ jsx2("div", { role: "alert", children: content }) : content }) });
|
|
549
|
-
const cardOf = (column) => column?.card === "title" ? "title" : column?.card === "hidden" ? "hidden" : void 0;
|
|
622
|
+
const cardOf = (column) => column?.card === "title" || column && !column.card && column.type === "title" ? "title" : column?.card === "hidden" ? "hidden" : void 0;
|
|
623
|
+
const contentOf = (column, original) => {
|
|
624
|
+
if (column.cell) return column.cell(original);
|
|
625
|
+
const value = valueOf(column, original);
|
|
626
|
+
const text = column.type === "date" && value instanceof Date ? value.toISOString().slice(0, 10) : display(value);
|
|
627
|
+
const cut = TRUNCATE[L];
|
|
628
|
+
switch (column.type) {
|
|
629
|
+
case "title": {
|
|
630
|
+
const sub = column.subtitle?.(original);
|
|
631
|
+
return /* @__PURE__ */ jsxs2("span", { className: "block min-w-0", children: [
|
|
632
|
+
/* @__PURE__ */ jsx2("span", { className: cn("block font-semibold text-fg", cut), title: text, children: text }),
|
|
633
|
+
sub ? /* @__PURE__ */ jsx2("span", { className: cn("block font-mono text-xs text-fg-tertiary", cut), children: sub }) : null
|
|
634
|
+
] });
|
|
635
|
+
}
|
|
636
|
+
case "number":
|
|
637
|
+
return /* @__PURE__ */ jsxs2("span", { children: [
|
|
638
|
+
typeof value === "number" ? value.toLocaleString("en") : text,
|
|
639
|
+
column.unit ? /* @__PURE__ */ jsx2("span", { className: "ms-1 text-fg-secondary", children: column.unit }) : null
|
|
640
|
+
] });
|
|
641
|
+
case "link": {
|
|
642
|
+
const href = column.href?.(original);
|
|
643
|
+
return href ? /* @__PURE__ */ jsx2("a", { href, title: text, className: cn("block text-fg-accent underline-offset-2 hover:underline", cut), children: text }) : /* @__PURE__ */ jsx2("span", { className: cn("block", cut), title: text, children: text });
|
|
644
|
+
}
|
|
645
|
+
default: {
|
|
646
|
+
const lines = column.clamp ?? (column.type === "text" ? 2 : void 0);
|
|
647
|
+
if (!column.nowrap && !lines) return text;
|
|
648
|
+
return /* @__PURE__ */ jsx2("span", { className: column.nowrap ? cn("block", cut || "truncate") : CLAMP[lines], title: text, children: text });
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
};
|
|
550
652
|
const dataCell = (row, cell, first) => {
|
|
551
653
|
const column = byId.get(cell.column.id);
|
|
552
654
|
if (!column) return null;
|
|
553
|
-
const { style, ...
|
|
655
|
+
const { style, ...pinnedProps } = pin(cell.column);
|
|
554
656
|
let content;
|
|
555
657
|
if (row.getIsGrouped()) {
|
|
556
658
|
const leaves = row.getLeafRows().filter((r) => !r.getIsGrouped()).map((r) => r.original);
|
|
@@ -561,16 +663,48 @@ function DataTable({
|
|
|
561
663
|
labels.group(value, leaves.length)
|
|
562
664
|
] });
|
|
563
665
|
} else content = column.aggregate ? column.aggregate(leaves) : null;
|
|
564
|
-
} else
|
|
666
|
+
} else {
|
|
667
|
+
content = contentOf(column, row.original);
|
|
668
|
+
if (first && inlineToggle) {
|
|
669
|
+
content = /* @__PURE__ */ jsxs2("span", { className: "flex min-w-0 items-center gap-1", children: [
|
|
670
|
+
/* @__PURE__ */ jsx2(
|
|
671
|
+
"button",
|
|
672
|
+
{
|
|
673
|
+
type: "button",
|
|
674
|
+
className: s2.toggle({ className: TOGGLE[L][maxPriority] }),
|
|
675
|
+
"aria-expanded": row.getIsExpanded(),
|
|
676
|
+
"aria-label": labels.showMore(nameOf(row)),
|
|
677
|
+
onClick: row.getToggleExpandedHandler(),
|
|
678
|
+
children: /* @__PURE__ */ jsx2(ChevronGlyph, { direction: "right", className: "h-4 w-4" })
|
|
679
|
+
}
|
|
680
|
+
),
|
|
681
|
+
/* @__PURE__ */ jsx2("span", { className: "min-w-0 flex-1", children: content })
|
|
682
|
+
] });
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
const level = priorityOf(column);
|
|
686
|
+
const type = column.type;
|
|
687
|
+
const cellClass = [
|
|
688
|
+
ALIGN[column.align ?? (type === "number" ? "end" : "start")],
|
|
689
|
+
type ? TYPE_CELL[type][L] : "",
|
|
690
|
+
level > 1 ? LEAVES[L][level] : "",
|
|
691
|
+
(type || column.priority) && column.minWidth !== void 0 ? MIN[L] : "",
|
|
692
|
+
column.maxWidth !== void 0 ? MAX[L] : ""
|
|
693
|
+
].join(" ");
|
|
565
694
|
return /* @__PURE__ */ jsx2(
|
|
566
695
|
"td",
|
|
567
696
|
{
|
|
568
697
|
role: "cell",
|
|
569
698
|
"data-label": column.header,
|
|
570
699
|
"data-card": row.getIsGrouped() ? cell.column.id === row.groupingColumnId ? "title" : column.aggregate ? void 0 : "hidden" : cardOf(column),
|
|
571
|
-
...
|
|
572
|
-
className: s2.td({ className:
|
|
573
|
-
style: {
|
|
700
|
+
...pinnedProps,
|
|
701
|
+
className: s2.td({ className: cellClass }),
|
|
702
|
+
style: {
|
|
703
|
+
...style,
|
|
704
|
+
...column.minWidth !== void 0 ? { ["--dt-min"]: `${column.minWidth}px` } : {},
|
|
705
|
+
...column.maxWidth !== void 0 ? { ["--dt-max"]: `${column.maxWidth}px` } : {},
|
|
706
|
+
...first && row.depth > 0 && !row.getIsGrouped() ? { paddingInlineStart: `${1 + row.depth * 1.25}rem` } : {}
|
|
707
|
+
},
|
|
574
708
|
children: content
|
|
575
709
|
},
|
|
576
710
|
cell.id
|
|
@@ -580,6 +714,7 @@ function DataTable({
|
|
|
580
714
|
const isChosen = chosen.has(row.id);
|
|
581
715
|
const grouped = row.getIsGrouped();
|
|
582
716
|
const canExpand = !grouped && (renderDetail ? true : row.getCanExpand());
|
|
717
|
+
const showDetail = detailed && !grouped && row.getIsExpanded() && !virtualized;
|
|
583
718
|
const cells = row.getVisibleCells();
|
|
584
719
|
const main = /* @__PURE__ */ jsxs2(
|
|
585
720
|
"tr",
|
|
@@ -596,13 +731,22 @@ function DataTable({
|
|
|
596
731
|
hasExpander && /* @__PURE__ */ jsx2("td", { role: "cell", className: s2.td({ className: s2.expander() }), children: canExpand ? /* @__PURE__ */ jsx2("button", { type: "button", className: s2.toggle(), "aria-expanded": row.getIsExpanded(), "aria-label": labels.expandRow(nameOf(row)), onClick: row.getToggleExpandedHandler(), children: /* @__PURE__ */ jsx2(ChevronGlyph, { direction: "right", className: "h-4 w-4" }) }) : null }),
|
|
597
732
|
cells.map((cell, i) => dataCell(row, cell, i === 0))
|
|
598
733
|
]
|
|
599
|
-
}
|
|
600
|
-
row.id
|
|
734
|
+
}
|
|
601
735
|
);
|
|
602
|
-
if (!
|
|
736
|
+
if (!showDetail) return /* @__PURE__ */ jsx2(React.Fragment, { children: main }, row.id);
|
|
737
|
+
const left = visibleColumns.filter((c) => priorityOf(byId.get(c.id)) > 1);
|
|
603
738
|
return /* @__PURE__ */ jsxs2(React.Fragment, { children: [
|
|
604
739
|
main,
|
|
605
|
-
/* @__PURE__ */ jsx2("tr", { role: "row", className: s2.tr({ className: "hover:bg-transparent" }), children: /* @__PURE__ */
|
|
740
|
+
/* @__PURE__ */ jsx2("tr", { role: "row", className: s2.tr({ className: "hover:bg-transparent" }), children: /* @__PURE__ */ jsxs2("td", { role: "cell", colSpan: span, "data-card": "message", className: s2.td({ className: renderDetail ? s2.detail() : "bg-surface-0 p-0 text-left" }), children: [
|
|
741
|
+
left.length > 0 ? /* @__PURE__ */ jsx2("dl", { className: cn("m-0 grid gap-3 text-left", renderDetail ? "mb-4" : cn("px-4 py-4", PANEL[L][maxPriority])), children: left.map((c) => {
|
|
742
|
+
const column = byId.get(c.id);
|
|
743
|
+
return /* @__PURE__ */ jsxs2("div", { className: cn(IN_DETAIL[L][priorityOf(column)], "grid-cols-[minmax(5rem,8rem)_minmax(0,1fr)] items-baseline gap-3"), children: [
|
|
744
|
+
/* @__PURE__ */ jsx2("dt", { className: "text-xs font-semibold text-fg-secondary", children: column.header }),
|
|
745
|
+
/* @__PURE__ */ jsx2("dd", { className: "m-0 min-w-0 text-sm text-fg", children: contentOf(column, row.original) })
|
|
746
|
+
] }, c.id);
|
|
747
|
+
}) }) : null,
|
|
748
|
+
renderDetail ? renderDetail(row.original) : null
|
|
749
|
+
] }) })
|
|
606
750
|
] }, row.id);
|
|
607
751
|
};
|
|
608
752
|
let body;
|
|
@@ -646,7 +790,8 @@ function DataTable({
|
|
|
646
790
|
if (!column) return null;
|
|
647
791
|
const sorted = header.column.getIsSorted();
|
|
648
792
|
const direction = sorted === "asc" ? "ascending" : sorted === "desc" ? "descending" : void 0;
|
|
649
|
-
const { style, ...
|
|
793
|
+
const { style, ...pinnedProps } = pin(header.column);
|
|
794
|
+
const level = priorityOf(column);
|
|
650
795
|
return /* @__PURE__ */ jsxs2(
|
|
651
796
|
"th",
|
|
652
797
|
{
|
|
@@ -654,9 +799,9 @@ function DataTable({
|
|
|
654
799
|
scope: "col",
|
|
655
800
|
"aria-sort": column.sortable ? direction ?? "none" : void 0,
|
|
656
801
|
"data-keep": column.sortable ? "" : void 0,
|
|
657
|
-
...
|
|
658
|
-
className: s2.th({ className: ALIGN[column.align ?? "start"] }),
|
|
659
|
-
style: { ...style, ...width(header.column) },
|
|
802
|
+
...pinnedProps,
|
|
803
|
+
className: s2.th({ className: cn(ALIGN[column.align ?? (column.type === "number" ? "end" : "start")], level > 1 && LEAVES_HEAD[L][level]) }),
|
|
804
|
+
style: { ...style, ...typeof stickyHeader === "number" ? { ["--dt-top"]: `${stickyHeader}px` } : {}, ...width(header.column) },
|
|
660
805
|
children: [
|
|
661
806
|
column.sortable ? /* @__PURE__ */ jsxs2("button", { type: "button", "aria-pressed": Boolean(direction), className: s2.sortButton(), onClick: () => header.column.toggleSorting(void 0, false), children: [
|
|
662
807
|
column.header,
|
|
@@ -727,7 +872,7 @@ function DataTable({
|
|
|
727
872
|
children: tableElement
|
|
728
873
|
}
|
|
729
874
|
)
|
|
730
|
-
) : /* @__PURE__ */ jsx2("div", { className: s2.scroller(), children: tableElement }),
|
|
875
|
+
) : /* @__PURE__ */ jsx2("div", { className: s2.scroller({ className: sideways ? scroll ? SHADOWS : void 0 : "overflow-x-clip" }), children: tableElement }),
|
|
731
876
|
pagination2 || footer ? /* @__PURE__ */ jsxs2("div", { className: s2.footer({ className: "flex flex-col gap-3" }), children: [
|
|
732
877
|
pagination2,
|
|
733
878
|
footer
|