From cf068ce4ec208299e18664e8c02bfad24bb7f9fe Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 10 May 2026 09:42:57 +0200 Subject: [PATCH] chore: initialize @limitless/ui git repo + add AppShell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This brings the long-untracked @limitless/ui source tree under version control. Until now /srv/k8s/templates/limitless-ui has been a plain file: dependency consumed by gscChronos / gscCRM / gscAdmin, with copies scattered across web/gsc{Portal,WWW,Aether,Register}/ and apps/gsc{Meet,Share}/. None were git-tracked. Treating /srv/k8s/templates/limitless-ui as the canonical going forward; secondary copies should be replaced with this version in their consumers' Dockerfiles when they next get touched. Changes in this initial commit beyond the snapshot: - Add src/layout/AppShell.tsx — runtime-loaded chrome (header, sidebar, footer) backed by gsc-shell-api. Public surface: AppShell, ShellProvider, useShell, ShellConfig types Framework-agnostic (no Next.js dep). Apps pass appKey + apiUrl + getToken; AppShell composes the existing PageShell / Navbar / Sidebar / Footer primitives with API data. - Re-export AppShell from src/index.ts. - Fix build script: `tsc -p tsconfig.json --noEmit false`. The bare `tsc` command was a no-op because tsconfig.json sets noEmit:true for typecheck speed. Existing dist/ only existed because of an earlier emit; clean rebuilds were silently broken. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 11 + .next/cache/.previewinfo | 1 + .next/cache/.rscinfo | 1 + .next/diagnostics/build-diagnostics.json | 6 + .next/diagnostics/framework.json | 1 + .next/package.json | 1 + .next/trace | 1 + .next/trace-build | 1 + .next/turbopack | 0 .next/types/routes.d.ts | 64 + .next/types/validator.ts | 112 + README.md | 164 + docs/MIGRATION_STATUS.md | 26 + next-env.d.ts | 6 + package-lock.json | 1063 ++ package.json | 62 + scripts/postbuild.cjs | 66 + src/components/Accordion.tsx | 61 + src/components/AdvancedSelect.tsx | 31 + src/components/Alert.tsx | 49 + src/components/Badge.tsx | 26 + src/components/Breadcrumbs.tsx | 33 + src/components/Button.tsx | 42 + src/components/Calendar.tsx | 781 ++ src/components/Card.tsx | 91 + src/components/Carousel.tsx | 213 + src/components/Collapse.tsx | 19 + src/components/ColorPicker.tsx | 23 + src/components/ContextMenu.tsx | 376 + src/components/DataTable.tsx | 106 + src/components/DatePicker.tsx | 12 + src/components/Dropdown.tsx | 72 + src/components/DualListBox.tsx | 85 + src/components/Embed.tsx | 440 + src/components/FAB.tsx | 297 + src/components/FileUpload.tsx | 472 + src/components/Form.tsx | 164 + src/components/Gallery.tsx | 484 + src/components/IdleTimeout.tsx | 463 + src/components/ImageCropper.tsx | 442 + src/components/ListGroup.tsx | 61 + src/components/Media.tsx | 25 + src/components/Modal.tsx | 66 + src/components/Nav.tsx | 60 + src/components/Notification.tsx | 353 + src/components/Offcanvas.tsx | 208 + src/components/PageHeader.tsx | 100 + src/components/Pagination.tsx | 47 + src/components/Pills.tsx | 232 + src/components/Popover.tsx | 76 + src/components/Progress.tsx | 50 + src/components/ProgressStacked.tsx | 38 + src/components/Rating.tsx | 231 + src/components/Scrollspy.tsx | 52 + src/components/Slider.tsx | 518 + src/components/Sortable.tsx | 529 + src/components/Spinner.tsx | 130 + src/components/Stepper.tsx | 285 + src/components/SweetAlert.tsx | 360 + src/components/SyntaxHighlighter.tsx | 501 + src/components/Table.tsx | 31 + src/components/Tabs.tsx | 93 + src/components/TagInput.tsx | 460 + src/components/Timeline.tsx | 223 + src/components/Toast.tsx | 38 + src/components/Tooltip.tsx | 69 + src/components/TreeView.tsx | 344 + src/components/Widget.tsx | 577 + src/components/Widget/index.tsx | 835 ++ src/components/Wizard.tsx | 92 + src/genui/components/Message.tsx | 118 + src/genui/components/SearchResults.tsx | 285 + src/genui/components/index.ts | 8 + src/genui/content.tsx | 191 + src/genui/hooks/index.ts | 8 + src/genui/hooks/useGenUI.ts | 218 + src/genui/hooks/useWebMCP.ts | 100 + src/genui/index.ts | 20 + src/genui/types.ts | 219 + src/genui/webmcp/index.ts | 160 + src/genui/webmcp/schemas.ts | 189 + src/hooks/useDisclosure.ts | 11 + src/index.ts | 84 + src/layout/AppShell.tsx | 349 + src/layout/Footer.tsx | 76 + src/layout/Navbar.tsx | 177 + src/layout/PageShell.tsx | 73 + src/layout/Sidebar.tsx | 319 + src/pages/Auth.tsx | 973 ++ src/pages/Chat.tsx | 753 ++ src/pages/Error.tsx | 595 + src/pages/Invoice.tsx | 1010 ++ src/pages/Mail.tsx | 813 ++ src/pages/Search.tsx | 982 ++ src/pages/TaskManager.tsx | 927 ++ src/pages/UserProfile.tsx | 858 ++ src/pages/index.ts | 9 + src/server/crypto.ts | 135 + src/server/email.ts | 199 + src/server/index.ts | 19 + src/styles.css | 10715 ++++++++++++++++ src/theme/ThemeProvider.tsx | 52 + .../hooks/useAddressAutocomplete.ts | 296 + src/validation/hooks/useFieldValidation.ts | 190 + src/validation/hooks/useValidation.ts | 408 + src/validation/index.ts | 88 + src/validation/server/index.ts | 26 + src/validation/server/sanitize.ts | 212 + src/validation/server/validateFormData.ts | 101 + src/validation/types.ts | 160 + src/validation/validators/address.ts | 370 + src/validation/validators/format.ts | 526 + src/validation/validators/index.ts | 56 + src/validation/validators/security.ts | 379 + tsconfig.json | 33 + 115 files changed, 36542 insertions(+) create mode 100644 .gitignore create mode 100644 .next/cache/.previewinfo create mode 100644 .next/cache/.rscinfo create mode 100644 .next/diagnostics/build-diagnostics.json create mode 100644 .next/diagnostics/framework.json create mode 100644 .next/package.json create mode 100644 .next/trace create mode 100644 .next/trace-build create mode 100644 .next/turbopack create mode 100644 .next/types/routes.d.ts create mode 100644 .next/types/validator.ts create mode 100644 README.md create mode 100644 docs/MIGRATION_STATUS.md create mode 100644 next-env.d.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 scripts/postbuild.cjs create mode 100644 src/components/Accordion.tsx create mode 100644 src/components/AdvancedSelect.tsx create mode 100644 src/components/Alert.tsx create mode 100644 src/components/Badge.tsx create mode 100644 src/components/Breadcrumbs.tsx create mode 100644 src/components/Button.tsx create mode 100644 src/components/Calendar.tsx create mode 100644 src/components/Card.tsx create mode 100644 src/components/Carousel.tsx create mode 100644 src/components/Collapse.tsx create mode 100644 src/components/ColorPicker.tsx create mode 100644 src/components/ContextMenu.tsx create mode 100644 src/components/DataTable.tsx create mode 100644 src/components/DatePicker.tsx create mode 100644 src/components/Dropdown.tsx create mode 100644 src/components/DualListBox.tsx create mode 100644 src/components/Embed.tsx create mode 100644 src/components/FAB.tsx create mode 100644 src/components/FileUpload.tsx create mode 100644 src/components/Form.tsx create mode 100644 src/components/Gallery.tsx create mode 100644 src/components/IdleTimeout.tsx create mode 100644 src/components/ImageCropper.tsx create mode 100644 src/components/ListGroup.tsx create mode 100644 src/components/Media.tsx create mode 100644 src/components/Modal.tsx create mode 100644 src/components/Nav.tsx create mode 100644 src/components/Notification.tsx create mode 100644 src/components/Offcanvas.tsx create mode 100644 src/components/PageHeader.tsx create mode 100644 src/components/Pagination.tsx create mode 100644 src/components/Pills.tsx create mode 100644 src/components/Popover.tsx create mode 100644 src/components/Progress.tsx create mode 100644 src/components/ProgressStacked.tsx create mode 100644 src/components/Rating.tsx create mode 100644 src/components/Scrollspy.tsx create mode 100644 src/components/Slider.tsx create mode 100644 src/components/Sortable.tsx create mode 100644 src/components/Spinner.tsx create mode 100644 src/components/Stepper.tsx create mode 100644 src/components/SweetAlert.tsx create mode 100644 src/components/SyntaxHighlighter.tsx create mode 100644 src/components/Table.tsx create mode 100644 src/components/Tabs.tsx create mode 100644 src/components/TagInput.tsx create mode 100644 src/components/Timeline.tsx create mode 100644 src/components/Toast.tsx create mode 100644 src/components/Tooltip.tsx create mode 100644 src/components/TreeView.tsx create mode 100644 src/components/Widget.tsx create mode 100644 src/components/Widget/index.tsx create mode 100644 src/components/Wizard.tsx create mode 100644 src/genui/components/Message.tsx create mode 100644 src/genui/components/SearchResults.tsx create mode 100644 src/genui/components/index.ts create mode 100644 src/genui/content.tsx create mode 100644 src/genui/hooks/index.ts create mode 100644 src/genui/hooks/useGenUI.ts create mode 100644 src/genui/hooks/useWebMCP.ts create mode 100644 src/genui/index.ts create mode 100644 src/genui/types.ts create mode 100644 src/genui/webmcp/index.ts create mode 100644 src/genui/webmcp/schemas.ts create mode 100644 src/hooks/useDisclosure.ts create mode 100644 src/index.ts create mode 100644 src/layout/AppShell.tsx create mode 100644 src/layout/Footer.tsx create mode 100644 src/layout/Navbar.tsx create mode 100644 src/layout/PageShell.tsx create mode 100644 src/layout/Sidebar.tsx create mode 100644 src/pages/Auth.tsx create mode 100644 src/pages/Chat.tsx create mode 100644 src/pages/Error.tsx create mode 100644 src/pages/Invoice.tsx create mode 100644 src/pages/Mail.tsx create mode 100644 src/pages/Search.tsx create mode 100644 src/pages/TaskManager.tsx create mode 100644 src/pages/UserProfile.tsx create mode 100644 src/pages/index.ts create mode 100644 src/server/crypto.ts create mode 100644 src/server/email.ts create mode 100644 src/server/index.ts create mode 100644 src/styles.css create mode 100644 src/theme/ThemeProvider.tsx create mode 100644 src/validation/hooks/useAddressAutocomplete.ts create mode 100644 src/validation/hooks/useFieldValidation.ts create mode 100644 src/validation/hooks/useValidation.ts create mode 100644 src/validation/index.ts create mode 100644 src/validation/server/index.ts create mode 100644 src/validation/server/sanitize.ts create mode 100644 src/validation/server/validateFormData.ts create mode 100644 src/validation/types.ts create mode 100644 src/validation/validators/address.ts create mode 100644 src/validation/validators/format.ts create mode 100644 src/validation/validators/index.ts create mode 100644 src/validation/validators/security.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..548cbc8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# Build output (regenerated by `npm run build`) +/dist/ +*.tsbuildinfo + +# Deps +/node_modules/ + +# Editor / OS +.vscode/ +.idea/ +.DS_Store diff --git a/.next/cache/.previewinfo b/.next/cache/.previewinfo new file mode 100644 index 0000000..1141b3a --- /dev/null +++ b/.next/cache/.previewinfo @@ -0,0 +1 @@ +{"previewModeId":"ef343e0fd89dc9ab6f08783ff0deef35","previewModeSigningKey":"2fa54fed7d2179894dacc11fb6965700299f5518a972c93780b2ec6a7bb6d0cd","previewModeEncryptionKey":"e6c3fa4101483282f8dd54a0c962f7e435cbc9aa3f389648bda2190fba138959","expireAt":1772117118591} \ No newline at end of file diff --git a/.next/cache/.rscinfo b/.next/cache/.rscinfo new file mode 100644 index 0000000..26216b3 --- /dev/null +++ b/.next/cache/.rscinfo @@ -0,0 +1 @@ +{"encryption.key":"rKSSp1jGbcTNnxCyUFDzQEDXMxC3YEQ2G/LDRFhRESE=","encryption.expire_at":1772117118521} \ No newline at end of file diff --git a/.next/diagnostics/build-diagnostics.json b/.next/diagnostics/build-diagnostics.json new file mode 100644 index 0000000..49f3647 --- /dev/null +++ b/.next/diagnostics/build-diagnostics.json @@ -0,0 +1,6 @@ +{ + "buildStage": "compile", + "buildOptions": { + "useBuildWorker": "true" + } +} \ No newline at end of file diff --git a/.next/diagnostics/framework.json b/.next/diagnostics/framework.json new file mode 100644 index 0000000..13fa2a4 --- /dev/null +++ b/.next/diagnostics/framework.json @@ -0,0 +1 @@ +{"name":"Next.js","version":"16.1.6"} \ No newline at end of file diff --git a/.next/package.json b/.next/package.json new file mode 100644 index 0000000..7156107 --- /dev/null +++ b/.next/package.json @@ -0,0 +1 @@ +{"type": "commonjs"} \ No newline at end of file diff --git a/.next/trace b/.next/trace new file mode 100644 index 0000000..7477748 --- /dev/null +++ b/.next/trace @@ -0,0 +1 @@ +[{"name":"generate-buildid","duration":378,"timestamp":2264145597921,"id":4,"parentId":1,"tags":{},"startTime":1770907518509,"traceId":"40900b3762bb777b"},{"name":"load-custom-routes","duration":863,"timestamp":2264145598524,"id":5,"parentId":1,"tags":{},"startTime":1770907518509,"traceId":"40900b3762bb777b"},{"name":"create-dist-dir","duration":716,"timestamp":2264145599441,"id":6,"parentId":1,"tags":{},"startTime":1770907518510,"traceId":"40900b3762bb777b"},{"name":"clean","duration":857,"timestamp":2264145601721,"id":7,"parentId":1,"tags":{},"startTime":1770907518513,"traceId":"40900b3762bb777b"},{"name":"collect-pages","duration":2777,"timestamp":2264145629026,"id":8,"parentId":1,"tags":{},"startTime":1770907518540,"traceId":"40900b3762bb777b"},{"name":"create-pages-mapping","duration":843,"timestamp":2264145680225,"id":9,"parentId":1,"tags":{},"startTime":1770907518591,"traceId":"40900b3762bb777b"},{"name":"generate-route-types","duration":16384,"timestamp":2264145681474,"id":10,"parentId":1,"tags":{},"startTime":1770907518592,"traceId":"40900b3762bb777b"},{"name":"public-dir-conflict-check","duration":1373,"timestamp":2264145698029,"id":11,"parentId":1,"tags":{},"startTime":1770907518609,"traceId":"40900b3762bb777b"},{"name":"generate-routes-manifest","duration":2758,"timestamp":2264145699647,"id":12,"parentId":1,"tags":{},"startTime":1770907518610,"traceId":"40900b3762bb777b"},{"name":"run-typescript","duration":6899691,"timestamp":2264145702908,"id":13,"parentId":1,"tags":{},"startTime":1770907518614,"traceId":"40900b3762bb777b"},{"name":"run-turbopack","duration":433948,"timestamp":2264152608591,"id":15,"parentId":1,"tags":{},"startTime":1770907525519,"traceId":"40900b3762bb777b"},{"name":"next-build","duration":7472002,"timestamp":2264145570565,"id":1,"tags":{"buildMode":"default","version":"16.1.6","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1770907518481,"traceId":"40900b3762bb777b"}] diff --git a/.next/trace-build b/.next/trace-build new file mode 100644 index 0000000..e2803b8 --- /dev/null +++ b/.next/trace-build @@ -0,0 +1 @@ +[{"name":"run-typescript","duration":6899691,"timestamp":2264145702908,"id":13,"parentId":1,"tags":{},"startTime":1770907518614,"traceId":"40900b3762bb777b"},{"name":"run-turbopack","duration":433948,"timestamp":2264152608591,"id":15,"parentId":1,"tags":{},"startTime":1770907525519,"traceId":"40900b3762bb777b"},{"name":"next-build","duration":7472002,"timestamp":2264145570565,"id":1,"tags":{"buildMode":"default","version":"16.1.6","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1770907518481,"traceId":"40900b3762bb777b"}] diff --git a/.next/turbopack b/.next/turbopack new file mode 100644 index 0000000..e69de29 diff --git a/.next/types/routes.d.ts b/.next/types/routes.d.ts new file mode 100644 index 0000000..e62799b --- /dev/null +++ b/.next/types/routes.d.ts @@ -0,0 +1,64 @@ +// This file is generated automatically by Next.js +// Do not edit this file manually + +type AppRoutes = never +type PageRoutes = "/" | "/Auth" | "/Chat" | "/Error" | "/Invoice" | "/Mail" | "/Search" | "/TaskManager" | "/UserProfile" +type LayoutRoutes = never +type RedirectRoutes = never +type RewriteRoutes = never +type Routes = AppRoutes | PageRoutes | LayoutRoutes | RedirectRoutes | RewriteRoutes + + +interface ParamMap { + "/": {} + "/Auth": {} + "/Chat": {} + "/Error": {} + "/Invoice": {} + "/Mail": {} + "/Search": {} + "/TaskManager": {} + "/UserProfile": {} +} + + +export type ParamsOf = ParamMap[Route] + +interface LayoutSlotMap { +} + + +export type { AppRoutes, PageRoutes, LayoutRoutes, RedirectRoutes, RewriteRoutes, ParamMap } + +declare global { + /** + * Props for Next.js App Router page components + * @example + * ```tsx + * export default function Page(props: PageProps<'/blog/[slug]'>) { + * const { slug } = await props.params + * return
Blog post: {slug}
+ * } + * ``` + */ + interface PageProps { + params: Promise + searchParams: Promise> + } + + /** + * Props for Next.js App Router layout components + * @example + * ```tsx + * export default function Layout(props: LayoutProps<'/dashboard'>) { + * return
{props.children}
+ * } + * ``` + */ + type LayoutProps = { + params: Promise + children: React.ReactNode + } & { + [K in LayoutSlotMap[LayoutRoute]]: React.ReactNode + } +} diff --git a/.next/types/validator.ts b/.next/types/validator.ts new file mode 100644 index 0000000..f247398 --- /dev/null +++ b/.next/types/validator.ts @@ -0,0 +1,112 @@ +// This file is generated automatically by Next.js +// Do not edit this file manually +// This file validates that all pages and layouts export the correct types + + + +type PagesPageConfig = { + default: React.ComponentType | ((props: any) => React.ReactNode | Promise | never | void) + getStaticProps?: (context: any) => Promise | any + getStaticPaths?: (context: any) => Promise | any + getServerSideProps?: (context: any) => Promise | any + getInitialProps?: (context: any) => Promise | any + /** + * Segment configuration for legacy Pages Router pages. + * Validated at build-time by parsePagesSegmentConfig. + */ + config?: { + maxDuration?: number + runtime?: 'edge' | 'experimental-edge' | 'nodejs' | string // necessary unless config is exported as const + regions?: string[] + } +} + + + + + + +// Validate ../../src/pages/Auth.tsx +{ + type __IsExpected = Specific + const handler = {} as typeof import("../../src/pages/Auth.js") + type __Check = __IsExpected + // @ts-ignore + type __Unused = __Check +} + +// Validate ../../src/pages/Chat.tsx +{ + type __IsExpected = Specific + const handler = {} as typeof import("../../src/pages/Chat.js") + type __Check = __IsExpected + // @ts-ignore + type __Unused = __Check +} + +// Validate ../../src/pages/Error.tsx +{ + type __IsExpected = Specific + const handler = {} as typeof import("../../src/pages/Error.js") + type __Check = __IsExpected + // @ts-ignore + type __Unused = __Check +} + +// Validate ../../src/pages/Invoice.tsx +{ + type __IsExpected = Specific + const handler = {} as typeof import("../../src/pages/Invoice.js") + type __Check = __IsExpected + // @ts-ignore + type __Unused = __Check +} + +// Validate ../../src/pages/Mail.tsx +{ + type __IsExpected = Specific + const handler = {} as typeof import("../../src/pages/Mail.js") + type __Check = __IsExpected + // @ts-ignore + type __Unused = __Check +} + +// Validate ../../src/pages/Search.tsx +{ + type __IsExpected = Specific + const handler = {} as typeof import("../../src/pages/Search.js") + type __Check = __IsExpected + // @ts-ignore + type __Unused = __Check +} + +// Validate ../../src/pages/TaskManager.tsx +{ + type __IsExpected = Specific + const handler = {} as typeof import("../../src/pages/TaskManager.js") + type __Check = __IsExpected + // @ts-ignore + type __Unused = __Check +} + +// Validate ../../src/pages/UserProfile.tsx +{ + type __IsExpected = Specific + const handler = {} as typeof import("../../src/pages/UserProfile.js") + type __Check = __IsExpected + // @ts-ignore + type __Unused = __Check +} + +// Validate ../../src/pages/index.ts +{ + type __IsExpected = Specific + const handler = {} as typeof import("../../src/pages/index.js") + type __Check = __IsExpected + // @ts-ignore + type __Unused = __Check +} + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee0752b --- /dev/null +++ b/README.md @@ -0,0 +1,164 @@ +# @limitless/ui + +Limitless Layout 3 (Detached Layout) inspired Bootstrap 5 React UI kit for Remix and Next.js. No jQuery, all components are React-first with Bootstrap-compatible markup and a thin theming layer (light/dark/material). + +## Layout 3 Structure + +This framework implements the **Layout 3 (Detached Layout)** from Limitless template: + +``` +├── Navbar (full width, top) +├── PageHeader (outside page-content) +│ ├── breadcrumb-line +│ └── page-header-content +├── page-content pt-0 +│ ├── Main Sidebar (detached, left) +│ ├── Secondary Sidebar (optional) +│ ├── content-wrapper +│ │ └── content +│ └── Right Sidebar (optional) +└── Footer (outside page-content, bottom) +``` + +Key characteristics: +- Sidebars appear as detached stand-alone components with shadows +- Page header is placed outside page-content container +- Footer is at the very bottom, outside page-content +- Supports material theme styling with user menu + +## Quickstart + +```bash +npm install @limitless/ui bootstrap +``` + +In your app entry (e.g., `root.tsx` in Remix, `_app.tsx` in Next): + +```tsx +import 'bootstrap/dist/css/bootstrap.min.css'; +import '@limitless/ui/dist/styles.css'; + +import { ThemeProvider, PageShell, Navbar, Sidebar, PageHeader, Footer } from '@limitless/ui'; + +export default function App() { + return ( + + } + endItems={/* user menu, notifications */} + /> + } + pageHeader={ + + } + mainSidebar={ + + } + footer={ +