Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d112d70
Initialize the bpk-component-layout directory
Faye-Xiao Dec 2, 2025
5513904
[CLOV-985][bpk-component-layout]Initialize the bpk-component-layout d…
Faye-Xiao Dec 8, 2025
bcf7931
fix(layout): wrap BpkBox tests in BpkProvider (#4077)
Faye-Xiao Dec 9, 2025
9ecd15a
[CLOV-989][BpkStack] Add BpkStack (#4075)
IrinaWei Dec 15, 2025
4c7d43d
[CLOV-987][BpkFlex][BpkGrid]Add Grid and Flex (#4074)
kerrie-wu Dec 15, 2025
cb273bb
[Clov-970][bpk-component-layout] Improve backpack layout logic and ti…
Faye-Xiao Dec 16, 2025
06f7544
bpk-component-layout: add temporary 2px spacing token (xs) (#4088)
Faye-Xiao Dec 19, 2025
858dff2
Bump @skyscanner/stylelint-config-skyscanner from 13.1.0 to 14.2.0 (#…
dependabot[bot] Dec 4, 2025
7740937
Bump the storybook group across 1 directory with 5 updates (#4058)
dependabot[bot] Dec 5, 2025
b5b706f
Bump jws from 3.2.2 to 3.2.3 (#4066)
dependabot[bot] Dec 8, 2025
a259d36
[CLOV-907][BpkButton] Update BpkButton link and linkOnDark type style…
Supremeyh Dec 16, 2025
6cec705
[CLOV-958][BpkButton] Remove BpkButton (v1) code and alias BpkButton …
xiaogliu Dec 16, 2025
545eff5
[CLOV-907][BpkButton] Fix BpkButton linkOnDark alignment (#4086)
Supremeyh Dec 16, 2025
21e03d9
Bump lint-staged from 16.1.5 to 16.2.7 (#4071)
dependabot[bot] Dec 17, 2025
46a0242
Bump glob from 11.1.0 to 13.0.0 (#4072)
dependabot[bot] Dec 17, 2025
198327a
[BpkLink] Migrate component to TypeScript (#4063)
Copilot Dec 18, 2025
c8448f6
bump bpk-foundations-web to 24.0.0 (#4092)
floracheng292 Dec 19, 2025
c08b3aa
feat[BpkPrice]: added variant size medium (#4089)
nicdaCosta Dec 22, 2025
7369958
Merge branch 'main' into bpk-layout-PoC
Faye-Xiao Dec 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import type { StorybookConfig } from '@storybook/react-webpack5';

const config: StorybookConfig = {
stories: [
'../examples/**/stories.@(ts|tsx|js|jsx)',
'../examples/**/{stories,*.stories}.@(ts|tsx|js|jsx)',
],
addons: [
'@storybook/addon-a11y',
Expand Down
203 changes: 203 additions & 0 deletions examples/bpk-component-layout/box-examples.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/*
* Backpack - Skyscanner's Design System
*
* Copyright 2016 Skyscanner Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {
BpkBox,
BpkSpacing,
} from '../../packages/bpk-component-layout';

import Wrapper from './layout-wrapper';

import STYLES from './examples.module.scss';

/**
* Core layout example – demonstrates basic spacing usage.
*
* @returns {JSX.Element} A box with padding and margin using Backpack spacing tokens.
*/
export const SpacingExample = () => (
<Wrapper>
<BpkBox padding={BpkSpacing.MD} margin={BpkSpacing.MD}>
<span className={STYLES['bpk-layout-examples__outline']}>
Default box with padding and margin using Backpack spacing tokens.
</span>
</BpkBox>
</Wrapper>
);

/**
* RTL-friendly spacing example – demonstrates margin/padding logical props.
*
* @returns {JSX.Element} Box using marginInline & paddingInline in RTL context.
*/
export const RtlSpacingExample = () => (
<Wrapper>
<div dir="rtl">
<BpkBox
paddingInline={BpkSpacing.MD}
marginInline={BpkSpacing.MD}
paddingTop={BpkSpacing.MD}
paddingBottom={BpkSpacing.Base}
>
<span className={STYLES['bpk-layout-examples__outline']}>
Box using marginInline &amp; paddingInline in RTL context.
</span>
</BpkBox>
</div>
</Wrapper>
);

/**
* Size example – demonstrates width/height using semantic values.
*
* @returns {JSX.Element} Box with 50% width and 6rem minHeight.
*/
export const SizeExample = () => (
<Wrapper>
<BpkBox width="50%" minHeight="6rem">
<span className={STYLES['bpk-layout-examples__outline']}>
Box with 50% width and 6rem minHeight.
</span>
</BpkBox>
</Wrapper>
);

/**
* Responsive example – demonstrates breakpoint-based responsive layout props.
*
* @returns {JSX.Element} A box whose spacing changes across breakpoints.
*/
export const ResponsiveExample = () => (
<Wrapper>
<BpkBox
display="flex"
padding={{
base: BpkSpacing.SM,
mobile: BpkSpacing.Base,
tablet: BpkSpacing.MD,
desktop: BpkSpacing.LG,
}}
gap={{
base: BpkSpacing.SM,
mobile: BpkSpacing.Base,
tablet: BpkSpacing.MD,
desktop: BpkSpacing.LG,
}}
>
<BpkBox>
<span className={STYLES['bpk-layout-examples__outline']}>
Responsive item 1
</span>
</BpkBox>
<BpkBox>
<span className={STYLES['bpk-layout-examples__outline']}>
Responsive item 2
</span>
</BpkBox>
</BpkBox>
</Wrapper>
);

/**
* Position example – demonstrates top/left offsets using allowed values.
*
* @returns {JSX.Element} A relative box with an absolutely positioned child.
*/
export const PositionExample = () => (
<Wrapper>
<BpkBox padding={BpkSpacing.MD}>
<BpkBox position="relative" width="10rem" minHeight="6rem">
<span className={STYLES['bpk-layout-examples__outline']}>
Relative box (10rem x 6rem)
</span>
<BpkBox position="absolute" top="12rem" left="6rem">
<span className={STYLES['bpk-layout-examples__outline']}>
Positioned child (top/left from 12rem, 6rem)
</span>
</BpkBox>
</BpkBox>
</BpkBox>
</Wrapper>
);

/**
* Flexbox example – demonstrates using BpkBox as a flex container.
*
* @returns {JSX.Element} A flex row with evenly spaced items.
*/
export const FlexExample = () => (
<Wrapper>
<BpkBox
display="flex"
flexDirection="row"
justifyContent="space-between"
padding={BpkSpacing.MD}
>
{[1, 2, 3].map((i) => (
<BpkBox key={i} padding={BpkSpacing.SM}>
<span className={STYLES['bpk-layout-examples__outline']}>
Flex item {i}
</span>
</BpkBox>
))}
</BpkBox>
</Wrapper>
);

/**
* Grid example – demonstrates using BpkBox as a grid container.
*
* @returns {JSX.Element} A simple three-column grid.
*/
export const GridExample = () => (
<Wrapper>
<BpkBox
display="grid"
gridTemplateColumns="repeat(3, minmax(0, 1fr))"
gap={BpkSpacing.MD}
padding={BpkSpacing.MD}
>
{[1, 2, 3, 4, 5, 6].map((i) => (
<BpkBox key={i} padding={BpkSpacing.SM}>
<span className={STYLES['bpk-layout-examples__outline']}>
Grid cell {i}
</span>
</BpkBox>
))}
</BpkBox>
</Wrapper>
);

/**
* Mixed visual regression example – used for Percy/visual tests.
*
* @returns {JSX.Element} A wrapper containing all Box examples for visual regression.
*/
export const MixedExample = () => (
<Wrapper>
<SpacingExample />
<RtlSpacingExample />
<SizeExample />
<ResponsiveExample />
<PositionExample />
<FlexExample />
<GridExample />
</Wrapper>
);


67 changes: 67 additions & 0 deletions examples/bpk-component-layout/box.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Backpack - Skyscanner's Design System
*
* Copyright 2016 Skyscanner Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { ArgTypes, Title, Markdown } from '@storybook/addon-docs/blocks';

import { BpkProvider, BpkBox } from '../../packages/bpk-component-layout';

import {
SpacingExample,
RtlSpacingExample,
SizeExample,
ResponsiveExample,
PositionExample,
FlexExample,
GridExample,
} from './box-examples';

export default {
title: 'bpk-component-layout/Box',
component: BpkBox,
decorators: [
(Story: any) => (
<BpkProvider>
<Story />
</BpkProvider>
),
],
parameters: {
docs: {
page: () => (
<>
<Title />
<ArgTypes exclude={['zoomEnabled']} />
<Markdown>
Notes: `BpkBox` is the base layout primitive. It exposes a curated,
structural prop surface and tokenised spacing.
</Markdown>
</>
),
},
},
};

export const Spacing = () => <SpacingExample />;
export const RtlSpacing = () => <RtlSpacingExample />;
export const Size = () => <SizeExample />;
export const Responsive = () => <ResponsiveExample />;
export const Position = () => <PositionExample />;
export const FlexViaBox = () => <FlexExample />;
export const GridViaBox = () => <GridExample />;


66 changes: 66 additions & 0 deletions examples/bpk-component-layout/examples.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Backpack - Skyscanner's Design System
*
* Copyright 2016 Skyscanner Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

@use '../../packages/bpk-mixins/tokens';
@use '../../packages/bpk-mixins/typography';

.bpk-layout-examples {
&__frame {
padding: tokens.bpk-spacing-base();
background-color: tokens.$bpk-canvas-contrast-day;
border-radius: tokens.$bpk-border-radius-md;

// Subtle grid to make layout boundaries easier to see.
background-size: 8px 8px;

// Outline the root element of each example (not the inner content).
// This avoids needing border props on layout primitives.
> :where(*) {
outline: tokens.$bpk-border-size-sm solid tokens.$bpk-line-day;
outline-offset: tokens.bpk-spacing-sm();
background-color: tokens.$bpk-canvas-day;
}
}

// Generic “item boundary” styling for Storybook examples.
// Use this on regular DOM elements (not layout primitives) to avoid exposing
// border props on the layout surface.
&__item {
outline: tokens.$bpk-border-size-sm solid tokens.$bpk-line-day;
outline-offset: 0;
border-radius: tokens.$bpk-border-radius-sm;
background-color: tokens.$bpk-canvas-day;
box-sizing: border-box;
}

&__outline {
@include typography.bpk-body-default;

display: block;
width: 100%;
padding: tokens.bpk-spacing-sm();

color: tokens.$bpk-text-primary-day;
background-color: tokens.$bpk-surface-highlight-day;

outline: tokens.$bpk-border-size-sm dashed tokens.$bpk-line-day;
outline-offset: 0;
border-radius: tokens.$bpk-border-radius-sm;
box-sizing: border-box;
}
}
Loading
Loading