@taicode/common-web 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taicode/common-web",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "author": "Alain",
5
5
  "license": "ISC",
6
6
  "description": "",
@@ -9,12 +9,24 @@
9
9
  "dev": "tsc -p tsconfig.json --watch"
10
10
  },
11
11
  "peerDependencies": {
12
+ "@types/react": ">=18",
12
13
  "mobx": ">=6",
13
- "react": ">=18",
14
- "@types/react": ">=18"
14
+ "react": ">=18"
15
15
  },
16
16
  "exports": {
17
- "./utils/*": ["./output/utils/*"],
18
- "./hooks/*": ["./output/hooks/*"]
17
+ "./utils/*": [
18
+ "./output/utils/*"
19
+ ],
20
+ "./hooks/*": [
21
+ "./output/hooks/*"
22
+ ],
23
+ "./catalyst/*": [
24
+ "./output/catalyst/*"
25
+ ]
26
+ },
27
+ "dependencies": {
28
+ "@headlessui/react": "^2.2.4",
29
+ "clsx": "^2.1.1",
30
+ "framer-motion": "^12.19.2"
19
31
  }
20
32
  }
@@ -0,0 +1,136 @@
1
+ # Changelog
2
+
3
+ ## 2025-06-05
4
+
5
+ - Update `DropdownLabel` to extend a plain `<div>` instead of the `Headless.Label` ([#1699](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1699))
6
+
7
+ ## 2025-04-28
8
+
9
+ - Update template to Tailwind CSS v4.1.4
10
+
11
+ ## 2025-04-22
12
+
13
+ - Fix focus styles in the `Avatar`, `Badge`, `Button`, `Checkbox`, and `Switch` components ([#1693](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1693))
14
+
15
+ ## 2025-04-17
16
+
17
+ - Update `@headlessui/react` dependency to `v2.2.2` to fix listbox performance issues ([#1667](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1667))
18
+
19
+ ## 2025-04-04
20
+
21
+ - Add new `Combobox` component
22
+ - Add new `AuthLayout` component, with example login page, registration page, and forgot password page
23
+ - Fix centering of checkboxes, radios, and switches in fields with multi-line labels
24
+ - Update template to Tailwind CSS v4.1.3
25
+ - Update template to Headless UI v2.2.1 (required for new `Combobox` component)
26
+
27
+ ## 2025-03-24
28
+
29
+ - Adjust avatar ring opacity from 20% to 10%
30
+
31
+ ## 2025-03-22
32
+
33
+ - Update template to Tailwind CSS v4.0.15
34
+
35
+ ## 2025-02-22
36
+
37
+ - Fix border radius of avatars in navbar items
38
+
39
+ ## 2025-02-12
40
+
41
+ - Fix baseline alignment for buttons with icons ([#1668](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1668))
42
+
43
+ ## 2025-02-10
44
+
45
+ - Update template to Tailwind CSS v4.0.6
46
+
47
+ ## 2025-01-29
48
+
49
+ - Fix conflicting outline utilities ([#1661](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1661))
50
+
51
+ ## 2025-01-23
52
+
53
+ - Update template to Tailwind CSS v4.0
54
+
55
+ ## 2024-10-31
56
+
57
+ - Fix `disabled` prop in `DropdownItem` component ([#1640](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1640))
58
+ - Update types in `SidebarItem` component
59
+
60
+ ## 2024-06-09
61
+
62
+ - Omit `as` prop from types for Headless UI-based components
63
+
64
+ ## 2024-06-26
65
+
66
+ - Update `@headlessui/react` dependency to `v2.1.1`
67
+ - Update `Dialog`, `Alert`, and `Listbox` to new data-attribute-based transition API
68
+
69
+ ## 2024-06-21
70
+
71
+ - Update `@headlessui/react` dependency to `v2.1.0`
72
+ - Use `DialogBackdrop` in `Alert` and `Dialog` components
73
+ - Update to new data-attribute-based transition API
74
+
75
+ ## 2024-06-19
76
+
77
+ - Prevent content from overflowing the mobile sidebar
78
+
79
+ ## 2024-06-18
80
+
81
+ - Use consistent `let` and `const` declarations
82
+ - Use consistent `clsx` import
83
+ - Use consistent `forwardRef` instead of `React.forwardRef` import
84
+ - Update `tailwindcss`, `prettier` and `prettier-plugin-tailwindcss` dependencies in Next.js demo app
85
+ - Fix class order in `Dropdown` component
86
+
87
+ ## 2024-06-10
88
+
89
+ - Add `dark:[color-scheme:dark]` class to `Input` component ([#1596](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1596))
90
+
91
+ ## 2024-05-31
92
+
93
+ - Add Next.js demo app ([#1580](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1580))
94
+ - Fix `Avatar` sizing and padding ([#1588](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1588))
95
+
96
+ ## 2024-05-27
97
+
98
+ - Add `pointer-events-none` to `InputGroup` icon ([#1594](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1594))
99
+ - Add default text color to `Table` component ([#1581](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1581))
100
+ - Fix TypeScript issues when using `as={Link}` ([#1582](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1582))
101
+ - Fix `SidebarItem` import ([#1582](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1582))
102
+ - Add `isolate` class to `InputGroup`, `SidebarLayout`, and `StackedLayout` components
103
+ - Fix comment indentation and use proper DocBlocks
104
+
105
+ ## 2024-05-24
106
+
107
+ - Add new `SidebarLayout` component
108
+ - Add new `StackedLayout` component
109
+ - Add new `Navbar` component
110
+ - Add new `Sidebar` component
111
+ - Add new `DescriptionList` component
112
+ - Add new `Heading` component
113
+ - Add new `Divider` component
114
+ - Add new `framer-motion` dependency
115
+ - Update `@headlessui/react` dependency to `v2.0`
116
+ - Remove `as={Fragment}` from the transition components
117
+ - Improve and fix a number of types
118
+ - Made formatting of `className` and `{...prop}` more consistent across all components
119
+ - Made formatting of `forwardRef` consistent across all components
120
+ - Update `PaginationGap` component to use a `span` instead of a `div`
121
+ - Update the `SidebarHeading` to render use an `h3` instead of a `d`iv
122
+ - Remove `children` prop from `Switch` component
123
+
124
+ ## 2024-01-08
125
+
126
+ - Add `resizable` prop to `Textarea` component ([#1543](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1543))
127
+
128
+ ## 2024-01-03
129
+
130
+ - Change top-level `let` declarations to `const`
131
+ - Fix `--btn-hover-overlay` color for dark/white button ([#1538](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1538))
132
+ - Add `forwardRef` to `Input`, `Select`, and `Textarea` components ([#1540](https://github.com/tailwindlabs/tailwind-plus-issues/issues/1540))
133
+
134
+ ## 2023-12-20
135
+
136
+ - Initial release
@@ -0,0 +1,65 @@
1
+ # Catalyst UI Kit
2
+
3
+ Catalyst is a modern application UI kit built with [Tailwind CSS](https://tailwindcss.com) and [React](https://react.dev/), designed and built by the Tailwind CSS team and included as part of [Tailwind Plus](https://tailwindcss.com/plus).
4
+
5
+ ## Getting started
6
+
7
+ To get started, first copy the component files included in the downloaded ZIP file into wherever you keep components in your own project. The components are provided in both TypeScript and plain JavaScript, pick whichever set you prefer.
8
+
9
+ Next, install the dependencies used by the components in Catalyst:
10
+
11
+ ```sh
12
+ npm install @headlessui/react framer-motion clsx
13
+ ```
14
+
15
+ Catalyst is also designed for the latest version of Tailwind CSS, which is currently Tailwind CSS v4.0. To make sure that you are on the latest version of Tailwind, update it via npm:
16
+
17
+ ```sh
18
+ npm install tailwindcss@latest
19
+ ```
20
+
21
+ Now you're ready to start using the components in your project — just import them from wherever you're keeping your components and start using them like any of your other React components:
22
+
23
+ ```jsx
24
+ import { Input } from './components/input'
25
+ import { Field, FieldGroup, Label } from './components/fieldset'
26
+ import { Button } from './components/button'
27
+
28
+ export default function SettingsForm() {
29
+ return (
30
+ <form>
31
+ <FieldGroup>
32
+ <Field>
33
+ <Label>Name</Label>
34
+ <Input name="name" />
35
+ </Field>
36
+ <Field>
37
+ <Label>Email</Label>
38
+ <Input type="email" name="email" />
39
+ </Field>
40
+ <Button type="submit">Save changes</Button>
41
+ </FieldGroup>
42
+ </form>
43
+ )
44
+ }
45
+ ```
46
+
47
+ Additional installation instructions can be found in the Catalyst documentation.
48
+
49
+ ## Documentation
50
+
51
+ You can find the Catalyst documentation at https://catalyst.tailwindui.com/docs.
52
+
53
+ ## License
54
+
55
+ This site template is a commercial product and is licensed under the [Tailwind Plus license](https://tailwindcss.com/plus/license).
56
+
57
+ ## Learn more
58
+
59
+ To learn more about the technologies used in this site template, see the following resources:
60
+
61
+ - [Tailwind CSS](https://tailwindcss.com/docs) - the official Tailwind CSS documentation
62
+ - [Headless UI](https://headlessui.dev) - the official Headless UI documentation
63
+ - [React](https://react.dev) - the official React documentation
64
+ - [Framer Motion](https://www.framer.com/docs/) - the official Framer Motion documentation
65
+ - [clsx](https://github.com/lukeed/clsx) - the GitHub repo for the `clsx` helper
@@ -0,0 +1,95 @@
1
+ import * as Headless from '@headlessui/react'
2
+ import clsx from 'clsx'
3
+ import type React from 'react'
4
+ import { Text } from './text'
5
+
6
+ const sizes = {
7
+ xs: 'sm:max-w-xs',
8
+ sm: 'sm:max-w-sm',
9
+ md: 'sm:max-w-md',
10
+ lg: 'sm:max-w-lg',
11
+ xl: 'sm:max-w-xl',
12
+ '2xl': 'sm:max-w-2xl',
13
+ '3xl': 'sm:max-w-3xl',
14
+ '4xl': 'sm:max-w-4xl',
15
+ '5xl': 'sm:max-w-5xl',
16
+ }
17
+
18
+ export function Alert({
19
+ size = 'md',
20
+ className,
21
+ children,
22
+ ...props
23
+ }: { size?: keyof typeof sizes; className?: string; children: React.ReactNode } & Omit<
24
+ Headless.DialogProps,
25
+ 'as' | 'className'
26
+ >) {
27
+ return (
28
+ <Headless.Dialog {...props}>
29
+ <Headless.DialogBackdrop
30
+ transition
31
+ className="fixed inset-0 flex w-screen justify-center overflow-y-auto bg-zinc-950/15 px-2 py-2 transition duration-100 focus:outline-0 data-closed:opacity-0 data-enter:ease-out data-leave:ease-in sm:px-6 sm:py-8 lg:px-8 lg:py-16 dark:bg-zinc-950/50"
32
+ />
33
+
34
+ <div className="fixed inset-0 w-screen overflow-y-auto pt-6 sm:pt-0">
35
+ <div className="grid min-h-full grid-rows-[1fr_auto_1fr] justify-items-center p-8 sm:grid-rows-[1fr_auto_3fr] sm:p-4">
36
+ <Headless.DialogPanel
37
+ transition
38
+ className={clsx(
39
+ className,
40
+ sizes[size],
41
+ 'row-start-2 w-full rounded-2xl bg-white p-8 shadow-lg ring-1 ring-zinc-950/10 sm:rounded-2xl sm:p-6 dark:bg-zinc-900 dark:ring-white/10 forced-colors:outline',
42
+ 'transition duration-100 will-change-transform data-closed:opacity-0 data-enter:ease-out data-closed:data-enter:scale-95 data-leave:ease-in'
43
+ )}
44
+ >
45
+ {children}
46
+ </Headless.DialogPanel>
47
+ </div>
48
+ </div>
49
+ </Headless.Dialog>
50
+ )
51
+ }
52
+
53
+ export function AlertTitle({
54
+ className,
55
+ ...props
56
+ }: { className?: string } & Omit<Headless.DialogTitleProps, 'as' | 'className'>) {
57
+ return (
58
+ <Headless.DialogTitle
59
+ {...props}
60
+ className={clsx(
61
+ className,
62
+ 'text-center text-base/6 font-semibold text-balance text-zinc-950 sm:text-left sm:text-sm/6 sm:text-wrap dark:text-white'
63
+ )}
64
+ />
65
+ )
66
+ }
67
+
68
+ export function AlertDescription({
69
+ className,
70
+ ...props
71
+ }: { className?: string } & Omit<Headless.DescriptionProps<typeof Text>, 'as' | 'className'>) {
72
+ return (
73
+ <Headless.Description
74
+ as={Text}
75
+ {...props}
76
+ className={clsx(className, 'mt-2 text-center text-pretty sm:text-left')}
77
+ />
78
+ )
79
+ }
80
+
81
+ export function AlertBody({ className, ...props }: React.ComponentPropsWithoutRef<'div'>) {
82
+ return <div {...props} className={clsx(className, 'mt-4')} />
83
+ }
84
+
85
+ export function AlertActions({ className, ...props }: React.ComponentPropsWithoutRef<'div'>) {
86
+ return (
87
+ <div
88
+ {...props}
89
+ className={clsx(
90
+ className,
91
+ 'mt-6 flex flex-col-reverse items-center justify-end gap-3 *:w-full sm:mt-4 sm:flex-row sm:*:w-auto'
92
+ )}
93
+ />
94
+ )
95
+ }
@@ -0,0 +1,11 @@
1
+ import type React from 'react'
2
+
3
+ export function AuthLayout({ children }: { children: React.ReactNode }) {
4
+ return (
5
+ <main className="flex min-h-dvh flex-col p-2">
6
+ <div className="flex grow items-center justify-center p-6 lg:rounded-lg lg:bg-white lg:p-10 lg:shadow-xs lg:ring-1 lg:ring-zinc-950/5 dark:lg:bg-zinc-900 dark:lg:ring-white/10">
7
+ {children}
8
+ </div>
9
+ </main>
10
+ )
11
+ }
@@ -0,0 +1,84 @@
1
+ import * as Headless from '@headlessui/react'
2
+ import clsx from 'clsx'
3
+ import React, { forwardRef } from 'react'
4
+ import { TouchTarget } from './button'
5
+ import { Link } from './link'
6
+
7
+ type AvatarProps = {
8
+ src?: string | null
9
+ square?: boolean
10
+ initials?: string
11
+ alt?: string
12
+ className?: string
13
+ }
14
+
15
+ export function Avatar({
16
+ src = null,
17
+ square = false,
18
+ initials,
19
+ alt = '',
20
+ className,
21
+ ...props
22
+ }: AvatarProps & React.ComponentPropsWithoutRef<'span'>) {
23
+ return (
24
+ <span
25
+ data-slot="avatar"
26
+ {...props}
27
+ className={clsx(
28
+ className,
29
+ // Basic layout
30
+ 'inline-grid shrink-0 align-middle [--avatar-radius:20%] *:col-start-1 *:row-start-1',
31
+ 'outline -outline-offset-1 outline-black/10 dark:outline-white/10',
32
+ // Border radius
33
+ square ? 'rounded-(--avatar-radius) *:rounded-(--avatar-radius)' : 'rounded-full *:rounded-full'
34
+ )}
35
+ >
36
+ {initials && (
37
+ <svg
38
+ className="size-full fill-current p-[5%] text-[48px] font-medium uppercase select-none"
39
+ viewBox="0 0 100 100"
40
+ aria-hidden={alt ? undefined : 'true'}
41
+ >
42
+ {alt && <title>{alt}</title>}
43
+ <text x="50%" y="50%" alignmentBaseline="middle" dominantBaseline="middle" textAnchor="middle" dy=".125em">
44
+ {initials}
45
+ </text>
46
+ </svg>
47
+ )}
48
+ {src && <img className="size-full" src={src} alt={alt} />}
49
+ </span>
50
+ )
51
+ }
52
+
53
+ export const AvatarButton = forwardRef(function AvatarButton(
54
+ {
55
+ src,
56
+ square = false,
57
+ initials,
58
+ alt,
59
+ className,
60
+ ...props
61
+ }: AvatarProps &
62
+ (Omit<Headless.ButtonProps, 'as' | 'className'> | Omit<React.ComponentPropsWithoutRef<typeof Link>, 'className'>),
63
+ ref: React.ForwardedRef<HTMLElement>
64
+ ) {
65
+ let classes = clsx(
66
+ className,
67
+ square ? 'rounded-[20%]' : 'rounded-full',
68
+ 'relative inline-grid focus:not-data-focus:outline-hidden data-focus:outline-2 data-focus:outline-offset-2 data-focus:outline-blue-500'
69
+ )
70
+
71
+ return 'href' in props ? (
72
+ <Link {...props} className={classes} ref={ref as React.ForwardedRef<HTMLAnchorElement>}>
73
+ <TouchTarget>
74
+ <Avatar src={src} square={square} initials={initials} alt={alt} />
75
+ </TouchTarget>
76
+ </Link>
77
+ ) : (
78
+ <Headless.Button {...props} className={classes} ref={ref}>
79
+ <TouchTarget>
80
+ <Avatar src={src} square={square} initials={initials} alt={alt} />
81
+ </TouchTarget>
82
+ </Headless.Button>
83
+ )
84
+ })
@@ -0,0 +1,82 @@
1
+ import * as Headless from '@headlessui/react'
2
+ import clsx from 'clsx'
3
+ import React, { forwardRef } from 'react'
4
+ import { TouchTarget } from './button'
5
+ import { Link } from './link'
6
+
7
+ const colors = {
8
+ red: 'bg-red-500/15 text-red-700 group-data-hover:bg-red-500/25 dark:bg-red-500/10 dark:text-red-400 dark:group-data-hover:bg-red-500/20',
9
+ orange:
10
+ 'bg-orange-500/15 text-orange-700 group-data-hover:bg-orange-500/25 dark:bg-orange-500/10 dark:text-orange-400 dark:group-data-hover:bg-orange-500/20',
11
+ amber:
12
+ 'bg-amber-400/20 text-amber-700 group-data-hover:bg-amber-400/30 dark:bg-amber-400/10 dark:text-amber-400 dark:group-data-hover:bg-amber-400/15',
13
+ yellow:
14
+ 'bg-yellow-400/20 text-yellow-700 group-data-hover:bg-yellow-400/30 dark:bg-yellow-400/10 dark:text-yellow-300 dark:group-data-hover:bg-yellow-400/15',
15
+ lime: 'bg-lime-400/20 text-lime-700 group-data-hover:bg-lime-400/30 dark:bg-lime-400/10 dark:text-lime-300 dark:group-data-hover:bg-lime-400/15',
16
+ green:
17
+ 'bg-green-500/15 text-green-700 group-data-hover:bg-green-500/25 dark:bg-green-500/10 dark:text-green-400 dark:group-data-hover:bg-green-500/20',
18
+ emerald:
19
+ 'bg-emerald-500/15 text-emerald-700 group-data-hover:bg-emerald-500/25 dark:bg-emerald-500/10 dark:text-emerald-400 dark:group-data-hover:bg-emerald-500/20',
20
+ teal: 'bg-teal-500/15 text-teal-700 group-data-hover:bg-teal-500/25 dark:bg-teal-500/10 dark:text-teal-300 dark:group-data-hover:bg-teal-500/20',
21
+ cyan: 'bg-cyan-400/20 text-cyan-700 group-data-hover:bg-cyan-400/30 dark:bg-cyan-400/10 dark:text-cyan-300 dark:group-data-hover:bg-cyan-400/15',
22
+ sky: 'bg-sky-500/15 text-sky-700 group-data-hover:bg-sky-500/25 dark:bg-sky-500/10 dark:text-sky-300 dark:group-data-hover:bg-sky-500/20',
23
+ blue: 'bg-blue-500/15 text-blue-700 group-data-hover:bg-blue-500/25 dark:text-blue-400 dark:group-data-hover:bg-blue-500/25',
24
+ indigo:
25
+ 'bg-indigo-500/15 text-indigo-700 group-data-hover:bg-indigo-500/25 dark:text-indigo-400 dark:group-data-hover:bg-indigo-500/20',
26
+ violet:
27
+ 'bg-violet-500/15 text-violet-700 group-data-hover:bg-violet-500/25 dark:text-violet-400 dark:group-data-hover:bg-violet-500/20',
28
+ purple:
29
+ 'bg-purple-500/15 text-purple-700 group-data-hover:bg-purple-500/25 dark:text-purple-400 dark:group-data-hover:bg-purple-500/20',
30
+ fuchsia:
31
+ 'bg-fuchsia-400/15 text-fuchsia-700 group-data-hover:bg-fuchsia-400/25 dark:bg-fuchsia-400/10 dark:text-fuchsia-400 dark:group-data-hover:bg-fuchsia-400/20',
32
+ pink: 'bg-pink-400/15 text-pink-700 group-data-hover:bg-pink-400/25 dark:bg-pink-400/10 dark:text-pink-400 dark:group-data-hover:bg-pink-400/20',
33
+ rose: 'bg-rose-400/15 text-rose-700 group-data-hover:bg-rose-400/25 dark:bg-rose-400/10 dark:text-rose-400 dark:group-data-hover:bg-rose-400/20',
34
+ zinc: 'bg-zinc-600/10 text-zinc-700 group-data-hover:bg-zinc-600/20 dark:bg-white/5 dark:text-zinc-400 dark:group-data-hover:bg-white/10',
35
+ }
36
+
37
+ type BadgeProps = { color?: keyof typeof colors }
38
+
39
+ export function Badge({ color = 'zinc', className, ...props }: BadgeProps & React.ComponentPropsWithoutRef<'span'>) {
40
+ return (
41
+ <span
42
+ {...props}
43
+ className={clsx(
44
+ className,
45
+ 'inline-flex items-center gap-x-1.5 rounded-md px-1.5 py-0.5 text-sm/5 font-medium sm:text-xs/5 forced-colors:outline',
46
+ colors[color]
47
+ )}
48
+ />
49
+ )
50
+ }
51
+
52
+ export const BadgeButton = forwardRef(function BadgeButton(
53
+ {
54
+ color = 'zinc',
55
+ className,
56
+ children,
57
+ ...props
58
+ }: BadgeProps & { className?: string; children: React.ReactNode } & (
59
+ | Omit<Headless.ButtonProps, 'as' | 'className'>
60
+ | Omit<React.ComponentPropsWithoutRef<typeof Link>, 'className'>
61
+ ),
62
+ ref: React.ForwardedRef<HTMLElement>
63
+ ) {
64
+ let classes = clsx(
65
+ className,
66
+ 'group relative inline-flex rounded-md focus:not-data-focus:outline-hidden data-focus:outline-2 data-focus:outline-offset-2 data-focus:outline-blue-500'
67
+ )
68
+
69
+ return 'href' in props ? (
70
+ <Link {...props} className={classes} ref={ref as React.ForwardedRef<HTMLAnchorElement>}>
71
+ <TouchTarget>
72
+ <Badge color={color}>{children}</Badge>
73
+ </TouchTarget>
74
+ </Link>
75
+ ) : (
76
+ <Headless.Button {...props} className={classes} ref={ref}>
77
+ <TouchTarget>
78
+ <Badge color={color}>{children}</Badge>
79
+ </TouchTarget>
80
+ </Headless.Button>
81
+ )
82
+ })