From e72a6639dd09219f7f79004584477b87e9290153 Mon Sep 17 00:00:00 2001 From: zuramai Date: Fri, 15 Dec 2023 10:33:40 +0700 Subject: [PATCH] feat: tabs component --- packages/tabs/.babelrc | 12 ++++ packages/tabs/.eslintrc.json | 18 +++++ packages/tabs/README.md | 7 ++ packages/tabs/package.json | 12 ++++ packages/tabs/project.json | 40 +++++++++++ packages/tabs/src/index.ts | 1 + packages/tabs/src/lib/tabs.spec.tsx | 10 +++ packages/tabs/src/lib/tabs.tsx | 84 ++++++++++++++++++++++ packages/tabs/src/stories/tabs.stories.tsx | 22 ++++++ packages/tabs/tsconfig.json | 21 ++++++ packages/tabs/tsconfig.lib.json | 23 ++++++ packages/tabs/tsconfig.spec.json | 25 +++++++ packages/tabs/vite.config.ts | 52 ++++++++++++++ tsconfig.base.json | 7 +- 14 files changed, 331 insertions(+), 3 deletions(-) create mode 100644 packages/tabs/.babelrc create mode 100644 packages/tabs/.eslintrc.json create mode 100644 packages/tabs/README.md create mode 100644 packages/tabs/package.json create mode 100644 packages/tabs/project.json create mode 100644 packages/tabs/src/index.ts create mode 100644 packages/tabs/src/lib/tabs.spec.tsx create mode 100644 packages/tabs/src/lib/tabs.tsx create mode 100644 packages/tabs/src/stories/tabs.stories.tsx create mode 100644 packages/tabs/tsconfig.json create mode 100644 packages/tabs/tsconfig.lib.json create mode 100644 packages/tabs/tsconfig.spec.json create mode 100644 packages/tabs/vite.config.ts diff --git a/packages/tabs/.babelrc b/packages/tabs/.babelrc new file mode 100644 index 0000000..1ea870e --- /dev/null +++ b/packages/tabs/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/packages/tabs/.eslintrc.json b/packages/tabs/.eslintrc.json new file mode 100644 index 0000000..a39ac5d --- /dev/null +++ b/packages/tabs/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nx/react", "../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/packages/tabs/README.md b/packages/tabs/README.md new file mode 100644 index 0000000..204049c --- /dev/null +++ b/packages/tabs/README.md @@ -0,0 +1,7 @@ +# tabs + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test tabs` to execute the unit tests via [Vitest](https://vitest.dev/). diff --git a/packages/tabs/package.json b/packages/tabs/package.json new file mode 100644 index 0000000..9cb8722 --- /dev/null +++ b/packages/tabs/package.json @@ -0,0 +1,12 @@ +{ + "name": "tabs", + "version": "0.0.1", + "main": "./index.js", + "types": "./index.d.ts", + "exports": { + ".": { + "import": "./index.mjs", + "require": "./index.js" + } + } +} diff --git a/packages/tabs/project.json b/packages/tabs/project.json new file mode 100644 index 0000000..0f689e5 --- /dev/null +++ b/packages/tabs/project.json @@ -0,0 +1,40 @@ +{ + "name": "tabs", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/tabs/src", + "projectType": "library", + "tags": [], + "targets": { + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["packages/tabs/**/*.{ts,tsx,js,jsx}"] + } + }, + "build": { + "executor": "@nx/vite:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "production", + "options": { + "outputPath": "dist/packages/tabs" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "passWithNoTests": true, + "reportsDirectory": "../../coverage/packages/tabs" + } + } + } +} diff --git a/packages/tabs/src/index.ts b/packages/tabs/src/index.ts new file mode 100644 index 0000000..413c798 --- /dev/null +++ b/packages/tabs/src/index.ts @@ -0,0 +1 @@ +export * from './lib/tabs'; diff --git a/packages/tabs/src/lib/tabs.spec.tsx b/packages/tabs/src/lib/tabs.spec.tsx new file mode 100644 index 0000000..b47d227 --- /dev/null +++ b/packages/tabs/src/lib/tabs.spec.tsx @@ -0,0 +1,10 @@ +import { render } from '@testing-library/react'; + +import Tabs from './tabs'; + +describe('Tabs', () => { + it('should render successfully', () => { + const { baseElement } = render(); + expect(baseElement).toBeTruthy(); + }); +}); diff --git a/packages/tabs/src/lib/tabs.tsx b/packages/tabs/src/lib/tabs.tsx new file mode 100644 index 0000000..e459b1e --- /dev/null +++ b/packages/tabs/src/lib/tabs.tsx @@ -0,0 +1,84 @@ +import { Children, ReactElement, ReactNode, useId, useRef, useState } from "react"; +import { cn } from '@bootwind/common' + +/* eslint-disable-next-line */ +export interface TabsProps { + id?: string + children: ReactNode +} +/* eslint-disable-next-line */ +export interface TabItemProps { + title: ReactNode | string + children: ReactNode | string +} + +function convertToSlug(text:string) { + return text.toLowerCase() + .replace(/[^\w ]+/g, "") + .replace(/ +/g, "-"); +} + +export function Tabs(props: TabsProps) { + const [activeTab, setActiveTab] = useState(0) + const children = Children.map(props.children as ReactElement, (child: ReactElement) => { + /** @ts-ignore */ + if (child.type.displayName == 'TabItem') { + return { + ...child.props, + id: useId() + } + } + }) + const changeActiveTab = (index: number) => { + console.log('chnage', index) + setActiveTab(index) + } + return ( +
+
    + { + children.map((child, i) => ( +
  • + +
  • + )) + } +
+
+ { + children.map((child, i) => i == activeTab && ( +
+ { child.children } +
+ )) + } +
+
+ ); +} + +export function TabItem(props: TabItemProps) { + return ( + <> + + ) +} + +export default Tabs; diff --git a/packages/tabs/src/stories/tabs.stories.tsx b/packages/tabs/src/stories/tabs.stories.tsx new file mode 100644 index 0000000..b84bb3f --- /dev/null +++ b/packages/tabs/src/stories/tabs.stories.tsx @@ -0,0 +1,22 @@ +import { TabItem, Tabs } from ".."; + +export default { + title: 'Components/Tabs', + component: Tabs, +}; + +export const BasicTabs = () => { + return ( + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam non odio posuere, ultricies quam at, tempor nisl. Mauris ultrices, nisi at viverra fringilla, sapien nulla congue lacus, eget faucibus justo mauris et est. Nunc pharetra porta nisi, in bibendum justo sollicitudin vitae. Sed tristique semper mi. Vivamus sit amet sagittis nisi. Etiam faucibus erat in rutrum dictum. Vivamus a metus non nisi imperdiet euismod. Integer condimentum faucibus eros aliquam rhoncus. Mauris at mauris eget risus malesuada sollicitudin. Mauris fermentum neque sed fringilla consequat. Aenean mattis auctor mi, sit amet fringilla justo imperdiet at. Nullam ac blandit lorem. Integer nec nisl a diam facilisis venenatis. + + + Etiam eget nulla vulputate, lacinia magna eu, malesuada odio. Suspendisse dignissim odio quis consectetur efficitur. Fusce feugiat arcu libero, in egestas mi faucibus eu. Sed rutrum fringilla diam volutpat mollis. Mauris nec nibh pretium, auctor felis quis, ornare mi. Mauris quis lobortis dui, nec congue leo. Proin sodales ligula in lorem gravida congue. Duis nec tellus et elit finibus viverra ac vitae neque. Suspendisse efficitur, dui in vulputate fermentum, risus justo finibus purus, et consectetur risus nulla sed est. Vivamus sollicitudin nisl a orci semper, sit amet semper nibh feugiat. Sed quis ipsum porta, hendrerit tellus nec, aliquet neque. Sed elementum lacinia eros, at rutrum leo pharetra eu. Praesent at lectus nec diam tincidunt varius sagittis non massa. Sed tempus vel nulla eu feugiat. In aliquet odio et sapien iaculis sagittis. + + + Donec sit amet cursus dolor. Cras euismod magna scelerisque, ultrices magna eget, posuere leo. Duis feugiat nec leo ultrices feugiat. Sed justo enim, semper vel tincidunt vel, porta auctor sapien. Aliquam quis maximus enim, non laoreet orci. Phasellus rutrum eros nec eros mollis, nec sagittis risus sollicitudin. Phasellus egestas felis nec turpis egestas, in ultricies urna bibendum. Etiam a sapien vitae ante rutrum aliquam facilisis at felis. Sed tincidunt quam nunc, eget finibus orci tristique sit amet. Sed ac mollis magna. + + + ) +} \ No newline at end of file diff --git a/packages/tabs/tsconfig.json b/packages/tabs/tsconfig.json new file mode 100644 index 0000000..cc96381 --- /dev/null +++ b/packages/tabs/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true, + "types": ["vite/client", "vitest"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../tsconfig.base.json" +} diff --git a/packages/tabs/tsconfig.lib.json b/packages/tabs/tsconfig.lib.json new file mode 100644 index 0000000..8d6bbf7 --- /dev/null +++ b/packages/tabs/tsconfig.lib.json @@ -0,0 +1,23 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": [ + "node", + "@nx/react/typings/cssmodule.d.ts", + "@nx/react/typings/image.d.ts", + "vite/client" + ] + }, + "exclude": [ + "**/*.spec.ts", + "**/*.test.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "**/*.spec.js", + "**/*.test.js", + "**/*.spec.jsx", + "**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/packages/tabs/tsconfig.spec.json b/packages/tabs/tsconfig.spec.json new file mode 100644 index 0000000..d231383 --- /dev/null +++ b/packages/tabs/tsconfig.spec.json @@ -0,0 +1,25 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/packages/tabs/vite.config.ts b/packages/tabs/vite.config.ts new file mode 100644 index 0000000..3db5cb0 --- /dev/null +++ b/packages/tabs/vite.config.ts @@ -0,0 +1,52 @@ +/// +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import dts from 'vite-plugin-dts'; +import * as path from 'path'; +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; + +export default defineConfig({ + cacheDir: '../../node_modules/.vite/tabs', + + plugins: [ + react(), + nxViteTsPaths(), + dts({ + entryRoot: 'src', + tsConfigFilePath: path.join(__dirname, 'tsconfig.lib.json'), + skipDiagnostics: true, + }), + ], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + // Configuration for building your library. + // See: https://vitejs.dev/guide/build.html#library-mode + build: { + lib: { + // Could also be a dictionary or array of multiple entry points. + entry: 'src/index.ts', + name: 'tabs', + fileName: 'index', + // Change this to the formats you want to support. + // Don't forget to update your package.json as well. + formats: ['es', 'cjs'], + }, + rollupOptions: { + // External packages that should not be bundled into your library. + external: ['react', 'react-dom', 'react/jsx-runtime'], + }, + }, + + test: { + globals: true, + cache: { + dir: '../../node_modules/.vitest', + }, + environment: 'jsdom', + include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + }, +}); diff --git a/tsconfig.base.json b/tsconfig.base.json index 193cd63..f6ef088 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -19,13 +19,14 @@ "@bootwind/forms": ["packages/forms/src/index.ts"], "@bootwind/modal": ["packages/modal/src/index.ts"], "@bootwind/pagination": ["packages/pagination/src/index.ts"], + "@bootwind/slider": ["packages/slider/src/index.ts"], + "@bootwind/table": ["packages/table/src/index.ts"], "@bootwind/title": ["./packages/title/src/index.ts"], "@bootwind/toast": ["./packages/toast/src/index.ts"], + "@bootwind/tooltip": ["packages/tooltip/src/index.ts"], "@bootwind/typography": ["packages/typography/src/index.ts"], "@bootwind/ui": ["./packages/ui/src/index.ts"], - "@bootwind/slider": ["packages/slider/src/index.ts"], - "@bootwind/table": ["packages/table/src/index.ts"], - "@bootwind/tooltip": ["packages/tooltip/src/index.ts"] + "@bootwind/tabs": ["packages/tabs/src/index.ts"] } } }