ui icon indicating copy to clipboard operation
ui copied to clipboard

Add an example of how to integrate with Deno-Fresh using Twind

Open thesobercoder opened this issue 2 years ago • 2 comments

It would be great if the docs added an example of how to set up shadcn/ui re-usable components in a Deno-Fresh project that uses Twind.

thesobercoder avatar May 04 '23 12:05 thesobercoder

I am not using Deno Fresh, but successfully added shadcn/ui to my internal React components lib with Twind.

As we are using Twind, we don't have a global stylesheet and therefore can't use CSS Variables for theming. However, there is still the config object that you can pass to defineConfig. I did it like so:

import { defineConfig } from '@twind/core';
import presetAutoprefix from '@twind/preset-autoprefix';
import presetTailwind from '@twind/preset-tailwind';
import { fontFamily } from 'tailwindcss/defaultTheme';

export default defineConfig({
  presets: [presetAutoprefix(), presetTailwind()],
  theme: {
    container: {
      center: true,
      padding: '2rem',
      screens: {
        '2xl': '1400px',
      },
    },
    extend: {
      colors: {
        border: 'hsl(213,9%,23%)',
        input: 'hsl(213,9%,23%)',
        ring: 'hsl(215,20.2%,65.1%)',
        background: 'hsl(213,10%,18%)',
        foreground: 'hsl(213,31%,91%)',
        primary: {
          DEFAULT: 'hsl(197,71%,62%)',
          foreground: 'hsl(0,0%,100%)',
        },
        secondary: {
          DEFAULT: 'hsl(213,9%,23%)',
          foreground: 'hsl(0,0%,100%)',
        },
        destructive: {
          DEFAULT: 'hsl(0,63%,31%)',
          foreground: 'hsl(210,40%,98%)',
        },
        muted: {
          DEFAULT: 'hsl(223,47%,11%)',
          foreground: 'hsl(,15.4 16.3%,56.9%)',
        },
        accent: {
          DEFAULT: 'hsl(214,12%,67%)',
          foreground: 'hsl(210,40%,98%)',
        },
        popover: {
          DEFAULT: 'hsl(224,71%,4%)',
          foreground: 'hsl(215,20.2%,65.1%)',
        },
        card: {
          DEFAULT: 'hsl(224,71%,4%)',
          foreground: 'hsl(213,31%,91%)',
        },
      },
      borderRadius: {
        extra: '0.8rem',
        lg: `0.5rem`,
        md: `calc(0.5rem - 2px)`,
        sm: 'calc(0.5rem - 4px)',
      },
      boxShadow: {
        'dark-sm': '0 0 0 1px rgba(16, 22, 26, 0.4)',
      },
      fontFamily: {
        sans: ['var(--font-sans)', ...fontFamily.sans],
      },
      keyframes: {
        'accordion-down': {
          from: { height: 0 },
          to: { height: 'var(--radix-accordion-content-height)' },
        },
        'accordion-up': {
          from: { height: 'var(--radix-accordion-content-height)' },
          to: { height: 0 },
        },
      },
      animation: {
        'accordion-down': 'accordion-down 0.2s ease-out',
        'accordion-up': 'accordion-up 0.2s ease-out',
      },
    },
  },
});

If you wanted to use a dark mode, you could do it this way:

import { defineConfig } from '@twind/core';
import presetAutoprefix from '@twind/preset-autoprefix';
import presetTailwind from '@twind/preset-tailwind';
import { fontFamily } from 'tailwindcss/defaultTheme';

export default defineConfig({
  presets: [presetAutoprefix(), presetTailwind()],
  darkMode: 'class',
  darkColor: (section, key, { theme }) => theme(`${section}.dark.${key}`) as ColorValue,
  theme: {
    container: {
      center: true,
      padding: '2rem',
      screens: {
        '2xl': '1400px',
      },
    },
    extend: {
      colors: {
        border: 'hsl(213,9%,23%)',
        input: 'hsl(213,9%,23%)',
        ring: 'hsl(215,20.2%,65.1%)',
        background: 'hsl(213,10%,18%)',
        foreground: 'hsl(213,31%,91%)',
        primary: {
          DEFAULT: 'hsl(197,71%,62%)',
          foreground: 'hsl(0,0%,100%)',
        },
        secondary: {
          DEFAULT: 'hsl(213,9%,23%)',
          foreground: 'hsl(0,0%,100%)',
        },
        destructive: {
          DEFAULT: 'hsl(0,63%,31%)',
          foreground: 'hsl(210,40%,98%)',
        },
        muted: {
          DEFAULT: 'hsl(223,47%,11%)',
          foreground: 'hsl(,15.4 16.3%,56.9%)',
        },
        accent: {
          DEFAULT: 'hsl(214,12%,67%)',
          foreground: 'hsl(210,40%,98%)',
        },
        popover: {
          DEFAULT: 'hsl(224,71%,4%)',
          foreground: 'hsl(215,20.2%,65.1%)',
        },
        card: {
          DEFAULT: 'hsl(224,71%,4%)',
          foreground: 'hsl(213,31%,91%)',
        },
        dark: {
          border: 'hsl(213,9%,23%)',
          input: 'hsl(213,9%,23%)',
          ring: 'hsl(215,20.2%,65.1%)',
          background: 'hsl(213,10%,18%)',
          foreground: 'hsl(213,31%,91%)',
          primary: {
            DEFAULT: 'hsl(197,71%,62%)',
            foreground: 'hsl(0,0%,100%)',
          },
          secondary: {
            DEFAULT: 'hsl(213,9%,23%)',
            foreground: 'hsl(0,0%,100%)',
          },
          destructive: {
            DEFAULT: 'hsl(0,63%,31%)',
            foreground: 'hsl(210,40%,98%)',
          },
          muted: {
            DEFAULT: 'hsl(223,47%,11%)',
            foreground: 'hsl(,15.4 16.3%,56.9%)',
          },
          accent: {
            DEFAULT: 'hsl(214,12%,67%)',
            foreground: 'hsl(210,40%,98%)',
          },
          popover: {
            DEFAULT: 'hsl(224,71%,4%)',
            foreground: 'hsl(215,20.2%,65.1%)',
          },
          card: {
            DEFAULT: 'hsl(224,71%,4%)',
            foreground: 'hsl(213,31%,91%)',
          },
        },
      },
      borderRadius: {
        extra: '0.8rem',
        lg: `0.5rem`,
        md: `calc(0.5rem - 2px)`,
        sm: 'calc(0.5rem - 4px)',
      },
      boxShadow: {
        'dark-sm': '0 0 0 1px rgba(16, 22, 26, 0.4)',
      },
      fontFamily: {
        sans: ['var(--font-sans)', ...fontFamily.sans],
      },
      keyframes: {
        'accordion-down': {
          from: { height: 0 },
          to: { height: 'var(--radix-accordion-content-height)' },
        },
        'accordion-up': {
          from: { height: 'var(--radix-accordion-content-height)' },
          to: { height: 0 },
        },
      },
      animation: {
        'accordion-down': 'accordion-down 0.2s ease-out',
        'accordion-up': 'accordion-up 0.2s ease-out',
      },
    },
  },
});

The class .dark would need to be added in your DOM somewhere (e.g. <body /> tag) Then somewhere in your code you would need to setup Twind:

import { setup } from '@twind/core';
import { config } from './config.ts';

setup(config);

You can then import your components using the cli command $ npx shadcn-ui add [component]. Although this might not be working 100% - I believe animation might need some work. There is also the question about updates and the components.json file. Not sure how to make that work.

P.S: Please note that I did not change the color values in dark mode. It was just as an example. Just change the values to match your need.

edouardr avatar Jun 22 '23 19:06 edouardr

A repo to testing shadcn-ui in Fresh: https://github.com/nikogoli/testing-shadcn-ui-in-fresh Demo: https://testing-shadcn-ui-in-fresh.deno.dev/

ooker777 avatar Mar 24 '24 12:03 ooker777

This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.

shadcn avatar Jul 02 '24 23:07 shadcn