@godxjp/ui 16.2.2 → 16.3.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,10 +1,14 @@
1
1
  import * as React from "react";
2
+ import type { DescriptionsLayoutProp } from "../../props/vocabulary/interaction.prop";
3
+ export type { DescriptionsLayoutProp };
2
4
  export interface DescriptionsProps {
3
5
  columns?: 1 | 2 | 3;
6
+ /** Label placement within each item. Default `vertical` (label over value). */
7
+ layout?: DescriptionsLayoutProp;
4
8
  className?: string;
5
9
  children: React.ReactNode;
6
10
  }
7
- export declare function Descriptions({ columns, className, children }: DescriptionsProps): import("react/jsx-runtime").JSX.Element;
11
+ export declare function Descriptions({ columns, layout, className, children, }: DescriptionsProps): import("react/jsx-runtime").JSX.Element;
8
12
  export declare namespace Descriptions {
9
13
  var Item: ({ label, mono, span, className, children, }: DescriptionsItemProps) => import("react/jsx-runtime").JSX.Element;
10
14
  }
@@ -1,8 +1,15 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
2
3
  import { cn } from "../../lib/utils";
3
- function Descriptions({ columns = 2, className, children }) {
4
+ const DescriptionsLayoutContext = React.createContext("vertical");
5
+ function Descriptions({
6
+ columns = 2,
7
+ layout = "vertical",
8
+ className,
9
+ children
10
+ }) {
4
11
  const colsClass = columns === 1 ? "grid-cols-1" : columns === 3 ? "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3" : "grid-cols-1 sm:grid-cols-2";
5
- return /* @__PURE__ */ jsx("dl", { className: cn("grid gap-x-6 gap-y-3", colsClass, className), children });
12
+ return /* @__PURE__ */ jsx(DescriptionsLayoutContext.Provider, { value: layout, children: /* @__PURE__ */ jsx("dl", { className: cn("grid gap-x-6 gap-y-3", colsClass, className), children }) });
6
13
  }
7
14
  Descriptions.Item = function DescriptionsItem({
8
15
  label,
@@ -11,13 +18,29 @@ Descriptions.Item = function DescriptionsItem({
11
18
  className,
12
19
  children
13
20
  }) {
21
+ const layout = React.useContext(DescriptionsLayoutContext);
14
22
  const spanClass = span === 2 ? "sm:col-span-2" : span === 3 ? "sm:col-span-2 lg:col-span-3" : "";
15
- return (
16
- // grid + the shared --field-label-gap so the label→value gap matches FormField / Form everywhere.
17
- /* @__PURE__ */ jsxs("div", { className: cn("grid gap-[var(--field-label-gap)]", spanClass, className), children: [
18
- /* @__PURE__ */ jsx("dt", { className: "text-muted-foreground text-xs", children: label }),
19
- /* @__PURE__ */ jsx("dd", { className: cn("text-sm break-all", mono && "font-mono"), children })
20
- ] })
23
+ return /* @__PURE__ */ jsxs(
24
+ "div",
25
+ {
26
+ className: cn(
27
+ layout === "horizontal" ? (
28
+ // Label beside value — a token-aligned label column so the values line up. The
29
+ // `--descriptions-label-width` knob aligns labels (rule #44/#45).
30
+ "grid grid-cols-[var(--descriptions-label-width)_minmax(0,1fr)] items-baseline gap-x-3"
31
+ ) : (
32
+ // Vertical (default): label over value. The shared --field-label-gap matches
33
+ // FormField / Form so the label→value gap is consistent everywhere.
34
+ "grid gap-[var(--field-label-gap)]"
35
+ ),
36
+ spanClass,
37
+ className
38
+ ),
39
+ children: [
40
+ /* @__PURE__ */ jsx("dt", { className: "text-muted-foreground text-xs", children: label }),
41
+ /* @__PURE__ */ jsx("dd", { className: cn("text-sm break-all", mono && "font-mono"), children })
42
+ ]
43
+ }
21
44
  );
22
45
  };
23
46
  export {
@@ -249,6 +249,11 @@ export declare const VOCABULARY_REGISTRY: {
249
249
  readonly category: "interaction";
250
250
  readonly description: "Form label layout: vertical | horizontal | inline";
251
251
  };
252
+ readonly DescriptionsLayoutProp: {
253
+ readonly file: "vocabulary/interaction.prop.ts";
254
+ readonly category: "interaction";
255
+ readonly description: "Descriptions label layout: vertical (over) | horizontal (beside)";
256
+ };
252
257
  readonly BreakpointProp: {
253
258
  readonly file: "vocabulary/interaction.prop.ts";
254
259
  readonly category: "interaction";
@@ -248,6 +248,11 @@ const VOCABULARY_REGISTRY = {
248
248
  category: "interaction",
249
249
  description: "Form label layout: vertical | horizontal | inline"
250
250
  },
251
+ DescriptionsLayoutProp: {
252
+ file: "vocabulary/interaction.prop.ts",
253
+ category: "interaction",
254
+ description: "Descriptions label layout: vertical (over) | horizontal (beside)"
255
+ },
251
256
  BreakpointProp: {
252
257
  file: "vocabulary/interaction.prop.ts",
253
258
  category: "interaction",
@@ -26,6 +26,9 @@ export type SizeProp = "xs" | "sm" | "md" | "lg";
26
26
  export type ButtonSizeProp = SizeProp | "default" | "icon" | "icon-xs" | "icon-sm" | "icon-lg";
27
27
  /** Form layout — label position relative to its control (Ant-style). */
28
28
  export type FormLayoutProp = "vertical" | "horizontal" | "inline";
29
+ /** Descriptions layout — label over value (`vertical`) or beside it (`horizontal`); the
30
+ * `FormLayoutProp` subset that a metadata grid supports (no `inline`). */
31
+ export type DescriptionsLayoutProp = Extract<FormLayoutProp, "vertical" | "horizontal">;
29
32
  /** Responsive breakpoint name (mobile-first); used by `collapseBelow` etc. */
30
33
  export type BreakpointProp = "sm" | "md" | "lg" | "xl";
31
34
  /** Dialog confirm button emphasis. */
@@ -9,6 +9,7 @@
9
9
  @import "./components/control.css";
10
10
  @import "./components/form.css";
11
11
  @import "./components/card.css";
12
+ @import "./components/descriptions.css";
12
13
  @import "./components/table.css";
13
14
  @import "./components/feedback.css";
14
15
  @import "./components/badge.css";
@@ -0,0 +1,9 @@
1
+ /* Descriptions component tokens. */
2
+
3
+ :root {
4
+ /* Width of the label column when <Descriptions layout="horizontal">. Labels align to this
5
+ * shared column so the values line up (the horizontal-detail look, mirroring <Form layout>).
6
+ * A rem value gives a fixed aligned column; set `max-content` to size each label to its text.
7
+ * (rule #44/#45 — a service theme tunes it here instead of forking CSS.) */
8
+ --descriptions-label-width: 8rem;
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "16.2.2",
3
+ "version": "16.3.0",
4
4
  "type": "module",
5
5
  "packageManager": "pnpm@10.29.1",
6
6
  "sideEffects": false,