@alexgorbatchev/shadcn 0.0.47 → 0.0.48

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.
@@ -0,0 +1,143 @@
1
+ # ActionsMenu
2
+
3
+ Story: @alexgorbatchev/shadcn/navigation/ActionsMenu
4
+ Source: src/components/stories/navigation/ActionsMenu.stories.tsx
5
+
6
+ [Full source and local helpers](https://github.com/alexgorbatchev/shadcn/blob/main/src/components/stories/navigation/ActionsMenu.stories.tsx)
7
+
8
+ ## Public imports
9
+
10
+ ```tsx
11
+ import { ActionsMenu, ActionsMenuContextTarget, ActionsMenuContextContent, ActionsMenuTrigger, MenuGroup, MenuItem, MenuLinkItem, MenuLabel, MenuSeparator, MenuSub, MenuSubContent, MenuSubTrigger, Button } from "@alexgorbatchev/shadcn";
12
+ import { Tree, TreeItem, useTree, syncDataLoaderFeature, hotkeysCoreFeature, selectionFeature } from "@alexgorbatchev/shadcn/tree";
13
+ ```
14
+
15
+ ## Supporting imports
16
+
17
+ ```tsx
18
+ import type { ReactElement } from "react";
19
+ ```
20
+
21
+ ## Default component
22
+
23
+ ```tsx
24
+ ActionsMenu
25
+ ```
26
+
27
+ ## Default args
28
+
29
+ ```tsx
30
+ {
31
+ label: "Track actions",
32
+ items: (<MenuGroup>
33
+ <MenuItem onClick={() => fixture_menuAction("track-42")}>Inspect track</MenuItem>
34
+ </MenuGroup>),
35
+ }
36
+ ```
37
+
38
+ ## Examples
39
+
40
+ Storybook CSF excerpts. Default args and render apply unless overridden. Local helpers, fixtures, decorators, and providers may be required; these are reference excerpts, not standalone consumer modules. Interaction tests are omitted.
41
+
42
+ ### RegisteredTree
43
+
44
+ ```tsx
45
+ {
46
+ render: () => <RegisteredTreeExample />
47
+ }
48
+ ```
49
+
50
+ ### Dropdown
51
+
52
+ ```tsx
53
+ {}
54
+ ```
55
+
56
+ ### BothEntryPoints
57
+
58
+ ```tsx
59
+ {
60
+ args: { contextTarget: <section aria-label="Track"/> },
61
+ render: (args) => (<ActionsMenu {...args}>
62
+ <p>Selected track</p>
63
+ <ActionsMenuTrigger />
64
+ </ActionsMenu>)
65
+ }
66
+ ```
67
+
68
+ ### NativeTableRow
69
+
70
+ ```tsx
71
+ {
72
+ render: (args) => (<table>
73
+ <tbody>
74
+ <ActionsMenu {...args}>
75
+ <ActionsMenuContextTarget render={<tr ref={fixture_menuTargetRef}/>}>
76
+ <td>Track title</td>
77
+ <td>
78
+ <ActionsMenuTrigger />
79
+ <ActionsMenuContextContent />
80
+ </td>
81
+ </ActionsMenuContextTarget>
82
+ </ActionsMenu>
83
+ </tbody>
84
+ </table>)
85
+ }
86
+ ```
87
+
88
+ ### Disabled
89
+
90
+ ```tsx
91
+ {
92
+ args: { disabled: true, contextTarget: <section aria-label="Protected track"/> }
93
+ }
94
+ ```
95
+
96
+ ### Submenu
97
+
98
+ ```tsx
99
+ {
100
+ args: {
101
+ trigger: <Button variant="outline"/>,
102
+ contextTarget: <section aria-label="Playlist track"/>,
103
+ items: (<>
104
+ <MenuGroup>
105
+ <MenuLabel>Track</MenuLabel>
106
+ <MenuItem disabled>Unavailable action</MenuItem>
107
+ </MenuGroup>
108
+ <MenuSeparator />
109
+ <MenuGroup>
110
+ <MenuSub>
111
+ <MenuSubTrigger>Playlist</MenuSubTrigger>
112
+ <MenuSubContent>
113
+ <MenuGroup>
114
+ <MenuItem onClick={() => fixture_menuAction("playlist-7", "track-42")}>Add to favorites</MenuItem>
115
+ </MenuGroup>
116
+ </MenuSubContent>
117
+ </MenuSub>
118
+ </MenuGroup>
119
+ </>),
120
+ },
121
+ render: (args) => (<ActionsMenu {...args}>
122
+ <ActionsMenuTrigger>Track options</ActionsMenuTrigger>
123
+ </ActionsMenu>)
124
+ }
125
+ ```
126
+
127
+ ### NativeLink
128
+
129
+ ```tsx
130
+ {
131
+ args: {
132
+ size: "sm",
133
+ items: (<MenuGroup>
134
+ <MenuLinkItem href="#details" onClick={(event) => {
135
+ fixture_menuAction(event.currentTarget.hash);
136
+ event.preventDefault();
137
+ }}>
138
+ View details
139
+ </MenuLinkItem>
140
+ </MenuGroup>),
141
+ }
142
+ }
143
+ ```
@@ -70,8 +70,38 @@ Storybook CSF excerpts. Default args and render apply unless overridden. Local h
70
70
  {
71
71
  args: {
72
72
  onConfirm: async () => {
73
- throw new Error("Could not remove image");
73
+ throw new Error("Private removal diagnostic");
74
74
  },
75
75
  }
76
76
  }
77
77
  ```
78
+
79
+ ### AuthoredFailureAndRetry
80
+
81
+ ```tsx
82
+ {
83
+ args: {
84
+ onConfirm: fn(),
85
+ renderError: () => "The image is in use. Close the editor and retry.",
86
+ }
87
+ }
88
+ ```
89
+
90
+ ### LongDescription
91
+
92
+ ```tsx
93
+ {
94
+ args: { description: "Review this irreversible image removal carefully. ".repeat(300) }
95
+ }
96
+ ```
97
+
98
+ ### Pending
99
+
100
+ ```tsx
101
+ {
102
+ beforeEach: () => {
103
+ fixture_confirmation.pending = Promise.withResolvers<void>();
104
+ },
105
+ args: { onConfirm: fn(() => fixture_confirmation.pending.promise) }
106
+ }
107
+ ```
@@ -0,0 +1,102 @@
1
+ # FormDialog
2
+
3
+ Story: @alexgorbatchev/shadcn/components/overlays/FormDialog
4
+ Source: src/components/stories/overlays/FormDialog.stories.tsx
5
+
6
+ [Full source and local helpers](https://github.com/alexgorbatchev/shadcn/blob/main/src/components/stories/overlays/FormDialog.stories.tsx)
7
+
8
+ ## Public imports
9
+
10
+ ```tsx
11
+ import { FormDialog, Input, Button } from "@alexgorbatchev/shadcn";
12
+ ```
13
+
14
+ ## Supporting imports
15
+
16
+ ```tsx
17
+ import { useState, type ReactElement } from "react";
18
+ ```
19
+
20
+ ## Default component
21
+
22
+ ```tsx
23
+ FormDialog
24
+ ```
25
+
26
+ ## Default args
27
+
28
+ ```tsx
29
+ {
30
+ open: false,
31
+ onOpenChange: fn(),
32
+ title: "Edit project",
33
+ description: "Change the project name.",
34
+ submitLabel: "Save project",
35
+ onSubmit: fn((event) => event.preventDefault()),
36
+ children: <Input aria-label="Project name" defaultValue="Example"/>,
37
+ }
38
+ ```
39
+
40
+ ## Default render
41
+
42
+ ```tsx
43
+ function Example(args): ReactElement {
44
+ const [open, setOpen] = useState(false);
45
+ return (<>
46
+ <Button onClick={() => setOpen(true)}>Edit project</Button>
47
+ <FormDialog {...args} open={open} onOpenChange={(next) => {
48
+ args.onOpenChange(next);
49
+ setOpen(next);
50
+ }}/>
51
+ </>);
52
+ }
53
+ ```
54
+
55
+ ## Examples
56
+
57
+ Storybook CSF excerpts. Default args and render apply unless overridden. Local helpers, fixtures, decorators, and providers may be required; these are reference excerpts, not standalone consumer modules. Interaction tests are omitted.
58
+
59
+ ### Submit
60
+
61
+ ```tsx
62
+ {}
63
+ ```
64
+
65
+ ### Busy
66
+
67
+ ```tsx
68
+ {
69
+ args: { isBusy: true }
70
+ }
71
+ ```
72
+
73
+ ### ConsentOnly
74
+
75
+ ```tsx
76
+ {
77
+ args: {
78
+ onSubmit: undefined,
79
+ submitLabel: undefined,
80
+ primaryAction: <Button onClick={fixture_formDialogAction}>Review changes</Button>,
81
+ }
82
+ }
83
+ ```
84
+
85
+ ### DoneOnly
86
+
87
+ ```tsx
88
+ {
89
+ args: { onSubmit: undefined, submitLabel: undefined, cancelLabel: "Done" }
90
+ }
91
+ ```
92
+
93
+ ### LongContent
94
+
95
+ ```tsx
96
+ {
97
+ args: {
98
+ children: Array.from({ length: 60 }, (_, index) => <p key={index}>Project detail {index + 1}</p>),
99
+ error: "Save failed. Retry after checking the project.",
100
+ }
101
+ }
102
+ ```
package/llms/setup.md CHANGED
@@ -360,7 +360,7 @@ Compose `QuestionnaireItem`, `QuestionnaireTitle`, and answer controls inside `Q
360
360
 
361
361
  # Inline editing and ratings
362
362
 
363
- `InlineEdit` mounts an edit session with a controlled `value`, `onValueChange`, `onCommit`, and `onCancel`. Mount it in place of the displayed label. Its input focuses and selects its text by default; `shouldSelectOnMount={false}` preserves the initial caret. Enter or blur commits once, Escape cancels without committing, and asynchronous saves disable the input until completion. Rejected saves display an error and allow retry.
363
+ `InlineEdit` mounts an edit session with a controlled `value`, `onValueChange`, `onCommit`, and `onCancel`. Mount it in place of the displayed label. Its input focuses and selects its text by default; `shouldSelectOnMount={false}` preserves the initial caret. Enter or blur commits once, Escape cancels without committing, and asynchronous saves disable the input until completion. Set `hasChanges={false}` to cancel an unchanged edit before calling `onCommit`; the caller owns normalization and comparison. It defaults to true, so creation sessions can commit their initial value. Rejected saves display a generic error and allow retry; `renderError` can map the unknown failure to application-authored guidance.
364
364
 
365
365
  `VirtualTable` renders a bounded, dynamically measured set of native table rows using TanStack Virtual. Supply `items`, stable `getItemKey`, `header`, `label`, and `renderRow`; spread the supplied measurement props onto each native row. Optional `columns` accepts a `TableColumnGroup`; responsive columns keep their widths aligned with cells that share their `visibleFrom`. `maxHeight` defaults to `65vh`, `estimateRowHeight` to 80 pixels, and `overscan` to five rows. `retainedKeys` keeps editing rows mounted; the focused row is retained automatically. Filtering and selection belong to the consumer.
366
366
 
@@ -370,6 +370,10 @@ Column `meta.filter` offers a column in `DataGridFilters`, hidden columns includ
370
370
 
371
371
  Import `DataGridSelectHeader` and `DataGridSelectCell` from `@alexgorbatchev/shadcn/data-grid`. Pass the current `useTable` result as `table` to both controls, and pass `row` and an accessible `label` to each cell. The header selects selectable filtered rows across all pages and preserves selections hidden by filters. It shows a mixed state when some of those rows are selected and disables itself when none are selectable. Its default label is "Select all filtered rows"; provide `label` to name the scope in your application. Cells follow native row selection rules, including disabled rows and partially selected parents. The controls observe selection changes without requiring the parent table selector to include selection state.
372
372
 
373
+ `ActionsMenu` shares one `items` definition between a dropdown action and an optional context menu. Supply an accessible `label`; the default trigger is a ghost icon button. `size="sm"` displays the label, and `variant`, `disabled`, and `trigger` customize the action. Supplying `contextTarget` composes the native context trigger with that element and adds its popup. Compose items with `MenuItem`, `MenuLinkItem`, checkbox/radio parts, groups, labels, separators, shortcuts, and submenu parts; dropdown and context menus share these implementations. `MenuLinkItem` retains its native anchor and menu keyboard semantics.
374
+
375
+ For nested layouts, compose `ActionsMenuTrigger`, `ActionsMenuContextTarget`, and `ActionsMenuContextContent` explicitly inside `ActionsMenu`. The dropdown trigger owns its local native dropdown root and popup; the context target and content share an independent context root. A tree row can use `TreeItem render={<ActionsMenuContextTarget />}` and put the trigger in its action slot. For a table row, render the context target as the actual `tr`, then place the dropdown trigger and context content inside a `td`: native popup portals insert focus guards at their declaration, which must remain valid table children.
376
+
373
377
  `TreeItem linkProps` places the registered tree item, roving focus, and native drag handlers on an anchor. Pass `href` and anchor events directly, or compose a router link through `linkProps.render`. The outer `render` and `ref` remain available for row overlays; disclosure and `endEnhancer` controls remain siblings of the link. Enter and modified clicks retain native link behavior, while tree arrows retain navigation and expansion behavior. Optional `dropHint={{ content, open, side }}` displays caller-controlled drag feedback without adding a focus target.
374
378
 
375
379
  Embedded actions, links, menus, editable fields, and media controls retain their own keyboard behavior. Registered anchor and button rows still participate in tree navigation; rename and search inputs retain their completion and cancellation shortcuts.
@@ -380,9 +384,11 @@ Embedded actions, links, menus, editable fields, and media controls retain their
380
384
 
381
385
  `DialogContent size="wide"` uses a desktop maximum width of 576px; `size="narrow"` uses 192px, and the default uses 384px. Dialogs remain bounded by the viewport. `FieldGroup columns={2}` arranges fields in two columns on desktop and one on mobile.
382
386
 
387
+ `FormDialog` supplies a controlled dialog with a fixed heading and footer around a scrolling body. Supply `open`, `onOpenChange`, `title`, and children; `description`, `size`, and `density` are optional. With `onSubmit`, the body and actions use a native form: the caller handles `preventDefault`, validation, submission, and pending state. `submitLabel` adds the stock submit button, with optional `submitVariant` and `submitDisabled`; `primaryAction` supplies a custom action instead. Without `onSubmit`, custom actions can request consent without introducing a form. Without a primary action, `cancelLabel="Done"` gives a close-only footer. `isBusy` blocks native dismissal and disables the stock actions; callers disable their own inputs and custom actions. Pass already-rendered safe guidance through `error`.
388
+
383
389
  `ImagePicker` displays a 256px square preview with upload and unset buttons. Supply the existing `src`, a staged `file` (`undefined` for the existing image, `null` for removal), and `onFileChange`/`onClear` callbacks. It accepts PNG, JPEG, and GIF files and releases local preview URLs when they change or unmount. The consumer owns saving and removal confirmation.
384
390
 
385
- `ConfirmationDialog` uses an alert dialog with Cancel and a destructive confirmation button. Supply `open`, `onOpenChange`, `title`, `description`, `confirmLabel`, and `onConfirm`. It waits for asynchronous work, keeps the dialog open on failure, and prevents cancellation while that work is pending.
391
+ `ConfirmationDialog` uses an alert dialog with Cancel and a destructive confirmation button. Supply `open`, `onOpenChange`, `title`, `description`, `confirmLabel`, and `onConfirm`. It waits for asynchronous work, keeps the dialog open on failure, and prevents cancellation while that work is pending. Its body scrolls within the viewport while the heading and actions stay visible. Failures display generic guidance by default; `renderError` maps unknown failures to application-authored messages.
386
392
 
387
393
  # Split views
388
394
 
package/llms.txt CHANGED
@@ -431,6 +431,7 @@ Generated from the public package exports and Storybook sources.
431
431
  ## navigation
432
432
 
433
433
  - [AccountMenu](./llms/components/navigation/AccountMenu.md)
434
+ - [ActionsMenu](./llms/components/navigation/ActionsMenu.md)
434
435
  - [Breadcrumb](./llms/components/navigation/Breadcrumb.md)
435
436
  - [Command](./llms/components/navigation/Command.md)
436
437
  - [ContextMenu](./llms/components/navigation/ContextMenu.md)
@@ -449,6 +450,7 @@ Generated from the public package exports and Storybook sources.
449
450
  - [ConfirmationDialog](./llms/components/overlays/ConfirmationDialog.md)
450
451
  - [Dialog](./llms/components/overlays/Dialog.md)
451
452
  - [Drawer](./llms/components/overlays/Drawer.md)
453
+ - [FormDialog](./llms/components/overlays/FormDialog.md)
452
454
  - [HoverCard](./llms/components/overlays/HoverCard.md)
453
455
  - [Popover](./llms/components/overlays/Popover.md)
454
456
  - [Sheet](./llms/components/overlays/Sheet.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexgorbatchev/shadcn",
3
- "version": "0.0.47",
3
+ "version": "0.0.48",
4
4
  "description": "Sharp, monospace React components with compact and comfortable densities.",
5
5
  "license": "MIT",
6
6
  "repository": {