@sixthshift/design-system 0.2.1 → 0.3.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 +135 -28
- package/dist/components/Badge/Badge.d.ts +5 -2
- package/dist/components/Badge/Badge.d.ts.map +1 -1
- package/dist/components/Badge/Badge.js +5 -3
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/BarChart/BarChart.d.ts +8 -2
- package/dist/components/BarChart/BarChart.d.ts.map +1 -1
- package/dist/components/BarChart/BarChart.js +5 -3
- package/dist/components/BarChart/BarChart.js.map +1 -1
- package/dist/components/Calendar/Calendar.d.ts +17 -1
- package/dist/components/Calendar/Calendar.d.ts.map +1 -1
- package/dist/components/Calendar/Calendar.js +80 -225
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/Calendar/CalendarView.d.ts +15 -0
- package/dist/components/Calendar/CalendarView.d.ts.map +1 -0
- package/dist/components/Calendar/CalendarView.js +255 -0
- package/dist/components/Calendar/CalendarView.js.map +1 -0
- package/dist/components/Calendar/calendar.types.d.ts +78 -27
- package/dist/components/Calendar/calendar.types.d.ts.map +1 -1
- package/dist/components/Calendar/calendar.types.js +10 -3
- package/dist/components/Calendar/calendar.types.js.map +1 -1
- package/dist/components/Calendar/index.d.ts +16 -2
- package/dist/components/Calendar/index.d.ts.map +1 -1
- package/dist/components/Calendar/index.js +15 -1
- package/dist/components/Calendar/index.js.map +1 -1
- package/dist/components/ColorDot/ColorDot.d.ts +9 -3
- package/dist/components/ColorDot/ColorDot.d.ts.map +1 -1
- package/dist/components/ColorDot/ColorDot.js +5 -3
- package/dist/components/ColorDot/ColorDot.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.d.ts +2 -2
- package/dist/components/DatePicker/DatePicker.d.ts.map +1 -1
- package/dist/components/DatePicker/DatePicker.js +65 -10
- package/dist/components/DatePicker/DatePicker.js.map +1 -1
- package/dist/components/DatePicker/datepicker.types.d.ts +34 -36
- package/dist/components/DatePicker/datepicker.types.d.ts.map +1 -1
- package/dist/components/DatePicker/datepicker.types.js +5 -3
- package/dist/components/DatePicker/datepicker.types.js.map +1 -1
- package/dist/components/DatePicker/index.d.ts +10 -1
- package/dist/components/DatePicker/index.d.ts.map +1 -1
- package/dist/components/DatePicker/index.js +8 -0
- package/dist/components/DatePicker/index.js.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.d.ts +3 -2
- package/dist/components/DateRangePicker/DateRangePicker.d.ts.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.js +17 -21
- package/dist/components/DateRangePicker/DateRangePicker.js.map +1 -1
- package/dist/components/DateRangePicker/daterangepicker.types.d.ts +20 -20
- package/dist/components/DateRangePicker/daterangepicker.types.d.ts.map +1 -1
- package/dist/components/DateRangePicker/daterangepicker.types.js +6 -0
- package/dist/components/DateRangePicker/daterangepicker.types.js.map +1 -1
- package/dist/components/DateRangePicker/index.d.ts +8 -1
- package/dist/components/DateRangePicker/index.d.ts.map +1 -1
- package/dist/components/DateRangePicker/index.js +6 -0
- package/dist/components/DateRangePicker/index.js.map +1 -1
- package/dist/components/DateTimePicker/DateTimePicker.d.ts +3 -3
- package/dist/components/DateTimePicker/DateTimePicker.d.ts.map +1 -1
- package/dist/components/DateTimePicker/DateTimePicker.js +30 -12
- package/dist/components/DateTimePicker/DateTimePicker.js.map +1 -1
- package/dist/components/DateTimePicker/datetimepicker.types.d.ts +20 -17
- package/dist/components/DateTimePicker/datetimepicker.types.d.ts.map +1 -1
- package/dist/components/DateTimePicker/datetimepicker.types.js +10 -0
- package/dist/components/DateTimePicker/datetimepicker.types.js.map +1 -1
- package/dist/components/DateTimePicker/index.d.ts +8 -1
- package/dist/components/DateTimePicker/index.d.ts.map +1 -1
- package/dist/components/DateTimePicker/index.js +6 -0
- package/dist/components/DateTimePicker/index.js.map +1 -1
- package/dist/components/DateTimeRangePicker/DateTimeRangePicker.d.ts +3 -3
- package/dist/components/DateTimeRangePicker/DateTimeRangePicker.d.ts.map +1 -1
- package/dist/components/DateTimeRangePicker/DateTimeRangePicker.js +41 -20
- package/dist/components/DateTimeRangePicker/DateTimeRangePicker.js.map +1 -1
- package/dist/components/DateTimeRangePicker/datetimerangepicker.types.d.ts +22 -18
- package/dist/components/DateTimeRangePicker/datetimerangepicker.types.d.ts.map +1 -1
- package/dist/components/DateTimeRangePicker/datetimerangepicker.types.js +8 -0
- package/dist/components/DateTimeRangePicker/datetimerangepicker.types.js.map +1 -1
- package/dist/components/DateTimeRangePicker/index.d.ts +8 -0
- package/dist/components/DateTimeRangePicker/index.d.ts.map +1 -1
- package/dist/components/DateTimeRangePicker/index.js +7 -0
- package/dist/components/DateTimeRangePicker/index.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.d.ts +16 -5
- package/dist/components/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/components/EmptyState/EmptyState.js +5 -3
- package/dist/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/components/Field/Field.d.ts +3 -3
- package/dist/components/Field/Field.d.ts.map +1 -1
- package/dist/components/Field/Field.js +6 -4
- package/dist/components/Field/Field.js.map +1 -1
- package/dist/components/LineChart/LineChart.d.ts +18 -2
- package/dist/components/LineChart/LineChart.d.ts.map +1 -1
- package/dist/components/LineChart/LineChart.js +5 -3
- package/dist/components/LineChart/LineChart.js.map +1 -1
- package/dist/components/Markdown/Markdown.d.ts +2 -4
- package/dist/components/Markdown/Markdown.d.ts.map +1 -1
- package/dist/components/Markdown/Markdown.js +3 -2
- package/dist/components/Markdown/Markdown.js.map +1 -1
- package/dist/components/Message/Message.d.ts.map +1 -1
- package/dist/components/Message/Message.js +16 -1
- package/dist/components/Message/Message.js.map +1 -1
- package/dist/components/MetricList/MetricList.d.ts +3 -3
- package/dist/components/MetricList/MetricList.d.ts.map +1 -1
- package/dist/components/MetricList/MetricList.js +5 -3
- package/dist/components/MetricList/MetricList.js.map +1 -1
- package/dist/components/Modal/Modal.d.ts +24 -5
- package/dist/components/Modal/Modal.d.ts.map +1 -1
- package/dist/components/Modal/Modal.js +16 -6
- package/dist/components/Modal/Modal.js.map +1 -1
- package/dist/components/Modal/components/ModalContext.d.ts +14 -0
- package/dist/components/Modal/components/ModalContext.d.ts.map +1 -1
- package/dist/components/Modal/components/ModalContext.js.map +1 -1
- package/dist/components/Modal/components/ModalHeader.d.ts.map +1 -1
- package/dist/components/Modal/components/ModalHeader.js +13 -2
- package/dist/components/Modal/components/ModalHeader.js.map +1 -1
- package/dist/components/NavBottom/NavBottom.d.ts +2 -1
- package/dist/components/NavBottom/NavBottom.d.ts.map +1 -1
- package/dist/components/NavBottom/NavBottom.js +6 -4
- package/dist/components/NavBottom/NavBottom.js.map +1 -1
- package/dist/components/NavSide/NavItem.js +1 -1
- package/dist/components/NavSide/NavItem.js.map +1 -1
- package/dist/components/NavSide/NavSide.d.ts +2 -1
- package/dist/components/NavSide/NavSide.d.ts.map +1 -1
- package/dist/components/NavSide/NavSide.js +5 -3
- package/dist/components/NavSide/NavSide.js.map +1 -1
- package/dist/components/Popover/Popover.d.ts.map +1 -1
- package/dist/components/Popover/Popover.js +7 -0
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Popover/components/PopoverBody.d.ts.map +1 -1
- package/dist/components/Popover/components/PopoverBody.js +5 -2
- package/dist/components/Popover/components/PopoverBody.js.map +1 -1
- package/dist/components/Popover/components/PopoverContext.d.ts +1 -0
- package/dist/components/Popover/components/PopoverContext.d.ts.map +1 -1
- package/dist/components/Popover/components/PopoverContext.js.map +1 -1
- package/dist/components/Popover/components/PopoverTrigger.d.ts.map +1 -1
- package/dist/components/Popover/components/PopoverTrigger.js +2 -2
- package/dist/components/Popover/components/PopoverTrigger.js.map +1 -1
- package/dist/components/ProgressBar/ProgressBar.d.ts +2 -1
- package/dist/components/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/components/ProgressBar/ProgressBar.js +5 -3
- package/dist/components/ProgressBar/ProgressBar.js.map +1 -1
- package/dist/components/Select/Select.d.ts +11 -2
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/Select.js +64 -18
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Select/SelectDropdown.d.ts +14 -2
- package/dist/components/Select/SelectDropdown.d.ts.map +1 -1
- package/dist/components/Select/SelectDropdown.js +19 -4
- package/dist/components/Select/SelectDropdown.js.map +1 -1
- package/dist/components/Select/SelectTrigger.d.ts +10 -3
- package/dist/components/Select/SelectTrigger.d.ts.map +1 -1
- package/dist/components/Select/SelectTrigger.js +12 -3
- package/dist/components/Select/SelectTrigger.js.map +1 -1
- package/dist/components/Select/useSelectKeyboard.d.ts +15 -1
- package/dist/components/Select/useSelectKeyboard.d.ts.map +1 -1
- package/dist/components/Select/useSelectKeyboard.js +73 -65
- package/dist/components/Select/useSelectKeyboard.js.map +1 -1
- package/dist/components/Sheet/Sheet.d.ts +19 -5
- package/dist/components/Sheet/Sheet.d.ts.map +1 -1
- package/dist/components/Sheet/Sheet.js +18 -6
- package/dist/components/Sheet/Sheet.js.map +1 -1
- package/dist/components/Sheet/components/SheetContext.d.ts +10 -0
- package/dist/components/Sheet/components/SheetContext.d.ts.map +1 -1
- package/dist/components/Sheet/components/SheetContext.js.map +1 -1
- package/dist/components/Sheet/components/SheetHeader.d.ts.map +1 -1
- package/dist/components/Sheet/components/SheetHeader.js +11 -2
- package/dist/components/Sheet/components/SheetHeader.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.d.ts +2 -1
- package/dist/components/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/components/Skeleton/Skeleton.js +5 -3
- package/dist/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/components/Sparkline/Sparkline.d.ts +10 -2
- package/dist/components/Sparkline/Sparkline.d.ts.map +1 -1
- package/dist/components/Sparkline/Sparkline.js +5 -3
- package/dist/components/Sparkline/Sparkline.js.map +1 -1
- package/dist/components/StatsCard/StatsCard.d.ts +4 -4
- package/dist/components/StatsCard/StatsCard.d.ts.map +1 -1
- package/dist/components/StatsCard/StatsCard.js +5 -3
- package/dist/components/StatsCard/StatsCard.js.map +1 -1
- package/dist/components/Tabs/Tabs.d.ts +2 -2
- package/dist/components/Tabs/components/TabsList.d.ts +1 -1
- package/dist/components/Tabs/components/TabsList.d.ts.map +1 -1
- package/dist/components/Tabs/components/TabsList.js +5 -4
- package/dist/components/Tabs/components/TabsList.js.map +1 -1
- package/dist/components/Tabs/components/TabsPanels.d.ts +1 -1
- package/dist/components/Tabs/components/TabsPanels.d.ts.map +1 -1
- package/dist/components/Tabs/components/TabsPanels.js +5 -3
- package/dist/components/Tabs/components/TabsPanels.js.map +1 -1
- package/dist/components/TagChip/TagChip.d.ts +2 -1
- package/dist/components/TagChip/TagChip.d.ts.map +1 -1
- package/dist/components/TagChip/TagChip.js +5 -3
- package/dist/components/TagChip/TagChip.js.map +1 -1
- package/dist/components/TagInput/TagInput.d.ts +1 -1
- package/dist/components/TagInput/TagInput.d.ts.map +1 -1
- package/dist/components/TagInput/TagInput.js +5 -4
- package/dist/components/TagInput/TagInput.js.map +1 -1
- package/dist/components/TimePicker/TimePicker.d.ts +2 -2
- package/dist/components/TimePicker/TimePicker.d.ts.map +1 -1
- package/dist/components/TimePicker/TimePicker.js +27 -11
- package/dist/components/TimePicker/TimePicker.js.map +1 -1
- package/dist/components/TimePicker/timepicker.types.d.ts +14 -13
- package/dist/components/TimePicker/timepicker.types.d.ts.map +1 -1
- package/dist/components/TimePicker/timepicker.types.js +4 -3
- package/dist/components/TimePicker/timepicker.types.js.map +1 -1
- package/dist/date-time/index.d.ts +2 -0
- package/dist/date-time/index.d.ts.map +1 -1
- package/dist/date-time/index.js +9 -0
- package/dist/date-time/index.js.map +1 -1
- package/dist/date-time/iso.d.ts +261 -0
- package/dist/date-time/iso.d.ts.map +1 -0
- package/dist/date-time/iso.js +358 -0
- package/dist/date-time/iso.js.map +1 -0
- package/dist/date-time/now.d.ts +7 -6
- package/dist/date-time/now.d.ts.map +1 -1
- package/dist/date-time/now.js +3 -3
- package/dist/date-time/now.js.map +1 -1
- package/dist/theme/index.d.ts +4 -3
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +3 -2
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/schema.d.ts +70 -32
- package/dist/theme/schema.d.ts.map +1 -1
- package/dist/theme/schema.js +36 -18
- package/dist/theme/schema.js.map +1 -1
- package/package.json +9 -15
- package/src/components/Badge/Badge.tsx +5 -4
- package/src/components/BarChart/BarChart.tsx +25 -30
- package/src/components/Calendar/Calendar.tsx +91 -401
- package/src/components/Calendar/CalendarView.tsx +445 -0
- package/src/components/Calendar/calendar.types.ts +94 -29
- package/src/components/Calendar/index.ts +16 -17
- package/src/components/ColorDot/ColorDot.tsx +6 -4
- package/src/components/DatePicker/DatePicker.tsx +92 -16
- package/src/components/DatePicker/datepicker.types.ts +38 -39
- package/src/components/DatePicker/index.ts +11 -10
- package/src/components/DateRangePicker/DateRangePicker.tsx +17 -21
- package/src/components/DateRangePicker/daterangepicker.types.ts +22 -22
- package/src/components/DateRangePicker/index.ts +9 -1
- package/src/components/DateTimePicker/DateTimePicker.tsx +46 -18
- package/src/components/DateTimePicker/datetimepicker.types.ts +22 -18
- package/src/components/DateTimePicker/index.ts +9 -1
- package/src/components/DateTimeRangePicker/DateTimeRangePicker.tsx +62 -28
- package/src/components/DateTimeRangePicker/datetimerangepicker.types.ts +24 -19
- package/src/components/DateTimeRangePicker/index.ts +9 -0
- package/src/components/EmptyState/EmptyState.tsx +8 -7
- package/src/components/Field/Field.tsx +7 -6
- package/src/components/LineChart/LineChart.tsx +147 -141
- package/src/components/Markdown/Markdown.tsx +4 -3
- package/src/components/Message/Message.tsx +17 -1
- package/src/components/MetricList/MetricList.tsx +10 -5
- package/src/components/Modal/Modal.tsx +119 -87
- package/src/components/Modal/components/ModalContext.tsx +14 -0
- package/src/components/Modal/components/ModalHeader.tsx +14 -2
- package/src/components/NavBottom/NavBottom.tsx +6 -4
- package/src/components/NavSide/NavItem.tsx +1 -1
- package/src/components/NavSide/NavSide.tsx +5 -3
- package/src/components/Popover/Popover.tsx +7 -0
- package/src/components/Popover/components/PopoverBody.tsx +6 -1
- package/src/components/Popover/components/PopoverContext.tsx +1 -0
- package/src/components/Popover/components/PopoverTrigger.tsx +2 -1
- package/src/components/ProgressBar/ProgressBar.tsx +32 -28
- package/src/components/Select/Select.tsx +76 -19
- package/src/components/Select/SelectDropdown.tsx +32 -3
- package/src/components/Select/SelectTrigger.tsx +26 -3
- package/src/components/Select/useSelectKeyboard.ts +20 -10
- package/src/components/Sheet/Sheet.tsx +108 -83
- package/src/components/Sheet/components/SheetContext.tsx +10 -0
- package/src/components/Sheet/components/SheetHeader.tsx +17 -2
- package/src/components/Skeleton/Skeleton.tsx +5 -3
- package/src/components/Sparkline/Sparkline.tsx +29 -36
- package/src/components/StatsCard/StatsCard.tsx +7 -6
- package/src/components/Tabs/components/TabsList.tsx +5 -3
- package/src/components/Tabs/components/TabsPanels.tsx +5 -3
- package/src/components/TagChip/TagChip.tsx +10 -3
- package/src/components/TagInput/TagInput.tsx +5 -3
- package/src/components/TimePicker/TimePicker.tsx +31 -13
- package/src/components/TimePicker/timepicker.types.ts +14 -13
- package/src/date-time/index.ts +61 -0
- package/src/date-time/iso.ts +511 -0
- package/src/date-time/now.ts +10 -9
- package/src/theme/index.ts +11 -3
- package/src/theme/schema.ts +82 -54
- package/src/theme/tokens.css +807 -0
- package/dist/styles.css +0 -2
- package/dist/theme.generated.css +0 -438
- package/src/styles/base.css +0 -41
- package/src/theme/palette.json +0 -100
- package/src/theme/palette.schema.json +0 -40
- package/src/theme/theme.json +0 -349
- package/src/theme/theme.schema.json +0 -876
- package/src/theme/typography.json +0 -7
- package/src/theme/typography.schema.json +0 -36
- package/tailwind.config.ts +0 -261
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Tooltip } from "@sixthshift/design-system/tooltip";
|
|
2
2
|
import { cn } from "@sixthshift/design-system/utils";
|
|
3
|
-
import
|
|
3
|
+
import * as React from "react";
|
|
4
4
|
|
|
5
5
|
export type LineChartDataPoint = {
|
|
6
6
|
label: string;
|
|
@@ -96,156 +96,162 @@ function buildPath(points: { x: number; y: number }[], interpolation: Interpolat
|
|
|
96
96
|
return parts.join(" ");
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
export const LineChart = (
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
99
|
+
export const LineChart = React.forwardRef<HTMLDivElement, LineChartProps>(
|
|
100
|
+
(
|
|
101
|
+
{
|
|
102
|
+
series,
|
|
103
|
+
height = 200,
|
|
104
|
+
showGrid = true,
|
|
105
|
+
showAxes = true,
|
|
106
|
+
showDots = true,
|
|
107
|
+
showLabels = true,
|
|
108
|
+
showValues = false,
|
|
109
|
+
interpolation = "monotone",
|
|
110
|
+
fillArea = false,
|
|
111
|
+
yMin: yMinProp,
|
|
112
|
+
yMax: yMaxProp,
|
|
113
|
+
yTicks = 4,
|
|
114
|
+
showTooltip = false,
|
|
115
|
+
formatTooltip,
|
|
116
|
+
formatValue = (v) => String(v),
|
|
117
|
+
className,
|
|
118
|
+
...rest
|
|
119
|
+
}: LineChartProps,
|
|
120
|
+
ref
|
|
121
|
+
) => {
|
|
122
|
+
const allValues = series.flatMap((s) => s.data.map((d) => d.value));
|
|
123
|
+
// Math.min() of an empty list is Infinity, which propagates NaN through the
|
|
124
|
+
// whole scale. Fall back to a plain 0-1 axis when there is no data.
|
|
125
|
+
const rawMin = yMinProp ?? (allValues.length > 0 ? Math.min(...allValues) : 0);
|
|
126
|
+
const rawMax = yMaxProp ?? (allValues.length > 0 ? Math.max(...allValues) : 1);
|
|
127
|
+
const scale = niceScale(rawMin, rawMax, yTicks);
|
|
128
|
+
|
|
129
|
+
const labelSet = new Set<string>();
|
|
130
|
+
for (const s of series) {
|
|
131
|
+
for (const d of s.data) {
|
|
132
|
+
labelSet.add(d.label);
|
|
133
|
+
}
|
|
129
134
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const labelIndex = new Map(labels.map((l, i) => [l, i]));
|
|
135
|
+
const labels = [...labelSet];
|
|
136
|
+
const labelCount = labels.length;
|
|
137
|
+
const labelIndex = new Map(labels.map((l, i) => [l, i]));
|
|
134
138
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
const padding = showAxes ? PADDING : PADDING_NO_AXES;
|
|
140
|
+
const viewWidth = 600;
|
|
141
|
+
const chartW = viewWidth - padding.left - padding.right;
|
|
142
|
+
const chartH = height - padding.top - padding.bottom;
|
|
139
143
|
|
|
140
|
-
|
|
144
|
+
const xStep = labelCount > 1 ? chartW / (labelCount - 1) : 0;
|
|
141
145
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
146
|
+
function toX(i: number) {
|
|
147
|
+
return padding.left + i * xStep;
|
|
148
|
+
}
|
|
145
149
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
+
function toY(v: number) {
|
|
151
|
+
const ratio = (v - scale.min) / (scale.max - scale.min);
|
|
152
|
+
return padding.top + chartH - ratio * chartH;
|
|
153
|
+
}
|
|
150
154
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
const yTickValues: number[] = [];
|
|
156
|
+
for (let v = scale.min; v <= scale.max + scale.step * 0.01; v += scale.step) {
|
|
157
|
+
yTickValues.push(Math.round(v * 1e6) / 1e6);
|
|
158
|
+
}
|
|
155
159
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
160
|
+
function tooltipText(point: LineChartDataPoint, seriesName?: string) {
|
|
161
|
+
if (formatTooltip) return formatTooltip(point, seriesName);
|
|
162
|
+
const prefix = seriesName ? `${seriesName}: ` : `${point.label}: `;
|
|
163
|
+
return `${prefix}${formatValue(point.value)}`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<div ref={ref} {...rest} className={cn("relative w-full", className)}>
|
|
168
|
+
<svg viewBox={`0 0 ${viewWidth} ${height}`} className="w-full" preserveAspectRatio="xMidYMid meet" role="img">
|
|
169
|
+
<title>Line chart</title>
|
|
170
|
+
{showGrid &&
|
|
171
|
+
yTickValues.map((v) => (
|
|
172
|
+
<line
|
|
173
|
+
key={`grid-${v}`}
|
|
174
|
+
x1={padding.left}
|
|
175
|
+
y1={toY(v)}
|
|
176
|
+
x2={viewWidth - padding.right}
|
|
177
|
+
y2={toY(v)}
|
|
178
|
+
className="stroke-border-subtle"
|
|
179
|
+
strokeWidth={1}
|
|
180
|
+
strokeDasharray="4 4"
|
|
181
|
+
/>
|
|
182
|
+
))}
|
|
161
183
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
y1={padding.top + chartH}
|
|
186
|
-
x2={viewWidth - padding.right}
|
|
187
|
-
y2={padding.top + chartH}
|
|
188
|
-
className="stroke-border-normal"
|
|
189
|
-
strokeWidth={1}
|
|
190
|
-
/>
|
|
191
|
-
{yTickValues.map((v) => (
|
|
192
|
-
<text key={`ytick-${v}`} x={padding.left - 8} y={toY(v)} textAnchor="end" dominantBaseline="middle" className="fill-fg-subtle" fontSize={11}>
|
|
193
|
-
{formatValue(v)}
|
|
184
|
+
{showAxes && (
|
|
185
|
+
<>
|
|
186
|
+
<line x1={padding.left} y1={padding.top} x2={padding.left} y2={padding.top + chartH} className="stroke-border-normal" strokeWidth={1} />
|
|
187
|
+
<line
|
|
188
|
+
x1={padding.left}
|
|
189
|
+
y1={padding.top + chartH}
|
|
190
|
+
x2={viewWidth - padding.right}
|
|
191
|
+
y2={padding.top + chartH}
|
|
192
|
+
className="stroke-border-normal"
|
|
193
|
+
strokeWidth={1}
|
|
194
|
+
/>
|
|
195
|
+
{yTickValues.map((v) => (
|
|
196
|
+
<text key={`ytick-${v}`} x={padding.left - 8} y={toY(v)} textAnchor="end" dominantBaseline="middle" className="fill-fg-subtle" fontSize={11}>
|
|
197
|
+
{formatValue(v)}
|
|
198
|
+
</text>
|
|
199
|
+
))}
|
|
200
|
+
</>
|
|
201
|
+
)}
|
|
202
|
+
|
|
203
|
+
{showLabels &&
|
|
204
|
+
labels.map((label, i) => (
|
|
205
|
+
<text key={`xlabel-${label}`} x={toX(i)} y={height - 4} textAnchor="middle" className="fill-fg-subtle" fontSize={11}>
|
|
206
|
+
{label}
|
|
194
207
|
</text>
|
|
195
208
|
))}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
<text key={`xlabel-${label}`} x={toX(i)} y={height - 4} textAnchor="middle" className="fill-fg-subtle" fontSize={11}>
|
|
202
|
-
{label}
|
|
203
|
-
</text>
|
|
204
|
-
))}
|
|
205
|
-
|
|
206
|
-
{series.map((s, si) => {
|
|
207
|
-
const color = s.color ?? SERIES_COLORS[si % SERIES_COLORS.length];
|
|
208
|
-
const points = s.data.map((d) => ({ x: toX(labelIndex.get(d.label)!), y: toY(d.value) }));
|
|
209
|
-
const path = buildPath(points, interpolation);
|
|
210
|
-
|
|
211
|
-
return (
|
|
212
|
-
<g key={s.name ?? si}>
|
|
213
|
-
{fillArea && path && (
|
|
214
|
-
<path
|
|
215
|
-
d={`${path} L ${points[points.length - 1]!.x} ${padding.top + chartH} L ${points[0]!.x} ${padding.top + chartH} Z`}
|
|
216
|
-
fill={color}
|
|
217
|
-
opacity={0.1}
|
|
218
|
-
/>
|
|
219
|
-
)}
|
|
220
|
-
{path && <path d={path} fill="none" stroke={color} strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" />}
|
|
221
|
-
{showDots && points.map((p, pi) => <circle key={`dot-${s.data[pi]!.label}`} cx={p.x} cy={p.y} r={3} fill={color} />)}
|
|
222
|
-
{showValues &&
|
|
223
|
-
points.map((p, vi) => (
|
|
224
|
-
<text key={`val-${s.data[vi]!.label}`} x={p.x} y={p.y - 10} textAnchor="middle" className="fill-fg-normal" fontSize={10} fontWeight={600}>
|
|
225
|
-
{formatValue(s.data[vi]!.value)}
|
|
226
|
-
</text>
|
|
227
|
-
))}
|
|
228
|
-
</g>
|
|
229
|
-
);
|
|
230
|
-
})}
|
|
231
|
-
</svg>
|
|
232
|
-
|
|
233
|
-
{showTooltip &&
|
|
234
|
-
series.map((s, si) =>
|
|
235
|
-
s.data.map((d) => {
|
|
236
|
-
const xPct = (toX(labelIndex.get(d.label)!) / viewWidth) * 100;
|
|
237
|
-
const yPct = (toY(d.value) / height) * 100;
|
|
209
|
+
|
|
210
|
+
{series.map((s, si) => {
|
|
211
|
+
const color = s.color ?? SERIES_COLORS[si % SERIES_COLORS.length];
|
|
212
|
+
const points = s.data.map((d) => ({ x: toX(labelIndex.get(d.label)!), y: toY(d.value) }));
|
|
213
|
+
const path = buildPath(points, interpolation);
|
|
238
214
|
|
|
239
215
|
return (
|
|
240
|
-
<
|
|
241
|
-
|
|
242
|
-
<
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
216
|
+
<g key={s.name ?? si}>
|
|
217
|
+
{fillArea && path && (
|
|
218
|
+
<path
|
|
219
|
+
d={`${path} L ${points[points.length - 1]!.x} ${padding.top + chartH} L ${points[0]!.x} ${padding.top + chartH} Z`}
|
|
220
|
+
fill={color}
|
|
221
|
+
opacity={0.1}
|
|
222
|
+
/>
|
|
223
|
+
)}
|
|
224
|
+
{path && <path d={path} fill="none" stroke={color} strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" />}
|
|
225
|
+
{showDots && points.map((p, pi) => <circle key={`dot-${s.data[pi]!.label}`} cx={p.x} cy={p.y} r={3} fill={color} />)}
|
|
226
|
+
{showValues &&
|
|
227
|
+
points.map((p, vi) => (
|
|
228
|
+
<text key={`val-${s.data[vi]!.label}`} x={p.x} y={p.y - 10} textAnchor="middle" className="fill-fg-normal" fontSize={10} fontWeight={600}>
|
|
229
|
+
{formatValue(s.data[vi]!.value)}
|
|
230
|
+
</text>
|
|
231
|
+
))}
|
|
232
|
+
</g>
|
|
246
233
|
);
|
|
247
|
-
})
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
234
|
+
})}
|
|
235
|
+
</svg>
|
|
236
|
+
|
|
237
|
+
{showTooltip &&
|
|
238
|
+
series.map((s, si) =>
|
|
239
|
+
s.data.map((d) => {
|
|
240
|
+
const xPct = (toX(labelIndex.get(d.label)!) / viewWidth) * 100;
|
|
241
|
+
const yPct = (toY(d.value) / height) * 100;
|
|
242
|
+
|
|
243
|
+
return (
|
|
244
|
+
<Tooltip key={`tip-${s.name ?? si}-${d.label}`} delayShow={0}>
|
|
245
|
+
<Tooltip.Trigger asChild>
|
|
246
|
+
<span className="absolute block -translate-x-1/2 -translate-y-1/2" style={{ left: `${xPct}%`, top: `${yPct}%`, width: 16, height: 16 }} />
|
|
247
|
+
</Tooltip.Trigger>
|
|
248
|
+
<Tooltip.Body>{tooltipText(d, s.name)}</Tooltip.Body>
|
|
249
|
+
</Tooltip>
|
|
250
|
+
);
|
|
251
|
+
})
|
|
252
|
+
)}
|
|
253
|
+
</div>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
LineChart.displayName = "LineChart";
|
|
@@ -2,6 +2,7 @@ import { Body } from "@sixthshift/design-system/body";
|
|
|
2
2
|
import { Emphasis } from "@sixthshift/design-system/emphasis";
|
|
3
3
|
import { Heading } from "@sixthshift/design-system/heading";
|
|
4
4
|
import { cn } from "@sixthshift/design-system/utils";
|
|
5
|
+
import * as React from "react";
|
|
5
6
|
import ReactMarkdown from "react-markdown";
|
|
6
7
|
|
|
7
8
|
export type MarkdownProps = {
|
|
@@ -9,8 +10,8 @@ export type MarkdownProps = {
|
|
|
9
10
|
className?: string;
|
|
10
11
|
};
|
|
11
12
|
|
|
12
|
-
export const Markdown = ({ children, className }
|
|
13
|
-
<div className={cn("flex flex-col", className)}>
|
|
13
|
+
export const Markdown = React.forwardRef<HTMLDivElement, MarkdownProps>(({ children, className }, ref) => (
|
|
14
|
+
<div ref={ref} className={cn("flex flex-col", className)}>
|
|
14
15
|
<ReactMarkdown
|
|
15
16
|
components={{
|
|
16
17
|
h1: ({ children }) => <Heading as="h3">{children}</Heading>,
|
|
@@ -36,5 +37,5 @@ export const Markdown = ({ children, className }: MarkdownProps) => (
|
|
|
36
37
|
{children}
|
|
37
38
|
</ReactMarkdown>
|
|
38
39
|
</div>
|
|
39
|
-
);
|
|
40
|
+
));
|
|
40
41
|
Markdown.displayName = "Markdown";
|
|
@@ -33,6 +33,22 @@ export type MessageProps = React.HTMLAttributes<HTMLDivElement> &
|
|
|
33
33
|
icon?: React.ReactNode;
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* A message is a live region, and the intent decides how rudely it interrupts.
|
|
38
|
+
* `danger` is the only intent that earns `role="alert"` — an assertive region
|
|
39
|
+
* cuts off whatever the screen reader was saying. Everything else is
|
|
40
|
+
* `role="status"` (polite), which is announced at the next natural pause. A
|
|
41
|
+
* success confirmation or a static "Note" callout stamped as `alert` trains
|
|
42
|
+
* users to ignore the role that actually matters. Consumers can override by
|
|
43
|
+
* passing their own `role` — `props` is spread after this.
|
|
44
|
+
*/
|
|
45
|
+
const intentRole = {
|
|
46
|
+
neutral: "status",
|
|
47
|
+
success: "status",
|
|
48
|
+
warning: "status",
|
|
49
|
+
danger: "alert",
|
|
50
|
+
} as const;
|
|
51
|
+
|
|
36
52
|
export const Message = React.forwardRef<HTMLDivElement, MessageProps>(({ className, intent = "neutral", size, title, icon, children, ...props }, ref) => {
|
|
37
53
|
const hasCompoundChildren = React.Children.toArray(children).some(
|
|
38
54
|
(child) =>
|
|
@@ -41,7 +57,7 @@ export const Message = React.forwardRef<HTMLDivElement, MessageProps>(({ classNa
|
|
|
41
57
|
);
|
|
42
58
|
|
|
43
59
|
return (
|
|
44
|
-
<div ref={ref} role="
|
|
60
|
+
<div ref={ref} role={intentRole[intent ?? "neutral"]} className={cn(messageVariants({ intent, size, className }))} {...props}>
|
|
45
61
|
{hasCompoundChildren ? (
|
|
46
62
|
children
|
|
47
63
|
) : (
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { cn } from "@sixthshift/design-system/utils";
|
|
2
|
-
import
|
|
2
|
+
import * as React from "react";
|
|
3
3
|
|
|
4
4
|
export type MetricListProps = {
|
|
5
5
|
/** Metric rows */
|
|
6
|
-
children: ReactNode;
|
|
6
|
+
children: React.ReactNode;
|
|
7
7
|
/** Additional CSS classes */
|
|
8
8
|
className?: string;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
export const MetricList = ({ children, className }
|
|
12
|
-
return
|
|
13
|
-
}
|
|
11
|
+
export const MetricList = React.forwardRef<HTMLDivElement, MetricListProps>(({ children, className }, ref) => {
|
|
12
|
+
return (
|
|
13
|
+
<div ref={ref} className={cn("flex flex-col gap-2 text-fg-subtle", className)}>
|
|
14
|
+
{children}
|
|
15
|
+
</div>
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
MetricList.displayName = "MetricList";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { FloatingFocusManager, FloatingOverlay, useDismiss, useFloating, useInteractions, useRole } from "@floating-ui/react";
|
|
2
2
|
import { useMergedFloatingRef, usePresence } from "@sixthshift/design-system/hooks";
|
|
3
3
|
import { cn } from "@sixthshift/design-system/utils";
|
|
4
|
-
import { type HTMLAttributes, type ReactNode, useCallback, useContext, useEffect, useMemo } from "react";
|
|
4
|
+
import { forwardRef, type HTMLAttributes, type ReactNode, useCallback, useContext, useEffect, useId, useMemo, useState } from "react";
|
|
5
5
|
import { ModalBody, ModalContext, ModalFooter, ModalHeader } from "./components";
|
|
6
6
|
|
|
7
7
|
// =============================================================================
|
|
8
8
|
// Types
|
|
9
9
|
// =============================================================================
|
|
10
10
|
|
|
11
|
-
export type ModalProps = Pick<HTMLAttributes<HTMLDivElement>, "className" | "style"> & {
|
|
11
|
+
export type ModalProps = Pick<HTMLAttributes<HTMLDivElement>, "className" | "style" | "aria-label" | "aria-labelledby" | "aria-describedby"> & {
|
|
12
12
|
/**
|
|
13
13
|
* Called when the modal's open state should change. Today Modal is mount-driven
|
|
14
14
|
* (parent conditionally renders), so this fires only with `false` on dismissal.
|
|
@@ -47,92 +47,124 @@ const sizeClasses = {
|
|
|
47
47
|
// Modal
|
|
48
48
|
// =============================================================================
|
|
49
49
|
|
|
50
|
-
const ModalRoot =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const handleClose = useCallback(() => {
|
|
66
|
-
hide(handleDismiss);
|
|
67
|
-
}, [handleDismiss, hide]);
|
|
68
|
-
|
|
69
|
-
const { refs, context } = useFloating({
|
|
70
|
-
open: true,
|
|
71
|
-
onOpenChange: (nextOpen) => {
|
|
72
|
-
if (!nextOpen) handleClose();
|
|
50
|
+
const ModalRoot = forwardRef<HTMLDivElement, ModalProps>(
|
|
51
|
+
(
|
|
52
|
+
{
|
|
53
|
+
onOpenChange,
|
|
54
|
+
size = "md",
|
|
55
|
+
className,
|
|
56
|
+
style,
|
|
57
|
+
children,
|
|
58
|
+
dismissable = true,
|
|
59
|
+
closable,
|
|
60
|
+
align = "center",
|
|
61
|
+
"aria-label": ariaLabel,
|
|
62
|
+
"aria-labelledby": ariaLabelledBy,
|
|
63
|
+
"aria-describedby": ariaDescribedBy,
|
|
73
64
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
65
|
+
ref
|
|
66
|
+
) => {
|
|
67
|
+
// Prefer explicit prop over context (context is set by useModal's overlay system)
|
|
68
|
+
const contextValue = useContext(ModalContext);
|
|
69
|
+
// Context provides a parameterless onClose for programmatic modals; adapt to the boolean shape.
|
|
70
|
+
const handleDismiss = useCallback(() => {
|
|
71
|
+
if (onOpenChange) onOpenChange(false);
|
|
72
|
+
else contextValue?.onClose();
|
|
73
|
+
}, [onOpenChange, contextValue]);
|
|
74
|
+
|
|
75
|
+
const { ref: presenceRef, state, isMounted, show, hide } = usePresence();
|
|
76
|
+
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
show();
|
|
79
|
+
}, [show]);
|
|
80
|
+
|
|
81
|
+
const handleClose = useCallback(() => {
|
|
82
|
+
hide(handleDismiss);
|
|
83
|
+
}, [handleDismiss, hide]);
|
|
84
|
+
|
|
85
|
+
const { refs, context } = useFloating({
|
|
86
|
+
open: true,
|
|
87
|
+
onOpenChange: (nextOpen) => {
|
|
88
|
+
if (!nextOpen) handleClose();
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const mergedRef = useMergedFloatingRef<HTMLDivElement>(refs, presenceRef, ref);
|
|
93
|
+
|
|
94
|
+
const dismiss = useDismiss(context, {
|
|
95
|
+
enabled: dismissable,
|
|
96
|
+
// OverlayContext handles escape key for proper stack ordering
|
|
97
|
+
escapeKey: false,
|
|
98
|
+
outsidePress: true,
|
|
99
|
+
outsidePressEvent: "mousedown",
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const role = useRole(context, {
|
|
103
|
+
role: "dialog",
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const { getFloatingProps } = useInteractions([dismiss, role]);
|
|
107
|
+
|
|
108
|
+
// The dialog names itself from its header. `Modal.Header` stamps `titleId`
|
|
109
|
+
// on itself and reports back, so a headerless modal falls through to the
|
|
110
|
+
// caller's `aria-label` instead of referencing an id that isn't there.
|
|
111
|
+
const titleId = useId();
|
|
112
|
+
const [hasTitle, setHasTitle] = useState(false);
|
|
113
|
+
const registerTitle = useCallback((present: boolean) => setHasTitle(present), []);
|
|
114
|
+
|
|
115
|
+
// `aria-labelledby` beats `aria-label` in the name computation, so a caller
|
|
116
|
+
// who passes a label must not also be pointed at the header — they would
|
|
117
|
+
// never see their own string win.
|
|
118
|
+
const labelledBy = ariaLabelledBy ?? (ariaLabel || !hasTitle ? undefined : titleId);
|
|
119
|
+
|
|
120
|
+
const modalContextValue = useMemo(() => ({ onClose: handleClose, closable, titleId, registerTitle }), [closable, handleClose, titleId, registerTitle]);
|
|
121
|
+
|
|
122
|
+
if (!isMounted) return null;
|
|
123
|
+
|
|
124
|
+
const isEntering = state === "entering";
|
|
125
|
+
const isExiting = state === "exiting";
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<FloatingFocusManager context={context} modal>
|
|
129
|
+
<FloatingOverlay lockScroll className={cn("fixed inset-0 z-modal bg-bg-overlay", isEntering && "animate-fade-in", isExiting && "animate-fade-out")}>
|
|
130
|
+
<div
|
|
131
|
+
ref={mergedRef}
|
|
132
|
+
role="dialog"
|
|
133
|
+
aria-modal="true"
|
|
134
|
+
aria-label={ariaLabel}
|
|
135
|
+
aria-labelledby={labelledBy}
|
|
136
|
+
aria-describedby={ariaDescribedBy}
|
|
137
|
+
tabIndex={-1}
|
|
138
|
+
data-state={state}
|
|
139
|
+
className={cn(
|
|
140
|
+
"fixed flex flex-col overflow-hidden outline-hidden",
|
|
141
|
+
"rounded-xl border border-border-normal bg-bg-normal",
|
|
142
|
+
// Size
|
|
143
|
+
sizeClasses[size],
|
|
144
|
+
// Cap height so ModalBody scrolls instead of overflowing the viewport
|
|
145
|
+
"max-h-[95%]",
|
|
146
|
+
// Mobile: slide up from bottom, full width
|
|
147
|
+
"max-sm:inset-x-0 max-sm:bottom-0 max-sm:rounded-b-none",
|
|
148
|
+
isEntering && "max-sm:animate-slide-up-in",
|
|
149
|
+
isExiting && "max-sm:animate-slide-up-out",
|
|
150
|
+
// Desktop: horizontal center + vertical alignment
|
|
151
|
+
"sm:left-1/2 sm:-translate-x-1/2",
|
|
152
|
+
align === "center" && "sm:top-1/2 sm:-translate-y-1/2",
|
|
153
|
+
align === "top" && "sm:top-[15vh]",
|
|
154
|
+
isEntering && "sm:animate-fade-in",
|
|
155
|
+
isExiting && "sm:animate-fade-out",
|
|
156
|
+
className
|
|
157
|
+
)}
|
|
158
|
+
style={style}
|
|
159
|
+
{...getFloatingProps({})}
|
|
160
|
+
>
|
|
161
|
+
<ModalContext.Provider value={modalContextValue}>{children}</ModalContext.Provider>
|
|
162
|
+
</div>
|
|
163
|
+
</FloatingOverlay>
|
|
164
|
+
</FloatingFocusManager>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
);
|
|
136
168
|
ModalRoot.displayName = "Modal";
|
|
137
169
|
|
|
138
170
|
// =============================================================================
|
|
@@ -9,6 +9,20 @@ export type OnClose = () => void;
|
|
|
9
9
|
interface ModalContextValue {
|
|
10
10
|
onClose: OnClose;
|
|
11
11
|
closable?: boolean | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* The id `Modal.Header` stamps on itself so the dialog can name itself from
|
|
14
|
+
* its own title. A dialog with no accessible name is announced as just
|
|
15
|
+
* "dialog", which tells a screen-reader user nothing about what interrupted
|
|
16
|
+
* them.
|
|
17
|
+
*/
|
|
18
|
+
titleId?: string;
|
|
19
|
+
/**
|
|
20
|
+
* The header reports its presence, because a headerless modal must not point
|
|
21
|
+
* `aria-labelledby` at an element that never rendered — a dangling reference
|
|
22
|
+
* is worse than no reference at all (it resolves to an empty name and axe
|
|
23
|
+
* flags it as an invalid attribute value).
|
|
24
|
+
*/
|
|
25
|
+
registerTitle?: (present: boolean) => void;
|
|
12
26
|
}
|
|
13
27
|
|
|
14
28
|
export const ModalContext = createContext<ModalContextValue | null>(null);
|