@usace/groundwork 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/dist/groundwork.es.js +5131 -0
- package/dist/groundwork.umd.js +30 -0
- package/dist/style.css +1 -0
- package/package.json +11 -3
- package/.eslintrc.cjs +0 -18
- package/.github/workflows/deploy-docs.yml +0 -59
- package/.github/workflows/publish.yml +0 -19
- package/index.html +0 -13
- package/lib/catalyst/alert.jsx +0 -110
- package/lib/catalyst/avatar.jsx +0 -64
- package/lib/catalyst/badge.jsx +0 -72
- package/lib/catalyst/checkbox.jsx +0 -160
- package/lib/catalyst/dialog.jsx +0 -101
- package/lib/catalyst/dropdown.jsx +0 -202
- package/lib/catalyst/fieldset.jsx +0 -87
- package/lib/catalyst/input.jsx +0 -78
- package/lib/catalyst/listbox.jsx +0 -195
- package/lib/catalyst/pagination.jsx +0 -75
- package/lib/catalyst/radio.jsx +0 -144
- package/lib/catalyst/select.jsx +0 -78
- package/lib/catalyst/switch.jsx +0 -203
- package/lib/catalyst/textarea.jsx +0 -59
- package/lib/components/breadcrumbs.jsx +0 -46
- package/lib/components/button.jsx +0 -219
- package/lib/components/display/headings.jsx +0 -39
- package/lib/components/display/text.jsx +0 -48
- package/lib/components/hero.jsx +0 -51
- package/lib/components/layout/container.jsx +0 -13
- package/lib/components/layout/usace-box.jsx +0 -26
- package/lib/components/link.jsx +0 -18
- package/lib/components/table.jsx +0 -146
- package/lib/composite/footer/essayons.jsx +0 -12
- package/lib/composite/footer/footer-links.jsx +0 -33
- package/lib/composite/footer/index.jsx +0 -148
- package/lib/composite/footer/logo-banner.jsx +0 -55
- package/lib/composite/footer/social-links.jsx +0 -60
- package/lib/composite/header/index.jsx +0 -83
- package/lib/composite/header/navbar-links.jsx +0 -113
- package/lib/composite/header/usa-banner/USABanner.jsx +0 -114
- package/lib/composite/header/usa-banner/usa-banner.css +0 -220
- package/lib/composite/site-wrapper/index.jsx +0 -52
- package/lib/index.jsx +0 -19
- package/postcss.config.js +0 -6
- package/public/Magnifying_glass_icon.svg +0 -5
- package/public/armystar-logo-rb.svg +0 -4
- package/public/cwbi-logo.png +0 -0
- package/public/essayonscrest.png +0 -0
- package/public/icon-dot-gov.svg +0 -1
- package/public/icon-https.svg +0 -1
- package/public/nww-lucky-peak-dam.jpg +0 -0
- package/public/rsgis-logo.png +0 -0
- package/public/us_flag_small.png +0 -0
- package/public/usace-logo-color.svg +0 -1
- package/src/App.jsx +0 -38
- package/src/app-bundles/index.js +0 -4
- package/src/app-bundles/route-bundle.js +0 -36
- package/src/app-components/code-example.jsx +0 -17
- package/src/app-components/copy-button.jsx +0 -32
- package/src/app-components/props-table.jsx +0 -43
- package/src/app-components/sub-site-banner.jsx +0 -15
- package/src/app-pages/documentation/_docs-page.jsx +0 -31
- package/src/app-pages/documentation/_docs-sidebar.jsx +0 -111
- package/src/app-pages/documentation/_template.jsx +0 -55
- package/src/app-pages/documentation/app-shell/index.jsx +0 -39
- package/src/app-pages/documentation/app-shell/site-wrapper.jsx +0 -190
- package/src/app-pages/documentation/buttons/index.jsx +0 -170
- package/src/app-pages/documentation/index.jsx +0 -57
- package/src/app-pages/documentation/layout/container.jsx +0 -68
- package/src/app-pages/documentation/layout/index.jsx +0 -52
- package/src/app-pages/documentation/layout/usace-box.jsx +0 -76
- package/src/app-pages/documentation/navigation/breadcrumbs.jsx +0 -119
- package/src/app-pages/documentation/navigation/index.jsx +0 -31
- package/src/app-pages/documentation/types/index.jsx +0 -31
- package/src/app-pages/documentation/types/link.jsx +0 -72
- package/src/app-pages/home.jsx +0 -71
- package/src/index.css +0 -3
- package/src/main.jsx +0 -18
- package/tailwind.config.js +0 -31
- package/vite.config.js +0 -46
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { Checkbox as HeadlessCheckbox, Field as HeadlessField } from '@headlessui/react'
|
|
2
|
-
import { clsx } from 'clsx'
|
|
3
|
-
|
|
4
|
-
export function CheckboxGroup({ className, ...props }) {
|
|
5
|
-
return (
|
|
6
|
-
<div
|
|
7
|
-
data-slot="control"
|
|
8
|
-
{...props}
|
|
9
|
-
className={clsx(
|
|
10
|
-
className,
|
|
11
|
-
|
|
12
|
-
// Basic groups
|
|
13
|
-
'space-y-3',
|
|
14
|
-
|
|
15
|
-
// With descriptions
|
|
16
|
-
'has-[[data-slot=description]]:space-y-6 [&_[data-slot=label]]:has-[[data-slot=description]]:font-medium'
|
|
17
|
-
)}
|
|
18
|
-
/>
|
|
19
|
-
)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function CheckboxField({ className, ...props }) {
|
|
23
|
-
return (
|
|
24
|
-
<HeadlessField
|
|
25
|
-
data-slot="field"
|
|
26
|
-
{...props}
|
|
27
|
-
className={clsx(
|
|
28
|
-
className,
|
|
29
|
-
|
|
30
|
-
// Base layout
|
|
31
|
-
'grid grid-cols-[1.125rem_1fr] items-center gap-x-4 gap-y-1 sm:grid-cols-[1rem_1fr]',
|
|
32
|
-
|
|
33
|
-
// Control layout
|
|
34
|
-
'[&>[data-slot=control]]:col-start-1 [&>[data-slot=control]]:row-start-1 [&>[data-slot=control]]:justify-self-center',
|
|
35
|
-
|
|
36
|
-
// Label layout
|
|
37
|
-
'[&>[data-slot=label]]:col-start-2 [&>[data-slot=label]]:row-start-1 [&>[data-slot=label]]:justify-self-start',
|
|
38
|
-
|
|
39
|
-
// Description layout
|
|
40
|
-
'[&>[data-slot=description]]:col-start-2 [&>[data-slot=description]]:row-start-2',
|
|
41
|
-
|
|
42
|
-
// With description
|
|
43
|
-
'[&_[data-slot=label]]:has-[[data-slot=description]]:font-medium'
|
|
44
|
-
)}
|
|
45
|
-
/>
|
|
46
|
-
)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const base = [
|
|
50
|
-
// Basic layout
|
|
51
|
-
'relative isolate flex size-[1.125rem] items-center justify-center rounded-[0.3125rem] sm:size-4',
|
|
52
|
-
|
|
53
|
-
// Background color + shadow applied to inset pseudo element, so shadow blends with border in light mode
|
|
54
|
-
'before:absolute before:inset-0 before:-z-10 before:rounded-[calc(0.3125rem-1px)] before:bg-white before:shadow',
|
|
55
|
-
|
|
56
|
-
// Background color when checked
|
|
57
|
-
'before:group-data-[checked]:bg-[--checkbox-checked-bg]',
|
|
58
|
-
|
|
59
|
-
// Background color is moved to control and shadow is removed in dark mode so hide `before` pseudo
|
|
60
|
-
'dark:before:hidden',
|
|
61
|
-
|
|
62
|
-
// Background color applied to control in dark mode
|
|
63
|
-
'dark:bg-white/5 dark:group-data-[checked]:bg-[--checkbox-checked-bg]',
|
|
64
|
-
|
|
65
|
-
// Border
|
|
66
|
-
'border border-zinc-950/15 group-data-[checked]:border-transparent group-data-[checked]:group-data-[hover]:border-transparent group-data-[hover]:border-zinc-950/30 group-data-[checked]:bg-[--checkbox-checked-border]',
|
|
67
|
-
'dark:border-white/15 dark:group-data-[checked]:border-white/5 dark:group-data-[checked]:group-data-[hover]:border-white/5 dark:group-data-[hover]:border-white/30',
|
|
68
|
-
|
|
69
|
-
// Inner highlight shadow
|
|
70
|
-
'after:absolute after:inset-0 after:rounded-[calc(0.3125rem-1px)] after:shadow-[inset_0_1px_theme(colors.white/15%)]',
|
|
71
|
-
'dark:after:-inset-px dark:after:hidden dark:after:rounded-[0.3125rem] dark:group-data-[checked]:after:block',
|
|
72
|
-
|
|
73
|
-
// Focus ring
|
|
74
|
-
'group-data-[focus]:outline group-data-[focus]:outline-2 group-data-[focus]:outline-offset-2 group-data-[focus]:outline-blue-500',
|
|
75
|
-
|
|
76
|
-
// Disabled state
|
|
77
|
-
'group-data-[disabled]:opacity-50',
|
|
78
|
-
'group-data-[disabled]:border-zinc-950/25 group-data-[disabled]:bg-zinc-950/5 group-data-[disabled]:[--checkbox-check:theme(colors.zinc.950/50%)] group-data-[disabled]:before:bg-transparent',
|
|
79
|
-
'dark:group-data-[disabled]:border-white/20 dark:group-data-[disabled]:bg-white/[2.5%] dark:group-data-[disabled]:[--checkbox-check:theme(colors.white/50%)] dark:group-data-[disabled]:group-data-[checked]:after:hidden',
|
|
80
|
-
|
|
81
|
-
// Forced colors mode
|
|
82
|
-
'forced-colors:[--checkbox-check:HighlightText] forced-colors:[--checkbox-checked-bg:Highlight] forced-colors:group-data-[disabled]:[--checkbox-check:Highlight]',
|
|
83
|
-
'dark:forced-colors:[--checkbox-check:HighlightText] dark:forced-colors:[--checkbox-checked-bg:Highlight] dark:forced-colors:group-data-[disabled]:[--checkbox-check:Highlight]',
|
|
84
|
-
]
|
|
85
|
-
|
|
86
|
-
const colors = {
|
|
87
|
-
'dark/zinc': [
|
|
88
|
-
'[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.zinc.900)] [--checkbox-checked-border:theme(colors.zinc.950/90%)]',
|
|
89
|
-
'dark:[--checkbox-checked-bg:theme(colors.zinc.600)]',
|
|
90
|
-
],
|
|
91
|
-
'dark/white': [
|
|
92
|
-
'[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.zinc.900)] [--checkbox-checked-border:theme(colors.zinc.950/90%)]',
|
|
93
|
-
'dark:[--checkbox-check:theme(colors.zinc.900)] dark:[--checkbox-checked-bg:theme(colors.white)] dark:[--checkbox-checked-border:theme(colors.zinc.950/15%)]',
|
|
94
|
-
],
|
|
95
|
-
white:
|
|
96
|
-
'[--checkbox-check:theme(colors.zinc.900)] [--checkbox-checked-bg:theme(colors.white)] [--checkbox-checked-border:theme(colors.zinc.950/15%)]',
|
|
97
|
-
dark: '[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.zinc.900)] [--checkbox-checked-border:theme(colors.zinc.950/90%)]',
|
|
98
|
-
zinc: '[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.zinc.600)] [--checkbox-checked-border:theme(colors.zinc.700/90%)]',
|
|
99
|
-
red: '[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.red.600)] [--checkbox-checked-border:theme(colors.red.700/90%)]',
|
|
100
|
-
orange:
|
|
101
|
-
'[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.orange.500)] [--checkbox-checked-border:theme(colors.orange.600/90%)]',
|
|
102
|
-
amber:
|
|
103
|
-
'[--checkbox-check:theme(colors.amber.950)] [--checkbox-checked-bg:theme(colors.amber.400)] [--checkbox-checked-border:theme(colors.amber.500/80%)]',
|
|
104
|
-
yellow:
|
|
105
|
-
'[--checkbox-check:theme(colors.yellow.950)] [--checkbox-checked-bg:theme(colors.yellow.300)] [--checkbox-checked-border:theme(colors.yellow.400/80%)]',
|
|
106
|
-
lime: '[--checkbox-check:theme(colors.lime.950)] [--checkbox-checked-bg:theme(colors.lime.300)] [--checkbox-checked-border:theme(colors.lime.400/80%)]',
|
|
107
|
-
green:
|
|
108
|
-
'[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.green.600)] [--checkbox-checked-border:theme(colors.green.700/90%)]',
|
|
109
|
-
emerald:
|
|
110
|
-
'[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.emerald.600)] [--checkbox-checked-border:theme(colors.emerald.700/90%)]',
|
|
111
|
-
teal: '[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.teal.600)] [--checkbox-checked-border:theme(colors.teal.700/90%)]',
|
|
112
|
-
cyan: '[--checkbox-check:theme(colors.cyan.950)] [--checkbox-checked-bg:theme(colors.cyan.300)] [--checkbox-checked-border:theme(colors.cyan.400/80%)]',
|
|
113
|
-
sky: '[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.sky.500)] [--checkbox-checked-border:theme(colors.sky.600/80%)]',
|
|
114
|
-
blue: '[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.blue.600)] [--checkbox-checked-border:theme(colors.blue.700/90%)]',
|
|
115
|
-
indigo:
|
|
116
|
-
'[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.indigo.500)] [--checkbox-checked-border:theme(colors.indigo.600/90%)]',
|
|
117
|
-
violet:
|
|
118
|
-
'[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.violet.500)] [--checkbox-checked-border:theme(colors.violet.600/90%)]',
|
|
119
|
-
purple:
|
|
120
|
-
'[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.purple.500)] [--checkbox-checked-border:theme(colors.purple.600/90%)]',
|
|
121
|
-
fuchsia:
|
|
122
|
-
'[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.fuchsia.500)] [--checkbox-checked-border:theme(colors.fuchsia.600/90%)]',
|
|
123
|
-
pink: '[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.pink.500)] [--checkbox-checked-border:theme(colors.pink.600/90%)]',
|
|
124
|
-
rose: '[--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.rose.500)] [--checkbox-checked-border:theme(colors.rose.600/90%)]',
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export function Checkbox({ color = 'dark/zinc', className, ...props }) {
|
|
128
|
-
return (
|
|
129
|
-
<HeadlessCheckbox
|
|
130
|
-
data-slot="control"
|
|
131
|
-
className={clsx(className, 'group inline-flex focus:outline-none')}
|
|
132
|
-
{...props}
|
|
133
|
-
>
|
|
134
|
-
<span className={clsx([base, colors[color]])}>
|
|
135
|
-
<svg
|
|
136
|
-
className="size-4 stroke-[--checkbox-check] opacity-0 group-data-[checked]:opacity-100 sm:h-3.5 sm:w-3.5"
|
|
137
|
-
viewBox="0 0 14 14"
|
|
138
|
-
fill="none"
|
|
139
|
-
>
|
|
140
|
-
{/* Checkmark icon */}
|
|
141
|
-
<path
|
|
142
|
-
className="opacity-100 group-data-[indeterminate]:opacity-0"
|
|
143
|
-
d="M3 8L6 11L11 3.5"
|
|
144
|
-
strokeWidth={2}
|
|
145
|
-
strokeLinecap="round"
|
|
146
|
-
strokeLinejoin="round"
|
|
147
|
-
/>
|
|
148
|
-
{/* Indeterminate icon */}
|
|
149
|
-
<path
|
|
150
|
-
className="opacity-0 group-data-[indeterminate]:opacity-100"
|
|
151
|
-
d="M3 7H11"
|
|
152
|
-
strokeWidth={2}
|
|
153
|
-
strokeLinecap="round"
|
|
154
|
-
strokeLinejoin="round"
|
|
155
|
-
/>
|
|
156
|
-
</svg>
|
|
157
|
-
</span>
|
|
158
|
-
</HeadlessCheckbox>
|
|
159
|
-
)
|
|
160
|
-
}
|
package/lib/catalyst/dialog.jsx
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Description as HeadlessDescription,
|
|
3
|
-
Dialog as HeadlessDialog,
|
|
4
|
-
DialogPanel as HeadlessDialogPanel,
|
|
5
|
-
DialogTitle as HeadlessDialogTitle,
|
|
6
|
-
Transition as HeadlessTransition,
|
|
7
|
-
TransitionChild as HeadlessTransitionChild,
|
|
8
|
-
} from '@headlessui/react'
|
|
9
|
-
import clsx from 'clsx'
|
|
10
|
-
import { Fragment } from 'react'
|
|
11
|
-
import { Text } from './text'
|
|
12
|
-
|
|
13
|
-
const sizes = {
|
|
14
|
-
xs: 'sm:max-w-xs',
|
|
15
|
-
sm: 'sm:max-w-sm',
|
|
16
|
-
md: 'sm:max-w-md',
|
|
17
|
-
lg: 'sm:max-w-lg',
|
|
18
|
-
xl: 'sm:max-w-xl',
|
|
19
|
-
'2xl': 'sm:max-w-2xl',
|
|
20
|
-
'3xl': 'sm:max-w-3xl',
|
|
21
|
-
'4xl': 'sm:max-w-4xl',
|
|
22
|
-
'5xl': 'sm:max-w-5xl',
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function Dialog({ open, onClose, size = 'lg', className, children, ...props }) {
|
|
26
|
-
return (
|
|
27
|
-
<HeadlessTransition appear as={Fragment} show={open} {...props}>
|
|
28
|
-
<HeadlessDialog onClose={onClose}>
|
|
29
|
-
<HeadlessTransitionChild
|
|
30
|
-
as={Fragment}
|
|
31
|
-
enter="ease-out duration-100"
|
|
32
|
-
enterFrom="opacity-0"
|
|
33
|
-
enterTo="opacity-100"
|
|
34
|
-
leave="ease-in duration-100"
|
|
35
|
-
leaveFrom="opacity-100"
|
|
36
|
-
leaveTo="opacity-0"
|
|
37
|
-
>
|
|
38
|
-
<div className="fixed inset-0 flex w-screen justify-center overflow-y-auto bg-zinc-950/25 px-2 py-2 focus:outline-0 sm:px-6 sm:py-8 lg:px-8 lg:py-16 dark:bg-zinc-950/50" />
|
|
39
|
-
</HeadlessTransitionChild>
|
|
40
|
-
|
|
41
|
-
<HeadlessTransitionChild
|
|
42
|
-
className="fixed inset-0 w-screen overflow-y-auto pt-6 sm:pt-0"
|
|
43
|
-
enter="ease-out duration-100"
|
|
44
|
-
enterFrom="opacity-0 translate-y-12 sm:translate-y-0"
|
|
45
|
-
enterTo="opacity-100 translate-y-0"
|
|
46
|
-
leave="ease-in duration-100"
|
|
47
|
-
leaveFrom="opacity-100 translate-y-0"
|
|
48
|
-
leaveTo="opacity-0 translate-y-12 sm:translate-y-0"
|
|
49
|
-
>
|
|
50
|
-
<div className="grid min-h-full grid-rows-[1fr_auto] justify-items-center sm:grid-rows-[1fr_auto_3fr] sm:p-4">
|
|
51
|
-
<HeadlessTransitionChild
|
|
52
|
-
as={HeadlessDialogPanel}
|
|
53
|
-
className={clsx(
|
|
54
|
-
className,
|
|
55
|
-
sizes[size],
|
|
56
|
-
'row-start-2 w-full min-w-0 rounded-t-3xl bg-white p-[--gutter] shadow-lg ring-1 ring-zinc-950/10 [--gutter:theme(spacing.8)] sm:mb-auto sm:rounded-2xl dark:bg-zinc-900 dark:ring-white/10 forced-colors:outline'
|
|
57
|
-
)}
|
|
58
|
-
enter="ease-out duration-100"
|
|
59
|
-
enterFrom="sm:scale-95"
|
|
60
|
-
enterTo="sm:scale-100"
|
|
61
|
-
leave="ease-in duration-100"
|
|
62
|
-
leaveFrom="sm:scale-100"
|
|
63
|
-
leaveTo="sm:scale-100"
|
|
64
|
-
>
|
|
65
|
-
{children}
|
|
66
|
-
</HeadlessTransitionChild>
|
|
67
|
-
</div>
|
|
68
|
-
</HeadlessTransitionChild>
|
|
69
|
-
</HeadlessDialog>
|
|
70
|
-
</HeadlessTransition>
|
|
71
|
-
)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function DialogTitle({ className, ...props }) {
|
|
75
|
-
return (
|
|
76
|
-
<HeadlessDialogTitle
|
|
77
|
-
{...props}
|
|
78
|
-
className={clsx(className, 'text-balance text-lg/6 font-semibold text-zinc-950 sm:text-base/6 dark:text-white')}
|
|
79
|
-
/>
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function DialogDescription({ className, ...props }) {
|
|
84
|
-
return <HeadlessDescription as={Text} {...props} className={clsx(className, 'mt-2 text-pretty')} />
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function DialogBody({ className, ...props }) {
|
|
88
|
-
return <div {...props} className={clsx(className, 'mt-6')} />
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function DialogActions({ className, ...props }) {
|
|
92
|
-
return (
|
|
93
|
-
<div
|
|
94
|
-
{...props}
|
|
95
|
-
className={clsx(
|
|
96
|
-
className,
|
|
97
|
-
'mt-8 flex flex-col-reverse items-center justify-end gap-3 *:w-full sm:flex-row sm:*:w-auto'
|
|
98
|
-
)}
|
|
99
|
-
/>
|
|
100
|
-
)
|
|
101
|
-
}
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
Description as HeadlessDescription,
|
|
5
|
-
Label as HeadlessLabel,
|
|
6
|
-
Menu as HeadlessMenu,
|
|
7
|
-
MenuButton as HeadlessMenuButton,
|
|
8
|
-
MenuHeading as HeadlessMenuHeading,
|
|
9
|
-
MenuItem as HeadlessMenuItem,
|
|
10
|
-
MenuItems as HeadlessMenuItems,
|
|
11
|
-
MenuSection as HeadlessMenuSection,
|
|
12
|
-
MenuSeparator as HeadlessMenuSeparator,
|
|
13
|
-
Transition as HeadlessTransition,
|
|
14
|
-
} from "@headlessui/react";
|
|
15
|
-
import clsx from "clsx";
|
|
16
|
-
import { Fragment } from "react";
|
|
17
|
-
import { Button } from "../components/button";
|
|
18
|
-
import { Link } from "./link";
|
|
19
|
-
|
|
20
|
-
export function Dropdown(props) {
|
|
21
|
-
return <HeadlessMenu {...props} />;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function DropdownButton(props) {
|
|
25
|
-
return <HeadlessMenuButton as={Button} {...props} />;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function DropdownMenu({ anchor = "bottom", ...props }) {
|
|
29
|
-
return (
|
|
30
|
-
<HeadlessTransition
|
|
31
|
-
as={Fragment}
|
|
32
|
-
leave="duration-100 ease-in"
|
|
33
|
-
leaveTo="opacity-0"
|
|
34
|
-
>
|
|
35
|
-
<HeadlessMenuItems
|
|
36
|
-
{...props}
|
|
37
|
-
anchor={{
|
|
38
|
-
to: anchor,
|
|
39
|
-
gap: "var(--anchor-gap)",
|
|
40
|
-
offset: "var(--anchor-offset)",
|
|
41
|
-
padding: "var(--anchor-padding)",
|
|
42
|
-
}}
|
|
43
|
-
className={clsx(
|
|
44
|
-
props.className,
|
|
45
|
-
|
|
46
|
-
// Anchor positioning
|
|
47
|
-
"[--anchor-gap:theme(spacing.2)] [--anchor-padding:theme(spacing.3)] data-[anchor~=end]:[--anchor-offset:4px] data-[anchor~=start]:[--anchor-offset:-4px]",
|
|
48
|
-
|
|
49
|
-
// Base styles
|
|
50
|
-
"isolate w-max rounded-xl p-1",
|
|
51
|
-
|
|
52
|
-
// Invisible border that is only visible in `forced-colors` mode for accessibility purposes
|
|
53
|
-
"outline outline-1 outline-transparent focus:outline-none",
|
|
54
|
-
|
|
55
|
-
// Handle scrolling when menu won't fit in viewport
|
|
56
|
-
"overflow-y-auto",
|
|
57
|
-
|
|
58
|
-
// Popover background
|
|
59
|
-
"bg-white/75 backdrop-blur-xl dark:bg-zinc-800/75",
|
|
60
|
-
|
|
61
|
-
// Shadows
|
|
62
|
-
"shadow-lg ring-1 ring-zinc-950/10 dark:ring-inset dark:ring-white/10",
|
|
63
|
-
|
|
64
|
-
// Define grid at the menu level if subgrid is supported
|
|
65
|
-
"supports-[grid-template-columns:subgrid]:grid supports-[grid-template-columns:subgrid]:grid-cols-[auto_1fr_1.5rem_0.5rem_auto]"
|
|
66
|
-
)}
|
|
67
|
-
/>
|
|
68
|
-
</HeadlessTransition>
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function DropdownItem(props) {
|
|
73
|
-
return (
|
|
74
|
-
<HeadlessMenuItem
|
|
75
|
-
as={props.href ? Link : "button"}
|
|
76
|
-
type={props.href ? undefined : "button"}
|
|
77
|
-
{...props}
|
|
78
|
-
className={clsx(
|
|
79
|
-
props.className,
|
|
80
|
-
|
|
81
|
-
// Base styles
|
|
82
|
-
"group cursor-default rounded-lg px-3.5 py-2.5 focus:outline-none sm:px-3 sm:py-1.5",
|
|
83
|
-
|
|
84
|
-
// Text styles
|
|
85
|
-
"text-left text-base/6 text-zinc-950 sm:text-sm/6 dark:text-white forced-colors:text-[CanvasText]",
|
|
86
|
-
|
|
87
|
-
// Focus
|
|
88
|
-
"data-[focus]:bg-blue-500 data-[focus]:text-white",
|
|
89
|
-
|
|
90
|
-
// Disabled state
|
|
91
|
-
"data-[disabled]:opacity-50",
|
|
92
|
-
|
|
93
|
-
// Forced colors mode
|
|
94
|
-
"forced-color-adjust-none forced-colors:data-[focus]:bg-[Highlight] forced-colors:data-[focus]:text-[HighlightText] forced-colors:[&>[data-slot=icon]]:data-[focus]:text-[HighlightText]",
|
|
95
|
-
|
|
96
|
-
// Use subgrid when available but fallback to an explicit grid layout if not
|
|
97
|
-
"col-span-full grid grid-cols-[auto_1fr_1.5rem_0.5rem_auto] items-center supports-[grid-template-columns:subgrid]:grid-cols-subgrid",
|
|
98
|
-
|
|
99
|
-
// Icon
|
|
100
|
-
"[&>[data-slot=icon]]:col-start-1 [&>[data-slot=icon]]:row-start-1 [&>[data-slot=icon]]:mr-2.5 [&>[data-slot=icon]]:size-5 sm:[&>[data-slot=icon]]:mr-2 [&>[data-slot=icon]]:sm:size-4",
|
|
101
|
-
"[&>[data-slot=icon]]:text-zinc-500 [&>[data-slot=icon]]:data-[focus]:text-white [&>[data-slot=icon]]:dark:text-zinc-500 [&>[data-slot=icon]]:data-[focus]:dark:text-white"
|
|
102
|
-
)}
|
|
103
|
-
/>
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function DropdownHeader({ className, ...props }) {
|
|
108
|
-
return (
|
|
109
|
-
<div
|
|
110
|
-
{...props}
|
|
111
|
-
className={clsx(className, "col-span-5 px-3.5 pb-1 pt-2.5 sm:px-3")}
|
|
112
|
-
/>
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export function DropdownSection({ className, ...props }) {
|
|
117
|
-
return (
|
|
118
|
-
<HeadlessMenuSection
|
|
119
|
-
{...props}
|
|
120
|
-
className={clsx(
|
|
121
|
-
className,
|
|
122
|
-
// Define grid at the section level instead of the item level if subgrid is supported
|
|
123
|
-
"col-span-full supports-[grid-template-columns:subgrid]:grid supports-[grid-template-columns:subgrid]:grid-cols-[auto_1fr_1.5rem_0.5rem_auto]"
|
|
124
|
-
)}
|
|
125
|
-
/>
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export function DropdownHeading({ className, ...props }) {
|
|
130
|
-
return (
|
|
131
|
-
<HeadlessMenuHeading
|
|
132
|
-
{...props}
|
|
133
|
-
className={clsx(
|
|
134
|
-
className,
|
|
135
|
-
"col-span-full grid grid-cols-[1fr,auto] gap-x-12 px-3.5 pb-1 pt-2 text-sm/5 font-medium text-zinc-500 sm:px-3 sm:text-xs/5 dark:text-zinc-400"
|
|
136
|
-
)}
|
|
137
|
-
/>
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export function DropdownSeparator({ className, ...props }) {
|
|
142
|
-
return (
|
|
143
|
-
<HeadlessMenuSeparator
|
|
144
|
-
{...props}
|
|
145
|
-
className={clsx(
|
|
146
|
-
className,
|
|
147
|
-
"col-span-full mx-3.5 my-1 h-px border-0 bg-zinc-950/5 sm:mx-3 dark:bg-white/10 forced-colors:bg-[CanvasText]"
|
|
148
|
-
)}
|
|
149
|
-
/>
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export function DropdownLabel({ className, ...props }) {
|
|
154
|
-
return (
|
|
155
|
-
<HeadlessLabel
|
|
156
|
-
{...props}
|
|
157
|
-
data-slot="label"
|
|
158
|
-
className={clsx(className, "col-start-2 row-start-1")}
|
|
159
|
-
{...props}
|
|
160
|
-
/>
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export function DropdownDescription({ className, ...props }) {
|
|
165
|
-
return (
|
|
166
|
-
<HeadlessDescription
|
|
167
|
-
data-slot="description"
|
|
168
|
-
{...props}
|
|
169
|
-
className={clsx(
|
|
170
|
-
className,
|
|
171
|
-
"col-span-2 col-start-2 row-start-2 text-sm/5 text-zinc-500 group-data-[focus]:text-white sm:text-xs/5 dark:text-zinc-400 forced-colors:group-data-[focus]:text-[HighlightText]"
|
|
172
|
-
)}
|
|
173
|
-
/>
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export function DropdownShortcut({ className, keys, ...props }) {
|
|
178
|
-
return (
|
|
179
|
-
<HeadlessDescription
|
|
180
|
-
as="kbd"
|
|
181
|
-
{...props}
|
|
182
|
-
className={clsx(
|
|
183
|
-
className,
|
|
184
|
-
"col-start-5 row-start-1 flex justify-self-end"
|
|
185
|
-
)}
|
|
186
|
-
>
|
|
187
|
-
{(Array.isArray(keys) ? keys : keys.split("")).map((char, index) => (
|
|
188
|
-
<kbd
|
|
189
|
-
key={index}
|
|
190
|
-
className={clsx([
|
|
191
|
-
"min-w-[2ch] text-center font-sans capitalize text-zinc-400 group-data-[focus]:text-white forced-colors:group-data-[focus]:text-[HighlightText]",
|
|
192
|
-
|
|
193
|
-
// Make sure key names that are longer than one character (like "Tab") have extra space
|
|
194
|
-
index > 0 && char.length > 1 && "pl-1",
|
|
195
|
-
])}
|
|
196
|
-
>
|
|
197
|
-
{char}
|
|
198
|
-
</kbd>
|
|
199
|
-
))}
|
|
200
|
-
</HeadlessDescription>
|
|
201
|
-
);
|
|
202
|
-
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Description as HeadlessDescription,
|
|
3
|
-
Field as HeadlessField,
|
|
4
|
-
Fieldset as HeadlessFieldset,
|
|
5
|
-
Label as HeadlessLabel,
|
|
6
|
-
Legend as HeadlessLegend,
|
|
7
|
-
} from '@headlessui/react'
|
|
8
|
-
import clsx from 'clsx'
|
|
9
|
-
|
|
10
|
-
export function Fieldset({ className, ...props }) {
|
|
11
|
-
return (
|
|
12
|
-
<HeadlessFieldset
|
|
13
|
-
{...props}
|
|
14
|
-
className={clsx(className, '[&>*+[data-slot=control]]:mt-6 [&>[data-slot=text]]:mt-1')}
|
|
15
|
-
/>
|
|
16
|
-
)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function Legend({ ...props }) {
|
|
20
|
-
return (
|
|
21
|
-
<HeadlessLegend
|
|
22
|
-
{...props}
|
|
23
|
-
data-slot="legend"
|
|
24
|
-
className={clsx(
|
|
25
|
-
props.className,
|
|
26
|
-
'text-base/6 font-semibold text-zinc-950 data-[disabled]:opacity-50 sm:text-sm/6 dark:text-white'
|
|
27
|
-
)}
|
|
28
|
-
/>
|
|
29
|
-
)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function FieldGroup({ className, ...props }) {
|
|
33
|
-
return <div {...props} data-slot="control" className={clsx(className, 'space-y-8')} />
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function Field({ className, ...props }) {
|
|
37
|
-
return (
|
|
38
|
-
<HeadlessField
|
|
39
|
-
className={clsx(
|
|
40
|
-
className,
|
|
41
|
-
'[&>[data-slot=label]+[data-slot=control]]:mt-3',
|
|
42
|
-
'[&>[data-slot=label]+[data-slot=description]]:mt-1',
|
|
43
|
-
'[&>[data-slot=description]+[data-slot=control]]:mt-3',
|
|
44
|
-
'[&>[data-slot=control]+[data-slot=description]]:mt-3',
|
|
45
|
-
'[&>[data-slot=control]+[data-slot=error]]:mt-3',
|
|
46
|
-
'[&>[data-slot=label]]:font-medium'
|
|
47
|
-
)}
|
|
48
|
-
{...props}
|
|
49
|
-
/>
|
|
50
|
-
)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function Label({ className, ...props }) {
|
|
54
|
-
return (
|
|
55
|
-
<HeadlessLabel
|
|
56
|
-
{...props}
|
|
57
|
-
data-slot="label"
|
|
58
|
-
className={clsx(
|
|
59
|
-
className,
|
|
60
|
-
'select-none text-base/6 text-zinc-950 data-[disabled]:opacity-50 sm:text-sm/6 dark:text-white'
|
|
61
|
-
)}
|
|
62
|
-
/>
|
|
63
|
-
)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function Description({ className, disabled, ...props }) {
|
|
67
|
-
return (
|
|
68
|
-
<HeadlessDescription
|
|
69
|
-
{...props}
|
|
70
|
-
data-slot="description"
|
|
71
|
-
className={clsx(
|
|
72
|
-
className,
|
|
73
|
-
'text-base/6 text-zinc-500 data-[disabled]:opacity-50 sm:text-sm/6 dark:text-zinc-400'
|
|
74
|
-
)}
|
|
75
|
-
/>
|
|
76
|
-
)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function ErrorMessage({ className, disabled, ...props }) {
|
|
80
|
-
return (
|
|
81
|
-
<HeadlessDescription
|
|
82
|
-
{...props}
|
|
83
|
-
data-slot="error"
|
|
84
|
-
className={clsx(className, 'text-base/6 text-red-600 data-[disabled]:opacity-50 sm:text-sm/6 dark:text-red-500')}
|
|
85
|
-
/>
|
|
86
|
-
)
|
|
87
|
-
}
|
package/lib/catalyst/input.jsx
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { Input as HeadlessInput } from '@headlessui/react'
|
|
2
|
-
import { clsx } from 'clsx'
|
|
3
|
-
import { forwardRef } from 'react'
|
|
4
|
-
|
|
5
|
-
const dateTypes = ['date', 'datetime-local', 'month', 'time', 'week']
|
|
6
|
-
|
|
7
|
-
export const Input = forwardRef(function Input({ className, ...props }, ref) {
|
|
8
|
-
return (
|
|
9
|
-
<span
|
|
10
|
-
data-slot="control"
|
|
11
|
-
className={clsx([
|
|
12
|
-
className,
|
|
13
|
-
|
|
14
|
-
// Basic layout
|
|
15
|
-
'relative block w-full',
|
|
16
|
-
|
|
17
|
-
// Background color + shadow applied to inset pseudo element, so shadow blends with border in light mode
|
|
18
|
-
'before:absolute before:inset-px before:rounded-[calc(theme(borderRadius.lg)-1px)] before:bg-white before:shadow',
|
|
19
|
-
|
|
20
|
-
// Background color is moved to control and shadow is removed in dark mode so hide `before` pseudo
|
|
21
|
-
'dark:before:hidden',
|
|
22
|
-
|
|
23
|
-
// Focus ring
|
|
24
|
-
'after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:ring-inset after:ring-transparent sm:after:focus-within:ring-2 sm:after:focus-within:ring-blue-500',
|
|
25
|
-
|
|
26
|
-
// Disabled state
|
|
27
|
-
'has-[[data-disabled]]:opacity-50 before:has-[[data-disabled]]:bg-zinc-950/5 before:has-[[data-disabled]]:shadow-none',
|
|
28
|
-
|
|
29
|
-
// Invalid state
|
|
30
|
-
'before:has-[[data-invalid]]:shadow-red-500/10',
|
|
31
|
-
])}
|
|
32
|
-
>
|
|
33
|
-
<HeadlessInput
|
|
34
|
-
ref={ref}
|
|
35
|
-
className={clsx([
|
|
36
|
-
// Date classes
|
|
37
|
-
props.type &&
|
|
38
|
-
dateTypes.includes(props.type) && [
|
|
39
|
-
'[&::-webkit-datetime-edit-fields-wrapper]:p-0',
|
|
40
|
-
'[&::-webkit-date-and-time-value]:min-h-[1.5em]',
|
|
41
|
-
'[&::-webkit-datetime-edit]:inline-flex',
|
|
42
|
-
'[&::-webkit-datetime-edit]:p-0',
|
|
43
|
-
'[&::-webkit-datetime-edit-year-field]:p-0',
|
|
44
|
-
'[&::-webkit-datetime-edit-month-field]:p-0',
|
|
45
|
-
'[&::-webkit-datetime-edit-day-field]:p-0',
|
|
46
|
-
'[&::-webkit-datetime-edit-hour-field]:p-0',
|
|
47
|
-
'[&::-webkit-datetime-edit-minute-field]:p-0',
|
|
48
|
-
'[&::-webkit-datetime-edit-second-field]:p-0',
|
|
49
|
-
'[&::-webkit-datetime-edit-millisecond-field]:p-0',
|
|
50
|
-
'[&::-webkit-datetime-edit-meridiem-field]:p-0',
|
|
51
|
-
],
|
|
52
|
-
|
|
53
|
-
// Basic layout
|
|
54
|
-
'relative block w-full appearance-none rounded-lg px-[calc(theme(spacing[3.5])-1px)] py-[calc(theme(spacing[2.5])-1px)] sm:px-[calc(theme(spacing[3])-1px)] sm:py-[calc(theme(spacing[1.5])-1px)]',
|
|
55
|
-
|
|
56
|
-
// Typography
|
|
57
|
-
'text-base/6 text-zinc-950 placeholder:text-zinc-500 sm:text-sm/6 dark:text-white',
|
|
58
|
-
|
|
59
|
-
// Border
|
|
60
|
-
'border border-zinc-950/10 data-[hover]:border-zinc-950/20 dark:border-white/10 dark:data-[hover]:border-white/20',
|
|
61
|
-
|
|
62
|
-
// Background color
|
|
63
|
-
'bg-transparent dark:bg-white/5',
|
|
64
|
-
|
|
65
|
-
// Hide default focus styles
|
|
66
|
-
'focus:outline-none',
|
|
67
|
-
|
|
68
|
-
// Invalid state
|
|
69
|
-
'data-[invalid]:border-red-500 data-[invalid]:data-[hover]:border-red-500 data-[invalid]:dark:border-red-500 data-[invalid]:data-[hover]:dark:border-red-500',
|
|
70
|
-
|
|
71
|
-
// Disabled state
|
|
72
|
-
'data-[disabled]:border-zinc-950/20 dark:data-[hover]:data-[disabled]:border-white/15 data-[disabled]:dark:border-white/15 data-[disabled]:dark:bg-white/[2.5%]',
|
|
73
|
-
])}
|
|
74
|
-
{...props}
|
|
75
|
-
/>
|
|
76
|
-
</span>
|
|
77
|
-
)
|
|
78
|
-
})
|