-
66e5151: Restore banner / category-slider / showcase parity with v1.
BannerBasic(ui): new optionalsizeprop ('s' | 'm' | 'l', default'm') — scales the text stack; heading scales one step above body. New optionalaspectRatioprop — applies a CSSaspect-ratioto the banner root.CategoryCardSlider(ui): new optionalctaprop ({ text, link, variant }) — rendered as a button in the slider's heading area via the existingSwiperChrome.buttonsslot.- New
BlockBannerBasic,BlockBannerIntegrated,BlockBannerShowcaseblocks (ui-app) — first-class block versions of the banner trio (previously only available asSectionBanner*). BlockBannerBasic(ui-app): new optionalaspectRatioschema field (text input, e.g.'1/1','16/9').SectionCategoryCardSlider(ui-app): new optionalctaschema field (object viabuttonFields) withctaVisiblevisibility decorator, plumbed through to the underlyingCategoryCardSlider.SectionProductSliderShowcase(ui-app): new optionalbannerTextSizeschema field (s/m/l, defaultm), routed to the innerBannerBasic.size.SectionContentSlider(ui-app): removed the cosmetic hardcodedsurface-tone="'light'"binding. The underlyingContentSliderdid not consume the prop, so there is no rendering change; surface tone now derives from the outerBackdropas intended.
- abe2a44: Route elevation shadows through the
--shadow-s/--shadow-m/--shadow-ldesign tokens instead of hardcodedbox-shadowvalues. Themes that override these tokens now actually take effect on Card, NavigationMenuContent, Select, ContextMenu, DropdownMenu, AlertDialog, Toast, ThemeEditor, the suggest-input dropdown, PlanCard, PersonaQuote, SearchAutoSuggest, and the variant-selector controls. Default-theme rendering is unchanged. - abe2a44: Revert HeroSlider height behaviour to v1
- Updated dependencies [abe2a44]
- Updated dependencies [bc16256]
- Updated dependencies [a1f6b28]
- @laioutr-core/ui-kit@2.1.0
- @laioutr-core/core-types@0.30.0
- @laioutr-core/kit@0.30.0
-
97e4e2d: Large coordinated refactor across the UI layer (
ui-kit,ui,ui-app). Breaking changes are described with import paths, auto-import tags, prop names, and CSS classes consumers depend on.IconButton— dedicated icon-only button atom. Requiredlabel: string(rendered asaria-label) andicon: IconNameprops. Owns shape chrome only; delegates variant/state styling toButton.TextGroup— caption + heading + subline molecule with configurable semantic tags (captionTag,headingTag,sublineTag), size tiers (s/m/l), alignment, gap, and optionalicon/iconSize/iconColor.OnSurface— replacesOnBackground. Provides surface-tone context ('light' | 'dark' | 'bright'); inherits from the nearest ancestorOnSurfacewhentoneis omitted. Emits--font-color-*and--icon-colortokens for descendants.LinkTile— flat wrapper that routes toLinkTileBasic/LinkTileCompact/LinkTileBigbased onvariant: 'basic' | 'compact' | 'compact-bordered' | 'big'. ReplacesCategoryCard.HighlightToggle— generic two-wayv-modeltoggle withlabel/badge/ariaLabel. Replaces the domain-specificBillingCycleSwitch.StatusMessage— generic icon-led message composition. Requiredicon: IconName, optionaltitle,description,status?: 'default' | 'success' | 'warning' | 'error'(colors the icon via--success-9/--warning-9/--error-9). ReplacesLoginReviewPanel(which hardcoded login/check icons + success tint).MediaStage— bare media + content stage primitive. ReplacesCtaBannerBase.- Reka-UI atoms:
Tabs,Popover,ContextMenu,Listbox,InputSlider. InputAutocompleteandInputCombobox— data-drivenoptions: { value, label, disabled? }[]molecules wrapping reka-ui'sAutocomplete/Combobox.InputComboboxsupportsmultipleand adisplayValue: (value: string | string[]) => stringprop.InputPin— coordinated row of input cells; styling mirrorsInput(same border/focus tokens, 48px cell height).useSwiperEdgeStatecomposable — consolidatesisBeginning/isEndevent wiring previously duplicated across the Swiper widget family.NavLinkItem— generic navigation list-row link primitive (href?,icon?: IconName,hug?: boolean). Replaces the oldMenuLinkIteminui.NavSectionHeading— navigation-list heading primitive (href?); renders asNuxtLinkwhenhrefis set. ReplacesMenuSectionTitleandFooterTitle.SwiperChrome— text + Swiper-chrome composition (caption/heading/subline/textSize/textAlign, navigationPosition, scrollbar/navigation toggles, action buttons). New-build component; no rename source.InputSlider— reka-ui-backed slider input. Single-thumb or multi-thumb (viadefaultValue: number[]), withmin/max/step/orientation/labelprops.Iframe— sandboxed iframe wrapper withsrc/title/aspectRatioprops and arefon the underlying<iframe>.BadgePromotion— promotional badge atom. ReplacesSavingsBadge. Props:variant?: 'promo' | 'sale' | 'new' | 'icon',radius?: 'equal' | 'unequal',size?: 's' | 'm',icon?: IconName,text?: string,savingPercentage?: number,withNotch?: boolean. The previousbadgeVariantfield is nowvariant; the previous requiredsavingPercentageis now optional. BEM root.badge-promotion(was.saving-percentage).- Moved in from
@laioutr-core/ui:DarkModeSwitch,BuyBoxStockInfo(nowStockInfoSummary),LanguageSwitcher,RatingProgressBarFilter. (IframeandCardare NOT moves:Iframeis a brand-new ui-kit component, andCardwas already in ui-kit and is redesigned in place — see "Other prop / API changes".) - Moved in from
@laioutr-core/ui— Swiper widget family:SwiperBullets,SwiperNumbers,SwiperNavBar,SwiperArrows,SwiperScrollbar,ThumbnailsSlidermoved from@laioutr-core/ui. The renames in the table above apply at the new location.SwiperScrollbarmoves without a rename —import SwiperScrollbar from '#ui-kit/components/SwiperScrollbar/SwiperScrollbar.vue'instead of'#ui/...'.
New Old SwatchSwatchPreviewSwatchChipColorSwatchSwatchOptionSwatchItemSwatchSummaryProductTilesSwatches(was inui)InputRadio/InputRadioItemRadioselect/RadioselectItemInputPasswordPasswordInputInputSearchSearchInputInputRatingRatingInputInputPinPinInputOptionTileTextVariantOptionSelectorButtonOptionTileImageVariantOptionSelectorImageVariantSelectionCardVariantSelectorMultipleVariantZoomLevelSegmentedZoomLevelMobileZoomLevelStepperZoomLevelDesktopEmailInputForm/EmailInputFormDisplayNewsletterInputBox/NewsletterInputBoxDisplayLightboxMediaLightboxSwiperBulletsSwiperNavigationBulletsSwiperNumbersSwiperNavigationNumbersSwiperNavBarSwiperNavigationCompact(was previouslySwiperCompact)SwiperArrowsSwiperFadeoutArrows(and prophasFadeoutBackground→fadeout, defaulttrue)ThumbnailsSliderSwiperThumbnailsSliderStatusMessageLoginReviewPanelStockInfoSummaryBuyBoxStockInfo(was inui; size'small' | 'medium'→'s' | 'm')For every rename: file path, folder, exported
*Propstype, auto-imported tag, and BEM block class follow the new name.OnBackground— useOnSurface.BillingCycleSwitch— useHighlightToggle.CategoryCard— useLinkTile.CategoryCardPropsandCategoryCardVariantexports are gone.Breadcrumb— moved to@laioutr-core/uiasBreadcrumbsItem. TheisProductprop is gone.Menubar,Stepper,HoverCard— unused, removed.DiscountFlag— useBadgewith aleftIconprop and the default slot for text.SavingsBadge— replaced byBadgePromotion(redesigned, not a 1:1 rename; see "New components").SwiperNavigationNumbersWithArrows— same UI is reachable viaSwiperNavBarwithnavigationStyle="numbers".
LightboxGallery→ renamed toMediaGallery.SearchResultHeader→ renamed toSearchResultHero.ReviewForm.SocialShare.NavigationNodeButton→ renamed toMenuSideBySideNode(now underui/components/MenuSideBySide/);NavigationNodetype moves to#ui/components/MenuSideBySide/types.- The redundant
FilterOffCanvasSwatchListItemis removed;FilterOffCanvasSwatchListbindsSwatchOptiondirectly.
The Cart family (
CartListItem,CartSummaryBox,EmptyStateCart,FreeDeliveryProgress,CartCouponCodeAccordion,CartCouponCodeAccordionInput), theVariantSelectorConfigurator*family,VariantSelectorMultipleTrigger,VariantSelectorMultipleAvailability,MobileMenuShared/*(wasMobileMenuBanner/MobileMenuButton/MobileMenuList/MobileMenuListItem), and theFilterOffCanvas*subcomponents (FilterOffCanvasAccordionItem,FilterOffCanvasCheckboxList,FilterOffCanvasCheckboxListItem,FilterOffCanvasRangeSlider,FilterOffCanvasSwatchList,FilterOffCanvasSwitchItem) were already in@laioutr-core/uiat base under nestedorganism/...paths. They are renamed/flattened withinuirather than moved fromui-kit— see the@laioutr-core/ui"Renamed and flattened withinui" entry.Button.typeprop removed. Use the newIconButtonfor icon-only buttons (type="close-button"/"icon"are gone).- Sizes:
'small' | 'medium' | 'large'→'xs' | 's' | 'm' | 'l'. Default changes from'medium'to'm'. - Variants flattened.
ButtonVariantis a single union (14 values).CtaButtonVariantandIconOnlyButtonVariantsub-unions are removed. - Variant renames:
'input-field'→'subtle'.'video-control'removed. - Legacy alias layer dropped:
LegacyButtonVariant,ButtonVariantInput,normalizeButtonVariant,VARIANT_ALIASES,isLegacyVariantare gone — pass canonical names. - Slots → props:
Button.iconLeft/iconRightacceptIconName(typed) instead of#iconLeft/#iconRightslots. - Loading semantics:
Buttonsetsaria-busy="true"whileloading; clicks are blocked; content usesvisibility: hiddenso the width stays stable; the<a>swap is gated by!loading. (Seeis*table for theisLoading→loadingrename.) - New
spinnerType?: 'row' | 'round'prop (default'row');IconButtonoverrides to'round'so the spinner fits the square footprint. BackgroundAwareButtonVariantis rebuilt to mirror the newButtonVariantshape. Removed:glass,white-secondary,white-ghost,black-ghost,white-close,black-close,black-close-always-black,white-close-always-white,input-field. Added:secondary-white,ghost-white,ghost-black,close-white,close-black,subtle,glass-black,info. Theme-levelbackgroundAwareButtonsmaps must rewrite their value entries accordingly.
BannerBasic,BannerShowcase,BannerIntegratedno longer expose avariantprop. TheBannerBasicVariant/BannerShowcaseVariant/BannerIntegratedVarianttypes are removed.- Border-radius is now context-driven via the new
.radius-containedutility class (calc(sign(100cqi - 100%) * var(--forms-border-radius))with a0fallback). It applies inside a constrained container, collapses to0edge-to-edge. - The redundant frame wrapper
<div>is removed from all three banners. MediaStageno longer hardcodesborder-radius.
BackgroundBrightness→SurfaceTone('light' | 'dark' | 'bright') across the Field, Input, Switch, Select, Checkbox,InputRadio, and Swatch families. The legacyBackgroundBrightnesstype is removed.OnBackgroundprimitive deleted; useOnSurface+useSurfaceTone()composable.useSurfaceTone(props)resolves explicit prop > nearest ancestor context >'light'.colorToBackgroundrenamed tocolorToSurfaceTone(file and exported symbol). ReturnsSurfaceTone.Backdropauto-derives tone for custom colors viacolorToSurfaceTone. Hex inputs work; non-hex (var(...),rgb(...),hsl(...),light-dark(...)) currently fall back to'light'.BackgroundAwareBackdropSetis nowRecord<KnownBackdropColors, SurfaceTone>— the'default'literal is dropped (was a synonym for'light'). Theme presets (classic/laioutr/sunny/tech) now spellnone: 'light'directly.- New CSS tokens:
--on-light-*,--on-dark-*,--on-bright-*. The.on-light/.on-dark/.on-brightclasses dereference their own token namespaces. MediaPreviewreads parent surface tone viauseSurfaceTone(props)and emitsmedia-preview--{light,dark,bright}modifiers.--font-color, ...fallback removed fromTextand the uno typography preset (body-*,heading-*,subline-*,caption-*); they emitcolor: var(--font-color-<type>)directly inside thelui-overridablelayer.- A bare
<OnSurface>(notoneprop) inherits the surrounding tone, matching the previous<OnBackground brightness="default">behaviour. (OnBackgroundno longer exists at HEAD; the comparison is offered as a migration aid.) Backdrop:containerBackgroundandbackgroundBrightnessprops are removed. Use:backgrounddirectly (preset name or CSS color) and letcolorToSurfaceTonederive the tone, or pass:surface-toneexplicitly to override.MediaPreview: the legacymodeprop is renamedsurfaceToneand is now resolved viauseSurfaceTone(props)(explicit prop wins, falls through to the ancestor<OnSurface>). The BEM root is also renamed.media-block→.media-preview.- New
SurfaceToneAwareinterface (packages/ui-kit/src/runtime/app/composables/useSurfaceTone.ts) exporting{ surfaceTone?: SurfaceTone }. Components likePaginationandMediaPreviewwiden theirdefineProps<>with this interface so the prop is always optional and resolves throughuseSurfaceTone(props). BackgroundAwareButtonSetKeyis rebuilt as${'dark' | 'light'}:${SurfaceTone}:${BackgroundAwareLookupVariant}. Variant axis narrows to'primary' | 'secondary' | 'ghost'(lookup-only). New exportedBackgroundAwareLookupVarianttype. ThemebackgroundAwareButtonsrecords must drop other-variant keys.BackgroundAwareBackdropSetexported type signature is nowRecord<KnownBackdropColors, SurfaceTone>(wasRecord<KnownBackdropColors, BackgroundBrightnessInput>).MediaStageauto-derives surface tone frombackgroundColorwhensurfaceToneis not explicitly set, usingcolorToSurfaceTone. Same hex-only caveat asBackdrop.provideSurfaceToneContextis renamed to_provideSurfaceToneContextto mark it internal. Only<OnSurface>is allowed to provide tone publicly. External code that previously calledprovideSurfaceToneContext({ tone })must wrap content in<OnSurface :tone="…">instead. The companioninjectSurfaceToneContextkeeps its name (still consumed byuseSurfaceTone()).SwatchChipgainsbrighttone CSS coverage via aswatch-chip--brightmodifier (parallel to--dark). Outline color uses--text-always-blackfor selected, unselected, and hover states. New storiesMultipleColorsOnBrightBackground/MultipleColorsSelectedOnBrightBackground.Pagination,Select,SwiperNavBarinternal: confirmed (with inline comment) that the existing binarytone === 'dark' ? 'ghost-white' : 'ghost-black'check correctly mapsbrightto the'ghost-black'else branch — no behavior change, no API change.- Surface-tone narrowing verdict.
LanguageSwitcher/LanguageSwitcherDisplay/NavigationMenuTextItem/NavigationMenuTextItemWrapper/DarkModeSwitchkeepExclude<SurfaceTone, 'bright'>on theirsurfaceToneprop type — these chrome/navigation components live on neutral surfaces by design. Widen + addbrightCSS only when a component is genuinely placed on a bright surface and visually signed off. New components default to the fullSurfaceToneunion.
Field: legacyerror: stringremoved. UseerrorMessage: stringfor the displayed message andinvalid: booleanfor the visual error state.Fieldauto-derivesisInvalidfromerrorMessagewheninvalidis unset.Input/InputAutocomplete/InputCombobox:isError→invalid.Label:error: boolean→invalid: boolean. BEM modifierlabel--error→label--invalid.InputPassword:readOnly→readonly(so the value reaches the underlyingInput).InputSearch: deadmodelValueprop removed (the live channel issearchTerm).InputCheckbox: the setup-time overwrite ofdefineModelwas removed; later prop changes now propagate.defaultCheckedaccepts'indeterminate'in addition toboolean.Switch: propagatesFieldcontext'sdisabled.defaultCheckedaccepts'indeterminate'.Switch: v-model channel renamed from'checked'to default'modelValue'(defineModel<boolean>('checked')→defineModel<boolean>()).v-model:checkedcallsites must becomev-model(orv-model:model-value). Alsosize: 'small' | 'medium'→'s' | 'm'(default'm'); newinvalid?: booleanprop.Checkbox: v-model channel renamed from'checked'to default'modelValue'(defineModel<boolean | 'indeterminate'>('checked')→defineModel<boolean | 'indeterminate'>()). The standalonecheckedprop is removed fromCheckboxProps(use the model).v-model:checkedcallsites must becomev-model.defaultCheckedalready widened toboolean | 'indeterminate'.InputRadioItem: stops forwarding per-itemrequiredtoRadioGroupItem; the group-level prop is canonical.Select:sizeprop removed (it was forwarded to a reka-ui slot that silently rejected the values). Express size via:trigger="{ size: 's' }".Checkbox/Switchstories switch to a liveuseArgs-drivenrenderround-trippingupdate:modelValue; story args usemodelValue, notchecked/defaultChecked.
For props where the subject is the component itself, the
isprefix is dropped. World-state facts (isUserLoggedIn,isAboveTheFold,isSoldOut,isVerified,isFreeDelivery,isShippingFree,isLoggedIn) keepis*.Component Old → New BadgeisRounded→roundedButtonisLoading→loadingLabelisRequired→required;size: 'small' | 'medium'→'s' | 'm'Switchv-model channel checked→ defaultmodelValue(v-model:checkedcallsites must becomev-model);size: 'small' | 'medium'→'s' | 'm'; newinvalid?: boolean.ThumbnailsSliderisCentered→centeredToast(andtoasterStore)isOpen→openLinkTileBigisBackgroundDark→backgroundDarkPaginationisNavigationNumbers→variant: 'arrows' | 'numbers'(default'arrows')OptionTileImage/OptionTileTextnotAvailable: { isNotAvailable, notAvailableTooltip }flattened tounavailable?: boolean+unavailableTooltip?: stringAccordion:accordionStyle→variant.Accordion: typeddefineModel<string | string[]>('value')exposed for v-model on the active panel(s) (single or multiple based ontype); newselectemit fires afterupdate:value.LoadingSpinner:type: 'row' | 'round'(shape) →variant; oldvariant: ButtonVariant(color) →colorScheme;size: 'small' | 'large'→'s' | 'l'(default'l'). Templates like<LoadingSpinner type="round" variant="primary" />become<LoadingSpinner variant="round" color-scheme="primary" />.IconList:size: 'xs' | 'small' | 'medium'→'xs' | 's' | 'm'(default'm').Avatar: newmedia?: Mediaprop. When set,mediais rendered directly through the<Media>component; otherwise the legacysrc/theme-default chain applies.Sheet: removes the legacycomponent?andcustomClass?props fromSheetProps. Usev-bind="$attrs"/ a wrapper component to add classes;componentwas unused.Card: redesigned.size: 'default' | 'small' | 'medium' | 'large'→'m' | 'l'(default'm'). New props:caption,subline,description: string | HtmlFragment,aspectRatio,icon,iconBackground,textSize,textAlignment,linkText.CardProps/CardCtaare declared inline inCard.vue(the oldCard/types.tsis deleted).BadgePromotion(renamed fromSavingsBadge): props are redesigned, not just renamed. Replace{ savingPercentage, badgeVariant }with{ variant?, radius?, size?, icon?, text?, savingPercentage?, withNotch? }.badgeVariantis nowvariant. BEM root is.badge-promotion(was.saving-percentage).- Type barrel (
packages/ui-kit/src/runtime/app/types/index.ts): dropsCtaBannerBase,CtaBannerBasic,CtaBannerIntegrated,CtaBannerShowcasere-exports; theColorSwatch/Typesre-export becomesSwatchChip/Types; addsMediaStage/MediaStage.vue. Cardtypes:packages/ui-kit/src/runtime/app/components/Card/types.tsis deleted. ImportCardPropsandCardCtafrom'#ui-kit/components/Card/Card.vue'instead.ImageContrastOverlayfields: the colocatedfields.ts(Studio field-helpers) is removed; sections that referencedimageContrastOverlayFieldsmust inline the equivalent shared-field calls.Tooltip: thewidthprop now reaches the rendered tooltip; the arrow size is no longer hardcoded at8.App,OnSurface,Tooltipdefine their own prop interfaces; they no longer re-exportConfigProviderProps/TooltipProviderProps/PrimitiveProps/TooltipArrowPropsfrom reka-ui.ContextMenu: no longer claims a controlledopenprop reka-ui doesn't expose; emitsupdate:openfor observation only.ProgressBar.maxis now bound to<ProgressRoot :max>and the indicator width respectsvalue/max(clamped to[0,100]).Select.prioritizePositionnow forwarded to<SelectContent :prioritize-position>.Card.CardCta.{size,iconLeft,iconRight}are now wired through to the renderedBackgroundAwareButton.Listbox/ListboxItem: the unusedtextValueprop is removed.DropdownMenuTextItem: the:sidebinding onDropdownMenuSubContentis removed (sub-menu direction follows the sub-trigger).IconButtonclick forwarding:IconButtonno longer declaresdefineEmits<{ click }>(); click listeners reach the underlyingButtonvia$attrs. Restores click on every<IconButton @click>callsite.MediaPreviewreactivity: registration now useswatch([props.lightbox, props.media], …, { immediate: true })so the store stays in sync when consumers swapmediaor togglelightboxon a mounted instance.Lightboxcleanup: removed dead Swiper-default-navigation CSS and switched.lightbox__navdesktop layout todisplay: flexso the IconButton no longer renders oval.NavigationBullets: no longer animates on initial mount; a--animatingmodifier gates the keyframes so they only fire on user interaction.HeaderShop:backdrop-filtermoved from.header-shopto.header-shop::beforeso absolutely-positioned descendants (e.g. NavigationMenu hover panel) are not trapped by the compositing clip.NavigationMenu: hover panel anchors to the trigger<li>viatop: 100%; left: 0; z-index: var(--z-index-popover)instead oftop: 52px; z-index: 10000.
- BEM cleanup. Mismatched block names normalized to component names; missing root BEM classes added; single-dash modifiers fixed; BEM hooks added alongside utility classes on structural elements. Notable renames:
Avatar:.user-avatar*→.avatar*Toaster:.toast__progress-bar→.toaster-progressbar;.toaster__viewport+--<position>modifiers addedLoadingSpinner:.round-spinner-s/-l→.round-spinner--s/--lLabel:.label--size-small/-medium→.label--size-s/-mIconList:.icon-list--size-small/-medium→.icon-list--size-s/-mMediaPreview:.media-block*→.media-preview*(and CSS custom properties--media-block-*→--media-preview-*)SwiperChrome:.swiper-chrome__head-{...}→__head--{...}; new.swiper-chrome__spacerEmailInputFormDisplay:.newsletter-form*→.email-input-form-display*Pagination/Sheet/Lightbox: root BEM classes addedMediaText,PlanCard,HeaderShop,FilterBar: single-dash → double-dash modifiers; missing inner-row classes addedNewsletterRegistration:.newsletter-block*→.newsletter-registration*PopUp/PopUpInfo/PopUpNewsletter/PopUpPromotion:.popup*→.pop-up*; keyframepopupShow→popUpShowSearchAutoSuggestItem:.search-suggestion*→.search-auto-suggest-item*
- State-modifier prefix cleanup:
SwatchChip.is-selected→.swatch-chip--selected;Switch.--small→--s;BreadcrumbsItem.--is-active→--active. Theis-modifier prefix is no longer used in BEM class names. <style scoped>/:deep()/:global()removed acrossToaster/ToasterProgressbar,Swatch,QuantityPicker,ThemeEditor/ThemeEditorRoot,Link,Placeholder,SwatchChip,PlanComparisonTable/{SectionHeader,RowValue},PopUp,HeaderBasic. Selectors are anchored explicitly with the owning component's BEM root.- Outer chrome stripped from primitives (
Separator.marginremoved,Labelroot padding removed,InputGroupAddonroot padding removed,InputRatingrootalign-selfremoved,SwiperBulletscentering wrapper removed,ThumbnailsSliderouter padding removed). Consumers apply layout chrome at the call site. v-bind()in CSS is now restricted to instance-private values; overrideable values flow through CSS custom properties (e.g.CouponBoxclear-button uses--icon-color).
New keys:
mediaPreview.openLightbox,zoomLevel.zoomIn/zoomOut,socialShare.{facebook,twitter,linkedin,pinterest,email},productTile.addToCart,pagination.previous/next,variantSelectionCard.saving(Save {percent}%/Spare {percent}%),select.placeholder,addToCart.{soldOut,addToCart},filterOffCanvas.ariaLabel,couponBox.copyToast.{title,subline},pdp.variantsAvailable,inputAutocomplete.emptyText,inputCombobox.{emptyText,toggleLabel},inputCheckbox.label,inputSlider.{thumbLabelValue,thumbLabelMin,thumbLabelMax,thumbLabelIndexed},inputRating.label,ratingProgressBarFilter.starsLabel,popUpNewsletter.{emailPlaceholder,emailButton},uspBanner.ariaLabel,cart.removeCoupon,searchAutoSuggest.yourSearch,sliderNavigation.{play,pause}. Rename: namespacelightboxGallery→mediaGallery(sole keylightboxGallery.close→mediaGallery.close),colorSwatch.*→swatchChip.*,searchInput.*→inputSearch.*,passwordInput.*→inputPassword.*,savingsBadge.*→badgePromotion.*,mediaLightbox.*→lightbox.*(collapsed onto the existinglightbox.closenamespace),shopHeader.*→headerShop.*. Removed:couponCodeInput.*(consumers reusecart.couponCodeandinputSearch.clear),pdp.basePrice.reka-uibumped from^2.3.1to^2.9.6(introduces theAutocompleteprimitive used byInputAutocomplete).- Pure swatch / color-brightness helpers (
getColorBrightness,isColorDark,doesColorNeedBorder,getSwatchDarkness,getSwatchBrightnessClass,doesSwatchNeedBorder) move from@laioutr-core/ui'scomposables/useColorBrightnessinto@laioutr-core/ui-kit'sutils/swatchBrightness.ts(no Vue reactivity, never belonged incomposables/). useImageZoomPankeeps its public composable signature and import path; pure helpers move toutils/imageZoomPan.ts(symbols:Translate,TouchState,ImageZoomPanOptions,updateImageTransform,calculateMaxTranslation,clampTranslation,getCurrentZoomLevel,handleImageMouseMove,handleImageTouchStart,handleImageTouchMove,handleImageTouchEnd,resetImageTranslation).- New
useFieldContext(props)composable (packages/ui-kit/src/runtime/app/composables/useFieldContext.ts) — merges<Field>ancestor context with component-level props (id,disabled,readonly,required,invalid,errorMessage). Replaces the inlineinjectFieldContext+useIdboilerplate that used to live in each input. - New
useSwiperEdgeState()composable (packages/ui-kit/src/runtime/app/composables/useSwiperEdgeState.ts) — returns{ isBeginning, isEnd, onSwiperUpdate }and consolidates theisBeginning/isEndevent wiring previously duplicated across the Swiper widget family. (Listed under "New components" earlier in the changeset for discovery; it is a composable, not a component.) CommonSwiperruntime helper moved from@laioutr-core/uito@laioutr-core/ui-kit(packages/ui-kit/src/runtime/app/components/CommonSwiper/CommonSwiper.ts); auto-wraps default-slot children inSwiperSlideand forwards Swiper props.swiperBreakpointshelper lives inpackages/ui-kit/src/runtime/app/utils/swiperBreakpoints.ts(canonicalcommonSwiperOptions+spacingBreakpoints); consumers in ui import via'#ui-kit/utils/swiperBreakpoints'.
@laioutr-core/uinow registers its auto-imported components with prefixL(matching@laioutr-core/ui-kit) instead ofLui. Every<LuiX>template tag pointing at auicomponent must be renamed to<LX>. Component file basenames are unchanged; only the auto-import prefix differs.Combined with the moves from
ui-kittouilisted below, this means consumers can apply a single<Lui→<L(and</Lui→</L) sweep across their templates regardless of which package a component ended up in. There is no longer a per-package prefix to keep track of.Container— backdrop + grid + alignment + media-sizes composition withcontainerStyle,background,customBackground,margin,padding,columnsMobile,columnsDesktop,sizing,alignmentandtop/default/bottomslots. Used by the mergedSectionContainer.MegaMenucompound —MegaMenu+MegaMenuTrigger+MegaMenuContent. The promo slot ships three auto-picked layouts (--narrow/--flex/--grid).BlogPostDetail— media + title + rich body + social share.ProductDetail— two-column gallery + content layout with#gallery/#contentslots.ScrollAnchor— invisible<div>whosenameprop becomes the DOMid.BlogPostListing— featured post, paginated grid, optional page hero.PopUpshell + presets:PopUp,PopUpInfo,PopUpNewsletter,PopUpPromotion. Shell wraps a reka-ui Dialog with a media slot plus a content stack; presets composeTextGroup,EmailInputForm,CouponBox, andButton.SortModescomposition. (Pagination remains a ui-kit component; onlySortModesis new in@laioutr-core/ui.)SearchAutoSuggest(renamed fromSearchOverlayInput, mounted once viaHeaderShop) and its colocatedSearchAutoSuggestItem.- Moved in from
ui-kit:ReviewForm;SocialShare;MenuSideBySideNode;BreadcrumbsItem;MediaGallery(wasLightboxGallery);SearchResultHero(wasSearchResultHeader). - Renamed and flattened within
ui(these were already inuiat base under nestedorganism/...paths, not moved fromui-kit): the Cart family (CartListItem,CartSummaryBox,EmptyStateCart←CartEmptyState,FreeDeliveryProgress←CartFreeDeliveryProgress,CartCouponCodeAccordion,CartCouponCodeAccordionInput←CartCouponCodeForm); theVariantSelectorConfigurator*family (wasVariantSelectionConfigurator*);VariantSelectorMultipleTrigger(wasMultipleVariantSelectionTrigger);VariantSelectorMultipleAvailability(wasMultipleVariantSelectionAvailability);MobileMenuShared/*(was underorganism/MobileMenu/);FilterOffCanvas*subcomponents (wasFilterSheet*underorganism/FilterSheet/). LogoSliderSlidepromoted to its own top-level folder (components/LogoSliderSlide/).FooterMenumoved to its own component folder with a dedicatedUI/Blocks/FooterMenuStorybook story.LogoGrid— promoted to its own top-level folder (was previously a sub-componentLogoGridMode.vueinsideorganism/LogoSlider/). PublicLogoGridPropswithcaption,heading,subline,orientation: 'left' | 'center',textSize: 's' | 'm' | 'l',logoBackground, and a typedslides: LogoSliderSlideProps[](fromLogoSlider).BannerBasic,BannerIntegrated,BannerShowcase— migrated fromui-kittouias part of the Banner refactor. (Prop changes are documented in the ui-kit "Banner refactor" section.)CategoryCardGridandCategoryCardSlider— replace the inpage-navigation family. Both renderLinkTilefor every variant;CategoryCardGridVariant/CategoryCardSliderVariantare aliases ofLinkTileVariant.EditorialGrid(renamed fromArticlesGrid) — exposesfeaturedCount, caption/heading/subline visibility flags.PersonaQuoteSlider— slider wrapping multiplePersonaQuoteitems, used bySectionPersonaQuoteSlider.PriceInfo,ProductTitle,QuantityDiscount,EnergyLabel,BenefitsBox,CouponBox,AddToCart— renamed from BuyBox-prefixed components (see the rename table).
New Old HeaderBasicHeaderHeaderShopShopHeaderHeroSliderBasicHeroSliderHeroSlideBasicHeroSliderSlideMegaMenu(compound)MegaMenuDesktop(full prop replacement; see "Other prop / API changes")MobileMenuBasicMobileMenuMobileMenuShop(+MobileMenuShopContentItem)MegaMenuMobile(+MegaMenuMobileContentItem)MenuSideBySide(+MenuSideBySideRoot/MenuSideBySideChild/MenuSideBySideNode)SideBySideMenu(+DesktopSideBySideRootMenu/DesktopSideBySideChildMenu/CategoryNodeButton)EditorialGridArticlesGridContentGridCardGridContentSliderGalleryContentSliderBrandListBrandGridMediaTextCmsImageTextMediaGalleryLightboxGallerySearchResultHeroSearchResultHeaderPageNotFoundError404PageEnergyLabelBuyBoxEnergyLabelBenefitsBoxBuyBoxBenefitsBoxPriceInfoBuyBoxPriceInfoCouponBoxBuyBoxApplyDiscountCodeQuantityDiscountBuyBoxQuantityPricesProductTitleBuyBoxProductInfoBasicAddToCartBuyBoxCartButtonVariantSelectorMultiple/VariantSelectorMultipleTrigger/VariantSelectorMultipleAvailabilityMultipleVariantSelection/MultipleVariantSelectionTrigger/MultipleVariantSelectionAvailabilityVariantOffCanvasMultipleVariantSelectionSheetVariantSelectorOptions/VariantSelectorOptionsImageGrid/VariantSelectorOptionsImageSliderVariantSelection/VariantSelectionImageGrid/VariantSelectionImageSliderVariantSelectorConfigurator(+*AccordionItem,*OptionsList,*SwatchList)VariantSelectionConfigurator(+ same suffixes)FilterOffCanvas(+*AccordionItem,*CheckboxList,*CheckboxListItem,*SwatchList,*SwitchItem)FilterSheet(+ same suffixes)ProductListingGridProductGridQuoteCardSliderQuoteSliderCartCouponCodeAccordionInputCartCouponCodeFormEmptyStateCartCartEmptyStateFreeDeliveryProgressCartFreeDeliveryProgressBreadcrumbsItemBreadcrumb(was inui-kit)PlanCard/PlanCardSlider/PlanComparisonTable(+*Header,*RowHeader,*RowValue,*SectionHeader)PricingCard/PricingGrid(orPricingCardSlider) /PricingTable(+ subcomponents)For every rename, file paths, exported
*Propstypes, BEM blocks, Storybook titles, andluiComponentDirsentries follow the new name.BuyBox— was a static demo composition; compose buy boxes from blocks at runtime.InpageNavigation*family (six components) — covered byCategoryCardGrid/CategoryCardSlider(themselves consumers ofLinkTile).CmsContainer/ContainerContent— inline the markup or use the surrounding Section/Block pattern.Iframe— moved toui-kit.Card— moved toui-kit. Thectaprop's type is now an inlineCardCta(same shape as the previousCtaBannerButton).DarkModeSwitch,BuyBoxStockInfo,LanguageSwitcher— moved toui-kit.Media— was a 42-line pass-through overMediaPreviewfromui-kit. Consumers should importMediaPreviewdirectly (prop names match 1:1).FooterMenuItem,FooterTitle— replaced byNavLinkItem/NavSectionHeadingfromui-kit.Footernow usesNavLinkItemdirectly for its contact rows.LightboxGallery— renamed toMediaGallery(see above).PageHeader— removed and inlined. Section-level page heroes (SectionPageHero) now composeLTextGroupandBackdropdirectly; there is no replacement ui component to import.CategoryNodeButton— replaced byMenuSideBySideNode(see ui-kit "Moved out" section).CategoryCard— replaced byLinkTilefromui-kit.CategoryCardGridandCategoryCardSlidernow renderLinkTilefor every variant;CategoryCardGridVariant/CategoryCardSliderVariantare aliases ofLinkTileVariant. The nodevariantfield is renamed tocardVariant.LightboxModal— replaced byLightboxin ui-kit (renamed fromMediaLightboxin this release).FilterBarQuickFilters— its quick-filter UI is integrated directly intoFilterBar; theFilterBarQuickFiltersPropstype export is removed.MobileMenuButtonGrid— removed (folded into theMobileMenuSharedfamily).FooterMenuDesktopItem— folded intoFooterMenu.CategoryHeaderBasic— removed (header chrome now built from page-hero + section composition).GridCardContent,GridCardTextContent— removed (card content now flows throughCardslots from ui-kit).
HeaderBasicandHeaderShopexposedesktopandmobilenamed slots that the hosting Section fills with block content. Inline navigation and mobile-menu markup is removed.HeaderBasicremoved props:menuItems,mobileMenuItems,socialLinks. TheMenuItem/SocialLinksinterfaces are no longer re-exported fromHeaderBasic.vue— import them fromMobileMenuBasic/types.HeaderShopremoved propnavigationMenuItemsand eventnavigationItemClick.NavigationMenuItemis removed.- Both headers now emit
menuClickwhen the mobile hamburger is activated; the hosting Section owns the mobile-menu open state. HeaderMenuContextcoordinates desktop (isOpen,selectedItemId,open,close) and mobile (isMobileOpen,openMobile,closeMobile) state.
MenuMegaMenuProps.contentLayoutremoved. The content-slot layout is auto-derived from the number of slotted children (0 → no content area, 1 → narrow single column, 2 → row/column, 3+ → 2×2 grid).- New
twoSlotDirection: 'row' | 'column'(default'row') controls the only design-variable case.
SectionFilterBarremoved inui-app; the filter bar is now block-only asBlockFilterBar.BlockFilterBaradopts the former section's Content and Design schema. The hosting Section provides background/margin/padding/style.
BrandHeronow uses the context-aware.radius-containedutility (rounds inside a padded container, flat edge-to-edge); the hardcodedborder-radius: 0is removed.
is*prefix sweep — for props where the subject is the component itself, theisprefix is dropped:SearchAutoSuggest:isLoading→loading; v-model channelisOpen→open(defineModel('isOpen')→defineModel('open')).MobileMenuListItem.isActiveis removed entirely. The prop never reached the DOM — visual:activestyling is driven by the CSS pseudo-class.MenuSideBySide.NavigationNode.isActivefollows.HeaderShop,HeaderBasic,FilterBar:isSticky→sticky.MobileMenuShop,MenuSideBySide: v-model channelisOpen/update:isOpen→open/update:open.HeroSlider:isFullHeight→fullHeight.isAboveTheFoldis kept (it states a fact about the slide's render context, not the component's own visual state).BreadcrumbsItem:isDropdown→dropdown.isCurrentPageis unchanged in this release; it flows through thecanonical-types/BreadcrumbItemZod schema and will be addressed in a separate canonical-types pass.CartListItem:isQuantityLoading→quantityLoading.ProductTileBasic:isAddToCartLoading→addToCartLoading;isAddToCartDisabled→addToCartDisabled.CouponBox:isApplied→applied. Also picks up the canonicalctaobject preset and richer error/success states.MenuItem.saleDesign(data shape used byMobileMenuBasicandHeaderBasicMenu):isSaleDesign→saleDesign.PlanComparisonTableRowValue:isHighlight→highlight.
Other prop / API changes:
HeaderBasicMenu—textColor→surfaceTone(semantic flip). The previoustextColornamed the foreground colour; the newsurfaceTonenames the surface against which the foreground is rendered. OldtextColor: 'dark'(dark text on light bg) maps to newsurfaceTone: 'light'; oldtextColor: 'light'maps tosurfaceTone: 'dark'. The default flips from'dark'to'light'accordingly. Sticky-header behaviour is unchanged: when fixed, the menu always renders against a light surface. (HeaderBasic.textColor— the header-level prop, not the menu-level one — is unchanged: still'light' | 'dark'. OnlyHeaderBasicMenu.textColorwas renamed/flipped tosurfaceTone.)Containercollapsesbackground+customBackgroundinto a single resolved value passed toBackdrop's:background. The:container-backgroundforwarding is dropped. (Container's public prop surface still declares bothbackgroundandcustomBackground; only the wire toBackdropis collapsed.)MediaText:containerBackgroundprop removed. Pass the resolved color via:background=directly (preset name or CSS color string). Same migration shape asContainer. The unusedcontainerBackgroundfield on the publishedBlockMediaTextContextinterface (runtime/components/MediaText/types.ts) is also removed.HeroSliderinternal: replaces the manualprovideSurfaceToneContext({ tone: activeSlideTone })call with an<OnSurface :tone="activeSlideTone">wrapper around the slider. Behavior identical; the change brings the component in line with the "only<OnSurface>may set tone publicly" rule.TopBarinternal: thenavItemSurfaceToneandswitcherSurfaceTonecomputeds are now wired into the template (NavigationMenuTextItemandLanguageSwitcher). OnmodeColor: 'grey'they inherit the ambient tone (was previously hardcoded'light'); on'black'mode they apply asymmetric'light'/'dark'per the original design intent.PageNotFound(wasError404Page):textColor: 'always-white' | 'always-black'replaced bysurfaceTone?: 'light' | 'dark'. Asset folderruntime/public/error-404-page/renamed toruntime/public/page-not-found/.AddToCart(wasBuyBoxCartButton):isLoading→loading;addToCartevent payload changed fromquantity: numbertoAddToCartPayload. New optionalproductId?/variantId?props.VariantSelectorOptions(wasVariantSelection):selectionChangeevent removed;selectedOptionsbecomes a v-model. New optionalid/disabled/required/invalidprops forField-context integration.VariantSelectorMultiple(wasMultipleVariantSelection):isOpenref →defineModel('open'); new optionalid/disabled/required/invalidprops.VariantOffCanvas(wasMultipleVariantSelectionSheet): explicitupdate:isOpenemit removed; v-model channel renamed toopen(covered bydefineModel('open')).MegaMenu(wasMegaMenuDesktop): complete API replacement. Old propscolorMode/isOpen/megaMenuItems/contentLayoutare gone. New propsitems: MegaMenuItem[];surfaceTone?: 'light' | 'dark';defaultValue?: string;delayDuration?: number;skipDelayDuration?: number. Trigger / content panels split intoMegaMenuTrigger/MegaMenuContentcompound parts. Promo-slot layout threshold: 1 promo →--narrow; 2 promos →--flex; 3+ promos →--grid(the first child spans two rows).Footer:columnsDesktopprop removed;alignmentandcontentAlignmenttyped asContentAlignmentHorizontalFieldValue.FooterMenu: exportedFooterMenuItemsinterface renamed toNavLinkItems(the items prop type).FilterBar:openFilterSheetButtonVariant→openFilterOffCanvasButtonVariant. The colocatedFilterBarQuickFiltersPropstype export is removed (its UI is folded intoFilterBar).FilterOffCanvas/AvailableFiltertype: union extended withAvailableFilterRange({ type: 'range', min, max, step?, formatLabel? }). Existing'boolean'/'list'members are unchanged.SelectedFilterRangealready existed; range is now a first-class supported filter type.SearchAutoSuggest(wasSearchOverlayInput): exported typesSearchOverlayInputProps/SearchOverlayInputSuggestionPropsrenamed toSearchAutoSuggestProps/SearchAutoSuggestItemProps.ContentSlider(wasGalleryContentSlider):colorMode,headline,sublinedefaults dropped; content now flows through slots.BrandList(wasBrandGrid): exportedBrandGridProps/BrandGridLinkrenamed toBrandListProps/BrandListItem.- Exported type renames — every
*Propstype follows its component rename:BasicHeroSliderProps→HeroSliderProps;BasicHeroSliderSlideProps→HeroSlideProps;BrandGridProps→BrandListProps;CmsImageTextProps→MediaTextProps;Error404PageProps→PageNotFoundProps;FilterSheetProps→FilterOffCanvasProps;GalleryContentSliderProps→ContentSliderProps;LightboxModalPropsremoved (useLightboxfrom ui-kit);MegaMenuDesktopPropsremoved (useMegaMenuProps);MultipleVariantSelectionProps→VariantSelectorMultipleProps;MultipleVariantSelectionSheetProps→VariantOffCanvasProps;MultipleVariantSelectionVariantProps→VariantSelectionCardProps(in ui-kit);PricingTableProps→PlanComparisonTableProps;PricingCardProps→PlanCardProps;ProductGridProps→ProductListingGridProps;SearchOverlayInputProps→SearchAutoSuggestProps;SearchOverlayInputSuggestionProps→SearchAutoSuggestItemProps;SearchResultHeaderProps→SearchResultHeroProps;ShopHeaderProps→HeaderShopProps;BuyBoxApplyDiscountCodeProps→CouponBoxProps;BuyBoxBenefitsBoxProps→BenefitsBoxProps;BuyBoxCartButtonProps→AddToCartProps(inline);BuyBoxEnergyLabelProps→EnergyLabelProps;BuyBoxPriceInfoProps→PriceInfoProps;BuyBoxProductInfoBasicProps→ProductTitleProps;BuyBoxQuantityPricesProps→QuantityDiscountProps;BuyBoxStockInfoProps(moved to ui-kit). Imports must be updated to the new module paths underruntime/components/<NewName>/typesor the.vuefile directly. PlanComparisonTableinterface is renamed toPlanComparisonTablePropsto resolve a component/type name collision. The component now forwardsshowChoosePlanto its header (previously dropped).ReviewItem:id: string→id?: string(the component never read the prop; onlyReview.vueneeded it for:key). Explicitid: undefineddefault.VariantSelectorOptions: numeric:font-weight="500"/"400"on the option title and selected-value<Text>are replaced byweight="medium"(Text accepts'bold' | 'semi-bold' | 'medium' | 'regular').VariantSelectorOptionsImageGrid:variant="subline"→type="subline"on the+N more variantslabel.HeroSlide: stray{{ overlay }}debug expression removed from the template.HeroSlide/HeroSliderstories: flag fixtures usevariant+colorScheme(the newFlagAPI).FilterOffCanvasCheckboxListItem: deaddefineModel<boolean>('item-selected')replaced by a one-wayitemSelectedprop.FilterOffCanvasSwatchList: unused requiredidprop dropped;FilterOffCanvasnow mounts the checkbox/swatch lists via staticv-ifbranches instead of<component :is>.FilterOffCanvasRangeSlider:SelectedFilterRangeis no longer redeclared; imported fromFilterOffCanvas/types.LogoSliderMode: reusesLogoSliderPropsheading shape instead of redeclaring.ReviewForm: deadupdate:ratingemit declaration removed.
MenuMegaMenuretains theecommerce-containerco-class on its root (it carries layout chrome the BEM class does not duplicate).BreadcrumbsItem:.breadcrumbs-item--is-active→.breadcrumbs-item--active(drop redundantis-modifier prefix).- BEM root renames following the component renames above:
MediaText:.cms-image-text*→.media-text*BrandList:.brand-grid*→.brand-list*HeaderShop:.shop-header*→.header-shop*ProductListingGrid:.product-grid*→.product-listing-grid*ContentSlider:.gallery-content-slider*→.content-slider*EditorialGrid:.articles-grid*→.editorial-grid*ContentGrid:.card-grid*→.content-grid*PageNotFound:.error-404-page*→.page-not-found*MobileMenuBasic:.mobile-menu*→.mobile-menu-basic*MobileMenuShop:.mega-menu-mobile*→.mobile-menu-shop*MenuSideBySide:.side-by-side-menu*→.menu-side-by-side*(also the*Child/*Rootsiblings)HeroSlider/HeroSlide:.basic-hero-slider*/.basic-hero-slider-slide*→.hero-slider*/.hero-slide*
Containeruses.s-scontaineras the root block (NOT.containeror.s-container, both of which collide with utility classes). Modifiers:--full-width/--boxed;--h-align-{left,center,right};--v-align-{top,center,bottom}; child grid block.s-scontainer__grid.
- Removed
useSwatchBrightnessfrom@laioutr-core/ui(composables/useColorBrightness.tsdeleted). Import from@laioutr-core/ui-kitinstead —utils/swatchBrightness.ts. - Removed
useImageZoomPanfrom@laioutr-core/ui(composables/useImagezoomPan.tsdeleted). Import from@laioutr-core/ui-kitinstead —composables/useImageZoomPan.tsandutils/imageZoomPan.ts. - Removed
runtime/utils/storybookSection.ts— internal story decorator (asSection()). useCategoryNavigation: internalDesktopCategoryNodetype (fromSideBySideMenu) renamed toNavigationNode(fromMenuSideBySide/types). Public function signature unchanged.useMobileMenuNavigation: internalMobileMenuItemtype now imports fromMobileMenuShop/types(wasMegaMenuMobile/types); public signature unchanged.
- Auto-import prefix unified to
Land the three-bucket structure (addLuiComponentsDir('molecule'),('organism'),('page'),('section')) collapsed into a singleaddComponentsDir({ path: './components', prefix: 'L', pathPrefix: false })over a flatruntime/components/<Name>/<Name>.vuelayout. There is no longer a section/block/page/molecule/organism distinction inmodule.ts. - Removed manual
addComponent('LuiCommonSwiper')(CommonSwiper.component.tsis deleted) and removedinstallModule('nuxt-swiper')from the ui module — Swiper is now provided by ui-kit. - Removed
installModule('@laioutr-core/frontend-core')/'@laioutr-core/orchestr'from the prepare-step branch (uino longer self-installs sibling modules duringnuxi prepare).
- The
PlanCardSliderSwiper config migrated to the canonicalswiperBreakpointshelper in ui-kit ('#ui-kit/utils/swiperBreakpoints'); numeric scale replaces inline string-pixelspaceBetween. - Asset
mobile-menu-banner-bg.pngmoved fromruntime/assets/img/toruntime/components/MobileMenuShared/. - New helper
components/_shared/ctaBanner.ts— exports the shared cta object used byBannerBasic/BannerIntegrated/BannerShowcase. - Storybook playground page demos (
Homepage,Landingpage,BlogOverviewPage,BlogPostPage,BrandOverviewPage,BrandPage,SearchResultsPage) removed; not part of the public package surface.
New Old SectionHeaderBasicSectionBasicHeaderSectionHeroSliderSectionBasicHeroSliderSectionMediaTextSectionImageAndContentSectionPersonaQuoteSliderSectionTestimonialPersonaQuoteSectionQuoteCardSliderSectionTestimonialQuoteCardSliderSectionBrandListSectionBrandLinkSectionSearchResultHeroSectionSearchResultHeaderSectionPlanCardSliderSectionPricingPlansSectionPlanComparisonTableSectionPricingTableSectionPageHeroSectionPageHeader/SectionCategoryHeaderSectionHeaderShopSectionShopHeaderSectionPageNotFoundSectionError404SectionProductDetailSectionProductDetailContainerSectionLogoSlider/SectionLogoGridSectionLogoPresentation(split by oldviewdiscriminator:view: 'slider'→SectionLogoSlider,view: 'grid'→SectionLogoGrid)SectionBannerBasic/SectionBannerIntegrated/SectionBannerShowcaseBlockCtaBannerBasic/BlockCtaBannerIntegrated/BlockCtaBannerShowcase(banner blocks promoted to sections; lifted out of hostSectionContainerslots into the page-levelsectionsarray)SectionContainerSectionBannerContainer(consolidated;SectionContaineris now a thin wrapper over the newContainerorganism inui)New Old BlockHeroSliderSlideBlockBasicHeroSliderSlideBlockPersonaQuoteBlockTestimonialBlockProductsListingBlockProductGridBlockPaginationBlockQueryPaginationBlockSortModesBlockQuerySortingBlockButton(Studio labelCMS Button→Button)BlockCmsButtonBlockCardBlockCmsCardContentBlockLogoSliderSlideBlockSingleLogoPresentationSectionBlogSlider,SectionFlexibleContentSlider→SectionContentSlider(now hybrid slot/query).SectionTestimonialQuoteCard→SectionQuoteCardSliderwith a single slide.SectionCardGrid→ newSectionContentGrid(defaultdataSource: 'slot', preserve slot contents).SectionInpageNavigationBasic/Big/Compact→SectionCategoryCardGrid/SectionCategoryCardSlider.SectionAmbiendoHeader→SectionHeaderShopwithBlockMenuSideBySidein the newmenuslot. Field mapping:logoLight→SectionHeaderShop.logo;logoDarkdropped (single-logo model);logoMenu→BlockMenuSideBySide.logoMenu;mobileSearchStyle→SectionHeaderShop.searchBarMobile;rootMenu→BlockMenuSideBySide.rootMenu;navigationMenuItems→BlockMenuSideBySide.navigationMenuItems;extraMenuItems→SectionHeaderShop.navigationMenuItems(flat top-bar);showCart/showSearch/showWishlist/showCustomerAccountunchanged.SectionShopHeaderNavigation→ demoted intoBlockMenuSideBySideinsideSectionHeaderShop.desktop/SectionHeaderBasic.desktop. Standalone instances must be lifted into a hosting header section.BlockProductReviews→SectionProductReviews.BlockInpageNavigationBasicGrid.
SectionContentGrid— hybrid slot/query wrapper.dataSource: 'slot'(default;BlockCardvia thedefaultslot) ordataSource: 'query'(auto-populated from a blog post collection).SectionEditorialGrid— Content (caption, heading, subline with visibility toggles,featuredCount) + Design (background, margin, padding via shared-field presets);cardsslot restricted toBlockCard.SectionCategoryCardGrid— grid counterpart toSectionCategoryCardSlider.SectionProductReviews— replaces the legacy block-level implementation.SectionUspBanner(existing section, reshaped) — dropsbannerStyle, dropscolors(colors.textColor→ top-levelcolor,colors.iconColor→ top-leveliconColor), and extracts the previoususps[]field into a newitemsslot populated byBlockUspBannerItemchildren.SectionContentSlider— adopts hybrid slot/query data source (defaultslot;queryis opt-in).
BlockCategoryCard,BlockUspBannerItem— non-standalone children for the new sections.BlockProductsListing,BlockFilterBar,BlockSortModes,BlockPagination— split out of the previous combinedSectionProductListing.BlockMobileMenuBasic,BlockMobileMenuShop— non-standalone, hosted in themobileslot ofSectionHeaderBasicandSectionHeaderShop. Carry the menu-items array,socialMediaLinks,languageSelect,modeSwitcherfields that previously lived on the sections.BlockMenuSideBySide— non-standalone, in thedesktopslot ofSectionHeaderShop. ThenavigationMenuItems/navigationMenuDataconfiguration moves from the section to the block.BlockMenuHeaderBasic— non-standalone, in thedesktopslot ofSectionHeaderBasic. MirrorsBlockMenuSideBySidebut for the basic header.BlockMegaMenu— collapsed to a thin schema/data-binding wrapper around the newMegaMenucompound inui.BlockProductDetailVariantSelectorOptions— non-standalone child for product-detail variant configuration.
Across 30+ sections/blocks the schema has been normalized to the section-config-standard:
Old New blockMarginmargin(usesmarginFieldpreset)blockPaddingpadding(usespaddingFieldpreset)contentColor(SectionProductSliderShowcase)backgroundBrightness(with enum remap:on-light→light,on-dark→dark,on-bright→bright)contentColor(SectionProductSlider)(dropped — no replacement) textAlignmentalignmentactionButton[0](array)cta(object viabuttonFields) +ctaVisiblesectionBackground/themePresets/customBackgroundbackground+customBackground(viabackgroundFields). Value remap onSectionContainer: oldtheme-presetsvalue flattens to whichever ofsolid/pale/defaultthe separatethemePresetsfield held; the standalonethemePresetsprop is dropped.headline*heading*SectionBrandHero.background(media)backgroundImage(the canonicalbackgroundname is now free for the painted background)productAmountNumber/productAmountWord(SectionFilterBar)productAmount.number/productAmount.word(both gainallowCustom: true)accordionStyle(BlockAccordion)variantcontentPosition(SectionMediaText)alignment(toggle button)image(SectionNewsletterRegistration)mediaoverlay/overlayStyle/overlayOpacity(BlockHeroSliderSlide)backgroundOverlay(object;variant === 'off'means no overlay)buttonText/buttonLink/buttonVariant(BlockCard)cta(object)productFlags(SectionProductSlider,SectionProductSliderShowcase)showFlagsinline checkbox + as: 'visibility'visibilityField()factoryinline button-variant arrays buttonVariantOptions(canonicalButtonVariantvalues)is*-prefixed schema fields are kept unchanged (isSticky,isSaleDesign) so customer-stored configurations continue to bind without a data migration; bindings now adapt at the section/block level (:sticky="props.isSticky").Component-specific prop renames not covered by the cross-cutting table above. Each row maps to a stored Studio-data migration.
Section / block Old New BlockIframeurlsrcBlockHeroSliderSlidectasslideButtonsBlockHeroSliderSlideflagscaptions(reshape)BlockHeroSliderSlidebackgroundBrightness(dropped) BlockTextresponsiveSizing(boolean)(dropped — no replacement) SectionScrollAnchoridanchorNameSectionTopBarbackgroundColorcolorModeSectionTopBarshowLanguageSwitchshowLocaleSelectorSectionTopBarshowModeSwitchershowDarkModeToggleSectionFootershowIconButtonssocialIconsVisibleSectionFootershowEmailButtonemailButtonVisibleSectionFooterblockMarginmarginSectionFooterblockPaddingpaddingSectionFooteremailButtonConfig.*emailButton(object reshape)SectionPageHerotitleheading(note: not covered by the genericheadline* → heading*row)SectionHeaderBasiccallToActionButtonctaButtonsSectionHeaderBasicheaderPaddingpaddingSectionPersonaQuoteSliderstylecontainerStyleSectionPersonaQuoteSlidersectionBackgroundbackgroundSectionQuoteCardSlidercardStyleFieldscardStyleSectionQuoteCardSlidercontentAlignmentalignmentSectionQuoteCardSlidersectionBackgroundbackgroundSectionCategoryCardSliderheaderheadingSectionCategoryCardSlidernodesVariantvariantSectionProductSliderbrandshowBrandSectionProductSliderproductDescriptionshowProductDescriptionSectionProductSliderratingshowRatingSectionProductSliderctabuttonSectionProductSliderblockMarginmarginSectionProductSliderinnerBlockPaddingpaddingSectionProductSliderShowcasebannerMediabannerImageSectionProductSliderShowcaseshowAddToCartButtonshowAddToCartSectionProductSliderShowcasecolorSwatchescolorSwatchPositionSectionProductSliderShowcasemaxTitleLengthtitleLengthSectionProductSliderShowcaseblockMarginmarginSectionProductSliderShowcaseblockPaddingpaddingSectionProductSliderShowcasebrand/productDescription/ratingshowBrand/showProductDescription/showRating<parent>.overlay.styleinner-key on overlayshared-field<parent>.overlay.variant(6 HEAD consumers:SectionBannerBasic.backgroundOverlay,SectionBannerIntegrated.backgroundOverlay,SectionBannerShowcase.backgroundOverlay,SectionBrandHero.backgroundOverlay,SectionProductSliderShowcase.backgroundOverlay,BlockHeroSliderSlide.backgroundOverlay)Section Field(s) dropped SectionBreadcrumbscolorMode(entireStylefieldset removed)SectionNewsletterRegistrationtextColor,legalSectionPersonaQuoteSlidertextColorSectionQuoteCardSlidercardStyle,profilePictureSectionCategoryCardSliderhasSubCategories,colorModeSectionUspBannerbannerStyle,colors(colors.textColor→ top-levelcolor,colors.iconColor→ top-leveliconColor);usps[]extracted to newitemsslot populated byBlockUspBannerItemThe
ctaButton.variantenum was reshaped from 12 to 14 values via the newbuttonFields.variant(sourced frombuttonVariantOptions). Applies to every Studio-stored*.variantfield acrossBlockText.cta,SectionProductSlider.button, all banner CTAs, etc.Old ( ctaButton.variant)New ( buttonFields.variant)primaryprimarysecondarysecondarywhite-ghostghost-whiteglassglass-black(verify with design)white-secondarysecondary-whiteblack-ghostghost-blackwhite-closeclose-whiteinput-field(dropped — no direct equivalent; map to subtleor drop)glass-whiteglass-whiteblack-closeclose-blackblack-close-always-blackclose-black(losesalways-blacksemantics)white-close-always-whiteclose-white(losesalways-whitesemantics)New variants without a predecessor (no migration needed):
tertiary,positive,danger,subtle,info.- New shared-field presets in
shared-fields/:background.ts,margin.ts,padding.ts,size.ts,visibility.ts,buttonVariant.ts,themedStyleColor.ts,button.ts,containerStyle.ts,headingElement.ts,surfaceTone.ts. - Deprecated and removed:
shared-fields/backdrop.ts(replaced bybackground/margin/padding),shared-fields/ctaButton.ts(replaced byshared-fields/button.ts+shared-fields/buttonVariant.ts; see the value-remap table above). - Modified:
shared-fields/overlay.ts— inner-field renamestyle→variant(6 HEAD consumers; cross-cutting, see the per-section table above). - Modified:
shared-fields/productTileQuery.ts— wrapper-fieldset removed; theproductsprop name is unchanged (no data migration), but the Studio panel grouping shifts from a dedicated "Products" sidebar to inline within the host's "Content" fieldset. Cosmetic for stored data. - Top-level panels normalized to
Content+Design(withStyling/Layoutinfo-dividers) across 30+ sections/blocks. SectionHeaderBasicbackground narrowed frombackgroundField + customBackgroundto'transparent' | 'solid'(defaulttransparent) — the only two valuesHeaderBasicactually renders. Studio-data migration: storedbackgroundvalues that aren'ttransparentorsolidshould be dropped (no remap).SectionEditorialGriduses the same custom-background resolver pattern asSectionProductReviews::background="background === 'custom' ? colorValueToCss(customBackground) : background".SectionQuoteCardSlider.cardsAlignmentfield swapped from a 9-valuecontent_alignmentto atoggle_buttonwithleft/center(matchesQuoteCardSlider.cardsAlignment).SectionProductReviews: dropped the unusedpercentagefield andtotalintermediate fromratingLevels; stars tuple typedas const.SectionProductSlider/SectionProductSliderShowcase/ConnectedProductTileBasic:productFlags→showFlags.ConnectedProductTileBasicnow declares and forwardsshow-add-to-cart,show-brand,show-product-description,show-flags,show-rating.showRatingis wired via:rating="showRating === false ? undefined : product.rating".
SectionBlogPostDetail,SectionProductDetail,SectionScrollAnchor,SectionBlogPostListing,SectionMediaText,BlockMedia,BlockIframeare now thin configuration adapters over the correspondinguicomponents. Imports moved into<script setup>; emptyDesignpanels dropped where appropriate.BlockFooterMenuupdates theitemsarray schema (itemLabelProperty+labelSingularinstead of a fieldset label).
Six sections (
SectionCategoryCardGrid,SectionCategoryCardSlider,SectionContentGrid,SectionContentSlider,SectionMediaText,SectionPlanComparisonTable) collapse the two-propbackdropBackground+backdropContainerBackgroundpattern into a singleresolvedBackgroundpassed toBackdrop's:background.Backdropno longer receives:container-background.HeaderBasicMenucolour values flip. The proptextColornamed the foreground colour; the newsurfaceTonenames the surface. Oldtext-color="dark"(dark text on light bg) maps to newsurface-tone="light", not"dark". Migrate by inverting the value, not just renaming the prop.Auto-import tag prefix unified to
<L*>.@laioutr-core/uipreviously registered components with theLuiprefix; it now usesL, matching@laioutr-core/ui-kit. Templates that referenced<Lui*>for anyuicomponent must be renamed to<L*>— e.g.<LuiProductSlider>→<LProductSlider>,<LuiMenuSideBySide>→<LMenuSideBySide>. Components moved fromui-kittoui(Cart family,ReviewForm,SocialShare,MobileMenuShared/*,MenuSideBySideNode,BreadcrumbsItem,MediaGallery,SearchResultHero,FilterOffCanvas*subcomponents,VariantSelectorConfigurator*,VariantSelectorMultipleTrigger,VariantSelectorMultipleAvailability) keep their existing<L*>prefix — no template rename is needed for the move itself.- import OnBackground from '#ui-kit/components/OnBackground/OnBackground.vue'; + import OnSurface from '#ui-kit/components/OnSurface/OnSurface.vue'; - import { colorToBackground } from '#ui-kit/imports/colorToBackground'; + import { colorToSurfaceTone } from '#ui-kit/imports/colorToSurfaceTone'; - import LightboxGallery from '#ui/components/LightboxGallery/LightboxGallery.vue'; + import MediaGallery from '#ui/components/MediaGallery/MediaGallery.vue'; - import LoginReviewPanel from '#ui-kit/components/LoginReviewPanel/LoginReviewPanel.vue'; + import StatusMessage from '#ui-kit/components/StatusMessage/StatusMessage.vue'; - import CategoryCard from '#ui-kit/components/CategoryCard/CategoryCard.vue'; + import LinkTile from '#ui-kit/components/LinkTile/LinkTile.vue'; - import Card from '#ui/components/Card/Card.vue'; + import Card from '#ui-kit/components/Card/Card.vue'; - import Iframe from '#ui/components/Iframe/Iframe.vue'; + import Iframe from '#ui-kit/components/Iframe/Iframe.vue'; - import Media from '#ui/components/Media/Media.vue'; + import MediaPreview from '#ui-kit/components/MediaPreview/MediaPreview.vue'; - import ReviewForm from '#ui-kit/components/ReviewForm/ReviewForm.vue'; + import ReviewForm from '#ui/components/ReviewForm/ReviewForm.vue'; - import Breadcrumb from '#ui-kit/components/Breadcrumb/Breadcrumb.vue'; + import BreadcrumbsItem from '#ui/components/Breadcrumbs/BreadcrumbsItem.vue'; - import Header from '#ui/components/Header/Header.vue'; + import HeaderBasic from '#ui/components/HeaderBasic/HeaderBasic.vue'; - import MobileMenu from '#ui/components/MobileMenu/MobileMenu.vue'; + import MobileMenuBasic from '#ui/components/MobileMenuBasic/MobileMenuBasic.vue'; - import MegaMenuMobile from '#ui/components/MegaMenuMobile/MegaMenuMobile.vue'; + import MobileMenuShop from '#ui/components/MobileMenuShop/MobileMenuShop.vue'; - import SideBySideMenu from '#ui/components/SideBySideMenu/SideBySideMenu.vue'; + import MenuSideBySide from '#ui/components/MenuSideBySide/MenuSideBySide.vue'; - import ArticlesGrid from '#ui/components/ArticlesGrid/ArticlesGrid.vue'; + import EditorialGrid from '#ui/components/EditorialGrid/EditorialGrid.vue'; - import CardGrid from '#ui/components/CardGrid/CardGrid.vue'; + import ContentGrid from '#ui/components/ContentGrid/ContentGrid.vue'; - import SearchOverlayInput from '#ui/components/SearchOverlayInput/SearchOverlayInput.vue'; + import SearchAutoSuggest from '#ui/components/SearchAutoSuggest/SearchAutoSuggest.vue'; - import PricingCard from '#ui/components/Pricing/PricingCard/PricingCard.vue'; + import PlanCard from '#ui/components/PlanCard/PlanCard.vue'; - import PricingTable from '#ui/components/Pricing/PricingTable/PricingTable.vue'; + import PlanComparisonTable from '#ui/components/PlanComparisonTable/PlanComparisonTable.vue'; - <LuiProductSlider /> <!-- old: ui registered components with the Lui prefix --> + <LProductSlider /> <!-- new: ui uses L, matching ui-kit. Applies to every native-ui component. --> - <LuiMenuSideBySide /> + <LMenuSideBySide />
- <Button type="icon" size="medium" /> + <IconButton label="..." icon="..." size="m" /> - <Button> - <template #iconLeft><Icon name="..." /></template> - </Button> + <Button :icon-left="iconName" /> - <Button variant="input-field" /> + <Button variant="subtle" /> - <Input :is-error="hasError" /> + <Input :invalid="hasError" /> - <Field :error="errorString" /> + <Field :error-message="errorString" /> + <!-- Field auto-derives `invalid` from `errorMessage`. Pass :invalid="…" explicitly only to override. --> - <Label :error="hasError" /> + <Label :invalid="hasError" /> - <Select size="small" /> + <Select :trigger="{ size: 's' }" /> - <Accordion accordion-style="..." /> + <Accordion variant="..." /> + <!-- BlockAccordion's Studio schema field also renames accordionStyle → variant; data migration required. --> - <SwatchChip color-mode="dark" /> + <SwatchChip surface-tone="dark" /> - <HeaderBasicMenu text-color="dark" /> <!-- old: dark text --> + <HeaderBasicMenu surface-tone="light" /> <!-- new: light surface -> dark text. VALUE FLIPS. --> - <Badge is-rounded /> + <Badge rounded /> - <Toast :is-open="open" /> + <Toast :open="open" /> - <Pagination :is-navigation-numbers="true" /> + <Pagination variant="numbers" /> - <OptionTileImage :not-available="{ isNotAvailable: true, notAvailableTooltip: '…' }" /> + <OptionTileImage unavailable unavailable-tooltip="…" /> - <SearchAutoSuggest :is-loading="loading" /> + <SearchAutoSuggest :loading="loading" /> - <SearchAutoSuggest v-model:is-open="open" /> + <SearchAutoSuggest v-model:open="open" /> - <HeaderBasic :is-sticky="sticky" /> + <HeaderBasic :sticky="sticky" /> - <MobileMenuShop :is-open="open" @update:isOpen="open = $event" /> + <MobileMenuShop :open="open" @update:open="open = $event" /> - <MenuSideBySide v-model:is-open="isOpen" /> + <MenuSideBySide v-model:open="isOpen" /> - <HeroSlider :is-full-height="full" /> + <HeroSlider :full-height="full" /> - <CouponBox :is-applied="applied" /> + <CouponBox :applied="applied" /> - <MobileMenuListItem :href="..." :is-active="active" /> + <MobileMenuListItem :href="..." /> + <!-- The active prop is removed; visual :active styling is driven by the CSS pseudo-class. --> - <BannerBasic variant="boxed" /> + <BannerBasic /> <!-- wrap in .ecommerce-container or .radius-contained for the boxed look --> - <LSwiperCompact /> + <LSwiperNavBar /> - <LSwiperFadeoutArrows :has-fadeout-background="false" /> + <LSwiperArrows :fadeout="false" /> - <LSwiperThumbnailsSlider /> + <LThumbnailsSlider /> - <Switch v-model:checked="open" /> + <Switch v-model="open" /> - <Checkbox v-model:checked="agreed" /> + <Checkbox v-model="agreed" />
- .breadcrumbs-item--is-active { ... } + .breadcrumbs-item--active { ... } - .swatch-chip.is-selected { ... } + .swatch-chip--selected { ... } - .switch--small { ... } + .switch--s { ... } - .round-spinner-s { ... } + .round-spinner--s { ... } - .swiper-chrome__head-top { ... } + .swiper-chrome__head--top { ... } - .user-avatar { ... } + .avatar { ... } - .toast__progress-bar { ... } + .toaster-progressbar { ... } - .newsletter-form { ... } + .email-input-form-display { ... } - .newsletter-block { ... } + .newsletter-registration { ... } - .popup, .popup-info, .popup-newsletter, .popup-promotion + .pop-up, .pop-up-info, .pop-up-newsletter, .pop-up-promotion - .search-suggestion { ... } + .search-auto-suggest-item { ... } - .search-overlay { ... } + .search-auto-suggest { ... } - .lightbox-gallery { ... } + .media-gallery { ... } - .login-review-panel { ... } + .status-message { ... } - .swatch-preview { ... } + .swatch { ... } - .swatch-item { ... } + .swatch-option { ... } - .product-tiles-swatches { ... } + .swatch-summary { ... } - .menu-link-item { ... } + .nav-link-item { ... } - .menu-section-title { ... } + .nav-section-heading { ... } - .navigation-node-button { ... } + .menu-side-by-side-node { ... } - .variant-option-selector-button, .variant-option-selector-image + .option-tile-text, .option-tile-image - .zoom-level-mobile, .zoom-level-desktop + .zoom-level-segmented, .zoom-level-stepper - .pricing-card, .pricing-grid, .pricing-table + .plan-card, .plan-card-slider, .plan-comparison-table - .cms-image-text* { ... } + .media-text* { ... } - .brand-grid* { ... } + .brand-list* { ... } - .shop-header* { ... } + .header-shop* { ... } - .product-grid* { ... } + .product-listing-grid* { ... } - .gallery-content-slider* { ... } + .content-slider* { ... } - .articles-grid* { ... } + .editorial-grid* { ... } - .card-grid* { ... } + .content-grid* { ... } - .error-404-page* { ... } + .page-not-found* { ... } - .mobile-menu* { ... } + .mobile-menu-basic* { ... } - .mega-menu-mobile* { ... } + .mobile-menu-shop* { ... } - .basic-hero-slider* { ... } + .hero-slider* { ... } - .basic-hero-slider-slide* { ... } + .hero-slide* { ... } - .media-block* { ... } + .media-preview* { ... }
- t('lightboxGallery.close') + t('mediaGallery.close') - t('colorSwatch.tooltipSingle', ...) + t('swatchChip.tooltipSingle', ...) - t('couponCodeInput.placeholder') + t('cart.couponCode.placeholder') /* placeholder copy reuses cart.couponCode */ - t('couponCodeInput.clear') + t('inputSearch.clear') /* clear-button copy reuses inputSearch.clear */
Stored Studio configurations must be migrated for every renamed or deleted section/block component string (see the section and block rename tables above), every renamed schema field, and every promoted or demoted section ↔ block.
A few non-obvious cases:
- Custom themes that defined
backgroundAwareBackdropwith'default'as a value must rewrite those entries with the equivalentSurfaceTonedirectly ('default'was a synonym for'light'). - The
BlockAccordion.accordionStyleschema field is renamed tovariant; configurations keyed on the old name fall back to the default (simple) until re-saved. - Single-dash modifier classes on
MediaText(e.g..media-text__media-keep-ratio,.media-text__media-cs-boxed-bg-none,.media-text__media-keep-ratio-cs-full-width,.media-text__media-container-keep-ratio) andPlanCard(.plan-card-true-animation,.plan-card-false-animation) are now double-dashed (--keep-ratio,--cs-boxed-bg-none,--true-animation,--false-animation). External CSS overrides relying on the old class names need updating. HeaderBasic's utility class.header_switchersis now.header-basic__switchers; the global sticky-layout class.lui-header--fixedis.lui-header-basic--fixed.
- Updated dependencies [97e4e2d]
- @laioutr-core/ui-kit@2.0.0