@hellboy/ds 0.1.2 → 0.2.7
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/README.md +568 -71
- package/{src/style/components/badge → dist/components}/badge.css +9 -25
- package/dist/components/badge.d.mts +12 -0
- package/dist/components/badge.d.ts +12 -0
- package/dist/components/badge.js +42 -0
- package/dist/components/badge.mjs +15 -0
- package/dist/components/banner.css +280 -0
- package/dist/components/banner.d.mts +12 -0
- package/dist/components/banner.d.ts +12 -0
- package/dist/components/banner.js +184 -0
- package/dist/components/banner.mjs +147 -0
- package/dist/components/button-group.css +289 -0
- package/dist/components/button-group.d.mts +81 -0
- package/dist/components/button-group.d.ts +81 -0
- package/dist/components/button-group.js +180 -0
- package/dist/components/button-group.mjs +143 -0
- package/{src/style/components/button → dist/components}/button.css +59 -62
- package/dist/components/button.d.mts +57 -0
- package/dist/components/button.d.ts +57 -0
- package/dist/components/button.js +129 -0
- package/dist/components/button.mjs +92 -0
- package/{src/style/components/card → dist/components}/card.css +9 -30
- package/dist/components/card.d.mts +31 -0
- package/dist/components/card.d.ts +31 -0
- package/dist/components/card.js +59 -0
- package/dist/components/card.mjs +32 -0
- package/{src/style → dist}/components/checkbox.css +51 -43
- package/dist/components/checkbox.d.mts +31 -0
- package/dist/components/checkbox.d.ts +31 -0
- package/dist/components/checkbox.js +130 -0
- package/dist/components/checkbox.mjs +93 -0
- package/{src/style/components/code-block → dist/components}/code-block.css +3 -7
- package/dist/components/code-block.d.mts +24 -0
- package/dist/components/code-block.d.ts +24 -0
- package/dist/components/code-block.js +43 -0
- package/dist/components/code-block.mjs +16 -0
- package/dist/components/color-control.css +285 -0
- package/dist/components/color-control.d.mts +5 -0
- package/dist/components/color-control.d.ts +5 -0
- package/dist/components/color-control.js +534 -0
- package/dist/components/color-control.mjs +497 -0
- package/dist/components/dialog.css +930 -0
- package/dist/components/dialog.d.mts +32 -0
- package/dist/components/dialog.d.ts +32 -0
- package/dist/components/dialog.js +1111 -0
- package/dist/components/dialog.mjs +1074 -0
- package/dist/components/divider.css +356 -0
- package/dist/components/divider.d.mts +32 -0
- package/dist/components/divider.d.ts +32 -0
- package/dist/components/divider.js +344 -0
- package/dist/components/divider.mjs +307 -0
- package/{src/style/components/drag-handle → dist/components}/drag-handle.css +3 -18
- package/dist/components/drag-handle.d.mts +11 -0
- package/dist/components/drag-handle.d.ts +11 -0
- package/dist/components/drag-handle.js +103 -0
- package/dist/components/drag-handle.mjs +66 -0
- package/dist/components/drawer.css +1027 -0
- package/dist/components/drawer.d.mts +14 -0
- package/dist/components/drawer.d.ts +14 -0
- package/dist/components/drawer.js +1072 -0
- package/dist/components/drawer.mjs +1035 -0
- package/dist/components/floating-bar.css +17 -0
- package/dist/components/floating-bar.d.mts +25 -0
- package/dist/components/floating-bar.d.ts +25 -0
- package/dist/components/floating-bar.js +52 -0
- package/dist/components/floating-bar.mjs +25 -0
- package/dist/components/footer.css +40 -0
- package/dist/components/footer.d.mts +8 -0
- package/dist/components/footer.d.ts +8 -0
- package/dist/components/footer.js +44 -0
- package/dist/components/footer.mjs +17 -0
- package/dist/components/grid.css +47 -0
- package/dist/components/grid.d.mts +27 -0
- package/dist/components/grid.d.ts +27 -0
- package/dist/components/grid.js +52 -0
- package/dist/components/grid.mjs +25 -0
- package/dist/components/header.css +1075 -0
- package/dist/components/header.d.mts +35 -0
- package/dist/components/header.d.ts +35 -0
- package/dist/components/header.js +1402 -0
- package/dist/components/header.mjs +1365 -0
- package/dist/components/hero.css +121 -0
- package/dist/components/hero.d.mts +111 -0
- package/dist/components/hero.d.ts +111 -0
- package/dist/components/hero.js +285 -0
- package/dist/components/hero.mjs +248 -0
- package/{src/style/components/icons → dist/components}/icons.css +14 -15
- package/dist/components/icons.d.mts +104 -0
- package/dist/components/icons.d.ts +104 -0
- package/dist/components/icons.js +239 -0
- package/dist/components/icons.mjs +203 -0
- package/{src/style/components/input → dist/components}/input.css +189 -102
- package/dist/components/input.d.mts +114 -0
- package/dist/components/input.d.ts +114 -0
- package/dist/components/input.js +926 -0
- package/dist/components/input.mjs +879 -0
- package/dist/components/layout.css +551 -0
- package/dist/components/layout.d.mts +16 -0
- package/dist/components/layout.d.ts +16 -0
- package/dist/components/layout.js +387 -0
- package/dist/components/layout.mjs +352 -0
- package/{src/style/components/list → dist/components}/list.css +47 -41
- package/dist/components/list.d.mts +46 -0
- package/dist/components/list.d.ts +46 -0
- package/dist/components/list.js +124 -0
- package/dist/components/list.mjs +96 -0
- package/dist/components/navbar.css +706 -0
- package/dist/components/navbar.d.mts +56 -0
- package/dist/components/navbar.d.ts +56 -0
- package/dist/components/navbar.js +994 -0
- package/dist/components/navbar.mjs +952 -0
- package/{src/style/components/page-index → dist/components}/page-index.css +2 -47
- package/dist/components/page-index.d.mts +25 -0
- package/dist/components/page-index.d.ts +25 -0
- package/dist/components/page-index.js +239 -0
- package/dist/components/page-index.mjs +202 -0
- package/{src/style/components/page → dist/components}/page.css +4 -15
- package/dist/components/page.d.mts +30 -0
- package/dist/components/page.d.ts +30 -0
- package/dist/components/page.js +40 -0
- package/dist/components/page.mjs +13 -0
- package/dist/components/popover.css +87 -0
- package/dist/components/popover.d.mts +22 -0
- package/dist/components/popover.d.ts +22 -0
- package/dist/components/popover.js +243 -0
- package/dist/components/popover.mjs +206 -0
- package/{src/style → dist}/components/radio.css +8 -51
- package/dist/components/radio.d.mts +59 -0
- package/dist/components/radio.d.ts +59 -0
- package/dist/components/radio.js +133 -0
- package/dist/components/radio.mjs +95 -0
- package/dist/components/section.css +993 -0
- package/dist/components/section.d.mts +33 -0
- package/dist/components/section.d.ts +33 -0
- package/dist/components/section.js +1401 -0
- package/dist/components/section.mjs +1364 -0
- package/dist/components/select.css +391 -0
- package/dist/components/select.d.mts +63 -0
- package/dist/components/select.d.ts +63 -0
- package/dist/components/select.js +452 -0
- package/dist/components/select.mjs +415 -0
- package/{src/style/components/slider → dist/components}/slider.css +55 -33
- package/dist/components/slider.d.mts +69 -0
- package/dist/components/slider.d.ts +69 -0
- package/dist/components/slider.js +254 -0
- package/dist/components/slider.mjs +217 -0
- package/dist/components/switch.css +1081 -0
- package/dist/components/switch.d.mts +33 -0
- package/dist/components/switch.d.ts +33 -0
- package/dist/components/switch.js +1092 -0
- package/dist/components/switch.mjs +1055 -0
- package/{src/style/components/table → dist/components}/table.css +3 -28
- package/dist/components/table.d.mts +42 -0
- package/dist/components/table.d.ts +42 -0
- package/dist/components/table.js +108 -0
- package/dist/components/table.mjs +76 -0
- package/dist/components/tag.css +97 -0
- package/dist/components/tag.d.mts +12 -0
- package/dist/components/tag.d.ts +12 -0
- package/dist/components/tag.js +42 -0
- package/dist/components/tag.mjs +15 -0
- package/dist/components/textarea.css +1359 -0
- package/dist/components/textarea.d.mts +84 -0
- package/dist/components/textarea.d.ts +84 -0
- package/dist/components/textarea.js +1962 -0
- package/dist/components/textarea.mjs +1924 -0
- package/{src/style/components/theme-control → dist/components}/theme-control.css +3 -7
- package/dist/components/theme-control.d.mts +9 -0
- package/dist/components/theme-control.d.ts +9 -0
- package/dist/components/theme-control.js +235 -0
- package/dist/components/theme-control.mjs +200 -0
- package/{src/style/components/tooltip → dist/components}/tooltip.css +5 -13
- package/dist/components/tooltip.d.mts +12 -0
- package/dist/components/tooltip.d.ts +12 -0
- package/dist/components/tooltip.js +200 -0
- package/dist/components/tooltip.mjs +163 -0
- package/dist/icons-Czahnf-r.d.mts +15 -0
- package/dist/icons-Czahnf-r.d.ts +15 -0
- package/dist/index.css +2915 -2068
- package/dist/index.d.mts +144 -721
- package/dist/index.d.ts +144 -721
- package/dist/index.js +4076 -2282
- package/dist/index.mjs +4132 -2366
- package/dist/theme.css +34 -34
- package/package.json +27 -8
- package/dist/index.css.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/hellboy-ds-0.1.2.tgz +0 -0
- package/src/components/badge/Badge.tsx +0 -29
- package/src/components/badge/index.ts +0 -1
- package/src/components/banner/Banner.tsx +0 -48
- package/src/components/banner/banner.css +0 -44
- package/src/components/banner/index.ts +0 -1
- package/src/components/button/button.tsx +0 -127
- package/src/components/button/index.ts +0 -1
- package/src/components/card/card.tsx +0 -57
- package/src/components/card/index.ts +0 -1
- package/src/components/checkbox/Checkbox.tsx +0 -98
- package/src/components/checkbox/index.ts +0 -1
- package/src/components/code-block/code-block.tsx +0 -44
- package/src/components/code-block/index.ts +0 -1
- package/src/components/color-control/color-control.tsx +0 -322
- package/src/components/color-control/index.ts +0 -1
- package/src/components/drag-handle/DragHandle.tsx +0 -78
- package/src/components/drag-handle/index.ts +0 -1
- package/src/components/drawer/drawer.tsx +0 -82
- package/src/components/drawer/index.ts +0 -1
- package/src/components/floating-bar/floating-bar.tsx +0 -52
- package/src/components/floating-bar/index.ts +0 -2
- package/src/components/footer/footer.tsx +0 -28
- package/src/components/footer/index.ts +0 -1
- package/src/components/grid/Grid.tsx +0 -53
- package/src/components/grid/index.ts +0 -1
- package/src/components/header/header.tsx +0 -57
- package/src/components/header/index.ts +0 -1
- package/src/components/icons/icons.tsx +0 -44
- package/src/components/icons/index.ts +0 -1
- package/src/components/index.ts +0 -29
- package/src/components/input/DatePicker.tsx +0 -133
- package/src/components/input/Input.tsx +0 -220
- package/src/components/input/InputDate.tsx +0 -10
- package/src/components/input/InputDateTime.tsx +0 -10
- package/src/components/input/InputEmail.tsx +0 -10
- package/src/components/input/InputField.tsx +0 -137
- package/src/components/input/InputNumber.tsx +0 -10
- package/src/components/input/InputPassword.tsx +0 -10
- package/src/components/input/InputSearch.tsx +0 -10
- package/src/components/input/InputTel.tsx +0 -10
- package/src/components/input/InputText.tsx +0 -10
- package/src/components/input/InputTime.tsx +0 -10
- package/src/components/input/InputUrl.tsx +0 -10
- package/src/components/input/TimePicker.tsx +0 -151
- package/src/components/input/index.ts +0 -11
- package/src/components/layout/Layout.tsx +0 -244
- package/src/components/layout/index.ts +0 -1
- package/src/components/list/List.tsx +0 -159
- package/src/components/list/index.ts +0 -1
- package/src/components/navbar/MenuCategory.tsx +0 -20
- package/src/components/navbar/MenuGroup.tsx +0 -288
- package/src/components/navbar/MenuItem.tsx +0 -65
- package/src/components/navbar/Navbar.tsx +0 -23
- package/src/components/navbar/index.ts +0 -4
- package/src/components/page/index.ts +0 -1
- package/src/components/page/page.tsx +0 -46
- package/src/components/page-index/PageIndex.tsx +0 -275
- package/src/components/page-index/index.ts +0 -1
- package/src/components/popover/index.ts +0 -1
- package/src/components/popover/popover.tsx +0 -199
- package/src/components/radio/Radio.tsx +0 -176
- package/src/components/radio/index.ts +0 -1
- package/src/components/section/index.ts +0 -1
- package/src/components/section/section.tsx +0 -66
- package/src/components/select/Select.tsx +0 -212
- package/src/components/select/index.ts +0 -1
- package/src/components/slider/Slider.tsx +0 -267
- package/src/components/slider/index.ts +0 -1
- package/src/components/switch/index.ts +0 -1
- package/src/components/switch/switch.tsx +0 -99
- package/src/components/table/Table.tsx +0 -147
- package/src/components/table/index.ts +0 -1
- package/src/components/theme-control/index.ts +0 -1
- package/src/components/theme-control/theme-control.tsx +0 -78
- package/src/components/tooltip/index.ts +0 -1
- package/src/components/tooltip/tooltip.tsx +0 -207
- package/src/contexts/NavbarTooltipContext.tsx +0 -48
- package/src/contexts/index.ts +0 -1
- package/src/foundations/motion.md +0 -136
- package/src/index.ts +0 -40
- package/src/style/_shared/field.css +0 -69
- package/src/style/components/color-control/color-control.css +0 -126
- package/src/style/components/drawer/drawer.css +0 -210
- package/src/style/components/floating-bar/floating-bar.css +0 -39
- package/src/style/components/footer/footer.css +0 -108
- package/src/style/components/grid/grid.css +0 -33
- package/src/style/components/header/header.css +0 -44
- package/src/style/components/layout/layout.css +0 -205
- package/src/style/components/navbar/navbar.css +0 -342
- package/src/style/components/popover/popover.css +0 -44
- package/src/style/components/section/section.css +0 -67
- package/src/style/components/select/select.css +0 -143
- package/src/style/components/switch/switch.css +0 -267
- package/src/style/foundations/global.css +0 -316
- package/src/style/foundations/motion.css +0 -164
- package/src/style/foundations/spacing.css +0 -51
- package/src/style/foundations/typography.css +0 -39
- package/src/style/foundations/z-index.css +0 -81
- package/src/style/modes/dark.css +0 -146
- package/src/style/modes/light.css +0 -147
- package/src/style/semantic.css +0 -52
- package/src/style/styles.css +0 -51
- package/src/style/themes/theme.json +0 -37
- package/src/utils/README.md +0 -305
- package/src/utils/USER_PREFERENCES.md +0 -558
- package/src/utils/theme.ts +0 -127
- package/src/utils/user-preferences.ts +0 -577
- package/tsconfig.json +0 -25
- package/tsup.config.ts +0 -52
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import "../../style/components/page-index/page-index.css";
|
|
3
|
-
|
|
4
|
-
export interface PageIndexItem {
|
|
5
|
-
id: string;
|
|
6
|
-
title: string;
|
|
7
|
-
level: number;
|
|
8
|
-
element: HTMLElement;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface PageIndexProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
12
|
-
/**
|
|
13
|
-
* Custom title for the index
|
|
14
|
-
*/
|
|
15
|
-
title?: string;
|
|
16
|
-
/**
|
|
17
|
-
* Whether the sidebar is collapsed
|
|
18
|
-
*/
|
|
19
|
-
collapsed?: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const PageIndex: React.FC<PageIndexProps> = ({
|
|
23
|
-
title = "On this page",
|
|
24
|
-
collapsed = false,
|
|
25
|
-
className = "",
|
|
26
|
-
...props
|
|
27
|
-
}) => {
|
|
28
|
-
const [items, setItems] = React.useState<PageIndexItem[]>([]);
|
|
29
|
-
const [activeId, setActiveId] = React.useState<string>("");
|
|
30
|
-
const [manualNavigation, setManualNavigation] = React.useState<boolean>(false);
|
|
31
|
-
|
|
32
|
-
// Function to extract text content from element
|
|
33
|
-
const getTextContent = React.useCallback((element: HTMLElement): string => {
|
|
34
|
-
// For headings, get text content
|
|
35
|
-
if (element.tagName.match(/^H[1-6]$/)) {
|
|
36
|
-
return element.textContent || "";
|
|
37
|
-
}
|
|
38
|
-
// For other elements, try to find a title attribute or data attribute
|
|
39
|
-
return element.getAttribute("data-page-index-title") ||
|
|
40
|
-
element.getAttribute("title") ||
|
|
41
|
-
element.textContent ||
|
|
42
|
-
"";
|
|
43
|
-
}, []);
|
|
44
|
-
|
|
45
|
-
// Function to generate ID from text
|
|
46
|
-
const generateId = React.useCallback((text: string): string => {
|
|
47
|
-
return text
|
|
48
|
-
.toLowerCase()
|
|
49
|
-
.replace(/[^\w\s-]/g, "") // Remove special characters
|
|
50
|
-
.replace(/\s+/g, "-") // Replace spaces with hyphens
|
|
51
|
-
.replace(/-+/g, "-") // Replace multiple hyphens with single
|
|
52
|
-
.trim();
|
|
53
|
-
}, []);
|
|
54
|
-
|
|
55
|
-
// Scan the page for headings that are direct children of sections within pages
|
|
56
|
-
const scanPage = React.useCallback(() => {
|
|
57
|
-
const newItems: PageIndexItem[] = [];
|
|
58
|
-
const seenIds = new Set<string>(); // Track seen IDs to prevent duplicates
|
|
59
|
-
|
|
60
|
-
// Find all pages (main elements) and their sections
|
|
61
|
-
const pages = document.querySelectorAll('main');
|
|
62
|
-
pages.forEach((page) => {
|
|
63
|
-
const pageElement = page as HTMLElement;
|
|
64
|
-
|
|
65
|
-
// Skip pages that are inside the page-index component
|
|
66
|
-
if (pageElement.closest('.page-index')) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Find all sections within this page
|
|
71
|
-
const sections = pageElement.querySelectorAll('section');
|
|
72
|
-
sections.forEach((section) => {
|
|
73
|
-
const sectionElement = section as HTMLElement;
|
|
74
|
-
|
|
75
|
-
// Skip sections that are inside the page-index component
|
|
76
|
-
if (sectionElement.closest('.page-index')) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Find direct child headings (h1, h2, h3, h4, h5, h6) of this section
|
|
81
|
-
// Using Array.from and filtering for better browser compatibility
|
|
82
|
-
const childElements = Array.from(sectionElement.children);
|
|
83
|
-
const headings = childElements.filter(child =>
|
|
84
|
-
child.tagName.match(/^H[1-6]$/)
|
|
85
|
-
) as HTMLElement[];
|
|
86
|
-
|
|
87
|
-
headings.forEach((element) => {
|
|
88
|
-
const text = getTextContent(element);
|
|
89
|
-
if (text.trim()) {
|
|
90
|
-
// Skip headings inside component previews, demo containers, or dialogs/drawers
|
|
91
|
-
if (element.closest('.component-preview, [data-demo], .demo, .example, .drawer, [role="dialog"]')) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const id = element.id || generateId(text);
|
|
96
|
-
|
|
97
|
-
// Skip if we've already seen this ID (prevent duplicates)
|
|
98
|
-
if (seenIds.has(id)) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
seenIds.add(id);
|
|
102
|
-
|
|
103
|
-
// Ensure the element has an ID
|
|
104
|
-
if (!element.id) {
|
|
105
|
-
element.id = id;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Determine level based on heading tag
|
|
109
|
-
const tagName = element.tagName.toLowerCase();
|
|
110
|
-
const level = parseInt(tagName.substring(1)); // h1 -> 1, h2 -> 2, etc.
|
|
111
|
-
|
|
112
|
-
newItems.push({
|
|
113
|
-
id,
|
|
114
|
-
title: text.trim(),
|
|
115
|
-
level,
|
|
116
|
-
element,
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
// Sort items by their position in the document
|
|
124
|
-
newItems.sort((a, b) => {
|
|
125
|
-
const aRect = a.element.getBoundingClientRect();
|
|
126
|
-
const bRect = b.element.getBoundingClientRect();
|
|
127
|
-
return aRect.top - bRect.top;
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
setItems(newItems);
|
|
131
|
-
}, [getTextContent, generateId]);
|
|
132
|
-
|
|
133
|
-
// Set up intersection observer to track active section
|
|
134
|
-
React.useEffect(() => {
|
|
135
|
-
const observer = new IntersectionObserver(
|
|
136
|
-
(entries) => {
|
|
137
|
-
// Skip intersection updates during manual navigation
|
|
138
|
-
if (manualNavigation) return;
|
|
139
|
-
|
|
140
|
-
entries.forEach((entry) => {
|
|
141
|
-
if (entry.isIntersecting) {
|
|
142
|
-
setActiveId(entry.target.id);
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
rootMargin: "-80px 0px -80% 0px",
|
|
148
|
-
threshold: 0,
|
|
149
|
-
}
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
items.forEach((item) => {
|
|
153
|
-
observer.observe(item.element);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
return () => {
|
|
157
|
-
items.forEach((item) => {
|
|
158
|
-
observer.unobserve(item.element);
|
|
159
|
-
});
|
|
160
|
-
};
|
|
161
|
-
}, [items, manualNavigation]);
|
|
162
|
-
|
|
163
|
-
// Scan page on mount and when dependencies change
|
|
164
|
-
React.useEffect(() => {
|
|
165
|
-
// Small delay to ensure DOM is ready
|
|
166
|
-
const timer = setTimeout(() => {
|
|
167
|
-
scanPage();
|
|
168
|
-
}, 100);
|
|
169
|
-
|
|
170
|
-
// Also re-scan when URL changes (for SPA navigation)
|
|
171
|
-
const handleLocationChange = () => {
|
|
172
|
-
setTimeout(() => {
|
|
173
|
-
scanPage();
|
|
174
|
-
}, 150); // Slightly longer delay for route transitions
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
// Listen for popstate (browser back/forward)
|
|
178
|
-
window.addEventListener('popstate', handleLocationChange);
|
|
179
|
-
|
|
180
|
-
// Listen for custom navigation events
|
|
181
|
-
window.addEventListener('locationchange', handleLocationChange);
|
|
182
|
-
|
|
183
|
-
// MutationObserver to detect DOM changes
|
|
184
|
-
const observer = new MutationObserver(() => {
|
|
185
|
-
// Debounce the scan to avoid too many re-scans
|
|
186
|
-
clearTimeout(timer);
|
|
187
|
-
setTimeout(() => {
|
|
188
|
-
scanPage();
|
|
189
|
-
}, 200);
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
// Observe changes to the main content area
|
|
193
|
-
const mainContent = document.querySelector('main') || document.body;
|
|
194
|
-
observer.observe(mainContent, {
|
|
195
|
-
childList: true,
|
|
196
|
-
subtree: true,
|
|
197
|
-
attributes: true,
|
|
198
|
-
attributeFilter: ['data-section-title', 'id'],
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
return () => {
|
|
202
|
-
clearTimeout(timer);
|
|
203
|
-
window.removeEventListener('popstate', handleLocationChange);
|
|
204
|
-
window.removeEventListener('locationchange', handleLocationChange);
|
|
205
|
-
observer.disconnect();
|
|
206
|
-
};
|
|
207
|
-
}, [scanPage]);
|
|
208
|
-
|
|
209
|
-
// Handle click on index item
|
|
210
|
-
const handleItemClick = React.useCallback((id: string) => {
|
|
211
|
-
const element = document.getElementById(id);
|
|
212
|
-
if (element) {
|
|
213
|
-
// Set manual navigation flag to prevent intersection observer interference
|
|
214
|
-
setManualNavigation(true);
|
|
215
|
-
setActiveId(id);
|
|
216
|
-
|
|
217
|
-
element.scrollIntoView({
|
|
218
|
-
behavior: "smooth",
|
|
219
|
-
block: "start",
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
// Reset manual navigation flag after scroll animation completes
|
|
223
|
-
setTimeout(() => {
|
|
224
|
-
setManualNavigation(false);
|
|
225
|
-
}, 1000); // 1 second should be enough for smooth scroll
|
|
226
|
-
}
|
|
227
|
-
}, []);
|
|
228
|
-
|
|
229
|
-
const classes = [
|
|
230
|
-
"page-index",
|
|
231
|
-
collapsed && "page-index--collapsed",
|
|
232
|
-
className,
|
|
233
|
-
].filter(Boolean).join(" ");
|
|
234
|
-
|
|
235
|
-
if (items.length === 0) {
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Remove custom props that shouldn't be passed to DOM
|
|
240
|
-
const { sidebarWidth, setSidebarWidth, ...domProps } = props as any;
|
|
241
|
-
|
|
242
|
-
return (
|
|
243
|
-
<div className={classes} {...domProps}>
|
|
244
|
-
{!collapsed && (
|
|
245
|
-
<h3 className="page-index__title">{title}</h3>
|
|
246
|
-
)}
|
|
247
|
-
<nav className="page-index__nav" aria-label="Page contents">
|
|
248
|
-
<ul className="page-index__list">
|
|
249
|
-
{items.map((item) => (
|
|
250
|
-
<li
|
|
251
|
-
key={item.id}
|
|
252
|
-
className={`page-index__item page-index__item--level-${item.level}`}
|
|
253
|
-
>
|
|
254
|
-
<button
|
|
255
|
-
className={`page-index__link ${
|
|
256
|
-
activeId === item.id ? "page-index__link--active" : ""
|
|
257
|
-
}`}
|
|
258
|
-
onClick={() => handleItemClick(item.id)}
|
|
259
|
-
aria-current={activeId === item.id ? "location" : undefined}
|
|
260
|
-
>
|
|
261
|
-
{collapsed ? (
|
|
262
|
-
<span className="page-index__link-text--collapsed">
|
|
263
|
-
{item.title.charAt(0)}
|
|
264
|
-
</span>
|
|
265
|
-
) : (
|
|
266
|
-
item.title
|
|
267
|
-
)}
|
|
268
|
-
</button>
|
|
269
|
-
</li>
|
|
270
|
-
))}
|
|
271
|
-
</ul>
|
|
272
|
-
</nav>
|
|
273
|
-
</div>
|
|
274
|
-
);
|
|
275
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./PageIndex";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Popover, type PopoverProps } from './popover';
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as ReactDOM from "react-dom";
|
|
3
|
-
import "../../style/components/popover/popover.css";
|
|
4
|
-
|
|
5
|
-
export interface PopoverProps {
|
|
6
|
-
trigger: React.ReactNode;
|
|
7
|
-
children: React.ReactNode;
|
|
8
|
-
isOpen?: boolean;
|
|
9
|
-
onToggle?: () => void;
|
|
10
|
-
placement?: 'top' | 'bottom' | 'left' | 'right';
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
type ResolvedPlacement = 'top' | 'bottom' | 'left' | 'right';
|
|
14
|
-
|
|
15
|
-
export const Popover: React.FC<PopoverProps> = ({
|
|
16
|
-
trigger,
|
|
17
|
-
children,
|
|
18
|
-
isOpen = false,
|
|
19
|
-
onToggle,
|
|
20
|
-
placement = 'bottom'
|
|
21
|
-
}) => {
|
|
22
|
-
const [internalOpen, setInternalOpen] = React.useState(false);
|
|
23
|
-
const triggerRef = React.useRef<HTMLDivElement>(null);
|
|
24
|
-
const popoverRef = React.useRef<HTMLDivElement>(null);
|
|
25
|
-
const [popoverStyle, setPopoverStyle] = React.useState<React.CSSProperties>({});
|
|
26
|
-
const [resolvedPlacement, setResolvedPlacement] = React.useState<ResolvedPlacement>(placement);
|
|
27
|
-
|
|
28
|
-
const open = isOpen !== undefined ? isOpen : internalOpen;
|
|
29
|
-
const toggle = onToggle || (() => setInternalOpen(!internalOpen));
|
|
30
|
-
|
|
31
|
-
// Fecha ao clicar fora
|
|
32
|
-
React.useEffect(() => {
|
|
33
|
-
const handleClickOutside = (event: MouseEvent) => {
|
|
34
|
-
if (
|
|
35
|
-
triggerRef.current &&
|
|
36
|
-
!triggerRef.current.contains(event.target as Node) &&
|
|
37
|
-
popoverRef.current &&
|
|
38
|
-
!popoverRef.current.contains(event.target as Node)
|
|
39
|
-
) {
|
|
40
|
-
if (onToggle) {
|
|
41
|
-
onToggle();
|
|
42
|
-
} else {
|
|
43
|
-
setInternalOpen(false);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
if (open) {
|
|
49
|
-
document.addEventListener('mousedown', handleClickOutside);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return () => {
|
|
53
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
54
|
-
};
|
|
55
|
-
}, [open, onToggle]);
|
|
56
|
-
|
|
57
|
-
// Calcula posição com ajuste automático baseado no espaço disponível
|
|
58
|
-
React.useEffect(() => {
|
|
59
|
-
if (!open || !triggerRef.current || !popoverRef.current) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const updatePosition = () => {
|
|
64
|
-
if (!triggerRef.current || !popoverRef.current) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
69
|
-
const popoverRect = popoverRef.current.getBoundingClientRect();
|
|
70
|
-
const gap = 8;
|
|
71
|
-
const viewportWidth = window.innerWidth;
|
|
72
|
-
const viewportHeight = window.innerHeight;
|
|
73
|
-
|
|
74
|
-
// Calcula espaço disponível em cada direção
|
|
75
|
-
const spaceTop = triggerRect.top;
|
|
76
|
-
const spaceBottom = viewportHeight - triggerRect.bottom;
|
|
77
|
-
const spaceLeft = triggerRect.left;
|
|
78
|
-
const spaceRight = viewportWidth - triggerRect.right;
|
|
79
|
-
|
|
80
|
-
// Determina o melhor placement baseado no espaço disponível
|
|
81
|
-
let finalPlacement: ResolvedPlacement = placement as ResolvedPlacement;
|
|
82
|
-
|
|
83
|
-
if (placement === 'right' && spaceRight < popoverRect.width + gap) {
|
|
84
|
-
finalPlacement = spaceLeft >= popoverRect.width + gap ? 'left' : 'bottom';
|
|
85
|
-
} else if (placement === 'left' && spaceLeft < popoverRect.width + gap) {
|
|
86
|
-
finalPlacement = spaceRight >= popoverRect.width + gap ? 'right' : 'bottom';
|
|
87
|
-
} else if (placement === 'bottom' && spaceBottom < popoverRect.height + gap) {
|
|
88
|
-
finalPlacement = spaceTop >= popoverRect.height + gap ? 'top' : 'bottom';
|
|
89
|
-
} else if (placement === 'top' && spaceTop < popoverRect.height + gap) {
|
|
90
|
-
finalPlacement = spaceBottom >= popoverRect.height + gap ? 'bottom' : 'top';
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
setResolvedPlacement(finalPlacement);
|
|
94
|
-
|
|
95
|
-
const newStyle: React.CSSProperties = {
|
|
96
|
-
position: 'fixed',
|
|
97
|
-
zIndex: 9999,
|
|
98
|
-
opacity: 1,
|
|
99
|
-
visibility: 'visible',
|
|
100
|
-
pointerEvents: 'auto',
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// Calcula posição baseada no placement final
|
|
104
|
-
switch (finalPlacement) {
|
|
105
|
-
case 'right':
|
|
106
|
-
newStyle.top = triggerRect.top;
|
|
107
|
-
newStyle.left = triggerRect.right + gap;
|
|
108
|
-
break;
|
|
109
|
-
case 'left':
|
|
110
|
-
newStyle.top = triggerRect.top;
|
|
111
|
-
newStyle.left = triggerRect.left - popoverRect.width - gap;
|
|
112
|
-
break;
|
|
113
|
-
case 'top':
|
|
114
|
-
newStyle.top = triggerRect.top - popoverRect.height - gap;
|
|
115
|
-
newStyle.left = triggerRect.left;
|
|
116
|
-
break;
|
|
117
|
-
case 'bottom':
|
|
118
|
-
default:
|
|
119
|
-
newStyle.top = triggerRect.bottom + gap;
|
|
120
|
-
newStyle.left = triggerRect.left;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Ajuste para não sair da viewport horizontalmente
|
|
124
|
-
if (typeof newStyle.left === 'number') {
|
|
125
|
-
if (newStyle.left + popoverRect.width > viewportWidth - gap) {
|
|
126
|
-
newStyle.left = viewportWidth - popoverRect.width - gap;
|
|
127
|
-
}
|
|
128
|
-
if (newStyle.left < gap) {
|
|
129
|
-
newStyle.left = gap;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Ajuste para não sair da viewport verticalmente
|
|
134
|
-
if (typeof newStyle.top === 'number') {
|
|
135
|
-
if (newStyle.top + popoverRect.height > viewportHeight - gap) {
|
|
136
|
-
newStyle.top = viewportHeight - popoverRect.height - gap;
|
|
137
|
-
}
|
|
138
|
-
if (newStyle.top < gap) {
|
|
139
|
-
newStyle.top = gap;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
setPopoverStyle(newStyle);
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
// Usa requestAnimationFrame para garantir que o popover foi renderizado
|
|
147
|
-
requestAnimationFrame(updatePosition);
|
|
148
|
-
|
|
149
|
-
window.addEventListener('resize', updatePosition);
|
|
150
|
-
window.addEventListener('scroll', updatePosition, true);
|
|
151
|
-
|
|
152
|
-
return () => {
|
|
153
|
-
window.removeEventListener('resize', updatePosition);
|
|
154
|
-
window.removeEventListener('scroll', updatePosition, true);
|
|
155
|
-
};
|
|
156
|
-
}, [open, placement]);
|
|
157
|
-
|
|
158
|
-
const handleTriggerClick = () => {
|
|
159
|
-
toggle();
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
return (
|
|
163
|
-
<>
|
|
164
|
-
<div
|
|
165
|
-
ref={triggerRef}
|
|
166
|
-
onClick={handleTriggerClick}
|
|
167
|
-
style={{ display: 'inline-block', position: 'relative' }}
|
|
168
|
-
>
|
|
169
|
-
{React.isValidElement(trigger)
|
|
170
|
-
? React.cloneElement(trigger as React.ReactElement, {
|
|
171
|
-
onClick: (e: React.MouseEvent) => {
|
|
172
|
-
e.stopPropagation();
|
|
173
|
-
handleTriggerClick();
|
|
174
|
-
(trigger as React.ReactElement).props?.onClick?.(e);
|
|
175
|
-
}
|
|
176
|
-
})
|
|
177
|
-
: trigger}
|
|
178
|
-
</div>
|
|
179
|
-
{open &&
|
|
180
|
-
ReactDOM.createPortal(
|
|
181
|
-
<div
|
|
182
|
-
ref={popoverRef}
|
|
183
|
-
className={`popover popover--${resolvedPlacement}`}
|
|
184
|
-
style={{
|
|
185
|
-
...popoverStyle,
|
|
186
|
-
// Start with opacity 0 and visibility hidden to prevent initial flash
|
|
187
|
-
opacity: popoverStyle.top !== undefined ? 1 : 0,
|
|
188
|
-
visibility: popoverStyle.top !== undefined ? 'visible' : 'hidden',
|
|
189
|
-
}}
|
|
190
|
-
>
|
|
191
|
-
<div className="popover__content">
|
|
192
|
-
{children}
|
|
193
|
-
</div>
|
|
194
|
-
</div>,
|
|
195
|
-
document.body
|
|
196
|
-
)}
|
|
197
|
-
</>
|
|
198
|
-
);
|
|
199
|
-
};
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Radio as AriakitRadio, RadioProps as AriakitRadioProps, RadioGroup as AriakitRadioGroup, RadioGroupProps as AriakitRadioGroupProps, useRadioStore } from '@ariakit/react';
|
|
3
|
-
|
|
4
|
-
export type RadioSize = 'sm' | 'md' | 'lg';
|
|
5
|
-
|
|
6
|
-
export interface RadioProps extends Omit<AriakitRadioProps, 'children' | 'size'> {
|
|
7
|
-
/**
|
|
8
|
-
* Size of the radio button
|
|
9
|
-
* @default 'md'
|
|
10
|
-
*/
|
|
11
|
-
size?: RadioSize;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Label text for the radio button
|
|
15
|
-
*/
|
|
16
|
-
label?: React.ReactNode;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Error state
|
|
20
|
-
*/
|
|
21
|
-
error?: boolean;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface RadioGroupProps extends Omit<AriakitRadioGroupProps, 'onChange'> {
|
|
25
|
-
/**
|
|
26
|
-
* Size of all radio buttons in the group
|
|
27
|
-
* @default 'md'
|
|
28
|
-
*/
|
|
29
|
-
size?: RadioSize;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Label for the radio group
|
|
33
|
-
*/
|
|
34
|
-
label?: string;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Error message to display below the radio group
|
|
38
|
-
*/
|
|
39
|
-
error?: string;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Helper text to display below the radio group
|
|
43
|
-
*/
|
|
44
|
-
helperText?: string;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Children (Radio components)
|
|
48
|
-
*/
|
|
49
|
-
children: React.ReactNode;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Orientation of the radio group
|
|
53
|
-
* @default 'vertical'
|
|
54
|
-
*/
|
|
55
|
-
orientation?: 'horizontal' | 'vertical';
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* The value of the selected radio button
|
|
59
|
-
*/
|
|
60
|
-
value?: string | number | null;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Callback when the selected value changes
|
|
64
|
-
*/
|
|
65
|
-
onChange?: (value: string | number | null) => void;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export const Radio = React.forwardRef<HTMLInputElement, RadioProps>(
|
|
69
|
-
(
|
|
70
|
-
{
|
|
71
|
-
size = 'md',
|
|
72
|
-
label,
|
|
73
|
-
error = false,
|
|
74
|
-
disabled = false,
|
|
75
|
-
className,
|
|
76
|
-
...props
|
|
77
|
-
},
|
|
78
|
-
ref
|
|
79
|
-
) => {
|
|
80
|
-
const radioClasses = [
|
|
81
|
-
'radio',
|
|
82
|
-
`radio--${size}`,
|
|
83
|
-
error && 'radio--error',
|
|
84
|
-
disabled && 'radio--disabled',
|
|
85
|
-
className,
|
|
86
|
-
]
|
|
87
|
-
.filter(Boolean)
|
|
88
|
-
.join(' ');
|
|
89
|
-
|
|
90
|
-
return (
|
|
91
|
-
<label className={radioClasses}>
|
|
92
|
-
<AriakitRadio
|
|
93
|
-
ref={ref}
|
|
94
|
-
disabled={disabled}
|
|
95
|
-
className="radio__input"
|
|
96
|
-
{...props}
|
|
97
|
-
/>
|
|
98
|
-
<span className="radio__box">
|
|
99
|
-
<span className="radio__dot" />
|
|
100
|
-
</span>
|
|
101
|
-
{label && <span className="radio__label">{label}</span>}
|
|
102
|
-
</label>
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
Radio.displayName = 'Radio';
|
|
108
|
-
|
|
109
|
-
export const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>(
|
|
110
|
-
(
|
|
111
|
-
{
|
|
112
|
-
size = 'md',
|
|
113
|
-
label,
|
|
114
|
-
error,
|
|
115
|
-
helperText,
|
|
116
|
-
children,
|
|
117
|
-
orientation = 'vertical',
|
|
118
|
-
disabled = false,
|
|
119
|
-
className,
|
|
120
|
-
value,
|
|
121
|
-
onChange,
|
|
122
|
-
...props
|
|
123
|
-
},
|
|
124
|
-
ref
|
|
125
|
-
) => {
|
|
126
|
-
const groupClasses = [
|
|
127
|
-
'radio-group',
|
|
128
|
-
`radio-group--${orientation}`,
|
|
129
|
-
error && 'radio-group--error',
|
|
130
|
-
disabled && 'radio-group--disabled',
|
|
131
|
-
className,
|
|
132
|
-
]
|
|
133
|
-
.filter(Boolean)
|
|
134
|
-
.join(' ');
|
|
135
|
-
|
|
136
|
-
// Create radio group store
|
|
137
|
-
const radioGroupStore = useRadioStore({
|
|
138
|
-
value,
|
|
139
|
-
setValue: onChange,
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
// Pass size down to children
|
|
143
|
-
const childrenWithProps = React.Children.map(children, (child) => {
|
|
144
|
-
if (React.isValidElement(child) && child.type === Radio) {
|
|
145
|
-
return React.cloneElement(child, {
|
|
146
|
-
size: child.props.size || size,
|
|
147
|
-
error: error ? true : child.props.error,
|
|
148
|
-
disabled: disabled || child.props.disabled,
|
|
149
|
-
} as any);
|
|
150
|
-
}
|
|
151
|
-
return child;
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
return (
|
|
155
|
-
<div className={groupClasses}>
|
|
156
|
-
{label && <div className="radio-group__label">{label}</div>}
|
|
157
|
-
<AriakitRadioGroup
|
|
158
|
-
ref={ref}
|
|
159
|
-
store={radioGroupStore}
|
|
160
|
-
className="radio-group__container"
|
|
161
|
-
{...props}
|
|
162
|
-
>
|
|
163
|
-
{childrenWithProps}
|
|
164
|
-
</AriakitRadioGroup>
|
|
165
|
-
{(error || helperText) && (
|
|
166
|
-
<div className="radio-group__feedback">
|
|
167
|
-
{error && <span className="radio-group__error-text">{error}</span>}
|
|
168
|
-
{!error && helperText && <span className="radio-group__helper-text">{helperText}</span>}
|
|
169
|
-
</div>
|
|
170
|
-
)}
|
|
171
|
-
</div>
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
RadioGroup.displayName = 'RadioGroup';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './Radio';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Section, type SectionProps, type SectionSize } from './section';
|