this.gui 1.3.22 → 1.3.26
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/dist/this-gui.es.js +0 -1
- package/dist/this-gui.umd.js +65 -65
- package/index.ts +3 -2
- package/init/index.html +4 -5
- package/init/package-lock.json +2 -2
- package/init/package.json +1 -1
- package/init/src/App.tsx +24 -0
- package/init/src/index.css +16 -0
- package/init/src/main.tsx +14 -0
- package/init/src/router/DerivableRouter.tsx +36 -0
- package/package.json +1 -1
- package/src/GUI.tsx +15 -0
- package/src/components/generics/Cards/Gridme.jsx +52 -0
- package/src/components/generics/Cards/LilBox.jsx +65 -0
- package/src/components/generics/Cards/ModuleCard.jsx +106 -0
- package/src/components/generics/Chats/FullChatBot.jsx +223 -0
- package/src/components/generics/Code/CodeBlock.jsx +33 -0
- package/src/components/generics/Feedback/Callout.jsx +92 -0
- package/src/components/generics/Layout/GridX.jsx +29 -0
- package/src/components/generics/Layout/Hero2.jsx +132 -0
- package/src/components/generics/Layout/PageContainer.jsx +29 -0
- package/src/components/generics/Layout/PageDivider.jsx +20 -0
- package/src/components/generics/Layout/Section.jsx +43 -0
- package/src/components/generics/Layout/SectionHeader.jsx +21 -0
- package/src/components/generics/Media/Img.jsx +58 -0
- package/src/components/generics/Media/VideoEmbed.jsx +51 -0
- package/src/components/generics/Organization/TableOfContents.jsx +51 -0
- package/src/components/generics/Organization/Tabs.jsx +45 -0
- package/src/components/generics/Text/TextList.jsx +41 -0
- package/src/components/generics/Text/TextParagraph.jsx +28 -0
- package/src/components/generics/Text/TextQuote.jsx +23 -0
- package/src/components/generics/Text/TextTitle.jsx +44 -0
- package/src/gui/Layouts/ResponsiveUI/Content/Content.resolver.tsx +0 -0
- package/src/gui/Layouts/ResponsiveUI/Content/Content.stories.tsx +88 -0
- package/src/gui/Layouts/ResponsiveUI/Content/Content.tsx +53 -0
- package/src/gui/Layouts/ResponsiveUI/Content/Content.types.tsx +40 -0
- package/src/gui/Layouts/ResponsiveUI/Footer/Footer.resolver.tsx +45 -0
- package/src/gui/Layouts/ResponsiveUI/Footer/Footer.stories.tsx +209 -0
- package/src/gui/Layouts/ResponsiveUI/Footer/Footer.tsx +337 -0
- package/src/gui/Layouts/ResponsiveUI/Footer/Footer.types.ts +40 -0
- package/src/gui/Layouts/ResponsiveUI/Layout/Layout.resolver.tsx +37 -0
- package/src/gui/Layouts/ResponsiveUI/Layout/Layout.stories.tsx +290 -0
- package/src/gui/Layouts/ResponsiveUI/Layout/Layout.tsx +112 -0
- package/src/gui/Layouts/ResponsiveUI/Layout/Layout.types.ts +56 -0
- package/src/gui/Layouts/ResponsiveUI/Layout/useLayoutBreakpoints.ts +9 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/LeftSidebar.resolver.tsx +87 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/LeftSidebar.stories.tsx +199 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/LeftSidebar.tsx +311 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/LeftSidebar.types.ts +41 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/SidebarToggleButton.tsx +53 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/components/LeftSidebarAction/LeftSidebarAction.resolver.tsx +19 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/components/LeftSidebarAction/LeftSidebarAction.tsx +107 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/components/LeftSidebarLink/LeftSidebarLink.resolver.tsx +0 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/components/LeftSidebarLink/LeftSidebarLink.tsx +122 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/components/LeftSidebarLink/LeftSidebarLink.types.ts +13 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/components/LeftSidebarMenu/LeftSidebarMenu.tsx +142 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/LeftSidebar/components/LeftSidebarToggleButton/LeftSidebarToggleButton.tsx +23 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/RightSidebar/RightSidebar.resolver.tsx +35 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/RightSidebar/RightSidebar.stories.tsx +240 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/RightSidebar/RightSidebar.tsx +319 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/RightSidebar/RightSidebar.types.ts +17 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/RightSidebar/components/RightSidebarAction/RightSidebarAction.tsx +102 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/RightSidebar/components/RightSidebarLink/RightSidebarLink.tsx +132 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/RightSidebar/components/RightSidebarMenu/RightSidebarMenu.tsx +140 -0
- package/src/gui/Layouts/ResponsiveUI/Sidebars/RightSidebar/components/RightSidebarToggleButton/RightSidebarToggleButton.tsx +22 -0
- package/src/gui/Layouts/ResponsiveUI/StickyOptions/StickyOptionsTop.stories.tsx +469 -0
- package/src/gui/Layouts/ResponsiveUI/StickyOptions/StickyOptionsTop.tsx +489 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/TopBar.resolver.tsx +86 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/TopBar.stories.tsx +350 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/TopBar.tsx +281 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/TopBar.types.ts +39 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/components/TopBarAction/TopBarAction.stories.tsx +83 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/components/TopBarAction/TopBarAction.tsx +18 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/components/TopBarAction/TopBarAction.types.ts +4 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/components/TopBarLink/TopBarLink.stories.tsx +189 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/components/TopBarLink/TopBarLink.tsx +30 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/components/TopBarLink/TopBarLink.types.ts +9 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/components/TopBarMenu/TopBarMenu.resolver.tsx +14 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/components/TopBarMenu/TopBarMenu.stories.tsx +56 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/components/TopBarMenu/TopBarMenu.tsx +123 -0
- package/src/gui/Layouts/ResponsiveUI/TopBar/components/TopBarMenu/TopBarMenu.types.ts +44 -0
- package/src/gui/Theme/GuiProvider.tsx +125 -0
- package/src/gui/Theme/Icon/Icon.resolver.tsx +29 -0
- package/src/gui/Theme/Icon/Icon.tsx +43 -0
- package/src/gui/Theme/catalog/CherryByte/CherryByte.png +0 -0
- package/src/gui/Theme/catalog/CherryByte/dark.tokens.ts +47 -0
- package/src/gui/Theme/catalog/CherryByte/light.tokens.ts +47 -0
- package/src/gui/Theme/catalog/CherryByte/manifest.ts +24 -0
- package/src/gui/Theme/catalog/GhostShell/dark.tokens.ts +43 -0
- package/src/gui/Theme/catalog/GhostShell/ghost.png +0 -0
- package/src/gui/Theme/catalog/GhostShell/light.tokens.ts +39 -0
- package/src/gui/Theme/catalog/GhostShell/manifest.ts +24 -0
- package/src/gui/Theme/catalog/LunaHex/LunaHex.png +0 -0
- package/src/gui/Theme/catalog/LunaHex/dark.tokens.ts +34 -0
- package/src/gui/Theme/catalog/LunaHex/light.tokens.ts +74 -0
- package/src/gui/Theme/catalog/LunaHex/manifest.ts +24 -0
- package/src/gui/Theme/catalog/MUI/MUI.png +0 -0
- package/src/gui/Theme/catalog/MUI/dark.tokens.ts +58 -0
- package/src/gui/Theme/catalog/MUI/light.tokens.ts +74 -0
- package/src/gui/Theme/catalog/MUI/manifest.ts +24 -0
- package/src/gui/Theme/catalog/PrinceOfDarkness/dark.tokens.ts +48 -0
- package/src/gui/Theme/catalog/PrinceOfDarkness/light.tokens.ts +47 -0
- package/src/gui/Theme/catalog/PrinceOfDarkness/manifest.ts +24 -0
- package/src/gui/Theme/catalog/PrinceOfDarkness/prince.png +0 -0
- package/src/gui/Theme/catalog/PrinceOfDarkness/princeOfDarkness.png +0 -0
- package/src/gui/Theme/catalog/Seafoam/dark.tokens.ts +49 -0
- package/src/gui/Theme/catalog/Seafoam/light.tokens.ts +47 -0
- package/src/gui/Theme/catalog/Seafoam/manifest.ts +24 -0
- package/src/gui/Theme/catalog/Seafoam/seaFoam.png +0 -0
- package/src/gui/Theme/catalog/neurons/dark.tokens.ts +58 -0
- package/src/gui/Theme/catalog/neurons/light.tokens.ts +74 -0
- package/src/gui/Theme/catalog/neurons/manifest.ts +24 -0
- package/src/gui/Theme/catalog/neurons/neurons.me.png +0 -0
- package/src/gui/Theme/fromTokens.ts +273 -0
- package/src/gui/Theme/gui.css +31 -0
- package/src/gui/Theme/index.ts +17 -0
- package/src/gui/Theme/styles/buildShadows.ts +83 -0
- package/src/gui/Theme/styles/theme.tokens.ts +108 -0
- package/src/gui/Theme/utils/catalog.ts +61 -0
- package/src/gui/Theme/utils/persistence.ts +66 -0
- package/src/gui/Theme/utils/themeUtils.ts +34 -0
- package/src/gui/apis/codegen.api.ts +38 -0
- package/src/gui/components/atoms/AppBar/AppBar.resolver.tsx +41 -0
- package/src/gui/components/atoms/AppBar/AppBar.stories.tsx +225 -0
- package/src/gui/components/atoms/AppBar/AppBar.tsx +8 -0
- package/src/gui/components/atoms/AppBar/AppBar.types.ts +28 -0
- package/src/gui/components/atoms/Avatar/Avatar.resolver.tsx +61 -0
- package/src/gui/components/atoms/Avatar/Avatar.stories.tsx +36 -0
- package/src/gui/components/atoms/Avatar/Avatar.tsx +14 -0
- package/src/gui/components/atoms/Box/Box.resolver.tsx +171 -0
- package/src/gui/components/atoms/Box/Box.stories.tsx +263 -0
- package/src/gui/components/atoms/Box/Box.tsx +15 -0
- package/src/gui/components/atoms/Button/Button.resolver.tsx +103 -0
- package/src/gui/components/atoms/Button/Button.stories.tsx +219 -0
- package/src/gui/components/atoms/Button/Button.tsx +40 -0
- package/src/gui/components/atoms/Card/Card.resolver.tsx +63 -0
- package/src/gui/components/atoms/Card/Card.stories.tsx +54 -0
- package/src/gui/components/atoms/Card/Card.tsx +13 -0
- package/src/gui/components/atoms/CardActions/CardActions.resolver.tsx +59 -0
- package/src/gui/components/atoms/CardActions/CardActions.stories.tsx +32 -0
- package/src/gui/components/atoms/CardActions/CardActions.tsx +14 -0
- package/src/gui/components/atoms/CardContent/CardContent.resolver.tsx +60 -0
- package/src/gui/components/atoms/CardContent/CardContent.stories.tsx +34 -0
- package/src/gui/components/atoms/CardContent/CardContent.tsx +13 -0
- package/src/gui/components/atoms/CardHeader/CardHeader.resolver.tsx +68 -0
- package/src/gui/components/atoms/CardHeader/CardHeader.stories.tsx +40 -0
- package/src/gui/components/atoms/CardHeader/CardHeader.tsx +12 -0
- package/src/gui/components/atoms/Collapse/Collapse.resolver.tsx +85 -0
- package/src/gui/components/atoms/Collapse/Collapse.stories.tsx +130 -0
- package/src/gui/components/atoms/Collapse/Collapse.tsx +17 -0
- package/src/gui/components/atoms/Divider/Divider.resolver.tsx +95 -0
- package/src/gui/components/atoms/Divider/Divider.stories.tsx +108 -0
- package/src/gui/components/atoms/Divider/Divider.tsx +14 -0
- package/src/gui/components/atoms/Drawer/Drawer.resolver.tsx +116 -0
- package/src/gui/components/atoms/Drawer/Drawer.stories.tsx +223 -0
- package/src/gui/components/atoms/Drawer/Drawer.tsx +25 -0
- package/src/gui/components/atoms/Grid/Grid.resolver.tsx +33 -0
- package/src/gui/components/atoms/Grid/Grid.stories.tsx +136 -0
- package/src/gui/components/atoms/Grid/Grid.tsx +15 -0
- package/src/gui/components/atoms/Grid/Grid.types.ts +9 -0
- package/src/gui/components/atoms/IconButton/IconButton.resolver.tsx +137 -0
- package/src/gui/components/atoms/IconButton/IconButton.stories.tsx +134 -0
- package/src/gui/components/atoms/IconButton/IconButton.tsx +22 -0
- package/src/gui/components/atoms/Link/Link.resolver.tsx +74 -0
- package/src/gui/components/atoms/Link/Link.stories.tsx +157 -0
- package/src/gui/components/atoms/Link/Link.tsx +36 -0
- package/src/gui/components/atoms/List/List.resolver.tsx +94 -0
- package/src/gui/components/atoms/List/List.stories.tsx +137 -0
- package/src/gui/components/atoms/List/List.tsx +20 -0
- package/src/gui/components/atoms/ListItem/ListItem.resolver.tsx +88 -0
- package/src/gui/components/atoms/ListItem/ListItem.stories.tsx +151 -0
- package/src/gui/components/atoms/ListItem/ListItem.tsx +19 -0
- package/src/gui/components/atoms/ListItemButton/ListItemButton.resolver.tsx +214 -0
- package/src/gui/components/atoms/ListItemButton/ListItemButton.stories.tsx +155 -0
- package/src/gui/components/atoms/ListItemButton/ListItemButton.tsx +15 -0
- package/src/gui/components/atoms/ListItemIcon/ListItemIcon.resolver.tsx +102 -0
- package/src/gui/components/atoms/ListItemIcon/ListItemIcon.stories.tsx +132 -0
- package/src/gui/components/atoms/ListItemIcon/ListItemIcon.tsx +11 -0
- package/src/gui/components/atoms/ListItemText/ListItemText.resolver.tsx +112 -0
- package/src/gui/components/atoms/ListItemText/ListItemText.stories.tsx +156 -0
- package/src/gui/components/atoms/ListItemText/ListItemText.tsx +15 -0
- package/src/gui/components/atoms/Menu/Menu.resolver.tsx +112 -0
- package/src/gui/components/atoms/Menu/Menu.stories.tsx +162 -0
- package/src/gui/components/atoms/Menu/Menu.tsx +17 -0
- package/src/gui/components/atoms/MenuItem/MenuItem.resolver.tsx +183 -0
- package/src/gui/components/atoms/MenuItem/MenuItem.stories.tsx +134 -0
- package/src/gui/components/atoms/MenuItem/MenuItem.tsx +14 -0
- package/src/gui/components/atoms/Paper/Paper.resolver.tsx +98 -0
- package/src/gui/components/atoms/Paper/Paper.stories.tsx +184 -0
- package/src/gui/components/atoms/Paper/Paper.tsx +15 -0
- package/src/gui/components/atoms/Section/Section.resolver.tsx +10 -0
- package/src/gui/components/atoms/Section/Section.stories.tsx +189 -0
- package/src/gui/components/atoms/Section/Section.tsx +76 -0
- package/src/gui/components/atoms/Section/Section.types.tsx +24 -0
- package/src/gui/components/atoms/Stack/Stack.resolver.tsx +94 -0
- package/src/gui/components/atoms/Stack/Stack.stories.tsx +160 -0
- package/src/gui/components/atoms/Stack/Stack.tsx +15 -0
- package/src/gui/components/atoms/Surface/Surface.resolver.tsx +37 -0
- package/src/gui/components/atoms/Surface/Surface.tsx +49 -0
- package/src/gui/components/atoms/Surface/Surface.types.ts +20 -0
- package/src/gui/components/atoms/Switch/Switch.resolver.tsx +53 -0
- package/src/gui/components/atoms/Switch/Switch.stories.tsx +236 -0
- package/src/gui/components/atoms/Switch/Switch.tsx +22 -0
- package/src/gui/components/atoms/TextField/TextField.stories.tsx +28 -0
- package/src/gui/components/atoms/TextField/TextField.tsx +15 -0
- package/src/gui/components/atoms/Toolbar/Toolbar.resolver.tsx +60 -0
- package/src/gui/components/atoms/Toolbar/Toolbar.stories.tsx +155 -0
- package/src/gui/components/atoms/Toolbar/Toolbar.tsx +16 -0
- package/src/gui/components/atoms/Tooltip/Tooltip.resolver.tsx +142 -0
- package/src/gui/components/atoms/Tooltip/Tooltip.stories.tsx +117 -0
- package/src/gui/components/atoms/Tooltip/Tooltip.tsx +70 -0
- package/src/gui/components/atoms/Typography/Typography.resolver.tsx +158 -0
- package/src/gui/components/atoms/Typography/Typography.stories.tsx +222 -0
- package/src/gui/components/atoms/Typography/Typography.tsx +27 -0
- package/src/gui/components/atoms.tsx +138 -0
- package/src/gui/components/molecules/Dialog/Dialog.stories.tsx +18 -0
- package/src/gui/components/molecules/Dialog/Dialog.tsx +5 -0
- package/src/gui/components/molecules/HeroSection/HeroSection.stories.tsx +141 -0
- package/src/gui/components/molecules/HeroSection/HeroSection.tsx +152 -0
- package/src/gui/components/molecules/HeroSection/HeroSection.types.tsx +18 -0
- package/src/gui/components/molecules/ModalBox/ModalBox.resolver.tsx +38 -0
- package/src/gui/components/molecules/ModalBox/ModalBox.stories.tsx +82 -0
- package/src/gui/components/molecules/ModalBox/ModalBox.tsx +106 -0
- package/src/gui/components/molecules/ModalBox/ModalBox.types.ts +29 -0
- package/src/gui/components/molecules/Page/Page.stories.tsx +135 -0
- package/src/gui/components/molecules/Page/Page.tsx +94 -0
- package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.resolver.tsx +58 -0
- package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.stories.tsx +133 -0
- package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.tsx +101 -0
- package/src/gui/components/molecules/Theme/ThemeModeToggle/ThemeModeToggle.types.ts +29 -0
- package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.resolver.tsx +15 -0
- package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.stories.tsx +88 -0
- package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.tsx +167 -0
- package/src/gui/components/molecules/Theme/ThemesCatalog/ThemesCatalog.types.ts +34 -0
- package/src/gui/components/organism/ChatGPTInterface/ChatGPTInterface.stories.tsx +17 -0
- package/src/gui/components/organism/ChatGPTInterface/ChatGPTInterface.tsx +71 -0
- package/src/gui/components/organism/RootDomain/RootDomain.stories.tsx +31 -0
- package/src/gui/components/organism/RootDomain/RootDomain.tsx +100 -0
- package/src/gui/components/organism/RootDomain/staticServices.ts +66 -0
- package/src/gui/components/window/Nodes/node.ts +0 -0
- package/src/gui/components/window/code/block/node.tsx +0 -0
- package/src/gui/components/window/code/hugging.face.api.ts +11 -0
- package/src/gui/components/window/connectors/index.ts +19 -0
- package/src/gui/components/window/window.stories.tsx +20 -0
- package/src/gui/components/window/window.tsx +633 -0
- package/src/gui/contexts/InsetsContext.tsx +38 -0
- package/src/gui/contexts/LeftSidebarContext.tsx +20 -0
- package/src/gui/contexts/RightSidebarContext.tsx +25 -0
- package/src/gui/contexts/ThemeContext.ts +34 -0
- package/src/gui/contexts/index.ts +4 -0
- package/src/gui/hooks/index.ts +11 -0
- package/src/gui/hooks/resolveColorToken.ts +39 -0
- package/src/gui/hooks/useCodeGen.ts +12 -0
- package/src/gui/hooks/useGuiMediaQuery.ts +18 -0
- package/src/gui/hooks/useGuiTheme.ts +18 -0
- package/src/gui/hooks/useInsets.ts +26 -0
- package/src/gui/hooks/useIsMobile.ts +13 -0
- package/src/gui/hooks/useIsTouchDevice.ts +25 -0
- package/src/gui/hooks/useLeftSidebar.ts +10 -0
- package/src/gui/hooks/useRightSidebar.ts +12 -0
- package/src/gui/hooks/useViewportKey.ts +19 -0
- package/src/gui/hooks/useViewportProp.ts +17 -0
- package/src/gui/me/Logic.tsx +31 -0
- package/src/gui/me/Me.stories.tsx +8 -0
- package/src/gui/me/Me.tsx +197 -0
- package/src/gui/me/fundamentals/verbs/verbs.tsx +94 -0
- package/src/gui/me/modificators/Adjectives.ts +0 -0
- package/src/gui/me/modificators/Adverbs.ts +0 -0
- package/src/gui/me/modificators/Complements.ts +27 -0
- package/src/gui/me/utils/Context.tsx +14 -0
- package/src/gui/me/utils/hooks/useMe.js +37 -0
- package/src/gui/utils/nodeID.ts +11 -0
- package/src/registry/GuiRegistry.ts +19 -0
- package/src/registry/factory.ts +12 -0
- package/src/registry/index.ts +3 -0
- package/src/registry/types.ts +6 -0
- package/src/stories/01.Home.mdx +22 -0
- package/src/stories/02.Understanding.This.GUI.mdx +149 -0
- package/src/stories/Theme/Palette.stories.tsx +86 -0
- package/src/stories/Theme/ThemeViewer.stories.tsx +91 -0
- package/src/stories/Theme/Typography.stories.jsx +211 -0
- package/src/types/gui.d.ts +67 -0
- package/src/types/theme.d.ts +191 -0
- package/src/types/viewport.ts +132 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import Grid from './Grid';
|
|
3
|
+
import Box from '@/gui/components/atoms/Box/Box';
|
|
4
|
+
|
|
5
|
+
// ======================= Meta =======================
|
|
6
|
+
const meta: Meta<typeof Grid> = {
|
|
7
|
+
title: 'Atoms/Containers/Grid',
|
|
8
|
+
component: Grid,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
decorators: [
|
|
11
|
+
(Story) => (
|
|
12
|
+
<div style={{ padding: 0, minHeight: 240 }}>
|
|
13
|
+
<Story />
|
|
14
|
+
</div>
|
|
15
|
+
),
|
|
16
|
+
],
|
|
17
|
+
parameters: {
|
|
18
|
+
docs: {
|
|
19
|
+
description: {
|
|
20
|
+
component: `
|
|
21
|
+
The **Grid** atom is a thin wrapper around MUI's \`Grid\` component. It keeps the original API and polymorphism but integrates with **This.GUI** tokens and allows declarative usage via the resolver.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
## Features
|
|
25
|
+
- Supports all MUI Grid props like \`container\`, \`item\`, \`spacing\`, \`xs\`, \`sm\`, \`md\`, etc.
|
|
26
|
+
- Fully themeable via **This.GUI** tokens and \`sx\`.
|
|
27
|
+
- Works both as a container and as an item.
|
|
28
|
+
- Can be described declaratively via JSON specs for resolvers.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
## Key Props
|
|
32
|
+
- \`container?: boolean\` — defines a grid container.
|
|
33
|
+
- \`item?: boolean\` — defines a grid item.
|
|
34
|
+
- \`spacing?: number | object\` — gap between items (when container).
|
|
35
|
+
- \`xs | sm | md | lg | xl?: number\` — responsive column sizes.
|
|
36
|
+
- \`sx?: object\` — granular styling.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
## Basic usage (React)
|
|
40
|
+
~~~tsx
|
|
41
|
+
import { Grid, Box } from '@/gui/atoms';
|
|
42
|
+
|
|
43
|
+
<Grid container spacing={2}>
|
|
44
|
+
<Grid item xs={6}>
|
|
45
|
+
<Box sx={{ backgroundColor: 'primary.main', p: 2, color: '#fff' }}>Item 1</Box>
|
|
46
|
+
</Grid>
|
|
47
|
+
<Grid item xs={6}>
|
|
48
|
+
<Box sx={{ backgroundColor: 'secondary.main', p: 2, color: '#fff' }}>Item 2</Box>
|
|
49
|
+
</Grid>
|
|
50
|
+
</Grid>
|
|
51
|
+
~~~
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
## Declarative JSON / Config usage
|
|
55
|
+
This GUI's **resolver** lets you describe a Grid via a config object:
|
|
56
|
+
|
|
57
|
+
~~~json
|
|
58
|
+
{
|
|
59
|
+
"type": "Grid",
|
|
60
|
+
"props": {
|
|
61
|
+
"container": true,
|
|
62
|
+
"spacing": 2,
|
|
63
|
+
"children": [
|
|
64
|
+
{
|
|
65
|
+
"type": "Grid",
|
|
66
|
+
"props": {
|
|
67
|
+
"item": true,
|
|
68
|
+
"xs": 6,
|
|
69
|
+
"children": {
|
|
70
|
+
"type": "Box",
|
|
71
|
+
"props": {
|
|
72
|
+
"sx": { "backgroundColor": "primary.main", "p": 2, "color": "#fff" },
|
|
73
|
+
"children": "Item 1"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"type": "Grid",
|
|
80
|
+
"props": {
|
|
81
|
+
"item": true,
|
|
82
|
+
"xs": 6,
|
|
83
|
+
"children": {
|
|
84
|
+
"type": "Box",
|
|
85
|
+
"props": {
|
|
86
|
+
"sx": { "backgroundColor": "secondary.main", "p": 2, "color": "#fff" },
|
|
87
|
+
"children": "Item 2"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
~~~
|
|
96
|
+
|
|
97
|
+
> The resolver maps this spec to real React elements, preserving polymorphism and \`sx\` styling.
|
|
98
|
+
`,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
export default meta;
|
|
104
|
+
|
|
105
|
+
type Story = StoryObj<typeof Grid>;
|
|
106
|
+
|
|
107
|
+
// ======================= Stories =======================
|
|
108
|
+
export const Playground: Story = {
|
|
109
|
+
render: (args) => (
|
|
110
|
+
<Grid {...args} container spacing={2}>
|
|
111
|
+
<Grid item xs={6}>
|
|
112
|
+
<Box sx={{ backgroundColor: 'primary.main', p: 2, color: '#fff' }}>Item 1</Box>
|
|
113
|
+
</Grid>
|
|
114
|
+
<Grid item xs={6}>
|
|
115
|
+
<Box sx={{ backgroundColor: 'secondary.main', p: 2, color: '#fff' }}>Item 2</Box>
|
|
116
|
+
</Grid>
|
|
117
|
+
</Grid>
|
|
118
|
+
),
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const ResponsiveGrid: Story = {
|
|
122
|
+
render: (args) => (
|
|
123
|
+
<Grid {...args} container spacing={2}>
|
|
124
|
+
<Grid item xs={12} sm={6} md={4}>
|
|
125
|
+
<Box sx={{ backgroundColor: 'info.main', p: 2, color: '#fff' }}>xs=12 sm=6 md=4</Box>
|
|
126
|
+
</Grid>
|
|
127
|
+
<Grid item xs={12} sm={6} md={4}>
|
|
128
|
+
<Box sx={{ backgroundColor: 'success.main', p: 2, color: '#fff' }}>xs=12 sm=6 md=4</Box>
|
|
129
|
+
</Grid>
|
|
130
|
+
<Grid item xs={12} sm={12} md={4}>
|
|
131
|
+
<Box sx={{ backgroundColor: 'warning.main', p: 2, color: '#fff' }}>xs=12 sm=12 md=4</Box>
|
|
132
|
+
</Grid>
|
|
133
|
+
</Grid>
|
|
134
|
+
),
|
|
135
|
+
name: 'Responsive Grid Layout',
|
|
136
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// File: Grid.tsx
|
|
2
|
+
import MuiGrid from '@mui/material/Grid';
|
|
3
|
+
import type { GridProps } from './Grid.types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This.GUI — Grid
|
|
7
|
+
* Wrapper around MUI’s Grid that preserves props & typing.
|
|
8
|
+
*
|
|
9
|
+
* Purpose:
|
|
10
|
+
* - Consistent namespace integration (This.GUI).
|
|
11
|
+
* - Supports full MUI Grid props including `sx`, `container`, `item`, etc.
|
|
12
|
+
*/
|
|
13
|
+
const Grid = MuiGrid;
|
|
14
|
+
(Grid as any).displayName = 'Gui.Grid';
|
|
15
|
+
export default Grid;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import MuiGrid from '@mui/material/Grid';
|
|
2
|
+
import type { GridProps as MuiGridProps } from '@mui/material/Grid';
|
|
3
|
+
export type GridProps = React.ComponentProps<typeof MuiGrid> & MuiGridProps;
|
|
4
|
+
|
|
5
|
+
export type GridResolverSpec = {
|
|
6
|
+
type: 'Grid';
|
|
7
|
+
props?: GridProps; // or GridProps if you want to alias it
|
|
8
|
+
};
|
|
9
|
+
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// src/gui/atoms/IconButton/IconButton.resolver.tsx
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import IconButton from './IconButton';
|
|
4
|
+
import Icon from '@/gui/Theme/Icon/Icon';
|
|
5
|
+
import Link from '@/gui/components/atoms/Link/Link';
|
|
6
|
+
import type { RegistryEntry, ResolveCtx } from '@/registry/types';
|
|
7
|
+
import type { SxProps, Theme } from '@mui/material/styles';
|
|
8
|
+
import { ensureNodeId } from '@/gui/utils/nodeID';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Declarative resolver for IconButton
|
|
12
|
+
* -----------------------------------
|
|
13
|
+
* - Forwards all MUI IconButton props faithfully.
|
|
14
|
+
* - Supports polymorphism via `component` / `as`.
|
|
15
|
+
* - Adds sugar:
|
|
16
|
+
* • `icon` string → rendered through our Icon registry (mui:/lucide: tokens), normalized to lowercase.
|
|
17
|
+
* • Routing helpers: if `to` w/o `component` → uses This.GUI `Link`; if `href`/`external` → uses anchor with safe target/rel.
|
|
18
|
+
* - Provides granular styling via `sx` (root) and optional `iconSx`.
|
|
19
|
+
*
|
|
20
|
+
* A11y note: when rendering only an icon (no visible text), pass an `aria-label`.
|
|
21
|
+
*/
|
|
22
|
+
export type IconButtonSpec = {
|
|
23
|
+
type: 'IconButton';
|
|
24
|
+
props?: {
|
|
25
|
+
children?: React.ReactNode;
|
|
26
|
+
|
|
27
|
+
// Polymorphism
|
|
28
|
+
component?: any;
|
|
29
|
+
as?: any; // alias for component
|
|
30
|
+
|
|
31
|
+
// Routing sugar
|
|
32
|
+
to?: string;
|
|
33
|
+
href?: string;
|
|
34
|
+
external?: boolean;
|
|
35
|
+
target?: React.HTMLAttributeAnchorTarget;
|
|
36
|
+
rel?: string;
|
|
37
|
+
|
|
38
|
+
// Sugar: icon may be a token or a node
|
|
39
|
+
icon?: string | React.ReactNode;
|
|
40
|
+
iconProps?: Record<string, any>;
|
|
41
|
+
|
|
42
|
+
// MUI props passthrough (subset; others go via index signature)
|
|
43
|
+
color?:
|
|
44
|
+
| 'inherit'
|
|
45
|
+
| 'default'
|
|
46
|
+
| 'primary'
|
|
47
|
+
| 'secondary'
|
|
48
|
+
| 'success'
|
|
49
|
+
| 'error'
|
|
50
|
+
| 'info'
|
|
51
|
+
| 'warning';
|
|
52
|
+
size?: 'small' | 'medium' | 'large';
|
|
53
|
+
edge?: 'start' | 'end' | false;
|
|
54
|
+
disabled?: boolean;
|
|
55
|
+
|
|
56
|
+
// Styling
|
|
57
|
+
sx?: SxProps<Theme>;
|
|
58
|
+
className?: string;
|
|
59
|
+
id?: string;
|
|
60
|
+
'data-testid'?: string;
|
|
61
|
+
|
|
62
|
+
// Arbitrary passthrough (MUI will validate)
|
|
63
|
+
[key: string]: any;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const IconButtonResolver: RegistryEntry = {
|
|
68
|
+
type: 'IconButton',
|
|
69
|
+
resolve(spec: IconButtonSpec, _ctx?: ResolveCtx) {
|
|
70
|
+
const p = spec.props ?? {};
|
|
71
|
+
const nodeId = ensureNodeId('iconbutton', p.id as string | undefined);
|
|
72
|
+
|
|
73
|
+
// Decide polymorphic target
|
|
74
|
+
const component =
|
|
75
|
+
p.component ??
|
|
76
|
+
p.as ??
|
|
77
|
+
(p.to ? Link : (p.href || p.external) ? 'a' : undefined);
|
|
78
|
+
|
|
79
|
+
// Routing / anchor props
|
|
80
|
+
const routingProps =
|
|
81
|
+
component === 'a' || p.external
|
|
82
|
+
? {
|
|
83
|
+
href: p.href,
|
|
84
|
+
target: p.target ?? (p.external ? '_blank' : undefined),
|
|
85
|
+
rel: p.rel ?? (p.external ? 'noopener noreferrer' : undefined),
|
|
86
|
+
}
|
|
87
|
+
: component === Link || (p.to && !p.component)
|
|
88
|
+
? { to: p.to }
|
|
89
|
+
: {};
|
|
90
|
+
|
|
91
|
+
// Prepare children (icon sugar)
|
|
92
|
+
const { children, icon, iconProps } = p;
|
|
93
|
+
const normalizedToken =
|
|
94
|
+
typeof icon === 'string' ? icon.trim() : null;
|
|
95
|
+
|
|
96
|
+
const effectiveChildren =
|
|
97
|
+
children ??
|
|
98
|
+
(normalizedToken ? (
|
|
99
|
+
<Icon
|
|
100
|
+
name={normalizedToken}
|
|
101
|
+
{...(iconProps || {})}
|
|
102
|
+
/>
|
|
103
|
+
) : (
|
|
104
|
+
icon ?? null
|
|
105
|
+
));
|
|
106
|
+
|
|
107
|
+
// Collect & strip resolver-only keys so they don't leak to DOM
|
|
108
|
+
const {
|
|
109
|
+
as: _as,
|
|
110
|
+
to: _to,
|
|
111
|
+
href: _href,
|
|
112
|
+
external: _external,
|
|
113
|
+
target: _target,
|
|
114
|
+
rel: _rel,
|
|
115
|
+
icon: _icon,
|
|
116
|
+
iconSx: _iconSx,
|
|
117
|
+
iconProps: _iconProps,
|
|
118
|
+
...rest
|
|
119
|
+
} = p;
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<IconButton
|
|
123
|
+
{...(component ? { component } : {})}
|
|
124
|
+
sx={p.sx}
|
|
125
|
+
className={p.className}
|
|
126
|
+
id={nodeId}
|
|
127
|
+
data-testid={p['data-testid']}
|
|
128
|
+
{...routingProps}
|
|
129
|
+
{...rest}
|
|
130
|
+
>
|
|
131
|
+
{effectiveChildren}
|
|
132
|
+
</IconButton>
|
|
133
|
+
);
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export default IconButtonResolver;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import IconButton from './IconButton';
|
|
3
|
+
import Icon from '@/gui/Theme/Icon/Icon';
|
|
4
|
+
const meta: Meta<typeof IconButton> = {
|
|
5
|
+
title: 'Atoms/Forms & Inputs/IconButton',
|
|
6
|
+
component: IconButton,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
decorators: [
|
|
9
|
+
(Story) => (
|
|
10
|
+
<div style={{ padding: 16, minHeight: 200 }}>
|
|
11
|
+
<Story />
|
|
12
|
+
</div>
|
|
13
|
+
),
|
|
14
|
+
],
|
|
15
|
+
parameters: {
|
|
16
|
+
docs: {
|
|
17
|
+
description: {
|
|
18
|
+
component: `
|
|
19
|
+
The **IconButton** atom is a thin wrapper around MUI's \`MuiIconButton\`, staying faithful to its API and polymorphism (\`component\`).
|
|
20
|
+
|
|
21
|
+
In **declarative** mode (resolver), you can pass an \`icon\` token (e.g., \`"lucide:menu"\`, \`"mui:Close"\`) and it will render through the Icon registry. You can also style the icon with \`iconSx\` while using \`sx\` for the button root.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
## React usage
|
|
25
|
+
~~~jsx
|
|
26
|
+
<IconButton color="primary" size="medium" aria-label="open menu">
|
|
27
|
+
<Icon name="lucide:menu" />
|
|
28
|
+
</IconButton>
|
|
29
|
+
~~~
|
|
30
|
+
|
|
31
|
+
## Declarative JSON / Resolver
|
|
32
|
+
~~~json
|
|
33
|
+
{
|
|
34
|
+
"type": "IconButton",
|
|
35
|
+
"props": {
|
|
36
|
+
"color": "primary",
|
|
37
|
+
"size": "medium",
|
|
38
|
+
"icon": "lucide:menu",
|
|
39
|
+
"sx": { "border": "1px solid", "borderColor": "divider" },
|
|
40
|
+
"iconSx": { "opacity": 0.9 }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
~~~
|
|
44
|
+
`,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
controls: {
|
|
48
|
+
exclude: ['component', 'children'],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
argTypes: {
|
|
52
|
+
color: {
|
|
53
|
+
control: { type: 'select' },
|
|
54
|
+
options: ['inherit', 'default', 'primary', 'secondary', 'success', 'error', 'info', 'warning'],
|
|
55
|
+
},
|
|
56
|
+
size: {
|
|
57
|
+
control: { type: 'radio' },
|
|
58
|
+
options: ['small', 'medium', 'large'],
|
|
59
|
+
},
|
|
60
|
+
edge: {
|
|
61
|
+
control: { type: 'radio' },
|
|
62
|
+
options: ['start', 'end', false],
|
|
63
|
+
},
|
|
64
|
+
disabled: { control: 'boolean' },
|
|
65
|
+
sx: { control: 'object' },
|
|
66
|
+
},
|
|
67
|
+
args: {
|
|
68
|
+
color: 'default',
|
|
69
|
+
size: 'medium',
|
|
70
|
+
edge: false,
|
|
71
|
+
disabled: false,
|
|
72
|
+
sx: {},
|
|
73
|
+
children: undefined,
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export default meta;
|
|
78
|
+
type Story = StoryObj<typeof IconButton>;
|
|
79
|
+
export const Playground: Story = {
|
|
80
|
+
render: (args) => (
|
|
81
|
+
<IconButton {...args} aria-label="menu">
|
|
82
|
+
<Icon name="lucide:menu" />
|
|
83
|
+
</IconButton>
|
|
84
|
+
),
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const Colors: Story = {
|
|
88
|
+
render: () => (
|
|
89
|
+
<div style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
|
|
90
|
+
{(['default', 'primary', 'secondary', 'success', 'info', 'warning', 'error'] as const).map((c) => (
|
|
91
|
+
<IconButton key={c} color={c} aria-label={c}>
|
|
92
|
+
<Icon name="mui:Favorite" />
|
|
93
|
+
</IconButton>
|
|
94
|
+
))}
|
|
95
|
+
</div>
|
|
96
|
+
),
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const Sizes: Story = {
|
|
100
|
+
render: () => (
|
|
101
|
+
<div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
|
|
102
|
+
<IconButton size="small" aria-label="small">
|
|
103
|
+
<Icon name="lucide:bell" />
|
|
104
|
+
</IconButton>
|
|
105
|
+
<IconButton size="medium" aria-label="medium">
|
|
106
|
+
<Icon name="lucide:bell" />
|
|
107
|
+
</IconButton>
|
|
108
|
+
<IconButton size="large" aria-label="large">
|
|
109
|
+
<Icon name="lucide:bell" />
|
|
110
|
+
</IconButton>
|
|
111
|
+
</div>
|
|
112
|
+
),
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export const WithEdge: Story = {
|
|
116
|
+
render: () => (
|
|
117
|
+
<div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
|
|
118
|
+
<IconButton edge="start" aria-label="start">
|
|
119
|
+
<Icon name="lucide:chevron-left" />
|
|
120
|
+
</IconButton>
|
|
121
|
+
<IconButton edge="end" aria-label="end">
|
|
122
|
+
<Icon name="lucide:chevron-right" />
|
|
123
|
+
</IconButton>
|
|
124
|
+
</div>
|
|
125
|
+
),
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const WithSx: Story = {
|
|
129
|
+
render: () => (
|
|
130
|
+
<IconButton sx={{ border: '1px solid', borderColor: 'divider' }} aria-label="styled">
|
|
131
|
+
<Icon name="mui:Close" />
|
|
132
|
+
</IconButton>
|
|
133
|
+
),
|
|
134
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This.GUI — IconButton
|
|
3
|
+
* ----------------------------------------
|
|
4
|
+
* Thin wrapper around MUI’s IconButton.
|
|
5
|
+
*
|
|
6
|
+
* Fidelity:
|
|
7
|
+
* - Directly re-exports MUI’s IconButton so all typing and props remain intact.
|
|
8
|
+
* - Preserves polymorphism (`component` prop) via OverridableComponent.
|
|
9
|
+
* - Supports granular styling via the standard `sx` prop (MUI System).
|
|
10
|
+
*
|
|
11
|
+
* Why wrap?
|
|
12
|
+
* - Consistency with This.GUI’s atom pattern (every MUI primitive wrapped).
|
|
13
|
+
* - Provides a clean declarative/resolver entry point.
|
|
14
|
+
*/
|
|
15
|
+
import * as React from 'react';
|
|
16
|
+
import MuiIconButton from '@mui/material/IconButton';
|
|
17
|
+
import type { OverridableComponent } from '@mui/material/OverridableComponent';
|
|
18
|
+
import type { IconButtonTypeMap } from '@mui/material/IconButton';
|
|
19
|
+
const IconButton = MuiIconButton as OverridableComponent<IconButtonTypeMap<{}, 'button'>>;
|
|
20
|
+
export type IconButtonProps = React.ComponentProps<typeof IconButton>;
|
|
21
|
+
(IconButton as any).displayName = 'Gui.IconButton';
|
|
22
|
+
export default IconButton;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// src/gui/atoms/Link/Link.resolver.tsx
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import type { RegistryEntry } from '@/registry/types';
|
|
4
|
+
import Link, { LinkProps as GuiLinkProps } from './Link';
|
|
5
|
+
import type { SxProps, Theme } from '@mui/material/styles';
|
|
6
|
+
import { ensureNodeId } from '@/gui/utils/nodeID';
|
|
7
|
+
import { useInRouterContext } from 'react-router-dom';
|
|
8
|
+
|
|
9
|
+
/** Declarative spec for Link (JSON-friendly) */
|
|
10
|
+
type LinkSpec = {
|
|
11
|
+
type: 'Link';
|
|
12
|
+
props?: {
|
|
13
|
+
label?: React.ReactNode; // convenience: text content
|
|
14
|
+
children?: React.ReactNode; // explicit children (wins over label)
|
|
15
|
+
href?: string; // external
|
|
16
|
+
to?: string; // internal (react-router)
|
|
17
|
+
external?: boolean; // force anchor + target/rel
|
|
18
|
+
underline?: 'none' | 'hover' | 'always';
|
|
19
|
+
// pass-through styling/attrs
|
|
20
|
+
sx?: SxProps<Theme>;
|
|
21
|
+
className?: string;
|
|
22
|
+
id?: string;
|
|
23
|
+
target?: string;
|
|
24
|
+
rel?: string;
|
|
25
|
+
color?: GuiLinkProps['color'];
|
|
26
|
+
variant?: GuiLinkProps['variant'];
|
|
27
|
+
// ...cualquier otro prop permitido por tu Link
|
|
28
|
+
'data-testid'?: string;
|
|
29
|
+
ariaLabel?: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const LinkResolver: RegistryEntry = {
|
|
34
|
+
type: 'Link',
|
|
35
|
+
resolve(spec: LinkSpec) {
|
|
36
|
+
const p = spec.props ?? {};
|
|
37
|
+
const nodeId = ensureNodeId('link', p.id as string | undefined);
|
|
38
|
+
const hasRouter = useInRouterContext();
|
|
39
|
+
|
|
40
|
+
// Routing / destino
|
|
41
|
+
const routingProps: Partial<GuiLinkProps> =
|
|
42
|
+
p.external
|
|
43
|
+
? {
|
|
44
|
+
href: p.href,
|
|
45
|
+
...(p.target ? { target: p.target } : { target: '_blank' }),
|
|
46
|
+
...(p.rel ? { rel: p.rel } : { rel: 'noopener noreferrer' }),
|
|
47
|
+
}
|
|
48
|
+
: p.to && hasRouter
|
|
49
|
+
? { to: p.to }
|
|
50
|
+
: p.href
|
|
51
|
+
? { href: p.href }
|
|
52
|
+
: {};
|
|
53
|
+
|
|
54
|
+
const children = p.children ?? p.label ?? null;
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<Link
|
|
58
|
+
underline={p.underline ?? 'hover'}
|
|
59
|
+
color={p.color}
|
|
60
|
+
variant={p.variant}
|
|
61
|
+
sx={p.sx}
|
|
62
|
+
className={p.className}
|
|
63
|
+
id={nodeId}
|
|
64
|
+
data-testid={p['data-testid']}
|
|
65
|
+
{...(p.ariaLabel ? { 'aria-label': p.ariaLabel } : {})}
|
|
66
|
+
{...routingProps}
|
|
67
|
+
>
|
|
68
|
+
{children}
|
|
69
|
+
</Link>
|
|
70
|
+
);
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export default LinkResolver;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Link, Button } from '@/gui/components/atoms';
|
|
3
|
+
// ======================= Meta =======================
|
|
4
|
+
const meta: Meta<typeof Link> = {
|
|
5
|
+
title: 'Atoms/Navigation/Link',
|
|
6
|
+
component: Link,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
decorators: [
|
|
9
|
+
(Story) => (
|
|
10
|
+
<div style={{ padding: 16, minHeight: 240 }}>
|
|
11
|
+
<Story />
|
|
12
|
+
</div>
|
|
13
|
+
),
|
|
14
|
+
],
|
|
15
|
+
parameters: {
|
|
16
|
+
docs: {
|
|
17
|
+
description: {
|
|
18
|
+
component: `
|
|
19
|
+
The **Link** primitive is a thin wrapper over MUI's \`MuiLink\` that supports **both** external links (\`href\`) and internal routing (\`to\`) using **react-router-dom**. It integrates with **This.GUI** theming via \`GuiProvider\`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
## Features
|
|
23
|
+
- External links with \`href\` (renders an anchor).
|
|
24
|
+
- Internal navigation with \`to\` (renders a RouterLink under the hood).
|
|
25
|
+
- Works seamlessly as a child or as a render target for other primitives (e.g. \`<Button component={Link} to="/docs"/>\`).
|
|
26
|
+
- Inherits typography and color from the theme tokens.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
## Key Props
|
|
30
|
+
- \`href?: string\` — external URL.
|
|
31
|
+
- \`to?: string | LocationDescriptor\` — internal route (react-router-dom).
|
|
32
|
+
- \`underline?: 'none' | 'hover' | 'always'\` — underline behavior.
|
|
33
|
+
- \`color?: 'primary' | 'secondary' | 'inherit' | 'textPrimary' | 'textSecondary' | 'error' | 'info' | 'success' | 'warning'\`.
|
|
34
|
+
|
|
35
|
+
> Note: \`to\` and \`href\` are demonstrated in dedicated stories rather than Storybook controls.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
## Basic Usage
|
|
39
|
+
~~~jsx
|
|
40
|
+
import { Link } from '@/gui/primitives';
|
|
41
|
+
|
|
42
|
+
<Link href="https://neurons.me" target="_blank" rel="noreferrer">Visit neurons.me</Link>
|
|
43
|
+
~~~
|
|
44
|
+
|
|
45
|
+
## Internal Routing
|
|
46
|
+
~~~jsx
|
|
47
|
+
import { Link } from '@/gui/primitives';
|
|
48
|
+
|
|
49
|
+
<Link to="/docs">Go to docs</Link>
|
|
50
|
+
~~~
|
|
51
|
+
|
|
52
|
+
## As render target for Button
|
|
53
|
+
~~~jsx
|
|
54
|
+
import { Button, Link } from '@/gui/primitives';
|
|
55
|
+
|
|
56
|
+
<Button component={Link} to="/docs">Docs</Button>
|
|
57
|
+
~~~
|
|
58
|
+
|
|
59
|
+
## Declarative JSON / Config usage
|
|
60
|
+
~~~json
|
|
61
|
+
{
|
|
62
|
+
"type": "Link",
|
|
63
|
+
"props": {
|
|
64
|
+
"to": "/docs",
|
|
65
|
+
"children": "Go to docs"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
~~~
|
|
69
|
+
|
|
70
|
+
Another example with an external URL:
|
|
71
|
+
~~~json
|
|
72
|
+
{
|
|
73
|
+
"type": "Link",
|
|
74
|
+
"props": {
|
|
75
|
+
"href": "https://neurons.me",
|
|
76
|
+
"target": "_blank",
|
|
77
|
+
"rel": "noreferrer",
|
|
78
|
+
"children": "Visit neurons.me"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
~~~
|
|
82
|
+
`,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
argTypes: {
|
|
87
|
+
underline: {
|
|
88
|
+
control: { type: 'radio' },
|
|
89
|
+
options: ['none', 'hover', 'always'],
|
|
90
|
+
},
|
|
91
|
+
color: {
|
|
92
|
+
control: { type: 'select' },
|
|
93
|
+
options: ['primary', 'secondary', 'inherit', 'textPrimary', 'textSecondary', 'error', 'info', 'success', 'warning'],
|
|
94
|
+
},
|
|
95
|
+
// Do not expose component/to/href as controls — they are shown in dedicated stories
|
|
96
|
+
component: { table: { disable: true } },
|
|
97
|
+
},
|
|
98
|
+
args: {
|
|
99
|
+
underline: 'hover',
|
|
100
|
+
color: 'primary',
|
|
101
|
+
children: 'Example link',
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
export default meta;
|
|
105
|
+
|
|
106
|
+
type Story = StoryObj<typeof Link>;
|
|
107
|
+
|
|
108
|
+
// ======================= Stories =======================
|
|
109
|
+
export const Playground: Story = {};
|
|
110
|
+
|
|
111
|
+
export const ExternalHref: Story = {
|
|
112
|
+
name: 'External (href)',
|
|
113
|
+
render: () => (
|
|
114
|
+
<Link href="https://neurons.me" target="_blank" rel="noreferrer">
|
|
115
|
+
Visit neurons.me
|
|
116
|
+
</Link>
|
|
117
|
+
),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export const InternalTo: Story = {
|
|
121
|
+
name: 'Internal (to)',
|
|
122
|
+
render: () => <Link to="/docs">Go to docs</Link>,
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export const Colors: Story = {
|
|
126
|
+
render: (args) => {
|
|
127
|
+
const colors: Array<any> = ['primary', 'secondary', 'success', 'info', 'warning', 'error'];
|
|
128
|
+
return (
|
|
129
|
+
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
|
|
130
|
+
{colors.map((c) => (
|
|
131
|
+
<Link key={c} {...args} color={c} href="#">
|
|
132
|
+
{c[0].toUpperCase() + c.slice(1)}
|
|
133
|
+
</Link>
|
|
134
|
+
))}
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const UnderlineVariants: Story = {
|
|
141
|
+
render: (args) => (
|
|
142
|
+
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
|
|
143
|
+
<Link {...args} underline="none" href="#">None</Link>
|
|
144
|
+
<Link {...args} underline="hover" href="#">Hover</Link>
|
|
145
|
+
<Link {...args} underline="always" href="#">Always</Link>
|
|
146
|
+
</div>
|
|
147
|
+
),
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export const AsButtonTarget: Story = {
|
|
151
|
+
name: 'As Button component',
|
|
152
|
+
render: () => (
|
|
153
|
+
<Button component={Link} to="/docs">
|
|
154
|
+
Docs via Link
|
|
155
|
+
</Button>
|
|
156
|
+
),
|
|
157
|
+
};
|