@alexgorbatchev/shadcn 0.0.43 → 0.0.44

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
@@ -270,6 +270,8 @@ The npm package includes the same index at `llms.txt` in its root and its linked
270
270
 
271
271
  Use the composed parts exported from the package root, such as `DialogTrigger`, `DialogContent`, and `DialogTitle`. Storybook provides working compositions, variants, disabled states, and action callbacks. The local preview starts with `bun run storybook` and binds to `127.0.0.1:6006`.
272
272
 
273
+ `ToggleGroup` supports optional single selection by default and independent selections with `multiple`. Set `required` for a single selection that stays pressed when activated again by pointer, Space, or Enter. Required groups accept exactly one initial item through the controlled `value` or uncontrolled `defaultValue` tuple and cannot use `multiple`. Empty selection requests are canceled through Base UI before consumer callbacks or analytics run; accepted changes retain the native array value and event-details API. This selection rule does not add form submission or validation behavior.
274
+
273
275
  `ScrollArea` supplies a native scroll viewport and one vertical `ScrollBar` by default. Set `scrollbars={<ScrollBar orientation="horizontal" />}` for a wide horizontal layout, or supply a fragment containing vertical and horizontal parts for both axes. The tracks stay outside the viewport and reserve their shared corner. `keepMounted` belongs to `ScrollBar`; root and track className callbacks receive native overflow/scroll state. Focus the viewport for native keyboard scrolling.
274
276
 
275
277
  Scrolling is intentional: cards, panels, dialogs, sheets, and floating surfaces carry `data-scroll="none"`. Put long content in a nested `ScrollArea` or an explicitly styled native scroll viewport; the outer surface stays stationary. `DialogContent` bounds its height to the viewport and uses a flex column, so give a nested `ScrollArea` `className="min-h-0"` to let it shrink within the dialog. Headers and footers stay outside that scroll area when they need to remain visible.
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  ToggleGroup2,
6
6
  ToggleGroupItem2
7
- } from "./chunk-w9s21aj0.js";
7
+ } from "./chunk-q606kj28.js";
8
8
 
9
9
  // src/components/assistant-ui/elements/MessageActions.tsx
10
10
  import { CheckIcon, CopyIcon, EllipsisIcon, RefreshCwIcon, ThumbsDownIcon, ThumbsUpIcon } from "lucide-react";
@@ -19,7 +19,7 @@ import {
19
19
  import {
20
20
  ToggleGroup2,
21
21
  ToggleGroupItem2
22
- } from "./chunk-w9s21aj0.js";
22
+ } from "./chunk-q606kj28.js";
23
23
 
24
24
  // src/components/assistant-ui/elements/FeedbackDialog.tsx
25
25
  import { useId } from "react";
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  ToggleGroup2,
9
9
  ToggleGroupItem2
10
- } from "./chunk-w9s21aj0.js";
10
+ } from "./chunk-q606kj28.js";
11
11
  import {
12
12
  pct,
13
13
  announced
@@ -62,6 +62,7 @@ function ToggleGroup2({
62
62
  orientation = "horizontal",
63
63
  children,
64
64
  style,
65
+ required = false,
65
66
  ...props
66
67
  }) {
67
68
  const trackedOnValueChange = useAnalyticsCallback("ToggleGroup", analytics, { name: "ui.change-request" }, props.onValueChange);
@@ -78,7 +79,13 @@ function ToggleGroup2({
78
79
  }),
79
80
  className: (state) => cn2("group/toggle-group flex w-fit flex-row items-center rounded-sm data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch", typeof className === "function" ? className(state) : className),
80
81
  ...props,
81
- onValueChange: trackedOnValueChange,
82
+ onValueChange: (value, details) => {
83
+ if (required && value.length === 0) {
84
+ details.cancel();
85
+ return;
86
+ }
87
+ trackedOnValueChange(value, details);
88
+ },
82
89
  children: /* @__PURE__ */ jsx2(ToggleGroupContext.Provider, {
83
90
  value: { variant, size, spacing },
84
91
  children
@@ -4,10 +4,24 @@ import { ToggleGroup as ToggleGroupPrimitive } from "@base-ui/react/toggle-group
4
4
  import type { VariantProps } from "class-variance-authority";
5
5
  import type { IDensityProps } from "../density/types.js";
6
6
  import { toggleVariants, type ToggleProps } from "./Toggle.js";
7
- export type ToggleGroupProps = IAnalyticsProps & ToggleGroupPrimitive.Props & VariantProps<typeof toggleVariants> & IDensityProps & IToggleGroupLayout;
7
+ export type ToggleGroupProps = IAnalyticsProps & Omit<ToggleGroupPrimitive.Props, "multiple" | "value" | "defaultValue"> & VariantProps<typeof toggleVariants> & IDensityProps & IToggleGroupLayout & (OptionalToggleGroupSelection | RequiredToggleGroupSelection);
8
+ type OptionalToggleGroupSelection = Pick<ToggleGroupPrimitive.Props, "multiple" | "value" | "defaultValue"> & {
9
+ required?: false;
10
+ };
11
+ type RequiredToggleGroupSelection = {
12
+ /** Keep one toggle pressed. Supply exactly one initial value. */
13
+ required: true;
14
+ multiple?: false;
15
+ } & ({
16
+ value: [string];
17
+ defaultValue?: [string];
18
+ } | {
19
+ value?: undefined;
20
+ defaultValue: [string];
21
+ });
8
22
  interface IToggleGroupLayout {
9
23
  spacing?: number;
10
24
  }
11
- export declare function ToggleGroup({ analytics, density, className, variant, size, spacing, orientation, children, style, ...props }: ToggleGroupProps): ReactElement;
25
+ export declare function ToggleGroup({ analytics, density, className, variant, size, spacing, orientation, children, style, required, ...props }: ToggleGroupProps): ReactElement;
12
26
  export declare function ToggleGroupItem({ density, className, variant, size, ...props }: ToggleProps): ReactElement;
13
27
  export {};
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  FeedbackDialog2
3
- } from "../../../chunk-0ybh8xre.js";
3
+ } from "../../../chunk-79vgr8w9.js";
4
4
  import"../../../chunk-6jpz5geq.js";
5
- import"../../../chunk-w9s21aj0.js";
5
+ import"../../../chunk-q606kj28.js";
6
6
  import"../../../chunk-bygq5yqf.js";
7
7
  import"../../../chunk-jcxxjkqx.js";
8
8
  import"../../../chunk-tq0pfv5h.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MessageActions2
3
- } from "../../../chunk-634pk1cg.js";
4
- import"../../../chunk-w9s21aj0.js";
3
+ } from "../../../chunk-6475gsta.js";
4
+ import"../../../chunk-q606kj28.js";
5
5
  import"../../../chunk-38301e40.js";
6
6
  import"../../../chunk-x90xmrba.js";
7
7
  import"../../../chunk-jpvw9xqy.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ReasoningEffort2
3
- } from "../../../chunk-3c35ysaq.js";
4
- import"../../../chunk-w9s21aj0.js";
3
+ } from "../../../chunk-dhmtrz6f.js";
4
+ import"../../../chunk-q606kj28.js";
5
5
  import"../../../chunk-5j39rehg.js";
6
6
  import"../../../chunk-5mydsjp3.js";
7
7
  import"../../../chunk-8ssktt4b.js";
@@ -259,10 +259,10 @@ import"../../chunk-f6rbv5gf.js";
259
259
  import {
260
260
  EveAskQuestion2
261
261
  } from "../../chunk-vg2j5044.js";
262
- import"../../chunk-w9s21aj0.js";
262
+ import"../../chunk-q606kj28.js";
263
263
  import {
264
264
  FeedbackDialog2
265
- } from "../../chunk-0ybh8xre.js";
265
+ } from "../../chunk-79vgr8w9.js";
266
266
  import {
267
267
  FileRoot2,
268
268
  FileIconDisplay2,
@@ -351,7 +351,7 @@ import {
351
351
  } from "../../chunk-1t959882.js";
352
352
  import {
353
353
  MessageActions2
354
- } from "../../chunk-634pk1cg.js";
354
+ } from "../../chunk-6475gsta.js";
355
355
  import {
356
356
  MessageAttachments2
357
357
  } from "../../chunk-wpa484a6.js";
@@ -461,7 +461,7 @@ import {
461
461
  } from "../../chunk-qv3b2jvc.js";
462
462
  import {
463
463
  ReasoningEffort2
464
- } from "../../chunk-3c35ysaq.js";
464
+ } from "../../chunk-dhmtrz6f.js";
465
465
  import {
466
466
  SwapLabel2
467
467
  } from "../../chunk-wgxs6b5t.js";
@@ -112,7 +112,7 @@ import {
112
112
  Toggle2,
113
113
  ToggleGroup2,
114
114
  ToggleGroupItem2
115
- } from "../../chunk-w9s21aj0.js";
115
+ } from "../../chunk-q606kj28.js";
116
116
  import {
117
117
  Alert2,
118
118
  AlertTitle2,
package/dist/index.js CHANGED
@@ -301,7 +301,7 @@ import {
301
301
  Toggle2,
302
302
  ToggleGroup2,
303
303
  ToggleGroupItem2
304
- } from "./chunk-w9s21aj0.js";
304
+ } from "./chunk-q606kj28.js";
305
305
  import {
306
306
  Spinner2
307
307
  } from "./chunk-1xncv9gb.js";
package/dist/prototype.js CHANGED
@@ -2051,7 +2051,7 @@ var program = new Command;
2051
2051
  // package.json
2052
2052
  var package_default = {
2053
2053
  name: "@alexgorbatchev/shadcn",
2054
- version: "0.0.43",
2054
+ version: "0.0.44",
2055
2055
  description: "Sharp, monospace React components with compact and comfortable densities.",
2056
2056
  license: "MIT",
2057
2057
  repository: {
@@ -8,7 +8,8 @@ Source: src/components/stories/actions/ToggleGroup.stories.tsx
8
8
  ## Public imports
9
9
 
10
10
  ```tsx
11
- import { ToggleGroup, ToggleGroupItem, DirectionProvider, Field, FieldLabel, FieldDescription } from "@alexgorbatchev/shadcn";
11
+ import { ToggleGroup, ToggleGroupItem, DirectionProvider, Field, FieldLabel, FieldDescription, Button } from "@alexgorbatchev/shadcn";
12
+ import { AnalyticsProvider } from "@alexgorbatchev/shadcn/analytics";
12
13
  ```
13
14
 
14
15
  ## Supporting imports
@@ -61,6 +62,52 @@ Storybook CSF excerpts. Default args and render apply unless overridden. Local h
61
62
  {}
62
63
  ```
63
64
 
65
+ ### RequiredSingle
66
+
67
+ ```tsx
68
+ {
69
+ args: { required: true, defaultValue: ["bold"], variant: "outline", analytics: { id: "required-format" } },
70
+ beforeEach: () => {
71
+ trackRequiredChange.mockClear();
72
+ },
73
+ decorators: [
74
+ (Story) => (<AnalyticsProvider transport={{ track: trackRequiredChange }}>
75
+ <Story />
76
+ </AnalyticsProvider>),
77
+ ]
78
+ }
79
+ ```
80
+
81
+ ### RequiredControlled
82
+
83
+ ```tsx
84
+ {
85
+ beforeEach: () => {
86
+ submitRequiredForm.mockClear();
87
+ },
88
+ render: function Render(args) {
89
+ const [value, setValue] = useState<[
90
+ string
91
+ ]>(["bold"]);
92
+ return (<form onSubmit={(event) => {
93
+ event.preventDefault();
94
+ submitRequiredForm(value);
95
+ }}>
96
+ <ToggleGroup {...args} required multiple={false} value={value} defaultValue={undefined} onValueChange={(values, details) => {
97
+ const next = values[0];
98
+ if (next !== undefined)
99
+ setValue([next]);
100
+ args.onValueChange?.(values, details);
101
+ }}>
102
+ <ToggleGroupItem value="bold">Bold</ToggleGroupItem>
103
+ <ToggleGroupItem value="italic">Italic</ToggleGroupItem>
104
+ </ToggleGroup>
105
+ <Button type="submit">Apply formatting</Button>
106
+ </form>);
107
+ }
108
+ }
109
+ ```
110
+
64
111
  ### Multiple
65
112
 
66
113
  ```tsx
package/llms/setup.md CHANGED
@@ -270,6 +270,8 @@ The npm package includes the same index at `llms.txt` in its root and its linked
270
270
 
271
271
  Use the composed parts exported from the package root, such as `DialogTrigger`, `DialogContent`, and `DialogTitle`. Storybook provides working compositions, variants, disabled states, and action callbacks. The local preview starts with `bun run storybook` and binds to `127.0.0.1:6006`.
272
272
 
273
+ `ToggleGroup` supports optional single selection by default and independent selections with `multiple`. Set `required` for a single selection that stays pressed when activated again by pointer, Space, or Enter. Required groups accept exactly one initial item through the controlled `value` or uncontrolled `defaultValue` tuple and cannot use `multiple`. Empty selection requests are canceled through Base UI before consumer callbacks or analytics run; accepted changes retain the native array value and event-details API. This selection rule does not add form submission or validation behavior.
274
+
273
275
  `ScrollArea` supplies a native scroll viewport and one vertical `ScrollBar` by default. Set `scrollbars={<ScrollBar orientation="horizontal" />}` for a wide horizontal layout, or supply a fragment containing vertical and horizontal parts for both axes. The tracks stay outside the viewport and reserve their shared corner. `keepMounted` belongs to `ScrollBar`; root and track className callbacks receive native overflow/scroll state. Focus the viewport for native keyboard scrolling.
274
276
 
275
277
  Scrolling is intentional: cards, panels, dialogs, sheets, and floating surfaces carry `data-scroll="none"`. Put long content in a nested `ScrollArea` or an explicitly styled native scroll viewport; the outer surface stays stationary. `DialogContent` bounds its height to the viewport and uses a flex column, so give a nested `ScrollArea` `className="min-h-0"` to let it shrink within the dialog. Headers and footers stay outside that scroll area when they need to remain visible.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexgorbatchev/shadcn",
3
- "version": "0.0.43",
3
+ "version": "0.0.44",
4
4
  "description": "Sharp, monospace React components with compact and comfortable densities.",
5
5
  "license": "MIT",
6
6
  "repository": {