From d44ea9faaf9d9f729fef4a945517ee5b8e71c97f Mon Sep 17 00:00:00 2001 From: Zaiid Moumni <141942826+Zaiidmo@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:07:19 +0100 Subject: [PATCH] v1.0.3 * data tables done * 1.0.3 * dashboard widgets, resizable, drag and drop, with actions done * persist layout to local storage done * v1.0.3 * data tables done * 1.0.3 * dashboard widgets, resizable, drag and drop, with actions done * persist layout to local storage done * chore: removed tracked dist files and empty directories & updated release workflow and gitignore * chore: updated husky pre-commit * chore: updated dependencies versions, ci/cd workflows, and fixed all lint & tc issues * fix: formatting issues --------- Co-authored-by: a-elkhiraooui-ciscode --- .github/workflows/cd-release.yml | 6 +- .gitignore | 5 +- .husky/_/.gitignore | 2 +- .husky/pre-commit | 3 - .husky/pre-push | 2 - README.md | 2 +- dist/index.d.ts | 391 -- dist/index.js | 1352 ---- dist/index.js.map | 1 - e2e/smoke.spec.ts | 9 - examples/App.tsx | 6 +- package-lock.json | 6112 +++++++---------- package.json | 73 +- postcss.config.js | 2 +- src/__tests__/setup.ts | 2 - src/assets/react.svg | 1 - src/common/Loader/TableLoader.tsx | 3 +- src/common/Loader/index.tsx | 3 +- .../Breadcrumbs/Breadcrumb.test.tsx | 5 +- src/components/Dashboard/ClickOutside.tsx | 12 +- src/components/Dashboard/Header/index.tsx | 3 +- .../Dashboard/Sidebar/SidebarLinkGroup.tsx | 3 +- src/components/Dashboard/Sidebar/index.tsx | 10 +- .../Dashboard/Widgets/ChartAdapters.tsx | 97 + .../Dashboard/Widgets/DashboardGrid.tsx | 335 + .../Dashboard/Widgets/WidgetContainer.tsx | 123 + .../Dashboard/Widgets/layoutUtils.ts | 33 + src/components/Form/ZodDynamicForm.tsx | 58 +- src/components/Table/TableDataCustom.test.tsx | 5 +- src/components/Table/TableDataCustom.tsx | 3 +- src/components/Table/TableDataCustomBase.tsx | 614 +- src/components/Table/test.tsx | 4 +- src/exceptions/TableErrorBoundary.tsx | 9 +- src/hooks/__tests__/useColorMode.test.tsx | 2 +- src/hooks/useA11y.ts | 15 +- src/hooks/useColorMode.tsx | 4 +- src/hooks/useKeyboardNavigation.ts | 6 +- src/hooks/useLogin.ts | 23 +- src/hooks/useLogin.tsx | 23 +- src/hooks/usePasswordReset.ts | 23 +- src/hooks/usePasswordReset.tsx | 23 +- src/hooks/useRegister.ts | 23 +- src/index.ts | 13 +- src/main/dashboard.tsx | 11 +- src/models/ColumnConfigTable.ts | 22 + src/models/DashboardWidget.ts | 40 + src/models/FieldConfigDynamicForm.ts | 10 +- src/models/SidebarItemModel.ts | 1 + src/pages/Dashboard/Home.tsx | 61 +- .../DashboardWidgets/layoutUtils.test.ts | 30 + .../components/Form/ZodDynamicForm.test.tsx | 8 +- tests/unit/hooks/useLogin.test.tsx | 6 +- tests/unit/hooks/usePasswordReset.test.tsx | 5 +- tsconfig.json | 2 +- 54 files changed, 3982 insertions(+), 5658 deletions(-) delete mode 100644 dist/index.d.ts delete mode 100644 dist/index.js delete mode 100644 dist/index.js.map delete mode 100644 e2e/smoke.spec.ts delete mode 100644 src/__tests__/setup.ts delete mode 100644 src/assets/react.svg create mode 100644 src/components/Dashboard/Widgets/ChartAdapters.tsx create mode 100644 src/components/Dashboard/Widgets/DashboardGrid.tsx create mode 100644 src/components/Dashboard/Widgets/WidgetContainer.tsx create mode 100644 src/components/Dashboard/Widgets/layoutUtils.ts create mode 100644 src/models/DashboardWidget.ts create mode 100644 tests/unit/components/DashboardWidgets/layoutUtils.test.ts diff --git a/.github/workflows/cd-release.yml b/.github/workflows/cd-release.yml index 3141924..575d28d 100644 --- a/.github/workflows/cd-release.yml +++ b/.github/workflows/cd-release.yml @@ -4,7 +4,7 @@ on: push: branches: - master - workflow_dispatch: + # workflow_dispatch: jobs: publish: @@ -21,8 +21,8 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: "20" - registry-url: "https://registry.npmjs.org" + node-version: '20' + registry-url: 'https://registry.npmjs.org' - name: Install dependencies run: npm ci diff --git a/.gitignore b/.gitignore index ad7bfc1..96600d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ -node_modules -dist +node_modules/ +dist/ coverage .vitest .DS_Store *.log *.tsbuildinfo .env* + diff --git a/.husky/_/.gitignore b/.husky/_/.gitignore index 234d3f7..f59ec20 100644 --- a/.husky/_/.gitignore +++ b/.husky/_/.gitignore @@ -1 +1 @@ -# * \ No newline at end of file +* \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit index d24fdfc..2312dc5 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - npx lint-staged diff --git a/.husky/pre-push b/.husky/pre-push index acfd8a0..90466dc 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1,5 +1,3 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" npm run typecheck npm test diff --git a/README.md b/README.md index d0c7fca..da3c299 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# React TypeScript DeveloperKit (Template) +# @ciscode/ui-widget-kit Template repository for building reusable React TypeScript **npm libraries** (components + hooks + utilities). diff --git a/dist/index.d.ts b/dist/index.d.ts deleted file mode 100644 index 25c3bb6..0000000 --- a/dist/index.d.ts +++ /dev/null @@ -1,391 +0,0 @@ -import * as React$1 from 'react'; -import React__default, { ReactNode } from 'react'; -import * as react_jsx_runtime from 'react/jsx-runtime'; -import { ZodSchema } from 'zod'; - -/** Each item within a section */ -interface SidebarItem$1 { - label: string; - path?: string; - icon?: JSX.Element; - order?: number; - children?: SidebarItem$1[]; -} -/** Each section has a name, an optional order, and an array of items */ -interface SidebarSection { - name: string; - order?: number; - items: SidebarItem$1[]; -} - -type VisibilityRule = { - /** Visible if user has at least one of these roles */ - roles?: string[]; - /** Visible if user has every permission listed here */ - permissions?: string[]; - /** Visible if user has at least one of these modules */ - modules?: string[]; -}; -type SidebarBase = { - id: string; - label: string; - /** Iconify icon name string (e.g., "mdi:view-dashboard") */ - icon?: string; - /** Nested menus (collapsible groups) */ - children?: SidebarItem[]; - /** If omitted, item is visible. If provided, item is hidden unless rule passes. */ - visibility?: VisibilityRule; -}; -type SidebarInternalLink = SidebarBase & { - to: string; - href?: never; - action?: never; -}; -type SidebarExternalLink = SidebarBase & { - href: string; - to?: never; - action?: never; - newTab?: boolean; -}; -type SidebarActionItem = SidebarBase & { - action: 'logout' | (string & {}); - to?: never; - href?: never; -}; -type SidebarItem = SidebarInternalLink | SidebarExternalLink | SidebarActionItem; -type TemplateSidebarConfig = { - items: SidebarItem[]; - className?: string; -}; -type TemplateNavbarBrandConfig = { - title?: string; - href?: string; - logoSrc?: string; - logoAlt?: string; -}; -type TemplateNavbarConfig = { - brand?: TemplateNavbarBrandConfig; - /** Optional full override */ - brandSlot?: ReactNode; - className?: string; -}; -type TemplateFooterLink = { - label: string; - href: string; - /** - * If omitted, default behavior is new tab (true). - * Can be overridden per link. - */ - newTab?: boolean; -}; -type TemplateFooterPresetConfig = { - leftText: string; - links?: TemplateFooterLink[]; - version?: string; -}; -type TemplateFooterConfig = { - /** - * Advanced: fully custom footer blocks (you control JSX). - * Optional because preset-only is valid. - */ - blocks?: ReactNode[]; - /** - * Preset: data-driven styled footer rendered by the template. - */ - preset?: TemplateFooterPresetConfig; - /** - * Optional className override on the footer wrapper. - */ - className?: string; -}; -type TemplateLayoutConfig = { - sidebar?: TemplateSidebarConfig; - navbar?: TemplateNavbarConfig; - footer?: TemplateFooterConfig; -}; - -/** - * Props for the `Template` (Dashboard Shell) component. - * Backward compatible with legacy sidebar/logo/onLogout while - * supporting modern `sidebar`, `navbar`, and optional `footer` configs. - */ -interface DashboardProps { - children: ReactNode; - /** - * Legacy props (backward compatible) - */ - sidebarContent?: SidebarSection[]; - logo?: ReactNode; - onLogout?: () => void; - /** - * New config props (preferred) - */ - sidebar?: TemplateSidebarConfig; - navbar?: TemplateNavbarConfig; - /** - * Optional footer (rendered inside DashboardLayout when provided) - */ - footer?: TemplateFooterConfig; -} -/** - * Template (Dashboard Shell) - * - * Backward compatible: - * - Existing apps can keep using: sidebarContent + logo + onLogout - * Preferred: - * - New apps should use: sidebar + navbar (+ footer when needed) - */ -declare const Template: React__default.FC; - -/** - * Props for `Breadcrumb` component. - * - `pageName`: current page label displayed in the trail. - */ -interface BreadcrumbProps { - pageName: string; -} -/** - * Accessible breadcrumb navigation. - * Renders a current page label and a link to home. - */ -declare const Breadcrumb: React__default.FC; - -/** The list of supported field types. */ -type FieldType = 'text' | 'number' | 'textarea' | 'select' | 'checkbox' | 'multiSelect' | 'custom'; -/** For select-type fields, each option has a label and a value. */ -interface FieldOption { - label: string; - value: string | number; -} -/** - * Describes each field in your dynamic form: - * - name, label, type, (optionally) placeholder, options, etc. - * - if "type" is "custom", you can supply a "component" - * that the form will render directly. - */ -interface FieldConfigDynamicForm { - /** Unique field name => used to store the value in state, reference in Zod schema, etc. */ - name: string; - /** The label displayed above or next to the input. */ - label?: string; - /** Type of input: text, number, textarea, select, checkbox, multiSelect, or custom. */ - type: FieldType; - /** Optional placeholder text for text/textarea/number fields. */ - placeholder?: string; - /** For select or multiSelect, an array of label/value pairs. */ - options?: FieldOption[]; - /** Default initial value (e.g. '', 0, [], etc.). */ - defaultValue?: any; - /** For multiSelect or custom logic, an optional URL for searching. */ - /** - * If `type` is 'custom', you can specify a React component - * that the form will render. This component should accept - * props like { value: any, onChange: (val: any) => void } at minimum. - */ - component?: React__default.ComponentType; - step?: string; - /** - * Tailwind classes for the field wrapper (the
). - * e.g. "w-1/2 px-2" or "col-span-2" or "flex-1" - */ - wrapperClassName?: string; - /** - * If you want custom classes for the