sonance-brand-mcp 1.2.5 → 1.3.2
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/dist/assets/api/sonance-analyze/route.ts +1116 -0
- package/dist/assets/api/sonance-assets/route.ts +113 -0
- package/dist/assets/api/sonance-components/route.ts +41 -0
- package/dist/assets/api/sonance-inject-id/route.ts +363 -0
- package/dist/assets/api/sonance-save-logo/route.ts +426 -0
- package/dist/assets/api/sonance-theme/route.ts +106 -0
- package/dist/assets/brand-system.ts +1265 -0
- package/dist/assets/components/accordion.stories.tsx +26 -26
- package/dist/assets/components/accordion.tsx +3 -3
- package/dist/assets/components/alert-dialog.stories.tsx +142 -0
- package/dist/assets/components/alert-dialog.tsx +143 -0
- package/dist/assets/components/alert.stories.tsx +3 -3
- package/dist/assets/components/alert.tsx +4 -3
- package/dist/assets/components/aspect-ratio.stories.tsx +70 -0
- package/dist/assets/components/aspect-ratio.tsx +8 -0
- package/dist/assets/components/autocomplete.stories.tsx +9 -9
- package/dist/assets/components/autocomplete.tsx +3 -3
- package/dist/assets/components/avatar.stories.tsx +5 -5
- package/dist/assets/components/avatar.tsx +67 -23
- package/dist/assets/components/badge.stories.tsx +10 -10
- package/dist/assets/components/badge.tsx +3 -3
- package/dist/assets/components/breadcrumbs.stories.tsx +7 -7
- package/dist/assets/components/breadcrumbs.tsx +13 -8
- package/dist/assets/components/button.stories.tsx +74 -74
- package/dist/assets/components/button.tsx +2 -0
- package/dist/assets/components/calendar.stories.tsx +11 -11
- package/dist/assets/components/calendar.tsx +4 -4
- package/dist/assets/components/card.stories.tsx +22 -22
- package/dist/assets/components/card.tsx +7 -3
- package/dist/assets/components/carousel.stories.tsx +158 -0
- package/dist/assets/components/carousel.tsx +264 -0
- package/dist/assets/components/chart.stories.tsx +376 -0
- package/dist/assets/components/chart.tsx +384 -0
- package/dist/assets/components/checkbox-group.stories.tsx +6 -6
- package/dist/assets/components/checkbox-group.tsx +3 -3
- package/dist/assets/components/checkbox.stories.tsx +23 -20
- package/dist/assets/components/checkbox.tsx +13 -6
- package/dist/assets/components/code.stories.tsx +24 -24
- package/dist/assets/components/code.tsx +22 -27
- package/dist/assets/components/collapsible.stories.tsx +128 -0
- package/dist/assets/components/collapsible.tsx +10 -0
- package/dist/assets/components/command.stories.tsx +183 -0
- package/dist/assets/components/command.tsx +171 -0
- package/dist/assets/components/context-menu.stories.tsx +159 -0
- package/dist/assets/components/context-menu.tsx +214 -0
- package/dist/assets/components/date-input.stories.tsx +9 -9
- package/dist/assets/components/date-input.tsx +2 -2
- package/dist/assets/components/date-picker.stories.tsx +9 -9
- package/dist/assets/components/date-picker.tsx +3 -3
- package/dist/assets/components/date-range-picker.stories.tsx +12 -12
- package/dist/assets/components/date-range-picker.tsx +3 -3
- package/dist/assets/components/dialog.stories.tsx +40 -40
- package/dist/assets/components/dialog.tsx +8 -12
- package/dist/assets/components/divider.stories.tsx +30 -30
- package/dist/assets/components/divider.tsx +34 -35
- package/dist/assets/components/drawer.stories.tsx +32 -31
- package/dist/assets/components/drawer.tsx +7 -6
- package/dist/assets/components/dropdown-menu.tsx +213 -0
- package/dist/assets/components/dropdown.stories.tsx +12 -12
- package/dist/assets/components/dropdown.tsx +5 -5
- package/dist/assets/components/form.stories.tsx +30 -29
- package/dist/assets/components/form.tsx +5 -5
- package/dist/assets/components/hover-card.stories.tsx +115 -0
- package/dist/assets/components/hover-card.tsx +35 -0
- package/dist/assets/components/image.stories.tsx +48 -25
- package/dist/assets/components/image.tsx +8 -5
- package/dist/assets/components/input-otp.stories.tsx +15 -15
- package/dist/assets/components/input-otp.tsx +5 -5
- package/dist/assets/components/input.stories.tsx +30 -25
- package/dist/assets/components/input.tsx +7 -4
- package/dist/assets/components/kbd.stories.tsx +34 -34
- package/dist/assets/components/kbd.tsx +9 -9
- package/dist/assets/components/link.stories.tsx +36 -36
- package/dist/assets/components/link.tsx +4 -0
- package/dist/assets/components/listbox.stories.tsx +5 -5
- package/dist/assets/components/listbox.tsx +4 -4
- package/dist/assets/components/menubar.stories.tsx +208 -0
- package/dist/assets/components/menubar.tsx +247 -0
- package/dist/assets/components/navbar.stories.tsx +24 -24
- package/dist/assets/components/navbar.tsx +8 -14
- package/dist/assets/components/navigation-menu.stories.tsx +239 -0
- package/dist/assets/components/navigation-menu.tsx +135 -0
- package/dist/assets/components/number-input.stories.tsx +11 -11
- package/dist/assets/components/number-input.tsx +3 -3
- package/dist/assets/components/pagination.stories.tsx +13 -13
- package/dist/assets/components/pagination.tsx +6 -6
- package/dist/assets/components/popover.stories.tsx +35 -35
- package/dist/assets/components/popover.tsx +98 -15
- package/dist/assets/components/progress.stories.tsx +5 -5
- package/dist/assets/components/progress.tsx +5 -5
- package/dist/assets/components/radio-group.stories.tsx +7 -7
- package/dist/assets/components/radio-group.tsx +3 -3
- package/dist/assets/components/range-calendar.stories.tsx +18 -18
- package/dist/assets/components/range-calendar.tsx +3 -3
- package/dist/assets/components/resizable.stories.tsx +197 -0
- package/dist/assets/components/resizable.tsx +47 -0
- package/dist/assets/components/scroll-area.stories.tsx +123 -0
- package/dist/assets/components/scroll-area.tsx +48 -0
- package/dist/assets/components/scroll-shadow.stories.tsx +17 -17
- package/dist/assets/components/scroll-shadow.tsx +31 -9
- package/dist/assets/components/select.stories.tsx +20 -19
- package/dist/assets/components/select.tsx +10 -6
- package/dist/assets/components/separator.tsx +32 -0
- package/dist/assets/components/sheet.tsx +137 -0
- package/dist/assets/components/sidebar.stories.tsx +351 -0
- package/dist/assets/components/sidebar.tsx +757 -0
- package/dist/assets/components/skeleton.stories.tsx +3 -3
- package/dist/assets/components/skeleton.tsx +2 -2
- package/dist/assets/components/slider.stories.tsx +6 -6
- package/dist/assets/components/slider.tsx +3 -3
- package/dist/assets/components/spacer.stories.tsx +11 -11
- package/dist/assets/components/spacer.tsx +2 -2
- package/dist/assets/components/spinner.stories.tsx +8 -8
- package/dist/assets/components/spinner.tsx +5 -5
- package/dist/assets/components/switch.stories.tsx +24 -20
- package/dist/assets/components/switch.tsx +14 -6
- package/dist/assets/components/table.stories.tsx +7 -7
- package/dist/assets/components/table.tsx +8 -8
- package/dist/assets/components/tabs.stories.tsx +37 -37
- package/dist/assets/components/tabs.tsx +3 -3
- package/dist/assets/components/textarea.stories.tsx +13 -12
- package/dist/assets/components/textarea.tsx +3 -3
- package/dist/assets/components/theme-toggle.stories.tsx +31 -30
- package/dist/assets/components/theme-toggle.tsx +2 -2
- package/dist/assets/components/time-input.stories.tsx +16 -16
- package/dist/assets/components/time-input.tsx +2 -2
- package/dist/assets/components/toast.stories.tsx +8 -5
- package/dist/assets/components/toast.tsx +6 -6
- package/dist/assets/components/toggle-group.stories.tsx +153 -0
- package/dist/assets/components/toggle-group.tsx +61 -0
- package/dist/assets/components/toggle.stories.tsx +77 -0
- package/dist/assets/components/toggle.tsx +46 -0
- package/dist/assets/components/tooltip.stories.tsx +49 -27
- package/dist/assets/components/tooltip.tsx +23 -90
- package/dist/assets/components/user.stories.tsx +23 -23
- package/dist/assets/components/user.tsx +7 -4
- package/dist/assets/dev-tools/SonanceDevTools.tsx +4201 -0
- package/dist/assets/dev-tools/index.ts +10 -0
- package/dist/assets/globals.css +39 -0
- package/dist/assets/logos/40th-anniversary/Sonance_40_Logo_CMYK_BEAM_BLUE_40_AND_BEAM_DARK.png +0 -0
- package/dist/assets/logos/Sonance logo dark mode.png +0 -0
- package/dist/assets/logos/Sonance logo light mode.png +0 -0
- package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_2C_Light_RGB_05162025.png +0 -0
- package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_3C_Dark_RGB_05162025.png +0 -0
- package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_White_RGB_05162025.png +0 -0
- package/dist/assets/logos/iport/IPORT_Sonance_LockUp_2C_Dark_RGB.png +0 -0
- package/dist/assets/logos/iport/IPORT_Sonance_LockUp_2C_Light_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_Black_CMYK.png +0 -0
- package/dist/assets/logos/james/James_Logo_Black_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_LtGray_CMYK.png +0 -0
- package/dist/assets/logos/james/James_Logo_LtGray_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_Polished_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_Reverse_CMYK.png +0 -0
- package/dist/assets/logos/james/James_Logo_Reverse_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_White_CMYK.png +0 -0
- package/dist/assets/logos/life-is-better/Sonance_LifeisBetter_Dark_RGB.png +0 -0
- package/dist/assets/logos/life-is-better/Sonance_LifeisBetter_Light_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Dark_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Light_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Reverse_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_Black_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_2C_Dark_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_2C_Light_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_2C_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_Black_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_Grayscale_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance-academy/SonanceAcademy_Logo_Dark_CMYK.png +0 -0
- package/dist/assets/logos/sonance-academy/SonanceAcademy_Logo_Light_CMYK.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Dark_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Light_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Black_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Grayscale_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance-james/Sonance_James_Lockup_Dark.png +0 -0
- package/dist/assets/logos/sonance-james/Sonance_James_Lockup_Light.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_LockupStacked_Dark.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_LockupStacked_Light.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Dark.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Light.png +0 -0
- package/dist/assets/logos/trufig/TrufigLogo_Black.png +0 -0
- package/dist/assets/logos/trufig/TrufigLogo_Light.png +0 -0
- package/dist/assets/logos/trufig/TrufigWatermark_Black.png +0 -0
- package/dist/assets/logos/trufig/TrufigWatermark_Light.png +0 -0
- package/dist/assets/styles/brand-overrides.css +37 -0
- package/dist/index.js +2055 -15
- package/package.json +1 -1
|
@@ -38,15 +38,15 @@ export const Default: Story = {
|
|
|
38
38
|
render: () => {
|
|
39
39
|
const [range, setRange] = useState<DateRange>({ start: undefined, end: undefined });
|
|
40
40
|
return (
|
|
41
|
-
<div className="space-y-4">
|
|
41
|
+
<div data-sonance-name="range-calendar.stories" className="space-y-4">
|
|
42
42
|
<RangeCalendar
|
|
43
43
|
value={range}
|
|
44
44
|
onValueChange={setRange}
|
|
45
45
|
/>
|
|
46
46
|
<div className="text-sm text-foreground-muted">
|
|
47
|
-
{range.start && <span>Start: {range.start.toLocaleDateString()}</span>}
|
|
48
|
-
{range.start && range.end && <span> | </span>}
|
|
49
|
-
{range.end && <span>End: {range.end.toLocaleDateString()}</span>}
|
|
47
|
+
{range.start && <span id="default-span-start-rangestarttolo">Start: {range.start.toLocaleDateString()}</span>}
|
|
48
|
+
{range.start && range.end && <span id="default-span"> | </span>}
|
|
49
|
+
{range.end && <span id="default-span-end-rangeendtolocale">End: {range.end.toLocaleDateString()}</span>}
|
|
50
50
|
</div>
|
|
51
51
|
</div>
|
|
52
52
|
);
|
|
@@ -105,7 +105,7 @@ export const WithMinMaxDates: Story = {
|
|
|
105
105
|
const today = new Date();
|
|
106
106
|
return (
|
|
107
107
|
<div className="space-y-4">
|
|
108
|
-
<p className="text-sm text-foreground-muted">
|
|
108
|
+
<p id="with-min-max-dates-p-selection-limited-to" className="text-sm text-foreground-muted">
|
|
109
109
|
Selection limited to next 60 days
|
|
110
110
|
</p>
|
|
111
111
|
<RangeCalendar
|
|
@@ -129,7 +129,7 @@ export const DisabledWeekends: Story = {
|
|
|
129
129
|
};
|
|
130
130
|
return (
|
|
131
131
|
<div className="space-y-4">
|
|
132
|
-
<p className="text-sm text-foreground-muted">
|
|
132
|
+
<p id="disabled-weekends-p-weekends-are-disable" className="text-sm text-foreground-muted">
|
|
133
133
|
Weekends are disabled (business days only)
|
|
134
134
|
</p>
|
|
135
135
|
<RangeCalendar
|
|
@@ -170,15 +170,15 @@ export const HotelBookingExample: Story = {
|
|
|
170
170
|
<div className="flex items-center gap-4 text-sm">
|
|
171
171
|
<div className="flex items-center gap-2">
|
|
172
172
|
<div className="w-4 h-4 bg-primary rounded-sm" />
|
|
173
|
-
<span>Selected</span>
|
|
173
|
+
<span id="hotel-booking-example-span-selected">Selected</span>
|
|
174
174
|
</div>
|
|
175
175
|
<div className="flex items-center gap-2">
|
|
176
176
|
<div className="w-4 h-4 bg-primary/20 rounded-sm" />
|
|
177
|
-
<span>In Range</span>
|
|
177
|
+
<span id="hotel-booking-example-span-in-range">In Range</span>
|
|
178
178
|
</div>
|
|
179
179
|
<div className="flex items-center gap-2">
|
|
180
180
|
<div className="w-4 h-4 bg-secondary text-foreground-subtle text-xs flex items-center justify-center">x</div>
|
|
181
|
-
<span>Unavailable</span>
|
|
181
|
+
<span id="hotel-booking-example-span-unavailable">Unavailable</span>
|
|
182
182
|
</div>
|
|
183
183
|
</div>
|
|
184
184
|
<RangeCalendar
|
|
@@ -191,8 +191,8 @@ export const HotelBookingExample: Story = {
|
|
|
191
191
|
{nights > 0 && (
|
|
192
192
|
<div className="p-4 border border-border rounded-sm">
|
|
193
193
|
<div className="flex justify-between">
|
|
194
|
-
<span className="text-foreground-muted">Duration</span>
|
|
195
|
-
<span className="font-medium">{nights} night{nights !== 1 ? 's' : ''}</span>
|
|
194
|
+
<span id="hotel-booking-example-span-duration" className="text-foreground-muted">Duration</span>
|
|
195
|
+
<span id="hotel-booking-example-span-nights-nightnights-1" className="font-medium">{nights} night{nights !== 1 ? 's' : ''}</span>
|
|
196
196
|
</div>
|
|
197
197
|
</div>
|
|
198
198
|
)}
|
|
@@ -239,7 +239,7 @@ export const ReportDateRangeExample: Story = {
|
|
|
239
239
|
maxDate={today}
|
|
240
240
|
/>
|
|
241
241
|
{range.start && range.end && (
|
|
242
|
-
<p className="text-sm">
|
|
242
|
+
<p id="report-date-range-example-p-selected-rangestartt" className="text-sm">
|
|
243
243
|
Selected: {range.start.toLocaleDateString()} - {range.end.toLocaleDateString()}
|
|
244
244
|
</p>
|
|
245
245
|
)}
|
|
@@ -258,7 +258,7 @@ export const AllConfigurations: Story = {
|
|
|
258
258
|
return (
|
|
259
259
|
<div className="space-y-8">
|
|
260
260
|
<div>
|
|
261
|
-
<h4 className="text-sm font-medium mb-2">Single Month</h4>
|
|
261
|
+
<h4 id="all-configurations-h4-single-month" className="text-sm font-medium mb-2">Single Month</h4>
|
|
262
262
|
<RangeCalendar
|
|
263
263
|
value={range1}
|
|
264
264
|
onValueChange={setRange1}
|
|
@@ -266,7 +266,7 @@ export const AllConfigurations: Story = {
|
|
|
266
266
|
/>
|
|
267
267
|
</div>
|
|
268
268
|
<div>
|
|
269
|
-
<h4 className="text-sm font-medium mb-2">Two Months (Default)</h4>
|
|
269
|
+
<h4 id="all-configurations-h4-two-months-default" className="text-sm font-medium mb-2">Two Months (Default)</h4>
|
|
270
270
|
<RangeCalendar
|
|
271
271
|
value={range2}
|
|
272
272
|
onValueChange={setRange2}
|
|
@@ -274,7 +274,7 @@ export const AllConfigurations: Story = {
|
|
|
274
274
|
/>
|
|
275
275
|
</div>
|
|
276
276
|
<div>
|
|
277
|
-
<h4 className="text-sm font-medium mb-2">Three Months</h4>
|
|
277
|
+
<h4 id="all-configurations-h4-three-months" className="text-sm font-medium mb-2">Three Months</h4>
|
|
278
278
|
<RangeCalendar
|
|
279
279
|
value={range3}
|
|
280
280
|
onValueChange={setRange3}
|
|
@@ -297,7 +297,7 @@ export const ResponsiveMatrix: Story = {
|
|
|
297
297
|
<div className="space-y-8">
|
|
298
298
|
{/* Mobile */}
|
|
299
299
|
<div>
|
|
300
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
300
|
+
<h4 id="responsive-matrix-h4-mobile-375px" className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
301
301
|
<div className="w-[375px] border border-dashed border-border p-4 overflow-x-auto">
|
|
302
302
|
<RangeCalendar
|
|
303
303
|
value={mobile}
|
|
@@ -308,7 +308,7 @@ export const ResponsiveMatrix: Story = {
|
|
|
308
308
|
</div>
|
|
309
309
|
{/* Tablet */}
|
|
310
310
|
<div>
|
|
311
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
311
|
+
<h4 id="responsive-matrix-h4-tablet-768px" className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
312
312
|
<div className="w-[768px] border border-dashed border-border p-4">
|
|
313
313
|
<RangeCalendar
|
|
314
314
|
value={tablet}
|
|
@@ -319,7 +319,7 @@ export const ResponsiveMatrix: Story = {
|
|
|
319
319
|
</div>
|
|
320
320
|
{/* Desktop */}
|
|
321
321
|
<div>
|
|
322
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
322
|
+
<h4 id="responsive-matrix-h4-desktop-1280px" className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
323
323
|
<div className="w-[1280px] border border-dashed border-border p-4">
|
|
324
324
|
<RangeCalendar
|
|
325
325
|
value={desktop}
|
|
@@ -112,8 +112,8 @@ export function RangeCalendar({
|
|
|
112
112
|
const days = eachDayOfInterval({ start: calendarStart, end: calendarEnd });
|
|
113
113
|
|
|
114
114
|
return (
|
|
115
|
-
<div key={monthDate.toISOString()}>
|
|
116
|
-
<h3 className="text-sm font-medium text-foreground text-center mb-4">
|
|
115
|
+
<div data-sonance-name="range-calendar" key={monthDate.toISOString()}>
|
|
116
|
+
<h3 id="h3-formatmonthdate-mmmm" className="text-sm font-medium text-foreground text-center mb-4">
|
|
117
117
|
{format(monthDate, "MMMM yyyy")}
|
|
118
118
|
</h3>
|
|
119
119
|
|
|
@@ -140,7 +140,7 @@ export function RangeCalendar({
|
|
|
140
140
|
const isEnd = isRangeEnd(day);
|
|
141
141
|
|
|
142
142
|
return (
|
|
143
|
-
<button
|
|
143
|
+
<button data-sonance-name="range-calendar"
|
|
144
144
|
key={day.toISOString()}
|
|
145
145
|
type="button"
|
|
146
146
|
onClick={() => handleSelectDate(day)}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import {
|
|
3
|
+
ResizableHandle,
|
|
4
|
+
ResizablePanel,
|
|
5
|
+
ResizablePanelGroup,
|
|
6
|
+
} from "./resizable";
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof ResizablePanelGroup> = {
|
|
9
|
+
title: "Components/Layout/Resizable",
|
|
10
|
+
component: ResizablePanelGroup,
|
|
11
|
+
parameters: {
|
|
12
|
+
layout: "centered",
|
|
13
|
+
},
|
|
14
|
+
tags: ["autodocs"],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default meta;
|
|
18
|
+
type Story = StoryObj<typeof ResizablePanelGroup>;
|
|
19
|
+
|
|
20
|
+
export const Default: Story = {
|
|
21
|
+
render: () => (
|
|
22
|
+
<ResizablePanelGroup
|
|
23
|
+
direction="horizontal"
|
|
24
|
+
className="max-w-md rounded-sm border border-border"
|
|
25
|
+
>
|
|
26
|
+
<ResizablePanel defaultSize={50}>
|
|
27
|
+
<div className="flex h-[200px] items-center justify-center p-6">
|
|
28
|
+
<span id="default-span-one" className="font-medium text-foreground">One</span>
|
|
29
|
+
</div>
|
|
30
|
+
</ResizablePanel>
|
|
31
|
+
<ResizableHandle />
|
|
32
|
+
<ResizablePanel defaultSize={50}>
|
|
33
|
+
<div className="flex h-[200px] items-center justify-center p-6">
|
|
34
|
+
<span id="default-span-two" className="font-medium text-foreground">Two</span>
|
|
35
|
+
</div>
|
|
36
|
+
</ResizablePanel>
|
|
37
|
+
</ResizablePanelGroup>
|
|
38
|
+
),
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const Vertical: Story = {
|
|
42
|
+
render: () => (
|
|
43
|
+
<ResizablePanelGroup
|
|
44
|
+
direction="vertical"
|
|
45
|
+
className="min-h-[200px] max-w-md rounded-sm border border-border"
|
|
46
|
+
>
|
|
47
|
+
<ResizablePanel defaultSize={25}>
|
|
48
|
+
<div className="flex h-full items-center justify-center p-6">
|
|
49
|
+
<span id="vertical-span-header" className="font-medium text-foreground">Header</span>
|
|
50
|
+
</div>
|
|
51
|
+
</ResizablePanel>
|
|
52
|
+
<ResizableHandle />
|
|
53
|
+
<ResizablePanel defaultSize={75}>
|
|
54
|
+
<div className="flex h-full items-center justify-center p-6">
|
|
55
|
+
<span id="vertical-span-content" className="font-medium text-foreground">Content</span>
|
|
56
|
+
</div>
|
|
57
|
+
</ResizablePanel>
|
|
58
|
+
</ResizablePanelGroup>
|
|
59
|
+
),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const WithHandle: Story = {
|
|
63
|
+
render: () => (
|
|
64
|
+
<ResizablePanelGroup
|
|
65
|
+
direction="horizontal"
|
|
66
|
+
className="min-h-[200px] max-w-md rounded-sm border border-border"
|
|
67
|
+
>
|
|
68
|
+
<ResizablePanel defaultSize={25}>
|
|
69
|
+
<div className="flex h-full items-center justify-center p-6">
|
|
70
|
+
<span id="with-handle-span-sidebar" className="font-medium text-foreground">Sidebar</span>
|
|
71
|
+
</div>
|
|
72
|
+
</ResizablePanel>
|
|
73
|
+
<ResizableHandle withHandle />
|
|
74
|
+
<ResizablePanel defaultSize={75}>
|
|
75
|
+
<div className="flex h-full items-center justify-center p-6">
|
|
76
|
+
<span id="with-handle-span-content" className="font-medium text-foreground">Content</span>
|
|
77
|
+
</div>
|
|
78
|
+
</ResizablePanel>
|
|
79
|
+
</ResizablePanelGroup>
|
|
80
|
+
),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const ThreePanels: Story = {
|
|
84
|
+
render: () => (
|
|
85
|
+
<ResizablePanelGroup
|
|
86
|
+
direction="horizontal"
|
|
87
|
+
className="min-h-[200px] max-w-lg rounded-sm border border-border"
|
|
88
|
+
>
|
|
89
|
+
<ResizablePanel defaultSize={20} minSize={15}>
|
|
90
|
+
<div className="flex h-full items-center justify-center p-4">
|
|
91
|
+
<span id="three-panels-span-nav" className="text-sm font-medium text-foreground">Nav</span>
|
|
92
|
+
</div>
|
|
93
|
+
</ResizablePanel>
|
|
94
|
+
<ResizableHandle withHandle />
|
|
95
|
+
<ResizablePanel defaultSize={60}>
|
|
96
|
+
<div className="flex h-full items-center justify-center p-4">
|
|
97
|
+
<span id="three-panels-span-main-content" className="font-medium text-foreground">Main Content</span>
|
|
98
|
+
</div>
|
|
99
|
+
</ResizablePanel>
|
|
100
|
+
<ResizableHandle withHandle />
|
|
101
|
+
<ResizablePanel defaultSize={20} minSize={15}>
|
|
102
|
+
<div className="flex h-full items-center justify-center p-4">
|
|
103
|
+
<span id="three-panels-span-panel" className="text-sm font-medium text-foreground">Panel</span>
|
|
104
|
+
</div>
|
|
105
|
+
</ResizablePanel>
|
|
106
|
+
</ResizablePanelGroup>
|
|
107
|
+
),
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export const NestedPanels: Story = {
|
|
111
|
+
render: () => (
|
|
112
|
+
<ResizablePanelGroup
|
|
113
|
+
direction="horizontal"
|
|
114
|
+
className="min-h-[300px] max-w-lg rounded-sm border border-border"
|
|
115
|
+
>
|
|
116
|
+
<ResizablePanel defaultSize={25}>
|
|
117
|
+
<div className="flex h-full items-center justify-center p-6">
|
|
118
|
+
<span id="nested-panels-span-sidebar" className="font-medium text-foreground">Sidebar</span>
|
|
119
|
+
</div>
|
|
120
|
+
</ResizablePanel>
|
|
121
|
+
<ResizableHandle withHandle />
|
|
122
|
+
<ResizablePanel defaultSize={75}>
|
|
123
|
+
<ResizablePanelGroup direction="vertical">
|
|
124
|
+
<ResizablePanel defaultSize={50}>
|
|
125
|
+
<div className="flex h-full items-center justify-center p-6">
|
|
126
|
+
<span id="nested-panels-span-top-panel" className="font-medium text-foreground">Top Panel</span>
|
|
127
|
+
</div>
|
|
128
|
+
</ResizablePanel>
|
|
129
|
+
<ResizableHandle />
|
|
130
|
+
<ResizablePanel defaultSize={50}>
|
|
131
|
+
<div className="flex h-full items-center justify-center p-6">
|
|
132
|
+
<span id="nested-panels-span-bottom-panel" className="font-medium text-foreground">Bottom Panel</span>
|
|
133
|
+
</div>
|
|
134
|
+
</ResizablePanel>
|
|
135
|
+
</ResizablePanelGroup>
|
|
136
|
+
</ResizablePanel>
|
|
137
|
+
</ResizablePanelGroup>
|
|
138
|
+
),
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export const IDELayout: Story = {
|
|
142
|
+
render: () => (
|
|
143
|
+
<ResizablePanelGroup
|
|
144
|
+
direction="horizontal"
|
|
145
|
+
className="min-h-[400px] max-w-2xl rounded-sm border border-border"
|
|
146
|
+
>
|
|
147
|
+
<ResizablePanel defaultSize={20} minSize={10}>
|
|
148
|
+
<div className="flex h-full flex-col bg-background p-2">
|
|
149
|
+
<p id="i-d-e-layout-p-explorer" className="text-xs font-medium uppercase tracking-widest text-foreground-muted mb-2">
|
|
150
|
+
Explorer
|
|
151
|
+
</p>
|
|
152
|
+
<div className="space-y-1 text-sm text-foreground-secondary">
|
|
153
|
+
<p id="i-d-e-layout-p--src">📁 src</p>
|
|
154
|
+
<p id="i-d-e-layout-p--components" className="pl-4">📁 components</p>
|
|
155
|
+
<p id="i-d-e-layout-p--lib" className="pl-4">📁 lib</p>
|
|
156
|
+
<p id="i-d-e-layout-p--packagejson">📄 package.json</p>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</ResizablePanel>
|
|
160
|
+
<ResizableHandle withHandle />
|
|
161
|
+
<ResizablePanel defaultSize={60}>
|
|
162
|
+
<ResizablePanelGroup direction="vertical">
|
|
163
|
+
<ResizablePanel defaultSize={70}>
|
|
164
|
+
<div className="flex h-full items-center justify-center bg-card p-6">
|
|
165
|
+
<span id="i-d-e-layout-span-editor" className="font-medium text-foreground">Editor</span>
|
|
166
|
+
</div>
|
|
167
|
+
</ResizablePanel>
|
|
168
|
+
<ResizableHandle />
|
|
169
|
+
<ResizablePanel defaultSize={30} minSize={15}>
|
|
170
|
+
<div className="flex h-full flex-col bg-background p-2">
|
|
171
|
+
<p id="i-d-e-layout-p-terminal" className="text-xs font-medium uppercase tracking-widest text-foreground-muted mb-2">
|
|
172
|
+
Terminal
|
|
173
|
+
</p>
|
|
174
|
+
<code className="text-sm text-foreground-secondary">
|
|
175
|
+
$ npm run dev
|
|
176
|
+
</code>
|
|
177
|
+
</div>
|
|
178
|
+
</ResizablePanel>
|
|
179
|
+
</ResizablePanelGroup>
|
|
180
|
+
</ResizablePanel>
|
|
181
|
+
<ResizableHandle withHandle />
|
|
182
|
+
<ResizablePanel defaultSize={20} minSize={10}>
|
|
183
|
+
<div className="flex h-full flex-col bg-background p-2">
|
|
184
|
+
<p id="i-d-e-layout-p-outline" className="text-xs font-medium uppercase tracking-widest text-foreground-muted mb-2">
|
|
185
|
+
Outline
|
|
186
|
+
</p>
|
|
187
|
+
<div className="space-y-1 text-sm text-foreground-secondary">
|
|
188
|
+
<p id="button-p--function-button">• function Button</p>
|
|
189
|
+
<p id="card-p--function-card">• function Card</p>
|
|
190
|
+
<p id="dialog-p--function-dialog">• function Dialog</p>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</ResizablePanel>
|
|
194
|
+
</ResizablePanelGroup>
|
|
195
|
+
),
|
|
196
|
+
};
|
|
197
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { GripVertical } from "lucide-react";
|
|
4
|
+
import * as ResizablePrimitive from "react-resizable-panels";
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
|
|
7
|
+
const ResizablePanelGroup = ({
|
|
8
|
+
className,
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
|
|
11
|
+
<ResizablePrimitive.PanelGroup data-sonance-name="resizable"
|
|
12
|
+
className={cn(
|
|
13
|
+
"flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
|
|
14
|
+
className
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const ResizablePanel = ResizablePrimitive.Panel;
|
|
21
|
+
|
|
22
|
+
const ResizableHandle = ({
|
|
23
|
+
withHandle,
|
|
24
|
+
className,
|
|
25
|
+
...props
|
|
26
|
+
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
|
|
27
|
+
withHandle?: boolean;
|
|
28
|
+
}) => (
|
|
29
|
+
<ResizablePrimitive.PanelResizeHandle
|
|
30
|
+
className={cn(
|
|
31
|
+
"relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary focus-visible:ring-offset-1",
|
|
32
|
+
"data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0",
|
|
33
|
+
"[&[data-panel-group-direction=vertical]>div]:rotate-90",
|
|
34
|
+
className
|
|
35
|
+
)}
|
|
36
|
+
{...props}
|
|
37
|
+
>
|
|
38
|
+
{withHandle && (
|
|
39
|
+
<div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border border-border bg-card">
|
|
40
|
+
<GripVertical className="h-2.5 w-2.5" />
|
|
41
|
+
</div>
|
|
42
|
+
)}
|
|
43
|
+
</ResizablePrimitive.PanelResizeHandle>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
|
|
47
|
+
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { ScrollArea, ScrollBar } from "./scroll-area";
|
|
3
|
+
import { Divider } from "./divider";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof ScrollArea> = {
|
|
6
|
+
title: "Components/Data Display/ScrollArea",
|
|
7
|
+
component: ScrollArea,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "centered",
|
|
10
|
+
},
|
|
11
|
+
tags: ["autodocs"],
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story = StoryObj<typeof ScrollArea>;
|
|
16
|
+
|
|
17
|
+
const tags = Array.from({ length: 50 }).map(
|
|
18
|
+
(_, i, a) => `v1.2.0-beta.${a.length - i}`
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export const Default: Story = {
|
|
22
|
+
render: () => (
|
|
23
|
+
<ScrollArea className="h-72 w-48 rounded-sm border border-border">
|
|
24
|
+
<div className="p-4">
|
|
25
|
+
<h4 id="default-h4-tags" className="mb-4 text-sm font-medium leading-none text-foreground">Tags</h4>
|
|
26
|
+
{tags.map((tag) => (
|
|
27
|
+
<div key={tag}>
|
|
28
|
+
<div className="text-sm text-foreground-secondary">{tag}</div>
|
|
29
|
+
<Divider className="my-2" />
|
|
30
|
+
</div>
|
|
31
|
+
))}
|
|
32
|
+
</div>
|
|
33
|
+
</ScrollArea>
|
|
34
|
+
),
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const works = [
|
|
38
|
+
{
|
|
39
|
+
artist: "Ornella Binni",
|
|
40
|
+
art: "Reflection",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
artist: "Tom Byrom",
|
|
44
|
+
art: "Living Room",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
artist: "Vladimir Malyavko",
|
|
48
|
+
art: "Sunrise",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
artist: "Anton Repponen",
|
|
52
|
+
art: "Mountains",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
artist: "Sead Dedić",
|
|
56
|
+
art: "Coastline",
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
export const Horizontal: Story = {
|
|
61
|
+
render: () => (
|
|
62
|
+
<ScrollArea className="w-96 whitespace-nowrap rounded-sm border border-border">
|
|
63
|
+
<div className="flex w-max space-x-4 p-4">
|
|
64
|
+
{works.map((artwork) => (
|
|
65
|
+
<figure key={artwork.artist} className="shrink-0">
|
|
66
|
+
<div className="overflow-hidden rounded-sm">
|
|
67
|
+
<div className="h-[150px] w-[200px] bg-secondary-hover flex items-center justify-center">
|
|
68
|
+
<span id="horizontal-span-artworkart" className="text-foreground-muted text-xs">{artwork.art}</span>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
<figcaption className="pt-2 text-xs text-foreground-muted">
|
|
72
|
+
Photo by{" "}
|
|
73
|
+
<span id="horizontal-span-artworkartist" className="font-medium text-foreground">
|
|
74
|
+
{artwork.artist}
|
|
75
|
+
</span>
|
|
76
|
+
</figcaption>
|
|
77
|
+
</figure>
|
|
78
|
+
))}
|
|
79
|
+
</div>
|
|
80
|
+
<ScrollBar orientation="horizontal" />
|
|
81
|
+
</ScrollArea>
|
|
82
|
+
),
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const LargeContent: Story = {
|
|
86
|
+
render: () => (
|
|
87
|
+
<ScrollArea className="h-[400px] w-[350px] rounded-sm border border-border p-4">
|
|
88
|
+
<div className="space-y-4">
|
|
89
|
+
<h4 id="large-content-h4-sonance-brand-guidel" className="text-lg font-medium text-foreground">Sonance Brand Guidelines</h4>
|
|
90
|
+
<p id="large-content-p-welcome-to-the-sonan" className="text-sm text-foreground-secondary leading-relaxed">
|
|
91
|
+
Welcome to the Sonance Brand Guidelines. This document outlines the visual
|
|
92
|
+
identity and design standards for the Sonance family of brands.
|
|
93
|
+
</p>
|
|
94
|
+
<h5 id="large-content-h5-typography" className="text-sm font-medium text-foreground mt-6">Typography</h5>
|
|
95
|
+
<p id="large-content-p-all-text-should-use-" className="text-sm text-foreground-secondary leading-relaxed">
|
|
96
|
+
All text should use the Montserrat font family. Headlines use font-weight 300
|
|
97
|
+
(Light) or 500 (Medium), while body text uses 400 (Regular).
|
|
98
|
+
</p>
|
|
99
|
+
<h5 id="large-content-h5-colors" className="text-sm font-medium text-foreground mt-6">Colors</h5>
|
|
100
|
+
<p id="large-content-p-the-sonance-brand-us" className="text-sm text-foreground-secondary leading-relaxed">
|
|
101
|
+
The Sonance brand uses a sophisticated palette centered around Charcoal
|
|
102
|
+
(#333F48) as the primary color, with Sonance Blue (#00D3C8) as the accent.
|
|
103
|
+
</p>
|
|
104
|
+
<h5 id="large-content-h5-logo-usage" className="text-sm font-medium text-foreground mt-6">Logo Usage</h5>
|
|
105
|
+
<p id="large-content-p-the-sonance-logo-sho" className="text-sm text-foreground-secondary leading-relaxed">
|
|
106
|
+
The Sonance logo should always have adequate clear space and never be
|
|
107
|
+
stretched, rotated, or modified in any way.
|
|
108
|
+
</p>
|
|
109
|
+
<h5 id="large-content-h5-photography" className="text-sm font-medium text-foreground mt-6">Photography</h5>
|
|
110
|
+
<p id="large-content-p-use-photorealistic-i" className="text-sm text-foreground-secondary leading-relaxed">
|
|
111
|
+
Use photo-realistic imagery only. Avoid cartoons, illustrations, or
|
|
112
|
+
AI-generated images that don't meet our quality standards.
|
|
113
|
+
</p>
|
|
114
|
+
<h5 id="large-content-h5-design-principles" className="text-sm font-medium text-foreground mt-6">Design Principles</h5>
|
|
115
|
+
<p id="large-content-p-embrace-generous-whi" className="text-sm text-foreground-secondary leading-relaxed">
|
|
116
|
+
Embrace generous whitespace, minimal borders, refined shadows, and clean
|
|
117
|
+
backgrounds. Every element should feel premium and intentional.
|
|
118
|
+
</p>
|
|
119
|
+
</div>
|
|
120
|
+
</ScrollArea>
|
|
121
|
+
),
|
|
122
|
+
};
|
|
123
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
|
|
7
|
+
const ScrollArea = React.forwardRef<
|
|
8
|
+
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
|
9
|
+
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
|
10
|
+
>(({ className, children, ...props }, ref) => (
|
|
11
|
+
<ScrollAreaPrimitive.Root data-sonance-name="scroll-area"
|
|
12
|
+
ref={ref}
|
|
13
|
+
className={cn("relative overflow-hidden", className)}
|
|
14
|
+
{...props}
|
|
15
|
+
>
|
|
16
|
+
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
|
|
17
|
+
{children}
|
|
18
|
+
</ScrollAreaPrimitive.Viewport>
|
|
19
|
+
<ScrollBar />
|
|
20
|
+
<ScrollAreaPrimitive.Corner />
|
|
21
|
+
</ScrollAreaPrimitive.Root>
|
|
22
|
+
));
|
|
23
|
+
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
24
|
+
|
|
25
|
+
const ScrollBar = React.forwardRef<
|
|
26
|
+
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
|
|
27
|
+
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
28
|
+
>(({ className, orientation = "vertical", ...props }, ref) => (
|
|
29
|
+
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
30
|
+
ref={ref}
|
|
31
|
+
orientation={orientation}
|
|
32
|
+
className={cn(
|
|
33
|
+
"flex touch-none select-none transition-colors",
|
|
34
|
+
orientation === "vertical" &&
|
|
35
|
+
"h-full w-2.5 border-l border-l-transparent p-[1px]",
|
|
36
|
+
orientation === "horizontal" &&
|
|
37
|
+
"h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
|
38
|
+
className
|
|
39
|
+
)}
|
|
40
|
+
{...props}
|
|
41
|
+
>
|
|
42
|
+
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
|
|
43
|
+
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
44
|
+
));
|
|
45
|
+
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
46
|
+
|
|
47
|
+
export { ScrollArea, ScrollBar };
|
|
48
|
+
|