@darthcharles/greda 1.2.0 → 1.3.1

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/README.md CHANGED
@@ -45,6 +45,51 @@ Greda and application markup share unprefixed utility classes such as
45
45
  `className` to override component defaults. See the introduction guide for supported
46
46
  utilities and migration from `ds-*` classes.
47
47
 
48
+ ## Toggle buttons
49
+
50
+ For toggle buttons, set `aria-pressed` to the current selection state and
51
+ update that state in `onClick`. Users can activate the button with a click,
52
+ Enter, or Space. This also applies to native buttons styled with `buttonVariants`.
53
+
54
+ ## Searchable selection
55
+
56
+ Use `Combobox` for filtering as you type and optional option creation. It uses
57
+ existing Radix dependencies. `Select` remains available for simple selection.
58
+
59
+ Import the same package stylesheet shown in Quick start, then compose the field:
60
+
61
+ ```tsx
62
+ import {
63
+ Combobox, ComboboxInput, ComboboxContent, Label,
64
+ } from "@darthcharles/greda";
65
+
66
+ const materials = [
67
+ { value: "clay", label: "Clay", keywords: ["pottery"] },
68
+ { value: "linen", label: "Linen" },
69
+ ];
70
+
71
+ export function MaterialField() {
72
+ return (
73
+ <>
74
+ <Label htmlFor="material">Material</Label>
75
+ <Combobox
76
+ options={materials}
77
+ name="material"
78
+ onCreate={(label) => ({ value: crypto.randomUUID(), label })}
79
+ >
80
+ <ComboboxInput id="material" placeholder="Choose or create" required />
81
+ <ComboboxContent />
82
+ </Combobox>
83
+ </>
84
+ );
85
+ }
86
+ ```
87
+
88
+ See the [usage guide](src/stories/Combobox.mdx) for controlled state, remote
89
+ search, creation callbacks, forms, and keyboard interaction. Explore the
90
+ [Storybook examples](https://elegant-hotteok-cbb834.netlify.app/?path=/docs/components-combobox--docs)
91
+ for component states.
92
+
48
93
  ## With Tailwind 4
49
94
 
50
95
  Import Greda's tokens in your app's Tailwind CSS entry point. This registers the
@@ -108,7 +153,7 @@ element. Importing it alone leaves the neutral base unchanged. The application
108
153
  still controls page backgrounds and fonts. Select **cobalto** in Storybook to
109
154
  preview components, and see the [composition recipe](src/stories/Cobalto.mdx)
110
155
  for large mixed-weight titles, an asterisk, a polaroid photo, scoped portals,
111
- and Tailwind 4 import order. Both recipes use Tailwind utilities directly in JSX;
156
+ and Tailwind 4 import order. The recipes use Tailwind utilities directly in JSX;
112
157
  compile them with your application’s Tailwind 4 setup.
113
158
 
114
159
  Comal is also available as an optional theme. Import
@@ -117,10 +162,18 @@ Comal is also available as an optional theme. Import
117
162
  element. It uses warm neutrals, terracotta actions and rounded corners. Its font
118
163
  stacks reference DM Sans and Fraunces; load those fonts in your application or
119
164
  override `--font-sans` and `--font-heading`. No fonts are downloaded or bundled
120
- by either theme. Both exports can be imported together and selected by attribute.
165
+ by these themes. Theme exports can be imported together and selected by attribute.
121
166
  See the [Comal composition recipe](src/stories/Comal.mdx) for a complete fictional
122
167
  workshop page, optional font setup, responsive layout and copyable Tailwind JSX.
123
168
 
169
+ Matrix adds a terminal identity with green actions, system monospace fonts and
170
+ square controls. Import `@darthcharles/greda/themes/matrix.css` after the package
171
+ stylesheet and set `data-theme="matrix"` with `data-color-scheme="dark"` for
172
+ green-black surfaces, or `"light"` for pale green surfaces. No font setup is
173
+ required. Select **matrix** in Storybook to preview components, or see the
174
+ [Matrix composition recipe](src/stories/Matrix.mdx) for a responsive console
175
+ layout and Tailwind 4 setup.
176
+
124
177
  Customization is optional. To change the default theme, import your own
125
178
  `theme.css` after the package stylesheet and override the base colors or other
126
179
  tokens you need.
@@ -0,0 +1,48 @@
1
+ import * as React from "react";
2
+ import { Input } from "./input";
3
+ import { type PopoverContentProps } from "./popover";
4
+ export interface ComboboxOption {
5
+ /** Stable, unique ID used for selection and form submission. */
6
+ value: string;
7
+ label: string;
8
+ disabled?: boolean;
9
+ keywords?: string[];
10
+ }
11
+ export type ComboboxFilter = (option: ComboboxOption, query: string) => boolean;
12
+ export interface ComboboxProps {
13
+ children: React.ReactNode;
14
+ options: ComboboxOption[];
15
+ value?: ComboboxOption | null;
16
+ defaultValue?: ComboboxOption | null;
17
+ onValueChange?: (option: ComboboxOption | null) => void;
18
+ inputValue?: string;
19
+ defaultInputValue?: string;
20
+ onInputValueChange?: (query: string) => void;
21
+ open?: boolean;
22
+ defaultOpen?: boolean;
23
+ onOpenChange?: (open: boolean) => void;
24
+ /** false preserves remote results and their ordering without filtering again. */
25
+ filter?: ComboboxFilter | false;
26
+ loading?: boolean;
27
+ error?: React.ReactNode;
28
+ disabled?: boolean;
29
+ name?: string;
30
+ form?: string;
31
+ onCreate?: (query: string) => ComboboxOption | Promise<ComboboxOption>;
32
+ /** Additional eligibility check; the server must still enforce uniqueness. */
33
+ isValidNewOption?: (query: string, options: ComboboxOption[]) => boolean;
34
+ }
35
+ declare function Combobox({ children, options, value, defaultValue, onValueChange, inputValue, defaultInputValue, onInputValueChange, open: controlledOpen, defaultOpen, onOpenChange, filter, loading, error, disabled, name, form, onCreate, isValidNewOption, }: ComboboxProps): React.JSX.Element;
36
+ export type ComboboxInputProps = Omit<React.ComponentPropsWithoutRef<typeof Input>, "value" | "defaultValue" | "type" | "role" | "name" | "disabled">;
37
+ declare const ComboboxInput: React.ForwardRefExoticComponent<ComboboxInputProps & React.RefAttributes<HTMLInputElement>>;
38
+ export interface ComboboxContentProps extends Omit<PopoverContentProps, "children" | "role"> {
39
+ emptyText?: React.ReactNode;
40
+ loadingText?: React.ReactNode;
41
+ creatingText?: React.ReactNode;
42
+ createErrorText?: React.ReactNode;
43
+ renderCreateLabel?: (query: string) => React.ReactNode;
44
+ renderOption?: (option: ComboboxOption) => React.ReactNode;
45
+ getStatusText?: (count: number, canCreate: boolean) => string;
46
+ }
47
+ declare const ComboboxContent: React.ForwardRefExoticComponent<ComboboxContentProps & React.RefAttributes<HTMLDivElement>>;
48
+ export { Combobox, ComboboxInput, ComboboxContent };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export * from "./components/ui/input";
3
3
  export * from "./components/ui/textarea";
4
4
  export * from "./components/ui/label";
5
5
  export * from "./components/ui/select";
6
+ export * from "./components/ui/combobox";
6
7
  export * from "./components/ui/dialog";
7
8
  export * from "./components/ui/card";
8
9
  export * from "./components/ui/badge";