@viax.io/uxm 4.40.1 → 4.41.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/CHANGELOG.md +14 -0
- package/README.md +78 -19
- package/dist/studio/index.cjs.map +1 -1
- package/dist/studio/index.d.ts +3 -2
- package/dist/studio/index.d.ts.map +1 -1
- package/dist/studio/index.js.map +1 -1
- package/dist/studio/lib/registry/composite/list-item.cjs +22 -5
- package/dist/studio/lib/registry/composite/list-item.cjs.map +1 -1
- package/dist/studio/lib/registry/composite/list-item.d.ts.map +1 -1
- package/dist/studio/lib/registry/composite/list-item.js +22 -5
- package/dist/studio/lib/registry/composite/list-item.js.map +1 -1
- package/dist/ui/app-sidebar/app-sidebar.css +0 -1
- package/dist/ui/app-top-bar/app-top-bar.css +0 -1
- package/dist/ui/avatar/avatar.css +0 -1
- package/dist/ui/back-link/back-link.css +0 -1
- package/dist/ui/badge/badge.css +0 -1
- package/dist/ui/banner/banner.css +0 -1
- package/dist/ui/breadcrumb/breadcrumb.css +0 -1
- package/dist/ui/bulk-action-bar/bulk-action-bar.css +0 -1
- package/dist/ui/button/button.css +0 -1
- package/dist/ui/button-group/button-group.css +0 -1
- package/dist/ui/button-icon/button-icon.css +0 -1
- package/dist/ui/button-with-icon/button-with-icon.css +0 -1
- package/dist/ui/calendar/calendar.css +0 -1
- package/dist/ui/card/card.css +0 -1
- package/dist/ui/checkbox/checkbox.css +0 -1
- package/dist/ui/chip/chip.css +0 -1
- package/dist/ui/cluster/cluster.css +0 -1
- package/dist/ui/code-editor/code-editor.css +0 -1
- package/dist/ui/color-input/color-input.css +0 -1
- package/dist/ui/component-row/component-row.css +0 -1
- package/dist/ui/config-component-row/config-component-row.css +0 -1
- package/dist/ui/config-segment-item/config-segment-item.css +0 -1
- package/dist/ui/currency-input/currency-input.css +0 -1
- package/dist/ui/data-table/data-table.css +0 -1
- package/dist/ui/date-input/date-input.css +0 -1
- package/dist/ui/detail-section/detail-section.css +0 -1
- package/dist/ui/dialog/dialog.css +0 -1
- package/dist/ui/disclosure/disclosure.css +0 -1
- package/dist/ui/divider/divider.css +0 -1
- package/dist/ui/editable-cell/editable-cell.css +0 -1
- package/dist/ui/empty-state/empty-state.css +0 -1
- package/dist/ui/error-page/error-page.css +0 -1
- package/dist/ui/explorer-list-item/explorer-list-item.css +0 -1
- package/dist/ui/explorer-section/explorer-section.css +0 -1
- package/dist/ui/file-upload/file-upload.css +0 -1
- package/dist/ui/filter-tabs/filter-tabs.css +0 -1
- package/dist/ui/form-field/form-field.css +0 -1
- package/dist/ui/icon/icon.css +0 -1
- package/dist/ui/icon-button/icon-button.css +0 -1
- package/dist/ui/icon-tile/icon-tile.css +0 -1
- package/dist/ui/inline-action/inline-action.css +0 -1
- package/dist/ui/inline-filter/inline-filter.css +0 -1
- package/dist/ui/input/input.css +0 -1
- package/dist/ui/input-with-icon/input-with-icon.css +0 -1
- package/dist/ui/language-switcher/language-switcher.css +0 -1
- package/dist/ui/lifecycle-connector/lifecycle-connector.css +0 -1
- package/dist/ui/lifecycle-drop-slot/lifecycle-drop-slot.css +0 -1
- package/dist/ui/lifecycle-edge-label/lifecycle-edge-label.css +0 -1
- package/dist/ui/lifecycle-group-box/lifecycle-group-box.css +0 -1
- package/dist/ui/lifecycle-minimap/lifecycle-minimap.css +0 -1
- package/dist/ui/lifecycle-node-card/lifecycle-node-card.css +0 -1
- package/dist/ui/lifecycle-terminal/lifecycle-terminal.css +0 -1
- package/dist/ui/lifecycle-zoom-control/lifecycle-zoom-control.css +0 -1
- package/dist/ui/link/link.css +0 -1
- package/dist/ui/list/list-item-preview.cjs +9 -4
- package/dist/ui/list/list-item-preview.cjs.map +1 -1
- package/dist/ui/list/list-item-preview.d.ts.map +1 -1
- package/dist/ui/list/list-item-preview.js +10 -5
- package/dist/ui/list/list-item-preview.js.map +1 -1
- package/dist/ui/list/list.cjs +9 -1
- package/dist/ui/list/list.cjs.map +1 -1
- package/dist/ui/list/list.css +39 -1
- package/dist/ui/list/list.d.ts +32 -1
- package/dist/ui/list/list.d.ts.map +1 -1
- package/dist/ui/list/list.js +8 -1
- package/dist/ui/list/list.js.map +1 -1
- package/dist/ui/listbox/listbox.css +0 -1
- package/dist/ui/loader/loader.css +0 -1
- package/dist/ui/menu/menu.css +0 -1
- package/dist/ui/meta-row/meta-row.css +0 -1
- package/dist/ui/modal/modal.css +0 -1
- package/dist/ui/number-input/number-input.css +0 -1
- package/dist/ui/number-stepper/number-stepper.css +0 -1
- package/dist/ui/option-list/option-list.css +0 -1
- package/dist/ui/page-header/page-header.css +0 -1
- package/dist/ui/page-shell/page-shell.css +0 -1
- package/dist/ui/password-input/password-input.css +0 -1
- package/dist/ui/phone-input/phone-input.css +0 -1
- package/dist/ui/pill-select/pill-select.css +0 -1
- package/dist/ui/popover/popover.css +0 -1
- package/dist/ui/progress-bar/progress-bar.css +0 -1
- package/dist/ui/property-field/property-field.css +0 -1
- package/dist/ui/radio-group/radio-group.css +0 -1
- package/dist/ui/range-slider/range-slider.css +0 -1
- package/dist/ui/responsive-grid/responsive-grid.css +0 -1
- package/dist/ui/search-dropdown/search-dropdown.css +0 -1
- package/dist/ui/section-header/section-header.css +0 -1
- package/dist/ui/segment-card/segment-card.css +0 -1
- package/dist/ui/segment-row/segment-row.css +0 -1
- package/dist/ui/side-flexpane/side-flexpane.css +0 -1
- package/dist/ui/sidebar-nav-item/sidebar-nav-item.css +0 -1
- package/dist/ui/sidebar-nav-trigger/sidebar-nav-trigger.css +0 -1
- package/dist/ui/slider/slider.css +0 -1
- package/dist/ui/stack/stack.css +0 -1
- package/dist/ui/stat-card/stat-card.css +0 -1
- package/dist/ui/tabs/tabs.css +0 -1
- package/dist/ui/tabs-underline/tabs-underline.css +0 -1
- package/dist/ui/tag/tag.css +0 -1
- package/dist/ui/thumbnail/thumbnail.css +0 -1
- package/dist/ui/time-input/time-input.css +0 -1
- package/dist/ui/timeline-entry/timeline-entry.css +0 -1
- package/dist/ui/toast/toast.css +0 -1
- package/dist/ui/toggle-switch/toggle-switch.css +0 -1
- package/dist/ui/tooltip/tooltip.css +0 -1
- package/dist/ui/type-overview-card/type-overview-card.css +0 -1
- package/dist/ui/view-switcher/view-switcher.css +0 -1
- package/package.json +3 -1
package/dist/ui/list/list.css
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
@charset "UTF-8";
|
|
2
1
|
/* ── list ── */
|
|
3
2
|
.uxm-list {
|
|
4
3
|
background-color: var(--color-card);
|
|
@@ -56,6 +55,26 @@
|
|
|
56
55
|
which owns the accent-tile treatment. The studio icon knobs are forwarded
|
|
57
56
|
into IconTile's var namespace via `LIST_ITEM_ICON_TILE_STYLE`, so the tile
|
|
58
57
|
pattern is defined once instead of being re-implemented here. */
|
|
58
|
+
/* Media slot — the alternative leading position for a thumbnail / avatar /
|
|
59
|
+
bare <img>, rendered as-is (no IconTile, no accent fill, no colour of its
|
|
60
|
+
own: the media brings its own frame). The row still owns the geometry, so
|
|
61
|
+
every leading element lands on the same grid whichever slot filled it. */
|
|
62
|
+
}
|
|
63
|
+
.uxm-list-item__media {
|
|
64
|
+
align-items: center;
|
|
65
|
+
box-sizing: border-box;
|
|
66
|
+
display: inline-flex;
|
|
67
|
+
/* Never let a long title squeeze the media out of square. */
|
|
68
|
+
flex-shrink: 0;
|
|
69
|
+
height: var(--uxm-list-item-media-size, 36px);
|
|
70
|
+
justify-content: center;
|
|
71
|
+
width: var(--uxm-list-item-media-size, 36px);
|
|
72
|
+
/* Only for a bare <img> passed straight in — without this it would
|
|
73
|
+
stretch to the box. `Thumbnail`'s own `--cover` / `--contain` rule is
|
|
74
|
+
more specific, so its fit choice still wins. */
|
|
75
|
+
}
|
|
76
|
+
.uxm-list-item__media img {
|
|
77
|
+
object-fit: cover;
|
|
59
78
|
}
|
|
60
79
|
.uxm-list-item__content {
|
|
61
80
|
display: flex;
|
|
@@ -74,4 +93,23 @@
|
|
|
74
93
|
.uxm-list-item__trailing {
|
|
75
94
|
color: var(--uxm-list-item-chevron-color, var(--color-text-muted));
|
|
76
95
|
font-size: calc(12px * var(--type-scale, 1));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Media fallback stretch, at (0,2,0) on purpose — same reasoning as
|
|
99
|
+
`avatar.scss`'s double-class size presets: a single-class selector here
|
|
100
|
+
(`.uxm-list-item__media > *`) TIES with a child atom's own size rule
|
|
101
|
+
(`.uxm-thumbnail`, also 0,1,0) and then loses or wins on nothing but the
|
|
102
|
+
`styles.css` import order, which is alphabetical — `Avatar` (line 7) would
|
|
103
|
+
obey the slot and `Thumbnail` (line 94) would ignore it. Two classes settle
|
|
104
|
+
it for every child regardless of order. The slot is always rendered inside a
|
|
105
|
+
row, so the descendant selector costs nothing.
|
|
106
|
+
|
|
107
|
+
Atoms with a size var of their own are ALSO handled by the forwarding in
|
|
108
|
+
`LIST_ITEM_MEDIA_STYLE` (list.tsx) — that path is what makes their border /
|
|
109
|
+
radius / inner glyph scale with the row instead of merely being clamped to
|
|
110
|
+
its box. Both resolve to the same size; this rule is the floor for a bare
|
|
111
|
+
<img>, <svg>, or a consumer's own node. */
|
|
112
|
+
.uxm-list-item .uxm-list-item__media > * {
|
|
113
|
+
height: 100%;
|
|
114
|
+
width: 100%;
|
|
77
115
|
}
|
package/dist/ui/list/list.d.ts
CHANGED
|
@@ -8,6 +8,21 @@ import type { AnchorHTMLAttributes, ButtonHTMLAttributes, CSSProperties, HTMLAtt
|
|
|
8
8
|
* constant so the studio preview can reuse the exact same forwarding.
|
|
9
9
|
*/
|
|
10
10
|
export declare const LIST_ITEM_ICON_TILE_STYLE: CSSProperties;
|
|
11
|
+
/**
|
|
12
|
+
* Forward the row's media-size knob into the size vars of the atoms that
|
|
13
|
+
* plausibly fill the `media` slot, so each one sizes itself through its OWN
|
|
14
|
+
* machinery — frame, border, radius and inner glyph / initials all scale with
|
|
15
|
+
* it — instead of being stretched from the outside. Mirrors
|
|
16
|
+
* `LIST_ITEM_ICON_TILE_STYLE` above, and is the only order-independent fix:
|
|
17
|
+
* both `Thumbnail` (`.uxm-thumbnail`, 0,1,0 but imported AFTER list in
|
|
18
|
+
* `styles.css`) and `Avatar` (double-class size presets at 0,2,0, deliberately
|
|
19
|
+
* so per its own note) would otherwise win or lose the cascade against a slot
|
|
20
|
+
* rule purely on stylesheet order. The generic `> *` stretch in `list.scss`
|
|
21
|
+
* stays as the fallback for a bare `<img>` / `<svg>` or any atom with no size
|
|
22
|
+
* var of its own; both mechanisms resolve to the same number. Kept as a module
|
|
23
|
+
* constant so the studio preview can reuse the exact same forwarding.
|
|
24
|
+
*/
|
|
25
|
+
export declare const LIST_ITEM_MEDIA_STYLE: CSSProperties;
|
|
11
26
|
export interface ListProps extends HTMLAttributes<HTMLDivElement> {
|
|
12
27
|
children: ReactNode;
|
|
13
28
|
}
|
|
@@ -25,6 +40,22 @@ export declare function List({ children, className, ...rest }: ListProps): impor
|
|
|
25
40
|
export interface ListItemProps {
|
|
26
41
|
/** Leading icon — typically <Icon ... /> from @modo/uxm/ui. */
|
|
27
42
|
icon?: ReactNode;
|
|
43
|
+
/** Leading media rendered as-is (a <Thumbnail>, <img>, avatar…) — NOT
|
|
44
|
+
* wrapped in the accent `IconTile` the `icon` slot uses. Mutually
|
|
45
|
+
* exclusive with `icon`: when both are passed, `media` wins. The slot
|
|
46
|
+
* box is `--uxm-list-item-media-size` (36px) square; a `Thumbnail` or
|
|
47
|
+
* `Avatar` gets that size forwarded into its own size var (see
|
|
48
|
+
* `LIST_ITEM_MEDIA_STYLE`) and anything else is stretched to fill, so
|
|
49
|
+
* rows stay on one leading grid either way.
|
|
50
|
+
*
|
|
51
|
+
* Prefer decorative media in a row whose title already names the thing
|
|
52
|
+
* (`alt=""`): the slot sits INSIDE the row's `<button>`/`<a>`, so a
|
|
53
|
+
* described image is concatenated into the row's accessible name.
|
|
54
|
+
*
|
|
55
|
+
* Note: this shadows the native `media` attribute of `<a>` for the
|
|
56
|
+
* anchor form of the row — pass it through `className`/a wrapper if
|
|
57
|
+
* you genuinely need the HTML attribute. */
|
|
58
|
+
media?: ReactNode;
|
|
28
59
|
/** Secondary text shown under the title (e.g. a value). */
|
|
29
60
|
value?: ReactNode;
|
|
30
61
|
/** Trailing content — meta text, chevron icon, or a custom node. */
|
|
@@ -49,6 +80,6 @@ export interface ListItemProps {
|
|
|
49
80
|
type AnchorRest = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, keyof ListItemProps>;
|
|
50
81
|
type ButtonRest = Omit<ButtonHTMLAttributes<HTMLButtonElement>, keyof ListItemProps>;
|
|
51
82
|
type DivRest = Omit<HTMLAttributes<HTMLDivElement>, keyof ListItemProps>;
|
|
52
|
-
export declare function ListItem({ icon, value, trailing, children, interactive, active, disabled, href, className, ...rest }: ListItemProps & (AnchorRest | ButtonRest | DivRest)): import("react").JSX.Element;
|
|
83
|
+
export declare function ListItem({ icon, media, value, trailing, children, interactive, active, disabled, href, className, ...rest }: ListItemProps & (AnchorRest | ButtonRest | DivRest)): import("react").JSX.Element;
|
|
53
84
|
export {};
|
|
54
85
|
//# sourceMappingURL=list.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/ui/list/list.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,SAAS,EACV,MAAM,OAAO,CAAC;AAEf;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAMjC,aAAa,CAAC;AAEnB,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,cAAc,CAAC;IAC/D,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,IAAI,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,+BAM/D;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,qBAAqB;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB;;0DAEsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;sEACkE;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;yCAEqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,KAAK,UAAU,GAAG,IAAI,CACpB,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,MAAM,aAAa,CACpB,CAAC;AACF,KAAK,UAAU,GAAG,IAAI,CACpB,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,MAAM,aAAa,CACpB,CAAC;AACF,KAAK,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,aAAa,CAAC,CAAC;AAEzE,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,GAAG,IAAI,EACR,EAAE,aAAa,GAAG,CAAC,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,+
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/ui/list/list.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,SAAS,EACV,MAAM,OAAO,CAAC;AAEf;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAMjC,aAAa,CAAC;AAEnB;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,EAI7B,aAAa,CAAC;AAEnB,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,cAAc,CAAC;IAC/D,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,IAAI,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,+BAM/D;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;;;;;;;;;;iDAc6C;IAC7C,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,qBAAqB;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB;;0DAEsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;sEACkE;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;yCAEqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,KAAK,UAAU,GAAG,IAAI,CACpB,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,MAAM,aAAa,CACpB,CAAC;AACF,KAAK,UAAU,GAAG,IAAI,CACpB,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,MAAM,aAAa,CACpB,CAAC;AACF,KAAK,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,aAAa,CAAC,CAAC;AAEzE,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,GAAG,IAAI,EACR,EAAE,aAAa,GAAG,CAAC,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,+BAoErD"}
|
package/dist/ui/list/list.js
CHANGED
|
@@ -8,11 +8,17 @@ const LIST_ITEM_ICON_TILE_STYLE = {
|
|
|
8
8
|
"--uxm-icon-tile-radius": "var(--uxm-list-item-icon-radius, 6px)",
|
|
9
9
|
"--uxm-icon-tile-icon-size": "calc(var(--uxm-list-item-icon-size, 24px) * 0.6)"
|
|
10
10
|
};
|
|
11
|
+
const LIST_ITEM_MEDIA_STYLE = {
|
|
12
|
+
"--uxm-thumbnail-size": "var(--uxm-list-item-media-size, 36px)",
|
|
13
|
+
"--uxm-avatar-size": "var(--uxm-list-item-media-size, 36px)",
|
|
14
|
+
"--uxm-avatar-small-size": "var(--uxm-list-item-media-size, 36px)"
|
|
15
|
+
};
|
|
11
16
|
function List({ children, className, ...rest }) {
|
|
12
17
|
return /* @__PURE__ */ jsx("div", { className: cn("uxm-list", className), ...rest, children });
|
|
13
18
|
}
|
|
14
19
|
function ListItem({
|
|
15
20
|
icon,
|
|
21
|
+
media,
|
|
16
22
|
value,
|
|
17
23
|
trailing,
|
|
18
24
|
children,
|
|
@@ -30,7 +36,7 @@ function ListItem({
|
|
|
30
36
|
);
|
|
31
37
|
const isInteractive = interactive || href !== void 0;
|
|
32
38
|
const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
33
|
-
icon && /* @__PURE__ */ jsx(IconTile, { className: "uxm-list-item__icon", style: LIST_ITEM_ICON_TILE_STYLE, children: icon }),
|
|
39
|
+
media ? /* @__PURE__ */ jsx("span", { className: "uxm-list-item__media", style: LIST_ITEM_MEDIA_STYLE, children: media }) : icon && /* @__PURE__ */ jsx(IconTile, { className: "uxm-list-item__icon", style: LIST_ITEM_ICON_TILE_STYLE, children: icon }),
|
|
34
40
|
/* @__PURE__ */ jsxs("span", { className: "uxm-list-item__content", children: [
|
|
35
41
|
/* @__PURE__ */ jsx("span", { className: "uxm-list-item__title", children }),
|
|
36
42
|
value !== void 0 && value !== null && /* @__PURE__ */ jsx("span", { className: "uxm-list-item__value", children: value })
|
|
@@ -74,6 +80,7 @@ function ListItem({
|
|
|
74
80
|
}
|
|
75
81
|
export {
|
|
76
82
|
LIST_ITEM_ICON_TILE_STYLE,
|
|
83
|
+
LIST_ITEM_MEDIA_STYLE,
|
|
77
84
|
List,
|
|
78
85
|
ListItem
|
|
79
86
|
};
|
package/dist/ui/list/list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/ui/list/list.tsx"],"sourcesContent":["import { cn } from '@/helpers';\n\nimport { IconTile } from '../icon-tile';\n\nimport type {\n AnchorHTMLAttributes,\n ButtonHTMLAttributes,\n CSSProperties,\n HTMLAttributes,\n ReactNode,\n} from 'react';\n\n/**\n * Forward the studio icon knobs (projected as `--uxm-list-item-icon-*` on the\n * row) into the `IconTile` atom's own var namespace, so the accent-tile\n * pattern lives in one place — the `IconTile` atom — instead of being\n * re-implemented in `list.scss`. The glyph tracks the tile at 0.6× (the\n * row-icon proportion used across the design system). Kept as a module\n * constant so the studio preview can reuse the exact same forwarding.\n */\nexport const LIST_ITEM_ICON_TILE_STYLE = {\n '--uxm-icon-tile-bg': 'var(--uxm-list-item-icon-bg, var(--color-accent))',\n '--uxm-icon-tile-color': 'var(--uxm-list-item-icon-color, var(--color-card))',\n '--uxm-icon-tile-size': 'var(--uxm-list-item-icon-size, 24px)',\n '--uxm-icon-tile-radius': 'var(--uxm-list-item-icon-radius, 6px)',\n '--uxm-icon-tile-icon-size': 'calc(var(--uxm-list-item-icon-size, 24px) * 0.6)',\n} as CSSProperties;\n\nexport interface ListProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nexport function List({ children, className, ...rest }: ListProps) {\n return (\n <div className={cn('uxm-list', className)} {...rest}>\n {children}\n </div>\n );\n}\n\n/**\n * ListItem renders as one of three element types depending on `interactive`:\n * - `<div>` (default) — display row, no state styling, not focusable\n * - `<button>` — interactive without navigation; emits click events\n * - `<a>` — interactive with navigation; pass `href`\n *\n * The state knobs (hover / focus / active / disabled) in the `list-item`\n * registry only paint when the row renders as button or anchor — the CSS\n * scopes them to element-type selectors so display-only divs stay inert.\n */\nexport interface ListItemProps {\n /** Leading icon — typically <Icon ... /> from @modo/uxm/ui. */\n icon?: ReactNode;\n /** Secondary text shown under the title (e.g. a value). */\n value?: ReactNode;\n /** Trailing content — meta text, chevron icon, or a custom node. */\n trailing?: ReactNode;\n /** Primary label. */\n children: ReactNode;\n /** Render as a clickable element. When false (default), renders as a\n * static `<div>` with no state styling. When true, renders as\n * `<button>` (or `<a>` if `href` is also passed). */\n interactive?: boolean;\n /** Show the selected/active treatment (only meaningful when\n * `interactive` is true). Adds the `--active` modifier class. */\n active?: boolean;\n /** Disable interaction — only meaningful when `interactive`.\n * Forwards to the native `disabled` attribute on `<button>`, or\n * sets `aria-disabled` on `<a>`. */\n disabled?: boolean;\n /** Navigate to this URL on click. Implies `interactive`. */\n href?: string;\n className?: string;\n}\n\ntype AnchorRest = Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n keyof ListItemProps\n>;\ntype ButtonRest = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n keyof ListItemProps\n>;\ntype DivRest = Omit<HTMLAttributes<HTMLDivElement>, keyof ListItemProps>;\n\nexport function ListItem({\n icon,\n value,\n trailing,\n children,\n interactive,\n active,\n disabled,\n href,\n className,\n ...rest\n}: ListItemProps & (AnchorRest | ButtonRest | DivRest)) {\n const classes = cn(\n 'uxm-list-item',\n active && 'uxm-list-item--active',\n className,\n );\n const isInteractive = interactive || href !== undefined;\n const inner = (\n <>\n {icon
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/list/list.tsx"],"sourcesContent":["import { cn } from '@/helpers';\n\nimport { IconTile } from '../icon-tile';\n\nimport type {\n AnchorHTMLAttributes,\n ButtonHTMLAttributes,\n CSSProperties,\n HTMLAttributes,\n ReactNode,\n} from 'react';\n\n/**\n * Forward the studio icon knobs (projected as `--uxm-list-item-icon-*` on the\n * row) into the `IconTile` atom's own var namespace, so the accent-tile\n * pattern lives in one place — the `IconTile` atom — instead of being\n * re-implemented in `list.scss`. The glyph tracks the tile at 0.6× (the\n * row-icon proportion used across the design system). Kept as a module\n * constant so the studio preview can reuse the exact same forwarding.\n */\nexport const LIST_ITEM_ICON_TILE_STYLE = {\n '--uxm-icon-tile-bg': 'var(--uxm-list-item-icon-bg, var(--color-accent))',\n '--uxm-icon-tile-color': 'var(--uxm-list-item-icon-color, var(--color-card))',\n '--uxm-icon-tile-size': 'var(--uxm-list-item-icon-size, 24px)',\n '--uxm-icon-tile-radius': 'var(--uxm-list-item-icon-radius, 6px)',\n '--uxm-icon-tile-icon-size': 'calc(var(--uxm-list-item-icon-size, 24px) * 0.6)',\n} as CSSProperties;\n\n/**\n * Forward the row's media-size knob into the size vars of the atoms that\n * plausibly fill the `media` slot, so each one sizes itself through its OWN\n * machinery — frame, border, radius and inner glyph / initials all scale with\n * it — instead of being stretched from the outside. Mirrors\n * `LIST_ITEM_ICON_TILE_STYLE` above, and is the only order-independent fix:\n * both `Thumbnail` (`.uxm-thumbnail`, 0,1,0 but imported AFTER list in\n * `styles.css`) and `Avatar` (double-class size presets at 0,2,0, deliberately\n * so per its own note) would otherwise win or lose the cascade against a slot\n * rule purely on stylesheet order. The generic `> *` stretch in `list.scss`\n * stays as the fallback for a bare `<img>` / `<svg>` or any atom with no size\n * var of its own; both mechanisms resolve to the same number. Kept as a module\n * constant so the studio preview can reuse the exact same forwarding.\n */\nexport const LIST_ITEM_MEDIA_STYLE = {\n '--uxm-thumbnail-size': 'var(--uxm-list-item-media-size, 36px)',\n '--uxm-avatar-size': 'var(--uxm-list-item-media-size, 36px)',\n '--uxm-avatar-small-size': 'var(--uxm-list-item-media-size, 36px)',\n} as CSSProperties;\n\nexport interface ListProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nexport function List({ children, className, ...rest }: ListProps) {\n return (\n <div className={cn('uxm-list', className)} {...rest}>\n {children}\n </div>\n );\n}\n\n/**\n * ListItem renders as one of three element types depending on `interactive`:\n * - `<div>` (default) — display row, no state styling, not focusable\n * - `<button>` — interactive without navigation; emits click events\n * - `<a>` — interactive with navigation; pass `href`\n *\n * The state knobs (hover / focus / active / disabled) in the `list-item`\n * registry only paint when the row renders as button or anchor — the CSS\n * scopes them to element-type selectors so display-only divs stay inert.\n */\nexport interface ListItemProps {\n /** Leading icon — typically <Icon ... /> from @modo/uxm/ui. */\n icon?: ReactNode;\n /** Leading media rendered as-is (a <Thumbnail>, <img>, avatar…) — NOT\n * wrapped in the accent `IconTile` the `icon` slot uses. Mutually\n * exclusive with `icon`: when both are passed, `media` wins. The slot\n * box is `--uxm-list-item-media-size` (36px) square; a `Thumbnail` or\n * `Avatar` gets that size forwarded into its own size var (see\n * `LIST_ITEM_MEDIA_STYLE`) and anything else is stretched to fill, so\n * rows stay on one leading grid either way.\n *\n * Prefer decorative media in a row whose title already names the thing\n * (`alt=\"\"`): the slot sits INSIDE the row's `<button>`/`<a>`, so a\n * described image is concatenated into the row's accessible name.\n *\n * Note: this shadows the native `media` attribute of `<a>` for the\n * anchor form of the row — pass it through `className`/a wrapper if\n * you genuinely need the HTML attribute. */\n media?: ReactNode;\n /** Secondary text shown under the title (e.g. a value). */\n value?: ReactNode;\n /** Trailing content — meta text, chevron icon, or a custom node. */\n trailing?: ReactNode;\n /** Primary label. */\n children: ReactNode;\n /** Render as a clickable element. When false (default), renders as a\n * static `<div>` with no state styling. When true, renders as\n * `<button>` (or `<a>` if `href` is also passed). */\n interactive?: boolean;\n /** Show the selected/active treatment (only meaningful when\n * `interactive` is true). Adds the `--active` modifier class. */\n active?: boolean;\n /** Disable interaction — only meaningful when `interactive`.\n * Forwards to the native `disabled` attribute on `<button>`, or\n * sets `aria-disabled` on `<a>`. */\n disabled?: boolean;\n /** Navigate to this URL on click. Implies `interactive`. */\n href?: string;\n className?: string;\n}\n\ntype AnchorRest = Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n keyof ListItemProps\n>;\ntype ButtonRest = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n keyof ListItemProps\n>;\ntype DivRest = Omit<HTMLAttributes<HTMLDivElement>, keyof ListItemProps>;\n\nexport function ListItem({\n icon,\n media,\n value,\n trailing,\n children,\n interactive,\n active,\n disabled,\n href,\n className,\n ...rest\n}: ListItemProps & (AnchorRest | ButtonRest | DivRest)) {\n const classes = cn(\n 'uxm-list-item',\n active && 'uxm-list-item--active',\n className,\n );\n const isInteractive = interactive || href !== undefined;\n const inner = (\n <>\n {/* Leading slot. `media` renders as-is so a product photo / avatar\n keeps its own frame; `icon` keeps the accent IconTile treatment.\n `media` wins when both are passed — a row has one leading grid\n position, and the as-is rendering is the more specific intent. */}\n {media ? (\n <span className=\"uxm-list-item__media\" style={LIST_ITEM_MEDIA_STYLE}>\n {media}\n </span>\n ) : (\n icon && (\n <IconTile className=\"uxm-list-item__icon\" style={LIST_ITEM_ICON_TILE_STYLE}>\n {icon}\n </IconTile>\n )\n )}\n <span className=\"uxm-list-item__content\">\n <span className=\"uxm-list-item__title\">{children}</span>\n {value !== undefined && value !== null && (\n <span className=\"uxm-list-item__value\">{value}</span>\n )}\n </span>\n {trailing && <span className=\"uxm-list-item__trailing\">{trailing}</span>}\n </>\n );\n\n if (href !== undefined) {\n return (\n <a\n href={href}\n className={classes}\n {...(disabled ? { 'aria-disabled': true as const, tabIndex: -1 } : {})}\n {...(rest as AnchorRest)}\n >\n {inner}\n </a>\n );\n }\n if (isInteractive) {\n return (\n <button\n type=\"button\"\n className={classes}\n disabled={disabled}\n aria-pressed={active}\n {...(rest as ButtonRest)}\n >\n {inner}\n </button>\n );\n }\n return (\n <div\n className={classes}\n {...(disabled ? { 'aria-disabled': true as const } : {})}\n {...(rest as DivRest)}\n >\n {inner}\n </div>\n );\n}\n"],"mappings":"AAsDI,SAuFA,UAvFA,KAuGE,YAvGF;AAtDJ,SAAS,UAAU;AAEnB,SAAS,gBAAgB;AAkBlB,MAAM,4BAA4B;AAAA,EACvC,sBAAsB;AAAA,EACtB,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,6BAA6B;AAC/B;AAgBO,MAAM,wBAAwB;AAAA,EACnC,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,2BAA2B;AAC7B;AAMO,SAAS,KAAK,EAAE,UAAU,WAAW,GAAG,KAAK,GAAc;AAChE,SACE,oBAAC,SAAI,WAAW,GAAG,YAAY,SAAS,GAAI,GAAG,MAC5C,UACH;AAEJ;AA+DO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAwD;AACtD,QAAM,UAAU;AAAA,IACd;AAAA,IACA,UAAU;AAAA,IACV;AAAA,EACF;AACA,QAAM,gBAAgB,eAAe,SAAS;AAC9C,QAAM,QACJ,iCAKG;AAAA,YACC,oBAAC,UAAK,WAAU,wBAAuB,OAAO,uBAC3C,iBACH,IAEA,QACE,oBAAC,YAAS,WAAU,uBAAsB,OAAO,2BAC9C,gBACH;AAAA,IAGJ,qBAAC,UAAK,WAAU,0BACd;AAAA,0BAAC,UAAK,WAAU,wBAAwB,UAAS;AAAA,MAChD,UAAU,UAAa,UAAU,QAChC,oBAAC,UAAK,WAAU,wBAAwB,iBAAM;AAAA,OAElD;AAAA,IACC,YAAY,oBAAC,UAAK,WAAU,2BAA2B,oBAAS;AAAA,KACnE;AAGF,MAAI,SAAS,QAAW;AACtB,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,QACV,GAAI,WAAW,EAAE,iBAAiB,MAAe,UAAU,GAAG,IAAI,CAAC;AAAA,QACnE,GAAI;AAAA,QAEJ;AAAA;AAAA,IACH;AAAA,EAEJ;AACA,MAAI,eAAe;AACjB,WACE;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAW;AAAA,QACX;AAAA,QACA,gBAAc;AAAA,QACb,GAAI;AAAA,QAEJ;AAAA;AAAA,IACH;AAAA,EAEJ;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,MACV,GAAI,WAAW,EAAE,iBAAiB,KAAc,IAAI,CAAC;AAAA,MACrD,GAAI;AAAA,MAEJ;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
package/dist/ui/menu/menu.css
CHANGED
package/dist/ui/modal/modal.css
CHANGED
package/dist/ui/stack/stack.css
CHANGED
package/dist/ui/tabs/tabs.css
CHANGED
package/dist/ui/tag/tag.css
CHANGED
package/dist/ui/toast/toast.css
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viax.io/uxm",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.41.0",
|
|
4
4
|
"description": "Viax UXM — React 19 UI primitives and design tokens.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
"check:drift": "node scripts/check-state-var-drift.mjs && npm run check:type-scale && npm run check:tokens",
|
|
70
70
|
"test": "vitest run",
|
|
71
71
|
"test:watch": "vitest",
|
|
72
|
+
"test:coverage": "vitest run --coverage",
|
|
72
73
|
"test:ci": "vitest run --reporter=default --reporter=junit --outputFile=junit-report.xml",
|
|
73
74
|
"audit:report": "npm audit --registry=https://registry.npmjs.org",
|
|
74
75
|
"audit:ci": "npm audit --registry=https://registry.npmjs.org --audit-level=critical",
|
|
@@ -112,6 +113,7 @@
|
|
|
112
113
|
"@types/react": "^19.0.0",
|
|
113
114
|
"@types/react-dom": "^19.0.0",
|
|
114
115
|
"@vitejs/plugin-react": "^6.1.1",
|
|
116
|
+
"@vitest/coverage-v8": "^5.0.0",
|
|
115
117
|
"axe-core": "^4.13.0",
|
|
116
118
|
"commitizen": "^4.3.1",
|
|
117
119
|
"cz-conventional-changelog": "^3.3.0",
|