@skyscanner/backpack-web 42.0.0 → 42.2.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 (153) hide show
  1. package/bpk-component-banner-alert/src/BpkBannerAlert.js +0 -7
  2. package/bpk-component-breakpoint/src/BpkBreakpoint.js +3 -1
  3. package/bpk-component-button/src/BpkButton.d.ts +1 -1
  4. package/bpk-component-button/src/BpkButton.js +17 -3
  5. package/bpk-component-button/src/BpkButton.module.css +1 -1
  6. package/bpk-component-button/src/common-types.d.ts +2 -0
  7. package/bpk-component-calendar/src/utils.js +1 -1
  8. package/bpk-component-card/index.d.ts +4 -1
  9. package/bpk-component-card/index.js +3 -1
  10. package/bpk-component-card/src/BpkCardV2/BpkCardV2.d.ts +27 -0
  11. package/bpk-component-card/src/BpkCardV2/BpkCardV2.js +57 -0
  12. package/bpk-component-card/src/BpkCardV2/BpkCardV2.module.css +18 -0
  13. package/bpk-component-card/src/BpkCardV2/common-types.d.ts +124 -0
  14. package/bpk-component-card/src/BpkCardV2/common-types.js +102 -0
  15. package/bpk-component-card/src/BpkCardV2/subcomponents/Body.d.ts +36 -0
  16. package/bpk-component-card/src/BpkCardV2/subcomponents/Body.js +65 -0
  17. package/bpk-component-card/src/BpkCardV2/subcomponents/Divider.d.ts +13 -0
  18. package/bpk-component-card/src/BpkCardV2/subcomponents/Divider.js +37 -0
  19. package/bpk-component-card/src/BpkCardV2/subcomponents/Footer.d.ts +24 -0
  20. package/bpk-component-card/src/BpkCardV2/subcomponents/Footer.js +60 -0
  21. package/bpk-component-card/src/BpkCardV2/subcomponents/Header.d.ts +24 -0
  22. package/bpk-component-card/src/BpkCardV2/subcomponents/Header.js +60 -0
  23. package/bpk-component-card/src/BpkCardV2/subcomponents/Root.d.ts +28 -0
  24. package/bpk-component-card/src/BpkCardV2/subcomponents/Root.js +68 -0
  25. package/bpk-component-card/src/BpkCardV2/subcomponents/Section.d.ts +22 -0
  26. package/bpk-component-card/src/BpkCardV2/subcomponents/Section.js +53 -0
  27. package/bpk-component-card/src/BpkCardV2/subcomponents/resolveDirectionalPadding.d.ts +16 -0
  28. package/bpk-component-card/src/BpkCardV2/subcomponents/resolveDirectionalPadding.js +32 -0
  29. package/bpk-component-card-list/src/BpkCardList.module.css +1 -1
  30. package/bpk-component-card-list/src/BpkCardListRowRail/BpkCardListCarousel.js +3 -3
  31. package/bpk-component-chatbot-input/index.d.ts +7 -0
  32. package/bpk-component-chatbot-input/index.js +23 -0
  33. package/bpk-component-chatbot-input/src/BpkChatbotInput.d.ts +4 -0
  34. package/bpk-component-chatbot-input/src/BpkChatbotInput.js +118 -0
  35. package/bpk-component-chatbot-input/src/BpkChatbotInput.module.css +18 -0
  36. package/bpk-component-chatbot-input/src/InputField/InputField.d.ts +3 -0
  37. package/bpk-component-chatbot-input/src/InputField/InputField.js +82 -0
  38. package/bpk-component-chatbot-input/src/InputField.module.css +18 -0
  39. package/bpk-component-chatbot-input/src/SendButton/SendButton.d.ts +9 -0
  40. package/bpk-component-chatbot-input/src/SendButton/SendButton.js +47 -0
  41. package/bpk-component-chatbot-input/src/TextAreaField/TextAreaField.d.ts +10 -0
  42. package/bpk-component-chatbot-input/src/TextAreaField/TextAreaField.js +93 -0
  43. package/bpk-component-chatbot-input/src/TextAreaField.module.css +18 -0
  44. package/bpk-component-chatbot-input/src/common-types.d.ts +37 -0
  45. package/bpk-component-chatbot-input/src/common-types.js +23 -0
  46. package/bpk-component-chatbot-input/src/constants.d.ts +5 -0
  47. package/bpk-component-chatbot-input/src/constants.js +22 -0
  48. package/bpk-component-chatbot-input/src/hooks/index.d.ts +4 -0
  49. package/bpk-component-chatbot-input/src/hooks/index.js +22 -0
  50. package/bpk-component-chatbot-input/src/hooks/useChatbotInput.d.ts +32 -0
  51. package/bpk-component-chatbot-input/src/hooks/useChatbotInput.js +111 -0
  52. package/bpk-component-chatbot-input/src/hooks/useChatbotInputManager.d.ts +20 -0
  53. package/bpk-component-chatbot-input/src/hooks/useChatbotInputManager.js +83 -0
  54. package/bpk-component-chatbot-input/src/hooks/useInputHandlers.d.ts +8 -0
  55. package/bpk-component-chatbot-input/src/hooks/useInputHandlers.js +54 -0
  56. package/bpk-component-chatbot-input/src/hooks/useTextAreaAutoResize.d.ts +22 -0
  57. package/bpk-component-chatbot-input/src/hooks/useTextAreaAutoResize.js +137 -0
  58. package/bpk-component-chatbot-input/src/themeAttributes.d.ts +14 -0
  59. package/bpk-component-chatbot-input/src/themeAttributes.js +34 -0
  60. package/bpk-component-checkbox/index.d.ts +7 -1
  61. package/bpk-component-checkbox/index.js +3 -1
  62. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2.d.ts +9 -0
  63. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2.js +33 -0
  64. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2.module.css +18 -0
  65. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2Control.d.ts +6 -0
  66. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2Control.js +30 -0
  67. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2Description.d.ts +6 -0
  68. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2Description.js +32 -0
  69. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2HiddenInput.d.ts +2 -0
  70. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2HiddenInput.js +25 -0
  71. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2Indicator.d.ts +2 -0
  72. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2Indicator.js +23 -0
  73. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2Label.d.ts +6 -0
  74. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2Label.js +30 -0
  75. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2Root.d.ts +16 -0
  76. package/bpk-component-checkbox/src/BpkCheckboxV2/BpkCheckboxV2Root.js +49 -0
  77. package/bpk-component-checkbox/src/BpkCheckboxV2/themeAttributes.d.ts +2 -0
  78. package/bpk-component-checkbox/src/BpkCheckboxV2/themeAttributes.js +20 -0
  79. package/bpk-component-checkbox-card/index.d.ts +3 -0
  80. package/bpk-component-checkbox-card/index.js +20 -0
  81. package/bpk-component-checkbox-card/src/BpkCheckboxCard.d.ts +128 -0
  82. package/bpk-component-checkbox-card/src/BpkCheckboxCard.js +216 -0
  83. package/bpk-component-checkbox-card/src/BpkCheckboxCard.module.css +18 -0
  84. package/bpk-component-checkbox-card/src/BpkCheckboxCardRoot.d.ts +95 -0
  85. package/bpk-component-checkbox-card/src/BpkCheckboxCardRoot.js +101 -0
  86. package/bpk-component-checkbox-card/src/CheckboxCardContext.d.ts +27 -0
  87. package/bpk-component-checkbox-card/src/CheckboxCardContext.js +47 -0
  88. package/bpk-component-checkbox-card/src/common-types.d.ts +27 -0
  89. package/bpk-component-checkbox-card/src/common-types.js +43 -0
  90. package/bpk-component-checkbox-card/src/themeAttributes.d.ts +46 -0
  91. package/bpk-component-checkbox-card/src/themeAttributes.js +87 -0
  92. package/bpk-component-icon/scripts/generate-figma-connect.js +267 -0
  93. package/bpk-component-inset-banner/index.d.ts +4 -1
  94. package/bpk-component-inset-banner/index.js +2 -1
  95. package/bpk-component-inset-banner/src/BpkInsetBannerV3/BpkInsetBannerV3.d.ts +56 -0
  96. package/bpk-component-inset-banner/src/BpkInsetBannerV3/BpkInsetBannerV3.js +118 -0
  97. package/bpk-component-inset-banner/src/BpkInsetBannerV3/BpkInsetBannerV3.module.css +18 -0
  98. package/bpk-component-layout/src/BpkProvider.d.ts +9 -4
  99. package/bpk-component-layout/src/BpkProvider.js +87 -8
  100. package/bpk-component-layout/src/types.d.ts +2 -2
  101. package/bpk-component-link/src/common-types.d.ts +1 -1
  102. package/bpk-component-modal/index.d.ts +2 -1
  103. package/bpk-component-modal/index.js +2 -1
  104. package/bpk-component-modal/src/BpkModalV3/BpkModalV3.d.ts +14 -0
  105. package/bpk-component-modal/src/BpkModalV3/BpkModalV3.js +43 -0
  106. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Body/BpkModalV3Body.d.ts +7 -0
  107. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Body/BpkModalV3Body.js +30 -0
  108. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Body.module.css +18 -0
  109. package/bpk-component-modal/src/BpkModalV3/BpkModalV3CloseTrigger/BpkModalV3CloseTrigger.d.ts +7 -0
  110. package/bpk-component-modal/src/BpkModalV3/BpkModalV3CloseTrigger/BpkModalV3CloseTrigger.js +49 -0
  111. package/bpk-component-modal/src/BpkModalV3/BpkModalV3CloseTrigger.module.css +18 -0
  112. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Content/BpkModalV3Content.d.ts +7 -0
  113. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Content/BpkModalV3Content.js +38 -0
  114. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Content.module.css +18 -0
  115. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Context.d.ts +3 -0
  116. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Context.js +22 -0
  117. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Description/BpkModalV3Description.d.ts +7 -0
  118. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Description/BpkModalV3Description.js +28 -0
  119. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Header/BpkModalV3Header.d.ts +7 -0
  120. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Header/BpkModalV3Header.js +34 -0
  121. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Header.module.css +18 -0
  122. package/bpk-component-modal/src/BpkModalV3/BpkModalV3HeroImage/BpkModalV3HeroImage.d.ts +10 -0
  123. package/bpk-component-modal/src/BpkModalV3/BpkModalV3HeroImage/BpkModalV3HeroImage.js +44 -0
  124. package/bpk-component-modal/src/BpkModalV3/BpkModalV3HeroImage.module.css +18 -0
  125. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Portal/BpkModalV3Portal.d.ts +7 -0
  126. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Portal/BpkModalV3Portal.js +26 -0
  127. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Root/BpkModalV3Root.d.ts +13 -0
  128. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Root/BpkModalV3Root.js +44 -0
  129. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Scrim/BpkModalV3Scrim.d.ts +2 -0
  130. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Scrim/BpkModalV3Scrim.js +32 -0
  131. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Scrim.module.css +18 -0
  132. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Title/BpkModalV3Title.d.ts +7 -0
  133. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Title/BpkModalV3Title.js +31 -0
  134. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Title.module.css +18 -0
  135. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Trigger/BpkModalV3Trigger.d.ts +8 -0
  136. package/bpk-component-modal/src/BpkModalV3/BpkModalV3Trigger/BpkModalV3Trigger.js +30 -0
  137. package/bpk-component-modal/src/BpkModalV3/common-types.d.ts +1 -0
  138. package/bpk-component-modal/src/BpkModalV3/common-types.js +1 -0
  139. package/bpk-component-page-indicator/src/NavButton.d.ts +2 -1
  140. package/bpk-component-scrollable-calendar/src/BpkScrollableCalendarGridList.js +40 -22
  141. package/bpk-component-scrollable-calendar/src/BpkScrollableCalendarGridList.module.css +1 -1
  142. package/bpk-component-segmented-control/src/BpkSegmentedControlV2/BpkSegmentedControlV2.js +37 -16
  143. package/bpk-component-skeleton/src/BpkBaseSkeleton.d.d.ts +1 -0
  144. package/bpk-component-skeleton/src/BpkSkeleton.d.d.ts +1 -0
  145. package/bpk-component-table/index.d.ts +2 -1
  146. package/bpk-component-table/index.js +2 -1
  147. package/bpk-component-table/src/BpkTable.module.css +1 -1
  148. package/bpk-component-table/src/BpkTableBody.d.ts +4 -1
  149. package/bpk-component-table/src/BpkTableBody.js +19 -4
  150. package/bpk-component-table/src/common-types.d.ts +5 -0
  151. package/bpk-component-table/src/common-types.js +22 -0
  152. package/bpk-react-utils/src/Portal.d.ts +1 -1
  153. package/package.json +2 -2
@@ -0,0 +1,267 @@
1
+ #!/usr/bin/env node
2
+
3
+ /*
4
+ * Backpack - Skyscanner's Design System
5
+ *
6
+ * Copyright 2016 Skyscanner Ltd
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */
20
+
21
+ /**
22
+ * Generates Figma Code Connect mappings for Backpack icons.
23
+ *
24
+ * This script fetches component metadata from the Figma Icons file and
25
+ * cross-references it with the icon files in sm/ and lg/ to produce
26
+ * a single .figma.tsx file that maps every icon to its Figma component.
27
+ *
28
+ * Usage:
29
+ * FIGMA_ACCESS_TOKEN=<token> node packages/bpk-component-icon/scripts/generate-figma-connect.js
30
+ *
31
+ * The generated file is written to:
32
+ * packages/bpk-component-icon/BpkIcon.figma.tsx
33
+ */
34
+ const fs = require('fs');
35
+ const path = require('path');
36
+ const FIGMA_FILE_KEY = 'I9hynSlX2wyrlhceZr7z1u';
37
+ const FIGMA_FILE_NAME = 'Backpack-Icons';
38
+ const FIGMA_BASE_URL = `https://www.figma.com/design/${FIGMA_FILE_KEY}/${FIGMA_FILE_NAME}`;
39
+ const ICON_PKG = path.resolve(__dirname, '..');
40
+ const OUTPUT_FILE = path.join(ICON_PKG, 'BpkIcon.figma.tsx');
41
+ function kebabToPascal(str) {
42
+ return str.split(/[-]+/).map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('');
43
+ }
44
+ function getIconFiles(dir) {
45
+ if (!fs.existsSync(dir)) return new Set();
46
+ return new Set(fs.readdirSync(dir).filter(f => f.endsWith('.jsx')).map(f => f.replace('.jsx', '')));
47
+ }
48
+ async function fetchFigmaComponents() {
49
+ const token = process.env.FIGMA_ACCESS_TOKEN;
50
+ if (!token) {
51
+ console.error('Error: FIGMA_ACCESS_TOKEN environment variable is required.');
52
+ process.exit(1);
53
+ }
54
+ const url = `https://api.figma.com/v1/files/${FIGMA_FILE_KEY}/components`;
55
+ const res = await fetch(url, {
56
+ headers: {
57
+ 'X-Figma-Token': token
58
+ }
59
+ });
60
+ if (!res.ok) {
61
+ console.error(`Figma API error: ${res.status} ${res.statusText}`);
62
+ process.exit(1);
63
+ }
64
+ const data = await res.json();
65
+ return data.meta.components;
66
+ }
67
+ function groupComponentSets(components) {
68
+ const sets = {};
69
+ for (const c of components) {
70
+ const {
71
+ name
72
+ } = c.containing_frame;
73
+ const setNodeId = c.containing_frame.nodeId;
74
+ if (!sets[name]) {
75
+ sets[name] = {
76
+ nodeId: setNodeId,
77
+ variants: {},
78
+ variantProp: null
79
+ };
80
+ }
81
+
82
+ // Detect the variant property name (most use "Size", one uses "Property 1")
83
+ const match = c.name.match(/^(.+?)=(\d+)$/);
84
+ if (match) {
85
+ const [, variantProp, variantValue] = match;
86
+ sets[name].variantProp = variantProp;
87
+ sets[name].variants[variantValue] = c.node_id;
88
+ }
89
+ }
90
+ return sets;
91
+ }
92
+ function figmaUrl(nodeId) {
93
+ const encoded = nodeId.replace(/:/g, '%3A');
94
+ return `${FIGMA_BASE_URL}?node-id=${encoded}`;
95
+ }
96
+
97
+ // Spelling aliases: Figma name → code name
98
+ const SPELLING_ALIASES = {
99
+ centre: 'center'
100
+ };
101
+
102
+ /**
103
+ * Normalize a name by collapsing double-hyphens to single and applying
104
+ * spelling aliases, so we can fuzzy-match Figma names to code file names.
105
+ *
106
+ * @param {string} name - The icon name to normalize.
107
+ * @returns {string} The normalized name.
108
+ */
109
+ function normalize(name) {
110
+ const collapsed = name.replace(/--/g, '-');
111
+ return collapsed.split('-').map(part => SPELLING_ALIASES[part] || part).join('-');
112
+ }
113
+
114
+ /**
115
+ * Find the matching code file name for a Figma icon name.
116
+ * Tries exact match first, then falls back to normalized matching.
117
+ *
118
+ * @param {string} figmaName - The icon name from Figma.
119
+ * @param {Set<string>} codeIcons - Set of icon file names from code.
120
+ * @returns {string|null} The matching code file name, or null if not found.
121
+ */
122
+ function findCodeMatch(figmaName, codeIcons) {
123
+ if (codeIcons.has(figmaName)) return figmaName;
124
+ const normalizedFigma = normalize(figmaName);
125
+ for (const codeName of codeIcons) {
126
+ if (normalize(codeName) === normalizedFigma) return codeName;
127
+ }
128
+ return null;
129
+ }
130
+ function generateFile(iconSets, smIcons, lgIcons) {
131
+ const entries = [];
132
+ for (const [name, set] of Object.entries(iconSets).sort(([a], [b]) => a.localeCompare(b))) {
133
+ const smMatch = set.variants['16'] ? findCodeMatch(name, smIcons) : null;
134
+ const lgMatch = set.variants['24'] ? findCodeMatch(name, lgIcons) : null;
135
+ if (smMatch || lgMatch) {
136
+ entries.push({
137
+ name: smMatch || lgMatch,
138
+ figmaName: name,
139
+ nodeId: set.nodeId,
140
+ smFile: smMatch,
141
+ lgFile: lgMatch,
142
+ variantProp: set.variantProp || 'Size'
143
+ });
144
+ }
145
+ }
146
+ if (entries.length === 0) {
147
+ console.error('No matching icons found between Figma and code.');
148
+ process.exit(1);
149
+ }
150
+
151
+ // Build imports — interleaved and sorted alphabetically by import path
152
+ // to satisfy eslint import/order rules
153
+ const allImports = [];
154
+ for (const e of entries) {
155
+ if (e.lgFile) {
156
+ const pascal = kebabToPascal(e.lgFile);
157
+ allImports.push(`import BpkLarge${pascal}Icon from './lg/${e.lgFile}';`);
158
+ }
159
+ if (e.smFile) {
160
+ const pascal = kebabToPascal(e.smFile);
161
+ allImports.push(`import BpkSmall${pascal}Icon from './sm/${e.smFile}';`);
162
+ }
163
+ }
164
+ allImports.sort((a, b) => {
165
+ const pathA = a.match(/from '(.+)'/)[1];
166
+ const pathB = b.match(/from '(.+)'/)[1];
167
+ return pathA.localeCompare(pathB);
168
+ });
169
+
170
+ // Build connect calls
171
+ const connectCalls = [];
172
+ for (const e of entries) {
173
+ const url = figmaUrl(e.nodeId);
174
+ const prop = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e.variantProp) ? e.variantProp : JSON.stringify(e.variantProp);
175
+ if (e.smFile && e.lgFile) {
176
+ const smPascal = kebabToPascal(e.smFile);
177
+ const lgPascal = kebabToPascal(e.lgFile);
178
+ connectCalls.push(`figma.connect(
179
+ BpkSmall${smPascal}Icon,
180
+ "${url}",
181
+ {
182
+ variant: { ${prop}: "16" },
183
+ example: () => <BpkSmall${smPascal}Icon />,
184
+ },
185
+ )
186
+
187
+ figma.connect(
188
+ BpkLarge${lgPascal}Icon,
189
+ "${url}",
190
+ {
191
+ variant: { ${prop}: "24" },
192
+ example: () => <BpkLarge${lgPascal}Icon />,
193
+ },
194
+ )`);
195
+ } else if (e.smFile) {
196
+ const smPascal = kebabToPascal(e.smFile);
197
+ const variantLine = prop ? ` variant: { ${prop}: "16" },\n` : '';
198
+ connectCalls.push(`figma.connect(
199
+ BpkSmall${smPascal}Icon,
200
+ "${url}",
201
+ {
202
+ ${variantLine} example: () => <BpkSmall${smPascal}Icon />,
203
+ },
204
+ )`);
205
+ } else if (e.lgFile) {
206
+ const lgPascal = kebabToPascal(e.lgFile);
207
+ const variantLine = prop ? ` variant: { ${prop}: "24" },\n` : '';
208
+ connectCalls.push(`figma.connect(
209
+ BpkLarge${lgPascal}Icon,
210
+ "${url}",
211
+ {
212
+ ${variantLine} example: () => <BpkLarge${lgPascal}Icon />,
213
+ },
214
+ )`);
215
+ }
216
+ }
217
+ const content = `/*
218
+ * Backpack - Skyscanner's Design System
219
+ *
220
+ * Copyright 2016 Skyscanner Ltd
221
+ *
222
+ * Licensed under the Apache License, Version 2.0 (the "License");
223
+ * you may not use this file except in compliance with the License.
224
+ * You may obtain a copy of the License at
225
+ *
226
+ * http://www.apache.org/licenses/LICENSE-2.0
227
+ *
228
+ * Unless required by applicable law or agreed to in writing, software
229
+ * distributed under the License is distributed on an "AS IS" BASIS,
230
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
231
+ * See the License for the specific language governing permissions and
232
+ * limitations under the License.
233
+ */
234
+
235
+ // AUTO-GENERATED by scripts/generate-figma-connect.js — do not edit manually.
236
+
237
+ import figma from '@figma/code-connect'
238
+
239
+ ${allImports.join('\n')}
240
+
241
+ ${connectCalls.join('\n\n')}
242
+ `;
243
+ return {
244
+ content,
245
+ count: entries.length
246
+ };
247
+ }
248
+ async function main() {
249
+ console.log('Fetching icon components from Figma...');
250
+ const components = await fetchFigmaComponents();
251
+ console.log(`Found ${components.length} components in Figma.`);
252
+ const iconSets = groupComponentSets(components);
253
+ console.log(`Grouped into ${Object.keys(iconSets).length} icon sets.`);
254
+ const smIcons = getIconFiles(path.join(ICON_PKG, 'sm'));
255
+ const lgIcons = getIconFiles(path.join(ICON_PKG, 'lg'));
256
+ console.log(`Code icons: ${smIcons.size} sm, ${lgIcons.size} lg.`);
257
+ const {
258
+ content,
259
+ count
260
+ } = generateFile(iconSets, smIcons, lgIcons);
261
+ fs.writeFileSync(OUTPUT_FILE, content);
262
+ console.log(`Generated ${OUTPUT_FILE} with ${count} icon mappings.`);
263
+ }
264
+ main().catch(err => {
265
+ console.error(err);
266
+ process.exit(1);
267
+ });
@@ -2,7 +2,10 @@ import BpkInsetBanner, { type Props as BpkInsetBannerProps } from './src/BpkInse
2
2
  import BpkInsetBannerSponsored from './src/BpkInsetBannerV2/BpkInsetBannerSponsored';
3
3
  import { type CommonProps as BpkInsetBannerSponsoredProps } from './src/BpkInsetBannerV2/common-types';
4
4
  import { VARIANT } from './src/BpkInsetBannerV2/common-types';
5
+ import BpkInsetBannerV3 from './src/BpkInsetBannerV3/BpkInsetBannerV3';
6
+ import type { RootProps as BpkInsetBannerV3RootProps, HeaderProps as BpkInsetBannerV3HeaderProps, LeadingAccessoryProps as BpkInsetBannerV3LeadingAccessoryProps, ContentProps as BpkInsetBannerV3ContentProps, BodyProps as BpkInsetBannerV3BodyProps, TrailingAccessoryProps as BpkInsetBannerV3TrailingAccessoryProps } from './src/BpkInsetBannerV3/BpkInsetBannerV3';
5
7
  export type { BpkInsetBannerProps };
6
8
  export type { BpkInsetBannerSponsoredProps };
9
+ export type { BpkInsetBannerV3RootProps, BpkInsetBannerV3HeaderProps, BpkInsetBannerV3LeadingAccessoryProps, BpkInsetBannerV3ContentProps, BpkInsetBannerV3BodyProps, BpkInsetBannerV3TrailingAccessoryProps, };
7
10
  export { VARIANT };
8
- export { BpkInsetBannerSponsored, BpkInsetBanner };
11
+ export { BpkInsetBannerSponsored, BpkInsetBanner, BpkInsetBannerV3 };
@@ -19,5 +19,6 @@
19
19
  import BpkInsetBanner from "./src/BpkInsetBanner";
20
20
  import BpkInsetBannerSponsored from "./src/BpkInsetBannerV2/BpkInsetBannerSponsored";
21
21
  import { VARIANT } from "./src/BpkInsetBannerV2/common-types";
22
+ import BpkInsetBannerV3 from "./src/BpkInsetBannerV3/BpkInsetBannerV3";
22
23
  export { VARIANT };
23
- export { BpkInsetBannerSponsored, BpkInsetBanner };
24
+ export { BpkInsetBannerSponsored, BpkInsetBanner, BpkInsetBannerV3 };
@@ -0,0 +1,56 @@
1
+ import type { ComponentPropsWithoutRef, MouseEvent, ReactNode } from 'react';
2
+ export type BodyProps = {
3
+ children: ReactNode;
4
+ bleed?: boolean;
5
+ backgroundColor?: string;
6
+ };
7
+ export type RootProps = Omit<ComponentPropsWithoutRef<'div'>, 'className' | 'style' | 'children'> & {
8
+ children: ReactNode;
9
+ backgroundColor?: string;
10
+ textVariant?: 'on-light' | 'on-dark';
11
+ };
12
+ export type HeaderProps = {
13
+ children: ReactNode;
14
+ layout?: 'horizontal' | 'vertical';
15
+ };
16
+ export type LeadingAccessoryProps = {
17
+ children: ReactNode;
18
+ };
19
+ export type ContentProps = {
20
+ children: ReactNode;
21
+ };
22
+ type InteractiveTrailingAccessoryProps = Omit<ComponentPropsWithoutRef<'button'>, 'className' | 'style' | 'children' | 'type' | 'onClick'> & {
23
+ children: ReactNode;
24
+ onClick: (event: MouseEvent<HTMLButtonElement>) => void;
25
+ 'aria-label'?: string;
26
+ };
27
+ type StaticTrailingAccessoryProps = Omit<ComponentPropsWithoutRef<'div'>, 'className' | 'style' | 'children'> & {
28
+ children: ReactNode;
29
+ onClick?: never;
30
+ };
31
+ export type TrailingAccessoryProps = InteractiveTrailingAccessoryProps | StaticTrailingAccessoryProps;
32
+ declare const BpkInsetBannerV3: {
33
+ Root: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "className" | "style" | "children"> & {
34
+ children: ReactNode;
35
+ backgroundColor?: string;
36
+ textVariant?: "on-light" | "on-dark";
37
+ } & import("react").RefAttributes<HTMLDivElement>>;
38
+ Header: {
39
+ ({ children, layout }: HeaderProps): import("react/jsx-runtime").JSX.Element;
40
+ displayName: string;
41
+ };
42
+ LeadingAccessory: {
43
+ ({ children }: LeadingAccessoryProps): import("react/jsx-runtime").JSX.Element;
44
+ displayName: string;
45
+ };
46
+ Content: {
47
+ ({ children }: ContentProps): import("react/jsx-runtime").JSX.Element;
48
+ displayName: string;
49
+ };
50
+ Body: {
51
+ ({ backgroundColor, bleed, children }: BodyProps): import("react/jsx-runtime").JSX.Element;
52
+ displayName: string;
53
+ };
54
+ TrailingAccessory: import("react").ForwardRefExoticComponent<TrailingAccessoryProps & import("react").RefAttributes<HTMLDivElement | HTMLButtonElement>>;
55
+ };
56
+ export default BpkInsetBannerV3;
@@ -0,0 +1,118 @@
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 { forwardRef } from 'react';
20
+ import { cssModules, getDataComponentAttribute } from "../../../bpk-react-utils";
21
+ import STYLES from "./BpkInsetBannerV3.module.css";
22
+ import { jsx as _jsx } from "react/jsx-runtime";
23
+ const getClassName = cssModules(STYLES);
24
+ const Body = ({
25
+ backgroundColor,
26
+ bleed,
27
+ children
28
+ }) => /*#__PURE__*/_jsx("div", {
29
+ ...getDataComponentAttribute('InsetBannerV3.Body'),
30
+ className: getClassName('bpk-inset-banner-v3__body', bleed && 'bpk-inset-banner-v3__body--bleed'),
31
+ style: backgroundColor ? {
32
+ backgroundColor
33
+ } : undefined,
34
+ children: children
35
+ });
36
+ Body.displayName = 'BpkInsetBannerV3.Body';
37
+ const Root = /*#__PURE__*/forwardRef(({
38
+ backgroundColor,
39
+ children,
40
+ textVariant = 'on-light',
41
+ ...rest
42
+ }, ref) => /*#__PURE__*/_jsx("div", {
43
+ ref: ref,
44
+ ...getDataComponentAttribute('InsetBannerV3'),
45
+ ...rest,
46
+ className: getClassName('bpk-inset-banner-v3', `bpk-inset-banner-v3--${textVariant}`),
47
+ style: backgroundColor ? {
48
+ backgroundColor
49
+ } : undefined,
50
+ children: children
51
+ }));
52
+ Root.displayName = 'BpkInsetBannerV3.Root';
53
+ const Header = ({
54
+ children,
55
+ layout
56
+ }) => /*#__PURE__*/_jsx("div", {
57
+ ...getDataComponentAttribute('InsetBannerV3.Header'),
58
+ className: getClassName('bpk-inset-banner-v3__header', layout === 'horizontal' && 'bpk-inset-banner-v3__header--horizontal', layout === 'vertical' && 'bpk-inset-banner-v3__header--vertical'),
59
+ children: children
60
+ });
61
+ Header.displayName = 'BpkInsetBannerV3.Header';
62
+ const LeadingAccessory = ({
63
+ children
64
+ }) => /*#__PURE__*/_jsx("div", {
65
+ ...getDataComponentAttribute('InsetBannerV3.LeadingAccessory'),
66
+ className: getClassName('bpk-inset-banner-v3__leading-accessory'),
67
+ children: children
68
+ });
69
+ LeadingAccessory.displayName = 'BpkInsetBannerV3.LeadingAccessory';
70
+ const Content = ({
71
+ children
72
+ }) => /*#__PURE__*/_jsx("div", {
73
+ ...getDataComponentAttribute('InsetBannerV3.Content'),
74
+ className: getClassName('bpk-inset-banner-v3__content'),
75
+ children: children
76
+ });
77
+ Content.displayName = 'BpkInsetBannerV3.Content';
78
+ const TrailingAccessory = /*#__PURE__*/forwardRef((props, ref) => {
79
+ if ('onClick' in props && props.onClick) {
80
+ const {
81
+ 'aria-label': ariaLabel,
82
+ children,
83
+ onClick,
84
+ ...rest
85
+ } = props;
86
+ return /*#__PURE__*/_jsx("button", {
87
+ ref: ref,
88
+ type: "button",
89
+ "aria-label": ariaLabel,
90
+ ...rest,
91
+ ...getDataComponentAttribute('InsetBannerV3.TrailingAccessory'),
92
+ className: getClassName('bpk-inset-banner-v3__trailing-accessory', 'bpk-inset-banner-v3__trailing-accessory--interactive'),
93
+ onClick: onClick,
94
+ children: children
95
+ });
96
+ }
97
+ const {
98
+ children,
99
+ ...rest
100
+ } = props;
101
+ return /*#__PURE__*/_jsx("div", {
102
+ ref: ref,
103
+ ...rest,
104
+ ...getDataComponentAttribute('InsetBannerV3.TrailingAccessory'),
105
+ className: getClassName('bpk-inset-banner-v3__trailing-accessory'),
106
+ children: children
107
+ });
108
+ });
109
+ TrailingAccessory.displayName = 'BpkInsetBannerV3.TrailingAccessory';
110
+ const BpkInsetBannerV3 = {
111
+ Root,
112
+ Header,
113
+ LeadingAccessory,
114
+ Content,
115
+ Body,
116
+ TrailingAccessory
117
+ };
118
+ export default BpkInsetBannerV3;
@@ -0,0 +1,18 @@
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
+ .bpk-inset-banner-v3{border-radius:.5rem;overflow:hidden;container-type:inline-size}.bpk-inset-banner-v3--on-light{color:#161616;fill:#161616}.bpk-inset-banner-v3--on-dark{color:#fff;fill:#fff}.bpk-inset-banner-v3__header{display:grid;padding:.5rem 1rem;grid-template-columns:auto 1fr auto;grid-template-areas:"leading content trailing";align-items:center;gap:1rem}@container (max-width: 25rem){.bpk-inset-banner-v3__header{grid-template-columns:1fr auto;grid-template-areas:"leading trailing" "content content";gap:.25rem}.bpk-inset-banner-v3__header--horizontal{grid-template-columns:auto 1fr auto;grid-template-areas:"leading content trailing";align-items:center;gap:1rem}}.bpk-inset-banner-v3__header--vertical{grid-template-columns:1fr auto;grid-template-areas:"leading trailing" "content content";gap:.25rem}.bpk-inset-banner-v3__leading-accessory{display:flex;grid-area:leading;align-items:center}.bpk-inset-banner-v3__content{display:flex;min-width:0;grid-area:content;flex-direction:column;word-wrap:break-word}.bpk-inset-banner-v3__trailing-accessory{display:flex;grid-area:trailing;align-items:center}@container (max-width: 25rem){.bpk-inset-banner-v3__trailing-accessory{align-self:flex-start}}.bpk-inset-banner-v3__header--horizontal>.bpk-inset-banner-v3__trailing-accessory{align-self:center}.bpk-inset-banner-v3__trailing-accessory--interactive{padding:0;border:none;background:none;color:inherit;cursor:pointer;position:relative}.bpk-inset-banner-v3__trailing-accessory--interactive::before{position:absolute;top:calc(-2.75rem/2 + 50%);left:calc(-2.75rem/2 + 50%);content:"";width:2.75rem;height:2.75rem}.bpk-inset-banner-v3__trailing-accessory--interactive:focus-visible{outline:.125rem solid #0062e3;outline-offset:.125rem}.bpk-inset-banner-v3__body{padding:1rem}.bpk-inset-banner-v3__body--bleed{padding:0}
@@ -3,12 +3,17 @@ export interface BpkProviderProps {
3
3
  children: ReactNode;
4
4
  }
5
5
  /**
6
- * BpkProvider - Provides Chakra UI context for Backpack layout components
6
+ * BpkProvider - Provides context for Backpack layout and Ark-based components.
7
7
  *
8
- * Chakra UI 3.0 requires the `value` prop to be set to a system object.
9
- * We create a custom system with Backpack tokens using createSystem.
8
+ * Wraps children with:
9
+ * - Chakra UI system context (for layout components: BpkFlex, BpkGrid, etc.)
10
+ * - Ark UI LocaleProvider (for Ark-based components: BpkCheckboxV2, BpkSegmentedControlV2, etc.)
11
+ *
12
+ * RTL support: reads document direction reactively via MutationObserver and passes
13
+ * the appropriate locale to Ark's LocaleProvider. All Ark-based components in the
14
+ * tree render correctly in RTL without requiring additional wrapping or prop changes.
10
15
  *
11
16
  * @param {BpkProviderProps} props - The provider props.
12
- * @returns {JSX.Element} The provider wrapping its children with Chakra context.
17
+ * @returns {JSX.Element} The provider wrapping its children with Chakra and Ark context.
13
18
  */
14
19
  export declare const BpkProvider: ({ children }: BpkProviderProps) => JSX.Element;
@@ -16,6 +16,8 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
+ import { useEffect, useState } from 'react';
20
+ import { LocaleProvider } from '@ark-ui/react';
19
21
  import { ChakraProvider, createSystem, defaultConfig } from '@chakra-ui/react';
20
22
  import { createBpkConfig } from "./theme";
21
23
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -29,19 +31,96 @@ const {
29
31
  ...defaultConfigWithoutGlobalCss
30
32
  } = defaultConfig;
31
33
  const bpkSystem = createSystem(defaultConfigWithoutGlobalCss, createBpkConfig());
34
+ // Fallback locale mapping used when no explicit locale is available on the document.
35
+ // Maps DOM direction to minimal BCP 47 locales understood by Ark's isRTL() utility.
36
+ // 'ar-SA' is the minimal RTL locale — Ark only uses it to derive dir='rtl'.
37
+ const FALLBACK_LOCALE_BY_DIRECTION = {
38
+ ltr: 'en-US',
39
+ rtl: 'ar-SA'
40
+ };
41
+
42
+ // Known RTL language subtags (ISO 639 codes). Used as fallback when
43
+ // Intl.Locale.textInfo is unavailable (Node < 22, older browsers).
44
+ const RTL_LANGUAGE_SUBTAGS = new Set(['ar', 'he', 'fa', 'ur', 'yi', 'iw', 'ps', 'sd', 'ug', 'ku']);
45
+
46
+ // Returns the text direction implied by a BCP 47 locale string.
47
+ // Uses Intl.Locale.textInfo when available (Chrome 99+, Safari 15.4+, Firefox 126+, Node 22+);
48
+ // falls back to a known-RTL-subtag lookup.
49
+ const getLangDir = locale => {
50
+ try {
51
+ const dir = new Intl.Locale(locale).textInfo?.direction;
52
+ if (dir) return dir === 'rtl' ? 'rtl' : 'ltr';
53
+ } catch {
54
+ // Ignore invalid locale strings
55
+ }
56
+ return RTL_LANGUAGE_SUBTAGS.has(locale.split('-')[0].toLowerCase()) ? 'rtl' : 'ltr';
57
+ };
58
+
59
+ // Resolves the locale to pass to Ark's LocaleProvider.
60
+ //
61
+ // Priority rules:
62
+ // 1. If html[dir] is explicitly set:
63
+ // - Use html[lang] only when its direction is consistent with html[dir].
64
+ // - Otherwise fall back to FALLBACK_LOCALE_BY_DIRECTION[dir].
65
+ // This prevents an LTR html[lang] (e.g. 'en' from a page template) from
66
+ // overriding an explicit html[dir]="rtl" signal (e.g. from a dev RTL toggle).
67
+ // 2. If html[dir] is not set: use html[lang] if present, else 'en-US'.
68
+ //
69
+ // SSR-safe: returns 'en-US' when document is unavailable.
70
+ const getArkLocale = () => {
71
+ if (typeof document === 'undefined') return 'en-US';
72
+ const explicitDir = document.documentElement.getAttribute('dir');
73
+ const lang = document.documentElement.getAttribute('lang');
74
+ if (explicitDir === 'rtl' || explicitDir === 'ltr') {
75
+ if (lang && getLangDir(lang) === explicitDir) return lang;
76
+ return FALLBACK_LOCALE_BY_DIRECTION[explicitDir];
77
+ }
78
+ return lang || 'en-US';
79
+ };
80
+
81
+ // Reactive hook: subscribes to document.documentElement[dir] and [lang] changes
82
+ // via MutationObserver. Re-renders BpkProvider when direction or locale is toggled
83
+ // (e.g. Storybook RTL toolbar, runtime locale switcher).
84
+ // SSR-safe: always initialises to 'en-US' so server and client agree on the first render,
85
+ // avoiding hydration mismatches. The real locale is read inside useEffect,
86
+ // which does not run on the server.
87
+ const useArkLocale = () => {
88
+ const [locale, setLocale] = useState('en-US');
89
+ useEffect(() => {
90
+ setLocale(getArkLocale());
91
+ const observer = new MutationObserver(() => setLocale(getArkLocale()));
92
+ observer.observe(document.documentElement, {
93
+ attributes: true,
94
+ attributeFilter: ['dir', 'lang']
95
+ });
96
+ return () => observer.disconnect();
97
+ }, []);
98
+ return locale;
99
+ };
32
100
 
33
101
  /**
34
- * BpkProvider - Provides Chakra UI context for Backpack layout components
102
+ * BpkProvider - Provides context for Backpack layout and Ark-based components.
103
+ *
104
+ * Wraps children with:
105
+ * - Chakra UI system context (for layout components: BpkFlex, BpkGrid, etc.)
106
+ * - Ark UI LocaleProvider (for Ark-based components: BpkCheckboxV2, BpkSegmentedControlV2, etc.)
35
107
  *
36
- * Chakra UI 3.0 requires the `value` prop to be set to a system object.
37
- * We create a custom system with Backpack tokens using createSystem.
108
+ * RTL support: reads document direction reactively via MutationObserver and passes
109
+ * the appropriate locale to Ark's LocaleProvider. All Ark-based components in the
110
+ * tree render correctly in RTL without requiring additional wrapping or prop changes.
38
111
  *
39
112
  * @param {BpkProviderProps} props - The provider props.
40
- * @returns {JSX.Element} The provider wrapping its children with Chakra context.
113
+ * @returns {JSX.Element} The provider wrapping its children with Chakra and Ark context.
41
114
  */
42
115
  export const BpkProvider = ({
43
116
  children
44
- }) => /*#__PURE__*/_jsx(ChakraProvider, {
45
- value: bpkSystem,
46
- children: children
47
- });
117
+ }) => {
118
+ const locale = useArkLocale();
119
+ return /*#__PURE__*/_jsx(ChakraProvider, {
120
+ value: bpkSystem,
121
+ children: /*#__PURE__*/_jsx(LocaleProvider, {
122
+ locale: locale,
123
+ children: children
124
+ })
125
+ });
126
+ };
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from 'react';
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
2
  import type StackOptionKeys from './BpkStack.constant';
3
3
  import type { BpkCommonLayoutProps } from './commonProps';
4
4
  import type { BpkSpacingValue, BpkResponsiveValue, BpkBasisValue } from './tokens';
@@ -144,7 +144,7 @@ export type VesselElement = 'div' | 'span' | 'section' | 'article' | 'nav' | 'ma
144
144
  */
145
145
  export type BpkVesselProps = {
146
146
  as?: VesselElement;
147
- } & React.HTMLAttributes<HTMLElement>;
147
+ } & HTMLAttributes<HTMLElement>;
148
148
  /**
149
149
  * Component-specific props for BpkFlex
150
150
  * Includes all Flex props except those in BpkCommonLayoutProps
@@ -1,4 +1,4 @@
1
- import type { ComponentPropsWithoutRef, ElementType, ReactNode, Ref } from 'react';
1
+ import type { ComponentPropsWithoutRef, ElementType, JSX, ReactNode, Ref } from 'react';
2
2
  /**
3
3
  * Polymorphic component types following Chakra UI pattern.
4
4
  * Allows BpkLink to be rendered as different HTML elements while
@@ -1,9 +1,10 @@
1
1
  import BpkModal from './src/BpkModal';
2
2
  import { MODAL_STYLING } from './src/BpkModalInner';
3
3
  import { BpkModalV2 } from './src/BpkModalV2/BpkModal';
4
+ import BpkModalV3 from './src/BpkModalV3/BpkModalV3';
4
5
  import { propTypes, defaultProps } from './src/legacy-prop-types';
5
6
  import themeAttributes from './src/themeAttributes';
6
7
  import type { Props } from './src/BpkModal';
7
8
  export type BpkModalProps = Props;
8
9
  export default BpkModal;
9
- export { propTypes, defaultProps, themeAttributes, BpkModalV2, MODAL_STYLING };
10
+ export { propTypes, defaultProps, themeAttributes, BpkModalV2, BpkModalV3, MODAL_STYLING, };
@@ -19,8 +19,9 @@
19
19
  import BpkModal from "./src/BpkModal";
20
20
  import { MODAL_STYLING } from "./src/BpkModalInner";
21
21
  import { BpkModalV2 } from "./src/BpkModalV2/BpkModal";
22
+ import BpkModalV3 from "./src/BpkModalV3/BpkModalV3";
22
23
  // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
23
24
  import { propTypes, defaultProps } from "./src/legacy-prop-types";
24
25
  import themeAttributes from "./src/themeAttributes";
25
26
  export default BpkModal;
26
- export { propTypes, defaultProps, themeAttributes, BpkModalV2, MODAL_STYLING };
27
+ export { propTypes, defaultProps, themeAttributes, BpkModalV2, BpkModalV3, MODAL_STYLING };