@adea-ai/ui 0.84.0 → 0.87.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 +90 -1
- package/dist/NOTICE +60 -0
- package/dist/components/composites/action-button/action-button.d.ts.map +1 -1
- package/dist/components/composites/action-button/action-button.js +2 -2
- package/dist/components/composites/action-button/action-button.js.map +1 -1
- package/dist/components/composites/catalog-browser/catalog-browser-group.d.ts +20 -0
- package/dist/components/composites/catalog-browser/catalog-browser-group.d.ts.map +1 -0
- package/dist/components/composites/catalog-browser/catalog-browser-group.js +195 -0
- package/dist/components/composites/catalog-browser/catalog-browser-group.js.map +1 -0
- package/dist/components/composites/catalog-browser/catalog-browser.d.ts +3 -0
- package/dist/components/composites/catalog-browser/catalog-browser.d.ts.map +1 -0
- package/dist/components/composites/catalog-browser/catalog-browser.js +378 -0
- package/dist/components/composites/catalog-browser/catalog-browser.js.map +1 -0
- package/dist/components/composites/catalog-browser/catalog-detail.d.ts +21 -0
- package/dist/components/composites/catalog-browser/catalog-detail.d.ts.map +1 -0
- package/dist/components/composites/catalog-browser/catalog-detail.js +92 -0
- package/dist/components/composites/catalog-browser/catalog-detail.js.map +1 -0
- package/dist/components/composites/catalog-browser/catalog-types.d.ts +78 -0
- package/dist/components/composites/catalog-browser/catalog-types.d.ts.map +1 -0
- package/dist/components/composites/catalog-browser/index.d.ts +4 -0
- package/dist/components/composites/catalog-browser/index.d.ts.map +1 -0
- package/dist/components/composites/catalog-browser/index.js +3 -0
- package/dist/components/composites/list-row/list-row.d.ts +6 -3
- package/dist/components/composites/list-row/list-row.d.ts.map +1 -1
- package/dist/components/composites/list-row/list-row.js +69 -7
- package/dist/components/composites/list-row/list-row.js.map +1 -1
- package/dist/components/composites/settings/settings.d.ts +9 -11
- package/dist/components/composites/settings/settings.d.ts.map +1 -1
- package/dist/components/composites/settings/settings.js +48 -33
- package/dist/components/composites/settings/settings.js.map +1 -1
- package/dist/components/conversation/message-composer.js +1 -1
- package/dist/components/conversation/scroll-follow.d.ts.map +1 -1
- package/dist/components/conversation/scroll-follow.js +95 -15
- package/dist/components/conversation/scroll-follow.js.map +1 -1
- package/dist/components/layout/app-shell/index.d.ts +1 -0
- package/dist/components/layout/app-shell/index.d.ts.map +1 -1
- package/dist/components/layout/app-shell/index.js +2 -1
- package/dist/components/layout/app-shell/skip-link.d.ts +11 -0
- package/dist/components/layout/app-shell/skip-link.d.ts.map +1 -0
- package/dist/components/layout/app-shell/skip-link.js +44 -0
- package/dist/components/layout/app-shell/skip-link.js.map +1 -0
- package/dist/components/layout/floating-preview/floating-preview.d.ts +12 -0
- package/dist/components/layout/floating-preview/floating-preview.d.ts.map +1 -0
- package/dist/components/layout/floating-preview/floating-preview.js +283 -0
- package/dist/components/layout/floating-preview/floating-preview.js.map +1 -0
- package/dist/components/layout/floating-preview/index.d.ts +3 -0
- package/dist/components/layout/floating-preview/index.d.ts.map +1 -0
- package/dist/components/layout/floating-preview/index.js +3 -0
- package/dist/components/layout/floating-preview/model.d.ts +74 -0
- package/dist/components/layout/floating-preview/model.d.ts.map +1 -0
- package/dist/components/layout/floating-preview/model.js +146 -0
- package/dist/components/layout/floating-preview/model.js.map +1 -0
- package/dist/components/theme/index.d.ts +1 -0
- package/dist/components/theme/index.d.ts.map +1 -1
- package/dist/components/theme/index.js +2 -1
- package/dist/components/theme/theme-mode-toggle.d.ts +10 -0
- package/dist/components/theme/theme-mode-toggle.d.ts.map +1 -0
- package/dist/components/theme/theme-mode-toggle.js +82 -0
- package/dist/components/theme/theme-mode-toggle.js.map +1 -0
- package/dist/components/ui/checkbox/checkbox.d.ts +2 -0
- package/dist/components/ui/checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/ui/checkbox/checkbox.js +24 -3
- package/dist/components/ui/checkbox/checkbox.js.map +1 -1
- package/dist/components/ui/combobox/combobox.d.ts.map +1 -1
- package/dist/components/ui/combobox/combobox.js +41 -4
- package/dist/components/ui/combobox/combobox.js.map +1 -1
- package/dist/components/ui/combobox/index.d.ts +1 -0
- package/dist/components/ui/combobox/index.d.ts.map +1 -1
- package/dist/components/ui/combobox/index.js +2 -1
- package/dist/components/ui/combobox/value-combobox.d.ts +19 -0
- package/dist/components/ui/combobox/value-combobox.d.ts.map +1 -0
- package/dist/components/ui/combobox/value-combobox.js +42 -0
- package/dist/components/ui/combobox/value-combobox.js.map +1 -0
- package/dist/components/ui/empty/empty-state.d.ts +15 -0
- package/dist/components/ui/empty/empty-state.d.ts.map +1 -0
- package/dist/components/ui/empty/empty-state.js +96 -0
- package/dist/components/ui/empty/empty-state.js.map +1 -0
- package/dist/components/ui/empty/index.d.ts +1 -0
- package/dist/components/ui/empty/index.d.ts.map +1 -1
- package/dist/components/ui/empty/index.js +2 -1
- package/dist/components/ui/entity-icon/entity-icon.d.ts +4 -1
- package/dist/components/ui/entity-icon/entity-icon.d.ts.map +1 -1
- package/dist/components/ui/entity-icon/entity-icon.js +37 -13
- package/dist/components/ui/entity-icon/entity-icon.js.map +1 -1
- package/dist/components/ui/field/field.d.ts +36 -13
- package/dist/components/ui/field/field.d.ts.map +1 -1
- package/dist/components/ui/field/field.js +146 -24
- package/dist/components/ui/field/field.js.map +1 -1
- package/dist/components/ui/field/index.d.ts +3 -1
- package/dist/components/ui/field/index.d.ts.map +1 -1
- package/dist/components/ui/field/index.js +3 -2
- package/dist/components/ui/field/number-field.d.ts +19 -0
- package/dist/components/ui/field/number-field.d.ts.map +1 -0
- package/dist/components/ui/field/number-field.js +76 -0
- package/dist/components/ui/field/number-field.js.map +1 -0
- package/dist/components/ui/input/index.d.ts +1 -0
- package/dist/components/ui/input/index.d.ts.map +1 -1
- package/dist/components/ui/input/index.js +2 -1
- package/dist/components/ui/input/input-control.d.ts +11 -0
- package/dist/components/ui/input/input-control.d.ts.map +1 -0
- package/dist/components/ui/input/input-control.js +24 -0
- package/dist/components/ui/input/input-control.js.map +1 -0
- package/dist/components/ui/input/input.d.ts.map +1 -1
- package/dist/components/ui/input/input.js +56 -28
- package/dist/components/ui/input/input.js.map +1 -1
- package/dist/components/ui/input-group/index.d.ts +1 -0
- package/dist/components/ui/input-group/index.d.ts.map +1 -1
- package/dist/components/ui/input-group/index.js +2 -1
- package/dist/components/ui/input-group/input-group.d.ts.map +1 -1
- package/dist/components/ui/input-group/input-group.js +42 -5
- package/dist/components/ui/input-group/input-group.js.map +1 -1
- package/dist/components/ui/input-group/secret-input-group.d.ts +11 -0
- package/dist/components/ui/input-group/secret-input-group.d.ts.map +1 -0
- package/dist/components/ui/input-group/secret-input-group.js +67 -0
- package/dist/components/ui/input-group/secret-input-group.js.map +1 -0
- package/dist/components/ui/native-select/native-select.d.ts.map +1 -1
- package/dist/components/ui/native-select/native-select.js +39 -4
- package/dist/components/ui/native-select/native-select.js.map +1 -1
- package/dist/components/ui/progress/progress.d.ts.map +1 -1
- package/dist/components/ui/progress/progress.js +30 -18
- package/dist/components/ui/progress/progress.js.map +1 -1
- package/dist/components/ui/radio-group/radio-group.d.ts.map +1 -1
- package/dist/components/ui/radio-group/radio-group.js +41 -4
- package/dist/components/ui/radio-group/radio-group.js.map +1 -1
- package/dist/components/ui/switch/switch.d.ts +2 -0
- package/dist/components/ui/switch/switch.d.ts.map +1 -1
- package/dist/components/ui/switch/switch.js +24 -3
- package/dist/components/ui/switch/switch.js.map +1 -1
- package/dist/components/ui/tabs/tabs.js +1 -1
- package/dist/components/ui/tabs/tabs.js.map +1 -1
- package/dist/components/ui/text-link/index.d.ts +2 -0
- package/dist/components/ui/text-link/index.d.ts.map +1 -0
- package/dist/components/ui/text-link/index.js +2 -0
- package/dist/components/ui/text-link/text-link.d.ts +9 -0
- package/dist/components/ui/text-link/text-link.d.ts.map +1 -0
- package/dist/components/ui/text-link/text-link.js +30 -0
- package/dist/components/ui/text-link/text-link.js.map +1 -0
- package/dist/components/ui/textarea/textarea.d.ts.map +1 -1
- package/dist/components/ui/textarea/textarea.js +41 -4
- package/dist/components/ui/textarea/textarea.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -8
- package/dist/lib/clipboard.d.ts +3 -0
- package/dist/lib/clipboard.d.ts.map +1 -0
- package/dist/lib/clipboard.js +35 -0
- package/dist/lib/clipboard.js.map +1 -0
- package/dist/lib/download.d.ts +3 -0
- package/dist/lib/download.d.ts.map +1 -0
- package/dist/lib/download.js +31 -0
- package/dist/lib/download.js.map +1 -0
- package/dist/lib/form-field.d.ts +37 -0
- package/dist/lib/form-field.d.ts.map +1 -0
- package/dist/lib/form-field.js +47 -0
- package/dist/lib/form-field.js.map +1 -0
- package/dist/r/app-shell.json +5 -0
- package/dist/r/catalog-browser.json +47 -0
- package/dist/r/combobox.json +5 -0
- package/dist/r/empty.json +10 -1
- package/dist/r/field.json +7 -0
- package/dist/r/floating-preview.json +30 -0
- package/dist/r/input-group.json +6 -0
- package/dist/r/input.json +5 -0
- package/dist/r/lib.json +15 -0
- package/dist/r/list-row.json +1 -0
- package/dist/r/registry.json +159 -1
- package/dist/r/src/components/composites/action-button/action-button.tsx +5 -1
- package/dist/r/src/components/composites/catalog-browser/catalog-browser-group.tsx +148 -0
- package/dist/r/src/components/composites/catalog-browser/catalog-browser.tsx +258 -0
- package/dist/r/src/components/composites/catalog-browser/catalog-detail.tsx +64 -0
- package/dist/r/src/components/composites/catalog-browser/catalog-types.ts +83 -0
- package/dist/r/src/components/composites/catalog-browser/index.ts +10 -0
- package/dist/r/src/components/composites/list-row/list-row.tsx +81 -8
- package/dist/r/src/components/composites/settings/settings.tsx +67 -37
- package/dist/r/src/components/conversation/scroll-follow.ts +109 -15
- package/dist/r/src/components/layout/app-shell/index.ts +1 -0
- package/dist/r/src/components/layout/app-shell/skip-link.tsx +35 -0
- package/dist/r/src/components/layout/floating-preview/floating-preview.tsx +260 -0
- package/dist/r/src/components/layout/floating-preview/index.ts +2 -0
- package/dist/r/src/components/layout/floating-preview/model.ts +285 -0
- package/dist/r/src/components/theme/index.ts +1 -0
- package/dist/r/src/components/theme/theme-mode-toggle.tsx +56 -0
- package/dist/r/src/components/ui/checkbox/checkbox.tsx +20 -3
- package/dist/r/src/components/ui/combobox/combobox.tsx +24 -1
- package/dist/r/src/components/ui/combobox/index.ts +1 -0
- package/dist/r/src/components/ui/combobox/value-combobox.tsx +38 -0
- package/dist/r/src/components/ui/empty/empty-state.tsx +71 -0
- package/dist/r/src/components/ui/empty/index.ts +1 -0
- package/dist/r/src/components/ui/entity-icon/entity-icon.tsx +33 -2
- package/dist/r/src/components/ui/field/field.tsx +102 -5
- package/dist/r/src/components/ui/field/index.ts +5 -0
- package/dist/r/src/components/ui/field/number-field.tsx +71 -0
- package/dist/r/src/components/ui/input/index.ts +1 -0
- package/dist/r/src/components/ui/input/input-control.tsx +38 -0
- package/dist/r/src/components/ui/input/input.tsx +32 -20
- package/dist/r/src/components/ui/input-group/index.ts +1 -0
- package/dist/r/src/components/ui/input-group/input-group.tsx +25 -2
- package/dist/r/src/components/ui/input-group/secret-input-group.tsx +58 -0
- package/dist/r/src/components/ui/native-select/native-select.tsx +27 -1
- package/dist/r/src/components/ui/progress/progress.tsx +12 -8
- package/dist/r/src/components/ui/radio-group/radio-group.tsx +30 -2
- package/dist/r/src/components/ui/switch/switch.tsx +20 -3
- package/dist/r/src/components/ui/tabs/tabs.tsx +1 -1
- package/dist/r/src/components/ui/text-link/index.ts +2 -0
- package/dist/r/src/components/ui/text-link/text-link.tsx +28 -0
- package/dist/r/src/components/ui/textarea/textarea.tsx +24 -1
- package/dist/r/src/lib/clipboard.ts +41 -0
- package/dist/r/src/lib/download.ts +29 -0
- package/dist/r/src/lib/form-field.ts +93 -0
- package/dist/r/text-link.json +22 -0
- package/dist/r/theming.json +6 -0
- package/package.json +1 -1
- package/registry.json +159 -1
- package/src/components/composites/action-button/action-button.tsx +5 -1
- package/src/components/composites/catalog-browser/catalog-browser-group.tsx +148 -0
- package/src/components/composites/catalog-browser/catalog-browser.tsx +258 -0
- package/src/components/composites/catalog-browser/catalog-detail.tsx +64 -0
- package/src/components/composites/catalog-browser/catalog-types.ts +83 -0
- package/src/components/composites/catalog-browser/index.ts +10 -0
- package/src/components/composites/list-row/list-row.tsx +81 -8
- package/src/components/composites/settings/settings.tsx +67 -37
- package/src/components/conversation/scroll-follow.ts +109 -15
- package/src/components/layout/app-shell/index.ts +1 -0
- package/src/components/layout/app-shell/skip-link.tsx +35 -0
- package/src/components/layout/floating-preview/floating-preview.tsx +260 -0
- package/src/components/layout/floating-preview/index.ts +2 -0
- package/src/components/layout/floating-preview/model.ts +285 -0
- package/src/components/theme/index.ts +1 -0
- package/src/components/theme/theme-mode-toggle.tsx +56 -0
- package/src/components/ui/checkbox/checkbox.tsx +20 -3
- package/src/components/ui/combobox/combobox.tsx +24 -1
- package/src/components/ui/combobox/index.ts +1 -0
- package/src/components/ui/combobox/value-combobox.tsx +38 -0
- package/src/components/ui/empty/empty-state.tsx +71 -0
- package/src/components/ui/empty/index.ts +1 -0
- package/src/components/ui/entity-icon/entity-icon.tsx +33 -2
- package/src/components/ui/field/field.tsx +102 -5
- package/src/components/ui/field/index.ts +5 -0
- package/src/components/ui/field/number-field.tsx +71 -0
- package/src/components/ui/input/index.ts +1 -0
- package/src/components/ui/input/input-control.tsx +38 -0
- package/src/components/ui/input/input.tsx +32 -20
- package/src/components/ui/input-group/index.ts +1 -0
- package/src/components/ui/input-group/input-group.tsx +25 -2
- package/src/components/ui/input-group/secret-input-group.tsx +58 -0
- package/src/components/ui/native-select/native-select.tsx +27 -1
- package/src/components/ui/progress/progress.tsx +12 -8
- package/src/components/ui/radio-group/radio-group.tsx +30 -2
- package/src/components/ui/switch/switch.tsx +20 -3
- package/src/components/ui/tabs/tabs.tsx +1 -1
- package/src/components/ui/text-link/index.ts +2 -0
- package/src/components/ui/text-link/text-link.tsx +28 -0
- package/src/components/ui/textarea/textarea.tsx +24 -1
- package/src/index.ts +4 -0
- package/src/lib/clipboard.ts +41 -0
- package/src/lib/download.ts +29 -0
- package/src/lib/form-field.ts +93 -0
package/README.md
CHANGED
|
@@ -67,7 +67,9 @@ through. Use `value` with `onChange` for a controlled selection, or `defaultValu
|
|
|
67
67
|
to initialize an uncontrolled one. Use `Select` for searchable, runtime, or
|
|
68
68
|
longer lists that need a custom popover.
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
`InputControl` is the styled native input without suggestion-list behavior. Use
|
|
71
|
+
`Input` when a form should offer native datalist suggestions; custom values
|
|
72
|
+
remain valid and submit unchanged.
|
|
71
73
|
The library owns the datalist and unique association; a suggestion does not
|
|
72
74
|
restrict the submitted value. Native `required`, `pattern`, form, event, and
|
|
73
75
|
ref props still apply to the input.
|
|
@@ -93,6 +95,85 @@ Ctrl/Cmd + arrow moves skip disabled columns without wrapping at the edges.
|
|
|
93
95
|
After a controlled move settles, focus follows the moved card only when the
|
|
94
96
|
source card owned focus; another focus or pointer action cancels restoration.
|
|
95
97
|
|
|
98
|
+
`CatalogBrowser` presents a host-owned searchable catalog with ordered category
|
|
99
|
+
groups, discover/installed tabs, bounded group expansion, optional filters and
|
|
100
|
+
supplemental tabs. Give `entries` the full set of detail records so opening an
|
|
101
|
+
item remains stable when a query or tab filters the visible `groups`. The host
|
|
102
|
+
owns catalog verification, filtering, installed state, permission decisions,
|
|
103
|
+
errors, and actions. Selecting an item opens its host-rendered detail and
|
|
104
|
+
returns focus to the originating result when Back is chosen. `CatalogDetail`
|
|
105
|
+
provides the shared item summary/action frame and `CatalogDetailSection` gives
|
|
106
|
+
host-specific permissions or metadata a shared section surface. Supply
|
|
107
|
+
`resultsRegionLabel` and `detailRegionLabel` to name their keyboard-focusable,
|
|
108
|
+
shared `ScrollArea` regions. The results area scrolls notices along with loading,
|
|
109
|
+
empty, and error states even when those states contain no interactive control.
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import {
|
|
113
|
+
CatalogBrowser,
|
|
114
|
+
CatalogDetail,
|
|
115
|
+
CatalogDetailSection,
|
|
116
|
+
type CatalogBrowserEntry,
|
|
117
|
+
type CatalogBrowserGroup,
|
|
118
|
+
} from '@adea-ai/ui/components/composites/catalog-browser'
|
|
119
|
+
|
|
120
|
+
const entries: readonly CatalogBrowserEntry<VerifiedPlugin>[] = /* all detail records */ []
|
|
121
|
+
const groups: readonly CatalogBrowserGroup<VerifiedPlugin>[] = /* visible filtered groups */ []
|
|
122
|
+
|
|
123
|
+
<CatalogBrowser
|
|
124
|
+
open={open()}
|
|
125
|
+
tabs={[
|
|
126
|
+
{ id: 'discover', label: 'Discover' },
|
|
127
|
+
{ id: 'installed', label: 'Installed' },
|
|
128
|
+
{ id: 'navigation', label: 'Navigation', kind: 'supplemental' },
|
|
129
|
+
]}
|
|
130
|
+
tab={tab()}
|
|
131
|
+
tabsLabel="Catalog views"
|
|
132
|
+
onTabChange={setTab}
|
|
133
|
+
query={query()}
|
|
134
|
+
onQueryChange={setQuery}
|
|
135
|
+
searchLabel="Search catalog"
|
|
136
|
+
searchPlaceholder="Search applications"
|
|
137
|
+
resultsRegionLabel="Catalog results"
|
|
138
|
+
resultCount={visibleCount()}
|
|
139
|
+
resultLabel={(count) => `${count} applications`}
|
|
140
|
+
loadingLabel="Loading catalog"
|
|
141
|
+
status={catalogStatus()}
|
|
142
|
+
catalogError={catalogError()}
|
|
143
|
+
emptyState={emptyState()}
|
|
144
|
+
groups={groups}
|
|
145
|
+
entries={entries}
|
|
146
|
+
selectedId={selectedId()}
|
|
147
|
+
onSelect={(plugin) => setSelectedId(plugin.id)}
|
|
148
|
+
onBack={() => setSelectedId(null)}
|
|
149
|
+
backLabel="Back to catalog"
|
|
150
|
+
detailRegionLabel="Application details"
|
|
151
|
+
installedLabel="Installed"
|
|
152
|
+
publishedByLabel={(publisher) => `Published by ${publisher}`}
|
|
153
|
+
showMoreLabel={(hidden) => `See ${hidden[0]?.name} and more`}
|
|
154
|
+
showLessLabel="Show less"
|
|
155
|
+
renderIcon={(plugin) => <PluginIcon plugin={plugin} />}
|
|
156
|
+
renderDetail={(plugin) => (
|
|
157
|
+
<CatalogDetail
|
|
158
|
+
title={plugin.name}
|
|
159
|
+
description={plugin.description}
|
|
160
|
+
category={plugin.category}
|
|
161
|
+
publisher={plugin.publisher}
|
|
162
|
+
publishedByLabel={(publisher) => `Published by ${publisher}`}
|
|
163
|
+
action={<InstallButton plugin={plugin} />}
|
|
164
|
+
>
|
|
165
|
+
<CatalogDetailSection title="Permissions">
|
|
166
|
+
<PluginPermissions plugin={plugin} />
|
|
167
|
+
</CatalogDetailSection>
|
|
168
|
+
</CatalogDetail>
|
|
169
|
+
)}
|
|
170
|
+
renderSupplementalView={(id) => (id === 'navigation' ? <NavigationSettings /> : undefined)}
|
|
171
|
+
/>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The `CatalogBrowser` story demonstrates category expansion, search, separate
|
|
175
|
+
installed content, a supplemental navigation surface, and host-provided details.
|
|
176
|
+
|
|
96
177
|
Tailwind ignores dependency directories by default. Register the component
|
|
97
178
|
directories your application uses in its stylesheet, relative to that stylesheet:
|
|
98
179
|
|
|
@@ -628,3 +709,11 @@ keyboard disclosure, visible actions and automated accessibility. This is shared
|
|
|
628
709
|
composition evidence; bounded runtime projection, storage and production chat
|
|
629
710
|
integration remain application acceptance gates. Attribution for the selected
|
|
630
711
|
KiroCrew source contracts is recorded in the issue-specific `NOTICE` entry.
|
|
712
|
+
|
|
713
|
+
### Controlled appearance mode
|
|
714
|
+
|
|
715
|
+
`ThemeModeToggle` provides the shared light/dark/system selector for hosts that
|
|
716
|
+
own their preference provider and storage. Pass `mode` and `onModeChange`; the
|
|
717
|
+
control owns roving keyboard focus, pressed state and explanatory tooltips. It
|
|
718
|
+
does not require or mount the shared `ThemeProvider`. `ThemeToggle` retains its
|
|
719
|
+
existing provider-bound API.
|
package/dist/NOTICE
CHANGED
|
@@ -390,3 +390,63 @@ Redux and Framer Motion ownership. Relevant test contracts come from
|
|
|
390
390
|
`website/src/test/rowDisclosure.test.tsx`; compiled and Solid packed consumers are
|
|
391
391
|
exercised in headless Chromium, WebKit and native Node SSR. Full runtime projection,
|
|
392
392
|
durable application storage and production Chat adoption remain host-owned gates.
|
|
393
|
+
|
|
394
|
+
## Floating preview geometry translated from t3code
|
|
395
|
+
|
|
396
|
+
`packages/ui/src/components/layout/floating-preview/model.ts` translates the
|
|
397
|
+
host-independent fitting, clamping, obstacle-avoidance and aspect-preserving
|
|
398
|
+
resize behavior from `apps/web/src/components/preview/previewMiniPlayerLayout.ts`
|
|
399
|
+
and its tests in t3code, issue #422, pinned at revision
|
|
400
|
+
`77bca8b2d76a1f42552e5eee7d277fcb1160347a`.
|
|
401
|
+
|
|
402
|
+
MIT License
|
|
403
|
+
|
|
404
|
+
Copyright (c) 2026 T3 Tools Inc.
|
|
405
|
+
|
|
406
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
407
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
408
|
+
in the Software without restriction, including without limitation the rights
|
|
409
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
410
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
411
|
+
furnished to do so, subject to the following conditions:
|
|
412
|
+
|
|
413
|
+
The above copyright notice and this permission notice shall be included in all
|
|
414
|
+
copies or substantial portions of the Software.
|
|
415
|
+
|
|
416
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
417
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
418
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
419
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
420
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
421
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
422
|
+
SOFTWARE.
|
|
423
|
+
|
|
424
|
+
The shared component owns reusable geometry and pointer/keyboard controls only.
|
|
425
|
+
T3 runtime state, streaming, Electron services, native picture-in-picture,
|
|
426
|
+
notifications and content rendering are not included.
|
|
427
|
+
|
|
428
|
+
## Catalog browser translated from KiroCrew (issue #425 selected unit)
|
|
429
|
+
|
|
430
|
+
`packages/ui/src/components/composites/catalog-browser/` translates the
|
|
431
|
+
category, search, discover/installed, result-detail and focus-return composition
|
|
432
|
+
from `website/src/pages/apps/DiscoverPage.tsx` and
|
|
433
|
+
`website/src/components/appstore/CategoryRail.tsx`, pinned at KiroCrew revision
|
|
434
|
+
`283e136c0f902e965a535a7c9548c57c7504fed0`.
|
|
435
|
+
|
|
436
|
+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
437
|
+
This product includes software developed at Amazon.com, Inc.
|
|
438
|
+
(https://www.amazon.com/). Licensed under the Apache License, Version 2.0.
|
|
439
|
+
|
|
440
|
+
The translated presentation keeps stable host-ordered categories, discover and
|
|
441
|
+
installed views, bounded category expansion, native search, item details, and
|
|
442
|
+
focus return to the selected result. `CatalogDetail` supplies a shared summary,
|
|
443
|
+
action and section frame; hosts own verified records, filtering, installed
|
|
444
|
+
truth, permissions, recovery, install effects and detail copy. The nearest
|
|
445
|
+
donor behavior tests are `website/playwright/apps.spec.ts` and
|
|
446
|
+
`website/src/test/appstoreCategories.test.ts`.
|
|
447
|
+
|
|
448
|
+
KiroCrew's React/runtime, catalog transport, account and entitlement state,
|
|
449
|
+
installation/execution authority, provider data and app-specific services are
|
|
450
|
+
excluded. Its distinct `/apps/library` core-app launchpad is also excluded:
|
|
451
|
+
this selected unit is the external verified plugin marketplace adapter, while
|
|
452
|
+
Adea's #757 App Library remains a separate core-view and rail-management flow.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-button.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/action-button/action-button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,GAAG,EACR,KAAK,cAAc,EACpB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAI1D;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG;IACpF,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjD,uFAAuF;IACvF,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AA+CD,wBAAgB,YAAY,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"action-button.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/action-button/action-button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,GAAG,EACR,KAAK,cAAc,EACpB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAI1D;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG;IACpF,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjD,uFAAuF;IACvF,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AA+CD,wBAAgB,YAAY,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,eAsG5F"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Button } from "../../ui/button/button.js";
|
|
2
|
-
import { Tooltip, TooltipContent, TooltipTrigger } from "../../ui/tooltip/tooltip.js";
|
|
3
2
|
import { Spinner } from "../../ui/spinner/spinner.js";
|
|
3
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "../../ui/tooltip/tooltip.js";
|
|
4
4
|
import { createComponent, insert, memo, mergeProps, template } from "solid-js/web";
|
|
5
5
|
import { Show, createSignal, splitProps } from "solid-js";
|
|
6
6
|
//#region src/components/composites/action-button/action-button.tsx
|
|
@@ -64,7 +64,7 @@ function ActionButton(props) {
|
|
|
64
64
|
class: [local.class, local.tooltip && disabled() && "aria-disabled:pointer-events-auto"].filter(Boolean).join(" "),
|
|
65
65
|
disabled: disabled() && !local.tooltip,
|
|
66
66
|
"aria-disabled": disabled() ? true : rest["aria-disabled"],
|
|
67
|
-
tabIndex: local.as === "a" && disabled() ? local.tooltip ? 0 : -1 :
|
|
67
|
+
tabIndex: rest.tabIndex ?? (local.as === "a" && disabled() ? local.tooltip ? 0 : -1 : local.tooltip ? 0 : void 0),
|
|
68
68
|
role: local.as === "a" && disabled() ? "link" : rest.role,
|
|
69
69
|
href: local.as === "a" && disabled() ? void 0 : rest.href,
|
|
70
70
|
"aria-busy": busy() || local["aria-busy"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-button.js","names":["Show","createSignal","splitProps","ComponentProps","JSX","ValidComponent","Button","ButtonProps","Spinner","Tooltip","TooltipContent","TooltipTrigger","ActionButtonProps","T","tooltip","tooltipSide","busy","busyLabel","invokeHandler","handler","event","Event","Array","isArray","callback","data","chainedHandler","before","guardedClick","disabled","onActivate","MouseEvent","preventDefault","stopImmediatePropagation","ButtonTargetProps","Omit","actionAs","ButtonTarget","props","local","rest","PolymorphicButton","targetProps","Element","_$createComponent","_$mergeProps","as","ActionButton","busyStatus","tooltipOpen","setTooltipOpen","tooltipSuppression","setTooltipSuppression","onClickCapture","buttonProps","PolymorphicButtonTarget","variant","size","class","filter","Boolean","join","tabIndex","role","href","undefined","onClick","detail","onPointerLeave","onBlur","Record","contents","when","children","label","_$memo","fallback","open","onOpenChange","side","_el$","_tmpl$","_$insert","_$createComponent","PolymorphicButton","_$mergeProps","_$memo"],"sources":["../../../../src/components/composites/action-button/action-button.tsx"],"sourcesContent":["import {\n Show,\n createSignal,\n splitProps,\n type ComponentProps,\n type JSX,\n type ValidComponent,\n} from 'solid-js'\nimport { Button, type ButtonProps } from '../../ui/button'\nimport { Spinner } from '../../ui/spinner'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip'\n\n/**\n * ActionButton.\n *\n * A Button with optional explanatory tooltip and busy feedback. Use it for a\n * simple action that needs these states; actions with product-specific rules\n * should compose Button directly.\n *\n * The tooltip trigger renders the polymorphic Button itself. A disabled native\n * control cannot receive pointer or keyboard events. When a tooltip is set,\n * disabled actions therefore use focusable `aria-disabled` semantics and guard\n * activation; without a tooltip, native buttons retain native disabling.\n * Custom polymorphic components must forward aria, event, and href props for\n * these guarantees to apply.\n */\nexport type ActionButtonProps<T extends ValidComponent = 'button'> = ButtonProps<T> & {\n /** A short explanation, also shown on keyboard focus. The Button still needs its own name. */\n tooltip?: string\n tooltipSide?: 'top' | 'right' | 'bottom' | 'left'\n /** Disables the action and announces the busy label through a polite status region. */\n busy?: boolean\n /** The activity announced while busy. The Button's accessible name stays unchanged. */\n busyLabel?: string\n}\n\nfunction invokeHandler(handler: unknown, event: Event) {\n if (Array.isArray(handler)) {\n const [callback, data] = handler as [(data: unknown, event: Event) => void, unknown]\n callback(data, event)\n } else if (typeof handler === 'function') {\n const callback = handler as (event: Event) => void\n callback(event)\n }\n}\n\nfunction chainedHandler(handler: unknown, before: (event: Event) => void) {\n return (event: Event) => {\n before(event)\n invokeHandler(handler, event)\n }\n}\n\nfunction guardedClick(\n handler: unknown,\n disabled: () => boolean,\n onActivate: (event: MouseEvent) => void = () => {}\n) {\n return (event: MouseEvent) => {\n if (disabled()) {\n event.preventDefault()\n event.stopImmediatePropagation()\n return\n }\n\n onActivate(event)\n invokeHandler(handler, event)\n }\n}\n\ntype ButtonTargetProps<T extends ValidComponent = 'button'> = Omit<ButtonProps<T>, 'as'> & {\n actionAs?: T\n}\n\n/** Adapter keeps TooltipTrigger's `as` separate from Button's polymorphic `as`. */\nfunction ButtonTarget<T extends ValidComponent = 'button'>(props: ButtonTargetProps<T>) {\n const [local, rest] = splitProps(props as ButtonTargetProps, ['actionAs'])\n const PolymorphicButton = Button as (targetProps: ButtonProps<T>) => JSX.Element\n return <PolymorphicButton as={(local.actionAs ?? 'button') as T} {...(rest as ButtonProps<T>)} />\n}\n\nexport function ActionButton<T extends ValidComponent = 'button'>(props: ActionButtonProps<T>) {\n const [local, rest] = splitProps(props as ActionButtonProps, [\n 'as',\n 'variant',\n 'size',\n 'class',\n 'children',\n 'disabled',\n 'aria-busy',\n 'tooltip',\n 'tooltipSide',\n 'busy',\n 'busyLabel',\n ])\n const busy = () => local.busy ?? false\n const disabled = () => busy() || !!local.disabled\n const busyStatus = () => local.busyLabel ?? 'Working'\n const [tooltipOpen, setTooltipOpen] = createSignal(false)\n const [tooltipSuppression, setTooltipSuppression] = createSignal<'pointer' | 'focus' | null>(null)\n const onClickCapture = (rest as { onClickCapture?: unknown }).onClickCapture\n const PolymorphicButton = Button as (buttonProps: ButtonProps<T>) => JSX.Element\n const PolymorphicButtonTarget = ButtonTarget as (targetProps: ButtonTargetProps<T>) => JSX.Element\n\n const buttonProps = () => ({\n ...rest,\n variant: local.variant,\n size: local.size,\n class: [local.class, local.tooltip && disabled() && 'aria-disabled:pointer-events-auto']\n .filter(Boolean)\n .join(' '),\n disabled: disabled() && !local.tooltip,\n 'aria-disabled': disabled() ? true : rest['aria-disabled'],\n tabIndex: local.as === 'a' && disabled() ? (local.tooltip ? 0 : -1) : rest.tabIndex,\n role: local.as === 'a' && disabled() ? 'link' : rest.role,\n href: local.as === 'a' && disabled() ? undefined : (rest as { href?: string }).href,\n 'aria-busy': busy() || local['aria-busy'],\n onClick: guardedClick(rest.onClick, disabled, (event) => {\n if (!local.tooltip) return\n setTooltipSuppression(event.detail > 0 ? 'pointer' : 'focus')\n setTooltipOpen(false)\n }),\n onPointerLeave: chainedHandler(rest.onPointerLeave, () => {\n if (tooltipSuppression() === 'pointer') setTooltipSuppression(null)\n }),\n onBlur: chainedHandler(rest.onBlur, () => {\n if (tooltipSuppression() === 'focus') setTooltipSuppression(null)\n }),\n onClickCapture: onClickCapture ? guardedClick(onClickCapture, disabled) : undefined,\n 'on:click': guardedClick((rest as Record<string, unknown>)['on:click'], disabled),\n 'oncapture:click': guardedClick((rest as Record<string, unknown>)['oncapture:click'], disabled),\n })\n\n const contents = () => (\n <>\n <Show when={busy()}>\n <Spinner size=\"sm\" label={false} aria-hidden=\"true\" data-icon=\"inline-start\" />\n </Show>\n {local.children}\n </>\n )\n\n return (\n <>\n <Show\n when={local.tooltip}\n fallback={\n <PolymorphicButton\n as={(local.as ?? 'button') as T}\n {...(buttonProps() as unknown as ButtonProps<T>)}\n >\n {contents()}\n </PolymorphicButton>\n }\n >\n <Tooltip\n open={tooltipOpen()}\n onOpenChange={(open) => {\n if (open && tooltipSuppression()) return\n setTooltipOpen(open)\n }}\n >\n <TooltipTrigger\n as={PolymorphicButtonTarget}\n {...(buttonProps() as unknown as ComponentProps<typeof PolymorphicButtonTarget>)}\n actionAs={(local.as ?? 'button') as T}\n >\n {contents()}\n </TooltipTrigger>\n <TooltipContent side={local.tooltipSide}>{local.tooltip}</TooltipContent>\n </Tooltip>\n </Show>\n <Show when={busy()}>\n <span role=\"status\" aria-live=\"polite\" class=\"visually-hidden\">\n {busyStatus()}\n </span>\n </Show>\n </>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"action-button.js","names":["Show","createSignal","splitProps","ComponentProps","JSX","ValidComponent","Button","ButtonProps","Spinner","Tooltip","TooltipContent","TooltipTrigger","ActionButtonProps","T","tooltip","tooltipSide","busy","busyLabel","invokeHandler","handler","event","Event","Array","isArray","callback","data","chainedHandler","before","guardedClick","disabled","onActivate","MouseEvent","preventDefault","stopImmediatePropagation","ButtonTargetProps","Omit","actionAs","ButtonTarget","props","local","rest","PolymorphicButton","targetProps","Element","_$createComponent","_$mergeProps","as","ActionButton","busyStatus","tooltipOpen","setTooltipOpen","tooltipSuppression","setTooltipSuppression","onClickCapture","buttonProps","PolymorphicButtonTarget","variant","size","class","filter","Boolean","join","tabIndex","undefined","role","href","onClick","detail","onPointerLeave","onBlur","Record","contents","when","children","label","_$memo","fallback","open","onOpenChange","side","_el$","_tmpl$","_$insert","_$createComponent","PolymorphicButton","_$mergeProps","_$memo"],"sources":["../../../../src/components/composites/action-button/action-button.tsx"],"sourcesContent":["import {\n Show,\n createSignal,\n splitProps,\n type ComponentProps,\n type JSX,\n type ValidComponent,\n} from 'solid-js'\nimport { Button, type ButtonProps } from '../../ui/button'\nimport { Spinner } from '../../ui/spinner'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip'\n\n/**\n * ActionButton.\n *\n * A Button with optional explanatory tooltip and busy feedback. Use it for a\n * simple action that needs these states; actions with product-specific rules\n * should compose Button directly.\n *\n * The tooltip trigger renders the polymorphic Button itself. A disabled native\n * control cannot receive pointer or keyboard events. When a tooltip is set,\n * disabled actions therefore use focusable `aria-disabled` semantics and guard\n * activation; without a tooltip, native buttons retain native disabling.\n * Custom polymorphic components must forward aria, event, and href props for\n * these guarantees to apply.\n */\nexport type ActionButtonProps<T extends ValidComponent = 'button'> = ButtonProps<T> & {\n /** A short explanation, also shown on keyboard focus. The Button still needs its own name. */\n tooltip?: string\n tooltipSide?: 'top' | 'right' | 'bottom' | 'left'\n /** Disables the action and announces the busy label through a polite status region. */\n busy?: boolean\n /** The activity announced while busy. The Button's accessible name stays unchanged. */\n busyLabel?: string\n}\n\nfunction invokeHandler(handler: unknown, event: Event) {\n if (Array.isArray(handler)) {\n const [callback, data] = handler as [(data: unknown, event: Event) => void, unknown]\n callback(data, event)\n } else if (typeof handler === 'function') {\n const callback = handler as (event: Event) => void\n callback(event)\n }\n}\n\nfunction chainedHandler(handler: unknown, before: (event: Event) => void) {\n return (event: Event) => {\n before(event)\n invokeHandler(handler, event)\n }\n}\n\nfunction guardedClick(\n handler: unknown,\n disabled: () => boolean,\n onActivate: (event: MouseEvent) => void = () => {}\n) {\n return (event: MouseEvent) => {\n if (disabled()) {\n event.preventDefault()\n event.stopImmediatePropagation()\n return\n }\n\n onActivate(event)\n invokeHandler(handler, event)\n }\n}\n\ntype ButtonTargetProps<T extends ValidComponent = 'button'> = Omit<ButtonProps<T>, 'as'> & {\n actionAs?: T\n}\n\n/** Adapter keeps TooltipTrigger's `as` separate from Button's polymorphic `as`. */\nfunction ButtonTarget<T extends ValidComponent = 'button'>(props: ButtonTargetProps<T>) {\n const [local, rest] = splitProps(props as ButtonTargetProps, ['actionAs'])\n const PolymorphicButton = Button as (targetProps: ButtonProps<T>) => JSX.Element\n return <PolymorphicButton as={(local.actionAs ?? 'button') as T} {...(rest as ButtonProps<T>)} />\n}\n\nexport function ActionButton<T extends ValidComponent = 'button'>(props: ActionButtonProps<T>) {\n const [local, rest] = splitProps(props as ActionButtonProps, [\n 'as',\n 'variant',\n 'size',\n 'class',\n 'children',\n 'disabled',\n 'aria-busy',\n 'tooltip',\n 'tooltipSide',\n 'busy',\n 'busyLabel',\n ])\n const busy = () => local.busy ?? false\n const disabled = () => busy() || !!local.disabled\n const busyStatus = () => local.busyLabel ?? 'Working'\n const [tooltipOpen, setTooltipOpen] = createSignal(false)\n const [tooltipSuppression, setTooltipSuppression] = createSignal<'pointer' | 'focus' | null>(null)\n const onClickCapture = (rest as { onClickCapture?: unknown }).onClickCapture\n const PolymorphicButton = Button as (buttonProps: ButtonProps<T>) => JSX.Element\n const PolymorphicButtonTarget = ButtonTarget as (targetProps: ButtonTargetProps<T>) => JSX.Element\n\n const buttonProps = () => ({\n ...rest,\n variant: local.variant,\n size: local.size,\n class: [local.class, local.tooltip && disabled() && 'aria-disabled:pointer-events-auto']\n .filter(Boolean)\n .join(' '),\n disabled: disabled() && !local.tooltip,\n 'aria-disabled': disabled() ? true : rest['aria-disabled'],\n // Make tooltip-bearing native controls explicit tab stops in WebKit configurations that\n // otherwise skip implicit button stops. A caller's tabIndex remains authoritative.\n tabIndex:\n rest.tabIndex ??\n (local.as === 'a' && disabled() ? (local.tooltip ? 0 : -1) : local.tooltip ? 0 : undefined),\n role: local.as === 'a' && disabled() ? 'link' : rest.role,\n href: local.as === 'a' && disabled() ? undefined : (rest as { href?: string }).href,\n 'aria-busy': busy() || local['aria-busy'],\n onClick: guardedClick(rest.onClick, disabled, (event) => {\n if (!local.tooltip) return\n setTooltipSuppression(event.detail > 0 ? 'pointer' : 'focus')\n setTooltipOpen(false)\n }),\n onPointerLeave: chainedHandler(rest.onPointerLeave, () => {\n if (tooltipSuppression() === 'pointer') setTooltipSuppression(null)\n }),\n onBlur: chainedHandler(rest.onBlur, () => {\n if (tooltipSuppression() === 'focus') setTooltipSuppression(null)\n }),\n onClickCapture: onClickCapture ? guardedClick(onClickCapture, disabled) : undefined,\n 'on:click': guardedClick((rest as Record<string, unknown>)['on:click'], disabled),\n 'oncapture:click': guardedClick((rest as Record<string, unknown>)['oncapture:click'], disabled),\n })\n\n const contents = () => (\n <>\n <Show when={busy()}>\n <Spinner size=\"sm\" label={false} aria-hidden=\"true\" data-icon=\"inline-start\" />\n </Show>\n {local.children}\n </>\n )\n\n return (\n <>\n <Show\n when={local.tooltip}\n fallback={\n <PolymorphicButton\n as={(local.as ?? 'button') as T}\n {...(buttonProps() as unknown as ButtonProps<T>)}\n >\n {contents()}\n </PolymorphicButton>\n }\n >\n <Tooltip\n open={tooltipOpen()}\n onOpenChange={(open) => {\n if (open && tooltipSuppression()) return\n setTooltipOpen(open)\n }}\n >\n <TooltipTrigger\n as={PolymorphicButtonTarget}\n {...(buttonProps() as unknown as ComponentProps<typeof PolymorphicButtonTarget>)}\n actionAs={(local.as ?? 'button') as T}\n >\n {contents()}\n </TooltipTrigger>\n <TooltipContent side={local.tooltipSide}>{local.tooltip}</TooltipContent>\n </Tooltip>\n </Show>\n <Show when={busy()}>\n <span role=\"status\" aria-live=\"polite\" class=\"visually-hidden\">\n {busyStatus()}\n </span>\n </Show>\n </>\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type JSX } from 'solid-js';
|
|
2
|
+
import type { CatalogBrowserEntry, CatalogBrowserGroup as CatalogGroup } from './catalog-types';
|
|
3
|
+
export declare function CatalogLoadingState(props: {
|
|
4
|
+
label: string;
|
|
5
|
+
}): JSX.Element;
|
|
6
|
+
export declare function CatalogBrowserGroup<Value>(props: {
|
|
7
|
+
group: CatalogGroup<Value>;
|
|
8
|
+
expanded: boolean;
|
|
9
|
+
previewCount: number;
|
|
10
|
+
disabled: boolean;
|
|
11
|
+
installedLabel: string;
|
|
12
|
+
publishedByLabel: (publisher: string) => string;
|
|
13
|
+
showMoreLabel: (entries: readonly CatalogBrowserEntry<Value>[], remainingCount: number) => string;
|
|
14
|
+
showLessLabel: string;
|
|
15
|
+
renderIcon: (value: Value) => JSX.Element;
|
|
16
|
+
onSelect: (entry: CatalogBrowserEntry<Value>, key: string) => void;
|
|
17
|
+
onRef: (key: string, element: HTMLButtonElement | undefined) => void;
|
|
18
|
+
onToggle: (id: string) => void;
|
|
19
|
+
}): JSX.Element;
|
|
20
|
+
//# sourceMappingURL=catalog-browser-group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-browser-group.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/catalog-browser/catalog-browser-group.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAMzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE/F,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,eAqB3D;AAiDD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE;IAChD,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IAC1B,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAA;IAC/C,aAAa,EAAE,CAAC,OAAO,EAAE,SAAS,mBAAmB,CAAC,KAAK,CAAC,EAAE,EAAE,cAAc,EAAE,MAAM,KAAK,MAAM,CAAA;IACjG,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,GAAG,CAAC,OAAO,CAAA;IACzC,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAClE,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,SAAS,KAAK,IAAI,CAAA;IACpE,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B,eAwDA"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { Badge } from "../../ui/badge/badge.js";
|
|
2
|
+
import { Button } from "../../ui/button/button.js";
|
|
3
|
+
import { Skeleton } from "../../ui/skeleton/skeleton.js";
|
|
4
|
+
import { keyedRows } from "../../../lib/keyed-rows.js";
|
|
5
|
+
import { createComponent, effect, insert, memo, setAttribute, template } from "solid-js/web";
|
|
6
|
+
import { ChevronDown, ChevronRight, ChevronUp } from "lucide-solid";
|
|
7
|
+
import { For, Show, createUniqueId, onCleanup } from "solid-js";
|
|
8
|
+
//#region src/components/composites/catalog-browser/catalog-browser-group.tsx
|
|
9
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div class="grid min-w-0 grid-cols-1 gap-3 md:grid-cols-2"aria-busy=true>`);
|
|
10
|
+
var _tmpl$2 = /*#__PURE__*/ template(`<div class="flex min-w-0 items-center gap-3 rounded-xl border border-border p-3"><div class="grid min-w-0 flex-1 gap-2">`);
|
|
11
|
+
var _tmpl$3 = /*#__PURE__*/ template(`<span class=shrink-0>`);
|
|
12
|
+
var _tmpl$4 = /*#__PURE__*/ template(`<span class="flex min-w-0 flex-1 flex-col gap-1 text-left"><span class="flex min-w-0 flex-wrap items-center gap-2"><strong class="min-w-0 truncate"></strong></span><span class="text-muted-foreground line-clamp-2 text-xs"></span><span class="text-muted-foreground truncate text-2xs"> · `);
|
|
13
|
+
var _tmpl$5 = /*#__PURE__*/ template(`<section class="grid min-w-0 gap-2"><header class="flex min-w-0 items-center gap-2"><h3 class="min-w-0 flex-1 truncate text-sm font-semibold"></h3></header><div class="grid min-w-0 grid-cols-1 gap-2 md:grid-cols-2">`);
|
|
14
|
+
function CatalogLoadingState(props) {
|
|
15
|
+
return (() => {
|
|
16
|
+
var _el$ = _tmpl$();
|
|
17
|
+
insert(_el$, createComponent(For, {
|
|
18
|
+
each: [
|
|
19
|
+
0,
|
|
20
|
+
1,
|
|
21
|
+
2,
|
|
22
|
+
3,
|
|
23
|
+
4,
|
|
24
|
+
5,
|
|
25
|
+
6
|
|
26
|
+
],
|
|
27
|
+
children: () => (() => {
|
|
28
|
+
var _el$2 = _tmpl$2(), _el$3 = _el$2.firstChild;
|
|
29
|
+
insert(_el$2, createComponent(Skeleton, { "class": "size-9 shrink-0" }), _el$3);
|
|
30
|
+
insert(_el$3, createComponent(Skeleton, { "class": "h-4 w-2/5" }), null);
|
|
31
|
+
insert(_el$3, createComponent(Skeleton, { "class": "h-3 w-4/5" }), null);
|
|
32
|
+
insert(_el$3, createComponent(Skeleton, { "class": "h-3 w-3/5" }), null);
|
|
33
|
+
return _el$2;
|
|
34
|
+
})()
|
|
35
|
+
}));
|
|
36
|
+
effect(() => setAttribute(_el$, "aria-label", props.label));
|
|
37
|
+
return _el$;
|
|
38
|
+
})();
|
|
39
|
+
}
|
|
40
|
+
function CatalogBrowserRow(props) {
|
|
41
|
+
const key = JSON.stringify([props.groupId, props.entry.id]);
|
|
42
|
+
let element;
|
|
43
|
+
onCleanup(() => {
|
|
44
|
+
if (element) props.onRef(key, void 0);
|
|
45
|
+
});
|
|
46
|
+
return createComponent(Button, {
|
|
47
|
+
ref: (node) => {
|
|
48
|
+
element = node;
|
|
49
|
+
props.onRef(key, node);
|
|
50
|
+
},
|
|
51
|
+
get ["data-catalog-entry-id"]() {
|
|
52
|
+
return props.entry.id;
|
|
53
|
+
},
|
|
54
|
+
variant: "outline",
|
|
55
|
+
size: "lg",
|
|
56
|
+
"class": "h-auto min-h-row-lg w-full min-w-0 justify-start gap-3 whitespace-normal",
|
|
57
|
+
get disabled() {
|
|
58
|
+
return props.disabled;
|
|
59
|
+
},
|
|
60
|
+
onClick: () => props.onSelect(props.entry, key),
|
|
61
|
+
get children() {
|
|
62
|
+
return [
|
|
63
|
+
(() => {
|
|
64
|
+
var _el$4 = _tmpl$3();
|
|
65
|
+
insert(_el$4, () => props.renderIcon(props.entry.value));
|
|
66
|
+
return _el$4;
|
|
67
|
+
})(),
|
|
68
|
+
(() => {
|
|
69
|
+
var _el$5 = _tmpl$4(), _el$6 = _el$5.firstChild, _el$7 = _el$6.firstChild, _el$8 = _el$6.nextSibling, _el$9 = _el$8.nextSibling, _el$0 = _el$9.firstChild;
|
|
70
|
+
insert(_el$7, () => props.entry.name);
|
|
71
|
+
insert(_el$6, createComponent(Show, {
|
|
72
|
+
get when() {
|
|
73
|
+
return props.entry.installed;
|
|
74
|
+
},
|
|
75
|
+
get children() {
|
|
76
|
+
return createComponent(Badge, {
|
|
77
|
+
variant: "secondary",
|
|
78
|
+
get children() {
|
|
79
|
+
return props.installedLabel;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}), null);
|
|
84
|
+
insert(_el$8, () => props.entry.description);
|
|
85
|
+
insert(_el$9, () => props.publishedByLabel(props.entry.publisher), _el$0);
|
|
86
|
+
insert(_el$9, () => props.entry.category, null);
|
|
87
|
+
return _el$5;
|
|
88
|
+
})(),
|
|
89
|
+
createComponent(ChevronRight, { "aria-hidden": "true" })
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function CatalogBrowserGroup(props) {
|
|
95
|
+
const headingId = `catalog-browser-group-${createUniqueId()}`;
|
|
96
|
+
const listId = `catalog-browser-items-${createUniqueId()}`;
|
|
97
|
+
const hidden = () => props.group.entries.slice(props.previewCount);
|
|
98
|
+
const preview = () => props.expanded ? props.group.entries : props.group.entries.slice(0, props.previewCount);
|
|
99
|
+
const rows = keyedRows(preview, (entry) => entry.id);
|
|
100
|
+
return (() => {
|
|
101
|
+
var _el$1 = _tmpl$5(), _el$10 = _el$1.firstChild, _el$11 = _el$10.firstChild, _el$12 = _el$10.nextSibling;
|
|
102
|
+
setAttribute(_el$1, "aria-labelledby", headingId);
|
|
103
|
+
setAttribute(_el$11, "id", headingId);
|
|
104
|
+
insert(_el$11, () => props.group.label);
|
|
105
|
+
insert(_el$10, createComponent(Badge, {
|
|
106
|
+
variant: "outline",
|
|
107
|
+
get children() {
|
|
108
|
+
return props.group.entries.length;
|
|
109
|
+
}
|
|
110
|
+
}), null);
|
|
111
|
+
setAttribute(_el$12, "id", listId);
|
|
112
|
+
insert(_el$12, createComponent(For, {
|
|
113
|
+
get each() {
|
|
114
|
+
return rows();
|
|
115
|
+
},
|
|
116
|
+
children: (row) => createComponent(CatalogBrowserRow, {
|
|
117
|
+
get entry() {
|
|
118
|
+
return row.item();
|
|
119
|
+
},
|
|
120
|
+
get groupId() {
|
|
121
|
+
return props.group.id;
|
|
122
|
+
},
|
|
123
|
+
get installedLabel() {
|
|
124
|
+
return props.installedLabel;
|
|
125
|
+
},
|
|
126
|
+
get publishedByLabel() {
|
|
127
|
+
return props.publishedByLabel;
|
|
128
|
+
},
|
|
129
|
+
get disabled() {
|
|
130
|
+
return props.disabled;
|
|
131
|
+
},
|
|
132
|
+
get renderIcon() {
|
|
133
|
+
return props.renderIcon;
|
|
134
|
+
},
|
|
135
|
+
get onSelect() {
|
|
136
|
+
return props.onSelect;
|
|
137
|
+
},
|
|
138
|
+
get onRef() {
|
|
139
|
+
return props.onRef;
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
}));
|
|
143
|
+
insert(_el$1, createComponent(Show, {
|
|
144
|
+
get when() {
|
|
145
|
+
return hidden().length > 0;
|
|
146
|
+
},
|
|
147
|
+
get children() {
|
|
148
|
+
return createComponent(Button, {
|
|
149
|
+
variant: "ghost",
|
|
150
|
+
size: "lg",
|
|
151
|
+
get disabled() {
|
|
152
|
+
return props.disabled;
|
|
153
|
+
},
|
|
154
|
+
get ["aria-expanded"]() {
|
|
155
|
+
return props.expanded;
|
|
156
|
+
},
|
|
157
|
+
"aria-controls": listId,
|
|
158
|
+
onClick: () => props.onToggle(props.group.id),
|
|
159
|
+
get children() {
|
|
160
|
+
return createComponent(Show, {
|
|
161
|
+
get when() {
|
|
162
|
+
return props.expanded;
|
|
163
|
+
},
|
|
164
|
+
get fallback() {
|
|
165
|
+
return [
|
|
166
|
+
memo(() => props.showMoreLabel(hidden(), hidden().length)),
|
|
167
|
+
" ",
|
|
168
|
+
createComponent(ChevronDown, {
|
|
169
|
+
"data-icon": "inline-end",
|
|
170
|
+
"aria-hidden": "true"
|
|
171
|
+
})
|
|
172
|
+
];
|
|
173
|
+
},
|
|
174
|
+
get children() {
|
|
175
|
+
return [
|
|
176
|
+
memo(() => props.showLessLabel),
|
|
177
|
+
" ",
|
|
178
|
+
createComponent(ChevronUp, {
|
|
179
|
+
"data-icon": "inline-end",
|
|
180
|
+
"aria-hidden": "true"
|
|
181
|
+
})
|
|
182
|
+
];
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}), null);
|
|
189
|
+
return _el$1;
|
|
190
|
+
})();
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
193
|
+
export { CatalogBrowserGroup, CatalogLoadingState };
|
|
194
|
+
|
|
195
|
+
//# sourceMappingURL=catalog-browser-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-browser-group.js","names":["createUniqueId","For","onCleanup","Show","JSX","ChevronDown","ChevronRight","ChevronUp","keyedRows","Badge","Button","Skeleton","CatalogBrowserEntry","CatalogBrowserGroup","CatalogGroup","CatalogLoadingState","props","label","_el$","_tmpl$","_$insert","_$createComponent","each","children","_el$2","_tmpl$2","_el$3","firstChild","_$effect","_$setAttribute","CatalogBrowserRow","entry","Value","groupId","installedLabel","publishedByLabel","publisher","disabled","renderIcon","value","Element","onSelect","key","onRef","element","HTMLButtonElement","JSON","stringify","id","undefined","ref","node","data-catalog-entry-id","variant","size","onClick","_el$4","_tmpl$3","_el$5","_tmpl$4","_el$6","_el$7","_el$8","nextSibling","_el$9","_el$0","name","when","installed","description","category","group","expanded","previewCount","showMoreLabel","entries","remainingCount","showLessLabel","onToggle","headingId","listId","hidden","slice","preview","rows","_el$1","_tmpl$5","_el$10","_el$11","_el$12","length","row","item","aria-expanded","fallback","_$memo","_$createComponent","_$setAttribute","_$memo"],"sources":["../../../../src/components/composites/catalog-browser/catalog-browser-group.tsx"],"sourcesContent":["import { createUniqueId, For, onCleanup, Show, type JSX } from 'solid-js'\nimport { ChevronDown, ChevronRight, ChevronUp } from 'lucide-solid'\nimport { keyedRows } from '#lib/keyed-rows'\nimport { Badge } from '../../ui/badge'\nimport { Button } from '../../ui/button'\nimport { Skeleton } from '../../ui/skeleton'\nimport type { CatalogBrowserEntry, CatalogBrowserGroup as CatalogGroup } from './catalog-types'\n\nexport function CatalogLoadingState(props: { label: string }) {\n return (\n <div\n class=\"grid min-w-0 grid-cols-1 gap-3 md:grid-cols-2\"\n aria-busy=\"true\"\n aria-label={props.label}\n >\n <For each={[0, 1, 2, 3, 4, 5, 6]}>\n {() => (\n <div class=\"flex min-w-0 items-center gap-3 rounded-xl border border-border p-3\">\n <Skeleton class=\"size-9 shrink-0\" />\n <div class=\"grid min-w-0 flex-1 gap-2\">\n <Skeleton class=\"h-4 w-2/5\" />\n <Skeleton class=\"h-3 w-4/5\" />\n <Skeleton class=\"h-3 w-3/5\" />\n </div>\n </div>\n )}\n </For>\n </div>\n )\n}\n\nfunction CatalogBrowserRow<Value>(props: {\n entry: CatalogBrowserEntry<Value>\n groupId: string\n installedLabel: string\n publishedByLabel: (publisher: string) => string\n disabled: boolean\n renderIcon: (value: Value) => JSX.Element\n onSelect: (entry: CatalogBrowserEntry<Value>, key: string) => void\n onRef: (key: string, element: HTMLButtonElement | undefined) => void\n}) {\n const key = JSON.stringify([props.groupId, props.entry.id])\n let element: HTMLButtonElement | undefined\n onCleanup(() => {\n if (element) props.onRef(key, undefined)\n })\n\n return (\n <Button\n ref={(node) => {\n element = node\n props.onRef(key, node)\n }}\n data-catalog-entry-id={props.entry.id}\n variant=\"outline\"\n size=\"lg\"\n class=\"h-auto min-h-row-lg w-full min-w-0 justify-start gap-3 whitespace-normal\"\n disabled={props.disabled}\n onClick={() => props.onSelect(props.entry, key)}\n >\n <span class=\"shrink-0\">{props.renderIcon(props.entry.value)}</span>\n <span class=\"flex min-w-0 flex-1 flex-col gap-1 text-left\">\n <span class=\"flex min-w-0 flex-wrap items-center gap-2\">\n <strong class=\"min-w-0 truncate\">{props.entry.name}</strong>\n <Show when={props.entry.installed}>\n <Badge variant=\"secondary\">{props.installedLabel}</Badge>\n </Show>\n </span>\n <span class=\"text-muted-foreground line-clamp-2 text-xs\">{props.entry.description}</span>\n <span class=\"text-muted-foreground truncate text-2xs\">\n {props.publishedByLabel(props.entry.publisher)} · {props.entry.category}\n </span>\n </span>\n <ChevronRight aria-hidden=\"true\" />\n </Button>\n )\n}\n\nexport function CatalogBrowserGroup<Value>(props: {\n group: CatalogGroup<Value>\n expanded: boolean\n previewCount: number\n disabled: boolean\n installedLabel: string\n publishedByLabel: (publisher: string) => string\n showMoreLabel: (entries: readonly CatalogBrowserEntry<Value>[], remainingCount: number) => string\n showLessLabel: string\n renderIcon: (value: Value) => JSX.Element\n onSelect: (entry: CatalogBrowserEntry<Value>, key: string) => void\n onRef: (key: string, element: HTMLButtonElement | undefined) => void\n onToggle: (id: string) => void\n}) {\n const headingId = `catalog-browser-group-${createUniqueId()}`\n const listId = `catalog-browser-items-${createUniqueId()}`\n const hidden = () => props.group.entries.slice(props.previewCount)\n const preview = () =>\n props.expanded ? props.group.entries : props.group.entries.slice(0, props.previewCount)\n const rows = keyedRows(preview, (entry) => entry.id)\n\n return (\n <section class=\"grid min-w-0 gap-2\" aria-labelledby={headingId}>\n <header class=\"flex min-w-0 items-center gap-2\">\n <h3 id={headingId} class=\"min-w-0 flex-1 truncate text-sm font-semibold\">\n {props.group.label}\n </h3>\n <Badge variant=\"outline\">{props.group.entries.length}</Badge>\n </header>\n <div id={listId} class=\"grid min-w-0 grid-cols-1 gap-2 md:grid-cols-2\">\n <For each={rows()}>\n {(row) => (\n <CatalogBrowserRow\n entry={row.item()}\n groupId={props.group.id}\n installedLabel={props.installedLabel}\n publishedByLabel={props.publishedByLabel}\n disabled={props.disabled}\n renderIcon={props.renderIcon}\n onSelect={props.onSelect}\n onRef={props.onRef}\n />\n )}\n </For>\n </div>\n <Show when={hidden().length > 0}>\n <Button\n variant=\"ghost\"\n size=\"lg\"\n disabled={props.disabled}\n aria-expanded={props.expanded}\n aria-controls={listId}\n onClick={() => props.onToggle(props.group.id)}\n >\n <Show\n when={props.expanded}\n fallback={\n <>\n {props.showMoreLabel(hidden(), hidden().length)}{' '}\n <ChevronDown data-icon=\"inline-end\" aria-hidden=\"true\" />\n </>\n }\n >\n {props.showLessLabel} <ChevronUp data-icon=\"inline-end\" aria-hidden=\"true\" />\n </Show>\n </Button>\n </Show>\n </section>\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-browser.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/catalog-browser/catalog-browser.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAE1D,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC,kCA8OtE"}
|