Skip to content

Instantly share code, notes, and snippets.

@screeny05
Created May 15, 2026 09:50
Show Gist options
  • Select an option

  • Save screeny05/51f8509ed27191ccba8a169f8cf097f8 to your computer and use it in GitHub Desktop.

Select an option

Save screeny05/51f8509ed27191ccba8a169f8cf097f8 to your computer and use it in GitHub Desktop.

@laioutr-core/ui

2.1.0

Minor Changes

  • 66e5151: Restore banner / category-slider / showcase parity with v1.

    • BannerBasic (ui): new optional size prop ('s' | 'm' | 'l', default 'm') — scales the text stack; heading scales one step above body. New optional aspectRatio prop — applies a CSS aspect-ratio to the banner root.
    • CategoryCardSlider (ui): new optional cta prop ({ text, link, variant }) — rendered as a button in the slider's heading area via the existing SwiperChrome.buttons slot.
    • New BlockBannerBasic, BlockBannerIntegrated, BlockBannerShowcase blocks (ui-app) — first-class block versions of the banner trio (previously only available as SectionBanner*).
    • BlockBannerBasic (ui-app): new optional aspectRatio schema field (text input, e.g. '1/1', '16/9').
    • SectionCategoryCardSlider (ui-app): new optional cta schema field (object via buttonFields) with ctaVisible visibility decorator, plumbed through to the underlying CategoryCardSlider.
    • SectionProductSliderShowcase (ui-app): new optional bannerTextSize schema field (s / m / l, default m), routed to the inner BannerBasic.size.
    • SectionContentSlider (ui-app): removed the cosmetic hardcoded surface-tone="'light'" binding. The underlying ContentSlider did not consume the prop, so there is no rendering change; surface tone now derives from the outer Backdrop as intended.

Patch Changes

  • abe2a44: Route elevation shadows through the --shadow-s / --shadow-m / --shadow-l design tokens instead of hardcoded box-shadow values. 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

2.0.0

Major Changes

  • 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.

    @laioutr-core/ui-kit

    New components

    • IconButton — dedicated icon-only button atom. Required label: string (rendered as aria-label) and icon: IconName props. Owns shape chrome only; delegates variant/state styling to Button.
    • TextGroup — caption + heading + subline molecule with configurable semantic tags (captionTag, headingTag, sublineTag), size tiers (s/m/l), alignment, gap, and optional icon / iconSize / iconColor.
    • OnSurface — replaces OnBackground. Provides surface-tone context ('light' | 'dark' | 'bright'); inherits from the nearest ancestor OnSurface when tone is omitted. Emits --font-color-* and --icon-color tokens for descendants.
    • LinkTile — flat wrapper that routes to LinkTileBasic / LinkTileCompact / LinkTileBig based on variant: 'basic' | 'compact' | 'compact-bordered' | 'big'. Replaces CategoryCard.
    • HighlightToggle — generic two-way v-model toggle with label / badge / ariaLabel. Replaces the domain-specific BillingCycleSwitch.
    • StatusMessage — generic icon-led message composition. Required icon: IconName, optional title, description, status?: 'default' | 'success' | 'warning' | 'error' (colors the icon via --success-9 / --warning-9 / --error-9). Replaces LoginReviewPanel (which hardcoded login/check icons + success tint).
    • MediaStage — bare media + content stage primitive. Replaces CtaBannerBase.
    • Reka-UI atoms: Tabs, Popover, ContextMenu, Listbox, InputSlider.
    • InputAutocomplete and InputCombobox — data-driven options: { value, label, disabled? }[] molecules wrapping reka-ui's Autocomplete / Combobox. InputCombobox supports multiple and a displayValue: (value: string | string[]) => string prop.
    • InputPin — coordinated row of input cells; styling mirrors Input (same border/focus tokens, 48px cell height).
    • useSwiperEdgeState composable — consolidates isBeginning / isEnd event wiring previously duplicated across the Swiper widget family.
    • NavLinkItem — generic navigation list-row link primitive (href?, icon?: IconName, hug?: boolean). Replaces the old MenuLinkItem in ui.
    • NavSectionHeading — navigation-list heading primitive (href?); renders as NuxtLink when href is set. Replaces MenuSectionTitle and FooterTitle.
    • 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 (via defaultValue: number[]), with min / max / step / orientation / label props.
    • Iframe — sandboxed iframe wrapper with src / title / aspectRatio props and a ref on the underlying <iframe>.
    • BadgePromotion — promotional badge atom. Replaces SavingsBadge. Props: variant?: 'promo' | 'sale' | 'new' | 'icon', radius?: 'equal' | 'unequal', size?: 's' | 'm', icon?: IconName, text?: string, savingPercentage?: number, withNotch?: boolean. The previous badgeVariant field is now variant; the previous required savingPercentage is now optional. BEM root .badge-promotion (was .saving-percentage).
    • Moved in from @laioutr-core/ui: DarkModeSwitch, BuyBoxStockInfo (now StockInfoSummary), LanguageSwitcher, RatingProgressBarFilter. (Iframe and Card are NOT moves: Iframe is a brand-new ui-kit component, and Card was 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, ThumbnailsSlider moved from @laioutr-core/ui. The renames in the table above apply at the new location. SwiperScrollbar moves without a rename — import SwiperScrollbar from '#ui-kit/components/SwiperScrollbar/SwiperScrollbar.vue' instead of '#ui/...'.

    Renamed components (final names)

    New Old
    Swatch SwatchPreview
    SwatchChip ColorSwatch
    SwatchOption SwatchItem
    SwatchSummary ProductTilesSwatches (was in ui)
    InputRadio / InputRadioItem Radioselect / RadioselectItem
    InputPassword PasswordInput
    InputSearch SearchInput
    InputRating RatingInput
    InputPin PinInput
    OptionTileText VariantOptionSelectorButton
    OptionTileImage VariantOptionSelectorImage
    VariantSelectionCard VariantSelectorMultipleVariant
    ZoomLevelSegmented ZoomLevelMobile
    ZoomLevelStepper ZoomLevelDesktop
    EmailInputForm / EmailInputFormDisplay NewsletterInputBox / NewsletterInputBoxDisplay
    Lightbox MediaLightbox
    SwiperBullets SwiperNavigationBullets
    SwiperNumbers SwiperNavigationNumbers
    SwiperNavBar SwiperNavigationCompact (was previously SwiperCompact)
    SwiperArrows SwiperFadeoutArrows (and prop hasFadeoutBackgroundfadeout, default true)
    ThumbnailsSlider SwiperThumbnailsSlider
    StatusMessage LoginReviewPanel
    StockInfoSummary BuyBoxStockInfo (was in ui; size 'small' | 'medium''s' | 'm')

    For every rename: file path, folder, exported *Props type, auto-imported tag, and BEM block class follow the new name.

    Removed components

    • OnBackground — use OnSurface.
    • BillingCycleSwitch — use HighlightToggle.
    • CategoryCard — use LinkTile. CategoryCardProps and CategoryCardVariant exports are gone.
    • Breadcrumb — moved to @laioutr-core/ui as BreadcrumbsItem. The isProduct prop is gone.
    • Menubar, Stepper, HoverCard — unused, removed.
    • DiscountFlag — use Badge with a leftIcon prop and the default slot for text.
    • SavingsBadge — replaced by BadgePromotion (redesigned, not a 1:1 rename; see "New components").
    • SwiperNavigationNumbersWithArrows — same UI is reachable via SwiperNavBar with navigationStyle="numbers".

    Moved out (now in @laioutr-core/ui)

    • LightboxGallery → renamed to MediaGallery.
    • SearchResultHeader → renamed to SearchResultHero.
    • ReviewForm.
    • SocialShare.
    • NavigationNodeButton → renamed to MenuSideBySideNode (now under ui/components/MenuSideBySide/); NavigationNode type moves to #ui/components/MenuSideBySide/types.
    • The redundant FilterOffCanvasSwatchListItem is removed; FilterOffCanvasSwatchList binds SwatchOption directly.

    The Cart family (CartListItem, CartSummaryBox, EmptyStateCart, FreeDeliveryProgress, CartCouponCodeAccordion, CartCouponCodeAccordionInput), the VariantSelectorConfigurator* family, VariantSelectorMultipleTrigger, VariantSelectorMultipleAvailability, MobileMenuShared/* (was MobileMenuBanner / MobileMenuButton / MobileMenuList / MobileMenuListItem), and the FilterOffCanvas* subcomponents (FilterOffCanvasAccordionItem, FilterOffCanvasCheckboxList, FilterOffCanvasCheckboxListItem, FilterOffCanvasRangeSlider, FilterOffCanvasSwatchList, FilterOffCanvasSwitchItem) were already in @laioutr-core/ui at base under nested organism/... paths. They are renamed/flattened within ui rather than moved from ui-kit — see the @laioutr-core/ui "Renamed and flattened within ui" entry.

    Button refactor

    • Button.type prop removed. Use the new IconButton for 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. ButtonVariant is a single union (14 values). CtaButtonVariant and IconOnlyButtonVariant sub-unions are removed.
    • Variant renames: 'input-field''subtle'. 'video-control' removed.
    • Legacy alias layer dropped: LegacyButtonVariant, ButtonVariantInput, normalizeButtonVariant, VARIANT_ALIASES, isLegacyVariant are gone — pass canonical names.
    • Slots → props: Button.iconLeft / iconRight accept IconName (typed) instead of #iconLeft / #iconRight slots.
    • Loading semantics: Button sets aria-busy="true" while loading; clicks are blocked; content uses visibility: hidden so the width stays stable; the <a> swap is gated by !loading. (See is* table for the isLoadingloading rename.)
    • New spinnerType?: 'row' | 'round' prop (default 'row'); IconButton overrides to 'round' so the spinner fits the square footprint.
    • BackgroundAwareButtonVariant is rebuilt to mirror the new ButtonVariant shape. 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-level backgroundAwareButtons maps must rewrite their value entries accordingly.

    Banner refactor

    • BannerBasic, BannerShowcase, BannerIntegrated no longer expose a variant prop. The BannerBasicVariant / BannerShowcaseVariant / BannerIntegratedVariant types are removed.
    • Border-radius is now context-driven via the new .radius-contained utility class (calc(sign(100cqi - 100%) * var(--forms-border-radius)) with a 0 fallback). It applies inside a constrained container, collapses to 0 edge-to-edge.
    • The redundant frame wrapper <div> is removed from all three banners.
    • MediaStage no longer hardcodes border-radius.

    Surface tone migration

    • BackgroundBrightnessSurfaceTone ('light' | 'dark' | 'bright') across the Field, Input, Switch, Select, Checkbox, InputRadio, and Swatch families. The legacy BackgroundBrightness type is removed.
    • OnBackground primitive deleted; use OnSurface + useSurfaceTone() composable. useSurfaceTone(props) resolves explicit prop > nearest ancestor context > 'light'.
    • colorToBackground renamed to colorToSurfaceTone (file and exported symbol). Returns SurfaceTone.
    • Backdrop auto-derives tone for custom colors via colorToSurfaceTone. Hex inputs work; non-hex (var(...), rgb(...), hsl(...), light-dark(...)) currently fall back to 'light'.
    • BackgroundAwareBackdropSet is now Record<KnownBackdropColors, SurfaceTone> — the 'default' literal is dropped (was a synonym for 'light'). Theme presets (classic / laioutr / sunny / tech) now spell none: 'light' directly.
    • New CSS tokens: --on-light-*, --on-dark-*, --on-bright-*. The .on-light / .on-dark / .on-bright classes dereference their own token namespaces.
    • MediaPreview reads parent surface tone via useSurfaceTone(props) and emits media-preview--{light,dark,bright} modifiers.
    • --font-color, ... fallback removed from Text and the uno typography preset (body-*, heading-*, subline-*, caption-*); they emit color: var(--font-color-<type>) directly inside the lui-overridable layer.
    • A bare <OnSurface> (no tone prop) inherits the surrounding tone, matching the previous <OnBackground brightness="default"> behaviour. (OnBackground no longer exists at HEAD; the comparison is offered as a migration aid.)
    • Backdrop: containerBackground and backgroundBrightness props are removed. Use :background directly (preset name or CSS color) and let colorToSurfaceTone derive the tone, or pass :surface-tone explicitly to override.
    • MediaPreview: the legacy mode prop is renamed surfaceTone and is now resolved via useSurfaceTone(props) (explicit prop wins, falls through to the ancestor <OnSurface>). The BEM root is also renamed .media-block.media-preview.
    • New SurfaceToneAware interface (packages/ui-kit/src/runtime/app/composables/useSurfaceTone.ts) exporting { surfaceTone?: SurfaceTone }. Components like Pagination and MediaPreview widen their defineProps<> with this interface so the prop is always optional and resolves through useSurfaceTone(props).
    • BackgroundAwareButtonSetKey is rebuilt as ${'dark' | 'light'}:${SurfaceTone}:${BackgroundAwareLookupVariant}. Variant axis narrows to 'primary' | 'secondary' | 'ghost' (lookup-only). New exported BackgroundAwareLookupVariant type. Theme backgroundAwareButtons records must drop other-variant keys.
    • BackgroundAwareBackdropSet exported type signature is now Record<KnownBackdropColors, SurfaceTone> (was Record<KnownBackdropColors, BackgroundBrightnessInput>).
    • MediaStage auto-derives surface tone from backgroundColor when surfaceTone is not explicitly set, using colorToSurfaceTone. Same hex-only caveat as Backdrop.
    • provideSurfaceToneContext is renamed to _provideSurfaceToneContext to mark it internal. Only <OnSurface> is allowed to provide tone publicly. External code that previously called provideSurfaceToneContext({ tone }) must wrap content in <OnSurface :tone="…"> instead. The companion injectSurfaceToneContext keeps its name (still consumed by useSurfaceTone()).
    • SwatchChip gains bright tone CSS coverage via a swatch-chip--bright modifier (parallel to --dark). Outline color uses --text-always-black for selected, unselected, and hover states. New stories MultipleColorsOnBrightBackground / MultipleColorsSelectedOnBrightBackground.
    • Pagination, Select, SwiperNavBar internal: confirmed (with inline comment) that the existing binary tone === 'dark' ? 'ghost-white' : 'ghost-black' check correctly maps bright to the 'ghost-black' else branch — no behavior change, no API change.
    • Surface-tone narrowing verdict. LanguageSwitcher / LanguageSwitcherDisplay / NavigationMenuTextItem / NavigationMenuTextItemWrapper / DarkModeSwitch keep Exclude<SurfaceTone, 'bright'> on their surfaceTone prop type — these chrome/navigation components live on neutral surfaces by design. Widen + add bright CSS only when a component is genuinely placed on a bright surface and visually signed off. New components default to the full SurfaceTone union.

    Form prop normalization

    • Field: legacy error: string removed. Use errorMessage: string for the displayed message and invalid: boolean for the visual error state. Field auto-derives isInvalid from errorMessage when invalid is unset.
    • Input / InputAutocomplete / InputCombobox: isErrorinvalid.
    • Label: error: booleaninvalid: boolean. BEM modifier label--errorlabel--invalid.
    • InputPassword: readOnlyreadonly (so the value reaches the underlying Input).
    • InputSearch: dead modelValue prop removed (the live channel is searchTerm).
    • InputCheckbox: the setup-time overwrite of defineModel was removed; later prop changes now propagate. defaultChecked accepts 'indeterminate' in addition to boolean.
    • Switch: propagates Field context's disabled. defaultChecked accepts 'indeterminate'.
    • Switch: v-model channel renamed from 'checked' to default 'modelValue' (defineModel<boolean>('checked')defineModel<boolean>()). v-model:checked callsites must become v-model (or v-model:model-value). Also size: 'small' | 'medium''s' | 'm' (default 'm'); new invalid?: boolean prop.
    • Checkbox: v-model channel renamed from 'checked' to default 'modelValue' (defineModel<boolean | 'indeterminate'>('checked')defineModel<boolean | 'indeterminate'>()). The standalone checked prop is removed from CheckboxProps (use the model). v-model:checked callsites must become v-model. defaultChecked already widened to boolean | 'indeterminate'.
    • InputRadioItem: stops forwarding per-item required to RadioGroupItem; the group-level prop is canonical.
    • Select: size prop removed (it was forwarded to a reka-ui slot that silently rejected the values). Express size via :trigger="{ size: 's' }".
    • Checkbox / Switch stories switch to a live useArgs-driven render round-tripping update:modelValue; story args use modelValue, not checked / defaultChecked.

    is* prefix prop renames

    For props where the subject is the component itself, the is prefix is dropped. World-state facts (isUserLoggedIn, isAboveTheFold, isSoldOut, isVerified, isFreeDelivery, isShippingFree, isLoggedIn) keep is*.

    Component Old → New
    Badge isRoundedrounded
    Button isLoadingloading
    Label isRequiredrequired; size: 'small' | 'medium''s' | 'm'
    Switch v-model channel checked → default modelValue (v-model:checked callsites must become v-model); size: 'small' | 'medium''s' | 'm'; new invalid?: boolean.
    ThumbnailsSlider isCenteredcentered
    Toast (and toasterStore) isOpenopen
    LinkTileBig isBackgroundDarkbackgroundDark
    Pagination isNavigationNumbersvariant: 'arrows' | 'numbers' (default 'arrows')
    OptionTileImage / OptionTileText notAvailable: { isNotAvailable, notAvailableTooltip } flattened to unavailable?: boolean + unavailableTooltip?: string

    Other prop / API changes

    • Accordion: accordionStylevariant.
    • Accordion: typed defineModel<string | string[]>('value') exposed for v-model on the active panel(s) (single or multiple based on type); new select emit fires after update:value.
    • LoadingSpinner: type: 'row' | 'round' (shape) → variant; old variant: 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: new media?: Media prop. When set, media is rendered directly through the <Media> component; otherwise the legacy src/theme-default chain applies.
    • Sheet: removes the legacy component? and customClass? props from SheetProps. Use v-bind="$attrs" / a wrapper component to add classes; component was 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 / CardCta are declared inline in Card.vue (the old Card/types.ts is deleted).
    • BadgePromotion (renamed from SavingsBadge): props are redesigned, not just renamed. Replace { savingPercentage, badgeVariant } with { variant?, radius?, size?, icon?, text?, savingPercentage?, withNotch? }. badgeVariant is now variant. BEM root is .badge-promotion (was .saving-percentage).
    • Type barrel (packages/ui-kit/src/runtime/app/types/index.ts): drops CtaBannerBase, CtaBannerBasic, CtaBannerIntegrated, CtaBannerShowcase re-exports; the ColorSwatch/Types re-export becomes SwatchChip/Types; adds MediaStage/MediaStage.vue.
    • Card types: packages/ui-kit/src/runtime/app/components/Card/types.ts is deleted. Import CardProps and CardCta from '#ui-kit/components/Card/Card.vue' instead.
    • ImageContrastOverlay fields: the colocated fields.ts (Studio field-helpers) is removed; sections that referenced imageContrastOverlayFields must inline the equivalent shared-field calls.
    • Tooltip: the width prop now reaches the rendered tooltip; the arrow size is no longer hardcoded at 8.
    • App, OnSurface, Tooltip define their own prop interfaces; they no longer re-export ConfigProviderProps / TooltipProviderProps / PrimitiveProps / TooltipArrowProps from reka-ui.
    • ContextMenu: no longer claims a controlled open prop reka-ui doesn't expose; emits update:open for observation only.
    • ProgressBar.max is now bound to <ProgressRoot :max> and the indicator width respects value/max (clamped to [0,100]).
    • Select.prioritizePosition now forwarded to <SelectContent :prioritize-position>.
    • Card.CardCta.{size,iconLeft,iconRight} are now wired through to the rendered BackgroundAwareButton.
    • Listbox/ListboxItem: the unused textValue prop is removed.
    • DropdownMenuTextItem: the :side binding on DropdownMenuSubContent is removed (sub-menu direction follows the sub-trigger).
    • IconButton click forwarding: IconButton no longer declares defineEmits<{ click }>(); click listeners reach the underlying Button via $attrs. Restores click on every <IconButton @click> callsite.
    • MediaPreview reactivity: registration now uses watch([props.lightbox, props.media], …, { immediate: true }) so the store stays in sync when consumers swap media or toggle lightbox on a mounted instance.
    • Lightbox cleanup: removed dead Swiper-default-navigation CSS and switched .lightbox__nav desktop layout to display: flex so the IconButton no longer renders oval.
    • NavigationBullets: no longer animates on initial mount; a --animating modifier gates the keyframes so they only fire on user interaction.
    • HeaderShop: backdrop-filter moved from .header-shop to .header-shop::before so absolutely-positioned descendants (e.g. NavigationMenu hover panel) are not trapped by the compositing clip.
    • NavigationMenu: hover panel anchors to the trigger <li> via top: 100%; left: 0; z-index: var(--z-index-popover) instead of top: 52px; z-index: 10000.

    CSS / public-CSS-API

    • 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 added
      • LoadingSpinner: .round-spinner-s / -l.round-spinner--s / --l
      • Label: .label--size-small / -medium.label--size-s / -m
      • IconList: .icon-list--size-small / -medium.icon-list--size-s / -m
      • MediaPreview: .media-block*.media-preview* (and CSS custom properties --media-block-*--media-preview-*)
      • SwiperChrome: .swiper-chrome__head-{...}__head--{...}; new .swiper-chrome__spacer
      • EmailInputFormDisplay: .newsletter-form*.email-input-form-display*
      • Pagination / Sheet / Lightbox: root BEM classes added
      • MediaText, PlanCard, HeaderShop, FilterBar: single-dash → double-dash modifiers; missing inner-row classes added
      • NewsletterRegistration: .newsletter-block*.newsletter-registration*
      • PopUp / PopUpInfo / PopUpNewsletter / PopUpPromotion: .popup*.pop-up*; keyframe popupShowpopUpShow
      • SearchAutoSuggestItem: .search-suggestion*.search-auto-suggest-item*
    • State-modifier prefix cleanup: SwatchChip.is-selected.swatch-chip--selected; Switch.--small--s; BreadcrumbsItem.--is-active--active. The is- modifier prefix is no longer used in BEM class names.
    • <style scoped> / :deep() / :global() removed across Toaster/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.margin removed, Label root padding removed, InputGroupAddon root padding removed, InputRating root align-self removed, SwiperBullets centering wrapper removed, ThumbnailsSlider outer 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. CouponBox clear-button uses --icon-color).

    Locale (i18n)

    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: namespace lightboxGallerymediaGallery (sole key lightboxGallery.closemediaGallery.close), colorSwatch.*swatchChip.*, searchInput.*inputSearch.*, passwordInput.*inputPassword.*, savingsBadge.*badgePromotion.*, mediaLightbox.*lightbox.* (collapsed onto the existing lightbox.close namespace), shopHeader.*headerShop.*. Removed: couponCodeInput.* (consumers reuse cart.couponCode and inputSearch.clear), pdp.basePrice.

    Dependencies

    reka-ui bumped from ^2.3.1 to ^2.9.6 (introduces the Autocomplete primitive used by InputAutocomplete).

    Composables and utilities reorganization

    • Pure swatch / color-brightness helpers (getColorBrightness, isColorDark, doesColorNeedBorder, getSwatchDarkness, getSwatchBrightnessClass, doesSwatchNeedBorder) move from @laioutr-core/ui's composables/useColorBrightness into @laioutr-core/ui-kit's utils/swatchBrightness.ts (no Vue reactivity, never belonged in composables/).
    • useImageZoomPan keeps its public composable signature and import path; pure helpers move to utils/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 inline injectFieldContext + useId boilerplate 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 the isBeginning / isEnd event 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.)
    • CommonSwiper runtime helper moved from @laioutr-core/ui to @laioutr-core/ui-kit (packages/ui-kit/src/runtime/app/components/CommonSwiper/CommonSwiper.ts); auto-wraps default-slot children in SwiperSlide and forwards Swiper props.
    • swiperBreakpoints helper lives in packages/ui-kit/src/runtime/app/utils/swiperBreakpoints.ts (canonical commonSwiperOptions + spacingBreakpoints); consumers in ui import via '#ui-kit/utils/swiperBreakpoints'.

    @laioutr-core/ui

    Auto-import prefix unified to L

    @laioutr-core/ui now registers its auto-imported components with prefix L (matching @laioutr-core/ui-kit) instead of Lui. Every <LuiX> template tag pointing at a ui component must be renamed to <LX>. Component file basenames are unchanged; only the auto-import prefix differs.

    Combined with the moves from ui-kit to ui listed 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.

    New components

    • Container — backdrop + grid + alignment + media-sizes composition with containerStyle, background, customBackground, margin, padding, columnsMobile, columnsDesktop, sizing, alignment and top / default / bottom slots. Used by the merged SectionContainer.
    • MegaMenu compoundMegaMenu + 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 / #content slots.
    • ScrollAnchor — invisible <div> whose name prop becomes the DOM id.
    • BlogPostListing — featured post, paginated grid, optional page hero.
    • PopUp shell + presets: PopUp, PopUpInfo, PopUpNewsletter, PopUpPromotion. Shell wraps a reka-ui Dialog with a media slot plus a content stack; presets compose TextGroup, EmailInputForm, CouponBox, and Button.
    • SortModes composition. (Pagination remains a ui-kit component; only SortModes is new in @laioutr-core/ui.)
    • SearchAutoSuggest (renamed from SearchOverlayInput, mounted once via HeaderShop) and its colocated SearchAutoSuggestItem.
    • Moved in from ui-kit: ReviewForm; SocialShare; MenuSideBySideNode; BreadcrumbsItem; MediaGallery (was LightboxGallery); SearchResultHero (was SearchResultHeader).
    • Renamed and flattened within ui (these were already in ui at base under nested organism/... paths, not moved from ui-kit): the Cart family (CartListItem, CartSummaryBox, EmptyStateCartCartEmptyState, FreeDeliveryProgressCartFreeDeliveryProgress, CartCouponCodeAccordion, CartCouponCodeAccordionInputCartCouponCodeForm); the VariantSelectorConfigurator* family (was VariantSelectionConfigurator*); VariantSelectorMultipleTrigger (was MultipleVariantSelectionTrigger); VariantSelectorMultipleAvailability (was MultipleVariantSelectionAvailability); MobileMenuShared/* (was under organism/MobileMenu/); FilterOffCanvas* subcomponents (was FilterSheet* under organism/FilterSheet/).
    • LogoSliderSlide promoted to its own top-level folder (components/LogoSliderSlide/).
    • FooterMenu moved to its own component folder with a dedicated UI/Blocks/FooterMenu Storybook story.
    • LogoGrid — promoted to its own top-level folder (was previously a sub-component LogoGridMode.vue inside organism/LogoSlider/). Public LogoGridProps with caption, heading, subline, orientation: 'left' | 'center', textSize: 's' | 'm' | 'l', logoBackground, and a typed slides: LogoSliderSlideProps[] (from LogoSlider).
    • BannerBasic, BannerIntegrated, BannerShowcase — migrated from ui-kit to ui as part of the Banner refactor. (Prop changes are documented in the ui-kit "Banner refactor" section.)
    • CategoryCardGrid and CategoryCardSlider — replace the inpage-navigation family. Both render LinkTile for every variant; CategoryCardGridVariant / CategoryCardSliderVariant are aliases of LinkTileVariant.
    • EditorialGrid (renamed from ArticlesGrid) — exposes featuredCount, caption/heading/subline visibility flags.
    • PersonaQuoteSlider — slider wrapping multiple PersonaQuote items, used by SectionPersonaQuoteSlider.
    • PriceInfo, ProductTitle, QuantityDiscount, EnergyLabel, BenefitsBox, CouponBox, AddToCart — renamed from BuyBox-prefixed components (see the rename table).

    Renamed components (final names)

    New Old
    HeaderBasic Header
    HeaderShop ShopHeader
    HeroSlider BasicHeroSlider
    HeroSlide BasicHeroSliderSlide
    MegaMenu (compound) MegaMenuDesktop (full prop replacement; see "Other prop / API changes")
    MobileMenuBasic MobileMenu
    MobileMenuShop (+ MobileMenuShopContentItem) MegaMenuMobile (+ MegaMenuMobileContentItem)
    MenuSideBySide (+ MenuSideBySideRoot / MenuSideBySideChild / MenuSideBySideNode) SideBySideMenu (+ DesktopSideBySideRootMenu / DesktopSideBySideChildMenu / CategoryNodeButton)
    EditorialGrid ArticlesGrid
    ContentGrid CardGrid
    ContentSlider GalleryContentSlider
    BrandList BrandGrid
    MediaText CmsImageText
    MediaGallery LightboxGallery
    SearchResultHero SearchResultHeader
    PageNotFound Error404Page
    EnergyLabel BuyBoxEnergyLabel
    BenefitsBox BuyBoxBenefitsBox
    PriceInfo BuyBoxPriceInfo
    CouponBox BuyBoxApplyDiscountCode
    QuantityDiscount BuyBoxQuantityPrices
    ProductTitle BuyBoxProductInfoBasic
    AddToCart BuyBoxCartButton
    VariantSelectorMultiple / VariantSelectorMultipleTrigger / VariantSelectorMultipleAvailability MultipleVariantSelection / MultipleVariantSelectionTrigger / MultipleVariantSelectionAvailability
    VariantOffCanvas MultipleVariantSelectionSheet
    VariantSelectorOptions / VariantSelectorOptionsImageGrid / VariantSelectorOptionsImageSlider VariantSelection / VariantSelectionImageGrid / VariantSelectionImageSlider
    VariantSelectorConfigurator (+ *AccordionItem, *OptionsList, *SwatchList) VariantSelectionConfigurator (+ same suffixes)
    FilterOffCanvas (+ *AccordionItem, *CheckboxList, *CheckboxListItem, *SwatchList, *SwitchItem) FilterSheet (+ same suffixes)
    ProductListingGrid ProductGrid
    QuoteCardSlider QuoteSlider
    CartCouponCodeAccordionInput CartCouponCodeForm
    EmptyStateCart CartEmptyState
    FreeDeliveryProgress CartFreeDeliveryProgress
    BreadcrumbsItem Breadcrumb (was in ui-kit)
    PlanCard / PlanCardSlider / PlanComparisonTable (+ *Header, *RowHeader, *RowValue, *SectionHeader) PricingCard / PricingGrid (or PricingCardSlider) / PricingTable (+ subcomponents)

    For every rename, file paths, exported *Props types, BEM blocks, Storybook titles, and luiComponentDirs entries follow the new name.

    Removed components

    • BuyBox — was a static demo composition; compose buy boxes from blocks at runtime.
    • InpageNavigation* family (six components) — covered by CategoryCardGrid / CategoryCardSlider (themselves consumers of LinkTile).
    • CmsContainer / ContainerContent — inline the markup or use the surrounding Section/Block pattern.
    • Iframe — moved to ui-kit.
    • Card — moved to ui-kit. The cta prop's type is now an inline CardCta (same shape as the previous CtaBannerButton).
    • DarkModeSwitch, BuyBoxStockInfo, LanguageSwitcher — moved to ui-kit.
    • Media — was a 42-line pass-through over MediaPreview from ui-kit. Consumers should import MediaPreview directly (prop names match 1:1).
    • FooterMenuItem, FooterTitle — replaced by NavLinkItem / NavSectionHeading from ui-kit. Footer now uses NavLinkItem directly for its contact rows.
    • LightboxGallery — renamed to MediaGallery (see above).
    • PageHeader — removed and inlined. Section-level page heroes (SectionPageHero) now compose LTextGroup and Backdrop directly; there is no replacement ui component to import.
    • CategoryNodeButton — replaced by MenuSideBySideNode (see ui-kit "Moved out" section).
    • CategoryCard — replaced by LinkTile from ui-kit. CategoryCardGrid and CategoryCardSlider now render LinkTile for every variant; CategoryCardGridVariant / CategoryCardSliderVariant are aliases of LinkTileVariant. The node variant field is renamed to cardVariant.
    • LightboxModal — replaced by Lightbox in ui-kit (renamed from MediaLightbox in this release).
    • FilterBarQuickFilters — its quick-filter UI is integrated directly into FilterBar; the FilterBarQuickFiltersProps type export is removed.
    • MobileMenuButtonGrid — removed (folded into the MobileMenuShared family).
    • FooterMenuDesktopItem — folded into FooterMenu.
    • CategoryHeaderBasic — removed (header chrome now built from page-hero + section composition).
    • GridCardContent, GridCardTextContent — removed (card content now flows through Card slots from ui-kit).

    Header refactor (slot-based)

    • HeaderBasic and HeaderShop expose desktop and mobile named slots that the hosting Section fills with block content. Inline navigation and mobile-menu markup is removed.
    • HeaderBasic removed props: menuItems, mobileMenuItems, socialLinks. The MenuItem / SocialLinks interfaces are no longer re-exported from HeaderBasic.vue — import them from MobileMenuBasic/types.
    • HeaderShop removed prop navigationMenuItems and event navigationItemClick. NavigationMenuItem is removed.
    • Both headers now emit menuClick when the mobile hamburger is activated; the hosting Section owns the mobile-menu open state.
    • HeaderMenuContext coordinates desktop (isOpen, selectedItemId, open, close) and mobile (isMobileOpen, openMobile, closeMobile) state.

    MenuMegaMenu rework

    • MenuMegaMenuProps.contentLayout removed. 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.

    Filter bar

    • SectionFilterBar removed in ui-app; the filter bar is now block-only as BlockFilterBar. BlockFilterBar adopts the former section's Content and Design schema. The hosting Section provides background/margin/padding/style.

    BrandHero

    • BrandHero now uses the context-aware .radius-contained utility (rounds inside a padded container, flat edge-to-edge); the hardcoded border-radius: 0 is removed.

    Prop / API changes

    is* prefix sweep — for props where the subject is the component itself, the is prefix is dropped:

    • SearchAutoSuggest: isLoadingloading; v-model channel isOpenopen (defineModel('isOpen')defineModel('open')).
    • MobileMenuListItem.isActive is removed entirely. The prop never reached the DOM — visual :active styling is driven by the CSS pseudo-class. MenuSideBySide.NavigationNode.isActive follows.
    • HeaderShop, HeaderBasic, FilterBar: isStickysticky.
    • MobileMenuShop, MenuSideBySide: v-model channel isOpen / update:isOpenopen / update:open.
    • HeroSlider: isFullHeightfullHeight. isAboveTheFold is kept (it states a fact about the slide's render context, not the component's own visual state).
    • BreadcrumbsItem: isDropdowndropdown. isCurrentPage is unchanged in this release; it flows through the canonical-types/BreadcrumbItem Zod schema and will be addressed in a separate canonical-types pass.
    • CartListItem: isQuantityLoadingquantityLoading.
    • ProductTileBasic: isAddToCartLoadingaddToCartLoading; isAddToCartDisabledaddToCartDisabled.
    • CouponBox: isAppliedapplied. Also picks up the canonical cta object preset and richer error/success states.
    • MenuItem.saleDesign (data shape used by MobileMenuBasic and HeaderBasicMenu): isSaleDesignsaleDesign.
    • PlanComparisonTableRowValue: isHighlighthighlight.

    Other prop / API changes:

    • HeaderBasicMenutextColorsurfaceTone (semantic flip). The previous textColor named the foreground colour; the new surfaceTone names the surface against which the foreground is rendered. Old textColor: 'dark' (dark text on light bg) maps to new surfaceTone: 'light'; old textColor: 'light' maps to surfaceTone: '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'. Only HeaderBasicMenu.textColor was renamed/flipped to surfaceTone.)
    • Container collapses background + customBackground into a single resolved value passed to Backdrop's :background. The :container-background forwarding is dropped. (Container's public prop surface still declares both background and customBackground; only the wire to Backdrop is collapsed.)
    • MediaText: containerBackground prop removed. Pass the resolved color via :background= directly (preset name or CSS color string). Same migration shape as Container. The unused containerBackground field on the published BlockMediaTextContext interface (runtime/components/MediaText/types.ts) is also removed.
    • HeroSlider internal: replaces the manual provideSurfaceToneContext({ 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.
    • TopBar internal: the navItemSurfaceTone and switcherSurfaceTone computeds are now wired into the template (NavigationMenuTextItem and LanguageSwitcher). On modeColor: 'grey' they inherit the ambient tone (was previously hardcoded 'light'); on 'black' mode they apply asymmetric 'light'/'dark' per the original design intent.
    • PageNotFound (was Error404Page): textColor: 'always-white' | 'always-black' replaced by surfaceTone?: 'light' | 'dark'. Asset folder runtime/public/error-404-page/ renamed to runtime/public/page-not-found/.
    • AddToCart (was BuyBoxCartButton): isLoadingloading; addToCart event payload changed from quantity: number to AddToCartPayload. New optional productId? / variantId? props.
    • VariantSelectorOptions (was VariantSelection): selectionChange event removed; selectedOptions becomes a v-model. New optional id / disabled / required / invalid props for Field-context integration.
    • VariantSelectorMultiple (was MultipleVariantSelection): isOpen ref → defineModel('open'); new optional id / disabled / required / invalid props.
    • VariantOffCanvas (was MultipleVariantSelectionSheet): explicit update:isOpen emit removed; v-model channel renamed to open (covered by defineModel('open')).
    • MegaMenu (was MegaMenuDesktop): complete API replacement. Old props colorMode / isOpen / megaMenuItems / contentLayout are gone. New props items: MegaMenuItem[]; surfaceTone?: 'light' | 'dark'; defaultValue?: string; delayDuration?: number; skipDelayDuration?: number. Trigger / content panels split into MegaMenuTrigger / MegaMenuContent compound parts. Promo-slot layout threshold: 1 promo → --narrow; 2 promos → --flex; 3+ promos → --grid (the first child spans two rows).
    • Footer: columnsDesktop prop removed; alignment and contentAlignment typed as ContentAlignmentHorizontalFieldValue.
    • FooterMenu: exported FooterMenuItems interface renamed to NavLinkItems (the items prop type).
    • FilterBar: openFilterSheetButtonVariantopenFilterOffCanvasButtonVariant. The colocated FilterBarQuickFiltersProps type export is removed (its UI is folded into FilterBar).
    • FilterOffCanvas / AvailableFilter type: union extended with AvailableFilterRange ({ type: 'range', min, max, step?, formatLabel? }). Existing 'boolean' / 'list' members are unchanged. SelectedFilterRange already existed; range is now a first-class supported filter type.
    • SearchAutoSuggest (was SearchOverlayInput): exported types SearchOverlayInputProps / SearchOverlayInputSuggestionProps renamed to SearchAutoSuggestProps / SearchAutoSuggestItemProps.
    • ContentSlider (was GalleryContentSlider): colorMode, headline, subline defaults dropped; content now flows through slots.
    • BrandList (was BrandGrid): exported BrandGridProps / BrandGridLink renamed to BrandListProps / BrandListItem.
    • Exported type renames — every *Props type follows its component rename: BasicHeroSliderPropsHeroSliderProps; BasicHeroSliderSlidePropsHeroSlideProps; BrandGridPropsBrandListProps; CmsImageTextPropsMediaTextProps; Error404PagePropsPageNotFoundProps; FilterSheetPropsFilterOffCanvasProps; GalleryContentSliderPropsContentSliderProps; LightboxModalProps removed (use Lightbox from ui-kit); MegaMenuDesktopProps removed (use MegaMenuProps); MultipleVariantSelectionPropsVariantSelectorMultipleProps; MultipleVariantSelectionSheetPropsVariantOffCanvasProps; MultipleVariantSelectionVariantPropsVariantSelectionCardProps (in ui-kit); PricingTablePropsPlanComparisonTableProps; PricingCardPropsPlanCardProps; ProductGridPropsProductListingGridProps; SearchOverlayInputPropsSearchAutoSuggestProps; SearchOverlayInputSuggestionPropsSearchAutoSuggestItemProps; SearchResultHeaderPropsSearchResultHeroProps; ShopHeaderPropsHeaderShopProps; BuyBoxApplyDiscountCodePropsCouponBoxProps; BuyBoxBenefitsBoxPropsBenefitsBoxProps; BuyBoxCartButtonPropsAddToCartProps (inline); BuyBoxEnergyLabelPropsEnergyLabelProps; BuyBoxPriceInfoPropsPriceInfoProps; BuyBoxProductInfoBasicPropsProductTitleProps; BuyBoxQuantityPricesPropsQuantityDiscountProps; BuyBoxStockInfoProps (moved to ui-kit). Imports must be updated to the new module paths under runtime/components/<NewName>/types or the .vue file directly.
    • PlanComparisonTable interface is renamed to PlanComparisonTableProps to resolve a component/type name collision. The component now forwards showChoosePlan to its header (previously dropped).
    • ReviewItem: id: stringid?: string (the component never read the prop; only Review.vue needed it for :key). Explicit id: undefined default.
    • VariantSelectorOptions: numeric :font-weight="500" / "400" on the option title and selected-value <Text> are replaced by weight="medium" (Text accepts 'bold' | 'semi-bold' | 'medium' | 'regular').
    • VariantSelectorOptionsImageGrid: variant="subline"type="subline" on the +N more variants label.
    • HeroSlide: stray {{ overlay }} debug expression removed from the template.
    • HeroSlide / HeroSlider stories: flag fixtures use variant + colorScheme (the new Flag API).
    • FilterOffCanvasCheckboxListItem: dead defineModel<boolean>('item-selected') replaced by a one-way itemSelected prop.
    • FilterOffCanvasSwatchList: unused required id prop dropped; FilterOffCanvas now mounts the checkbox/swatch lists via static v-if branches instead of <component :is>.
    • FilterOffCanvasRangeSlider: SelectedFilterRange is no longer redeclared; imported from FilterOffCanvas/types.
    • LogoSliderMode: reuses LogoSliderProps heading shape instead of redeclaring.
    • ReviewForm: dead update:rating emit declaration removed.

    CSS / BEM

    • MenuMegaMenu retains the ecommerce-container co-class on its root (it carries layout chrome the BEM class does not duplicate).
    • BreadcrumbsItem: .breadcrumbs-item--is-active.breadcrumbs-item--active (drop redundant is- 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 / *Root siblings)
      • HeroSlider / HeroSlide: .basic-hero-slider* / .basic-hero-slider-slide*.hero-slider* / .hero-slide*
    • Container uses .s-scontainer as the root block (NOT .container or .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.

    Composables / utilities

    • Removed useSwatchBrightness from @laioutr-core/ui (composables/useColorBrightness.ts deleted). Import from @laioutr-core/ui-kit instead — utils/swatchBrightness.ts.
    • Removed useImageZoomPan from @laioutr-core/ui (composables/useImagezoomPan.ts deleted). Import from @laioutr-core/ui-kit instead — composables/useImageZoomPan.ts and utils/imageZoomPan.ts.
    • Removed runtime/utils/storybookSection.ts — internal story decorator (asSection()).
    • useCategoryNavigation: internal DesktopCategoryNode type (from SideBySideMenu) renamed to NavigationNode (from MenuSideBySide/types). Public function signature unchanged.
    • useMobileMenuNavigation: internal MobileMenuItem type now imports from MobileMenuShop/types (was MegaMenuMobile/types); public signature unchanged.

    Module setup

    • Auto-import prefix unified to L and the three-bucket structure (addLuiComponentsDir('molecule'), ('organism'), ('page'), ('section')) collapsed into a single addComponentsDir({ path: './components', prefix: 'L', pathPrefix: false }) over a flat runtime/components/<Name>/<Name>.vue layout. There is no longer a section/block/page/molecule/organism distinction in module.ts.
    • Removed manual addComponent('LuiCommonSwiper') (CommonSwiper.component.ts is deleted) and removed installModule('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 (ui no longer self-installs sibling modules during nuxi prepare).

    Internal moves

    • The PlanCardSlider Swiper config migrated to the canonical swiperBreakpoints helper in ui-kit ('#ui-kit/utils/swiperBreakpoints'); numeric scale replaces inline string-pixel spaceBetween.
    • Asset mobile-menu-banner-bg.png moved from runtime/assets/img/ to runtime/components/MobileMenuShared/.
    • New helper components/_shared/ctaBanner.ts — exports the shared cta object used by BannerBasic / BannerIntegrated / BannerShowcase.
    • Storybook playground page demos (Homepage, Landingpage, BlogOverviewPage, BlogPostPage, BrandOverviewPage, BrandPage, SearchResultsPage) removed; not part of the public package surface.

    @laioutr-app/ui

    Section renames (Studio data migration required)

    New Old
    SectionHeaderBasic SectionBasicHeader
    SectionHeroSlider SectionBasicHeroSlider
    SectionMediaText SectionImageAndContent
    SectionPersonaQuoteSlider SectionTestimonialPersonaQuote
    SectionQuoteCardSlider SectionTestimonialQuoteCardSlider
    SectionBrandList SectionBrandLink
    SectionSearchResultHero SectionSearchResultHeader
    SectionPlanCardSlider SectionPricingPlans
    SectionPlanComparisonTable SectionPricingTable
    SectionPageHero SectionPageHeader / SectionCategoryHeader
    SectionHeaderShop SectionShopHeader
    SectionPageNotFound SectionError404
    SectionProductDetail SectionProductDetailContainer
    SectionLogoSlider / SectionLogoGrid SectionLogoPresentation (split by old view discriminator: view: 'slider'SectionLogoSlider, view: 'grid'SectionLogoGrid)
    SectionBannerBasic / SectionBannerIntegrated / SectionBannerShowcase BlockCtaBannerBasic / BlockCtaBannerIntegrated / BlockCtaBannerShowcase (banner blocks promoted to sections; lifted out of host SectionContainer slots into the page-level sections array)
    SectionContainer SectionBannerContainer (consolidated; SectionContainer is now a thin wrapper over the new Container organism in ui)

    Block renames (Studio data migration required)

    New Old
    BlockHeroSliderSlide BlockBasicHeroSliderSlide
    BlockPersonaQuote BlockTestimonial
    BlockProductsListing BlockProductGrid
    BlockPagination BlockQueryPagination
    BlockSortModes BlockQuerySorting
    BlockButton (Studio label CMS ButtonButton) BlockCmsButton
    BlockCard BlockCmsCardContent
    BlockLogoSliderSlide BlockSingleLogoPresentation

    Section / block deletions (Studio data migration required)

    • SectionBlogSlider, SectionFlexibleContentSliderSectionContentSlider (now hybrid slot/query).
    • SectionTestimonialQuoteCardSectionQuoteCardSlider with a single slide.
    • SectionCardGrid → new SectionContentGrid (default dataSource: 'slot', preserve slot contents).
    • SectionInpageNavigationBasic / Big / CompactSectionCategoryCardGrid / SectionCategoryCardSlider.
    • SectionAmbiendoHeaderSectionHeaderShop with BlockMenuSideBySide in the new menu slot. Field mapping: logoLightSectionHeaderShop.logo; logoDark dropped (single-logo model); logoMenuBlockMenuSideBySide.logoMenu; mobileSearchStyleSectionHeaderShop.searchBarMobile; rootMenuBlockMenuSideBySide.rootMenu; navigationMenuItemsBlockMenuSideBySide.navigationMenuItems; extraMenuItemsSectionHeaderShop.navigationMenuItems (flat top-bar); showCart / showSearch / showWishlist / showCustomerAccount unchanged.
    • SectionShopHeaderNavigation → demoted into BlockMenuSideBySide inside SectionHeaderShop.desktop / SectionHeaderBasic.desktop. Standalone instances must be lifted into a hosting header section.
    • BlockProductReviewsSectionProductReviews.
    • BlockInpageNavigationBasicGrid.

    New sections

    • SectionContentGrid — hybrid slot/query wrapper. dataSource: 'slot' (default; BlockCard via the default slot) or dataSource: '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); cards slot restricted to BlockCard.
    • SectionCategoryCardGrid — grid counterpart to SectionCategoryCardSlider.
    • SectionProductReviews — replaces the legacy block-level implementation.
    • SectionUspBanner (existing section, reshaped) — drops bannerStyle, drops colors (colors.textColor → top-level color, colors.iconColor → top-level iconColor), and extracts the previous usps[] field into a new items slot populated by BlockUspBannerItem children.
    • SectionContentSlider — adopts hybrid slot/query data source (default slot; query is opt-in).

    New blocks

    • BlockCategoryCard, BlockUspBannerItem — non-standalone children for the new sections.
    • BlockProductsListing, BlockFilterBar, BlockSortModes, BlockPagination — split out of the previous combined SectionProductListing.
    • BlockMobileMenuBasic, BlockMobileMenuShop — non-standalone, hosted in the mobile slot of SectionHeaderBasic and SectionHeaderShop. Carry the menu-items array, socialMediaLinks, languageSelect, modeSwitcher fields that previously lived on the sections.
    • BlockMenuSideBySide — non-standalone, in the desktop slot of SectionHeaderShop. The navigationMenuItems / navigationMenuData configuration moves from the section to the block.
    • BlockMenuHeaderBasic — non-standalone, in the desktop slot of SectionHeaderBasic. Mirrors BlockMenuSideBySide but for the basic header.
    • BlockMegaMenu — collapsed to a thin schema/data-binding wrapper around the new MegaMenu compound in ui.
    • BlockProductDetailVariantSelectorOptions — non-standalone child for product-detail variant configuration.

    Schema field renames (Studio data migration required)

    Across 30+ sections/blocks the schema has been normalized to the section-config-standard:

    Old New
    blockMargin margin (uses marginField preset)
    blockPadding padding (uses paddingField preset)
    contentColor (SectionProductSliderShowcase) backgroundBrightness (with enum remap: on-lightlight, on-darkdark, on-brightbright)
    contentColor (SectionProductSlider) (dropped — no replacement)
    textAlignment alignment
    actionButton[0] (array) cta (object via buttonFields) + ctaVisible
    sectionBackground / themePresets / customBackground background + customBackground (via backgroundFields). Value remap on SectionContainer: old theme-presets value flattens to whichever of solid / pale / default the separate themePresets field held; the standalone themePresets prop is dropped.
    headline* heading*
    SectionBrandHero.background (media) backgroundImage (the canonical background name is now free for the painted background)
    productAmountNumber / productAmountWord (SectionFilterBar) productAmount.number / productAmount.word (both gain allowCustom: true)
    accordionStyle (BlockAccordion) variant
    contentPosition (SectionMediaText) alignment (toggle button)
    image (SectionNewsletterRegistration) media
    overlay / overlayStyle / overlayOpacity (BlockHeroSliderSlide) backgroundOverlay (object; variant === 'off' means no overlay)
    buttonText / buttonLink / buttonVariant (BlockCard) cta (object)
    productFlags (SectionProductSlider, SectionProductSliderShowcase) showFlags
    inline checkbox + as: 'visibility' visibilityField() factory
    inline button-variant arrays buttonVariantOptions (canonical ButtonVariant values)
    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").

    Per-section prop / schema-field renames (Studio data migration required)

    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
    BlockIframe url src
    BlockHeroSliderSlide ctas slideButtons
    BlockHeroSliderSlide flags captions (reshape)
    BlockHeroSliderSlide backgroundBrightness (dropped)
    BlockText responsiveSizing (boolean) (dropped — no replacement)
    SectionScrollAnchor id anchorName
    SectionTopBar backgroundColor colorMode
    SectionTopBar showLanguageSwitch showLocaleSelector
    SectionTopBar showModeSwitcher showDarkModeToggle
    SectionFooter showIconButtons socialIconsVisible
    SectionFooter showEmailButton emailButtonVisible
    SectionFooter blockMargin margin
    SectionFooter blockPadding padding
    SectionFooter emailButtonConfig.* emailButton (object reshape)
    SectionPageHero title heading (note: not covered by the generic headline* → heading* row)
    SectionHeaderBasic callToActionButton ctaButtons
    SectionHeaderBasic headerPadding padding
    SectionPersonaQuoteSlider style containerStyle
    SectionPersonaQuoteSlider sectionBackground background
    SectionQuoteCardSlider cardStyleFields cardStyle
    SectionQuoteCardSlider contentAlignment alignment
    SectionQuoteCardSlider sectionBackground background
    SectionCategoryCardSlider header heading
    SectionCategoryCardSlider nodesVariant variant
    SectionProductSlider brand showBrand
    SectionProductSlider productDescription showProductDescription
    SectionProductSlider rating showRating
    SectionProductSlider cta button
    SectionProductSlider blockMargin margin
    SectionProductSlider innerBlockPadding padding
    SectionProductSliderShowcase bannerMedia bannerImage
    SectionProductSliderShowcase showAddToCartButton showAddToCart
    SectionProductSliderShowcase colorSwatches colorSwatchPosition
    SectionProductSliderShowcase maxTitleLength titleLength
    SectionProductSliderShowcase blockMargin margin
    SectionProductSliderShowcase blockPadding padding
    SectionProductSliderShowcase brand / productDescription / rating showBrand / showProductDescription / showRating
    <parent>.overlay.style inner-key on overlay shared-field <parent>.overlay.variant (6 HEAD consumers: SectionBannerBasic.backgroundOverlay, SectionBannerIntegrated.backgroundOverlay, SectionBannerShowcase.backgroundOverlay, SectionBrandHero.backgroundOverlay, SectionProductSliderShowcase.backgroundOverlay, BlockHeroSliderSlide.backgroundOverlay)

    Per-section schema-field deletions (Studio data migration required)

    Section Field(s) dropped
    SectionBreadcrumbs colorMode (entire Style fieldset removed)
    SectionNewsletterRegistration textColor, legal
    SectionPersonaQuoteSlider textColor
    SectionQuoteCardSlider cardStyle, profilePicture
    SectionCategoryCardSlider hasSubCategories, colorMode
    SectionUspBanner bannerStyle, colors (colors.textColor → top-level color, colors.iconColor → top-level iconColor); usps[] extracted to new items slot populated by BlockUspBannerItem

    ctaButton.variant value remap (Studio data migration required)

    The ctaButton.variant enum was reshaped from 12 to 14 values via the new buttonFields.variant (sourced from buttonVariantOptions). Applies to every Studio-stored *.variant field across BlockText.cta, SectionProductSlider.button, all banner CTAs, etc.

    Old (ctaButton.variant) New (buttonFields.variant)
    primary primary
    secondary secondary
    white-ghost ghost-white
    glass glass-black (verify with design)
    white-secondary secondary-white
    black-ghost ghost-black
    white-close close-white
    input-field (dropped — no direct equivalent; map to subtle or drop)
    glass-white glass-white
    black-close close-black
    black-close-always-black close-black (loses always-black semantics)
    white-close-always-white close-white (loses always-white semantics)

    New variants without a predecessor (no migration needed): tertiary, positive, danger, subtle, info.

    Section-config-standard

    • 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 by background / margin / padding), shared-fields/ctaButton.ts (replaced by shared-fields/button.ts + shared-fields/buttonVariant.ts; see the value-remap table above).
    • Modified: shared-fields/overlay.ts — inner-field rename stylevariant (6 HEAD consumers; cross-cutting, see the per-section table above).
    • Modified: shared-fields/productTileQuery.ts — wrapper-fieldset removed; the products prop 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 (with Styling / Layout info-dividers) across 30+ sections/blocks.
    • SectionHeaderBasic background narrowed from backgroundField + customBackground to 'transparent' | 'solid' (default transparent) — the only two values HeaderBasic actually renders. Studio-data migration: stored background values that aren't transparent or solid should be dropped (no remap).
    • SectionEditorialGrid uses the same custom-background resolver pattern as SectionProductReviews: :background="background === 'custom' ? colorValueToCss(customBackground) : background".
    • SectionQuoteCardSlider.cardsAlignment field swapped from a 9-value content_alignment to a toggle_button with left / center (matches QuoteCardSlider.cardsAlignment).
    • SectionProductReviews: dropped the unused percentage field and total intermediate from ratingLevels; stars tuple typed as const.
    • SectionProductSlider / SectionProductSliderShowcase / ConnectedProductTileBasic: productFlagsshowFlags. ConnectedProductTileBasic now declares and forwards show-add-to-cart, show-brand, show-product-description, show-flags, show-rating. showRating is wired via :rating="showRating === false ? undefined : product.rating".

    Section delegation refactor (no schema changes)

    • SectionBlogPostDetail, SectionProductDetail, SectionScrollAnchor, SectionBlogPostListing, SectionMediaText, BlockMedia, BlockIframe are now thin configuration adapters over the corresponding ui components. Imports moved into <script setup>; empty Design panels dropped where appropriate.
    • BlockFooterMenu updates the items array schema (itemLabelProperty + labelSingular instead of a fieldset label).

    Section background pattern consolidation

    Six sections (SectionCategoryCardGrid, SectionCategoryCardSlider, SectionContentGrid, SectionContentSlider, SectionMediaText, SectionPlanComparisonTable) collapse the two-prop backdropBackground + backdropContainerBackground pattern into a single resolvedBackground passed to Backdrop's :background. Backdrop no longer receives :container-background.

    Migration notes for consumers

    HeaderBasicMenu colour values flip. The prop textColor named the foreground colour; the new surfaceTone names the surface. Old text-color="dark" (dark text on light bg) maps to new surface-tone="light", not "dark". Migrate by inverting the value, not just renaming the prop.

    Auto-import tag prefix unified to <L*>. @laioutr-core/ui previously registered components with the Lui prefix; it now uses L, matching @laioutr-core/ui-kit. Templates that referenced <Lui*> for any ui component must be renamed to <L*> — e.g. <LuiProductSlider><LProductSlider>, <LuiMenuSideBySide><LMenuSideBySide>. Components moved from ui-kit to ui (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.

    Imports and template tags

    - 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 />

    Props and bindings

    - <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" />

    CSS class names

    - .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*               { ... }

    Locale keys

    - 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 */

    Studio data migration required

    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 backgroundAwareBackdrop with 'default' as a value must rewrite those entries with the equivalent SurfaceTone directly ('default' was a synonym for 'light').
    • The BlockAccordion.accordionStyle schema field is renamed to variant; 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) and PlanCard (.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_switchers is now .header-basic__switchers; the global sticky-layout class .lui-header--fixed is .lui-header-basic--fixed.

Patch Changes

  • Updated dependencies [97e4e2d]
    • @laioutr-core/ui-kit@2.0.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment