@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.
- package/build/components/Accordion/style.css +2 -0
- package/build/components/Accordion/style.css.map +1 -0
- package/build/components/Alert/style.css +2 -0
- package/build/components/Alert/style.css.map +1 -0
- package/build/components/AnchorNavigation/style.css +2 -0
- package/build/components/AnchorNavigation/style.css.map +1 -0
- package/build/components/Bar/style.css +2 -0
- package/build/components/Bar/style.css.map +1 -0
- package/build/components/BlockAction/style.css +2 -0
- package/build/components/BlockAction/style.css.map +1 -0
- package/build/components/BodyBanner/style.css +2 -0
- package/build/components/BodyBanner/style.css.map +1 -0
- package/build/components/Breadcrumbs/style.css +2 -0
- package/build/components/Breadcrumbs/style.css.map +1 -0
- package/build/components/Button/style.css +2 -0
- package/build/components/Button/style.css.map +1 -0
- package/build/components/Buttons/style.css +2 -0
- package/build/components/Buttons/style.css.map +1 -0
- package/build/components/Card/style.css +2 -0
- package/build/components/Card/style.css.map +1 -0
- package/build/components/Carousel/style.css +2 -0
- package/build/components/Carousel/style.css.map +1 -0
- package/build/components/CarouselHero/style.css +2 -0
- package/build/components/CarouselHero/style.css.map +1 -0
- package/build/components/CarouselPromotions/style.css +2 -0
- package/build/components/CarouselPromotions/style.css.map +1 -0
- package/build/components/CartTable/style.css +2 -0
- package/build/components/CartTable/style.css.map +1 -0
- package/build/components/Code/style.css +2 -0
- package/build/components/Code/style.css.map +1 -0
- package/build/components/Container/style.css +2 -0
- package/build/components/Container/style.css.map +1 -0
- package/build/components/Controls/style.css +2 -0
- package/build/components/Controls/style.css.map +1 -0
- package/build/components/Cover/style.css +2 -0
- package/build/components/Cover/style.css.map +1 -0
- package/build/components/Divider/style.css +2 -0
- package/build/components/Divider/style.css.map +1 -0
- package/build/components/DocumentationSidebar/style.css +2 -0
- package/build/components/DocumentationSidebar/style.css.map +1 -0
- package/build/components/Dropdown/style.css +2 -0
- package/build/components/Dropdown/style.css.map +1 -0
- package/build/components/Expander/style.css +2 -0
- package/build/components/Expander/style.css.map +1 -0
- package/build/components/FeatureAccordion/style.css +2 -0
- package/build/components/FeatureAccordion/style.css.map +1 -0
- package/build/components/Footer/style.css +2 -0
- package/build/components/Footer/style.css.map +1 -0
- package/build/components/Gauge/style.css +2 -0
- package/build/components/Gauge/style.css.map +1 -0
- package/build/components/Grid/style.css +2 -0
- package/build/components/Grid/style.css.map +1 -0
- package/build/components/Hero/style.css +2 -0
- package/build/components/Hero/style.css.map +1 -0
- package/build/components/Icon/style.css +2 -0
- package/build/components/Icon/style.css.map +1 -0
- package/build/components/IconList/style.css +2 -0
- package/build/components/IconList/style.css.map +1 -0
- package/build/components/Image/style.css +2 -0
- package/build/components/Image/style.css.map +1 -0
- package/build/components/Link/style.css +2 -0
- package/build/components/Link/style.css.map +1 -0
- package/build/components/List/style.css +2 -0
- package/build/components/List/style.css.map +1 -0
- package/build/components/Loader/style.css +2 -0
- package/build/components/Loader/style.css.map +1 -0
- package/build/components/Megamenu/style.css +2 -0
- package/build/components/Megamenu/style.css.map +1 -0
- package/build/components/Modal/style.css +2 -0
- package/build/components/Modal/style.css.map +1 -0
- package/build/components/Pagination/style.css +2 -0
- package/build/components/Pagination/style.css.map +1 -0
- package/build/components/Pill/style.css +2 -0
- package/build/components/Pill/style.css.map +1 -0
- package/build/components/Preview/style.css +2 -0
- package/build/components/Preview/style.css.map +1 -0
- package/build/components/Progress/style.css +2 -0
- package/build/components/Progress/style.css.map +1 -0
- package/build/components/PromoBanner/style.css +2 -0
- package/build/components/PromoBanner/style.css.map +1 -0
- package/build/components/PromotionCard/style.css +2 -0
- package/build/components/PromotionCard/style.css.map +1 -0
- package/build/components/Section/style.css +2 -0
- package/build/components/Section/style.css.map +1 -0
- package/build/components/Skeleton/style.css +2 -0
- package/build/components/Skeleton/style.css.map +1 -0
- package/build/components/SkipLink/style.css +2 -0
- package/build/components/SkipLink/style.css.map +1 -0
- package/build/components/Stepbar/style.css +2 -0
- package/build/components/Stepbar/style.css.map +1 -0
- package/build/components/Sticker/style.css +2 -0
- package/build/components/Sticker/style.css.map +1 -0
- package/build/components/Table/style.css +2 -0
- package/build/components/Table/style.css.map +1 -0
- package/build/components/Tabs/style.css +2 -0
- package/build/components/Tabs/style.css.map +1 -0
- package/build/components/Tag/style.css +2 -0
- package/build/components/Tag/style.css.map +1 -0
- package/build/components/Testimonial/style.css +2 -0
- package/build/components/Testimonial/style.css.map +1 -0
- package/build/components/Tile/style.css +2 -0
- package/build/components/Tile/style.css.map +1 -0
- package/build/components/Tooltip/style.css +2 -0
- package/build/components/Tooltip/style.css.map +1 -0
- package/build/components/index.js +2 -2
- package/build/components/index.js.map +1 -1
- package/build/components/tsconfig.tsbuildinfo +1 -1
- package/build/components/types/index.d.ts +4 -2
- package/build/components/types/src/components/DocumentationSidebar/DocumentationSidebar.d.ts +1 -0
- package/build/components/types/src/components/Grid/Grid.d.ts +1 -1
- package/build/components/types/src/components/Link/Link.d.ts +1 -1
- package/build/components/types/src/components/Megamenu/Megamenu.d.ts +6 -1
- package/build/components/types/src/components/Megamenu/MegamenuBlog.d.ts +2 -1
- package/build/components/types/src/components/Megamenu/constants.d.ts +2 -0
- package/build/components/types/src/components/Modal/ModalProductHeader.d.ts +2 -0
- package/build/lib/base.css +3 -0
- package/build/lib/base.css.map +1 -0
- package/build/lib/components.css +1 -1
- package/build/lib/components.css.map +1 -1
- package/build/lib/megamenu.css +1 -1
- package/build/lib/megamenu.css.map +1 -1
- package/build/lib/megamenu.js.map +1 -1
- package/build/lib/style.css +1 -1
- package/build/lib/style.css.map +1 -1
- package/build/lib/tsconfig.tsbuildinfo +1 -1
- package/build/lib/utilities.css +2 -0
- package/build/lib/utilities.css.map +1 -0
- package/package.json +9 -7
- package/src/components/Code/styles/style.scss +6 -5
- package/src/components/DocumentationSidebar/DocumentationSidebar.tsx +188 -2
- package/src/components/DocumentationSidebar/styles/style.scss +73 -0
- package/src/components/FeatureAccordion/tests/FeatureAccordion.conformance.test.js +1 -0
- package/src/components/Forms/Field/tests/Autocomplete.Field.conformance.test.js +1 -1
- package/src/components/Forms/Field/tests/Checkbox.Field.conformance.test.js +1 -0
- package/src/components/Forms/Field/tests/File.Field.conformance.test.js +1 -0
- package/src/components/Forms/Field/tests/Group.Field.conformance.test.js +1 -0
- package/src/components/Forms/Field/tests/Radio.Field.conformance.test.js +1 -0
- package/src/components/Forms/Field/tests/Rangeslider.Field.test.js +1 -0
- package/src/components/Forms/Field/tests/Select.Field.conformance.test.js +1 -0
- package/src/components/Forms/Field/tests/Text.Field.conformance.test.js +1 -0
- package/src/components/Forms/Field/tests/Textarea.Field.conformance.test.js +1 -0
- package/src/components/Grid/Grid.tsx +1 -1
- package/src/components/Grid/styles/config.scss +5 -3
- package/src/components/Grid/styles/mixins.scss +29 -19
- package/src/components/Grid/tests/Grid.unit.test.js +11 -0
- package/src/components/Link/Link.tsx +2 -2
- package/src/components/Link/styles/mixins.scss +1 -1
- package/src/components/Link/styles/style.scss +0 -7
- package/src/components/Megamenu/Megamenu.tsx +81 -23
- package/src/components/Megamenu/MegamenuBlog.tsx +38 -21
- package/src/components/Megamenu/constants.ts +2 -0
- package/src/components/Megamenu/styles/mixins.scss +19 -1
- package/src/components/Megamenu/styles/style.scss +2 -0
- package/src/components/Modal/ModalProductHeader.tsx +6 -2
- package/src/components/Modal/tests/ModalProductHeader.unit.test.js +12 -0
- package/src/components/PromoBanner/PromoBanner.tsx +1 -1
- package/src/components/PromoBanner/styles/mixins.scss +5 -0
- package/src/components/Table/tests/Table.conformance.test.js +5 -1
- package/src/components/Tooltip/tests/Tooltip.conformance.test.js +5 -1
- package/src/styles/base/globals.scss +1 -37
- package/src/styles/base/styleguide.scss +1 -0
- package/src/styles/export/color.js +3 -3
- package/src/styles/tokens/color-vars.scss +39 -0
- package/src/styles/tokens/color.scss +4 -4
- package/src/styles/typography/mixins.scss +4 -5
- package/src/styles/utilities/text.scss +17 -0
- package/build/lib/after-components.css +0 -2
- package/build/lib/after-components.css.map +0 -1
- package/build/lib/before-components.css +0 -3
- package/build/lib/before-components.css.map +0 -1
- package/src/styles/after-components.scss +0 -2
- package/src/styles/before-components.scss +0 -18
- /package/build/lib/{after-components.js → base.js} +0 -0
- /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")
|
|
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
|
-
<
|
|
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;
|
|
@@ -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
|
|
1
|
+
@use "../../../styles/tokens/space";
|
|
2
2
|
|
|
3
3
|
$grid-base: 12 !default;
|
|
4
4
|
|
|
5
|
-
$grid-row-gap-sizes: (
|
|
5
|
+
$grid-row-gap-sizes: ("medium", "large", "xlarge");
|
|
6
6
|
|
|
7
7
|
$column-gap: (
|
|
8
|
-
|
|
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
|
|
2
|
+
@use "sass:math";
|
|
3
3
|
|
|
4
|
-
@use
|
|
5
|
-
@use
|
|
6
|
-
@use
|
|
7
|
-
@use
|
|
8
|
-
@use
|
|
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:
|
|
26
|
+
@mixin grid-column-gap($size: "default", $column-gap: config.$column-gap) {
|
|
27
27
|
$gap: map.get($column-gap, $size);
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
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:
|
|
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:
|
|
78
|
+
@mixin grid-col-column-gap($size: "default", $column-gap: config.$column-gap) {
|
|
74
79
|
$gap: map.get($column-gap, $size);
|
|
75
80
|
|
|
76
|
-
|
|
77
|
-
|
|
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*=
|
|
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,
|
|
118
|
+
.grid__col-#{generate.variant-name($breakpoint, "-")}-shrink {
|
|
109
119
|
@include column-shrink;
|
|
110
120
|
}
|
|
111
121
|
|
|
112
|
-
.grid__col-#{generate.variant-name($breakpoint,
|
|
122
|
+
.grid__col-#{generate.variant-name($breakpoint, "-")}-fill {
|
|
113
123
|
@include column-fill;
|
|
114
124
|
}
|
|
115
125
|
|
|
116
|
-
.grid__col-#{generate.variant-name($breakpoint,
|
|
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,
|
|
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 .
|
|
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
|
-
"
|
|
43
|
+
"no-accent": noAccent,
|
|
44
44
|
},
|
|
45
45
|
className,
|
|
46
46
|
);
|