@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.
Files changed (79) hide show
  1. package/dist/groundwork.es.js +5131 -0
  2. package/dist/groundwork.umd.js +30 -0
  3. package/dist/style.css +1 -0
  4. package/package.json +11 -3
  5. package/.eslintrc.cjs +0 -18
  6. package/.github/workflows/deploy-docs.yml +0 -59
  7. package/.github/workflows/publish.yml +0 -19
  8. package/index.html +0 -13
  9. package/lib/catalyst/alert.jsx +0 -110
  10. package/lib/catalyst/avatar.jsx +0 -64
  11. package/lib/catalyst/badge.jsx +0 -72
  12. package/lib/catalyst/checkbox.jsx +0 -160
  13. package/lib/catalyst/dialog.jsx +0 -101
  14. package/lib/catalyst/dropdown.jsx +0 -202
  15. package/lib/catalyst/fieldset.jsx +0 -87
  16. package/lib/catalyst/input.jsx +0 -78
  17. package/lib/catalyst/listbox.jsx +0 -195
  18. package/lib/catalyst/pagination.jsx +0 -75
  19. package/lib/catalyst/radio.jsx +0 -144
  20. package/lib/catalyst/select.jsx +0 -78
  21. package/lib/catalyst/switch.jsx +0 -203
  22. package/lib/catalyst/textarea.jsx +0 -59
  23. package/lib/components/breadcrumbs.jsx +0 -46
  24. package/lib/components/button.jsx +0 -219
  25. package/lib/components/display/headings.jsx +0 -39
  26. package/lib/components/display/text.jsx +0 -48
  27. package/lib/components/hero.jsx +0 -51
  28. package/lib/components/layout/container.jsx +0 -13
  29. package/lib/components/layout/usace-box.jsx +0 -26
  30. package/lib/components/link.jsx +0 -18
  31. package/lib/components/table.jsx +0 -146
  32. package/lib/composite/footer/essayons.jsx +0 -12
  33. package/lib/composite/footer/footer-links.jsx +0 -33
  34. package/lib/composite/footer/index.jsx +0 -148
  35. package/lib/composite/footer/logo-banner.jsx +0 -55
  36. package/lib/composite/footer/social-links.jsx +0 -60
  37. package/lib/composite/header/index.jsx +0 -83
  38. package/lib/composite/header/navbar-links.jsx +0 -113
  39. package/lib/composite/header/usa-banner/USABanner.jsx +0 -114
  40. package/lib/composite/header/usa-banner/usa-banner.css +0 -220
  41. package/lib/composite/site-wrapper/index.jsx +0 -52
  42. package/lib/index.jsx +0 -19
  43. package/postcss.config.js +0 -6
  44. package/public/Magnifying_glass_icon.svg +0 -5
  45. package/public/armystar-logo-rb.svg +0 -4
  46. package/public/cwbi-logo.png +0 -0
  47. package/public/essayonscrest.png +0 -0
  48. package/public/icon-dot-gov.svg +0 -1
  49. package/public/icon-https.svg +0 -1
  50. package/public/nww-lucky-peak-dam.jpg +0 -0
  51. package/public/rsgis-logo.png +0 -0
  52. package/public/us_flag_small.png +0 -0
  53. package/public/usace-logo-color.svg +0 -1
  54. package/src/App.jsx +0 -38
  55. package/src/app-bundles/index.js +0 -4
  56. package/src/app-bundles/route-bundle.js +0 -36
  57. package/src/app-components/code-example.jsx +0 -17
  58. package/src/app-components/copy-button.jsx +0 -32
  59. package/src/app-components/props-table.jsx +0 -43
  60. package/src/app-components/sub-site-banner.jsx +0 -15
  61. package/src/app-pages/documentation/_docs-page.jsx +0 -31
  62. package/src/app-pages/documentation/_docs-sidebar.jsx +0 -111
  63. package/src/app-pages/documentation/_template.jsx +0 -55
  64. package/src/app-pages/documentation/app-shell/index.jsx +0 -39
  65. package/src/app-pages/documentation/app-shell/site-wrapper.jsx +0 -190
  66. package/src/app-pages/documentation/buttons/index.jsx +0 -170
  67. package/src/app-pages/documentation/index.jsx +0 -57
  68. package/src/app-pages/documentation/layout/container.jsx +0 -68
  69. package/src/app-pages/documentation/layout/index.jsx +0 -52
  70. package/src/app-pages/documentation/layout/usace-box.jsx +0 -76
  71. package/src/app-pages/documentation/navigation/breadcrumbs.jsx +0 -119
  72. package/src/app-pages/documentation/navigation/index.jsx +0 -31
  73. package/src/app-pages/documentation/types/index.jsx +0 -31
  74. package/src/app-pages/documentation/types/link.jsx +0 -72
  75. package/src/app-pages/home.jsx +0 -71
  76. package/src/index.css +0 -3
  77. package/src/main.jsx +0 -18
  78. package/tailwind.config.js +0 -31
  79. 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
- }
@@ -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
- }
@@ -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
- })