@birdycom/omniaui-react 0.11.0 → 0.11.2

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 (143) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +21 -21
  3. package/package.json +71 -71
  4. package/src/blocks/BlockAboutTimeline.tsx +46 -46
  5. package/src/blocks/BlockAppHeader.tsx +52 -52
  6. package/src/blocks/BlockAppShell.tsx +56 -56
  7. package/src/blocks/BlockAuth.tsx +53 -53
  8. package/src/blocks/BlockAuthSplit.tsx +84 -84
  9. package/src/blocks/BlockContactGrid.tsx +71 -71
  10. package/src/blocks/BlockCta.tsx +23 -23
  11. package/src/blocks/BlockDataTable.tsx +57 -57
  12. package/src/blocks/BlockFaq.tsx +55 -55
  13. package/src/blocks/BlockFeatures.tsx +38 -38
  14. package/src/blocks/BlockFooter.tsx +50 -50
  15. package/src/blocks/BlockFormPage.tsx +26 -26
  16. package/src/blocks/BlockHero.tsx +27 -27
  17. package/src/blocks/BlockHeroCode.tsx +63 -63
  18. package/src/blocks/BlockHeroOrbit.tsx +73 -73
  19. package/src/blocks/BlockHeroSplit.tsx +28 -28
  20. package/src/blocks/BlockModuleHeader.tsx +34 -34
  21. package/src/blocks/BlockPageHero.tsx +25 -25
  22. package/src/blocks/BlockPortfolioGrid.tsx +50 -50
  23. package/src/blocks/BlockPricing.tsx +62 -62
  24. package/src/blocks/BlockProcess.tsx +50 -50
  25. package/src/blocks/BlockProductGrid.tsx +54 -54
  26. package/src/blocks/BlockProfileHeader.tsx +57 -57
  27. package/src/blocks/BlockShowcase.tsx +58 -58
  28. package/src/blocks/BlockSiteFooter.tsx +60 -60
  29. package/src/blocks/BlockSiteHeader.tsx +42 -42
  30. package/src/blocks/BlockSpotlight.tsx +58 -58
  31. package/src/blocks/BlockStats.tsx +26 -26
  32. package/src/blocks/BlockStatsCounter.tsx +31 -31
  33. package/src/blocks/BlockTeamList.tsx +48 -48
  34. package/src/blocks/BlockTwoFactor.tsx +57 -57
  35. package/src/blocks/BlockWizardDialog.tsx +101 -101
  36. package/src/components/Accordion.tsx +31 -31
  37. package/src/components/AccordionAccent.tsx +39 -39
  38. package/src/components/AffixInput.tsx +47 -47
  39. package/src/components/Alert.tsx +24 -24
  40. package/src/components/AlertDialog.tsx +60 -60
  41. package/src/components/AlphaTabs.tsx +63 -63
  42. package/src/components/Attachment.tsx +140 -140
  43. package/src/components/Avatar.tsx +32 -32
  44. package/src/components/BackLink.tsx +11 -11
  45. package/src/components/Badge.tsx +14 -14
  46. package/src/components/BarcodeInput.tsx +64 -64
  47. package/src/components/Breadcrumb.tsx +32 -32
  48. package/src/components/BrowserFrame.tsx +48 -48
  49. package/src/components/BusyOverlay.tsx +52 -52
  50. package/src/components/Button.tsx +49 -49
  51. package/src/components/Card.tsx +27 -27
  52. package/src/components/ChartLine.tsx +119 -119
  53. package/src/components/ChatComposer.tsx +73 -73
  54. package/src/components/Checkbox.tsx +14 -14
  55. package/src/components/Checklist.tsx +45 -45
  56. package/src/components/ChipFilter.tsx +60 -60
  57. package/src/components/Collapsible.tsx +43 -43
  58. package/src/components/ColorField.tsx +48 -48
  59. package/src/components/ColorSelect.tsx +49 -49
  60. package/src/components/ColumnMenu.tsx +66 -66
  61. package/src/components/Command.tsx +113 -113
  62. package/src/components/ConfirmDialog.tsx +95 -95
  63. package/src/components/CookieConsent.tsx +137 -137
  64. package/src/components/CopyField.tsx +44 -44
  65. package/src/components/Counter.tsx +21 -21
  66. package/src/components/DataTable.tsx +201 -201
  67. package/src/components/DecimalInput.tsx +87 -87
  68. package/src/components/DefinitionList.tsx +38 -38
  69. package/src/components/DocViewer.tsx +110 -110
  70. package/src/components/Dropdown.tsx +52 -52
  71. package/src/components/Dropzone.tsx +46 -46
  72. package/src/components/EmojiPicker.tsx +72 -72
  73. package/src/components/EmptyState.tsx +27 -27
  74. package/src/components/EntityCard.tsx +56 -56
  75. package/src/components/FactList.tsx +43 -43
  76. package/src/components/FilterCounts.tsx +50 -50
  77. package/src/components/FlipCard.tsx +55 -55
  78. package/src/components/FormField.tsx +54 -54
  79. package/src/components/Greeting.tsx +63 -63
  80. package/src/components/Heading.tsx +27 -27
  81. package/src/components/Icon.tsx +25 -25
  82. package/src/components/ImageZoom.tsx +51 -51
  83. package/src/components/Input.tsx +21 -21
  84. package/src/components/InputGroup.tsx +24 -24
  85. package/src/components/LanguageSelect.tsx +64 -64
  86. package/src/components/LauncherCard.tsx +50 -50
  87. package/src/components/Lightbox.tsx +83 -83
  88. package/src/components/LinkArrow.tsx +27 -27
  89. package/src/components/ListToolbar.tsx +67 -67
  90. package/src/components/Marquee.tsx +38 -38
  91. package/src/components/MediaCard.tsx +47 -47
  92. package/src/components/MediaRow.tsx +53 -53
  93. package/src/components/MediaThumb.tsx +49 -49
  94. package/src/components/Message.tsx +171 -171
  95. package/src/components/MessageThread.tsx +177 -177
  96. package/src/components/Modal.tsx +81 -81
  97. package/src/components/Navmenu.tsx +62 -62
  98. package/src/components/NextTeaser.tsx +29 -29
  99. package/src/components/NumberInput.tsx +64 -64
  100. package/src/components/OtpInput.tsx +48 -48
  101. package/src/components/PageHeader.tsx +43 -43
  102. package/src/components/Pagination.tsx +42 -42
  103. package/src/components/PasswordInput.tsx +36 -36
  104. package/src/components/PasswordRequirements.tsx +46 -46
  105. package/src/components/PhoneInput.tsx +93 -93
  106. package/src/components/Popover.tsx +34 -34
  107. package/src/components/PriceCard.tsx +83 -83
  108. package/src/components/ProductMark.tsx +35 -35
  109. package/src/components/Progress.tsx +32 -32
  110. package/src/components/ProjectCard.tsx +46 -46
  111. package/src/components/Prose.tsx +79 -79
  112. package/src/components/RecoveryCodes.tsx +65 -65
  113. package/src/components/Segmented.tsx +47 -47
  114. package/src/components/Select.tsx +27 -27
  115. package/src/components/SeverityCard.tsx +53 -53
  116. package/src/components/Sheet.tsx +62 -62
  117. package/src/components/Skeleton.tsx +12 -12
  118. package/src/components/SortableRow.tsx +46 -46
  119. package/src/components/StackCard.tsx +40 -40
  120. package/src/components/StackList.tsx +42 -42
  121. package/src/components/StatCard.tsx +49 -49
  122. package/src/components/Stepper.tsx +54 -54
  123. package/src/components/Switch.tsx +18 -18
  124. package/src/components/Table.tsx +75 -75
  125. package/src/components/TableActions.tsx +54 -54
  126. package/src/components/TableCompact.tsx +61 -61
  127. package/src/components/Tabs.tsx +45 -45
  128. package/src/components/TagInput.tsx +73 -73
  129. package/src/components/TerminalLog.tsx +63 -63
  130. package/src/components/Textarea.tsx +19 -19
  131. package/src/components/ThemeSwitch.tsx +45 -45
  132. package/src/components/TimeInput.tsx +76 -76
  133. package/src/components/Timeline.tsx +45 -45
  134. package/src/components/Toast.tsx +138 -138
  135. package/src/components/ToggleField.tsx +39 -39
  136. package/src/components/Tooltip.tsx +14 -14
  137. package/src/components/TopProgress.tsx +54 -54
  138. package/src/components/Tree.tsx +97 -97
  139. package/src/components/UpgradeBanner.tsx +62 -62
  140. package/src/components/User.tsx +31 -31
  141. package/src/components/VersionBanner.tsx +41 -41
  142. package/src/hooks.tsx +141 -141
  143. package/src/utils.ts +25 -25
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Serge Cools (Birdycom)
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Serge Cools (Birdycom)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,21 +1,21 @@
1
- # @birdycom/omniaui-react
2
-
3
- React 18/19 function components for [OmniaCSS](https://github.com/Birdycom/omniacss). Every component and block renders the exact markup and classes of the HTML snippets in `@birdycom/omniaui` and `@birdycom/omniaui-blocks`; the CSS packages own all styling.
4
-
5
- ```bash
6
- npm install @birdycom/omniaui-react @birdycom/omniaui @birdycom/omniaui-blocks react react-dom
7
- ```
8
-
9
- ```tsx
10
- import { Button, Modal, ModalClose, ToastProvider, useToast } from "@birdycom/omniaui-react";
11
-
12
- <Button variant="outline" size="sm">Save</Button>
13
- ```
14
-
15
- - Props map to modifiers: `variant`, `size` (`sm`/`md`/`lg`), boolean flags; slots are `children` plus named props (`title`, `description`, `actions`, `footer`).
16
- - `ref` is forwarded, rest props are spread, `className` is merged.
17
- - Dialogs (`Modal`, `AlertDialog`, `Sheet`, `BlockWizardDialog`) sync an `open` prop with the native `<dialog>`; dropdowns and popovers use the native `popover` attribute.
18
- - Wrapper logic lives in the components: `Command` filtering, `PasswordInput` reveal, `CopyField`, toast queue (`ToastProvider` + `useToast`).
19
- - `src/` is published too: copy a file into your project to own the code. `manifest.json` lists `{ name, kind, file, snippet }` for every item.
20
-
21
- MIT
1
+ # @birdycom/omniaui-react
2
+
3
+ React 18/19 function components for [OmniaCSS](https://github.com/Birdycom/omniacss). Every component and block renders the exact markup and classes of the HTML snippets in `@birdycom/omniaui` and `@birdycom/omniaui-blocks`; the CSS packages own all styling.
4
+
5
+ ```bash
6
+ npm install @birdycom/omniaui-react @birdycom/omniaui @birdycom/omniaui-blocks react react-dom
7
+ ```
8
+
9
+ ```tsx
10
+ import { Button, Modal, ModalClose, ToastProvider, useToast } from "@birdycom/omniaui-react";
11
+
12
+ <Button variant="outline" size="sm">Save</Button>
13
+ ```
14
+
15
+ - Props map to modifiers: `variant`, `size` (`sm`/`md`/`lg`), boolean flags; slots are `children` plus named props (`title`, `description`, `actions`, `footer`).
16
+ - `ref` is forwarded, rest props are spread, `className` is merged.
17
+ - Dialogs (`Modal`, `AlertDialog`, `Sheet`, `BlockWizardDialog`) sync an `open` prop with the native `<dialog>`; dropdowns and popovers use the native `popover` attribute.
18
+ - Wrapper logic lives in the components: `Command` filtering, `PasswordInput` reveal, `CopyField`, toast queue (`ToastProvider` + `useToast`).
19
+ - `src/` is published too: copy a file into your project to own the code. `manifest.json` lists `{ name, kind, file, snippet }` for every item.
20
+
21
+ MIT
package/package.json CHANGED
@@ -1,71 +1,71 @@
1
- {
2
- "name": "@birdycom/omniaui-react",
3
- "version": "0.11.0",
4
- "description": "OmniaUI for React: typed function components and page blocks that render the exact @birdycom/omniaui and @birdycom/omniaui-blocks markup.",
5
- "type": "module",
6
- "license": "MIT",
7
- "author": "Serge Cools (Birdycom)",
8
- "homepage": "https://omniaui.eu",
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/Birdycom/OmniaUI.git",
12
- "directory": "packages/react"
13
- },
14
- "bugs": {
15
- "url": "https://github.com/Birdycom/OmniaUI/issues"
16
- },
17
- "keywords": [
18
- "react",
19
- "components",
20
- "css",
21
- "omniaui",
22
- "tsx"
23
- ],
24
- "main": "./dist/index.js",
25
- "module": "./dist/index.js",
26
- "types": "./dist/index.d.ts",
27
- "exports": {
28
- ".": {
29
- "types": "./dist/index.d.ts",
30
- "import": "./dist/index.js"
31
- },
32
- "./src/*": "./src/*",
33
- "./manifest.json": "./manifest.json",
34
- "./package.json": "./package.json"
35
- },
36
- "files": [
37
- "dist",
38
- "src",
39
- "manifest.json",
40
- "README.md",
41
- "LICENSE"
42
- ],
43
- "sideEffects": false,
44
- "scripts": {
45
- "build": "node scripts/build-manifest.mjs && tsup",
46
- "typecheck": "tsc --noEmit",
47
- "test": "vitest run"
48
- },
49
- "peerDependencies": {
50
- "react": ">=18",
51
- "react-dom": ">=18"
52
- },
53
- "devDependencies": {
54
- "@testing-library/jest-dom": "^6.6.3",
55
- "@testing-library/react": "^16.1.0",
56
- "@types/react": "^19.0.0",
57
- "@types/react-dom": "^19.0.0",
58
- "jsdom": "^26.0.0",
59
- "react": "^19.0.0",
60
- "react-dom": "^19.0.0",
61
- "tsup": "^8.3.5",
62
- "typescript": "^5.7.0",
63
- "vitest": "^3.0.0"
64
- },
65
- "engines": {
66
- "node": ">=22"
67
- },
68
- "publishConfig": {
69
- "access": "public"
70
- }
71
- }
1
+ {
2
+ "name": "@birdycom/omniaui-react",
3
+ "version": "0.11.2",
4
+ "description": "OmniaUI for React: typed function components and page blocks that render the exact @birdycom/omniaui and @birdycom/omniaui-blocks markup.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Serge Cools (Birdycom)",
8
+ "homepage": "https://omniaui.eu",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/Birdycom/OmniaUI.git",
12
+ "directory": "packages/react"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/Birdycom/OmniaUI/issues"
16
+ },
17
+ "keywords": [
18
+ "react",
19
+ "components",
20
+ "css",
21
+ "omniaui",
22
+ "tsx"
23
+ ],
24
+ "main": "./dist/index.js",
25
+ "module": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ },
32
+ "./src/*": "./src/*",
33
+ "./manifest.json": "./manifest.json",
34
+ "./package.json": "./package.json"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "src",
39
+ "manifest.json",
40
+ "README.md",
41
+ "LICENSE"
42
+ ],
43
+ "sideEffects": false,
44
+ "scripts": {
45
+ "build": "node scripts/build-manifest.mjs && tsup",
46
+ "typecheck": "tsc --noEmit",
47
+ "test": "vitest run"
48
+ },
49
+ "peerDependencies": {
50
+ "react": ">=18",
51
+ "react-dom": ">=18"
52
+ },
53
+ "devDependencies": {
54
+ "@testing-library/jest-dom": "^6.6.3",
55
+ "@testing-library/react": "^16.1.0",
56
+ "@types/react": "^19.0.0",
57
+ "@types/react-dom": "^19.0.0",
58
+ "jsdom": "^26.0.0",
59
+ "react": "^19.0.0",
60
+ "react-dom": "^19.0.0",
61
+ "tsup": "^8.3.5",
62
+ "typescript": "^5.7.0",
63
+ "vitest": "^5.0.5"
64
+ },
65
+ "engines": {
66
+ "node": ">=22"
67
+ },
68
+ "publishConfig": {
69
+ "access": "public"
70
+ }
71
+ }
@@ -1,46 +1,46 @@
1
- // File: packages/react/src/blocks/BlockAboutTimeline.tsx | Map: props -> BlockAboutTimeline (media + badge -> copy -> timeline)
2
- import { forwardRef, useId } from "react";
3
- import type { HTMLAttributes, ReactNode } from "react";
4
- import { cx } from "../utils";
5
- import { Timeline } from "../components/Timeline";
6
- import type { TimelineEntry } from "../components/Timeline";
7
-
8
- export interface BlockAboutTimelineProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
9
- eyebrow?: ReactNode;
10
- /** Heading; wrap a part in `<span className="oc-text-gradient">`. */
11
- title: ReactNode;
12
- /** Paragraphs (or any content) below the title. */
13
- children?: ReactNode;
14
- timeline?: TimelineEntry[];
15
- /** Picture URL; without it the media is an accent gradient. */
16
- image?: string;
17
- imageAlt?: string;
18
- /** Badge on the picture (e.g. <><strong>12+</strong>years</>). */
19
- badge?: ReactNode;
20
- /** Picture on the right. */
21
- reverse?: boolean;
22
- }
23
-
24
- /** `.oc-block-about`: picture next to the company story with a year timeline. */
25
- export const BlockAboutTimeline = forwardRef<HTMLElement, BlockAboutTimelineProps>(function BlockAboutTimeline(
26
- { eyebrow, title, children, timeline = [], image, imageAlt = "", badge, reverse = false, className, ...rest },
27
- ref,
28
- ) {
29
- const titleId = `oc-about-title-${useId().replace(/[^\w-]/g, "")}`;
30
- return (
31
- <section ref={ref} className={cx("oc-block-about", reverse && "oc-block-about--reverse", className)} aria-labelledby={titleId} {...rest}>
32
- <div className="oc-block-about-inner">
33
- <figure className="oc-block-about-media" aria-hidden={image ? undefined : true}>
34
- {image && <img src={image} alt={imageAlt} loading="lazy" />}
35
- {badge != null && <span className="oc-block-about-badge">{badge}</span>}
36
- </figure>
37
- <div className="oc-block-about-copy">
38
- {eyebrow != null && <p className="oc-eyebrow">{eyebrow}</p>}
39
- <h2 className="oc-block-about-title" id={titleId}>{title}</h2>
40
- {children}
41
- {timeline.length > 0 && <Timeline items={timeline} />}
42
- </div>
43
- </div>
44
- </section>
45
- );
46
- });
1
+ // File: packages/react/src/blocks/BlockAboutTimeline.tsx | Map: props -> BlockAboutTimeline (media + badge -> copy -> timeline)
2
+ import { forwardRef, useId } from "react";
3
+ import type { HTMLAttributes, ReactNode } from "react";
4
+ import { cx } from "../utils";
5
+ import { Timeline } from "../components/Timeline";
6
+ import type { TimelineEntry } from "../components/Timeline";
7
+
8
+ export interface BlockAboutTimelineProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
9
+ eyebrow?: ReactNode;
10
+ /** Heading; wrap a part in `<span className="oc-text-gradient">`. */
11
+ title: ReactNode;
12
+ /** Paragraphs (or any content) below the title. */
13
+ children?: ReactNode;
14
+ timeline?: TimelineEntry[];
15
+ /** Picture URL; without it the media is an accent gradient. */
16
+ image?: string;
17
+ imageAlt?: string;
18
+ /** Badge on the picture (e.g. <><strong>12+</strong>years</>). */
19
+ badge?: ReactNode;
20
+ /** Picture on the right. */
21
+ reverse?: boolean;
22
+ }
23
+
24
+ /** `.oc-block-about`: picture next to the company story with a year timeline. */
25
+ export const BlockAboutTimeline = forwardRef<HTMLElement, BlockAboutTimelineProps>(function BlockAboutTimeline(
26
+ { eyebrow, title, children, timeline = [], image, imageAlt = "", badge, reverse = false, className, ...rest },
27
+ ref,
28
+ ) {
29
+ const titleId = `oc-about-title-${useId().replace(/[^\w-]/g, "")}`;
30
+ return (
31
+ <section ref={ref} className={cx("oc-block-about", reverse && "oc-block-about--reverse", className)} aria-labelledby={titleId} {...rest}>
32
+ <div className="oc-block-about-inner">
33
+ <figure className="oc-block-about-media" aria-hidden={image ? undefined : true}>
34
+ {image && <img src={image} alt={imageAlt} loading="lazy" />}
35
+ {badge != null && <span className="oc-block-about-badge">{badge}</span>}
36
+ </figure>
37
+ <div className="oc-block-about-copy">
38
+ {eyebrow != null && <p className="oc-eyebrow">{eyebrow}</p>}
39
+ <h2 className="oc-block-about-title" id={titleId}>{title}</h2>
40
+ {children}
41
+ {timeline.length > 0 && <Timeline items={timeline} />}
42
+ </div>
43
+ </div>
44
+ </section>
45
+ );
46
+ });
@@ -1,52 +1,52 @@
1
- import { forwardRef } from "react";
2
- import type { HTMLAttributes, ReactNode } from "react";
3
- import { cx } from "../utils";
4
- import { Icon } from "../components/Icon";
5
- import { Navmenu, NavmenuItem, NavmenuLink } from "../components/Navmenu";
6
-
7
- export interface AppHeaderNavItem {
8
- label: ReactNode;
9
- href: string;
10
- current?: boolean;
11
- }
12
-
13
- export interface BlockAppHeaderProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
14
- /** Id of the sidebar toggle checkbox (see BlockAppShell). Omit to hide the toggle button. */
15
- toggleFor?: string;
16
- toggleLabel?: string;
17
- /** Module navigation links. */
18
- nav?: AppHeaderNavItem[];
19
- navLabel?: string;
20
- /** Right-aligned actions: theme switch, switchers, user menu. */
21
- actions?: ReactNode;
22
- /** Optional page title (`oc-block-appbar-title`). */
23
- title?: ReactNode;
24
- }
25
-
26
- /** `.oc-block-appbar`: top bar with sidebar toggle, module navigation and actions. */
27
- export const BlockAppHeader = forwardRef<HTMLElement, BlockAppHeaderProps>(function BlockAppHeader(
28
- { toggleFor, toggleLabel = "Toggle sidebar", nav, navLabel = "Module navigation", actions, title, className, ...rest },
29
- ref,
30
- ) {
31
- return (
32
- <header ref={ref} className={cx("oc-block-appbar", className)} {...rest}>
33
- {toggleFor && (
34
- <label className="oc-btn oc-btn--ghost oc-btn--icon" htmlFor={toggleFor} title={toggleLabel}>
35
- <Icon d="M4 6h16M4 12h16M4 18h16" />
36
- <span className="oc-visually-hidden">{toggleLabel}</span>
37
- </label>
38
- )}
39
- {title != null && <span className="oc-block-appbar-title">{title}</span>}
40
- {nav && (
41
- <Navmenu label={navLabel} navClassName="oc-block-appbar-nav">
42
- {nav.map((item, i) => (
43
- <NavmenuItem key={i}>
44
- <NavmenuLink href={item.href} current={item.current}>{item.label}</NavmenuLink>
45
- </NavmenuItem>
46
- ))}
47
- </Navmenu>
48
- )}
49
- {actions != null && <div className="oc-block-appbar-actions">{actions}</div>}
50
- </header>
51
- );
52
- });
1
+ import { forwardRef } from "react";
2
+ import type { HTMLAttributes, ReactNode } from "react";
3
+ import { cx } from "../utils";
4
+ import { Icon } from "../components/Icon";
5
+ import { Navmenu, NavmenuItem, NavmenuLink } from "../components/Navmenu";
6
+
7
+ export interface AppHeaderNavItem {
8
+ label: ReactNode;
9
+ href: string;
10
+ current?: boolean;
11
+ }
12
+
13
+ export interface BlockAppHeaderProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
14
+ /** Id of the sidebar toggle checkbox (see BlockAppShell). Omit to hide the toggle button. */
15
+ toggleFor?: string;
16
+ toggleLabel?: string;
17
+ /** Module navigation links. */
18
+ nav?: AppHeaderNavItem[];
19
+ navLabel?: string;
20
+ /** Right-aligned actions: theme switch, switchers, user menu. */
21
+ actions?: ReactNode;
22
+ /** Optional page title (`oc-block-appbar-title`). */
23
+ title?: ReactNode;
24
+ }
25
+
26
+ /** `.oc-block-appbar`: top bar with sidebar toggle, module navigation and actions. */
27
+ export const BlockAppHeader = forwardRef<HTMLElement, BlockAppHeaderProps>(function BlockAppHeader(
28
+ { toggleFor, toggleLabel = "Toggle sidebar", nav, navLabel = "Module navigation", actions, title, className, ...rest },
29
+ ref,
30
+ ) {
31
+ return (
32
+ <header ref={ref} className={cx("oc-block-appbar", className)} {...rest}>
33
+ {toggleFor && (
34
+ <label className="oc-btn oc-btn--ghost oc-btn--icon" htmlFor={toggleFor} title={toggleLabel}>
35
+ <Icon d="M4 6h16M4 12h16M4 18h16" />
36
+ <span className="oc-visually-hidden">{toggleLabel}</span>
37
+ </label>
38
+ )}
39
+ {title != null && <span className="oc-block-appbar-title">{title}</span>}
40
+ {nav && (
41
+ <Navmenu label={navLabel} navClassName="oc-block-appbar-nav">
42
+ {nav.map((item, i) => (
43
+ <NavmenuItem key={i}>
44
+ <NavmenuLink href={item.href} current={item.current}>{item.label}</NavmenuLink>
45
+ </NavmenuItem>
46
+ ))}
47
+ </Navmenu>
48
+ )}
49
+ {actions != null && <div className="oc-block-appbar-actions">{actions}</div>}
50
+ </header>
51
+ );
52
+ });
@@ -1,56 +1,56 @@
1
- import { forwardRef, useId } from "react";
2
- import type { CSSProperties, HTMLAttributes, ReactNode } from "react";
3
- import { cx } from "../utils";
4
- import type { BreadcrumbItemData } from "../components/Breadcrumb";
5
-
6
- export interface BlockAppShellProps extends HTMLAttributes<HTMLDivElement> {
7
- /** A `<Sidebar>`; rendered as the first grid child. */
8
- sidebar: ReactNode;
9
- /** A `<BlockAppHeader toggleFor={toggleId}>`. */
10
- header?: ReactNode;
11
- /** Breadcrumb strip under the header bar. */
12
- breadcrumbs?: BreadcrumbItemData[];
13
- /** Id of the collapse checkbox; pass the same value to `BlockAppHeader`'s `toggleFor`. */
14
- toggleId?: string;
15
- /** Shell height (`--oc-block-shell-height`, default 100dvh). */
16
- height?: string;
17
- }
18
-
19
- /** `.oc-block-shell`: sidebar, header bar, breadcrumb strip and the scrolling content. */
20
- export const BlockAppShell = forwardRef<HTMLDivElement, BlockAppShellProps>(function BlockAppShell(
21
- { sidebar, header, breadcrumbs, toggleId, height, className, style, children, ...rest },
22
- ref,
23
- ) {
24
- const auto = useId();
25
- const id = toggleId ?? `oc-shell-toggle-${auto.replace(/:/g, "")}`;
26
- return (
27
- <div
28
- ref={ref}
29
- className={cx("oc-block-shell", className)}
30
- style={height ? ({ "--oc-block-shell-height": height, ...style } as CSSProperties) : style}
31
- {...rest}
32
- >
33
- <input className="oc-block-shell-toggle" type="checkbox" id={id} aria-label="Collapse sidebar" />
34
- {sidebar}
35
- <div className="oc-block-shell-main">
36
- {header}
37
- {breadcrumbs && (
38
- <div className="oc-block-shell-breadcrumbs">
39
- <nav aria-label="Breadcrumb">
40
- <ol className="oc-breadcrumb">
41
- {breadcrumbs.map((item, i) =>
42
- item.href && i < breadcrumbs.length - 1 ? (
43
- <li className="oc-breadcrumb-item" key={i}><a href={item.href}>{item.label}</a></li>
44
- ) : (
45
- <li className="oc-breadcrumb-item" aria-current="page" key={i}>{item.label}</li>
46
- ),
47
- )}
48
- </ol>
49
- </nav>
50
- </div>
51
- )}
52
- <main className="oc-block-shell-content">{children}</main>
53
- </div>
54
- </div>
55
- );
56
- });
1
+ import { forwardRef, useId } from "react";
2
+ import type { CSSProperties, HTMLAttributes, ReactNode } from "react";
3
+ import { cx } from "../utils";
4
+ import type { BreadcrumbItemData } from "../components/Breadcrumb";
5
+
6
+ export interface BlockAppShellProps extends HTMLAttributes<HTMLDivElement> {
7
+ /** A `<Sidebar>`; rendered as the first grid child. */
8
+ sidebar: ReactNode;
9
+ /** A `<BlockAppHeader toggleFor={toggleId}>`. */
10
+ header?: ReactNode;
11
+ /** Breadcrumb strip under the header bar. */
12
+ breadcrumbs?: BreadcrumbItemData[];
13
+ /** Id of the collapse checkbox; pass the same value to `BlockAppHeader`'s `toggleFor`. */
14
+ toggleId?: string;
15
+ /** Shell height (`--oc-block-shell-height`, default 100dvh). */
16
+ height?: string;
17
+ }
18
+
19
+ /** `.oc-block-shell`: sidebar, header bar, breadcrumb strip and the scrolling content. */
20
+ export const BlockAppShell = forwardRef<HTMLDivElement, BlockAppShellProps>(function BlockAppShell(
21
+ { sidebar, header, breadcrumbs, toggleId, height, className, style, children, ...rest },
22
+ ref,
23
+ ) {
24
+ const auto = useId();
25
+ const id = toggleId ?? `oc-shell-toggle-${auto.replace(/:/g, "")}`;
26
+ return (
27
+ <div
28
+ ref={ref}
29
+ className={cx("oc-block-shell", className)}
30
+ style={height ? ({ "--oc-block-shell-height": height, ...style } as CSSProperties) : style}
31
+ {...rest}
32
+ >
33
+ <input className="oc-block-shell-toggle" type="checkbox" id={id} aria-label="Collapse sidebar" />
34
+ {sidebar}
35
+ <div className="oc-block-shell-main">
36
+ {header}
37
+ {breadcrumbs && (
38
+ <div className="oc-block-shell-breadcrumbs">
39
+ <nav aria-label="Breadcrumb">
40
+ <ol className="oc-breadcrumb">
41
+ {breadcrumbs.map((item, i) =>
42
+ item.href && i < breadcrumbs.length - 1 ? (
43
+ <li className="oc-breadcrumb-item" key={i}><a href={item.href}>{item.label}</a></li>
44
+ ) : (
45
+ <li className="oc-breadcrumb-item" aria-current="page" key={i}>{item.label}</li>
46
+ ),
47
+ )}
48
+ </ol>
49
+ </nav>
50
+ </div>
51
+ )}
52
+ <main className="oc-block-shell-content">{children}</main>
53
+ </div>
54
+ </div>
55
+ );
56
+ });