sid-ui 0.0.0-stage → 0.1.1
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 +54 -2
- package/package.json +51 -4
- package/src/brand/BrandFooter.tsx +45 -0
- package/src/brand/BrandHeading.tsx +24 -0
- package/src/brand/BrandLockup.tsx +47 -0
- package/src/brand/JoinedLogo.tsx +67 -0
- package/src/brand/JoinedMark.tsx +76 -0
- package/src/brand/geometry.ts +26 -0
- package/src/brand/index.ts +11 -0
- package/src/brand/name.ts +5 -0
- package/src/brand/paint.tsx +56 -0
- package/src/components/Action.tsx +44 -0
- package/src/components/AddressSelector.tsx +99 -0
- package/src/components/BarChart.tsx +132 -0
- package/src/components/Calendar.tsx +284 -0
- package/src/components/CalendarAgenda.tsx +87 -0
- package/src/components/CalendarMonth.tsx +223 -0
- package/src/components/CalendarSchedule.tsx +210 -0
- package/src/components/Card.tsx +80 -0
- package/src/components/Charts.tsx +64 -0
- package/src/components/Chat.tsx +35 -0
- package/src/components/CitySelector.tsx +81 -0
- package/src/components/Clock.tsx +196 -0
- package/src/components/CodeInput.tsx +183 -0
- package/src/components/Container.tsx +20 -0
- package/src/components/Content.tsx +50 -0
- package/src/components/Data.tsx +43 -0
- package/src/components/DataInput.tsx +107 -0
- package/src/components/DateField.tsx +162 -0
- package/src/components/DonutChart.tsx +123 -0
- package/src/components/Drawer.tsx +110 -0
- package/src/components/Feedback.tsx +37 -0
- package/src/components/FileUploader.tsx +377 -0
- package/src/components/FunnelChart.tsx +83 -0
- package/src/components/Glyph.tsx +330 -0
- package/src/components/GoogleSignIn.tsx +67 -0
- package/src/components/GridSystem.tsx +131 -0
- package/src/components/HeatmapCalendar.tsx +167 -0
- package/src/components/KanbanBoard.tsx +421 -0
- package/src/components/Kpi.tsx +61 -0
- package/src/components/LayoutPrimitives.tsx +86 -0
- package/src/components/Lists.tsx +19 -0
- package/src/components/LocationSelector.tsx +49 -0
- package/src/components/MessageList.tsx +80 -0
- package/src/components/Nav.tsx +69 -0
- package/src/components/Navigation.tsx +52 -0
- package/src/components/Notification.tsx +115 -0
- package/src/components/NotificationTrigger.tsx +248 -0
- package/src/components/Overlay.tsx +50 -0
- package/src/components/Page.tsx +143 -0
- package/src/components/PageTabs.tsx +28 -0
- package/src/components/PickerShell.tsx +138 -0
- package/src/components/PillNav.tsx +194 -0
- package/src/components/Primitives.tsx +30 -0
- package/src/components/Rating.tsx +78 -0
- package/src/components/Responsive.tsx +128 -0
- package/src/components/ResponsiveFrame.tsx +122 -0
- package/src/components/Segment.tsx +190 -0
- package/src/components/Sparkline.tsx +52 -0
- package/src/components/StateSelector.tsx +39 -0
- package/src/components/Sticky.tsx +95 -0
- package/src/components/Table.tsx +344 -0
- package/src/components/ThemeToggle.tsx +48 -0
- package/src/components/Tile.tsx +23 -0
- package/src/components/TimeColumns.tsx +155 -0
- package/src/components/TimeDial.tsx +260 -0
- package/src/components/TimeField.tsx +196 -0
- package/src/components/TimeInput.tsx +213 -0
- package/src/components/TimeSlots.tsx +83 -0
- package/src/components/Timeline.tsx +111 -0
- package/src/components/TokenDemo.tsx +378 -0
- package/src/components/Tree.tsx +283 -0
- package/src/components/TrendChart.tsx +211 -0
- package/src/components/breakpoints.ts +42 -0
- package/src/components/calendarTypes.ts +26 -0
- package/src/components/chartMath.ts +125 -0
- package/src/components/chartParts.tsx +116 -0
- package/src/components/codeInputRules.ts +58 -0
- package/src/components/date.ts +87 -0
- package/src/components/hooks.ts +53 -0
- package/src/components/index.ts +195 -0
- package/src/components/kanban.ts +78 -0
- package/src/components/motion.ts +78 -0
- package/src/components/places-search.tsx +73 -0
- package/src/components/places.ts +209 -0
- package/src/components/size.ts +3 -0
- package/src/components/time.ts +83 -0
- package/src/components/useFileDrop.ts +104 -0
- package/src/places/geoapify.ts +129 -0
- package/src/styles/astryx.css +5 -0
- package/src/styles/components/brand.css +98 -0
- package/src/styles/components/calendar.css +680 -0
- package/src/styles/components/charts.css +659 -0
- package/src/styles/components/code-input.css +233 -0
- package/src/styles/components/google.css +11 -0
- package/src/styles/components/message-list.css +153 -0
- package/src/styles/components/notification.css +350 -0
- package/src/styles/components/picker.css +114 -0
- package/src/styles/components/pill-nav.css +179 -0
- package/src/styles/components/responsive.css +419 -0
- package/src/styles/components/sticky.css +23 -0
- package/src/styles/components/table.css +267 -0
- package/src/styles/components/time.css +526 -0
- package/src/styles/components/timeline.css +426 -0
- package/src/styles/components/tree.css +269 -0
- package/src/styles/components.css +423 -0
- package/src/styles/joined.css +4 -0
- package/src/styles/theme.css +79 -0
- package/src/styles/tokens.css +338 -0
- package/src/theme/JoinedProvider.tsx +50 -0
- package/src/theme/index.ts +3 -0
- package/src/theme/joined.d.ts +11 -0
- package/src/theme/joined.js +569 -0
- package/src/theme/joined.theme.ts +74 -0
- package/src/theme/joined.variants.d.ts +16 -0
- package/src/theme/theme.css +786 -0
- package/styles/astryx.css +1 -0
- package/styles/components.css +1 -0
- package/styles/joined.css +1 -0
- package/styles/theme.css +1 -0
- package/styles/tokens.css +1 -0
- package/styles.css +1 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
|
|
5
|
+
import { Button } from "./Action";
|
|
6
|
+
import { Calendar, type CalendarProps } from "./Calendar";
|
|
7
|
+
import { MONTHS_PER_YEAR, daysInMonth, startOfDay } from "./date";
|
|
8
|
+
import { PickerShell } from "./PickerShell";
|
|
9
|
+
import { NumberSegment, SegmentDivider } from "./Segment";
|
|
10
|
+
|
|
11
|
+
import type { ControlSize } from "./size";
|
|
12
|
+
|
|
13
|
+
const MIN_YEAR = 1;
|
|
14
|
+
const MAX_YEAR = 9999;
|
|
15
|
+
const LEAP_YEAR = 2024;
|
|
16
|
+
|
|
17
|
+
export interface DateFieldProps {
|
|
18
|
+
value: Date | null;
|
|
19
|
+
onChange?: (value: Date | null) => void;
|
|
20
|
+
/** Type-only when false. */
|
|
21
|
+
withCalendar?: boolean;
|
|
22
|
+
/** Passed to the dropdown calendar — events, disabled days, week start. */
|
|
23
|
+
calendar?: Pick<
|
|
24
|
+
CalendarProps,
|
|
25
|
+
"events" | "min" | "max" | "isDateDisabled" | "weekStartsOn" | "showWeekNumbers"
|
|
26
|
+
>;
|
|
27
|
+
size?: ControlSize;
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
error?: boolean;
|
|
30
|
+
label?: string;
|
|
31
|
+
labelledBy?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface Draft {
|
|
35
|
+
month: number | null;
|
|
36
|
+
day: number | null;
|
|
37
|
+
year: number | null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function draftOf(value: Date | null): Draft {
|
|
41
|
+
return value
|
|
42
|
+
? { month: value.getMonth() + 1, day: value.getDate(), year: value.getFullYear() }
|
|
43
|
+
: { month: null, day: null, year: null };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Type a date as MM / DD / YYYY, or open the calendar and pick it. */
|
|
47
|
+
export function DateField({
|
|
48
|
+
value,
|
|
49
|
+
onChange,
|
|
50
|
+
withCalendar = true,
|
|
51
|
+
calendar,
|
|
52
|
+
size = "md",
|
|
53
|
+
disabled,
|
|
54
|
+
error,
|
|
55
|
+
label = "Date",
|
|
56
|
+
labelledBy,
|
|
57
|
+
}: DateFieldProps) {
|
|
58
|
+
const [open, setOpen] = useState(false);
|
|
59
|
+
const [draft, setDraft] = useState(() => draftOf(value));
|
|
60
|
+
const [seen, setSeen] = useState(value?.getTime() ?? null);
|
|
61
|
+
const stamp = value?.getTime() ?? null;
|
|
62
|
+
if (seen !== stamp) {
|
|
63
|
+
setSeen(stamp);
|
|
64
|
+
setDraft(draftOf(value));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function update(patch: Partial<Draft>) {
|
|
68
|
+
const next = { ...draft, ...patch };
|
|
69
|
+
setDraft(next);
|
|
70
|
+
if (next.month == null && next.day == null && next.year == null) return onChange?.(null);
|
|
71
|
+
if (next.month == null || next.day == null || next.year == null) return;
|
|
72
|
+
const day = Math.min(next.day, daysInMonth(next.year, next.month - 1));
|
|
73
|
+
const date = new Date(next.year, next.month - 1, day);
|
|
74
|
+
date.setFullYear(next.year);
|
|
75
|
+
onChange?.(date);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const dayMax = daysInMonth(draft.year ?? LEAP_YEAR, (draft.month ?? 1) - 1);
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<PickerShell
|
|
82
|
+
open={open}
|
|
83
|
+
onOpenChange={setOpen}
|
|
84
|
+
icon="calendar"
|
|
85
|
+
label={label}
|
|
86
|
+
labelledBy={labelledBy}
|
|
87
|
+
size={size}
|
|
88
|
+
error={error}
|
|
89
|
+
disabled={disabled}
|
|
90
|
+
panel={
|
|
91
|
+
withCalendar ? (
|
|
92
|
+
<div className="os-picker-body">
|
|
93
|
+
<Calendar
|
|
94
|
+
{...calendar}
|
|
95
|
+
size="sm"
|
|
96
|
+
value={value}
|
|
97
|
+
onChange={(date) => {
|
|
98
|
+
onChange?.(date);
|
|
99
|
+
setOpen(false);
|
|
100
|
+
}}
|
|
101
|
+
footer={
|
|
102
|
+
<div className="os-picker-footer">
|
|
103
|
+
<Button
|
|
104
|
+
label="Clear"
|
|
105
|
+
variant="ghost"
|
|
106
|
+
size="sm"
|
|
107
|
+
onClick={() => onChange?.(null)}
|
|
108
|
+
/>
|
|
109
|
+
<Button
|
|
110
|
+
label="Today"
|
|
111
|
+
variant="secondary"
|
|
112
|
+
size="sm"
|
|
113
|
+
onClick={() => {
|
|
114
|
+
onChange?.(startOfDay(new Date()));
|
|
115
|
+
setOpen(false);
|
|
116
|
+
}}
|
|
117
|
+
/>
|
|
118
|
+
</div>
|
|
119
|
+
}
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
) : undefined
|
|
123
|
+
}
|
|
124
|
+
segments={
|
|
125
|
+
<>
|
|
126
|
+
<NumberSegment
|
|
127
|
+
label="Month"
|
|
128
|
+
value={draft.month}
|
|
129
|
+
min={1}
|
|
130
|
+
max={MONTHS_PER_YEAR}
|
|
131
|
+
digits={2}
|
|
132
|
+
placeholder="MM"
|
|
133
|
+
disabled={disabled}
|
|
134
|
+
onChange={(month) => update({ month })}
|
|
135
|
+
/>
|
|
136
|
+
<SegmentDivider>/</SegmentDivider>
|
|
137
|
+
<NumberSegment
|
|
138
|
+
label="Day"
|
|
139
|
+
value={draft.day}
|
|
140
|
+
min={1}
|
|
141
|
+
max={dayMax}
|
|
142
|
+
digits={2}
|
|
143
|
+
placeholder="DD"
|
|
144
|
+
disabled={disabled}
|
|
145
|
+
onChange={(day) => update({ day })}
|
|
146
|
+
/>
|
|
147
|
+
<SegmentDivider>/</SegmentDivider>
|
|
148
|
+
<NumberSegment
|
|
149
|
+
label="Year"
|
|
150
|
+
value={draft.year}
|
|
151
|
+
min={MIN_YEAR}
|
|
152
|
+
max={MAX_YEAR}
|
|
153
|
+
digits={4}
|
|
154
|
+
placeholder="YYYY"
|
|
155
|
+
disabled={disabled}
|
|
156
|
+
onChange={(year) => update({ year })}
|
|
157
|
+
/>
|
|
158
|
+
</>
|
|
159
|
+
}
|
|
160
|
+
/>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
|
|
5
|
+
import { arcPath, segmentShares } from "./chartMath";
|
|
6
|
+
import { ChartTable, defaultFormat, toneAt, type ChartTone } from "./chartParts";
|
|
7
|
+
|
|
8
|
+
export type DonutSlice = {
|
|
9
|
+
label: string;
|
|
10
|
+
value: number;
|
|
11
|
+
tone?: ChartTone;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const DEFAULT_SIZE = 168;
|
|
15
|
+
const RING = 0.22;
|
|
16
|
+
/** The 2px surface gap between slices, in px along the outer edge. */
|
|
17
|
+
const GAP_PX = 2;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Part of a whole, for up to five slices. The middle shows the total, or the hovered
|
|
21
|
+
* slice. The legend carries every name, value, and share, so colour never works alone.
|
|
22
|
+
*/
|
|
23
|
+
export function DonutChart({
|
|
24
|
+
data,
|
|
25
|
+
label,
|
|
26
|
+
centerLabel = "Total",
|
|
27
|
+
size = DEFAULT_SIZE,
|
|
28
|
+
formatValue = defaultFormat,
|
|
29
|
+
}: {
|
|
30
|
+
data: DonutSlice[];
|
|
31
|
+
/** Accessible name for the chart. */
|
|
32
|
+
label: string;
|
|
33
|
+
/** Names the figure in the middle, e.g. "Applications". */
|
|
34
|
+
centerLabel?: string;
|
|
35
|
+
size?: number;
|
|
36
|
+
formatValue?: (value: number) => string;
|
|
37
|
+
}) {
|
|
38
|
+
const [active, setActive] = useState<number | null>(null);
|
|
39
|
+
const shares = segmentShares(data.map((slice) => slice.value));
|
|
40
|
+
const total = data.reduce((sum, slice) => sum + Math.max(0, slice.value), 0);
|
|
41
|
+
const outer = size / 2;
|
|
42
|
+
const inner = outer * (1 - RING * 2);
|
|
43
|
+
const pad = GAP_PX / (2 * Math.PI * outer);
|
|
44
|
+
const visible = shares.filter((share) => share > 0).length;
|
|
45
|
+
const toned = data.map((slice, index) => ({ ...slice, tone: toneAt(index, slice.tone) }));
|
|
46
|
+
|
|
47
|
+
let start = 0;
|
|
48
|
+
const arcs = toned.map((slice, index) => {
|
|
49
|
+
const fraction = shares[index] / 100;
|
|
50
|
+
const from = start;
|
|
51
|
+
start += fraction;
|
|
52
|
+
const gap = visible > 1 ? pad : 0;
|
|
53
|
+
return {
|
|
54
|
+
slice,
|
|
55
|
+
index,
|
|
56
|
+
d: fraction > 0 ? arcPath(outer, outer, inner, outer, from + gap / 2, start - gap / 2) : "",
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const focus = active === null ? null : toned[active];
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div className="os-donut">
|
|
64
|
+
<div className="os-donut-figure" style={{ width: size, height: size }}>
|
|
65
|
+
<svg width={size} height={size} aria-hidden>
|
|
66
|
+
<circle
|
|
67
|
+
className="os-donut-track"
|
|
68
|
+
cx={outer}
|
|
69
|
+
cy={outer}
|
|
70
|
+
r={(outer + inner) / 2}
|
|
71
|
+
strokeWidth={outer - inner}
|
|
72
|
+
/>
|
|
73
|
+
{arcs.map(({ slice, index, d }) =>
|
|
74
|
+
d ? (
|
|
75
|
+
<path
|
|
76
|
+
key={slice.label}
|
|
77
|
+
d={d}
|
|
78
|
+
className="os-donut-slice"
|
|
79
|
+
data-tone={slice.tone}
|
|
80
|
+
data-dim={active !== null && active !== index ? true : undefined}
|
|
81
|
+
onPointerEnter={() => setActive(index)}
|
|
82
|
+
onPointerLeave={() => setActive(null)}
|
|
83
|
+
/>
|
|
84
|
+
) : null,
|
|
85
|
+
)}
|
|
86
|
+
</svg>
|
|
87
|
+
<div className="os-donut-center" aria-live="polite">
|
|
88
|
+
<strong>{formatValue(focus ? focus.value : total)}</strong>
|
|
89
|
+
<span>
|
|
90
|
+
{focus ? `${focus.label} · ${Math.round(shares[active ?? 0])}%` : centerLabel}
|
|
91
|
+
</span>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
<ul className="os-donut-legend" aria-label={label}>
|
|
95
|
+
{toned.map((slice, index) => (
|
|
96
|
+
<li
|
|
97
|
+
key={slice.label}
|
|
98
|
+
tabIndex={0}
|
|
99
|
+
data-active={active === index || undefined}
|
|
100
|
+
onPointerEnter={() => setActive(index)}
|
|
101
|
+
onPointerLeave={() => setActive(null)}
|
|
102
|
+
onFocus={() => setActive(index)}
|
|
103
|
+
onBlur={() => setActive(null)}
|
|
104
|
+
>
|
|
105
|
+
<span className="os-chart-key" data-tone={slice.tone} aria-hidden />
|
|
106
|
+
<span className="os-donut-name">{slice.label}</span>
|
|
107
|
+
<strong>{formatValue(slice.value)}</strong>
|
|
108
|
+
<span className="os-donut-share">{Math.round(shares[index])}%</span>
|
|
109
|
+
</li>
|
|
110
|
+
))}
|
|
111
|
+
</ul>
|
|
112
|
+
<ChartTable
|
|
113
|
+
caption={label}
|
|
114
|
+
headers={["", "Value", "Share"]}
|
|
115
|
+
rows={data.map((slice, index) => [
|
|
116
|
+
slice.label,
|
|
117
|
+
formatValue(slice.value),
|
|
118
|
+
`${Math.round(shares[index])}%`,
|
|
119
|
+
])}
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Layout, LayoutContent, LayoutFooter } from "./LayoutPrimitives";
|
|
4
|
+
import { Dialog, DialogHeader, type DialogPurpose } from "./Overlay";
|
|
5
|
+
|
|
6
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
7
|
+
|
|
8
|
+
export type DrawerSide = "start" | "end" | "top" | "bottom";
|
|
9
|
+
export type DrawerSize = "sm" | "md" | "lg" | "full";
|
|
10
|
+
|
|
11
|
+
/** Panel length along the drawer's axis: width for start/end, height for top/bottom. */
|
|
12
|
+
const LENGTH: Record<Exclude<DrawerSize, "full">, number> = { sm: 360, md: 480, lg: 720 };
|
|
13
|
+
const FULL = "100%";
|
|
14
|
+
|
|
15
|
+
/** Flush to the viewport. A radius leaves a crescent of the scrim in each corner. */
|
|
16
|
+
const FLUSH = { borderRadius: 0, "--_dialog-radius": "0px" } as CSSProperties;
|
|
17
|
+
|
|
18
|
+
export interface DrawerProps {
|
|
19
|
+
isOpen: boolean;
|
|
20
|
+
onOpenChange: (isOpen: boolean) => void;
|
|
21
|
+
title: string;
|
|
22
|
+
subtitle?: string;
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
/** Sticky actions at the bottom — Save, Cancel, Next. */
|
|
25
|
+
footer?: ReactNode;
|
|
26
|
+
/** Actions beside the title, before the close button. */
|
|
27
|
+
headerActions?: ReactNode;
|
|
28
|
+
/** Leading content in the header — an avatar or icon. */
|
|
29
|
+
headerStart?: ReactNode;
|
|
30
|
+
/** Which edge the drawer slides from. Logical start/end mirror under RTL. */
|
|
31
|
+
side?: DrawerSide;
|
|
32
|
+
/** sm 360, md 480, lg 720, full — or any px/CSS length. */
|
|
33
|
+
size?: number | string;
|
|
34
|
+
/**
|
|
35
|
+
* form keeps focus inside and guards against losing input; info closes on
|
|
36
|
+
* outside click; required must be answered.
|
|
37
|
+
*/
|
|
38
|
+
purpose?: DialogPurpose;
|
|
39
|
+
/** Renders in place instead of on the top layer — for docs and embedded previews. */
|
|
40
|
+
isInline?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function lengthOf(size: DrawerProps["size"]) {
|
|
44
|
+
if (size === undefined) return LENGTH.md;
|
|
45
|
+
if (size === "full") return FULL;
|
|
46
|
+
if (typeof size === "string" && size in LENGTH) return LENGTH[size as keyof typeof LENGTH];
|
|
47
|
+
return size;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A panel that slides in from an edge for detail, editing, or filters while the
|
|
52
|
+
* page stays in context. Built on Astryx Dialog, so focus, Escape, and the
|
|
53
|
+
* scrim behave like every other overlay.
|
|
54
|
+
*/
|
|
55
|
+
export function Drawer({
|
|
56
|
+
isOpen,
|
|
57
|
+
onOpenChange,
|
|
58
|
+
title,
|
|
59
|
+
subtitle,
|
|
60
|
+
children,
|
|
61
|
+
footer,
|
|
62
|
+
headerActions,
|
|
63
|
+
headerStart,
|
|
64
|
+
side = "end",
|
|
65
|
+
size = "md",
|
|
66
|
+
purpose = "info",
|
|
67
|
+
isInline,
|
|
68
|
+
}: DrawerProps) {
|
|
69
|
+
const horizontal = side === "start" || side === "end";
|
|
70
|
+
const length = lengthOf(size);
|
|
71
|
+
const position = {
|
|
72
|
+
start: { start: 0, top: 0, bottom: 0 },
|
|
73
|
+
end: { end: 0, top: 0, bottom: 0 },
|
|
74
|
+
top: { top: 0, start: 0, end: 0 },
|
|
75
|
+
bottom: { bottom: 0, start: 0, end: 0 },
|
|
76
|
+
}[side];
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<Dialog
|
|
80
|
+
isOpen={isOpen}
|
|
81
|
+
onOpenChange={onOpenChange}
|
|
82
|
+
isInline={isInline}
|
|
83
|
+
purpose={purpose}
|
|
84
|
+
position={position}
|
|
85
|
+
width={horizontal ? length : FULL}
|
|
86
|
+
maxHeight={horizontal ? FULL : length}
|
|
87
|
+
style={
|
|
88
|
+
horizontal
|
|
89
|
+
? { height: FULL, maxWidth: FULL, ...FLUSH }
|
|
90
|
+
: { height: length, width: FULL, maxWidth: FULL, ...FLUSH }
|
|
91
|
+
}
|
|
92
|
+
>
|
|
93
|
+
<Layout
|
|
94
|
+
height="fill"
|
|
95
|
+
header={
|
|
96
|
+
<DialogHeader
|
|
97
|
+
title={title}
|
|
98
|
+
subtitle={subtitle}
|
|
99
|
+
startContent={headerStart}
|
|
100
|
+
endContent={headerActions}
|
|
101
|
+
onOpenChange={onOpenChange}
|
|
102
|
+
hasDivider
|
|
103
|
+
/>
|
|
104
|
+
}
|
|
105
|
+
content={<LayoutContent>{children}</LayoutContent>}
|
|
106
|
+
footer={footer ? <LayoutFooter hasDivider>{footer}</LayoutFooter> : undefined}
|
|
107
|
+
/>
|
|
108
|
+
</Dialog>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feedback and status components are original Astryx — Joined only themes
|
|
3
|
+
* them. JoinedProvider mounts the ToastViewport, so useToast works anywhere.
|
|
4
|
+
*/
|
|
5
|
+
export { Badge } from "@astryxdesign/core/Badge";
|
|
6
|
+
export type { BadgeProps, BadgeVariant } from "@astryxdesign/core/Badge";
|
|
7
|
+
|
|
8
|
+
export { Banner } from "@astryxdesign/core/Banner";
|
|
9
|
+
export type { BannerProps, BannerStatus, BannerContainer } from "@astryxdesign/core/Banner";
|
|
10
|
+
|
|
11
|
+
export { ProgressBar } from "@astryxdesign/core/ProgressBar";
|
|
12
|
+
export type {
|
|
13
|
+
ProgressBarProps,
|
|
14
|
+
ProgressBarMark,
|
|
15
|
+
ProgressBarVariant,
|
|
16
|
+
} from "@astryxdesign/core/ProgressBar";
|
|
17
|
+
|
|
18
|
+
export { Skeleton } from "@astryxdesign/core/Skeleton";
|
|
19
|
+
export type { SkeletonProps, SkeletonRadius } from "@astryxdesign/core/Skeleton";
|
|
20
|
+
|
|
21
|
+
export { Spinner } from "@astryxdesign/core/Spinner";
|
|
22
|
+
export type { SpinnerProps, SpinnerSize, SpinnerShade } from "@astryxdesign/core/Spinner";
|
|
23
|
+
|
|
24
|
+
export { StatusDot } from "@astryxdesign/core/StatusDot";
|
|
25
|
+
export type { StatusDotProps, StatusDotVariant } from "@astryxdesign/core/StatusDot";
|
|
26
|
+
|
|
27
|
+
export { Toast, ToastViewport, useToast } from "@astryxdesign/core/Toast";
|
|
28
|
+
export type {
|
|
29
|
+
ToastProps,
|
|
30
|
+
ToastViewportProps,
|
|
31
|
+
ToastOptions,
|
|
32
|
+
ToastType,
|
|
33
|
+
ToastPosition,
|
|
34
|
+
ToastDismissFn,
|
|
35
|
+
ToastDismissReason,
|
|
36
|
+
ShowToastFn,
|
|
37
|
+
} from "@astryxdesign/core/Toast";
|