@spunto/design-system 0.22.0 → 0.24.0

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
@@ -73,6 +73,26 @@ const nextConfig = { transpilePackages: ["@spunto/design-system"] }
73
73
  - _Forms_ — `Input`, `Textarea`, `Label`, `Switch`, `Checkbox`,
74
74
  `RadioGroup` (+`RadioGroupItem`), `Select` (+`SelectTrigger`/`SelectValue`/
75
75
  `SelectContent`/`SelectItem`/`SelectGroup`/`SelectGroupLabel`/`SelectSeparator`).
76
+ - _Combobox_ — `Combobox` (+`ComboboxInput`/`Clear`/`Trigger`/`Value`/`Search`/`Chips`/
77
+ `Chip`/`ChipsInput`/`Content`/`List`/`Group`/`GroupLabel`/`Separator`/`Item`/`Empty`/
78
+ `Loading`), the `Select` you can type into — for the list nobody wants to scroll
79
+ (branches, repos, model ids, members, tags). Base UI's `Combobox` underneath, and
80
+ compositional like `Select`: items are children. Three things it adds. (1) **Items
81
+ filter themselves**, with the same collator `CommandPalette` uses, so no caller
82
+ re-`.filter()`s its options and "deploi" finds "déploiement"; groups hide themselves
83
+ through `:has()` (no more `if (items.length === 0) return null`), and so does a
84
+ separator with nothing left after it. (2) **A query is only a query when someone
85
+ typed it** — Base UI writes the selected item's label into the input, and taken at
86
+ face value that text filters the list down to the row you just picked; the filter
87
+ keys off the `input-change` reason and ignores anything the component wrote itself.
88
+ (3) In multi-select **the chips field registers itself as the popup's anchor**, so
89
+ the list opens under the whole field instead of the caret-sized `<input>` — no ref
90
+ to remember, no `anchor` prop to pass. Two field shapes, two components rather than
91
+ a flag: `ComboboxInput` (the combobox *is* the field, same 32 px/border/ring as
92
+ `Input`, chevron out of the tab order) or `ComboboxTrigger` + `ComboboxValue` with a
93
+ `ComboboxSearch` at the top of the popup, for when the value is rendered rather than
94
+ typed. Presentational only: `loading` is a prop and a server-side search is
95
+ `onInputValueChange` + `filter={null}`.
76
96
  - _Navigation & feedback_ — `Tabs` (+`TabsList`/`TabsIndicator`/`TabsTab`/`TabsPanel`),
77
97
  `Alert` (+`AlertTitle`/`AlertDescription`, +`alertVariants`) — an **inline, persistent,
78
98
  declarative** status banner, the counterpart to the ephemeral imperative `toast()`.
@@ -292,9 +312,24 @@ hand-typed reference that degrades cleanly.
292
312
  secrets") instead of showing a bare chevron, and the form opens it by itself
293
313
  when any of those sections already has a value — so editing a project never
294
314
  hides a setting you made earlier.
315
+ - **Git hosting is a list of providers, not GitHub** (0.21.0). `gitProviders`
316
+ (id, name, `connected`, `accounts`, `installUrl`, `operations`, `icon`) and
317
+ `gitRepos` (each tagged with its `provider`) replace `githubRepos` / `github` /
318
+ `connectUrl` / `githubIcon`, and `ProjectRepo.provider` widens from
319
+ `"github" | "git"` to a `string` — the set of forges belongs to the deployment,
320
+ not to this package. The component reads `operations` to decide what to offer
321
+ rather than branching on a provider id, so a second forge needs no change here.
322
+ `"git"` (exported as `RAW_GIT`) still means "a raw clone URL", which is the
323
+ *absence* of a provider rather than one more of them.
324
+ - **One "Add repository" button, with no brand on it.** The forge is a property
325
+ of the repository you pick, not a decision to make before you know which
326
+ repository you want — so the field offers every connected provider's repos at
327
+ once and `renderRepoField`'s `onChange(value, option?)` hands back the chosen
328
+ entry, which is how the row learns its provider. A brand glyph on a generic
329
+ button is wrong as soon as two providers are connected.
295
330
  - **Nothing fetches.** Catalogs come in as data, the marketplace search is
296
- `onSearchExtensions`, the GitHub combobox is `renderRepoField` (without it: a
297
- plain `<input list>` + `<datalist>`, no dependency, keyboard-friendly), and
331
+ `onSearchExtensions`, the repository combobox is `renderRepoField` (without it:
332
+ a plain `<input list>` + `<datalist>`, no dependency, keyboard-friendly), and
298
333
  `extras` slips app-specific content *inside* a section — the deploy key card,
299
334
  a warning — without forking the component.
300
335
  - **Its bricks, exported individually**: `FormSection`, `Field`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spunto/design-system",
3
- "version": "0.22.0",
3
+ "version": "0.24.0",
4
4
  "description": "Spunto's shared design system — warm/flame tokens, color constants, and UI primitives.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -61,7 +61,8 @@
61
61
  "README.md"
62
62
  ],
63
63
  "scripts": {
64
- "typecheck": "tsc --noEmit"
64
+ "typecheck": "tsc --noEmit",
65
+ "test": "vitest run"
65
66
  },
66
67
  "dependencies": {
67
68
  "@xterm/addon-fit": "^0.11.0",
@@ -81,8 +82,13 @@
81
82
  },
82
83
  "devDependencies": {
83
84
  "@base-ui/react": "^1.6.0",
85
+ "@testing-library/react": "^16.3.0",
86
+ "@testing-library/user-event": "^14.6.1",
84
87
  "@types/react": "^19",
85
88
  "@types/react-dom": "^19",
86
- "typescript": "^5"
89
+ "@vitejs/plugin-react": "^5.0.4",
90
+ "jsdom": "^28.0.0",
91
+ "typescript": "^5",
92
+ "vitest": "^4.1.11"
87
93
  }
88
94
  }