@viraui/react 0.0.18 → 0.0.20
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/catalog.json +18 -0
- package/dist/components/avatar/avatar.css +1 -1
- package/dist/components/avatar/avatar.d.ts +1 -1
- package/dist/components/avatar/avatar.js +2 -0
- package/dist/components/avatar-group/avatar-group.css +1 -0
- package/dist/components/avatar-group/avatar-group.d.ts +55 -0
- package/dist/components/avatar-group/avatar-group.guide.json +22 -0
- package/dist/components/avatar-group/avatar-group.js +61 -0
- package/dist/components/avatar-group/avatar-group.module.js +9 -0
- package/dist/components/avatar-group/index.d.ts +2 -0
- package/dist/components/checkbox/checkbox.css +1 -1
- package/dist/components/checkbox/checkbox.js +1 -1
- package/dist/components/chip/chip.css +1 -0
- package/dist/components/chip/chip.d.ts +46 -0
- package/dist/components/chip/chip.guide.json +26 -0
- package/dist/components/chip/chip.js +48 -0
- package/dist/components/chip/chip.module.js +8 -0
- package/dist/components/chip/index.d.ts +2 -0
- package/dist/components/icon/icon.css +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/linear-progress/linear-progress.js +1 -1
- package/dist/components/masonry/index.d.ts +2 -0
- package/dist/components/masonry/masonry-item.d.ts +32 -0
- package/dist/components/masonry/masonry-item.js +22 -0
- package/dist/components/masonry/masonry.css +1 -0
- package/dist/components/masonry/masonry.d.ts +67 -0
- package/dist/components/masonry/masonry.guide.json +24 -0
- package/dist/components/masonry/masonry.js +38 -0
- package/dist/components/masonry/masonry.module.js +6 -0
- package/dist/components/radio/radio-group.js +1 -1
- package/dist/components/radio/radio.css +1 -1
- package/dist/components/radio/radio.js +1 -1
- package/dist/components/select/select-group.js +1 -1
- package/dist/components/select/select-option.js +1 -1
- package/dist/components/select/select.css +1 -1
- package/dist/components/select/select.guide.json +5 -1
- package/dist/components/select/select.js +6 -3
- package/dist/components/slider/slider.js +1 -1
- package/dist/components/surface/surface.css +1 -1
- package/dist/components/surface/surface.js +1 -1
- package/dist/components/switch/switch.css +1 -1
- package/dist/components/switch/switch.js +2 -1
- package/dist/components/textarea/textarea.js +1 -1
- package/dist/components/textfield/textfield.js +1 -1
- package/dist/components/title/title.d.ts +5 -2
- package/dist/components/title/title.guide.json +5 -2
- package/dist/core/props/intrinsic-vira-props.d.ts +7 -0
- package/dist/core/props/intrinsic-vira-props.js +3 -2
- package/dist/core/theme/resolve-theme-value.d.ts +3 -4
- package/dist/core/theme/resolve-theme-value.js +1 -2
- package/dist/index.js +6 -3
- package/dist/internal-icons/icon-registry.d.ts +4 -1
- package/dist/internal-icons/icon-registry.js +9 -0
- package/dist/internal-icons/icons/duo/ArrowDown.js +1 -1
- package/dist/internal-icons/icons/duo/ArrowDownLeft.js +1 -1
- package/dist/internal-icons/icons/duo/ArrowDownRight.js +1 -1
- package/dist/internal-icons/icons/duo/ArrowLeft.js +1 -1
- package/dist/internal-icons/icons/duo/ArrowRight.js +1 -1
- package/dist/internal-icons/icons/duo/ArrowUp.js +1 -1
- package/dist/internal-icons/icons/duo/ArrowUpLeft.js +1 -1
- package/dist/internal-icons/icons/duo/ArrowUpRight.js +1 -1
- package/dist/internal-icons/icons/duo/CaretDown.js +1 -1
- package/dist/internal-icons/icons/duo/CaretLeft.js +1 -1
- package/dist/internal-icons/icons/duo/CaretRight.js +1 -1
- package/dist/internal-icons/icons/duo/CaretUp.js +1 -1
- package/dist/internal-icons/icons/duo/ChevronExpandY.js +1 -1
- package/dist/internal-icons/icons/duo/CircleHalfDottedClock.js +1 -1
- package/dist/internal-icons/icons/duo/CircleImage.d.ts +7 -0
- package/dist/internal-icons/icons/duo/CircleImage.js +13 -0
- package/dist/internal-icons/icons/duo/Clock.js +1 -1
- package/dist/internal-icons/icons/duo/DarkLight.js +1 -1
- package/dist/internal-icons/icons/duo/History.js +1 -1
- package/dist/internal-icons/icons/duo/Image.d.ts +7 -0
- package/dist/internal-icons/icons/duo/Image.js +13 -0
- package/dist/internal-icons/icons/duo/ImagesLayered.d.ts +7 -0
- package/dist/internal-icons/icons/duo/ImagesLayered.js +13 -0
- package/dist/internal-icons/icons/duo/Lock.js +1 -1
- package/dist/internal-icons/icons/duo/LockOpen.js +1 -1
- package/dist/internal-icons/icons/duo/Magnifier.js +1 -1
- package/dist/internal-icons/icons/duo/MoonStars.js +1 -1
- package/dist/internal-icons/icons/duo/Quickstart.js +1 -1
- package/dist/internal-icons/icons/duo/RefreshAnticlockwise.js +1 -1
- package/dist/internal-icons/icons/duo/Sun.js +1 -1
- package/dist/internal-icons/icons/duo/index.d.ts +3 -0
- package/dist/internal-icons/icons/duo/index.js +3 -0
- package/dist/preflight.css +1 -1
- package/dist/theme-surface.json +5 -0
- package/package.json +2 -2
package/dist/catalog.json
CHANGED
|
@@ -8,6 +8,18 @@
|
|
|
8
8
|
"summary": "Circular identity image or fallback for users, entities, or profile chips.",
|
|
9
9
|
"guidePath": "./components/avatar/avatar.guide.json"
|
|
10
10
|
},
|
|
11
|
+
{
|
|
12
|
+
"id": "avatar-group",
|
|
13
|
+
"name": "AvatarGroup",
|
|
14
|
+
"summary": "Overlapping avatar stack with shared sizing, directional layout, and an optional overflow pill.",
|
|
15
|
+
"guidePath": "./components/avatar-group/avatar-group.guide.json"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "chip",
|
|
19
|
+
"name": "Chip",
|
|
20
|
+
"summary": "Compact visual label primitive for short status, category, or metadata treatments.",
|
|
21
|
+
"guidePath": "./components/chip/chip.guide.json"
|
|
22
|
+
},
|
|
11
23
|
{
|
|
12
24
|
"id": "clamp-text",
|
|
13
25
|
"name": "ClampText",
|
|
@@ -38,6 +50,12 @@
|
|
|
38
50
|
"summary": "Shows determinate or indeterminate progress for a task in a compact horizontal track.",
|
|
39
51
|
"guidePath": "./components/linear-progress/linear-progress.guide.json"
|
|
40
52
|
},
|
|
53
|
+
{
|
|
54
|
+
"id": "masonry",
|
|
55
|
+
"name": "Masonry",
|
|
56
|
+
"summary": "Multi-column layout primitive for read-only mixed-height content walls.",
|
|
57
|
+
"guidePath": "./components/masonry/masonry.guide.json"
|
|
58
|
+
},
|
|
41
59
|
{
|
|
42
60
|
"id": "textfield",
|
|
43
61
|
"name": "Textfield",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.avatar-module_Avatar_BRuS3{--avatar-size:var(--space-2x-large);--avatar-background:var(--global-contrast);--avatar-foreground:var(--global-foreground);display:inline-flex;align-items:center;justify-content:center;inline-size:var(--avatar-size);block-size:var(--avatar-size);min-inline-size:var(--avatar-size);min-block-size:var(--avatar-size);overflow:hidden;border-radius:var(--radius
|
|
1
|
+
.avatar-module_Avatar_BRuS3{--avatar-size:var(--space-2x-large);--avatar-background:var(--global-contrast);--avatar-foreground:var(--global-foreground);--avatar-radius:var(--radius-infinite);display:inline-flex;align-items:center;justify-content:center;inline-size:var(--avatar-size);block-size:var(--avatar-size);min-inline-size:var(--avatar-size);min-block-size:var(--avatar-size);overflow:hidden;border-radius:var(--avatar-radius);background:var(--avatar-background);color:var(--avatar-foreground);vertical-align:middle;-webkit-user-select:none;user-select:none;container-name:viraui-avatar;container-type:inline-size;&[data-size=x-small]{--avatar-size:var(--space-large)}&[data-size=small]{--avatar-size:var(--space-2x-large)}&[data-size=regular]{--avatar-size:var(--space-wide)}&[data-size=big]{--avatar-size:var(--space-2x-wide)}}.avatar-module_Image_Q7bHi{inline-size:100%;block-size:100%;display:block;object-fit:cover}.avatar-module_Label_QASTF{font-size:30cqw}
|
|
@@ -8,7 +8,7 @@ import type * as React from 'react';
|
|
|
8
8
|
*
|
|
9
9
|
* @default Native span pass-through props keep React defaults.
|
|
10
10
|
*/
|
|
11
|
-
export type AvatarProps = React.
|
|
11
|
+
export type AvatarProps = React.ComponentPropsWithRef<'span'> & IntrinsicViraProps & {
|
|
12
12
|
/**
|
|
13
13
|
* Supplies the avatar image source URL.
|
|
14
14
|
*
|
|
@@ -25,6 +25,8 @@ var Avatar$1 = ({ alt = "", className, fallback, loading = false, ref, size = "s
|
|
|
25
25
|
"data-has-image": hasImage ? "true" : "false",
|
|
26
26
|
"data-loading": loading ? "true" : "false",
|
|
27
27
|
"data-size": size,
|
|
28
|
+
"data-grow": false,
|
|
29
|
+
"data-shrink": false,
|
|
28
30
|
children: loading ? /* @__PURE__ */ jsx(Skeleton, {
|
|
29
31
|
minHeight: "100%",
|
|
30
32
|
minWidth: "100%",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.avatar-group-module_AvatarGroup_zOrR-{--avatar-size:var(--space-2x-large);--avatar-overlap-distance:var(--space-medium);--avatar-group-gap-size:var(--space-x-small);--avatar-mask-anti-alias-size:0.5px;--avatar-mask-radius:calc((var(--avatar-size) / 2) + var(--avatar-group-gap-size));display:inline-flex;flex-wrap:nowrap;align-items:flex-start;min-inline-size:max-content;vertical-align:middle;&[data-direction=horizontal]{flex-direction:row}&[data-direction=vertical]{flex-direction:column}&[data-size=x-small]{--avatar-size:var(--space-large);--avatar-overlap-distance:var(--space-x-small)}&[data-size=small]{--avatar-size:var(--space-2x-large);--avatar-overlap-distance:var(--space-small)}&[data-size=regular]{--avatar-size:var(--space-wide);--avatar-overlap-distance:var(--space-medium)}&[data-size=big]{--avatar-size:var(--space-2x-wide);--avatar-overlap-distance:var(--space-large)}}.avatar-group-module_AvatarWrapper_0opqY{position:relative;display:inline-flex;flex:0 0 auto;inline-size:var(--avatar-size);block-size:var(--avatar-size);.avatar-group-module_AvatarGroup_zOrR-[data-direction=horizontal] &:not(:first-child){margin-inline-start:calc(var(--avatar-overlap-distance) * -1)}.avatar-group-module_AvatarGroup_zOrR-[data-direction=vertical] &:not(:first-child){margin-block-start:calc(var(--avatar-overlap-distance) * -1)}.avatar-group-module_AvatarGroup_zOrR-:dir(ltr)[data-direction=horizontal] &:not(:last-child){mask-image:radial-gradient(circle var(--avatar-mask-radius) at calc(100% + (var(--avatar-size) / 2) - var(--avatar-overlap-distance)) 50%,transparent calc(var(--avatar-mask-radius) - var(--avatar-mask-anti-alias-size)),#000 calc(var(--avatar-mask-radius) + var(--avatar-mask-anti-alias-size)))}.avatar-group-module_AvatarGroup_zOrR-:dir(rtl)[data-direction=horizontal] &:not(:last-child){mask-image:radial-gradient(circle var(--avatar-mask-radius) at calc((var(--avatar-size) / 2) - var(--avatar-overlap-distance)) 50%,transparent calc(var(--avatar-mask-radius) - var(--avatar-mask-anti-alias-size)),#000 calc(var(--avatar-mask-radius) + var(--avatar-mask-anti-alias-size)))}.avatar-group-module_AvatarGroup_zOrR-[data-direction=vertical] &:not(:last-child){mask-image:radial-gradient(circle var(--avatar-mask-radius) at 50% calc(100% + (var(--avatar-size) / 2) - var(--avatar-overlap-distance)),transparent calc(var(--avatar-mask-radius) - var(--avatar-mask-anti-alias-size)),#000 calc(var(--avatar-mask-radius) + var(--avatar-mask-anti-alias-size)))}}.avatar-group-module_OverflowWrapper_bKv6I{inline-size:auto;min-inline-size:var(--avatar-size)}.avatar-group-module_AvatarGroupItem_Vvlyh{--avatar-radius:100%;corner-shape:unset}.avatar-group-module_OverflowPill_nMmTD{display:inline-flex;align-items:center;justify-content:center;min-inline-size:var(--avatar-size);block-size:var(--avatar-size);min-block-size:var(--avatar-size);corner-shape:unset}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { AvatarProps } from '..';
|
|
2
|
+
import { IntrinsicViraProps } from '../../core/props/intrinsic-vira-props';
|
|
3
|
+
import { ThemeTypes } from '@viraui/foundation/vira/types';
|
|
4
|
+
import type * as React from 'react';
|
|
5
|
+
type AvatarGroupAvatarProps = Omit<AvatarProps, 'size' | 'ref'>;
|
|
6
|
+
/**
|
|
7
|
+
* Public AvatarGroup props.
|
|
8
|
+
*
|
|
9
|
+
* Includes standard `div` attributes such as `id`, `role`, `title`, data attributes, and event handlers,
|
|
10
|
+
* plus Vira-owned avatar composition controls.
|
|
11
|
+
*
|
|
12
|
+
* @default Native div pass-through props keep React defaults.
|
|
13
|
+
*/
|
|
14
|
+
export type AvatarGroupProps = React.ComponentPropsWithRef<'div'> & IntrinsicViraProps & {
|
|
15
|
+
/**
|
|
16
|
+
* Supplies the avatar payloads rendered by the group in DOM order.
|
|
17
|
+
*
|
|
18
|
+
* @default No default; consumers must provide an array.
|
|
19
|
+
*/
|
|
20
|
+
avatars: AvatarGroupAvatarProps[];
|
|
21
|
+
/**
|
|
22
|
+
* Selects the shared avatar footprint for every rendered avatar.
|
|
23
|
+
*
|
|
24
|
+
* @default 'small'
|
|
25
|
+
*/
|
|
26
|
+
size?: AvatarProps['size'];
|
|
27
|
+
/**
|
|
28
|
+
* Chooses whether avatars overlap across the inline or block axis.
|
|
29
|
+
*
|
|
30
|
+
* @default 'horizontal'
|
|
31
|
+
*/
|
|
32
|
+
direction?: 'horizontal' | 'vertical';
|
|
33
|
+
/**
|
|
34
|
+
* Sets the empty visual separation preserved inside the overlap cutout.
|
|
35
|
+
*
|
|
36
|
+
* @default 'x-small'
|
|
37
|
+
*/
|
|
38
|
+
gap?: Extract<ThemeTypes['space'], '2x-small' | 'x-small' | 'small'>;
|
|
39
|
+
/**
|
|
40
|
+
* Limits how many real avatars render before the optional overflow pill is appended.
|
|
41
|
+
*
|
|
42
|
+
* Omitted, zero, and negative values are ignored.
|
|
43
|
+
*
|
|
44
|
+
* @default No truncation.
|
|
45
|
+
*/
|
|
46
|
+
maxVisible?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Supplies the content rendered inside the optional overflow pill when truncation is active.
|
|
49
|
+
*
|
|
50
|
+
* @default No overflow pill content.
|
|
51
|
+
*/
|
|
52
|
+
overflowText?: React.ReactNode;
|
|
53
|
+
};
|
|
54
|
+
export declare const AvatarGroup: React.FC<AvatarGroupProps>;
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "AvatarGroup",
|
|
3
|
+
"summary": "Overlapping avatar stack with shared sizing, directional layout, and an optional overflow pill.",
|
|
4
|
+
"whenToUse": [
|
|
5
|
+
"Show a compact list of people or entities with consistent avatar sizing",
|
|
6
|
+
"Display overlapping circular identity clusters in horizontal or vertical layouts",
|
|
7
|
+
"Collapse long avatar lists into a final overflow pill such as +15 or +9938"
|
|
8
|
+
],
|
|
9
|
+
"whenNotToUse": ["Interactive chip collections that need per-item actions", "Mixed avatar sizes inside one group"],
|
|
10
|
+
"accessibility": [
|
|
11
|
+
"Provide meaningful alt text on each avatar image when identity matters",
|
|
12
|
+
"Treat overflow content such as +3 or +9938 as summary text rather than an interactive affordance",
|
|
13
|
+
"Keep decorative avatars on empty alt text when the surrounding context already labels the group"
|
|
14
|
+
],
|
|
15
|
+
"antiPatterns": [
|
|
16
|
+
"Passing per-avatar size values instead of using the group size prop",
|
|
17
|
+
"Expecting AvatarGroup to derive hidden-count labels instead of passing overflowText directly",
|
|
18
|
+
"Expecting grouped avatars to follow theme radius tokens instead of always rendering as circles",
|
|
19
|
+
"Using non-positive maxVisible values expecting truncation"
|
|
20
|
+
],
|
|
21
|
+
"related": ["Avatar"]
|
|
22
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import './avatar-group.css';
|
|
2
|
+
import { extractIntrinsicViraProps } from "../../core/props/intrinsic-vira-props.js";
|
|
3
|
+
import { Avatar } from "../avatar/avatar.js";
|
|
4
|
+
import { resolveThemeValue } from "../../core/theme/resolve-theme-value.js";
|
|
5
|
+
import avatar_group_module_default from "./avatar-group.module.js";
|
|
6
|
+
import { Stack } from "../stack/stack.js";
|
|
7
|
+
import { Text } from "../text/text.js";
|
|
8
|
+
import { Surface } from "../surface/surface.js";
|
|
9
|
+
import { clsx } from "clsx";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
//#region src/components/avatar-group/avatar-group.tsx
|
|
12
|
+
var getAvatarKey = (avatar, index) => `${avatar.src ?? "fallback"}-${typeof avatar.fallback === "string" ? avatar.fallback : "node"}-${index}`;
|
|
13
|
+
var AvatarGroup = ({ avatars, className, direction = "horizontal", gap = "x-small", maxVisible, overflowText, size = "small", style, ...otherProps }) => {
|
|
14
|
+
const { componentProps, intrinsicAttributes } = extractIntrinsicViraProps(otherProps);
|
|
15
|
+
const isOverflowing = typeof maxVisible === "number" && maxVisible > 0 && avatars.length > maxVisible;
|
|
16
|
+
const hasOverflow = isOverflowing && overflowText !== void 0 && overflowText !== null;
|
|
17
|
+
const truncatedAvatars = isOverflowing ? avatars.slice(0, maxVisible) : avatars;
|
|
18
|
+
const dynamicStyle = {
|
|
19
|
+
"--avatar-group-gap-size": resolveThemeValue(gap, "space", "var(--space-x-small)"),
|
|
20
|
+
...style
|
|
21
|
+
};
|
|
22
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
23
|
+
...componentProps,
|
|
24
|
+
...intrinsicAttributes,
|
|
25
|
+
className: clsx(avatar_group_module_default.AvatarGroup, className),
|
|
26
|
+
"data-direction": direction,
|
|
27
|
+
"data-gap": gap,
|
|
28
|
+
"data-has-overflow": hasOverflow ? "true" : "false",
|
|
29
|
+
"data-size": size,
|
|
30
|
+
style: dynamicStyle,
|
|
31
|
+
children: [truncatedAvatars.map((avatar, index) => /* @__PURE__ */ jsx("div", {
|
|
32
|
+
className: avatar_group_module_default.AvatarWrapper,
|
|
33
|
+
children: /* @__PURE__ */ jsx(Avatar, {
|
|
34
|
+
className: avatar_group_module_default.AvatarGroupItem,
|
|
35
|
+
...avatar,
|
|
36
|
+
size
|
|
37
|
+
})
|
|
38
|
+
}, getAvatarKey(avatar, index))), hasOverflow && /* @__PURE__ */ jsx("div", {
|
|
39
|
+
className: clsx(avatar_group_module_default.AvatarWrapper, avatar_group_module_default.OverflowWrapper),
|
|
40
|
+
children: /* @__PURE__ */ jsx(Surface, {
|
|
41
|
+
className: avatar_group_module_default.OverflowPill,
|
|
42
|
+
color: 3,
|
|
43
|
+
render: /* @__PURE__ */ jsx(Stack, {
|
|
44
|
+
inline: true,
|
|
45
|
+
direction: "row",
|
|
46
|
+
fillChildren: false,
|
|
47
|
+
hAlign: "center",
|
|
48
|
+
vAlign: "center",
|
|
49
|
+
hPadding: "medium"
|
|
50
|
+
}),
|
|
51
|
+
style: { "--surface-border-radius": "1e5px" },
|
|
52
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
53
|
+
whiteSpace: "nowrap",
|
|
54
|
+
children: overflowText
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
})]
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { AvatarGroup };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
var avatar_group_module_default = {
|
|
2
|
+
AvatarGroup: "avatar-group-module_AvatarGroup_zOrR-",
|
|
3
|
+
AvatarWrapper: "avatar-group-module_AvatarWrapper_0opqY",
|
|
4
|
+
OverflowWrapper: "avatar-group-module_OverflowWrapper_bKv6I",
|
|
5
|
+
AvatarGroupItem: "avatar-group-module_AvatarGroupItem_Vvlyh",
|
|
6
|
+
OverflowPill: "avatar-group-module_OverflowPill_nMmTD"
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
9
|
+
export { avatar_group_module_default as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.checkbox-module_Checkbox_3oGip{--checkbox-size:var(--space-medium);--checkbox-radius:var(--radius-x-small);--checkbox-background:var(--global-contrast);--checkbox-border-color:transparent;--checkbox-indicator-color:contrast-color(var(--global-primary));&:has([required]) [data-field-label]:after{content:" *";color:var(--highlight-red)}}.checkbox-module_CheckboxRoot_PeyF5{position:relative;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;appearance:none;border:0;box-shadow:inset 0 0 0 1px var(--checkbox-border-color);inline-size:var(--checkbox-size);block-size:var(--checkbox-size);background:var(--checkbox-background);border-radius:var(--checkbox-radius);&[data-size=regular]{--checkbox-size:var(--space-large);--checkbox-radius:var(--radius-small)}&[data-checked]:not([data-disabled]):not([data-invalid]),&[data-indeterminate]:not([data-disabled]):not([data-invalid]){--checkbox-background:var(--global-primary);--checkbox-border-color:var(--global-primary);box-shadow:none}&[data-invalid]:not([data-disabled]),.checkbox-module_Checkbox_3oGip[data-invalid]>&:not([data-disabled]){--checkbox-border-color:var(--highlight-red);--checkbox-indicator-color:var(--global-primary);box-shadow:inset 0 0 0 1px var(--highlight-red);outline-color:oklab(from var(--highlight-red) l a b/.5)}&[data-disabled],.checkbox-module_Checkbox_3oGip[data-disabled]>&{--checkbox-background:var(--global-disabled-background);--checkbox-border-color:transparent;--checkbox-indicator-color:var(--global-disabled-foreground);box-shadow:none}}.checkbox-module_Indicator_C-k-l{display:inline-flex;align-items:center;justify-content:center;color:var(--checkbox-indicator-color)}.checkbox-module_Icon_926Sa{stroke:currentColor}.checkbox-module_CheckboxRoot_PeyF5:not([data-indeterminate]) .checkbox-module_MinusIcon_Q57pY,.checkbox-module_CheckboxRoot_PeyF5[data-indeterminate] .checkbox-module_CheckIcon_XqUcs{display:none}.checkbox-module_CheckboxRoot_PeyF5[data-indeterminate] .checkbox-module_MinusIcon_Q57pY{display:inline-flex}
|
|
1
|
+
.checkbox-module_Checkbox_3oGip{--checkbox-size:var(--space-medium);--checkbox-radius:var(--radius-x-small);--checkbox-background:var(--global-contrast);--checkbox-border-color:transparent;--checkbox-indicator-color:contrast-color(var(--global-primary));&:has([required]) [data-field-label]:after{content:" *";color:var(--highlight-red)}}.checkbox-module_CheckboxRoot_PeyF5{position:relative;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;appearance:none;border:0;box-shadow:inset 0 0 0 1px var(--checkbox-border-color);inline-size:var(--checkbox-size);block-size:var(--checkbox-size);background:var(--checkbox-background);border-radius:var(--checkbox-radius);&[data-size=regular]{--checkbox-size:var(--space-large);--checkbox-radius:var(--radius-small)}&[data-checked]:not([data-disabled]):not([data-invalid]),&[data-indeterminate]:not([data-disabled]):not([data-invalid]){--checkbox-background:var(--global-primary);--checkbox-border-color:var(--global-primary);box-shadow:none}&[data-invalid]:not([data-disabled]),.checkbox-module_Checkbox_3oGip[data-invalid]>&:not([data-disabled]){--checkbox-border-color:var(--highlight-red);--checkbox-indicator-color:var(--global-primary);box-shadow:inset 0 0 0 1px var(--highlight-red);outline-color:oklab(from var(--highlight-red) l a b/.5)}&[data-disabled],.checkbox-module_Checkbox_3oGip[data-disabled]>&{--checkbox-background:var(--global-disabled-background);--checkbox-border-color:transparent;--checkbox-indicator-color:var(--global-disabled-foreground);box-shadow:none;cursor:not-allowed}}.checkbox-module_Indicator_C-k-l{display:inline-flex;align-items:center;justify-content:center;color:var(--checkbox-indicator-color)}.checkbox-module_Icon_926Sa{stroke:currentColor}.checkbox-module_CheckboxRoot_PeyF5:not([data-indeterminate]) .checkbox-module_MinusIcon_Q57pY,.checkbox-module_CheckboxRoot_PeyF5[data-indeterminate] .checkbox-module_CheckIcon_XqUcs{display:none}.checkbox-module_CheckboxRoot_PeyF5[data-indeterminate] .checkbox-module_MinusIcon_Q57pY{display:inline-flex}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import './checkbox.css';
|
|
3
3
|
import { extractIntrinsicViraProps } from "../../core/props/intrinsic-vira-props.js";
|
|
4
|
+
import { Stack } from "../stack/stack.js";
|
|
4
5
|
import { FieldHelperCopy } from "../basic-input/field-helper-copy.js";
|
|
5
6
|
import { FieldLabel } from "../basic-input/field-label.js";
|
|
6
|
-
import { Stack } from "../stack/stack.js";
|
|
7
7
|
import checkbox_module_default from "./checkbox.module.js";
|
|
8
8
|
import { Icon } from "../icon/icon.js";
|
|
9
9
|
import { clsx } from "clsx";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.chip-module_Chip_2D18T{--chip-background:var(--global-primary);--chip-border-color:transparent;--chip-color:contrast-color(var(--global-primary));--chip-height:var(--space-large);--chip-icon-size:0.9em;--chip-color-bg-opacity:13%;--chip-color-border-opacity:0%;min-block-size:var(--chip-height);block-size:var(--chip-height);border:1px solid var(--chip-border-color);border-radius:var(--radius-infinite);background:var(--chip-background);color:var(--chip-color);font-size:var(--font-scale-body-small);font-variation-settings:"wght" 400;text-decoration:none;white-space:nowrap;overflow:hidden;&[data-variant=primary]{--chip-background:var(--global-primary);--chip-color:contrast-color(var(--global-primary))}&[data-variant=secondary]{--chip-background:var(--global-contrast);--chip-color:var(--base-6)}&[data-variant=outline]{--chip-background:transparent;--chip-border-color:oklab(from var(--global-contrast) l a b/0.2);--chip-color:var(--base-6)}&[data-variant=gray]{--chip-background:oklab(from currentColor l a b/var(--chip-color-bg-opacity));--chip-border-color:oklab(from currentColor l a b/var(--chip-color-border-opacity));--chip-color:var(--highlight-gray)}&[data-variant=slate]{--chip-background:oklab(from currentColor l a b/var(--chip-color-bg-opacity));--chip-border-color:oklab(from currentColor l a b/var(--chip-color-border-opacity));--chip-color:var(--highlight-slate)}&[data-variant=yellow]{--chip-background:oklab(from currentColor l a b/var(--chip-color-bg-opacity));--chip-border-color:oklab(from currentColor l a b/var(--chip-color-border-opacity));--chip-color:var(--highlight-yellow)}&[data-variant=green]{--chip-background:oklab(from currentColor l a b/var(--chip-color-bg-opacity));--chip-border-color:oklab(from currentColor l a b/var(--chip-color-border-opacity));--chip-color:var(--highlight-green)}&[data-variant=blue]{--chip-color:var(--highlight-blue)}&[data-variant=blue],&[data-variant=red]{--chip-background:oklab(from currentColor l a b/var(--chip-color-bg-opacity));--chip-border-color:oklab(from currentColor l a b/var(--chip-color-border-opacity))}&[data-variant=red]{--chip-color:var(--highlight-red)}&[data-variant=cyan]{--chip-background:oklab(from currentColor l a b/var(--chip-color-bg-opacity));--chip-border-color:oklab(from currentColor l a b/var(--chip-color-border-opacity));--chip-color:var(--highlight-cyan)}&[data-variant=purple]{--chip-background:oklab(from currentColor l a b/var(--chip-color-bg-opacity));--chip-border-color:oklab(from currentColor l a b/var(--chip-color-border-opacity));--chip-color:var(--highlight-purple)}&[data-variant=indigo]{--chip-background:oklab(from currentColor l a b/var(--chip-color-bg-opacity));--chip-border-color:oklab(from currentColor l a b/var(--chip-color-border-opacity));--chip-color:var(--highlight-indigo)}&[data-variant=acid]{--chip-background:oklab(from currentColor l a b/var(--chip-color-bg-opacity));--chip-border-color:oklab(from currentColor l a b/var(--chip-color-border-opacity));--chip-color:var(--highlight-acid)}&[data-variant=salmon]{--chip-background:oklab(from currentColor l a b/var(--chip-color-bg-opacity));--chip-border-color:oklab(from currentColor l a b/var(--chip-color-border-opacity));--chip-color:var(--highlight-salmon)}&[data-variant=magenta]{--chip-background:oklab(from currentColor l a b/var(--chip-color-bg-opacity));--chip-border-color:oklab(from currentColor l a b/var(--chip-color-border-opacity));--chip-color:var(--highlight-magenta)}}.chip-module_Content_7mLuL{min-inline-size:0;min-block-size:100%}.chip-module_IconSlot_9N5vD{display:inline-grid;place-items:center;flex-shrink:0;>svg{inline-size:var(--chip-icon-size);block-size:var(--chip-icon-size)}}.chip-module_Label_Hdx7l{display:inline-block;min-inline-size:0;overflow:hidden;text-overflow:ellipsis}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
2
|
+
import { IntrinsicViraProps } from '../../core/props/intrinsic-vira-props';
|
|
3
|
+
import { ThemeTypes } from '@viraui/foundation/vira/types';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
/**
|
|
7
|
+
* Public Chip props.
|
|
8
|
+
*
|
|
9
|
+
* Includes standard `div` attributes such as `children`, `id`, `title`, and event handlers,
|
|
10
|
+
* plus Vira-owned visual variant, decorative addon, and Base UI `render` support for replacing the root element.
|
|
11
|
+
*
|
|
12
|
+
* @default Base UI pass-through props keep upstream defaults.
|
|
13
|
+
*/
|
|
14
|
+
export type ChipProps = React.ComponentPropsWithRef<'div'> & IntrinsicViraProps & {
|
|
15
|
+
/**
|
|
16
|
+
* Replaces the default `div` root using Base UI render semantics.
|
|
17
|
+
*
|
|
18
|
+
* @default The chip renders a `div` root.
|
|
19
|
+
*/
|
|
20
|
+
render?: useRender.RenderProp;
|
|
21
|
+
/**
|
|
22
|
+
* Ref forwarded to the rendered chip root element.
|
|
23
|
+
*
|
|
24
|
+
* @default No ref is attached.
|
|
25
|
+
*/
|
|
26
|
+
ref?: React.Ref<HTMLElement>;
|
|
27
|
+
/**
|
|
28
|
+
* Selects the visual treatment for the chip.
|
|
29
|
+
*
|
|
30
|
+
* @default 'primary'
|
|
31
|
+
*/
|
|
32
|
+
variant?: 'primary' | 'secondary' | 'outline' | ThemeTypes['highlight'];
|
|
33
|
+
/**
|
|
34
|
+
* Decorative addon rendered alongside the chip label.
|
|
35
|
+
*
|
|
36
|
+
* @default No default; omit when the chip has no addon.
|
|
37
|
+
*/
|
|
38
|
+
addon?: ReactNode;
|
|
39
|
+
/**
|
|
40
|
+
* Controls whether the addon appears before or after the label.
|
|
41
|
+
*
|
|
42
|
+
* @default 'start'
|
|
43
|
+
*/
|
|
44
|
+
addonPosition?: 'start' | 'end';
|
|
45
|
+
};
|
|
46
|
+
export declare const Chip: React.FC<ChipProps>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Chip",
|
|
3
|
+
"summary": "Compact visual label primitive for short status, category, or metadata treatments.",
|
|
4
|
+
"whenToUse": [
|
|
5
|
+
"Short, non-interactive labels that need a compact pill treatment",
|
|
6
|
+
"Metadata, category, status, or inline tag-like presentation",
|
|
7
|
+
"Color-coded badges using the semantic highlight palette",
|
|
8
|
+
"Polymorphic label content that should render as div by default or as another semantic tag through render"
|
|
9
|
+
],
|
|
10
|
+
"whenNotToUse": [
|
|
11
|
+
"Interactive actions or dismiss controls — use Button or IconButton",
|
|
12
|
+
"Long-form text content that should wrap like body copy — use Text"
|
|
13
|
+
],
|
|
14
|
+
"accessibility": [
|
|
15
|
+
"Chip renders a div by default, so choose render explicitly when a different semantic element is needed",
|
|
16
|
+
"Decorative addons are aria-hidden and should not carry the accessible name",
|
|
17
|
+
"Chip does not add button semantics, disabled state, or loading behavior in v1"
|
|
18
|
+
],
|
|
19
|
+
"antiPatterns": [
|
|
20
|
+
"Using Chip as a button replacement for clickable actions",
|
|
21
|
+
"Expecting addonPosition to have any effect when addon is omitted",
|
|
22
|
+
"Introducing custom size variants instead of the fixed compact height",
|
|
23
|
+
"Re-adding a one-off destructive variant instead of using the red highlight color"
|
|
24
|
+
],
|
|
25
|
+
"related": ["Button", "Icon", "IconButton", "Stack", "Text"]
|
|
26
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import './chip.css';
|
|
3
|
+
import { extractIntrinsicViraProps } from "../../core/props/intrinsic-vira-props.js";
|
|
4
|
+
import { Stack } from "../stack/stack.js";
|
|
5
|
+
import chip_module_default from "./chip.module.js";
|
|
6
|
+
import { clsx } from "clsx";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
9
|
+
import "react";
|
|
10
|
+
//#region src/components/chip/chip.tsx
|
|
11
|
+
var Chip = ({ addon, addonPosition = "start", children, className, ref, render, variant = "primary", ...otherProps }) => {
|
|
12
|
+
const { componentProps, intrinsicAttributes } = extractIntrinsicViraProps(otherProps);
|
|
13
|
+
const content = /* @__PURE__ */ jsxs(Stack, {
|
|
14
|
+
inline: true,
|
|
15
|
+
direction: addonPosition === "start" ? "row" : "row-reverse",
|
|
16
|
+
vAlign: "center",
|
|
17
|
+
fillChildren: false,
|
|
18
|
+
hPadding: "small",
|
|
19
|
+
columnGap: "x-small",
|
|
20
|
+
className: chip_module_default.Content,
|
|
21
|
+
children: [addon && /* @__PURE__ */ jsx("span", {
|
|
22
|
+
"aria-hidden": "true",
|
|
23
|
+
className: chip_module_default.IconSlot,
|
|
24
|
+
children: addon
|
|
25
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
26
|
+
className: chip_module_default.Label,
|
|
27
|
+
children
|
|
28
|
+
})]
|
|
29
|
+
});
|
|
30
|
+
return useRender({
|
|
31
|
+
defaultTagName: "div",
|
|
32
|
+
render,
|
|
33
|
+
ref,
|
|
34
|
+
props: {
|
|
35
|
+
...componentProps,
|
|
36
|
+
...intrinsicAttributes,
|
|
37
|
+
"data-grow": false,
|
|
38
|
+
"data-shrink": false,
|
|
39
|
+
children: content,
|
|
40
|
+
className: clsx(chip_module_default.Chip, className),
|
|
41
|
+
"data-has-icon": addon ? "true" : void 0,
|
|
42
|
+
"data-icon-position": addon ? addonPosition : void 0,
|
|
43
|
+
"data-variant": variant
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
//#endregion
|
|
48
|
+
export { Chip };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.icon-module_Icon_6DoBq{display:inline-flex;flex:none;vertical-align:middle;& [fill]{fill:currentcolor}& [fill=none][stroke]{fill:none;stroke:currentcolor}}
|
|
1
|
+
.icon-module_Icon_6DoBq{display:inline-flex;flex:none;vertical-align:middle;& [fill]{fill:currentcolor}& [stroke]{stroke:currentcolor}& [fill=none][stroke]{fill:none;stroke:currentcolor}}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
export * from './avatar';
|
|
2
|
+
export * from './avatar-group';
|
|
3
|
+
export * from './chip';
|
|
2
4
|
export * from './clamp-text';
|
|
3
5
|
export * from './elevator';
|
|
4
6
|
export * from './button';
|
|
5
7
|
export * from './icon-button';
|
|
6
8
|
export * from './linear-progress';
|
|
9
|
+
export * from './masonry';
|
|
7
10
|
export * from './textfield';
|
|
8
11
|
export * from './textarea';
|
|
9
12
|
export * from './slider';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import './linear-progress.css';
|
|
3
3
|
import { extractIntrinsicViraProps } from "../../core/props/intrinsic-vira-props.js";
|
|
4
|
+
import { Stack } from "../stack/stack.js";
|
|
4
5
|
import { Text } from "../text/text.js";
|
|
5
6
|
import { FieldLabel } from "../basic-input/field-label.js";
|
|
6
|
-
import { Stack } from "../stack/stack.js";
|
|
7
7
|
import linear_progress_module_default from "./linear-progress.module.js";
|
|
8
8
|
import { clsx } from "clsx";
|
|
9
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
2
|
+
import { IntrinsicViraProps } from '../../core/props/intrinsic-vira-props';
|
|
3
|
+
import type * as React from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Public Masonry.Item props.
|
|
6
|
+
*
|
|
7
|
+
* Includes standard `div` attributes such as `id`, `role`, `title`, data attributes, and event handlers,
|
|
8
|
+
* plus Base UI `render` support for replacing the default item root.
|
|
9
|
+
*
|
|
10
|
+
* @default Native div pass-through props keep React defaults.
|
|
11
|
+
*/
|
|
12
|
+
export type MasonryItemProps = React.ComponentPropsWithRef<'div'> & IntrinsicViraProps & {
|
|
13
|
+
/**
|
|
14
|
+
* Replaces the default `div` root using Base UI render semantics.
|
|
15
|
+
*
|
|
16
|
+
* @default The item renders a `div` root.
|
|
17
|
+
*/
|
|
18
|
+
render?: useRender.RenderProp;
|
|
19
|
+
/**
|
|
20
|
+
* Makes the item span across all columns.
|
|
21
|
+
*
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
spanAll?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Ref forwarded to the rendered item root element.
|
|
27
|
+
*
|
|
28
|
+
* @default No ref is attached.
|
|
29
|
+
*/
|
|
30
|
+
ref?: React.Ref<HTMLElement>;
|
|
31
|
+
};
|
|
32
|
+
export declare const MasonryItem: React.FC<MasonryItemProps>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { extractIntrinsicViraProps } from "../../core/props/intrinsic-vira-props.js";
|
|
3
|
+
import masonry_module_default from "./masonry.module.js";
|
|
4
|
+
import { clsx } from "clsx";
|
|
5
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
6
|
+
//#region src/components/masonry/masonry-item.tsx
|
|
7
|
+
var MasonryItem = ({ className, ref, render, spanAll = false, ...otherProps }) => {
|
|
8
|
+
const { componentProps, intrinsicAttributes } = extractIntrinsicViraProps(otherProps);
|
|
9
|
+
return useRender({
|
|
10
|
+
defaultTagName: "div",
|
|
11
|
+
render,
|
|
12
|
+
ref,
|
|
13
|
+
props: {
|
|
14
|
+
...componentProps,
|
|
15
|
+
...intrinsicAttributes,
|
|
16
|
+
"data-masonry-item-span-all": spanAll ? "true" : "false",
|
|
17
|
+
className: clsx(masonry_module_default.Item, className)
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
export { MasonryItem };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.masonry-module_Masonry_l7c8U{--masonry-gap:var(--space-large);--masonry-column-fill:balance;--masonry-column-rule-color:var(--global-contrast);display:block;column-gap:var(--masonry-gap);column-fill:var(--masonry-column-fill);column-rule-color:var(--masonry-column-rule-color);columns:var(--masonry-column-width,auto) var(--masonry-column-count,auto);max-inline-size:100%}.masonry-module_Item_ywXwo{display:block;break-inside:avoid;margin:0;padding-block-end:var(--masonry-gap);&[data-masonry-item-span-all=true]{column-span:all}}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
2
|
+
import { ThemeTypes } from '@viraui/foundation/vira/types';
|
|
3
|
+
import { IntrinsicViraProps } from '../../core/props/intrinsic-vira-props';
|
|
4
|
+
import { MasonryItemProps } from './masonry-item';
|
|
5
|
+
import type * as React from 'react';
|
|
6
|
+
type MasonryColumnRuleStyle = 'none' | 'hidden' | 'dotted' | 'dashed' | 'solid' | 'double' | 'groove' | 'ridge' | 'inset' | 'outset';
|
|
7
|
+
/**
|
|
8
|
+
* Public Masonry props.
|
|
9
|
+
*
|
|
10
|
+
* Includes standard `div` attributes such as `id`, `role`, `title`, data attributes, and event handlers,
|
|
11
|
+
* plus Vira-owned CSS multi-column layout controls.
|
|
12
|
+
*
|
|
13
|
+
* @default Native div pass-through props keep React defaults.
|
|
14
|
+
*/
|
|
15
|
+
export type MasonryProps = React.ComponentPropsWithRef<'div'> & IntrinsicViraProps & {
|
|
16
|
+
/**
|
|
17
|
+
* Replaces the default `div` root using Base UI render semantics.
|
|
18
|
+
*
|
|
19
|
+
* @default The masonry renders a `div` root.
|
|
20
|
+
*/
|
|
21
|
+
render?: useRender.RenderProp;
|
|
22
|
+
/**
|
|
23
|
+
* Sets the gap between columns and the block-end spacing on each `Masonry.Item`.
|
|
24
|
+
*
|
|
25
|
+
* @default 'large'
|
|
26
|
+
*/
|
|
27
|
+
gap?: ThemeTypes['space'];
|
|
28
|
+
/**
|
|
29
|
+
* Sets how the browser balances content across columns.
|
|
30
|
+
*
|
|
31
|
+
* @default 'balance'
|
|
32
|
+
*/
|
|
33
|
+
columnFill?: 'balance' | 'auto';
|
|
34
|
+
/**
|
|
35
|
+
* Sets the CSS `column-width` value used for width-based multi-column layout.
|
|
36
|
+
*
|
|
37
|
+
* When provided, it overrides `columnCount`.
|
|
38
|
+
*
|
|
39
|
+
* @default No width override.
|
|
40
|
+
*/
|
|
41
|
+
columnWidth?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Sets the CSS `column-count` value used for count-based multi-column layout.
|
|
44
|
+
*
|
|
45
|
+
* Ignored when `columnWidth` is provided.
|
|
46
|
+
*
|
|
47
|
+
* @default 4
|
|
48
|
+
*/
|
|
49
|
+
columnCount?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Sets the CSS `column-rule-width` value for the separator between columns.
|
|
52
|
+
*
|
|
53
|
+
* @default No rule width override.
|
|
54
|
+
*/
|
|
55
|
+
columnRuleWidth?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Sets the CSS `column-rule-style` value for the separator between columns.
|
|
58
|
+
*
|
|
59
|
+
* @default No rule style override.
|
|
60
|
+
*/
|
|
61
|
+
columnRuleStyle?: MasonryColumnRuleStyle;
|
|
62
|
+
};
|
|
63
|
+
export type { MasonryItemProps } from './masonry-item';
|
|
64
|
+
type MasonryComponent = React.FC<MasonryProps> & {
|
|
65
|
+
Item: React.FC<MasonryItemProps>;
|
|
66
|
+
};
|
|
67
|
+
export declare const Masonry: MasonryComponent;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Masonry",
|
|
3
|
+
"summary": "Multi-column layout primitive for read-only mixed-height content walls.",
|
|
4
|
+
"whenToUse": [
|
|
5
|
+
"Card walls, gallery-like collections, and editorial layouts with uneven item heights",
|
|
6
|
+
"Presentational grids where visual packing matters more than row alignment",
|
|
7
|
+
"Read-only collections composed from Surface, Stack, Text, and similar content primitives"
|
|
8
|
+
],
|
|
9
|
+
"whenNotToUse": [
|
|
10
|
+
"Interactive collections where keyboard tab order must match visual scan order",
|
|
11
|
+
"Layouts that need strict row alignment or item-to-item placement control",
|
|
12
|
+
"Cases where Stack or another linear layout already preserves the intended reading sequence"
|
|
13
|
+
],
|
|
14
|
+
"accessibility": [
|
|
15
|
+
"Masonry is presentational and keeps DOM order, so tab order follows source order rather than the visual column flow",
|
|
16
|
+
"Avoid interactive descendants when the visual arrangement could mislead keyboard users",
|
|
17
|
+
"Choose semantic item roots with Masonry.Item render when list or article semantics matter"
|
|
18
|
+
],
|
|
19
|
+
"antiPatterns": [
|
|
20
|
+
"Treating CSS columns as a true interactive grid with predictable left-to-right keyboard traversal",
|
|
21
|
+
"Using arbitrary child margins instead of the component gap contract for item spacing"
|
|
22
|
+
],
|
|
23
|
+
"related": ["Stack", "Surface", "Text"]
|
|
24
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import './masonry.css';
|
|
3
|
+
import { extractIntrinsicViraProps } from "../../core/props/intrinsic-vira-props.js";
|
|
4
|
+
import { resolveThemeValue } from "../../core/theme/resolve-theme-value.js";
|
|
5
|
+
import masonry_module_default from "./masonry.module.js";
|
|
6
|
+
import { MasonryItem } from "./masonry-item.js";
|
|
7
|
+
import { clsx } from "clsx";
|
|
8
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
9
|
+
//#region src/components/masonry/masonry.tsx
|
|
10
|
+
var MasonryRoot = ({ children, className, columnCount = 4, columnFill = "balance", columnRuleStyle, columnRuleWidth, columnWidth, gap = "large", ref, render, style, ...otherProps }) => {
|
|
11
|
+
const { componentProps, intrinsicAttributes } = extractIntrinsicViraProps(otherProps);
|
|
12
|
+
const usesColumnWidth = columnWidth !== void 0;
|
|
13
|
+
const dynamicStyle = {
|
|
14
|
+
"--masonry-gap": resolveThemeValue(gap, "space", "var(--space-large)"),
|
|
15
|
+
"--masonry-column-fill": columnFill,
|
|
16
|
+
...usesColumnWidth ? { "--masonry-column-width": columnWidth } : { "--masonry-column-count": `${columnCount}` },
|
|
17
|
+
...columnRuleWidth ? { columnRuleWidth } : {},
|
|
18
|
+
...columnRuleStyle ? { columnRuleStyle } : {},
|
|
19
|
+
...style
|
|
20
|
+
};
|
|
21
|
+
return useRender({
|
|
22
|
+
defaultTagName: "div",
|
|
23
|
+
render,
|
|
24
|
+
ref,
|
|
25
|
+
props: {
|
|
26
|
+
...componentProps,
|
|
27
|
+
...intrinsicAttributes,
|
|
28
|
+
"data-masonry-column-fill": columnFill,
|
|
29
|
+
"data-masonry-layout-mode": usesColumnWidth ? "width" : "count",
|
|
30
|
+
className: clsx(masonry_module_default.Masonry, className),
|
|
31
|
+
style: dynamicStyle,
|
|
32
|
+
children
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
var Masonry = Object.assign(MasonryRoot, { Item: MasonryItem });
|
|
37
|
+
//#endregion
|
|
38
|
+
export { Masonry };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { extractIntrinsicViraProps } from "../../core/props/intrinsic-vira-props.js";
|
|
3
|
+
import { Stack } from "../stack/stack.js";
|
|
3
4
|
import { FieldHelperCopy } from "../basic-input/field-helper-copy.js";
|
|
4
5
|
import { FieldLabel } from "../basic-input/field-label.js";
|
|
5
|
-
import { Stack } from "../stack/stack.js";
|
|
6
6
|
import radio_module_default from "./radio.module.js";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { Field, Fieldset, RadioGroup } from "@base-ui/react";
|