{"id":20314787,"url":"https://github.com/xizon/funda-ui","last_synced_at":"2026-01-12T02:21:31.760Z","repository":{"id":149303790,"uuid":"621345805","full_name":"xizon/funda-ui","owner":"xizon","description":"React components using pure Bootstrap 5+ which has undergone complex business testing and is easy to integrate with any API","archived":false,"fork":false,"pushed_at":"2025-04-11T03:42:16.000Z","size":10276,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-11T04:24:53.257Z","etag":null,"topics":["ai-chat","bootstrap","components","components-react","funda-ui","fundaui","react","react-bootstrap","react-bootstrap-components","ui-components","ui-kit","uikit"],"latest_commit_sha":null,"homepage":"https://xizon.github.io/funda-ui-doc","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xizon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-30T13:31:45.000Z","updated_at":"2025-04-11T03:23:49.000Z","dependencies_parsed_at":"2023-08-31T01:54:00.601Z","dependency_job_id":"3bbe27ba-5878-48ce-ada0-1c84cb03d484","html_url":"https://github.com/xizon/funda-ui","commit_stats":null,"previous_names":["xizon/funda-ui","xizon/react-pure-bootstrap"],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xizon%2Ffunda-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xizon%2Ffunda-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xizon%2Ffunda-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xizon%2Ffunda-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xizon","download_url":"https://codeload.github.com/xizon/funda-ui/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248345252,"owners_count":21088231,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-chat","bootstrap","components","components-react","funda-ui","fundaui","react","react-bootstrap","react-bootstrap-components","ui-components","ui-kit","uikit"],"created_at":"2024-11-14T18:16:42.574Z","updated_at":"2026-01-12T02:21:31.754Z","avatar_url":"https://github.com/xizon.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Funda UI\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"logo.png\"  alt=\"Funda UI\"  width=\"180\" \u003e\n\u003c/p\u003e\n\n\nReact components using pure Bootstrap 5+ which has undergone complex business testing and is easy to integrate with any API. You can load Bootstrap css libraries separately in your project.\n\nAll components have undergone complex business verification and provide multiple examples.\n\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"preview.png\"  alt=\"Funda UI\" \u003e\n\u003c/p\u003e\n\n\n\n---\n\n- [Documentation](https://uiux.cc/funda-ui-doc)\n\n---\n\n\n\n\n## Key Features\n\n1. Simplify the assignment method of diversified data.\n2. Components are compatible with `gRPC`, `REST APIs`, `GraphQL` self-packaging, uniformly use [Classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) and their methods to introduce interfaces\n3. Enhanced user interaction, flexible use in asynchronous and synchronous states\n4. Introduce appropriate component `.css` files as needed, only for some components with special needs. Most of them can directly use Bootstrap's official style sheet. Styles are performant and easy to override.\n5. Do not embed css-in-js, directly use external CSS styles to completely change the component style.\n\n\n## Components List\n\nHere is a table of the components and their status.\n\n\n| WEB ELEMENTS | FORMS | INTERACTION | NAVIGATION | LAYOUTS |\n| --- | --- | --- | --- | --- |\n| [Accordion ✅](packages/Accordion/README.md) | [Input ✅](packages/Input/README.md) | [Infinite Scroll ❏](packages/InfiniteScroll/README.md) |[Multilevel Dropdown Menu ✅](packages/MultilevelDropdownMenu/README.md)  | [MasonryLayout ✅](packages/MasonryLayout/README.md) |\n| [Accordion Slider ❏](packages/AccordionSlider/README.md) | [Number Input ✅](packages/NumberInput/README.md) | [Image Perspective Hover ❏](packages/ImagePerspectiveHover/README.md) | [Dropdown Menu ✅](packages/DropdownMenu/README.md)  | [RootPortal ✅](packages/RootPortal/README.md)  |\n| [Back To Top ✅](packages/BackToTop/README.md) | [Date ✅🔥](packages/Date/README.md) | [Mousewheel Interaction ❏](packages/MousewheelInteraction/README.md) | | [Splitter Panel  ✅](packages/SplitterPanel/README.md) |\n| [Button ❏](packages/Button/README.md) | [Tag Input ✅](packages/TagInput/README.md) | [Parallax ❏](packages/Parallax/README.md) |  |   |\n| [Card ❏](packages/Card/README.md) | [Textarea  ✅](packages/Textarea/README.md) | [Scroll Reveal ✅](packages/ScrollReveal/README.md) |  |   |\n| [Content Placeholder ❏](packages/ContentPlaceholder/README.md) | [NativeSelect ✅](packages/NativeSelect/README.md) |  [DragDrop List ✅🔥](packages/DragDropList/README.md)  |  |  |\n| [Counter ❏](packages/Counter/README.md) | [Cascading Select ✅](packages/CascadingSelect/README.md) | [Mode Switch ✅](packages/ModeSwitch/README.md) |  |  |\n| [Hybrid Content Slider ❏](packages/HybridContentSlider/README.md) | [Cascading Select End-to-end ✅🔥](packages/CascadingSelectE2E/README.md) | [Custom Scrollbar ✅](packages/Scrollbar/README.md) |  |  |\n| [Image Shapes ❏](packages/ImageShapes/README.md) | [Radio ✅](packages/Radio/README.md) | [Horizontal Scroll Content ✅](packages/HorizontalScrollContent/README.md) |  |  |\n| [Lightbox ❏](packages/Lightbox/README.md) | [Checkbox ✅](packages/Checkbox/README.md) | [Refresher ✅](packages/Refresher/README.md) |  |  |\n| [List Bulleted ❏](packages/ListBulleted/README.md) | [Select ✅🔥](packages/Select/README.md) |  |  |  |\n| [Modal Dialog ✅🔥](packages/ModalDialog/README.md) | [Live Search ✅](packages/LiveSearch/README.md) |  |  |  |\n| [Pagination ✅](packages/Pagination/README.md) |  [File ✅](packages/File/README.md) |  |  |  |\n| [Table ✅🔥](packages/Table/README.md) | [SearchBar ✅](packages/SearchBar/README.md) |  |  |  |\n| [Periodical Scroll ❏](packages/PeriodicalScroll/README.md) | [Switch ✅](packages/Switch/README.md) |  |  |  |\n| [Progress Bar ❏](packages/ProgressBar/README.md) | [Dynamic Fields ✅🔥](packages/DynamicFields/README.md) |  |  |  |\n| [Rating ❏](packages/Rating/README.md) | [MultipleCheckboxes ✅](packages/MultipleCheckboxes/README.md) |  |  |  |\n| [Seamless Scrolling Element ❏](packages/SeamlessScrollingElement/README.md) | [MultipleSelect ✅🔥](packages/MultipleSelect/README.md)  |  |  |  |\n| [Show More Less ✅](packages/ShowMoreLess/README.md) | [Range Slider ✅](packages/RangeSlider/README.md) | |  |  |\n| [Slideshow ❏](packages/Slideshow/README.md) | [Color Picker ✅](packages/ColorPicker/README.md) |  |  |  |\n| [Tabs ✅](packages/Tabs/README.md) |  |  |  |  |\n| [Timeline ❏](packages/Timeline/README.md) | |  |  |  |\n| [Toast ✅](packages/Toast/README.md) |  |  |  |  |\n| [Tooltip ✅](packages/Tooltip/README.md) |  |  |  |  |\n| [Digital Clock ✅](packages/DigitalClock/README.md) |  |  |  |  |\n| [Tree ✅🔥](packages/Tree/README.md) |  |  |  |  |\n| [Event Calendar ✅🔥](packages/EventCalendar/README.md) |  |  |  |  |\n| [Event Calendar Timeline ✅🔥](packages/EventCalendarTimeline/README.md) |  |  |  |  |\n| [Chatbox ✅🔥🤖](packages/Chatbox/README.md) |  |  |  |  |\n| [Stepper ✅](packages/Stepper/README.md) |  |  |  |  |\n| [Popover ✅](packages/Popover/README.md) |  |  |  |  |\n\n\n\n## Usage\n\n**Step 1**. You need to install it:\n\n```sh\n$ npm i funda-ui\n```\n\nor\n\n```sh\n$ pnpm add funda-ui\n```\n\n**Step 2**. Using Bootstrap CSS together (recommended)\n\n[Download bootstrap](https://github.com/twbs/bootstrap)\n\n```html\n\u003clink href=\"./bootstrap.min.css\" rel=\"stylesheet\"/\u003e\n```\n\n\u003e You could remove Bootstrap's styles. All components support setting Bootstrap's default class names through `**ClassName` attributes.\n\n**Step 3**. import required components as required\n\n\u003e If the component does not have a CSS file, it can not be imported, or use own CSS.\n\n\n```js\nimport Input from 'funda-ui/Input';\nimport Textarea from 'funda-ui/Textarea';\nimport CascadingSelect from 'funda-ui/CascadingSelect';\n\n// component styles\nimport 'funda-ui/CascadingSelect/index.css';\n```\n\nor \n\n```js\nimport { \n    Input,\n    Textarea,\n    CascadingSelect\n} from 'funda-ui';\n\n// component styles\nimport 'funda-ui/CascadingSelect/index.css';\n```\n\nor\n\n```js\nconst Input = require('funda-ui').Input;\nconst Textarea = require('funda-ui').Textarea;\nconst CascadingSelect = require('funda-ui').CascadingSelect;\n\n// component styles\nimport 'funda-ui/CascadingSelect/index.css';\n```\n\n\n\n## Collecting Data\n\n### Basic\n\nUse `useState()` to store data.\n\n```js\nimport React, { useState } from 'react';\nimport Input from 'funda-ui/Input';\nimport Select, { OptionConfig, MultiSelectValue } from 'funda-ui/Select';\n\n// component styles\nimport 'funda-ui/Select/index.css';\n\n\ninterface Config {\n    name: string;\n    role: boolean;\n}\n\n\nexport default () =\u003e {\n    // Consolidated config state\n    const [config, setConfig] = useState\u003cConfig\u003e({\n        name: '',\n        role: '',\n    });\n\n    const updateConfig = (newConfig: Partial\u003cConfig\u003e) =\u003e {\n        setConfig(prev =\u003e ({ ...prev, ...newConfig }));\n    };\n    \n\n    const handleSubmit = (e: React.MouseEvent\u003cHTMLButtonElement\u003e) =\u003e {\n        e.preventDefault();\n        alert(`Name: ${config.name}, Role: ${config.role}`);\n    };\n\n    return (\n        \u003cform onSubmit={handleSubmit}\u003e\n            \u003cdiv\u003e\n\n                \u003cInput\n                    name=\"name\"\n                    label=\"Name\"\n                    onChange={(e: React.MouseEvent, onComposition: any, el: any, value: string) =\u003e {\n                        updateConfig({ name: value });\n                    }}\n                /\u003e\n            \u003c/div\u003e\n\n            \u003cdiv\u003e\n        \n                \u003cSelect\n                    label=\"Role\"\n                    placeholder=\"Select\"\n                    name=\"role\"\n                    options={[\n                        {\"label\": \"Admin\",\"value\": \"admin\",\"queryString\": \"\"},\n                        {\"label\": \"User\",\"value\": \"user\",\"queryString\": \"\"}\n                    ]}\n                    onChange={(e: React.MouseEvent\u003cHTMLElement\u003e | React.KeyboardEvent\u003cHTMLElement\u003e, e2: HTMLElement, val: OptionConfig | MultiSelectValue): void =\u003e {\n                        updateConfig({ role: (val as OptionConfig).value });\n                    }}\n                /\u003e\n\n            \u003c/div\u003e\n\n            \u003cbutton className=\"btn btn-outline-primary btn-sm mb-2\" type=\"submit\"\u003eSubmit\u003c/button\u003e\n        \u003c/form\u003e\n    );\n\n}\n```\n\n\n\n\n### Advanced\n\nUsing vanilla JS to collect the value of name is faster and easier.\n\n\n```js\nimport React, { useRef } from \"react\";\nimport Input from 'funda-ui/Input';\nimport Select, { OptionConfig, MultiSelectValue } from 'funda-ui/Select';\n\n// component styles\nimport 'funda-ui/Select/index.css';\n\n// utils\nimport { serializeArray } from 'funda-ui/Utils/formdata';\nimport { isEmpty } from \"funda-ui/Utils/validate\";\n\ninterface FormField {\n    name: string;\n    value: string;\n}\n\ninterface FormData {\n    [key: string]: string;\n}\n\ntype CallbackFunction = (formData: FormData) =\u003e void;\ntype ErrorCallbackFunction = () =\u003e void;\n\nfunction customValidate(\n    form: HTMLFormElement | HTMLDivElement | null,\n    callback?: CallbackFunction,\n    errCallback?: ErrorCallbackFunction\n): void {\n    if (form === null) return;\n\n    const formData: FormData = {};\n    const fieldsData: FormField[] = serializeArray(form);\n    let fieldsCheck: boolean = true;\n    let customFieldsCheck: boolean = true;\n\n    // Step 1: everything is ok  \n    //-------------\n    // required fields\n    const emptyFieldsCheck = fieldsData.every((item: FormField) =\u003e {\n        if (item.name !== null \u0026\u0026 item.name !== '') {\n            formData[item.name] = item.value;\n\n            const _field = form.querySelector\u003cHTMLElement\u003e(`[name=\"${item.name}\"]`);\n            if (!_field) return true;\n\n            const fieldRequired = _field.getAttribute('required');\n            if (fieldRequired !== null \u0026\u0026 fieldRequired !== 'false') {\n                if (item.value === '' || isEmpty(item.value)) {\n                    const _label = _field.dataset.requiredTitle;\n                    alert(`${_label} cannot be empty!`);\n                    return false;\n                }\n            }\n        }\n\n        errCallback?.();\n\n        return true;\n    });\n\n    //  merged result\n    fieldsCheck = [emptyFieldsCheck, customFieldsCheck].every((item: boolean) =\u003e {\n        return item;\n    });\n\n    // Step 2: everything is ok  \n    //-------------\n    if (fieldsCheck) {\n        callback?.(formData);\n    }\n}\n\n\n\nexport default () =\u003e {\n    const formRef = useRef\u003cHTMLDivElement\u003e(null);\n\n    const handleSubmit = (e: React.MouseEvent\u003cHTMLButtonElement\u003e) =\u003e {\n        e.preventDefault();\n   \n        customValidate(\n            formRef.current, \n            (formData: any[]) =\u003e {\n                alert(JSON.stringify(formData));\n            },\n            () =\u003e { }\n        );\n\n    };\n\n    return (\n        \u003cdiv ref={formRef}\u003e\n            \u003cdiv\u003e\n\n                \u003cInput\n                    name=\"name\"\n                    label=\"Name\"\n                /\u003e\n            \u003c/div\u003e\n\n            \u003cdiv\u003e\n        \n                \u003cSelect\n                    label=\"Role\"\n                    placeholder=\"Select\"\n                    name=\"role\"\n                    options={[\n                        {\"label\": \"Admin\",\"value\": \"admin\",\"queryString\": \"\"},\n                        {\"label\": \"User\",\"value\": \"user\",\"queryString\": \"\"}\n                    ]}\n                /\u003e\n\n            \u003c/div\u003e\n\n            \u003cbutton className=\"btn btn-outline-primary btn-sm mb-2\" type=\"button\" onClick={handleSubmit}\u003eSubmit\u003c/button\u003e\n        \u003c/div\u003e\n    );\n\n}\n```\n\n\n## Getting Started\n\nMake sure if Node 14+ is installed on your computer.\n\n### Step 1: Create a new Lerna workspace by running:\n\n```sh\n$ cd /{your_directory}/funda-ui\n$ npx lerna init\n```\n\n\n### Step 2: Install dependencies (Required)\n\nIt will automatically install the dependencies of all resources in `packages/` without duplication.\n\n```sh\n$ npm install\n```\n \n\n### Step 3: To open the visualization, run:\n\n```sh\n$ npx nx graph\n```\n \n### Step 4: To build all projects, run\n\n```sh\n$ npx lerna run build\n```\n\nor Build the package you want (recommend):\n\n```sh\n$ npx lerna run build --scope=plugin-1 --scope=plugin-2\n```\n\nPlease do not install **lerna** globally to use `lerna run build`\n\n\n### Step 5: (optional) Use a custom script like:\n\n```sh\n$ npx lerna exec npm run export --scope=plugin-2\n```\n  \n\n## Publish the lib of components, it will hang on NPM: \n\n\n```sh\n$ npm run build:lib\n$ npm run build:publish\n```\n  \n  \n\u003e **(Optional) Update Utils**\n\u003e \n\u003e ```sh\n\u003e $ npx lerna run build --scope=funda-utils\n\u003e $ npm i\n\u003e $ npx lerna run build\n\u003e ```\n\u003e \n\n\n\n\u003e **(Optional) Manually generate `.d.ts` files, you can execute**\n\u003e \n\u003e ```sh\n\u003e $ npx -p typescript tsc lib/cjs/*.js --declaration --allowJs --emitDeclarationOnly\n\u003e ```\n\u003e \n\n\n## Contributing\n\n- [Lerna](https://github.com/lerna/lerna)\n- [Bootstrap](https://getbootstrap.com/)\n- [React](https://react.dev/)\n\n\n## Inspiration and References\n\nThis component library is inspired by several open-source projects such as [react-bootstrap](https://react-bootstrap.netlify.app), [Ant Design](https://ant.design), [MUI](https://mui.com), and [shadcn/ui](https://ui.shadcn.com). It is an open-source plugin library designed as a learning-to-practice project.\n\nThe library does **not** contain any personal or company-specific business logic. It serves purely as an auxiliary tool to help efficiently and reliably develop company applications.\n\n\n## Licensing\n\nLicensed under the [MIT](https://opensource.org/licenses/MIT).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxizon%2Ffunda-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxizon%2Ffunda-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxizon%2Ffunda-ui/lists"}