@skyscanner/backpack-web 41.13.0 → 41.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/bpk-component-input/src/withOpenEvents.d.ts +17 -10
  2. package/bpk-component-input/src/withOpenEvents.js +13 -3
  3. package/bpk-component-layout/index.d.ts +18 -0
  4. package/bpk-component-layout/index.js +29 -0
  5. package/bpk-component-layout/src/BpkBox.d.ts +3 -0
  6. package/bpk-component-layout/src/BpkBox.js +35 -0
  7. package/bpk-component-layout/src/BpkFlex.d.ts +3 -0
  8. package/bpk-component-layout/src/BpkFlex.js +53 -0
  9. package/bpk-component-layout/src/BpkGrid.d.ts +3 -0
  10. package/bpk-component-layout/src/BpkGrid.js +59 -0
  11. package/bpk-component-layout/src/BpkGridItem.d.ts +3 -0
  12. package/bpk-component-layout/src/BpkGridItem.js +47 -0
  13. package/bpk-component-layout/src/BpkProvider.d.ts +14 -0
  14. package/bpk-component-layout/src/BpkProvider.js +42 -0
  15. package/bpk-component-layout/src/BpkStack.constant.d.ts +2 -0
  16. package/bpk-component-layout/src/BpkStack.constant.js +22 -0
  17. package/bpk-component-layout/src/BpkStack.d.ts +5 -0
  18. package/bpk-component-layout/src/BpkStack.js +61 -0
  19. package/bpk-component-layout/src/BpkVessel.d.ts +46 -0
  20. package/bpk-component-layout/src/BpkVessel.js +72 -0
  21. package/bpk-component-layout/src/commonProps.d.ts +86 -0
  22. package/bpk-component-layout/src/commonProps.js +1 -0
  23. package/bpk-component-layout/src/theme.d.ts +36 -0
  24. package/bpk-component-layout/src/theme.js +229 -0
  25. package/bpk-component-layout/src/tokenUtils.d.ts +108 -0
  26. package/bpk-component-layout/src/tokenUtils.js +323 -0
  27. package/bpk-component-layout/src/tokens.d.ts +96 -0
  28. package/bpk-component-layout/src/tokens.js +138 -0
  29. package/bpk-component-layout/src/types.d.ts +236 -0
  30. package/bpk-component-layout/src/types.js +1 -0
  31. package/package.json +2 -1
@@ -0,0 +1,86 @@
1
+ import type { BpkSpacingValue, BpkSizeValue, BpkPositionValue, BpkResponsiveValue } from './tokens';
2
+ /**
3
+ * Common spacing-related props shared by all Backpack layout components
4
+ * All spacing props must use Backpack spacing tokens or percentages
5
+ */
6
+ export interface BpkSpacingProps {
7
+ padding?: BpkResponsiveValue<BpkSpacingValue>;
8
+ paddingTop?: BpkResponsiveValue<BpkSpacingValue>;
9
+ paddingRight?: BpkResponsiveValue<BpkSpacingValue>;
10
+ paddingBottom?: BpkResponsiveValue<BpkSpacingValue>;
11
+ paddingLeft?: BpkResponsiveValue<BpkSpacingValue>;
12
+ margin?: BpkResponsiveValue<BpkSpacingValue>;
13
+ marginTop?: BpkResponsiveValue<BpkSpacingValue>;
14
+ marginRight?: BpkResponsiveValue<BpkSpacingValue>;
15
+ marginBottom?: BpkResponsiveValue<BpkSpacingValue>;
16
+ marginLeft?: BpkResponsiveValue<BpkSpacingValue>;
17
+ marginStart?: BpkResponsiveValue<BpkSpacingValue>;
18
+ marginEnd?: BpkResponsiveValue<BpkSpacingValue>;
19
+ paddingStart?: BpkResponsiveValue<BpkSpacingValue>;
20
+ paddingEnd?: BpkResponsiveValue<BpkSpacingValue>;
21
+ marginInline?: BpkResponsiveValue<BpkSpacingValue>;
22
+ paddingInline?: BpkResponsiveValue<BpkSpacingValue>;
23
+ gap?: BpkResponsiveValue<BpkSpacingValue>;
24
+ width?: BpkResponsiveValue<BpkSizeValue>;
25
+ height?: BpkResponsiveValue<BpkSizeValue>;
26
+ minWidth?: BpkResponsiveValue<BpkSizeValue>;
27
+ minHeight?: BpkResponsiveValue<BpkSizeValue>;
28
+ maxWidth?: BpkResponsiveValue<BpkSizeValue>;
29
+ maxHeight?: BpkResponsiveValue<BpkSizeValue>;
30
+ top?: BpkResponsiveValue<BpkPositionValue>;
31
+ right?: BpkResponsiveValue<BpkPositionValue>;
32
+ bottom?: BpkResponsiveValue<BpkPositionValue>;
33
+ left?: BpkResponsiveValue<BpkPositionValue>;
34
+ }
35
+ /**
36
+ * Common props for all Backpack layout components
37
+ * Combines spacing and color props, and explicitly excludes className and
38
+ * certain props (e.g. typography, composite borders, transitions) to keep
39
+ * layout components purely structural.
40
+ *
41
+ * NOTE:
42
+ * - Layout components other than BpkBox do not expose event handlers.
43
+ * - BpkBox reintroduces a minimal set of events (onClick, onFocus, onBlur)
44
+ * on its own props type.
45
+ */
46
+ export interface BpkCommonLayoutProps extends BpkSpacingProps {
47
+ className?: never;
48
+ style?: never;
49
+ 'data-testid'?: string;
50
+ 'data-cy'?: string;
51
+ color?: never;
52
+ background?: never;
53
+ backgroundColor?: never;
54
+ borderColor?: never;
55
+ borderTopColor?: never;
56
+ borderRightColor?: never;
57
+ borderBottomColor?: never;
58
+ borderLeftColor?: never;
59
+ borderWidth?: never;
60
+ borderTopWidth?: never;
61
+ borderRightWidth?: never;
62
+ borderBottomWidth?: never;
63
+ borderLeftWidth?: never;
64
+ borderRadius?: never;
65
+ borderTopLeftRadius?: never;
66
+ borderTopRightRadius?: never;
67
+ borderBottomLeftRadius?: never;
68
+ borderBottomRightRadius?: never;
69
+ boxShadow?: never;
70
+ border?: never;
71
+ borderTop?: never;
72
+ borderRight?: never;
73
+ borderBottom?: never;
74
+ borderLeft?: never;
75
+ borderInline?: never;
76
+ borderBlock?: never;
77
+ borderX?: never;
78
+ borderY?: never;
79
+ transition?: never;
80
+ transitionProperty?: never;
81
+ transitionDuration?: never;
82
+ transitionTimingFunction?: never;
83
+ transitionDelay?: never;
84
+ transform?: never;
85
+ transformOrigin?: never;
86
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Exports spacing map for use in tokenUtils
3
+ * This allows tokenUtils to look up actual spacing values
4
+ *
5
+ * @returns {Record<string, string>} A map of spacing token names to values.
6
+ */
7
+ export declare function getSpacingMap(): Record<string, string>;
8
+ /**
9
+ * Gets the actual spacing value for a Backpack spacing token
10
+ *
11
+ * @param {string} token - Backpack spacing token name.
12
+ * @returns {string | undefined} The actual spacing value.
13
+ */
14
+ export declare function getSpacingValue(token: string): string | undefined;
15
+ /**
16
+ * Gets the actual border width value for a Backpack border size token
17
+ *
18
+ * @param {string} token - Backpack border size token name.
19
+ * @returns {string | undefined} The actual border width value.
20
+ */
21
+ export declare function getBorderSizeValue(token: string): string | undefined;
22
+ /**
23
+ * Gets the actual border radius value for a Backpack border radius token
24
+ *
25
+ * @param {string} token - Backpack border radius token name.
26
+ * @returns {string | undefined} The actual border radius value.
27
+ */
28
+ export declare function getBorderRadiusValue(token: string): string | undefined;
29
+ /**
30
+ * Gets the actual box-shadow value for a Backpack shadow token
31
+ *
32
+ * @param {string} token - Backpack shadow token name.
33
+ * @returns {string | undefined} The actual box-shadow value.
34
+ */
35
+ export declare function getShadowValue(token: string): string | undefined;
36
+ export declare function createBpkConfig(): import("@chakra-ui/react").SystemConfig;
@@ -0,0 +1,229 @@
1
+ /*
2
+ * Backpack - Skyscanner's Design System
3
+ *
4
+ * Copyright 2016 Skyscanner Ltd
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import { defineConfig } from '@chakra-ui/react';
20
+ // Import tokens from Backpack foundations
21
+ // Note: Some tokens may not be in TypeScript definitions but exist at runtime
22
+
23
+ const bpkTokens = require('@skyscanner/bpk-foundations-web/tokens/base.es6');
24
+
25
+ // NOTE:
26
+ // We intentionally do not use the raw breakpoint *values* from foundations here.
27
+ // Foundations exports breakpoint values such as `breakpointMobile = "32rem"` which
28
+ // are used primarily for max-width queries (e.g. `(max-width: 32rem)`).
29
+ //
30
+ // Backpack layout responsive values in this package are mobile-first and behave
31
+ // like Chakra breakpoints (min-width thresholds). To align with Backpack’s
32
+ // intended breakpoint ranges we define lower-bound (min-width) thresholds:
33
+ //
34
+ // - small-mobile: 320px+
35
+ // - mobile: 360px+
36
+ // - small-tablet: 513px+
37
+ // - tablet: 769px+
38
+ // - desktop: 1025px+
39
+
40
+ // Note: Spacing tokens are defined as SCSS functions in Backpack foundations,
41
+ // not as direct values. We need to use the actual rem values from the SCSS functions.
42
+ // Based on @skyscanner/bpk-foundations-web/tokens/base.default.scss:
43
+ // - bpk-spacing-sm() returns .25rem
44
+ // - bpk-spacing-md() returns .5rem
45
+ // - bpk-spacing-lg() returns 1.5rem
46
+ // - bpk-spacing-xl() returns 2rem (needs verification)
47
+ // - bpk-spacing-xxl() returns 2.5rem
48
+ // - bpk-spacing-base() returns 1rem (standard base spacing)
49
+ // TODO: CLOV-1021 - will add spacing tokens to Backpack Foundations package and use them here after we ship the PoC
50
+ const spacingXs = '.125rem'; // 2px
51
+ const spacingSm = '.25rem';
52
+ const spacingBase = '1rem'; // Standard base spacing
53
+ const spacingMd = '.5rem';
54
+ const spacingLg = '1.5rem';
55
+ const spacingXl = '2rem';
56
+ const spacingXxl = '2.5rem';
57
+
58
+ /**
59
+ * Backpack Theme Configuration for Chakra UI
60
+ *
61
+ * This theme maps Backpack design tokens from @skyscanner/bpk-foundations-web
62
+ * to Chakra UI's theme structure.
63
+ */
64
+
65
+ /**
66
+ * Maps Backpack spacing tokens to actual rem values.
67
+ * These come directly from @skyscanner/bpk-foundations-web.
68
+ */
69
+ // Spacing tokens - directly imported from foundations
70
+ const spacingMap = {
71
+ 'bpk-spacing-none': {
72
+ value: '0'
73
+ },
74
+ // Temporary: Foundations does not yet export a 2px spacing token. This will be
75
+ // replaced with a foundations value once available.
76
+ 'bpk-spacing-xs': {
77
+ value: spacingXs
78
+ },
79
+ 'bpk-spacing-sm': {
80
+ value: spacingSm
81
+ },
82
+ 'bpk-spacing-base': {
83
+ value: spacingBase
84
+ },
85
+ 'bpk-spacing-md': {
86
+ value: spacingMd
87
+ },
88
+ 'bpk-spacing-lg': {
89
+ value: spacingLg
90
+ },
91
+ 'bpk-spacing-xl': {
92
+ value: spacingXl
93
+ },
94
+ 'bpk-spacing-xxl': {
95
+ value: spacingXxl
96
+ }
97
+ };
98
+
99
+ /**
100
+ * Maps Backpack border size tokens to actual border width values
101
+ * These come directly from @skyscanner/bpk-foundations-web
102
+ */
103
+ const borderSizeMap = {
104
+ 'bpk-border-size-sm': bpkTokens.borderSizeSm,
105
+ 'bpk-border-size-lg': bpkTokens.borderSizeLg,
106
+ 'bpk-border-size-xl': bpkTokens.borderSizeXl
107
+ };
108
+
109
+ /**
110
+ * Maps Backpack border radius tokens to actual radius values.
111
+ * These come directly from @skyscanner/bpk-foundations-web.
112
+ */
113
+ const borderRadiusMap = {
114
+ 'bpk-border-radius-none': '0',
115
+ 'bpk-border-radius-xs': bpkTokens.borderRadiusXs,
116
+ 'bpk-border-radius-sm': bpkTokens.borderRadiusSm,
117
+ 'bpk-border-radius-md': bpkTokens.borderRadiusMd,
118
+ 'bpk-border-radius-lg': bpkTokens.borderRadiusLg,
119
+ 'bpk-border-radius-xl': bpkTokens.borderRadiusXl,
120
+ 'bpk-border-radius-full': bpkTokens.borderRadiusFull
121
+ };
122
+
123
+ /**
124
+ * Maps Backpack shadow tokens to actual box-shadow values
125
+ * These come directly from @skyscanner/bpk-foundations-web
126
+ */
127
+ const shadowMap = {
128
+ 'bpk-shadow-sm': bpkTokens.boxShadowSm,
129
+ 'bpk-shadow-lg': bpkTokens.boxShadowLg,
130
+ 'bpk-shadow-xl': bpkTokens.boxShadowXl
131
+ };
132
+
133
+ /**
134
+ * Chakra expects raw width values (e.g. "48rem"), not full media queries.
135
+ * The media query construction is handled internally by Chakra's system.
136
+ *
137
+ * We align Backpack breakpoint tokens to Chakra's keys like this:
138
+ * - base: 0 (implicit)
139
+ * - sm: small-mobile (>= 320px)
140
+ * - md: mobile (>= 360px)
141
+ * - lg: small-tablet (>= 513px)
142
+ * - xl: tablet (>= 769px)
143
+ * - 2xl: desktop (>= 1025px)
144
+ */
145
+ // TODO: CLOV-1021 - will add breakpoint boundary tokens to Backpack Foundations package and use them here after we ship the PoC
146
+ const breakpointMap = {
147
+ base: '0rem',
148
+ sm: '20rem',
149
+ // 320px
150
+ md: '22.5rem',
151
+ // 360px
152
+ lg: '32.0625rem',
153
+ // 513px
154
+ xl: '48.0625rem',
155
+ // 769px
156
+ '2xl': '64.0625rem' // 1025px
157
+ };
158
+
159
+ /**
160
+ * Exports spacing map for use in tokenUtils
161
+ * This allows tokenUtils to look up actual spacing values
162
+ *
163
+ * @returns {Record<string, string>} A map of spacing token names to values.
164
+ */
165
+ export function getSpacingMap() {
166
+ // Return simple string values for backward compatibility with utilities
167
+ const simpleMap = {};
168
+ Object.entries(spacingMap).forEach(([key, obj]) => {
169
+ simpleMap[key] = obj.value;
170
+ });
171
+ return simpleMap;
172
+ }
173
+
174
+ /**
175
+ * Gets the actual spacing value for a Backpack spacing token
176
+ *
177
+ * @param {string} token - Backpack spacing token name.
178
+ * @returns {string | undefined} The actual spacing value.
179
+ */
180
+ export function getSpacingValue(token) {
181
+ return spacingMap[token]?.value;
182
+ }
183
+
184
+ /**
185
+ * Gets the actual border width value for a Backpack border size token
186
+ *
187
+ * @param {string} token - Backpack border size token name.
188
+ * @returns {string | undefined} The actual border width value.
189
+ */
190
+ export function getBorderSizeValue(token) {
191
+ return borderSizeMap[token];
192
+ }
193
+
194
+ /**
195
+ * Gets the actual border radius value for a Backpack border radius token
196
+ *
197
+ * @param {string} token - Backpack border radius token name.
198
+ * @returns {string | undefined} The actual border radius value.
199
+ */
200
+ export function getBorderRadiusValue(token) {
201
+ return borderRadiusMap[token];
202
+ }
203
+
204
+ /**
205
+ * Gets the actual box-shadow value for a Backpack shadow token
206
+ *
207
+ * @param {string} token - Backpack shadow token name.
208
+ * @returns {string | undefined} The actual box-shadow value.
209
+ */
210
+ export function getShadowValue(token) {
211
+ return shadowMap[token];
212
+ }
213
+ export function createBpkConfig() {
214
+ // Convert breakpoint map to Chakra UI format
215
+ // Breakpoints in Chakra v3 are typically simple strings in the breakpoints object
216
+ const chakraBreakpoints = {};
217
+ Object.entries(breakpointMap).forEach(([token, value]) => {
218
+ chakraBreakpoints[token] = value;
219
+ });
220
+ return defineConfig({
221
+ cssVarsPrefix: 'bpk',
222
+ theme: {
223
+ tokens: {
224
+ spacing: spacingMap
225
+ },
226
+ breakpoints: chakraBreakpoints
227
+ }
228
+ });
229
+ }
@@ -0,0 +1,108 @@
1
+ export type BpkLayoutComponentName = 'BpkBox' | 'BpkFlex' | 'BpkGrid' | 'BpkStack';
2
+ /**
3
+ * Allowlisted, component-scoped prop groups that are eligible for Backpack responsive value
4
+ * processing (Backpack breakpoint keys -> Chakra breakpoint keys).
5
+ *
6
+ * NOTE:
7
+ * - Spacing/size/position props are processed separately via `processBpkProps` and therefore
8
+ * are intentionally NOT included here.
9
+ * - These groups are meant to keep the responsive surface predictable per component, while
10
+ * avoiding duplicated per-component breakpoint mapping logic.
11
+ */
12
+ type BpkResponsivePropGroups = {
13
+ /**
14
+ * Container-level layout props (how children are laid out).
15
+ */
16
+ container: readonly string[];
17
+ /**
18
+ * Item-level layout props (how this element participates in a parent layout).
19
+ */
20
+ item?: readonly string[];
21
+ };
22
+ export declare const BPK_RESPONSIVE_PROP_GROUPS_BY_COMPONENT: Record<BpkLayoutComponentName, BpkResponsivePropGroups>;
23
+ export declare const BPK_RESPONSIVE_PROP_KEYS_BY_COMPONENT: Record<BpkLayoutComponentName, readonly string[]>;
24
+ export type ProcessBpkComponentPropsOptions = {
25
+ component: BpkLayoutComponentName;
26
+ /**
27
+ * Optional map of responsive props. When provided, it will be filtered to the
28
+ * allowlist for the given component, then breakpoint-normalised.
29
+ *
30
+ * This is useful for components like `BpkFlex` and `BpkGrid` that expose a
31
+ * public API with different prop names.
32
+ */
33
+ responsiveProps?: Record<string, any>;
34
+ /**
35
+ * Optional mapping of source prop name -> target prop name.
36
+ * Primarily kept for parity with `processResponsiveProps`.
37
+ */
38
+ propNameMap?: Record<string, string>;
39
+ };
40
+ /**
41
+ * Process a component's props in one place:
42
+ * - strip className/style
43
+ * - process spacing/size/position props (including breakpoint mapping + token conversion)
44
+ * - process allowlisted non-spacing responsive layout props (breakpoint mapping only)
45
+ *
46
+ * The allowlist is grouped by component via `BPK_RESPONSIVE_PROP_KEYS_BY_COMPONENT`.
47
+ *
48
+ * @param {T} props - The component props to process.
49
+ * @param {ProcessBpkComponentPropsOptions} options - Component processing options (allowlist group + mapping).
50
+ * @returns {Record<string, any>} The processed props ready to pass to Chakra primitives.
51
+ */
52
+ export declare function processBpkComponentProps<T extends Record<string, any>>(props: T, options: ProcessBpkComponentPropsOptions): Record<string, any>;
53
+ /**
54
+ * Converts Backpack spacing token to Chakra UI compatible value
55
+ * Returns the actual spacing value from the theme, not a token path
56
+ *
57
+ * @param {string} value - Backpack spacing token (e.g., 'bpk-spacing-base') or percentage
58
+ * @returns {string} The actual spacing value in rem or the percentage string
59
+ */
60
+ export declare function convertBpkSpacingToChakra(value: string): string;
61
+ /**
62
+ * Recursively processes responsive values (arrays or objects) to validate and convert tokens
63
+ *
64
+ * @param {*} value - The value to process (could be string, array, or object)
65
+ * @param {Function} converter - Function to convert valid tokens to actual values
66
+ * @param {Function} validator - Function to validate if a token is allowed
67
+ * @param {string} propName - The name of the prop being processed (for warning messages)
68
+ * @returns {*} The processed value with tokens converted, or undefined for invalid tokens
69
+ */
70
+ export declare function normalizeResponsiveObject<T>(value: Record<string, T>): Record<string, T>;
71
+ export declare function processResponsiveValue(value: any, converter: (v: string) => string, validator: (v: string) => boolean, propName: string): any;
72
+ /**
73
+ * Validates and converts spacing props for Chakra UI
74
+ * Handles all spacing-related properties including padding, margin, gap, size, border radius and position
75
+ *
76
+ * @param {T} props - Component props object
77
+ * @returns {Record<string, any>} Processed props with spacing tokens converted to actual values
78
+ */
79
+ export declare function processSpacingProps<T extends Record<string, any>>(props: T): Record<string, any>;
80
+ /**
81
+ * Processes all props to convert Backpack tokens to Chakra UI format
82
+ * Also explicitly removes className and style to prevent ad-hoc overrides
83
+ *
84
+ * Processing order:
85
+ * 1. Remove className & style
86
+ * 2. Process spacing props (includes position)
87
+ *
88
+ * @param {T} props - Component props object
89
+ * @returns {Record<string, any>} Processed props with tokens converted and disallowed props removed
90
+ */
91
+ export declare function processBpkProps<T extends Record<string, any>>(props: T): Record<string, any>;
92
+ /**
93
+ * Processes responsive props that are simple string/enum values (non-spacing)
94
+ * using Backpack breakpoint keys. Array syntax is rejected as in spacing.
95
+ *
96
+ * @param {*} value - The value to process
97
+ * @param {string} propName - The name of the prop being processed
98
+ * @returns {*} The processed value with breakpoint keys mapped to Chakra keys
99
+ */
100
+ export declare function processResponsiveStringProp(value: any, propName: string): any;
101
+ /**
102
+ * Processes a collection of responsive props.
103
+ * @param {Record<string, any>} props - Object containing prop values.
104
+ * @param {Record<string, string>} propNameMap - Map of prop name to CSS/Chakra property name (for error messages and mapping).
105
+ * @returns {Record<string, any>} Processed props object.
106
+ */
107
+ export declare function processResponsiveProps(props: Record<string, any>, propNameMap?: Record<string, string>): Record<string, any>;
108
+ export {};