@orangesk/orange-design-system 2.0.0-beta.16 → 2.0.0-beta.18

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 (174) hide show
  1. package/build/components/Accordion/style.css +2 -0
  2. package/build/components/Accordion/style.css.map +1 -0
  3. package/build/components/Alert/style.css +2 -0
  4. package/build/components/Alert/style.css.map +1 -0
  5. package/build/components/AnchorNavigation/style.css +2 -0
  6. package/build/components/AnchorNavigation/style.css.map +1 -0
  7. package/build/components/Bar/style.css +2 -0
  8. package/build/components/Bar/style.css.map +1 -0
  9. package/build/components/BlockAction/style.css +2 -0
  10. package/build/components/BlockAction/style.css.map +1 -0
  11. package/build/components/BodyBanner/style.css +2 -0
  12. package/build/components/BodyBanner/style.css.map +1 -0
  13. package/build/components/Breadcrumbs/style.css +2 -0
  14. package/build/components/Breadcrumbs/style.css.map +1 -0
  15. package/build/components/Button/style.css +2 -0
  16. package/build/components/Button/style.css.map +1 -0
  17. package/build/components/Buttons/style.css +2 -0
  18. package/build/components/Buttons/style.css.map +1 -0
  19. package/build/components/Card/style.css +2 -0
  20. package/build/components/Card/style.css.map +1 -0
  21. package/build/components/Carousel/style.css +2 -0
  22. package/build/components/Carousel/style.css.map +1 -0
  23. package/build/components/CarouselHero/style.css +2 -0
  24. package/build/components/CarouselHero/style.css.map +1 -0
  25. package/build/components/CarouselPromotions/style.css +2 -0
  26. package/build/components/CarouselPromotions/style.css.map +1 -0
  27. package/build/components/CartTable/style.css +2 -0
  28. package/build/components/CartTable/style.css.map +1 -0
  29. package/build/components/Code/style.css +2 -0
  30. package/build/components/Code/style.css.map +1 -0
  31. package/build/components/Container/style.css +2 -0
  32. package/build/components/Container/style.css.map +1 -0
  33. package/build/components/Controls/style.css +2 -0
  34. package/build/components/Controls/style.css.map +1 -0
  35. package/build/components/Cover/style.css +2 -0
  36. package/build/components/Cover/style.css.map +1 -0
  37. package/build/components/Divider/style.css +2 -0
  38. package/build/components/Divider/style.css.map +1 -0
  39. package/build/components/DocumentationSidebar/style.css +2 -0
  40. package/build/components/DocumentationSidebar/style.css.map +1 -0
  41. package/build/components/Dropdown/style.css +2 -0
  42. package/build/components/Dropdown/style.css.map +1 -0
  43. package/build/components/Expander/style.css +2 -0
  44. package/build/components/Expander/style.css.map +1 -0
  45. package/build/components/FeatureAccordion/style.css +2 -0
  46. package/build/components/FeatureAccordion/style.css.map +1 -0
  47. package/build/components/Footer/style.css +2 -0
  48. package/build/components/Footer/style.css.map +1 -0
  49. package/build/components/Gauge/style.css +2 -0
  50. package/build/components/Gauge/style.css.map +1 -0
  51. package/build/components/Grid/style.css +2 -0
  52. package/build/components/Grid/style.css.map +1 -0
  53. package/build/components/Hero/style.css +2 -0
  54. package/build/components/Hero/style.css.map +1 -0
  55. package/build/components/Icon/style.css +2 -0
  56. package/build/components/Icon/style.css.map +1 -0
  57. package/build/components/IconList/style.css +2 -0
  58. package/build/components/IconList/style.css.map +1 -0
  59. package/build/components/Image/style.css +2 -0
  60. package/build/components/Image/style.css.map +1 -0
  61. package/build/components/Link/style.css +2 -0
  62. package/build/components/Link/style.css.map +1 -0
  63. package/build/components/List/style.css +2 -0
  64. package/build/components/List/style.css.map +1 -0
  65. package/build/components/Loader/style.css +2 -0
  66. package/build/components/Loader/style.css.map +1 -0
  67. package/build/components/Megamenu/style.css +2 -0
  68. package/build/components/Megamenu/style.css.map +1 -0
  69. package/build/components/Modal/style.css +2 -0
  70. package/build/components/Modal/style.css.map +1 -0
  71. package/build/components/Pagination/style.css +2 -0
  72. package/build/components/Pagination/style.css.map +1 -0
  73. package/build/components/Pill/style.css +2 -0
  74. package/build/components/Pill/style.css.map +1 -0
  75. package/build/components/Preview/style.css +2 -0
  76. package/build/components/Preview/style.css.map +1 -0
  77. package/build/components/Progress/style.css +2 -0
  78. package/build/components/Progress/style.css.map +1 -0
  79. package/build/components/PromoBanner/style.css +2 -0
  80. package/build/components/PromoBanner/style.css.map +1 -0
  81. package/build/components/PromotionCard/style.css +2 -0
  82. package/build/components/PromotionCard/style.css.map +1 -0
  83. package/build/components/Section/style.css +2 -0
  84. package/build/components/Section/style.css.map +1 -0
  85. package/build/components/Skeleton/style.css +2 -0
  86. package/build/components/Skeleton/style.css.map +1 -0
  87. package/build/components/SkipLink/style.css +2 -0
  88. package/build/components/SkipLink/style.css.map +1 -0
  89. package/build/components/Stepbar/style.css +2 -0
  90. package/build/components/Stepbar/style.css.map +1 -0
  91. package/build/components/Sticker/style.css +2 -0
  92. package/build/components/Sticker/style.css.map +1 -0
  93. package/build/components/Table/style.css +2 -0
  94. package/build/components/Table/style.css.map +1 -0
  95. package/build/components/Tabs/style.css +2 -0
  96. package/build/components/Tabs/style.css.map +1 -0
  97. package/build/components/Tag/style.css +2 -0
  98. package/build/components/Tag/style.css.map +1 -0
  99. package/build/components/Testimonial/style.css +2 -0
  100. package/build/components/Testimonial/style.css.map +1 -0
  101. package/build/components/Tile/style.css +2 -0
  102. package/build/components/Tile/style.css.map +1 -0
  103. package/build/components/Tooltip/style.css +2 -0
  104. package/build/components/Tooltip/style.css.map +1 -0
  105. package/build/components/index.js +2 -2
  106. package/build/components/index.js.map +1 -1
  107. package/build/components/tsconfig.tsbuildinfo +1 -1
  108. package/build/components/types/index.d.ts +4 -2
  109. package/build/components/types/src/components/DocumentationSidebar/DocumentationSidebar.d.ts +1 -0
  110. package/build/components/types/src/components/Grid/Grid.d.ts +1 -1
  111. package/build/components/types/src/components/Link/Link.d.ts +1 -1
  112. package/build/components/types/src/components/Megamenu/Megamenu.d.ts +6 -1
  113. package/build/components/types/src/components/Megamenu/MegamenuBlog.d.ts +2 -1
  114. package/build/components/types/src/components/Megamenu/constants.d.ts +2 -0
  115. package/build/components/types/src/components/Modal/ModalProductHeader.d.ts +2 -0
  116. package/build/lib/base.css +3 -0
  117. package/build/lib/base.css.map +1 -0
  118. package/build/lib/components.css +1 -1
  119. package/build/lib/components.css.map +1 -1
  120. package/build/lib/megamenu.css +1 -1
  121. package/build/lib/megamenu.css.map +1 -1
  122. package/build/lib/megamenu.js.map +1 -1
  123. package/build/lib/style.css +1 -1
  124. package/build/lib/style.css.map +1 -1
  125. package/build/lib/tsconfig.tsbuildinfo +1 -1
  126. package/build/lib/utilities.css +2 -0
  127. package/build/lib/utilities.css.map +1 -0
  128. package/package.json +9 -7
  129. package/src/components/Code/styles/style.scss +6 -5
  130. package/src/components/DocumentationSidebar/DocumentationSidebar.tsx +188 -2
  131. package/src/components/DocumentationSidebar/styles/style.scss +73 -0
  132. package/src/components/FeatureAccordion/tests/FeatureAccordion.conformance.test.js +1 -0
  133. package/src/components/Forms/Field/tests/Autocomplete.Field.conformance.test.js +1 -1
  134. package/src/components/Forms/Field/tests/Checkbox.Field.conformance.test.js +1 -0
  135. package/src/components/Forms/Field/tests/File.Field.conformance.test.js +1 -0
  136. package/src/components/Forms/Field/tests/Group.Field.conformance.test.js +1 -0
  137. package/src/components/Forms/Field/tests/Radio.Field.conformance.test.js +1 -0
  138. package/src/components/Forms/Field/tests/Rangeslider.Field.test.js +1 -0
  139. package/src/components/Forms/Field/tests/Select.Field.conformance.test.js +1 -0
  140. package/src/components/Forms/Field/tests/Text.Field.conformance.test.js +1 -0
  141. package/src/components/Forms/Field/tests/Textarea.Field.conformance.test.js +1 -0
  142. package/src/components/Grid/Grid.tsx +1 -1
  143. package/src/components/Grid/styles/config.scss +5 -3
  144. package/src/components/Grid/styles/mixins.scss +29 -19
  145. package/src/components/Grid/tests/Grid.unit.test.js +11 -0
  146. package/src/components/Link/Link.tsx +2 -2
  147. package/src/components/Link/styles/mixins.scss +1 -1
  148. package/src/components/Link/styles/style.scss +0 -7
  149. package/src/components/Megamenu/Megamenu.tsx +81 -23
  150. package/src/components/Megamenu/MegamenuBlog.tsx +38 -21
  151. package/src/components/Megamenu/constants.ts +2 -0
  152. package/src/components/Megamenu/styles/mixins.scss +19 -1
  153. package/src/components/Megamenu/styles/style.scss +2 -0
  154. package/src/components/Modal/ModalProductHeader.tsx +6 -2
  155. package/src/components/Modal/tests/ModalProductHeader.unit.test.js +12 -0
  156. package/src/components/PromoBanner/PromoBanner.tsx +1 -1
  157. package/src/components/PromoBanner/styles/mixins.scss +5 -0
  158. package/src/components/Table/tests/Table.conformance.test.js +5 -1
  159. package/src/components/Tooltip/tests/Tooltip.conformance.test.js +5 -1
  160. package/src/styles/base/globals.scss +1 -37
  161. package/src/styles/base/styleguide.scss +1 -0
  162. package/src/styles/export/color.js +3 -3
  163. package/src/styles/tokens/color-vars.scss +39 -0
  164. package/src/styles/tokens/color.scss +4 -4
  165. package/src/styles/typography/mixins.scss +4 -5
  166. package/src/styles/utilities/text.scss +17 -0
  167. package/build/lib/after-components.css +0 -2
  168. package/build/lib/after-components.css.map +0 -1
  169. package/build/lib/before-components.css +0 -3
  170. package/build/lib/before-components.css.map +0 -1
  171. package/src/styles/after-components.scss +0 -2
  172. package/src/styles/before-components.scss +0 -18
  173. /package/build/lib/{after-components.js → base.js} +0 -0
  174. /package/build/lib/{before-components.js → utilities.js} +0 -0
@@ -4,8 +4,10 @@ import React from "react";
4
4
  import cx from "classnames";
5
5
  import { usePathname } from "next/navigation";
6
6
  import Link from "next/link";
7
+ import MiniSearch from "minisearch";
7
8
  import { Image } from "../Image";
8
9
  import { Icon } from "../Icon";
10
+ import { TextInput } from "../Forms/TextInput";
9
11
  import packageJson from "../../../package.json";
10
12
 
11
13
  export interface DocumentationSidebarItem {
@@ -13,6 +15,7 @@ export interface DocumentationSidebarItem {
13
15
  href?: string;
14
16
  target?: React.HTMLAttributeAnchorTarget;
15
17
  items?: DocumentationSidebarItem[];
18
+ content?: string; // Optional: MDX content for searching
16
19
  }
17
20
 
18
21
  export interface DocumentationSidebarProps {
@@ -26,6 +29,90 @@ export interface DocumentationSidebarProps {
26
29
 
27
30
  const CLASS_ROOT = "documentation-sidebar";
28
31
 
32
+ interface SearchResult {
33
+ id: string;
34
+ label: string;
35
+ href: string;
36
+ }
37
+
38
+ interface IndexedItem {
39
+ id: string;
40
+ label: string;
41
+ href: string;
42
+ content: string;
43
+ }
44
+
45
+ interface MiniSearchResult {
46
+ id: string;
47
+ label?: string;
48
+ href?: string;
49
+ score?: number;
50
+ }
51
+
52
+ // Flatten and index all menu items for search
53
+ const flattenMenuItems = (
54
+ items: DocumentationSidebarItem[],
55
+ indexedItems: IndexedItem[] = [],
56
+ ): IndexedItem[] => {
57
+ items.forEach((item) => {
58
+ if (item.href) {
59
+ indexedItems.push({
60
+ id: item.href,
61
+ label: item.label,
62
+ href: item.href,
63
+ content: `${item.label} ${item.content || ""}`,
64
+ });
65
+ }
66
+ if (item.items && item.items.length > 0) {
67
+ flattenMenuItems(item.items, indexedItems);
68
+ }
69
+ });
70
+ return indexedItems;
71
+ };
72
+
73
+ // Initialize MiniSearch with indexed items
74
+ const initializeSearch = (items: DocumentationSidebarItem[]) => {
75
+ const indexedItems = flattenMenuItems(items);
76
+ const miniSearch = new MiniSearch({
77
+ fields: ["label", "content"],
78
+ storeFields: ["id", "label", "href"],
79
+ });
80
+ miniSearch.addAll(indexedItems);
81
+ return miniSearch;
82
+ };
83
+
84
+ // Merge search index from MDX files with menu items
85
+ const mergeSearchIndex = (
86
+ items: DocumentationSidebarItem[],
87
+ indexData: Array<{ href: string; content: string }>,
88
+ ): DocumentationSidebarItem[] => {
89
+ const contentMap = new Map(
90
+ indexData.map((item) => [item.href, item.content]),
91
+ );
92
+
93
+ const merge = (
94
+ items: DocumentationSidebarItem[],
95
+ ): DocumentationSidebarItem[] => {
96
+ return items.map((item) => {
97
+ const mergedItem = { ...item };
98
+
99
+ // Add content from search index if available and not already set
100
+ if (item.href && !item.content && contentMap.has(item.href)) {
101
+ mergedItem.content = contentMap.get(item.href);
102
+ }
103
+
104
+ // Recursively merge child items
105
+ if (item.items) {
106
+ mergedItem.items = merge(item.items);
107
+ }
108
+
109
+ return mergedItem;
110
+ });
111
+ };
112
+
113
+ return merge(items);
114
+ };
115
+
29
116
  const SidebarItem: React.FC<{
30
117
  item: DocumentationSidebarItem;
31
118
  pathname: string;
@@ -142,12 +229,63 @@ export const DocumentationSidebar: React.FC<DocumentationSidebarProps> = (
142
229
  const { items, className, onChangeHref, children } = props;
143
230
 
144
231
  const [isMenuOpenOnMobile, setIsMenuOpenOnMobile] = React.useState(false);
232
+ const [searchQuery, setSearchQuery] = React.useState("");
233
+ const [searchResults, setSearchResults] = React.useState<SearchResult[]>([]);
234
+ const [miniSearch, setMiniSearch] = React.useState<MiniSearch | null>(null);
145
235
  const pathname = usePathname();
146
236
  const sidebarRef = React.useRef<HTMLElement>(null);
147
237
 
238
+ // Initialize search on mount
239
+ React.useEffect(() => {
240
+ const search = initializeSearch(items);
241
+ setMiniSearch(search);
242
+
243
+ // Load additional content from search index if available
244
+ const loadSearchIndex = async () => {
245
+ try {
246
+ const response = await fetch("/search-index.json");
247
+ if (!response.ok) throw new Error("Failed to fetch search index");
248
+ const indexData = await response.json();
249
+
250
+ // Re-initialize search with both menu items and indexed MDX content
251
+ const mergedItems = mergeSearchIndex(items, indexData);
252
+ const updatedSearch = initializeSearch(mergedItems);
253
+ setMiniSearch(updatedSearch);
254
+ } catch (err) {
255
+ // Search index not found or fetch failed, continue with menu items only
256
+ console.debug("Search index not available, using menu items only");
257
+ }
258
+ };
259
+
260
+ loadSearchIndex();
261
+ }, [items]);
262
+
263
+ // Handle search input
264
+ const handleSearch = (query: string) => {
265
+ setSearchQuery(query);
266
+ if (query.trim() && miniSearch) {
267
+ const results = miniSearch.search(query, {
268
+ boost: { label: 10 },
269
+ fuzzy: (term) => {
270
+ // Allow 1 character difference for short terms, more for longer terms
271
+ return term.length > 3 ? 0.2 : 0.3;
272
+ },
273
+ prefix: true, // Enable prefix matching (search "text" matches "text-secondary")
274
+ combineWith: "AND", // Require all terms to match
275
+ }) as unknown as SearchResult[];
276
+ setSearchResults(results.slice(0, 10)); // Limit to 10 results
277
+ } else {
278
+ setSearchResults([]);
279
+ }
280
+ };
281
+
148
282
  React.useEffect(() => {
149
283
  const handleEsc = (event: KeyboardEvent) => {
150
- if (event.key === "Escape") setIsMenuOpenOnMobile(false);
284
+ if (event.key === "Escape") {
285
+ setIsMenuOpenOnMobile(false);
286
+ setSearchQuery("");
287
+ setSearchResults([]);
288
+ }
151
289
  };
152
290
  document.addEventListener("keydown", handleEsc);
153
291
  return () => document.removeEventListener("keydown", handleEsc);
@@ -171,6 +309,8 @@ export const DocumentationSidebar: React.FC<DocumentationSidebarProps> = (
171
309
  const handleSelect = (href: string) => {
172
310
  onChangeHref?.(href);
173
311
  setIsMenuOpenOnMobile(false);
312
+ setSearchQuery("");
313
+ setSearchResults([]);
174
314
  };
175
315
 
176
316
  const classes = cx(CLASS_ROOT, className, {
@@ -197,7 +337,53 @@ export const DocumentationSidebar: React.FC<DocumentationSidebarProps> = (
197
337
  >
198
338
  <Image src="/logo.svg" alt="logo" />
199
339
 
200
- <nav className={`${CLASS_ROOT}__nav`}>
340
+ <div className={`${CLASS_ROOT}__search-container`}>
341
+ <TextInput
342
+ id="search-documentation"
343
+ htmlType="search"
344
+ placeholder="Search documentation..."
345
+ value={searchQuery}
346
+ onChange={(e) => handleSearch(e.currentTarget.value)}
347
+ width="fullwidth"
348
+ aria-label="Search documentation"
349
+ />
350
+ {searchQuery && (
351
+ <button
352
+ type="button"
353
+ className={`${CLASS_ROOT}__search-clear`}
354
+ onClick={() => {
355
+ setSearchQuery("");
356
+ setSearchResults([]);
357
+ }}
358
+ aria-label="Clear search"
359
+ >
360
+
361
+ </button>
362
+ )}
363
+ </div>
364
+
365
+ {searchResults.length > 0 && (
366
+ <div className={`${CLASS_ROOT}__search-results`}>
367
+ <ul className={`${CLASS_ROOT}__search-list`}>
368
+ {searchResults.map((result) => (
369
+ <li key={result.id}>
370
+ <Link
371
+ href={result.href}
372
+ className={`${CLASS_ROOT}__search-result-link`}
373
+ onClick={() => handleSelect(result.href)}
374
+ >
375
+ {result.label}
376
+ </Link>
377
+ </li>
378
+ ))}
379
+ </ul>
380
+ </div>
381
+ )}
382
+
383
+ <nav
384
+ className={`${CLASS_ROOT}__nav`}
385
+ style={{ display: searchResults.length > 0 ? "none" : "block" }}
386
+ >
201
387
  <ul className={`${CLASS_ROOT}__list`}>
202
388
  {items.map((item, index) => (
203
389
  <SidebarItem
@@ -201,6 +201,79 @@
201
201
  padding-left: convert.to-rem(15px);
202
202
  }
203
203
 
204
+ // Search styles
205
+ &__search-container {
206
+ position: relative;
207
+ margin-bottom: 16px;
208
+ }
209
+
210
+ &__search-clear {
211
+ position: absolute;
212
+ right: 8px;
213
+ top: 50%;
214
+ transform: translateY(-50%);
215
+ border: none;
216
+ background: none;
217
+ color: #999;
218
+ cursor: pointer;
219
+ padding: 4px 8px;
220
+ font-size: 1rem;
221
+ line-height: 1;
222
+
223
+ &:hover {
224
+ color: var(--color-text-default);
225
+ }
226
+
227
+ &:focus-visible {
228
+ outline: 2px solid var(--color-border-accent);
229
+ outline-offset: 2px;
230
+ }
231
+ }
232
+
233
+ &__search-results {
234
+ margin-bottom: 16px;
235
+ border: 1px solid var(--color-border-subtle);
236
+ border-radius: convert.to-rem(5px);
237
+ background: white;
238
+ max-height: 400px;
239
+ overflow-y: auto;
240
+ }
241
+
242
+ &__search-list {
243
+ list-style: none;
244
+ margin: 0;
245
+ padding: 0;
246
+
247
+ li {
248
+ margin: 0;
249
+ padding: 0;
250
+ border-bottom: 1px solid var(--color-border-subtle);
251
+
252
+ &:last-child {
253
+ border-bottom: none;
254
+ }
255
+ }
256
+ }
257
+
258
+ &__search-result-link {
259
+ display: block;
260
+ padding: 8px 12px;
261
+ color: #666;
262
+ text-decoration: none;
263
+ font-size: 0.9rem;
264
+ transition: background-color 0.2s ease;
265
+
266
+ &:hover {
267
+ background-color: var(--color-surface-subtle);
268
+ color: var(--color-text-default);
269
+ }
270
+
271
+ &:focus-visible {
272
+ outline: 2px solid var(--color-border-accent);
273
+ outline-offset: -2px;
274
+ }
275
+ }
276
+
204
277
  // Mobile behavior - below lg breakpoint (992px)
205
278
  @include breakpoint.get(lg, downfrom) {
206
279
  grid-template-columns: 1fr;
@@ -29,6 +29,7 @@ describe("FeatureAccordion conformance", () => {
29
29
  rules: {
30
30
  "attribute-boolean-style": "off",
31
31
  "prefer-native-element": "off",
32
+ "attribute-empty-style": "off",
32
33
  },
33
34
  });
34
35
  });
@@ -35,7 +35,7 @@ it("is valid html", () => {
35
35
  rules: {
36
36
  "no-inline-style": "off",
37
37
  "prefer-native-element": "off",
38
- "attribute-boolean-style": "off",
38
+ "attribute-empty-style": "off",
39
39
  },
40
40
  });
41
41
  });
@@ -33,6 +33,7 @@ it("is valid html", () => {
33
33
  rules: {
34
34
  "no-inline-style": "off",
35
35
  "attribute-boolean-style": "off",
36
+ "attribute-empty-style": "off",
36
37
  },
37
38
  });
38
39
  });
@@ -37,6 +37,7 @@ it("is valid html", () => {
37
37
  rules: {
38
38
  "no-inline-style": "off",
39
39
  "attribute-boolean-style": "off",
40
+ "attribute-empty-style": "off",
40
41
  },
41
42
  });
42
43
  });
@@ -37,6 +37,7 @@ it("is valid html", () => {
37
37
  rules: {
38
38
  "no-inline-style": "off",
39
39
  "attribute-boolean-style": "off",
40
+ "attribute-empty-style": "off",
40
41
  },
41
42
  });
42
43
  });
@@ -33,6 +33,7 @@ it("is valid html", () => {
33
33
  rules: {
34
34
  "no-inline-style": "off",
35
35
  "attribute-boolean-style": "off",
36
+ "attribute-empty-style": "off",
36
37
  },
37
38
  });
38
39
  });
@@ -50,6 +50,7 @@ it("is valid html", () => {
50
50
  rules: {
51
51
  "no-inline-style": "off",
52
52
  "attribute-boolean-style": "off",
53
+ "attribute-empty-style": "off",
53
54
  },
54
55
  });
55
56
  });
@@ -35,6 +35,7 @@ it("is valid html", () => {
35
35
  rules: {
36
36
  "no-inline-style": "off",
37
37
  "attribute-boolean-style": "off",
38
+ "attribute-empty-style": "off",
38
39
  },
39
40
  });
40
41
  });
@@ -33,6 +33,7 @@ it("is valid html", () => {
33
33
  rules: {
34
34
  "no-inline-style": "off",
35
35
  "attribute-boolean-style": "off",
36
+ "attribute-empty-style": "off",
36
37
  },
37
38
  });
38
39
  });
@@ -33,6 +33,7 @@ it("is valid html", () => {
33
33
  rules: {
34
34
  "no-inline-style": "off",
35
35
  "attribute-boolean-style": "off",
36
+ "attribute-empty-style": "off",
36
37
  },
37
38
  });
38
39
  });
@@ -9,7 +9,7 @@ export type GridRowGapSize =
9
9
  | "large"
10
10
  | "xlarge"
11
11
  | Record<string, "medium" | "large" | "xlarge">;
12
- export type GridColumnGapSize = "none";
12
+ export type GridColumnGapSize = "none" | "small" | "default" | "large";
13
13
 
14
14
  export interface GridProps extends React.HTMLAttributes<HTMLElement> {
15
15
  vAlign?: GridVAlign;
@@ -1,10 +1,12 @@
1
- @use '../../../styles/tokens/space';
1
+ @use "../../../styles/tokens/space";
2
2
 
3
3
  $grid-base: 12 !default;
4
4
 
5
- $grid-row-gap-sizes: ('medium', 'large', 'xlarge');
5
+ $grid-row-gap-sizes: ("medium", "large", "xlarge");
6
6
 
7
7
  $column-gap: (
8
- default: space.get('small'),
8
+ small: space.get("xsmall"),
9
+ default: space.get("small"),
10
+ large: space.get("medium"),
9
11
  none: 0,
10
12
  );
@@ -1,11 +1,11 @@
1
1
  @use "sass:map";
2
- @use 'sass:math';
2
+ @use "sass:math";
3
3
 
4
- @use './../../../styles/tools/generate';
5
- @use './../../../styles/tools/layout';
6
- @use './../../../styles/tokens/breakpoint';
7
- @use './../../../styles/tokens/space';
8
- @use './config';
4
+ @use "./../../../styles/tools/generate";
5
+ @use "./../../../styles/tools/layout";
6
+ @use "./../../../styles/tokens/breakpoint";
7
+ @use "./../../../styles/tokens/space";
8
+ @use "./config";
9
9
 
10
10
  @mixin grid-base() {
11
11
  display: flex;
@@ -16,18 +16,23 @@
16
16
 
17
17
  /* Fixes VoiceOver no announcing unordered lists */
18
18
  > li::before {
19
- content: ' ';
19
+ content: " ";
20
20
  position: absolute;
21
21
  width: 0;
22
22
  height: 0;
23
23
  }
24
24
  }
25
25
 
26
- @mixin grid-column-gap($size: 'default', $column-gap: config.$column-gap) {
26
+ @mixin grid-column-gap($size: "default", $column-gap: config.$column-gap) {
27
27
  $gap: map.get($column-gap, $size);
28
28
 
29
- margin-left: -$gap;
30
- margin-right: -$gap;
29
+ @if ($size == "default") {
30
+ margin-left: -$gap;
31
+ margin-right: -$gap;
32
+ } @else {
33
+ margin-left: -$gap !important;
34
+ margin-right: -$gap !important;
35
+ }
31
36
  }
32
37
 
33
38
  @mixin grid-with-equal-height-content(
@@ -53,7 +58,7 @@
53
58
  }
54
59
 
55
60
  @mixin grid-row-gap(
56
- $size: 'medium',
61
+ $size: "medium",
57
62
  $grid-col-selector: '[class*="grid__col"]'
58
63
  ) {
59
64
  margin-top: #{space.get($size) * -1};
@@ -70,11 +75,16 @@
70
75
  max-width: 100%;
71
76
  }
72
77
 
73
- @mixin grid-col-column-gap($size: 'default', $column-gap: config.$column-gap) {
78
+ @mixin grid-col-column-gap($size: "default", $column-gap: config.$column-gap) {
74
79
  $gap: map.get($column-gap, $size);
75
80
 
76
- padding-left: $gap;
77
- padding-right: $gap;
81
+ @if ($size == "default") {
82
+ padding-left: $gap;
83
+ padding-right: $gap;
84
+ } @else {
85
+ padding-left: $gap !important;
86
+ padding-right: $gap !important;
87
+ }
78
88
  }
79
89
 
80
90
  @mixin column-size($width: config.$grid-base, $grid-base: config.$grid-base) {
@@ -100,25 +110,25 @@
100
110
  }
101
111
 
102
112
  @mixin column-classes() {
103
- *[class*='grid__col'] {
113
+ *[class*="grid__col"] {
104
114
  @include grid-col-base();
105
115
  }
106
116
 
107
117
  @include breakpoint.each using ($breakpoint) {
108
- .grid__col-#{generate.variant-name($breakpoint, '-')}-shrink {
118
+ .grid__col-#{generate.variant-name($breakpoint, "-")}-shrink {
109
119
  @include column-shrink;
110
120
  }
111
121
 
112
- .grid__col-#{generate.variant-name($breakpoint, '-')}-fill {
122
+ .grid__col-#{generate.variant-name($breakpoint, "-")}-fill {
113
123
  @include column-fill;
114
124
  }
115
125
 
116
- .grid__col-#{generate.variant-name($breakpoint, '-')}-auto {
126
+ .grid__col-#{generate.variant-name($breakpoint, "-")}-auto {
117
127
  @include column-auto;
118
128
  }
119
129
 
120
130
  @for $i from 1 through config.$grid-base {
121
- .grid__col-#{generate.variant-name($breakpoint, '-')}-#{$i} {
131
+ .grid__col-#{generate.variant-name($breakpoint, "-")}-#{$i} {
122
132
  @include column-size($i);
123
133
  }
124
134
  }
@@ -62,6 +62,17 @@ describe("Grid", () => {
62
62
  });
63
63
  });
64
64
 
65
+ ["small", "large", "none"].forEach((columnGapSize) => {
66
+ it(`applies grid--column-gap-${columnGapSize} class when columnGapSize is ${columnGapSize}`, () => {
67
+ const { getByTestId } = render(
68
+ <Grid data-testid="test-id" columnGapSize={columnGapSize} />,
69
+ );
70
+ expect(getByTestId("test-id")).toHaveClass(
71
+ `grid--column-gap-${columnGapSize}`,
72
+ );
73
+ });
74
+ });
75
+
65
76
  it("merges additional className", () => {
66
77
  const { getByTestId } = render(
67
78
  <Grid data-testid="test-id" className="test-class" />,
@@ -18,7 +18,7 @@ export interface LinkProps {
18
18
  isUnderline?: boolean;
19
19
  /** whether the link should have normal font weight */
20
20
  isNormal?: boolean;
21
- /** when true, adds the .link--no-accent modifier to disable orange accent color on hover (useful for dark backgrounds) */
21
+ /** when true, adds the .no-accent modifier to disable orange accent color on hover (useful for dark backgrounds) */
22
22
  noAccent?: boolean;
23
23
  }
24
24
 
@@ -40,7 +40,7 @@ export const Link: React.FC<LinkProps & React.HTMLAttributes<HTMLElement>> = ({
40
40
  "is-light": colorScheme === "light",
41
41
  underline: isUnderline,
42
42
  normal: isNormal,
43
- "link--no-accent": noAccent,
43
+ "no-accent": noAccent,
44
44
  },
45
45
  className,
46
46
  );
@@ -4,9 +4,9 @@
4
4
  @mixin base {
5
5
  font-weight: bold;
6
6
  text-decoration: underline;
7
+ text-underline-offset: 0.1em;
7
8
  color: inherit;
8
9
  background: none;
9
- text-decoration: none;
10
10
  cursor: pointer;
11
11
  }
12
12
 
@@ -44,10 +44,3 @@
44
44
  @include mixins.icon-right;
45
45
  }
46
46
  }
47
-
48
- @layer utilities {
49
- .link--no-accent:hover {
50
- color: inherit !important;
51
- text-decoration: underline;
52
- }
53
- }