@viraui/react 2026.0.9 → 2026.0.11

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 CHANGED
@@ -185,7 +185,7 @@
185
185
  {
186
186
  "id": "stack",
187
187
  "name": "Stack",
188
- "summary": "Flex layout primitive for arranging children with token spacing, alignment, and padding; root is a named CSS container query context (`stack`).",
188
+ "summary": "Flex layout primitive for arranging children with token spacing, alignment, and padding; optionally enables a named CSS container query context (`stack`) via `enableContainer`.",
189
189
  "guidePath": "./components/stack/stack.guide.json"
190
190
  },
191
191
  {
@@ -197,7 +197,7 @@
197
197
  {
198
198
  "id": "surface",
199
199
  "name": "Surface",
200
- "summary": "Presentational container with token background, optional border, radius, and padding; nested surfaces use radius=\"auto\" for concentric corners; root is a named CSS container query context (`surface`).",
200
+ "summary": "Presentational container with token background, optional border, radius, and padding; nested surfaces use radius=\"auto\" for concentric corners; optionally enables a named CSS container query context (`surface`) via `enableContainer`.",
201
201
  "guidePath": "./components/surface/surface.guide.json"
202
202
  },
203
203
  {
@@ -1 +1 @@
1
- @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-button-background{syntax:"<color>";inherits:false;initial-value:#0000}@property --vui-button-color{syntax:"<color>";inherits:false;initial-value:#0000}@property --vui-button-height{syntax:"<length>";inherits:false;initial-value:0}@property --vui-button-padding-inline{syntax:"<length>";inherits:false;initial-value:0}@property --vui-button-padding-block{syntax:"<length>";inherits:false;initial-value:0}@property --vui-button-spinner-color{syntax:"<color>";inherits:false;initial-value:#0000}@property --vui-button-icon-size{syntax:"<length>";inherits:true;initial-value:0}@property --vui-button-radius{syntax:"<length-percentage>";inherits:false;initial-value:0}.viraui__button-module__Button_oPhrP{--vui-button-background:var(--global-primary);--vui-button-color:var(--base-1);--vui-button-height:var(--space-2x-large);--vui-button-padding-inline:calc(var(--space-small) + var(--space-2x-small));--vui-button-padding-block:var(--space-small);--vui-button-icon-size:1.125em;--vui-button-spinner-color:currentColor;--vui-button-radius:var(--radius-medium);-webkit-user-select:none;user-select:none;margin:0;cursor:pointer;font-family:inherit;display:inline-flex;align-items:center;min-inline-size:fit-content;max-block-size:var(--vui-button-height);block-size:var(--vui-button-height);justify-content:center;text-decoration:none;white-space:nowrap;appearance:button;overflow:hidden;position:relative;padding:var(--vui-button-padding-block) var(--vui-button-padding-inline);font-weight:400;font-variation-settings:"wght" 400;gap:var(--space-small);border:1px solid #0000;background:var(--vui-button-background);color:var(--vui-button-color);font-size:var(--font-scale-body-medium);border-radius:var(--vui-button-radius);transition:translate var(--easing-elastic) var(--duration-instant);will-change:translate;&:not(:disabled){background-clip:padding-box}&:not(:disabled,[aria-disabled=true]):active{translate:0 1px}&[data-pill=true]{border-radius:var(--radius-infinite)}&[data-size=big]{--vui-button-height:calc(var(--space-2x-large) + var(--space-x-small));--vui-button-padding-inline:calc(var(--space-medium) + var(--space-2x-small));--vui-button-padding-block:var(--space-small);--vui-button-icon-size:1.125em;--vui-button-radius:var(--radius-medium)}&[data-size=small]{--vui-button-height:var(--space-x-large);--vui-button-padding-inline:var(--space-small);--vui-button-padding-block:var(--space-x-small);--vui-button-icon-size:1em;--vui-button-radius:var(--radius-small);gap:var(--space-x-small);font-size:var(--font-scale-body-small)}&[data-variant=primary]{--vui-button-background:var(--global-primary);--vui-button-color:contrast-color(var(--global-primary));&:hover{--vui-button-background:oklab(from var(--global-primary) calc(l + 0.05) a b)}}&[data-variant=secondary]{--vui-button-background:var(--global-contrast);--vui-button-color:var(--base-6);background-clip:unset;&:hover{--vui-button-background:oklab(from var(--global-contrast) l a b/calc(alpha + 0.03))}@container root style(--is-light-mode: black){--vui-button-background:oklab(from var(--global-contrast) l a b/0.1)}}&[data-variant=flat]{--vui-button-background:#0000;--vui-button-color:var(--base-5);&:hover{--vui-button-background:var(--global-contrast);--vui-button-color:var(--base-7)}}&[data-variant=destructive]{--vui-button-background:oklab(from var(--highlight-red) l a b/12%);--vui-button-color:var(--highlight-red);outline-color:var(--highlight-red);&:hover{--vui-button-background:oklab(from var(--highlight-red) l a b/30%)}}&[data-addon-position=start]{flex-direction:row;padding-inline-end:calc(var(--vui-button-padding-inline) * 1.2)}&[data-addon-position=end]{flex-direction:row-reverse;padding-inline-start:calc(var(--vui-button-padding-inline) * 1.2)}&[data-icon-only=true]{gap:0;padding-block:var(--vui-button-padding-block);padding-inline:var(--vui-button-padding-block);inline-size:var(--vui-button-height);min-inline-size:var(--vui-button-height);max-inline-size:var(--vui-button-height);aspect-ratio:1/1}&:disabled,&:disabled:active,&:disabled:hover,&[aria-disabled=true],&[aria-disabled=true]:active,&[aria-disabled=true]:hover{--vui-button-background:var(--global-disabled-background);--vui-button-color:var(--global-disabled-foreground);cursor:not-allowed;box-shadow:none;translate:0}&[data-loading=true][data-disabled]{pointer-events:none;border:0;box-shadow:none;--vui-button-color:var(--base-7)}}.viraui__button-module__Content_w-pX-{display:inline-grid;place-items:center;&[data-loading=true]{opacity:0}&:first-child>svg{block-size:var(--vui-button-icon-size);inline-size:var(--vui-button-icon-size);flex-shrink:0}}.viraui__button-module__SpinnerOverlay_vKqw1{position:absolute;inset:0;display:grid;place-content:center;pointer-events:none;color:var(--vui-button-spinner-color)}}
1
+ @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-button-background{syntax:"<color>";inherits:false;initial-value:#0000}@property --vui-button-color{syntax:"<color>";inherits:false;initial-value:#0000}@property --vui-button-height{syntax:"<length>";inherits:false;initial-value:0}@property --vui-button-padding-inline{syntax:"<length>";inherits:false;initial-value:0}@property --vui-button-padding-block{syntax:"<length>";inherits:false;initial-value:0}@property --vui-button-spinner-color{syntax:"<color>";inherits:false;initial-value:#0000}@property --vui-button-icon-size{syntax:"<length>";inherits:true;initial-value:0}@property --vui-button-radius{syntax:"<length-percentage>";inherits:false;initial-value:0}.viraui__button-module__Button_oPhrP{--vui-button-background:var(--global-primary);--vui-button-color:var(--base-1);--vui-button-height:var(--space-2x-large);--vui-button-padding-inline:calc(var(--space-small) + var(--space-2x-small));--vui-button-padding-block:var(--space-small);--vui-button-icon-size:1.125em;--vui-button-spinner-color:currentColor;--vui-button-radius:var(--radius-medium);-webkit-user-select:none;user-select:none;margin:0;cursor:pointer;font-family:inherit;display:inline-flex;align-items:center;min-inline-size:fit-content;min-block-size:var(--vui-button-height);block-size:var(--vui-button-height);justify-content:center;text-decoration:none;white-space:nowrap;appearance:button;overflow:hidden;position:relative;padding:var(--vui-button-padding-block) var(--vui-button-padding-inline);font-weight:400;font-variation-settings:"wght" 400;gap:var(--space-small);border:1px solid #0000;background:var(--vui-button-background);color:var(--vui-button-color);font-size:var(--font-scale-body-medium);border-radius:var(--vui-button-radius);transition:translate var(--easing-elastic) var(--duration-instant);will-change:translate;&:not(:disabled){background-clip:padding-box}&:not(:disabled,[aria-disabled=true]):active{translate:0 1px}&[data-pill=true]{border-radius:var(--radius-infinite)}&[data-size=big]{--vui-button-height:calc(var(--space-2x-large) + var(--space-x-small));--vui-button-padding-inline:calc(var(--space-medium) + var(--space-2x-small));--vui-button-padding-block:var(--space-small);--vui-button-icon-size:1.125em;--vui-button-radius:var(--radius-medium)}&[data-size=small]{--vui-button-height:var(--space-x-large);--vui-button-padding-inline:var(--space-small);--vui-button-padding-block:var(--space-x-small);--vui-button-icon-size:1em;--vui-button-radius:var(--radius-small);gap:var(--space-x-small);font-size:var(--font-scale-body-small)}&[data-variant=primary]{--vui-button-background:var(--global-primary);--vui-button-color:contrast-color(var(--global-primary));&:hover{--vui-button-background:oklab(from var(--global-primary) calc(l + 0.05) a b)}}&[data-variant=secondary]{--vui-button-background:var(--global-contrast);--vui-button-color:var(--base-6);background-clip:unset;&:hover{--vui-button-background:oklab(from var(--global-contrast) l a b/calc(alpha + 0.03))}@container root style(--is-light-mode: black){--vui-button-background:oklab(from var(--global-contrast) l a b/0.1)}}&[data-variant=flat]{--vui-button-background:#0000;--vui-button-color:var(--base-5);&:hover{--vui-button-background:var(--global-contrast);--vui-button-color:var(--base-7)}}&[data-variant=destructive]{--vui-button-background:oklab(from var(--highlight-red) l a b/12%);--vui-button-color:var(--highlight-red);outline-color:var(--highlight-red);&:hover{--vui-button-background:oklab(from var(--highlight-red) l a b/30%)}}&[data-addon-position=start]{flex-direction:row;padding-inline-end:calc(var(--vui-button-padding-inline) * 1.2)}&[data-addon-position=end]{flex-direction:row-reverse;padding-inline-start:calc(var(--vui-button-padding-inline) * 1.2)}&[data-icon-only=true]{gap:0;padding-block:var(--vui-button-padding-block);padding-inline:var(--vui-button-padding-block);inline-size:var(--vui-button-height);min-inline-size:var(--vui-button-height);max-inline-size:var(--vui-button-height);aspect-ratio:1/1}&:disabled,&:disabled:active,&:disabled:hover,&[aria-disabled=true],&[aria-disabled=true]:active,&[aria-disabled=true]:hover{--vui-button-background:var(--global-disabled-background);--vui-button-color:var(--global-disabled-foreground);cursor:not-allowed;box-shadow:none;translate:0}&[data-loading=true][data-disabled]{pointer-events:none;border:0;box-shadow:none;--vui-button-color:var(--base-7)}}.viraui__button-module__Content_w-pX-{display:inline-grid;place-items:center;&[data-loading=true]{opacity:0}&:first-child>svg{block-size:var(--vui-button-icon-size);inline-size:var(--vui-button-icon-size);flex-shrink:0}}.viraui__button-module__SpinnerOverlay_vKqw1{position:absolute;inset:0;display:grid;place-content:center;pointer-events:none;color:var(--vui-button-spinner-color)}}
@@ -24,7 +24,9 @@
24
24
  "antiPatterns": [
25
25
  "Expecting multi-select or combobox behavior",
26
26
  "Leaving the trigger without label or aria-label",
27
- "Never set the size prop (if present) of Buttons, IconButtons or other interactive elements passed as addon other than small"
27
+ "Never set the size prop (if present) of Buttons, IconButtons or other interactive elements passed as addon other than small",
28
+ "Using the Select component as a combobox, use Autocomplete instead.",
29
+ "Set alignItemWithTrigger false when options don't have a leading addon"
28
30
  ],
29
31
  "related": ["Autocomplete", "Fieldset", "Textfield", "Stack", "Surface", "Icon"],
30
32
  "properties": {
@@ -1 +1 @@
1
- @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-slider-track-size{syntax:"<length>";inherits:true;initial-value:0}@property --vui-slider-thumb-size{syntax:"<length>";inherits:true;initial-value:0}@property --vui-slider-track-background{syntax:"<color>";inherits:true;initial-value:#0000}@property --vui-slider-progress-background{syntax:"<color>";inherits:true;initial-value:#0000}@property --vui-slider-thumb-background{syntax:"<color>";inherits:true;initial-value:#0000}.viraui__slider-module__Slider_vDNlm{--vui-slider-track-size:var(--space-x-small);--vui-slider-thumb-size:var(--space-medium);--vui-slider-track-background:var(--global-contrast);--vui-slider-progress-background:var(--global-primary);--vui-slider-thumb-background:var(--base-2);inline-size:100%;block-size:100%;min-inline-size:0;min-block-size:0;&:has([required]) .viraui__slider-module__Label_eQQHf:after{content:" *";color:var(--highlight-red)}&[data-invalid]{--vui-slider-progress-background:var(--highlight-red)}&:has(.viraui__slider-module__SliderRoot_4JScw[data-disabled]),&[data-disabled]{--vui-slider-track-background:var(--global-disabled-background);--vui-slider-progress-background:var(--global-disabled-foreground);--vui-slider-thumb-background:var(--global-disabled-foreground);cursor:not-allowed}}.viraui__slider-module__SliderRoot_4JScw{inline-size:100%;block-size:100%;min-inline-size:0;min-block-size:0}.viraui__slider-module__SliderHeader_gOy9k{inline-size:100%;min-inline-size:0}.viraui__slider-module__Value_FaY9i{flex-shrink:0}.viraui__slider-module__SliderControl_FQd5-{position:relative;flex:1 1 auto;-webkit-user-select:none;user-select:none;touch-action:none;inline-size:100%;block-size:var(--vui-slider-track-size);min-inline-size:0;min-block-size:0;&[data-orientation=vertical]{inline-size:var(--vui-slider-track-size);block-size:100%;>.viraui__slider-module__Track_wvLEH{inline-size:var(--vui-slider-track-size);block-size:100%}}}.viraui__slider-module__Track_wvLEH{position:relative;overflow:visible;inline-size:100%;block-size:var(--vui-slider-track-size);background:var(--vui-slider-track-background);border-radius:var(--radius-infinite)}.viraui__slider-module__Indicator_y3JyJ{background:var(--vui-slider-progress-background);border-radius:inherit}.viraui__slider-module__Thumb_S-uLF{box-sizing:border-box;inline-size:var(--vui-slider-thumb-size);block-size:calc(var(--vui-slider-thumb-size) - 2px);background:var(--vui-slider-thumb-background);border:2px solid var(--vui-slider-progress-background);border-radius:var(--radius-x-small);appearance:none;transition:scale var(--duration-instant) var(--easing-standard);&:not(:disabled,[data-disabled]){cursor:grab}&:not(:disabled,[data-disabled]):active,&:not(:disabled,[data-disabled]):has(>input:active),&:not(:disabled,[data-disabled])[data-dragging]:has(>input:focus){cursor:grabbing;scale:1.2}&:has(>input:focus-visible){outline:var(--outline);outline-offset:var(--outline-offset)}>input:focus-visible{outline:none}}}
1
+ @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-slider-track-size{syntax:"<length>";inherits:true;initial-value:0}@property --vui-slider-thumb-size{syntax:"<length>";inherits:true;initial-value:0}@property --vui-slider-track-background{syntax:"<color>";inherits:true;initial-value:#0000}@property --vui-slider-progress-background{syntax:"<color>";inherits:true;initial-value:#0000}@property --vui-slider-thumb-background{syntax:"<color>";inherits:true;initial-value:#0000}.viraui__slider-module__Slider_vDNlm{--vui-slider-track-size:var(--space-x-small);--vui-slider-thumb-size:var(--space-medium);--vui-slider-track-background:var(--global-contrast);--vui-slider-progress-background:var(--global-foreground);--vui-slider-thumb-background:var(--base-2);inline-size:100%;block-size:100%;min-inline-size:0;min-block-size:0;&:has([required]) .viraui__slider-module__Label_eQQHf:after{content:" *";color:var(--highlight-red)}&[data-invalid]{--vui-slider-progress-background:var(--highlight-red)}&:has(.viraui__slider-module__SliderRoot_4JScw[data-disabled]),&[data-disabled]{--vui-slider-track-background:var(--global-disabled-background);--vui-slider-progress-background:var(--global-disabled-foreground);--vui-slider-thumb-background:var(--global-disabled-foreground);cursor:not-allowed}}.viraui__slider-module__SliderRoot_4JScw{inline-size:100%;block-size:100%;min-inline-size:0;min-block-size:0}.viraui__slider-module__SliderHeader_gOy9k{inline-size:100%;min-inline-size:0}.viraui__slider-module__Value_FaY9i{flex-shrink:0}.viraui__slider-module__SliderControl_FQd5-{position:relative;flex:1 1 auto;-webkit-user-select:none;user-select:none;touch-action:none;inline-size:100%;block-size:var(--vui-slider-track-size);min-inline-size:0;min-block-size:0;&[data-orientation=vertical]{inline-size:var(--vui-slider-track-size);block-size:100%;>.viraui__slider-module__Track_wvLEH{inline-size:var(--vui-slider-track-size);block-size:100%}}}.viraui__slider-module__Track_wvLEH{position:relative;overflow:visible;inline-size:100%;block-size:var(--vui-slider-track-size);background:var(--vui-slider-track-background);border-radius:var(--radius-infinite)}.viraui__slider-module__Indicator_y3JyJ{background:var(--vui-slider-progress-background);border-radius:inherit}.viraui__slider-module__Thumb_S-uLF{box-sizing:border-box;inline-size:var(--vui-slider-thumb-size);block-size:calc(var(--vui-slider-thumb-size) - 2px);background:var(--vui-slider-thumb-background);border:2px solid var(--vui-slider-progress-background);border-radius:var(--radius-x-small);appearance:none;transition:scale var(--duration-instant) var(--easing-standard);&:not(:disabled,[data-disabled]){cursor:grab}&:not(:disabled,[data-disabled]):active,&:not(:disabled,[data-disabled]):has(>input:active),&:not(:disabled,[data-disabled])[data-dragging]:has(>input:focus){cursor:grabbing;scale:1.2}&:has(>input:focus-visible){outline:var(--outline);outline-offset:var(--outline-offset)}>input:focus-visible{outline:none}}}
@@ -1 +1 @@
1
- @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-stack-row-gap{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-column-gap{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-h-align{syntax:"*";inherits:false;initial-value:initial}@property --vui-stack-v-align{syntax:"*";inherits:false;initial-value:initial}@property --vui-stack-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-max-width{syntax:"*";inherits:false;initial-value:none}@property --vui-stack-min-width{syntax:"*";inherits:false;initial-value:none}.viraui__stack-module__Stack_NR-Ey{display:flex;gap:var(--vui-stack-row-gap) var(--vui-stack-column-gap);flex-direction:column;align-items:var(--vui-stack-h-align);justify-content:var(--vui-stack-v-align);max-inline-size:var(--vui-stack-max-width);min-inline-size:var(--vui-stack-min-width);&[data-stack-direction=column-reverse]{flex-direction:column-reverse}&[data-stack-direction=row-reverse],&[data-stack-direction=row]{align-items:var(--vui-stack-v-align);justify-content:var(--vui-stack-h-align)}&[data-stack-direction=row]{flex-direction:row}&[data-stack-direction=row-reverse]{flex-direction:row-reverse}&[data-stack-inline=true]{display:inline-flex;flex-grow:0}:where(&[data-stack-wrap=true]){flex-wrap:wrap}:where(&[data-stack-has-padding=true]){padding:var(--vui-stack-padding-block-start) var(--vui-stack-padding-inline-end) var(--vui-stack-padding-block-end) var(--vui-stack-padding-inline-start)}:where(&[data-stack-fill-children=true]>*){flex-grow:var(--vira-flex-grow,1)}}}
1
+ @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-stack-row-gap{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-column-gap{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-h-align{syntax:"*";inherits:false;initial-value:initial}@property --vui-stack-v-align{syntax:"*";inherits:false;initial-value:initial}@property --vui-stack-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-stack-max-width{syntax:"*";inherits:false;initial-value:none}@property --vui-stack-min-width{syntax:"*";inherits:false;initial-value:none}.viraui__stack-module__Stack_NR-Ey{display:flex;gap:var(--vui-stack-row-gap) var(--vui-stack-column-gap);flex-direction:column;align-items:var(--vui-stack-h-align);justify-content:var(--vui-stack-v-align);max-inline-size:var(--vui-stack-max-width);min-inline-size:var(--vui-stack-min-width);&[data-stack-direction=column-reverse]{flex-direction:column-reverse}&[data-stack-direction=row-reverse],&[data-stack-direction=row]{align-items:var(--vui-stack-v-align);justify-content:var(--vui-stack-h-align)}&[data-stack-direction=row]{flex-direction:row}&[data-stack-direction=row-reverse]{flex-direction:row-reverse}&[data-stack-inline=true]{display:inline-flex;flex-grow:0}:where(&[data-stack-wrap=true]){flex-wrap:wrap}:where(&[data-stack-has-padding=true]){padding:var(--vui-stack-padding-block-start) var(--vui-stack-padding-inline-end) var(--vui-stack-padding-block-end) var(--vui-stack-padding-inline-start)}:where(&[data-stack-fill-children=true]>*){flex-grow:var(--vira-flex-grow,1)}&[data-stack-container=true]{container:stack/size}}}
@@ -97,6 +97,18 @@ export type StackProps = React.ComponentPropsWithoutRef<'div'> & {
97
97
  * @default No min width constraint.
98
98
  */
99
99
  minWidth?: string;
100
+ /**
101
+ * Opt-in named CSS container query context for this Stack.
102
+ *
103
+ * Enables `container: stack / size` on the rendered root (via `data-stack-container="true"`),
104
+ * so descendants can use `@container stack (min-width/min-height: ...)` against this Stack size.
105
+ *
106
+ * Warning: container size containment can affect nested layout (e.g. cards inside Masonry).
107
+ * Use only when you need container queries against this specific Stack.
108
+ *
109
+ * @default false
110
+ */
111
+ enableContainer?: boolean;
100
112
  };
101
113
  export declare const Stack: React.FC<StackProps>;
102
114
  export {};
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "Stack",
3
3
  "structure": "<Stack>…</Stack>",
4
- "summary": "Flex layout primitive for arranging children with token spacing, alignment, and padding; root is a named CSS container query context (`stack`).",
4
+ "summary": "Flex layout primitive for arranging children with token spacing, alignment, and padding; optionally enables a named CSS container query context (`stack`) via `enableContainer`.",
5
5
  "whenToUse": [
6
6
  "Column or row layouts with token gap and alignment",
7
7
  "Composing screens and component internals without custom flex CSS",
8
8
  "Custom native root through render while keeping data-stack hooks",
9
- "Style descendants with @container stack queries when layout, gap, or typography should respond to the Stack's own inline-size and block-size instead of the viewport"
9
+ "Style descendants with `@container stack` queries when layout, gap, or typography should respond to the Stack's own inline-size and block-size instead of the viewport (set `enableContainer` on the Stack you're querying)"
10
10
  ],
11
11
  "whenNotToUse": [
12
12
  "Cases where a single component already owns required flex chrome",
13
- "Expecting the Stack root itself to grow via fillChildren"
13
+ "Expecting the Stack root itself to grow via fillChildren",
14
+ "Using `enableContainer` inside complex masonry-like layouts when you don't need container queries (size containment can change nested layout)"
14
15
  ],
15
16
  "accessibility": [
16
17
  "Stack is presentational — choose render roots that preserve correct semantics (button, list, heading)",
@@ -27,6 +28,9 @@
27
28
  "columnGap": {
28
29
  "description": "Sets the gap between flex columns using the Vira space token scale."
29
30
  },
31
+ "enableContainer": {
32
+ "description": "Opt-in named CSS container query context for this Stack (enables `container: stack / size` on the root via `data-stack-container`). Required for `@container stack (min-width/min-height: ...)` rules to react to this Stack size. Warning: container size containment can affect nested layout (e.g. cards inside Masonry). Use only when you need container queries against this specific Stack."
33
+ },
30
34
  "direction": {
31
35
  "description": "Renders children across rows or columns using the chosen flex direction."
32
36
  },
@@ -5,7 +5,7 @@ import { resolveAxisPadding } from "../../core/styles/resolve-axis-padding.js";
5
5
  import stack_module_default from "./stack.module.js";
6
6
  import { useRender } from "@base-ui/react/use-render";
7
7
  //#region src/components/stack/stack.tsx
8
- var Stack = ({ className, direction = "column", fillChildren = true, hAlign = "initial", hPadding, inline = false, maxWidth, minWidth, ref, render, rowGap, columnGap, style, vAlign = "initial", vPadding, wrap = false, ...otherProps }) => {
8
+ var Stack = ({ className, direction = "column", fillChildren = true, hAlign = "initial", hPadding, inline = false, maxWidth, minWidth, enableContainer, ref, render, rowGap, columnGap, style, vAlign = "initial", vPadding, wrap = false, ...otherProps }) => {
9
9
  const hasPadding = Boolean(hPadding || vPadding);
10
10
  const dynamicStyle = {
11
11
  "--vui-stack-row-gap": resolveThemeValue(rowGap, "space", 0),
@@ -25,6 +25,7 @@ var Stack = ({ className, direction = "column", fillChildren = true, hAlign = "i
25
25
  props: {
26
26
  ...otherProps,
27
27
  "data-stack-direction": direction,
28
+ ...enableContainer && { "data-stack-container": "true" },
28
29
  "data-stack-inline": inline ? "true" : "false",
29
30
  "data-stack-wrap": wrap ? "true" : "false",
30
31
  "data-stack-fill-children": fillChildren ? "true" : "false",
@@ -1 +1 @@
1
- @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-surface-background{syntax:"*";inherits:false;initial-value:none}@property --vui-surface-background-hover{syntax:"*";inherits:false;initial-value:none}@property --vui-surface-border-style{syntax:"<custom-ident>";inherits:false;initial-value:solid}@property --vui-surface-overflow{syntax:"<custom-ident>";inherits:false;initial-value:visible}@property --vui-surface-border-radius{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-top-left{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-top-right{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-bottom-right{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-bottom-left{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}.viraui__surface-module__Surface_slEYq{--vui-surface-border-radius-top-left:var(--vui-surface-border-radius);--vui-surface-border-radius-top-right:var(--vui-surface-border-radius);--vui-surface-border-radius-bottom-right:var(--vui-surface-border-radius);--vui-surface-border-radius-bottom-left:var(--vui-surface-border-radius);--vui-surface-background-hover:var(--vui-surface-background);position:relative;overflow:var(--vui-surface-overflow);box-sizing:border-box;background:var(--vui-surface-background);border-radius:var(--vui-surface-border-radius-top-left) var(--vui-surface-border-radius-top-right) var(--vui-surface-border-radius-bottom-right) var(--vui-surface-border-radius-bottom-left);border:0;&[data-surface-color=primary]{--vui-surface-background:light-dark(oklab(from var(--global-primary) l a b/20%),oklab(from var(--global-primary) l a b/10%))}&[data-surface-hover-color=primary]{--vui-surface-background-hover:light-dark(oklab(from var(--global-primary) l a b/20%),oklab(from var(--global-primary) l a b/10%))}@container root not style(--vibrancy-enable: initial){&[data-vibrant]{background:light-dark(oklab(from var(--vui-surface-background) l a b/60%),oklab(from var(--vui-surface-background) l a b/80%))}}&[data-surface-has-padding=true]{padding:var(--vui-surface-padding-block-start) var(--vui-surface-padding-inline-end) var(--vui-surface-padding-block-end) var(--vui-surface-padding-inline-start)}&[data-surface-border]{border-style:var(--vui-surface-border-style);border-color:var(--global-contrast)}&[data-surface-border=all]{border-width:1px}&[data-surface-border=top]{border-width:1px 0 0}&[data-surface-border=right]{border-width:0 1px 0 0}&[data-surface-border=bottom]{border-width:0 0 1px}&[data-surface-border=left]{border-width:0 0 0 1px}&[data-surface-border=x]{border-width:0 1px}&[data-surface-border=y]{border-width:1px 0}@media (hover:hover) and (pointer:fine){&[data-surface-has-hover-color=true]:hover{background:var(--vui-surface-background-hover)}}}}
1
+ @layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-surface-background{syntax:"*";inherits:false;initial-value:none}@property --vui-surface-background-hover{syntax:"*";inherits:false;initial-value:none}@property --vui-surface-border-style{syntax:"<custom-ident>";inherits:false;initial-value:solid}@property --vui-surface-overflow{syntax:"<custom-ident>";inherits:false;initial-value:visible}@property --vui-surface-border-radius{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-top-left{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-top-right{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-bottom-right{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-border-radius-bottom-left{syntax:"<length-percentage>";inherits:false;initial-value:0}@property --vui-surface-padding-inline-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-inline-end{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-block-start{syntax:"<length>";inherits:false;initial-value:0}@property --vui-surface-padding-block-end{syntax:"<length>";inherits:false;initial-value:0}.viraui__surface-module__Surface_slEYq{--vui-surface-border-radius-top-left:var(--vui-surface-border-radius);--vui-surface-border-radius-top-right:var(--vui-surface-border-radius);--vui-surface-border-radius-bottom-right:var(--vui-surface-border-radius);--vui-surface-border-radius-bottom-left:var(--vui-surface-border-radius);--vui-surface-background-hover:var(--vui-surface-background);position:relative;overflow:var(--vui-surface-overflow);box-sizing:border-box;background:var(--vui-surface-background);border-radius:var(--vui-surface-border-radius-top-left) var(--vui-surface-border-radius-top-right) var(--vui-surface-border-radius-bottom-right) var(--vui-surface-border-radius-bottom-left);border:0;&[data-surface-color=primary]{--vui-surface-background:light-dark(oklab(from var(--global-primary) l a b/20%),oklab(from var(--global-primary) l a b/10%))}&[data-surface-hover-color=primary]{--vui-surface-background-hover:light-dark(oklab(from var(--global-primary) l a b/20%),oklab(from var(--global-primary) l a b/10%))}@container root not style(--vibrancy-enable: initial){&[data-vibrant]{background:light-dark(oklab(from var(--vui-surface-background) l a b/60%),oklab(from var(--vui-surface-background) l a b/80%))}}&[data-surface-has-padding=true]{padding:var(--vui-surface-padding-block-start) var(--vui-surface-padding-inline-end) var(--vui-surface-padding-block-end) var(--vui-surface-padding-inline-start)}&[data-surface-border]{border-style:var(--vui-surface-border-style);border-color:var(--global-contrast)}&[data-surface-border=all]{border-width:1px}&[data-surface-border=top]{border-width:1px 0 0}&[data-surface-border=right]{border-width:0 1px 0 0}&[data-surface-border=bottom]{border-width:0 0 1px}&[data-surface-border=left]{border-width:0 0 0 1px}&[data-surface-border=x]{border-width:0 1px}&[data-surface-border=y]{border-width:1px 0}@media (hover:hover) and (pointer:fine){&[data-surface-has-hover-color=true]:hover{background:var(--vui-surface-background-hover)}}&[data-surface-container=true]{container:surface/size}}}
@@ -77,6 +77,18 @@ export type SurfaceProps = Omit<React.ComponentPropsWithoutRef<'div'>, 'color'>
77
77
  * @default visible
78
78
  */
79
79
  overflow?: React.CSSProperties['overflow'];
80
+ /**
81
+ * Opt-in named CSS container query context for this Surface.
82
+ *
83
+ * Enables `container: surface / size` on the rendered root (via `data-surface-container="true"`),
84
+ * so descendants can use `@container surface (min-width/min-height: ...)` against this Surface size.
85
+ *
86
+ * Warning: container size containment can affect nested layout (e.g. cards inside Masonry).
87
+ * Use only when you need container queries against this specific Surface.
88
+ *
89
+ * @default false
90
+ */
91
+ enableContainer?: boolean;
80
92
  };
81
93
  export declare const Surface: React.FC<SurfaceProps>;
82
94
  export {};
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "Surface",
3
3
  "structure": "<Surface>…</Surface>",
4
- "summary": "Presentational container with token background, optional border, radius, and padding; nested surfaces use radius=\"auto\" for concentric corners; root is a named CSS container query context (`surface`).",
4
+ "summary": "Presentational container with token background, optional border, radius, and padding; nested surfaces use radius=\"auto\" for concentric corners; optionally enables a named CSS container query context (`surface`) via `enableContainer`.",
5
5
  "whenToUse": [
6
6
  "Group content with base-level background and contrast border",
7
7
  "Popup or card chrome with optional hover background",
@@ -11,7 +11,7 @@
11
11
  "Set radius=\"auto\" on a nested Surface when its parent Surface has a radius so each corner subtracts the nearest ancestor padding and stays concentric",
12
12
  "Stack nested auto-radius Surfaces recursively; context still resolves through wrapper layout such as Stack",
13
13
  "Set overflow=\"hidden\" (or scroll/auto) when Surface must clip or scroll inner content with radius or padding",
14
- "Style descendants with @container surface queries when layout or typography should respond to the Surface's own inline-size and block-size instead of the viewport"
14
+ "Style descendants with `@container surface` queries when layout or typography should respond to the Surface's own inline-size and block-size instead of the viewport (set `enableContainer` on the Surface you're querying)"
15
15
  ],
16
16
  "whenNotToUse": [
17
17
  "Interactive control semantics without an appropriate render root",
@@ -36,6 +36,9 @@
36
36
  "border": {
37
37
  "description": "Applies the shared contrast border on the chosen side or axis. Omit for no border."
38
38
  },
39
+ "enableContainer": {
40
+ "description": "Opt-in named CSS container query context for this Surface (enables `container: surface / size` on the root). Required for `@container surface (min-width/min-height: ...)` rules to react to this Surface size. Warning: container size containment can affect nested layout (e.g. cards inside Masonry). Use only when you need container queries against this specific Surface."
41
+ },
39
42
  "borderStyle": {
40
43
  "description": "Sets the CSS border style when `border` is set."
41
44
  },
@@ -20,7 +20,7 @@ var surfaceDefaultRadiusProps = {
20
20
  style: void 0,
21
21
  vPadding: void 0
22
22
  };
23
- var Surface = ({ border, borderStyle = "solid", className, color, hPadding, hoverColor, overflow, radius, ref, render, style, vPadding, ...otherProps }) => {
23
+ var Surface = ({ border, borderStyle = "solid", className, color, hPadding, hoverColor, overflow, radius, ref, render, style, vPadding, enableContainer, ...otherProps }) => {
24
24
  const hasPadding = Boolean(hPadding || vPadding);
25
25
  const hasHoverColor = hoverColor !== void 0;
26
26
  const { contextValue, hasAutoRadius, radiusStyle } = useSurfaceRadius({
@@ -50,6 +50,7 @@ var Surface = ({ border, borderStyle = "solid", className, color, hPadding, hove
50
50
  ...hasAutoRadius && { "data-surface-radius": "auto" },
51
51
  ...isSurfaceColorToken(color) && { "data-surface-color": color },
52
52
  ...isSurfaceColorToken(hoverColor) && { "data-surface-hover-color": hoverColor },
53
+ ...enableContainer && { "data-surface-container": "true" },
53
54
  "data-surface-has-hover-color": hasHoverColor ? "true" : "false",
54
55
  "data-surface-has-padding": hasPadding ? "true" : "false",
55
56
  className: clsx(surface_module_default.Surface, className),
@@ -19,7 +19,7 @@ var ToastBanner = ({ children, className, description, dismissable = true, dismi
19
19
  color: 1,
20
20
  border: "all",
21
21
  radius: "large",
22
- "data-vibrant": ""
22
+ "data-vibrant": true
23
23
  }),
24
24
  ...!resolvedTitle && resolvedDescription && { "aria-label": typeof resolvedDescription === "string" ? resolvedDescription : void 0 },
25
25
  children: /* @__PURE__ */ jsxs(Toast.Content, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viraui/react",
3
- "version": "2026.0.9",
3
+ "version": "2026.0.11",
4
4
  "private": false,
5
5
  "files": [
6
6
  "dist"
@@ -35,7 +35,7 @@
35
35
  "unplugin-dts": "1.0.3",
36
36
  "vite": "8.1.4",
37
37
  "vite-plugin-static-copy": "4.1.1",
38
- "@viraui/foundation": "2026.0.9",
38
+ "@viraui/foundation": "2026.0.11",
39
39
  "@viraui/icons": "2026.0.0",
40
40
  "@viraui/postcss-config": "2026.0.0",
41
41
  "@viraui/tsconfig": "2026.0.0"