Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup ui components package #3 #4

Merged
merged 7 commits into from
Feb 13, 2024
Merged

Setup ui components package #3 #4

merged 7 commits into from
Feb 13, 2024

Conversation

hyukkwonepic
Copy link
Member

@hyukkwonepic hyukkwonepic commented Feb 9, 2024

Works done

Video explanation

  • Created ui package with 'create-vite'.
  • Made the vite build results are separated by components
    • const componentsDir = resolve(__dirname, "src/components");
      const getFiles = (dir: string): string[] => {
      const dirents = readdirSync(dir, { withFileTypes: true });
      const files = dirents.map((dirent) => {
      const res = resolve(dir, dirent.name);
      return dirent.isDirectory() ? getFiles(res) : res;
      });
      return Array.prototype.concat(...files);
      };
      const components = getFiles(componentsDir);
      const entry = components.reduce(
      (entries, componentPath) => {
      const key = componentPath
      .replace(componentsDir, "components")
      .replace(".tsx", "");
      return { ...entries, [key]: componentPath };
      },
      {
      index: resolve(__dirname, "src/index.ts"),
      }
      );
    • Due to the usage of the client component, bundling it in one file and importing it from the nextjs server component triggers an error. For example, import { Button } from 'ui' in the server component triggers an error even when the Button component is not a client component but the bundle includes another client component.
    • The build results are like this:
      /dist
        /components
         / shadcn-ui/
            button.js (not a client component)
            accordion.js (client component)
            ...
      
      The package's consumer can import as import { Button } from 'ui/shadcn-ui/button making sure only the button component is imported. So it doesn't trigger a nextjs client component error.
  • Setup the package path
    "exports": {
    "./*": {
    "import": "./dist/components/*.es.js",
    "types": "./dist/components/*.d.ts"
    },
    "./shadcn-ui": {
    "import": "./dist/components/shadcn-ui/*.es.js",
    "types": "./dist/components/shadcn-ui/*.d.ts"
    },
    "./dist/style.css": "./dist/style.css"
    },
    • The library can be imported as ui/button, ui/shadcn-ui/accordion
  • Added ui package as "ui": "workspace:*" in the dailyscrum app.
  • Setup to use ui package components
    • import "ui/dist/style.css";
    • "use client";
      import { Button } from "ui/button";
      import {
      Accordion,
      AccordionContent,
      AccordionItem,
      AccordionTrigger,
      } from "ui/shadcn-ui/accordion";
      export default function Page() {
      return (
      <>
      <Button>Hey</Button>
      <Accordion type="single" collapsible className="w-full">
      <AccordionItem value="item-1">
      <AccordionTrigger>Is it accessible?</AccordionTrigger>
      <AccordionContent>
      Yes. It adheres to the WAI-ARIA design pattern.
      </AccordionContent>
      </AccordionItem>
      <AccordionItem value="item-2">
      <AccordionTrigger>Is it styled?</AccordionTrigger>
      <AccordionContent>
      Yes. It comes with default styles that matches the other
      components&apos; aesthetic.
      </AccordionContent>
      </AccordionItem>
      <AccordionItem value="item-3">
      <AccordionTrigger>Is it animated?</AccordionTrigger>
      <AccordionContent>
      Yes. It&apos;s animated by default, but you can disable it if you
      prefer.
      </AccordionContent>
      </AccordionItem>
      </Accordion>
      </>
      );
      }
  • Added nx target dependency for the build. Building dailyscrum automatically builds its workspace dependency, which is ui in this case.
    • dailyscrum/nx.json

      Lines 1 to 10 in 016de5a

      {
      "targetDefaults": {
      "build": {
      "dependsOn": ["^build"]
      },
      "dev": {
      "dependsOn": []
      }
      }
      }
  • Created a custom button component that expands shadcn-ui/button
    type BaseButtonVariants = VariantProps<typeof ShadcnButton.buttonVariants>;
    type ExtendedButtonVariants = Omit<BaseButtonVariants, "size"> & {
    size?: BaseButtonVariants["size"] | "icon-sm";
    };
    • Added a 'icon-sm' variant
  • All shadcn-ui components are generated with shadcn-ui cli. Located in components/shadcn-ui dir.
  • Resolved typescript issue of pnpm soft linked type inferring.
    declare module "class-variance-authority/types" {
    export type ClassPropKey = "class" | "className";
    export type ClassValue = CLSX.ClassValue;
    export type ClassProp =
    | {
    class: ClassValue;
    className?: never;
    }
    | {
    class?: never;
    className: ClassValue;
    }
    | {
    class?: never;
    className?: never;
    };
    export type OmitUndefined<T> = T extends undefined ? never : T;
    export type StringToBoolean<T> = T extends "true" | "false" ? boolean : T;
    }
    • Explicitly declared the type that typescript couldn't get in global.d.ts

Resolve #3

- Formatted all files with prettier

Resolve #3
- Remove unnecessary config of nx.json
- Removed unnecessary setting
- Removed unnecessary vite config
- Refactor package ui usage example
- Removed unused configs
@hyukkwonepic hyukkwonepic merged commit d1b2cc8 into main Feb 13, 2024
@hyukkwonepic hyukkwonepic deleted the feature/#3 branch February 13, 2024 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Setup ui components package
1 participant