@nadicodeai/ui 12.1.11 → 12.1.13

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.
@@ -3,6 +3,11 @@ export type ObjectFact = {
3
3
  label: string;
4
4
  value: ReactNode;
5
5
  icon?: ReactNode;
6
+ /**
7
+ * A value long enough to be a paragraph rather than a figure, such as a note
8
+ * or a pasted reference. It takes the full measure with its label above it.
9
+ */
10
+ block?: boolean;
6
11
  };
7
12
  export type ObjectIdentitySupportFacts = {
8
13
  facts: readonly ObjectFact[];
@@ -1 +1 @@
1
- {"version":3,"file":"object-workspace.d.ts","sourceRoot":"","sources":["../../src/components/object-workspace.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC;AAE/E,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,KAAK,EACL,WAAW,EACX,QAAQ,EACR,MAAM,EACN,UAAU,EACV,MAAiB,EACjB,OAAO,GACR,EAAE;IACD,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,0BAA0B,CAAC;CACtC,+BAwCA;AAED,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,UAAU,GACX,EAAE;IACD,OAAO,EAAE,SAAS,CAAC;IACnB,UAAU,EAAE,SAAS,CAAC;CACvB,+BAUA;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,EACX,MAAM,EACN,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAoBA;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAmB,GACpB,EAAE;IACD,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC,+BA6BA"}
1
+ {"version":3,"file":"object-workspace.d.ts","sourceRoot":"","sources":["../../src/components/object-workspace.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,KAAK,EACL,WAAW,EACX,QAAQ,EACR,MAAM,EACN,UAAU,EACV,MAAiB,EACjB,OAAO,GACR,EAAE;IACD,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,0BAA0B,CAAC;CACtC,+BAwCA;AAED,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,UAAU,GACX,EAAE;IACD,OAAO,EAAE,SAAS,CAAC;IACnB,UAAU,EAAE,SAAS,CAAC;CACvB,+BAUA;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,EACX,MAAM,EACN,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAoBA;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAmB,GACpB,EAAE;IACD,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC,+BAkCA"}
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils.js";
2
3
  import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "./card.js";
3
4
  import { ObjectIdentitySupport } from "../internal/object-identity-support.js";
4
5
  export function ObjectIdentity({ visual, title, description, metadata, action, editAction, layout = "inline", support, }) {
@@ -15,5 +16,5 @@ export function ObjectSection({ title, description, action, icon, children, }) {
15
16
  export function ObjectFacts({ facts, density = "default", }) {
16
17
  return (_jsx("dl", { "data-density": density, "data-slot": "object-facts", className: density === "compact"
17
18
  ? "grid min-w-0 grid-cols-2 gap-x-6 gap-y-2"
18
- : "grid min-w-0 gap-x-6 gap-y-5 sm:grid-cols-2", children: facts.map((fact) => (_jsxs("div", { className: density === "compact" ? "grid min-w-0 gap-0.5" : "grid min-w-0 gap-1.5", children: [_jsxs("dt", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [fact.icon ? (_jsx("span", { "aria-hidden": "true", className: "[&_svg]:size-3.5", children: fact.icon })) : null, fact.label] }), _jsx("dd", { className: "text-sm break-words", children: fact.value })] }, fact.label))) }));
19
+ : "grid min-w-0 gap-x-6 gap-y-5 sm:grid-cols-2", children: facts.map((fact) => (_jsxs("div", { className: cn(density === "compact" ? "grid min-w-0 gap-0.5" : "grid min-w-0 gap-1.5", fact.block && "col-span-full"), children: [_jsxs("dt", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [fact.icon ? (_jsx("span", { "aria-hidden": "true", className: "[&_svg]:size-3.5", children: fact.icon })) : null, fact.label] }), _jsx("dd", { className: cn("text-sm break-words", fact.block && "whitespace-pre-wrap"), children: fact.value })] }, fact.label))) }));
19
20
  }
@@ -23,12 +23,11 @@ export type SettingsFactsSectionProps = Omit<ComponentPropsWithoutRef<"section">
23
23
  headingId: string;
24
24
  title: string;
25
25
  surface?: CardSurface;
26
- factLayout?: "cells" | "plain";
27
26
  /**
28
27
  * The card's density. The default matches the settings sections it sits
29
28
  * among; `sm` is for a compact card in a side column.
30
29
  */
31
30
  size?: ComponentPropsWithoutRef<typeof Card>["size"];
32
31
  };
33
- export declare function SettingsFactsSection({ action, description, facts, footer, missingValueLabel, headingId, title, surface, factLayout, size, ...props }: SettingsFactsSectionProps): import("react").JSX.Element;
32
+ export declare function SettingsFactsSection({ action, description, facts, footer, missingValueLabel, headingId, title, surface, size, ...props }: SettingsFactsSectionProps): import("react").JSX.Element;
34
33
  //# sourceMappingURL=settings-facts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings-facts.d.ts","sourceRoot":"","sources":["../../src/components/settings-facts.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKjE,OAAO,EACL,IAAI,EAOJ,KAAK,WAAW,EACjB,MAAM,QAAQ,CAAC;AAEhB,MAAM,MAAM,YAAY,GAAG;IACzB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,wBAAwB,CAAC,SAAS,CAAC,EACnC,UAAU,GAAG,WAAW,CACzB,GAAG;IACF,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC/B;;;OAGG;IACH,IAAI,CAAC,EAAE,wBAAwB,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;CACtD,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,WAAW,EACX,KAAK,EACL,MAAM,EACN,iBAAiB,EACjB,SAAS,EACT,KAAK,EACL,OAAmB,EACnB,UAAoB,EACpB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,yBAAyB,+BAiE3B"}
1
+ {"version":3,"file":"settings-facts.d.ts","sourceRoot":"","sources":["../../src/components/settings-facts.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKjE,OAAO,EACL,IAAI,EAOJ,KAAK,WAAW,EACjB,MAAM,QAAQ,CAAC;AAEhB,MAAM,MAAM,YAAY,GAAG;IACzB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,wBAAwB,CAAC,SAAS,CAAC,EACnC,UAAU,GAAG,WAAW,CACzB,GAAG;IACF,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;OAGG;IACH,IAAI,CAAC,EAAE,wBAAwB,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;CACtD,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,WAAW,EACX,KAAK,EACL,MAAM,EACN,iBAAiB,EACjB,SAAS,EACT,KAAK,EACL,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,yBAAyB,+BAqC3B"}
@@ -1,10 +1,11 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ObjectFacts } from "./object-workspace.js";
2
3
  import { Separator } from "./separator.js";
3
- import { cn } from "../lib/utils.js";
4
4
  import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "./card.js";
5
- export function SettingsFactsSection({ action, description, facts, footer, missingValueLabel, headingId, title, surface = "resting", factLayout = "cells", size = "default", ...props }) {
6
- return (_jsxs(Card, { render: _jsx("section", {}), ...props, "aria-labelledby": headingId, surface: surface, size: size, className: "min-w-0", children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: _jsx("h2", { id: headingId, tabIndex: -1, children: title }) }), description ? _jsx(CardDescription, { children: description }) : null, action ? _jsx(CardAction, { children: action }) : null] }), _jsx(Separator, {}), _jsx(CardContent, { children: _jsx("dl", { className: cn("grid min-w-0 grid-cols-1 nc-type-body-sm sm:grid-cols-2", factLayout === "plain" ? "gap-x-8 gap-y-5" : "gap-3"), children: facts.map((fact) => {
7
- const content = (_jsxs(_Fragment, { children: [_jsx("dt", { className: "text-xs text-muted-foreground", children: fact.label }), _jsx("dd", { className: cn("min-w-0 break-words", fact.block && "whitespace-pre-wrap", (fact.value == null || fact.value === "") && "text-muted-foreground"), children: fact.value == null || fact.value === "" ? missingValueLabel : fact.value })] }));
8
- return factLayout === "plain" ? (_jsx("div", { className: cn("flex min-w-0 flex-col gap-1", fact.block && "col-span-full"), children: content }, fact.label)) : (_jsx(Card, { className: cn("min-w-0 gap-1 px-(--card-spacing)", fact.block && "col-span-full"), size: "sm", surface: "outlined", children: content }, fact.label));
9
- }) }) }), footer ? _jsx(CardFooter, { className: "flex-wrap gap-3", children: footer }) : null] }));
5
+ export function SettingsFactsSection({ action, description, facts, footer, missingValueLabel, headingId, title, surface = "resting", size = "default", ...props }) {
6
+ return (_jsxs(Card, { render: _jsx("section", {}), ...props, "aria-labelledby": headingId, surface: surface, size: size, className: "min-w-0", children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: _jsx("h2", { id: headingId, tabIndex: -1, children: title }) }), description ? _jsx(CardDescription, { children: description }) : null, action ? _jsx(CardAction, { children: action }) : null] }), _jsx(Separator, {}), _jsx(CardContent, { children: _jsx(ObjectFacts, { facts: facts.map((fact) => ({
7
+ label: fact.label,
8
+ block: fact.block,
9
+ value: fact.value == null || fact.value === "" ? (_jsx("span", { className: "text-muted-foreground", children: missingValueLabel })) : (fact.value),
10
+ })) }) }), footer ? _jsx(CardFooter, { className: "flex-wrap gap-3", children: footer }) : null] }));
10
11
  }
@@ -19,6 +19,7 @@ import { noPackageComponentRedefinition } from "./rules/no-package-component-red
19
19
  import { noPairedSizeUtility } from "./rules/no-paired-size-utility.js";
20
20
  import { noRestingSettingsControl } from "./rules/no-resting-settings-control.js";
21
21
  import { oneControlHeight } from "./rules/one-control-height.js";
22
+ import { tableColumnWrapsByMeta } from "./rules/table-column-wraps-by-meta.js";
22
23
  import { noShadcnAppearanceOverride } from "./rules/no-shadcn-appearance-override.js";
23
24
  import { noSubjectDerivedExpectation } from "./rules/no-subject-derived-expectation.js";
24
25
  import { noUnpinnedVercelFunctionsImport } from "./rules/no-unpinned-vercel-functions-import.js";
@@ -131,6 +132,7 @@ const plugin = {
131
132
  "no-invalid-token-utility": noInvalidTokenUtility,
132
133
  "no-token-category-bypass": noTokenCategoryBypass,
133
134
  "one-control-height": oneControlHeight,
135
+ "table-column-wraps-by-meta": tableColumnWrapsByMeta,
134
136
  "server-action-discipline": serverActionDiscipline,
135
137
  "settings-section-description": settingsSectionDescription,
136
138
  "shadcn-composition": shadcnComposition,
@@ -0,0 +1,55 @@
1
+ /*
2
+ * A table column wraps by its definition, never by its cells. DataTable holds a
3
+ * fact on one line and gives a column marked `meta: { prose: true }` a floor
4
+ * and wrapping between words (DESIGN.md, "Tables and missing values"). A cell
5
+ * that sets its own wrapping gets neither the floor nor the identity's share
6
+ * of the width, and the table squeezes it until each word takes a line.
7
+ *
8
+ * Standard tool checked first: `better-tailwindcss`'s `no-restricted-classes`
9
+ * judges one class at a time, and `whitespace-normal` is right in a button or a
10
+ * card. What is wrong is where it is written: inside a column's `cell`, which
11
+ * this rule reads on the shared className reader.
12
+ */
13
+ import { openingElementClassUtilities } from "./jsx-class-utility.js";
14
+
15
+ const WRAPPING = /^(?:.*:)?whitespace-(?:normal|pre-line|pre-wrap)$/;
16
+
17
+ /** Inside the `cell` renderer of a column definition object. */
18
+ function insideColumnCell(node) {
19
+ for (let current = node.parent; current; current = current.parent) {
20
+ if (
21
+ current.type === "Property" &&
22
+ !current.computed &&
23
+ current.key.type === "Identifier" &&
24
+ current.key.name === "cell"
25
+ ) {
26
+ return true;
27
+ }
28
+ }
29
+ return false;
30
+ }
31
+
32
+ export const tableColumnWrapsByMeta = {
33
+ meta: {
34
+ type: "problem",
35
+ docs: {
36
+ description: "Disallow a table cell setting its own wrapping; mark the column prose",
37
+ },
38
+ schema: [],
39
+ messages: {
40
+ cellWraps:
41
+ '"{{token}}" wraps one cell of a table column. Mark the column `meta: { prose: true }` so DataTable gives it a floor and wraps it between words.',
42
+ },
43
+ },
44
+ create(context) {
45
+ return {
46
+ JSXOpeningElement(node) {
47
+ if (!insideColumnCell(node)) return;
48
+ for (const token of openingElementClassUtilities(node, context)) {
49
+ if (WRAPPING.test(token))
50
+ context.report({ node, messageId: "cellWraps", data: { token } });
51
+ }
52
+ },
53
+ };
54
+ },
55
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nadicodeai/ui",
3
- "version": "12.1.11",
3
+ "version": "12.1.13",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -71,7 +71,7 @@
71
71
  "@assistant-ui/react": "0.15.21",
72
72
  "@assistant-ui/react-markdown": "0.14.16",
73
73
  "@base-ui/react": "^1.8.0",
74
- "@nadicodeai/design-system": "12.1.11",
74
+ "@nadicodeai/design-system": "12.1.13",
75
75
  "class-variance-authority": "^0.7.1",
76
76
  "clsx": "^2.1.1",
77
77
  "cmdk": "^1.1.1",