@aortl/admin-react 0.6.0 → 0.7.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.
@@ -0,0 +1,44 @@
1
+ import { ComponentProps, ReactNode } from 'react';
2
+ export interface PropertyListProps extends Omit<ComponentProps<"section">, "title"> {
3
+ striped?: boolean;
4
+ /** Reveals a copy button on every item's value cell. Per-item `copyable`
5
+ * on `<PropertyList.Item>` opts in for individual rows. */
6
+ copyable?: boolean;
7
+ /** Collapses the whole section when every item rendered the auto em-dash
8
+ * fallback for an empty value. */
9
+ hideIfAllEmpty?: boolean;
10
+ /** Optional section heading rendered as `<h3 class="property-list-title">`
11
+ * above the items grid. */
12
+ title?: ReactNode;
13
+ }
14
+ declare function PropertyListRoot({ striped, copyable, hideIfAllEmpty, title, className, children, ...rest }: PropertyListProps): import("react/jsx-runtime").JSX.Element;
15
+ export interface PropertyListItemProps extends Omit<ComponentProps<"dd">, "title" | "label"> {
16
+ label?: ReactNode;
17
+ value?: ReactNode;
18
+ /** Right-aligns the value cell + applies `tabular-nums`. Mirrors `Table.Cell.numeric`. */
19
+ numeric?: boolean;
20
+ /** Opts this row into the copy affordance regardless of list-level `copyable`. */
21
+ copyable?: boolean;
22
+ /** Overrides the text the copy button writes to the clipboard. */
23
+ copyValue?: string;
24
+ }
25
+ declare function PropertyListItem({ label, value, numeric, copyable, copyValue, children, ...rest }: PropertyListItemProps): import("react/jsx-runtime").JSX.Element;
26
+ export type PropertyListLabelProps = ComponentProps<"dt">;
27
+ declare function PropertyListLabel({ className, ...rest }: PropertyListLabelProps): import("react/jsx-runtime").JSX.Element;
28
+ export interface PropertyListValueProps extends ComponentProps<"dd"> {
29
+ numeric?: boolean;
30
+ copyable?: boolean;
31
+ /** Marks the cell as carrying an auto-rendered em-dash. The list-level
32
+ * `hideIfAllEmpty` collapses the section when every value is empty. */
33
+ empty?: boolean;
34
+ /** Overrides the text the copy button writes to the clipboard. */
35
+ copyValue?: string;
36
+ }
37
+ declare function PropertyListValue({ numeric, copyable, empty, copyValue, className, children, ...rest }: PropertyListValueProps): import("react/jsx-runtime").JSX.Element;
38
+ export declare const PropertyList: typeof PropertyListRoot & {
39
+ Item: typeof PropertyListItem;
40
+ Label: typeof PropertyListLabel;
41
+ Value: typeof PropertyListValue;
42
+ };
43
+ export {};
44
+ //# sourceMappingURL=PropertyList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PropertyList.d.ts","sourceRoot":"","sources":["../src/PropertyList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AA+C9E,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;gEAC4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;uCACmC;IACnC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;gCAC4B;IAC5B,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,iBAAS,gBAAgB,CAAC,EACxB,OAAO,EACP,QAAQ,EACR,cAAc,EACd,KAAK,EACL,SAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,iBAAiB,2CAoBnB;AAED,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC1F,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAWD,iBAAS,gBAAgB,CAAC,EACxB,KAAK,EACL,KAAK,EACL,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,qBAAqB,2CAmBvB;AAED,MAAM,MAAM,sBAAsB,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;AAC1D,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,sBAAsB,2CAExE;AAED,MAAM,WAAW,sBAAuB,SAAQ,cAAc,CAAC,IAAI,CAAC;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;4EACwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,iBAAS,iBAAiB,CAAC,EACzB,OAAO,EACP,QAAQ,EACR,KAAK,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,sBAAsB,2CA2CxB;AAED,eAAO,MAAM,YAAY;;;;CAIvB,CAAC"}
@@ -277,6 +277,7 @@
277
277
  --text-xl--line-height: calc(1.75 / 1.25);
278
278
  --font-weight-medium: 500;
279
279
  --font-weight-semibold: 600;
280
+ --font-weight-bold: 700;
280
281
  --tracking-wide: 0.025em;
281
282
  --leading-tight: 1.25;
282
283
  --leading-snug: 1.375;
@@ -1165,6 +1166,101 @@
1165
1166
  -webkit-user-select: none;
1166
1167
  user-select: none;
1167
1168
  }
1169
+ :scope._ao-property-list, :scope ._ao-property-list {
1170
+ display: flex;
1171
+ flex-direction: column;
1172
+ font-size: var(--text-sm);
1173
+ line-height: var(--tw-leading, var(--text-sm--line-height));
1174
+ color: var(--color-text);
1175
+ }
1176
+ :scope._ao-property-list-title, :scope ._ao-property-list-title {
1177
+ margin-bottom: calc(var(--spacing) * 2);
1178
+ font-size: var(--text-sm);
1179
+ line-height: var(--tw-leading, var(--text-sm--line-height));
1180
+ --tw-font-weight: var(--font-weight-bold);
1181
+ font-weight: var(--font-weight-bold);
1182
+ color: var(--color-text);
1183
+ }
1184
+ :scope._ao-property-list-items, :scope ._ao-property-list-items {
1185
+ display: grid;
1186
+ grid-template-columns: max-content 1fr;
1187
+ }
1188
+ :scope._ao-property-list-label, :scope ._ao-property-list-label, :scope._ao-property-list-value, :scope ._ao-property-list-value {
1189
+ display: flex;
1190
+ align-items: center;
1191
+ padding: 0.375rem 0.75rem;
1192
+ min-height: 2rem;
1193
+ }
1194
+ :scope._ao-property-list-label, :scope ._ao-property-list-label {
1195
+ color: var(--color-text-muted);
1196
+ }
1197
+ :scope._ao-property-list-value, :scope ._ao-property-list-value {
1198
+ gap: 0.5rem;
1199
+ min-width: 0;
1200
+ }
1201
+ :scope._ao-property-list-value-numeric, :scope ._ao-property-list-value-numeric {
1202
+ justify-content: flex-end;
1203
+ --tw-numeric-spacing: tabular-nums;
1204
+ font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
1205
+ }
1206
+ :scope._ao-property-list-striped dt:nth-of-type(2n + 2), :scope ._ao-property-list-striped dt:nth-of-type(2n + 2), :scope._ao-property-list-striped dd:nth-of-type(2n + 2), :scope ._ao-property-list-striped dd:nth-of-type(2n + 2) {
1207
+ background-color: var(--color-surface-muted);
1208
+ }
1209
+ :scope._ao-property-list-hide-if-empty:not(:has(._ao-property-list-value:not(._ao-property-list-value-empty))), :scope ._ao-property-list-hide-if-empty:not(:has(._ao-property-list-value:not(._ao-property-list-value-empty))) {
1210
+ display: none;
1211
+ }
1212
+ :scope._ao-property-list-copy, :scope ._ao-property-list-copy {
1213
+ margin-left: auto;
1214
+ display: inline-flex;
1215
+ cursor: pointer;
1216
+ align-items: center;
1217
+ justify-content: center;
1218
+ border-radius: 0.25rem;
1219
+ border-style: var(--tw-border-style);
1220
+ border-width: 0px;
1221
+ background-color: transparent;
1222
+ color: var(--color-text-muted);
1223
+ &:hover {
1224
+ @media (hover: hover) {
1225
+ color: var(--color-text);
1226
+ }
1227
+ }
1228
+ &:focus-visible {
1229
+ outline-style: var(--tw-outline-style);
1230
+ outline-width: 2px;
1231
+ }
1232
+ &:focus-visible {
1233
+ outline-offset: 2px;
1234
+ }
1235
+ &:focus-visible {
1236
+ outline-color: var(--color-primary);
1237
+ }
1238
+ display: none;
1239
+ flex-shrink: 0;
1240
+ padding: 0.125rem;
1241
+ transition: opacity 100ms ease, color 100ms ease;
1242
+ }
1243
+ :scope._ao-property-list-copyable ._ao-property-list-copy, :scope ._ao-property-list-copyable ._ao-property-list-copy, :scope._ao-property-list-value-copyable ._ao-property-list-copy, :scope ._ao-property-list-value-copyable ._ao-property-list-copy {
1244
+ display: inline-flex;
1245
+ opacity: 0;
1246
+ pointer-events: none;
1247
+ }
1248
+ :scope._ao-property-list-copyable ._ao-property-list-label:hover + ._ao-property-list-value ._ao-property-list-copy, :scope ._ao-property-list-copyable ._ao-property-list-label:hover + ._ao-property-list-value ._ao-property-list-copy, :scope._ao-property-list-copyable ._ao-property-list-value:hover ._ao-property-list-copy, :scope ._ao-property-list-copyable ._ao-property-list-value:hover ._ao-property-list-copy, :scope._ao-property-list-label:has(+ ._ao-property-list-value-copyable):hover + ._ao-property-list-value ._ao-property-list-copy, :scope ._ao-property-list-label:has(+ ._ao-property-list-value-copyable):hover + ._ao-property-list-value ._ao-property-list-copy, :scope._ao-property-list-value-copyable:hover ._ao-property-list-copy, :scope ._ao-property-list-value-copyable:hover ._ao-property-list-copy, :scope._ao-property-list-copy:focus-visible, :scope ._ao-property-list-copy:focus-visible, :scope._ao-property-list-copy[data-copied], :scope ._ao-property-list-copy[data-copied] {
1249
+ opacity: 1;
1250
+ pointer-events: auto;
1251
+ }
1252
+ :scope._ao-property-list-copy ._ao-property-list-copy-icon-copied, :scope ._ao-property-list-copy ._ao-property-list-copy-icon-copied {
1253
+ display: none;
1254
+ }
1255
+ :scope._ao-property-list-copy[data-copied] ._ao-property-list-copy-icon, :scope ._ao-property-list-copy[data-copied] ._ao-property-list-copy-icon {
1256
+ display: none;
1257
+ }
1258
+ :scope._ao-property-list-copy[data-copied] ._ao-property-list-copy-icon-copied, :scope ._ao-property-list-copy[data-copied] ._ao-property-list-copy-icon-copied {
1259
+ display: inline-flex;
1260
+ }
1261
+ :scope._ao-property-list-copy[data-copied], :scope ._ao-property-list-copy[data-copied] {
1262
+ color: var(--color-success);
1263
+ }
1168
1264
  :scope._ao-btn, :scope ._ao-btn {
1169
1265
  display: inline-flex;
1170
1266
  cursor: pointer;
package/dist/index.cjs CHANGED
@@ -1167,6 +1167,117 @@ var Tooltip = Object.assign(TooltipShorthand, {
1167
1167
  Popup: TooltipPopup
1168
1168
  });
1169
1169
  //#endregion
1170
+ //#region src/PropertyList.tsx
1171
+ function CopyGlyph({ className }) {
1172
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1173
+ xmlns: "http://www.w3.org/2000/svg",
1174
+ width: "14",
1175
+ height: "14",
1176
+ viewBox: "0 0 24 24",
1177
+ fill: "none",
1178
+ stroke: "currentColor",
1179
+ strokeWidth: "2",
1180
+ strokeLinecap: "round",
1181
+ strokeLinejoin: "round",
1182
+ "aria-hidden": "true",
1183
+ className,
1184
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M7 7m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M15 7v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2" })]
1185
+ });
1186
+ }
1187
+ function CheckGlyph({ className }) {
1188
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1189
+ xmlns: "http://www.w3.org/2000/svg",
1190
+ width: "14",
1191
+ height: "14",
1192
+ viewBox: "0 0 24 24",
1193
+ fill: "none",
1194
+ stroke: "currentColor",
1195
+ strokeWidth: "2",
1196
+ strokeLinecap: "round",
1197
+ strokeLinejoin: "round",
1198
+ "aria-hidden": "true",
1199
+ className,
1200
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M5 12l5 5l10 -10" })
1201
+ });
1202
+ }
1203
+ function PropertyListRoot({ striped, copyable, hideIfAllEmpty, title, className, children, ...rest }) {
1204
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1205
+ className: cn([
1206
+ "property-list",
1207
+ striped && "property-list-striped",
1208
+ copyable && "property-list-copyable",
1209
+ hideIfAllEmpty && "property-list-hide-if-empty"
1210
+ ], className),
1211
+ ...rest,
1212
+ children: [title !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
1213
+ className: cn("property-list-title", void 0),
1214
+ children: title
1215
+ }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dl", {
1216
+ className: cn("property-list-items", void 0),
1217
+ children
1218
+ })]
1219
+ });
1220
+ }
1221
+ function isEmptyValue(value) {
1222
+ if (value == null) return true;
1223
+ if (typeof value === "string") return value.trim() === "";
1224
+ return false;
1225
+ }
1226
+ function PropertyListItem({ label, value, numeric, copyable, copyValue, children, ...rest }) {
1227
+ if (children !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
1228
+ const empty = isEmptyValue(value);
1229
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PropertyListLabel, { children: label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PropertyListValue, {
1230
+ numeric,
1231
+ copyable,
1232
+ empty,
1233
+ copyValue: copyValue ?? (typeof value === "string" ? value : void 0),
1234
+ ...rest,
1235
+ children: empty ? "—" : value
1236
+ })] });
1237
+ }
1238
+ function PropertyListLabel({ className, ...rest }) {
1239
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", {
1240
+ className: cn("property-list-label", className),
1241
+ ...rest
1242
+ });
1243
+ }
1244
+ function PropertyListValue({ numeric, copyable, empty, copyValue, className, children, ...rest }) {
1245
+ const ddRef = (0, react.useRef)(null);
1246
+ const [copied, setCopied] = (0, react.useState)(false);
1247
+ async function handleCopy() {
1248
+ const text = copyValue ?? ddRef.current?.textContent?.trim() ?? "";
1249
+ if (!text) return;
1250
+ try {
1251
+ await navigator.clipboard.writeText(text);
1252
+ setCopied(true);
1253
+ setTimeout(() => setCopied(false), 1200);
1254
+ } catch {}
1255
+ }
1256
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dd", {
1257
+ ref: ddRef,
1258
+ className: cn([
1259
+ "property-list-value",
1260
+ numeric && "property-list-value-numeric",
1261
+ copyable && "property-list-value-copyable",
1262
+ empty && "property-list-value-empty"
1263
+ ], className),
1264
+ ...rest,
1265
+ children: [children, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1266
+ type: "button",
1267
+ "aria-label": "Copy",
1268
+ className: cn("property-list-copy", void 0),
1269
+ onClick: handleCopy,
1270
+ "data-copied": copied ? "true" : void 0,
1271
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyGlyph, { className: cn("property-list-copy-icon", void 0) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckGlyph, { className: cn("property-list-copy-icon-copied", void 0) })]
1272
+ })]
1273
+ });
1274
+ }
1275
+ var PropertyList = Object.assign(PropertyListRoot, {
1276
+ Item: PropertyListItem,
1277
+ Label: PropertyListLabel,
1278
+ Value: PropertyListValue
1279
+ });
1280
+ //#endregion
1170
1281
  //#region src/Table.tsx
1171
1282
  function TableRoot({ striped, bordered, relaxed, sticky, className, ...rest }) {
1172
1283
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("table", {
@@ -1417,6 +1528,7 @@ exports.Menu = Menu;
1417
1528
  exports.Navbar = Navbar;
1418
1529
  exports.Pagination = Pagination;
1419
1530
  exports.Progress = Progress;
1531
+ exports.PropertyList = PropertyList;
1420
1532
  exports.Radio = Radio;
1421
1533
  exports.RadioGroup = RadioGroup;
1422
1534
  exports.Select = Select;