@pitchfork-ui/react 0.2.0 → 0.7.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/dist/components/Accordion/Accordion.css +85 -0
- package/dist/components/Accordion/Accordion2.js +96 -0
- package/dist/components/Alert/Alert.css +29 -1
- package/dist/components/Alert/Alert2.js +4 -2
- package/dist/components/Avatar/Avatar.css +1 -1
- package/dist/components/BadgeGroup/BadgeGroup.css +4 -4
- package/dist/components/Button/Button.css +4 -4
- package/dist/components/ButtonGroup/ButtonGroup.css +2 -2
- package/dist/components/Carousel/Carousel.css +4 -2
- package/dist/components/Carousel/Carousel2.js +89 -76
- package/dist/components/CodeSnippet/CodeSnippet.css +2 -2
- package/dist/components/ContentDivider/ContentDivider.css +2 -2
- package/dist/components/DatePicker/DatePicker.css +1 -1
- package/dist/components/DatePicker/DatePicker2.js +3 -3
- package/dist/components/Dropdown/Dropdown.css +19 -2
- package/dist/components/Dropdown/Dropdown2.js +2 -3
- package/dist/components/GaugeChart/GaugeChart.css +18 -1
- package/dist/components/GaugeChart/GaugeChart2.js +5 -4
- package/dist/components/Heatmap/Heatmap.css +104 -0
- package/dist/components/Heatmap/Heatmap2.js +160 -0
- package/dist/components/InlineCTA/InlineCTA.css +58 -0
- package/dist/components/InlineCTA/InlineCTA2.js +14 -2
- package/dist/components/Modal/Modal.css +62 -0
- package/dist/components/Modal/Modal2.js +8 -6
- package/dist/components/MultiSelect/MultiSelect.css +19 -2
- package/dist/components/MultiSelect/MultiSelect2.js +3 -4
- package/dist/components/Notification/Notification.css +59 -4
- package/dist/components/Notification/Notification2.js +4 -2
- package/dist/components/Pagination/Pagination.css +5 -2
- package/dist/components/PieChart/PieChart.css +34 -0
- package/dist/components/PieChart/PieChart2.js +1 -1
- package/dist/components/ProgressIndicators/ProgressIndicators.css +20 -2
- package/dist/components/ProgressIndicators/ProgressIndicators2.js +4 -1
- package/dist/components/ProgressSteps/ProgressSteps.css +20 -3
- package/dist/components/RadarChart/RadarChart.css +22 -0
- package/dist/components/RadarChart/RadarChart2.js +19 -13
- package/dist/components/RichTextEditor/RichTextEditor.css +1 -1
- package/dist/components/Select/Select.css +21 -2
- package/dist/components/Select/Select2.js +3 -4
- package/dist/components/SidebarNavigation/SidebarNavigation.css +1 -1
- package/dist/components/SlideoutMenu/SlideoutMenu.css +2 -2
- package/dist/components/Sparkline/Sparkline.css +48 -0
- package/dist/components/Sparkline/Sparkline2.js +3 -2
- package/dist/components/Table/Table.css +4 -4
- package/dist/components/Tabs/Tabs.css +31 -5
- package/dist/components/Tabs/Tabs2.js +51 -4
- package/dist/components/Tag/Tag.css +1 -1
- package/dist/components/Tooltip/Tooltip.css +35 -0
- package/dist/components/Tooltip/Tooltip2.js +4 -4
- package/dist/components/TreeView/TreeView.css +2 -2
- package/dist/hooks/useExitAnimation.js +25 -0
- package/dist/hooks/usePresence.js +31 -0
- package/dist/index.cjs +834 -454
- package/dist/index.js +12 -8
- package/dist/src/components/Accordion/Accordion.d.ts +20 -0
- package/dist/src/components/Accordion/Accordion.test.d.ts +1 -0
- package/dist/src/components/Accordion/index.d.ts +1 -0
- package/dist/src/components/Heatmap/Heatmap.d.ts +28 -0
- package/dist/src/components/Heatmap/Heatmap.test.d.ts +1 -0
- package/dist/src/components/Heatmap/index.d.ts +1 -0
- package/dist/src/components/InlineCTA/InlineCTA.d.ts +2 -0
- package/dist/src/components/Sparkline/Sparkline.d.ts +2 -0
- package/dist/src/hooks/index.d.ts +2 -0
- package/dist/src/hooks/useExitAnimation.d.ts +18 -0
- package/dist/src/hooks/usePresence.d.ts +13 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/styles/theme.css +47 -13
- package/dist/styles.css +767 -66
- package/package.json +1 -1
- package/theme.starter.css +4 -3
|
@@ -7,8 +7,7 @@ var GaugeChart = forwardRef(function GaugeChart({ className, value, max = 100, c
|
|
|
7
7
|
const progress = max > 0 ? Math.min(Math.max(value, 0), max) / max : 0;
|
|
8
8
|
const radius = (size - strokeWidth) / 2;
|
|
9
9
|
const circumference = 2 * Math.PI * radius;
|
|
10
|
-
const
|
|
11
|
-
const gap = circumference - filled;
|
|
10
|
+
const offset = circumference - progress * circumference;
|
|
12
11
|
const center = size / 2;
|
|
13
12
|
const pct = Math.round(progress * 100);
|
|
14
13
|
const defaultLabel = `${pct}%`;
|
|
@@ -48,10 +47,12 @@ var GaugeChart = forwardRef(function GaugeChart({ className, value, max = 100, c
|
|
|
48
47
|
stroke: colorVar,
|
|
49
48
|
strokeWidth,
|
|
50
49
|
strokeLinecap: "round",
|
|
51
|
-
strokeDasharray:
|
|
50
|
+
strokeDasharray: circumference,
|
|
52
51
|
style: {
|
|
53
52
|
transform: "rotate(-90deg)",
|
|
54
|
-
transformOrigin: `${center}px ${center}px
|
|
53
|
+
transformOrigin: `${center}px ${center}px`,
|
|
54
|
+
"--pf-gauge-circumference": circumference,
|
|
55
|
+
"--pf-gauge-offset": offset
|
|
55
56
|
},
|
|
56
57
|
className: "pf-gauge__fill"
|
|
57
58
|
})]
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
.pf-heatmap {
|
|
2
|
+
display: inline-block;
|
|
3
|
+
max-width: 100%;
|
|
4
|
+
/* A full year is wider than small screens — scroll horizontally instead of
|
|
5
|
+
overflowing the page. */
|
|
6
|
+
overflow-x: auto;
|
|
7
|
+
font-family: var(--font-family-sans);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.pf-heatmap__empty {
|
|
11
|
+
color: var(--color-semantic-text-muted);
|
|
12
|
+
font-size: var(--font-size-sm);
|
|
13
|
+
padding: var(--space-4);
|
|
14
|
+
text-align: center;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.pf-heatmap__body {
|
|
18
|
+
display: flex;
|
|
19
|
+
gap: var(--pf-heatmap-cell-gap);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.pf-heatmap__weekdays {
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.pf-heatmap__weekday-spacer {
|
|
28
|
+
display: block;
|
|
29
|
+
height: calc(var(--font-size-xs) + var(--space-1));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.pf-heatmap__weekday-grid {
|
|
33
|
+
display: grid;
|
|
34
|
+
grid-template-rows: repeat(7, var(--pf-heatmap-cell-size));
|
|
35
|
+
gap: var(--pf-heatmap-cell-gap);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.pf-heatmap__weekday {
|
|
39
|
+
align-items: center;
|
|
40
|
+
color: var(--pf-heatmap-label-color);
|
|
41
|
+
display: flex;
|
|
42
|
+
font-size: var(--font-size-xs);
|
|
43
|
+
line-height: 1;
|
|
44
|
+
padding-inline-end: var(--space-1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.pf-heatmap__main {
|
|
48
|
+
display: flex;
|
|
49
|
+
flex-direction: column;
|
|
50
|
+
gap: var(--space-1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.pf-heatmap__months {
|
|
54
|
+
display: grid;
|
|
55
|
+
gap: var(--pf-heatmap-cell-gap);
|
|
56
|
+
height: var(--font-size-xs);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.pf-heatmap__month {
|
|
60
|
+
color: var(--pf-heatmap-label-color);
|
|
61
|
+
font-size: var(--font-size-xs);
|
|
62
|
+
line-height: 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.pf-heatmap__grid {
|
|
66
|
+
display: grid;
|
|
67
|
+
grid-template-rows: repeat(7, var(--pf-heatmap-cell-size));
|
|
68
|
+
grid-auto-flow: column;
|
|
69
|
+
grid-auto-columns: var(--pf-heatmap-cell-size);
|
|
70
|
+
gap: var(--pf-heatmap-cell-gap);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.pf-heatmap__cell {
|
|
74
|
+
border-radius: var(--pf-heatmap-cell-radius);
|
|
75
|
+
height: var(--pf-heatmap-cell-size);
|
|
76
|
+
width: var(--pf-heatmap-cell-size);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.pf-heatmap__cell--empty {
|
|
80
|
+
background: transparent;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* Staggered fade-in on mount — per-column animation-delay is set inline so
|
|
84
|
+
the grid wipes in left-to-right (oldest week → newest). */
|
|
85
|
+
.pf-heatmap__cell {
|
|
86
|
+
animation: pf-heatmap-cell-in var(--duration-moderate) var(--easing-decelerate) both;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@keyframes pf-heatmap-cell-in {
|
|
90
|
+
from {
|
|
91
|
+
opacity: 0;
|
|
92
|
+
transform: scale(0.6);
|
|
93
|
+
}
|
|
94
|
+
to {
|
|
95
|
+
opacity: 1;
|
|
96
|
+
transform: scale(1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@media (prefers-reduced-motion: reduce) {
|
|
101
|
+
.pf-heatmap__cell {
|
|
102
|
+
animation: none;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { cx } from "../../utils/cx.js";
|
|
2
|
+
import './Heatmap.css';/* empty css */
|
|
3
|
+
import { forwardRef } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/Heatmap/Heatmap.tsx
|
|
6
|
+
var MONTHS = [
|
|
7
|
+
"Jan",
|
|
8
|
+
"Feb",
|
|
9
|
+
"Mar",
|
|
10
|
+
"Apr",
|
|
11
|
+
"May",
|
|
12
|
+
"Jun",
|
|
13
|
+
"Jul",
|
|
14
|
+
"Aug",
|
|
15
|
+
"Sep",
|
|
16
|
+
"Oct",
|
|
17
|
+
"Nov",
|
|
18
|
+
"Dec"
|
|
19
|
+
];
|
|
20
|
+
var WEEKDAYS = [
|
|
21
|
+
"Sun",
|
|
22
|
+
"Mon",
|
|
23
|
+
"Tue",
|
|
24
|
+
"Wed",
|
|
25
|
+
"Thu",
|
|
26
|
+
"Fri",
|
|
27
|
+
"Sat"
|
|
28
|
+
];
|
|
29
|
+
function parseISO(s) {
|
|
30
|
+
const [y, m, d] = s.split("-").map(Number);
|
|
31
|
+
return new Date(y, m - 1, d);
|
|
32
|
+
}
|
|
33
|
+
function toISO(d) {
|
|
34
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
35
|
+
}
|
|
36
|
+
function addDays(d, n) {
|
|
37
|
+
const r = new Date(d);
|
|
38
|
+
r.setDate(r.getDate() + n);
|
|
39
|
+
return r;
|
|
40
|
+
}
|
|
41
|
+
var Heatmap = forwardRef(function Heatmap({ className, data, startDate, endDate, levels = 5, weekStartsOn = 0, cellSize = 12, cellGap = 3, showWeekdayLabels = true, showMonthLabels = true, valueFormatter, label, emptyLabel = "No data", style, ...props }, ref) {
|
|
42
|
+
const sortedDates = data.map((d) => d.date).sort();
|
|
43
|
+
if (!Boolean(startDate || endDate || data.length)) return /* @__PURE__ */ jsx("div", {
|
|
44
|
+
ref,
|
|
45
|
+
className: cx("pf-heatmap", className),
|
|
46
|
+
...props,
|
|
47
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
48
|
+
className: "pf-heatmap__empty",
|
|
49
|
+
children: emptyLabel
|
|
50
|
+
})
|
|
51
|
+
});
|
|
52
|
+
const valueByDate = new Map(data.map((d) => [d.date, d.value]));
|
|
53
|
+
const maxValue = data.reduce((max, d) => Math.max(max, d.value), 0);
|
|
54
|
+
const total = data.reduce((sum, d) => sum + d.value, 0);
|
|
55
|
+
const levelCount = Math.max(2, levels);
|
|
56
|
+
const start = parseISO(startDate ?? sortedDates[0]);
|
|
57
|
+
const end = parseISO(endDate ?? sortedDates[sortedDates.length - 1]);
|
|
58
|
+
const gridStart = addDays(start, -((start.getDay() - weekStartsOn + 7) % 7));
|
|
59
|
+
const weeks = [];
|
|
60
|
+
let cursor = gridStart;
|
|
61
|
+
while (cursor <= end) {
|
|
62
|
+
const week = [];
|
|
63
|
+
for (let i = 0; i < 7; i++) {
|
|
64
|
+
week.push({
|
|
65
|
+
iso: toISO(cursor),
|
|
66
|
+
date: new Date(cursor),
|
|
67
|
+
inRange: cursor >= start && cursor <= end
|
|
68
|
+
});
|
|
69
|
+
cursor = addDays(cursor, 1);
|
|
70
|
+
}
|
|
71
|
+
weeks.push(week);
|
|
72
|
+
}
|
|
73
|
+
function levelFor(value) {
|
|
74
|
+
if (value <= 0 || maxValue <= 0) return 0;
|
|
75
|
+
return Math.min(levelCount - 1, Math.max(1, Math.ceil(value / maxValue * (levelCount - 1))));
|
|
76
|
+
}
|
|
77
|
+
function cellColor(level) {
|
|
78
|
+
if (level === 0) return "var(--pf-heatmap-empty)";
|
|
79
|
+
return `color-mix(in srgb, var(--pf-heatmap-color) ${Math.round(level / (levelCount - 1) * 100)}%, var(--pf-heatmap-empty))`;
|
|
80
|
+
}
|
|
81
|
+
const monthLabels = [];
|
|
82
|
+
let lastMonth = -1;
|
|
83
|
+
weeks.forEach((week, col) => {
|
|
84
|
+
const firstInRange = week.find((c) => c.inRange);
|
|
85
|
+
if (!firstInRange) return;
|
|
86
|
+
const month = firstInRange.date.getMonth();
|
|
87
|
+
if (month !== lastMonth) {
|
|
88
|
+
monthLabels.push({
|
|
89
|
+
col: col + 1,
|
|
90
|
+
label: MONTHS[month]
|
|
91
|
+
});
|
|
92
|
+
lastMonth = month;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
const styleVars = {
|
|
96
|
+
"--pf-heatmap-cell-size": `${cellSize}px`,
|
|
97
|
+
"--pf-heatmap-cell-gap": `${cellGap}px`,
|
|
98
|
+
...style
|
|
99
|
+
};
|
|
100
|
+
const ariaLabel = label ?? `Activity heatmap from ${toISO(start)} to ${toISO(end)}, ${total} total`;
|
|
101
|
+
return /* @__PURE__ */ jsx("div", {
|
|
102
|
+
ref,
|
|
103
|
+
className: cx("pf-heatmap", className),
|
|
104
|
+
style: styleVars,
|
|
105
|
+
role: "img",
|
|
106
|
+
"aria-label": ariaLabel,
|
|
107
|
+
...props,
|
|
108
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
109
|
+
className: "pf-heatmap__body",
|
|
110
|
+
children: [showWeekdayLabels ? /* @__PURE__ */ jsxs("div", {
|
|
111
|
+
className: "pf-heatmap__weekdays",
|
|
112
|
+
children: [showMonthLabels ? /* @__PURE__ */ jsx("span", {
|
|
113
|
+
className: "pf-heatmap__weekday-spacer",
|
|
114
|
+
"aria-hidden": "true"
|
|
115
|
+
}) : null, /* @__PURE__ */ jsx("div", {
|
|
116
|
+
className: "pf-heatmap__weekday-grid",
|
|
117
|
+
children: Array.from({ length: 7 }, (_, i) => {
|
|
118
|
+
const dow = (weekStartsOn + i) % 7;
|
|
119
|
+
return /* @__PURE__ */ jsx("span", {
|
|
120
|
+
className: "pf-heatmap__weekday",
|
|
121
|
+
children: i % 2 === 1 ? WEEKDAYS[dow] : ""
|
|
122
|
+
}, i);
|
|
123
|
+
})
|
|
124
|
+
})]
|
|
125
|
+
}) : null, /* @__PURE__ */ jsxs("div", {
|
|
126
|
+
className: "pf-heatmap__main",
|
|
127
|
+
children: [showMonthLabels ? /* @__PURE__ */ jsx("div", {
|
|
128
|
+
className: "pf-heatmap__months",
|
|
129
|
+
style: { gridTemplateColumns: `repeat(${weeks.length}, var(--pf-heatmap-cell-size))` },
|
|
130
|
+
"aria-hidden": "true",
|
|
131
|
+
children: monthLabels.map((m) => /* @__PURE__ */ jsx("span", {
|
|
132
|
+
className: "pf-heatmap__month",
|
|
133
|
+
style: { gridColumnStart: m.col },
|
|
134
|
+
children: m.label
|
|
135
|
+
}, `${m.label}-${m.col}`))
|
|
136
|
+
}) : null, /* @__PURE__ */ jsx("div", {
|
|
137
|
+
className: "pf-heatmap__grid",
|
|
138
|
+
children: weeks.flatMap((week, wi) => week.map((cell, di) => {
|
|
139
|
+
if (!cell.inRange) return /* @__PURE__ */ jsx("span", { className: "pf-heatmap__cell pf-heatmap__cell--empty" }, `${wi}-${di}`);
|
|
140
|
+
const value = valueByDate.get(cell.iso) ?? 0;
|
|
141
|
+
const level = levelFor(value);
|
|
142
|
+
const title = valueFormatter ? valueFormatter(value, cell.iso) : `${cell.iso}: ${value}`;
|
|
143
|
+
return /* @__PURE__ */ jsx("span", {
|
|
144
|
+
className: "pf-heatmap__cell",
|
|
145
|
+
style: {
|
|
146
|
+
background: cellColor(level),
|
|
147
|
+
animationDelay: `${wi * 8}ms`
|
|
148
|
+
},
|
|
149
|
+
title,
|
|
150
|
+
"data-level": level
|
|
151
|
+
}, `${wi}-${di}`);
|
|
152
|
+
}))
|
|
153
|
+
})]
|
|
154
|
+
})]
|
|
155
|
+
})
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
Heatmap.displayName = "Heatmap";
|
|
159
|
+
//#endregion
|
|
160
|
+
export { Heatmap };
|
|
@@ -7,6 +7,64 @@
|
|
|
7
7
|
gap: var(--space-3);
|
|
8
8
|
grid-template-columns: auto 1fr;
|
|
9
9
|
padding: var(--space-3);
|
|
10
|
+
position: relative;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* Leave room for the centered dismiss button so content/action don't crowd it */
|
|
14
|
+
.pf-inline-cta--dismissible {
|
|
15
|
+
padding-inline-end: var(--space-12);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.pf-inline-cta__dismiss {
|
|
19
|
+
align-items: center;
|
|
20
|
+
background: transparent;
|
|
21
|
+
border: 0;
|
|
22
|
+
border-radius: var(--radius-sm);
|
|
23
|
+
color: var(--color-semantic-text-muted);
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
display: inline-flex;
|
|
26
|
+
height: 28px;
|
|
27
|
+
justify-content: center;
|
|
28
|
+
position: absolute;
|
|
29
|
+
inset-inline-end: var(--space-3);
|
|
30
|
+
top: 50%;
|
|
31
|
+
transform: translateY(-50%);
|
|
32
|
+
width: 28px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.pf-inline-cta__dismiss:hover,
|
|
36
|
+
.pf-inline-cta__dismiss:focus-visible {
|
|
37
|
+
background: var(--color-semantic-background-subtle);
|
|
38
|
+
color: var(--color-semantic-text-default);
|
|
39
|
+
outline: none;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Exit: fade and collapse so surrounding content reflows when dismissed. */
|
|
43
|
+
.pf-inline-cta--exiting {
|
|
44
|
+
animation: pf-inline-cta-out var(--duration-moderate) var(--easing-accelerate) forwards;
|
|
45
|
+
overflow: hidden;
|
|
46
|
+
pointer-events: none;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@keyframes pf-inline-cta-out {
|
|
50
|
+
from {
|
|
51
|
+
opacity: 1;
|
|
52
|
+
max-height: 480px;
|
|
53
|
+
}
|
|
54
|
+
to {
|
|
55
|
+
opacity: 0;
|
|
56
|
+
max-height: 0;
|
|
57
|
+
margin-top: 0;
|
|
58
|
+
margin-bottom: 0;
|
|
59
|
+
padding-top: 0;
|
|
60
|
+
padding-bottom: 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@media (prefers-reduced-motion: reduce) {
|
|
65
|
+
.pf-inline-cta--exiting {
|
|
66
|
+
animation: none;
|
|
67
|
+
}
|
|
10
68
|
}
|
|
11
69
|
|
|
12
70
|
@media (min-width: 768px) {
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
+
import { useExitAnimation } from "../../hooks/useExitAnimation.js";
|
|
1
2
|
import { cx } from "../../utils/cx.js";
|
|
2
3
|
import { Icon } from "../Icon/Icon2.js";
|
|
3
4
|
import './InlineCTA.css';/* empty css */
|
|
4
5
|
import { forwardRef } from "react";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
//#region src/components/InlineCTA/InlineCTA.tsx
|
|
7
|
-
var InlineCTA = forwardRef(function InlineCTA({ className, heading, description, action, icon, iconName = "circle-question", tone = "default", children, ...props }, ref) {
|
|
8
|
+
var InlineCTA = forwardRef(function InlineCTA({ className, heading, description, action, icon, iconName = "circle-question", tone = "default", dismissible = false, onDismiss, children, ...props }, ref) {
|
|
8
9
|
const resolvedIcon = icon ?? /* @__PURE__ */ jsx(Icon, {
|
|
9
10
|
name: iconName,
|
|
10
11
|
"aria-hidden": true
|
|
11
12
|
});
|
|
13
|
+
const { isExiting, startExit } = useExitAnimation({ onExited: onDismiss });
|
|
12
14
|
return /* @__PURE__ */ jsxs("div", {
|
|
13
15
|
ref,
|
|
14
|
-
className: cx("pf-inline-cta", `pf-inline-cta--${tone}`, className),
|
|
16
|
+
className: cx("pf-inline-cta", `pf-inline-cta--${tone}`, dismissible && "pf-inline-cta--dismissible", isExiting && "pf-inline-cta--exiting", className),
|
|
15
17
|
...props,
|
|
16
18
|
children: [
|
|
17
19
|
/* @__PURE__ */ jsx("span", {
|
|
@@ -36,6 +38,16 @@ var InlineCTA = forwardRef(function InlineCTA({ className, heading, description,
|
|
|
36
38
|
action ? /* @__PURE__ */ jsx("div", {
|
|
37
39
|
className: "pf-inline-cta__action",
|
|
38
40
|
children: action
|
|
41
|
+
}) : null,
|
|
42
|
+
dismissible ? /* @__PURE__ */ jsx("button", {
|
|
43
|
+
type: "button",
|
|
44
|
+
className: "pf-inline-cta__dismiss",
|
|
45
|
+
"aria-label": "Dismiss",
|
|
46
|
+
onClick: startExit,
|
|
47
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
48
|
+
name: "circle-xmark",
|
|
49
|
+
"aria-hidden": true
|
|
50
|
+
})
|
|
39
51
|
}) : null
|
|
40
52
|
]
|
|
41
53
|
});
|
|
@@ -89,6 +89,8 @@
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
.pf-modal__body {
|
|
92
|
+
display: grid;
|
|
93
|
+
gap: var(--space-4);
|
|
92
94
|
overflow-y: auto;
|
|
93
95
|
padding: var(--space-3);
|
|
94
96
|
}
|
|
@@ -134,3 +136,63 @@
|
|
|
134
136
|
color: var(--pf-modal-text);
|
|
135
137
|
outline: none;
|
|
136
138
|
}
|
|
139
|
+
|
|
140
|
+
/* Entrance animation — uses motion tokens via theme aliases */
|
|
141
|
+
@keyframes pf-modal-overlay-in {
|
|
142
|
+
from {
|
|
143
|
+
opacity: 0;
|
|
144
|
+
}
|
|
145
|
+
to {
|
|
146
|
+
opacity: 1;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@keyframes pf-modal-in {
|
|
151
|
+
from {
|
|
152
|
+
opacity: 0;
|
|
153
|
+
transform: translateY(8px) scale(0.98);
|
|
154
|
+
}
|
|
155
|
+
to {
|
|
156
|
+
opacity: 1;
|
|
157
|
+
transform: translateY(0) scale(1);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.pf-modal__overlay {
|
|
162
|
+
animation: pf-modal-overlay-in var(--pf-transition-fast);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.pf-modal {
|
|
166
|
+
animation: pf-modal-in var(--pf-transition-enter);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* Exit animation — plays while the dialog is being dismissed (presence handling) */
|
|
170
|
+
@keyframes pf-modal-overlay-out {
|
|
171
|
+
to {
|
|
172
|
+
opacity: 0;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@keyframes pf-modal-out {
|
|
177
|
+
to {
|
|
178
|
+
opacity: 0;
|
|
179
|
+
transform: translateY(8px) scale(0.98);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.pf-modal__overlay--exiting {
|
|
184
|
+
animation: pf-modal-overlay-out var(--pf-transition-fast) forwards;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.pf-modal--exiting {
|
|
188
|
+
animation: pf-modal-out var(--pf-transition-fast) forwards;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@media (prefers-reduced-motion: reduce) {
|
|
192
|
+
.pf-modal__overlay,
|
|
193
|
+
.pf-modal,
|
|
194
|
+
.pf-modal__overlay--exiting,
|
|
195
|
+
.pf-modal--exiting {
|
|
196
|
+
animation: none;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { useFocusTrap } from "../../hooks/useFocusTrap.js";
|
|
2
|
+
import { usePresence } from "../../hooks/usePresence.js";
|
|
1
3
|
import { cx } from "../../utils/cx.js";
|
|
2
4
|
import { Icon } from "../Icon/Icon2.js";
|
|
3
|
-
import { useFocusTrap } from "../../hooks/useFocusTrap.js";
|
|
4
5
|
import './Modal.css';/* empty css */
|
|
5
6
|
import { forwardRef, useEffect, useId, useImperativeHandle, useRef } from "react";
|
|
6
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -28,25 +29,26 @@ var Modal = forwardRef(function Modal({ className, open, onOpenChange, title, de
|
|
|
28
29
|
const titleId = useId();
|
|
29
30
|
const descriptionId = useId();
|
|
30
31
|
const dialogRef = useRef(null);
|
|
32
|
+
const { isMounted, isExiting } = usePresence(open);
|
|
31
33
|
useImperativeHandle(ref, () => dialogRef.current, []);
|
|
32
34
|
useEffect(() => {
|
|
33
|
-
if (!
|
|
35
|
+
if (!isMounted || typeof document === "undefined") return;
|
|
34
36
|
const originalOverflow = document.body.style.overflow;
|
|
35
37
|
document.body.style.overflow = "hidden";
|
|
36
38
|
return () => {
|
|
37
39
|
document.body.style.overflow = originalOverflow;
|
|
38
40
|
};
|
|
39
|
-
}, [
|
|
41
|
+
}, [isMounted]);
|
|
40
42
|
useFocusTrap({
|
|
41
43
|
containerRef: dialogRef,
|
|
42
44
|
enabled: open,
|
|
43
45
|
onEscape: () => onOpenChange?.(false)
|
|
44
46
|
});
|
|
45
|
-
if (!
|
|
47
|
+
if (!isMounted || typeof document === "undefined") return null;
|
|
46
48
|
return createPortal(/* @__PURE__ */ jsxs("div", {
|
|
47
49
|
className: "pf-modal__portal",
|
|
48
50
|
children: [/* @__PURE__ */ jsx("div", {
|
|
49
|
-
className: "pf-modal__overlay",
|
|
51
|
+
className: cx("pf-modal__overlay", isExiting && "pf-modal__overlay--exiting"),
|
|
50
52
|
onClick: () => {
|
|
51
53
|
if (closeOnOverlayClick) onOpenChange?.(false);
|
|
52
54
|
}
|
|
@@ -54,7 +56,7 @@ var Modal = forwardRef(function Modal({ className, open, onOpenChange, title, de
|
|
|
54
56
|
className: "pf-modal__viewport",
|
|
55
57
|
children: /* @__PURE__ */ jsxs("div", {
|
|
56
58
|
ref: dialogRef,
|
|
57
|
-
className: cx("pf-modal", `pf-modal--${size}`, className),
|
|
59
|
+
className: cx("pf-modal", `pf-modal--${size}`, isExiting && "pf-modal--exiting", className),
|
|
58
60
|
role: "dialog",
|
|
59
61
|
"aria-modal": "true",
|
|
60
62
|
"aria-labelledby": title ? titleId : void 0,
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
justify-content: space-between;
|
|
16
16
|
min-height: 40px;
|
|
17
17
|
padding: var(--space-1) var(--space-2) var(--space-1) var(--space-2);
|
|
18
|
-
text-align:
|
|
18
|
+
text-align: start;
|
|
19
19
|
width: 100%;
|
|
20
20
|
transition:
|
|
21
21
|
background 0.2s,
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
justify-content: center;
|
|
79
79
|
width: 20px;
|
|
80
80
|
transform-origin: center;
|
|
81
|
-
transition: transform
|
|
81
|
+
transition: transform var(--pf-transition-fast);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
.pf-multi-select__icon svg {
|
|
@@ -103,6 +103,19 @@
|
|
|
103
103
|
padding: var(--space-1);
|
|
104
104
|
position: fixed;
|
|
105
105
|
z-index: 1000;
|
|
106
|
+
transform-origin: top center;
|
|
107
|
+
animation: pf-multi-select-menu-in var(--duration-fast) var(--easing-decelerate);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@keyframes pf-multi-select-menu-in {
|
|
111
|
+
from {
|
|
112
|
+
opacity: 0;
|
|
113
|
+
transform: translateY(-4px) scaleY(0.96);
|
|
114
|
+
}
|
|
115
|
+
to {
|
|
116
|
+
opacity: 1;
|
|
117
|
+
transform: translateY(0) scaleY(1);
|
|
118
|
+
}
|
|
106
119
|
}
|
|
107
120
|
|
|
108
121
|
.pf-multi-select__option {
|
|
@@ -154,4 +167,8 @@
|
|
|
154
167
|
.pf-multi-select__icon {
|
|
155
168
|
transition: none;
|
|
156
169
|
}
|
|
170
|
+
|
|
171
|
+
.pf-multi-select__menu {
|
|
172
|
+
animation: none;
|
|
173
|
+
}
|
|
157
174
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Keys, composeDescribedBy, isActivationKey } from "../../a11y/index.js";
|
|
2
|
-
import { cx } from "../../utils/cx.js";
|
|
3
|
-
import { Icon } from "../Icon/Icon2.js";
|
|
4
|
-
import { FieldWrapper } from "../../utils/FieldWrapper.js";
|
|
5
2
|
import { useAnchoredPosition } from "../../hooks/useAnchoredPosition.js";
|
|
6
3
|
import { useComposedRefs } from "../../hooks/useComposedRefs.js";
|
|
7
4
|
import { useControllableState } from "../../hooks/useControllableState.js";
|
|
8
5
|
import { useDisclosure } from "../../hooks/useDisclosure.js";
|
|
9
6
|
import { useListNavigation } from "../../hooks/useListNavigation.js";
|
|
10
7
|
import { useOutsideInteraction } from "../../hooks/useOutsideInteraction.js";
|
|
8
|
+
import { cx } from "../../utils/cx.js";
|
|
9
|
+
import { Icon } from "../Icon/Icon2.js";
|
|
10
|
+
import { FieldWrapper } from "../../utils/FieldWrapper.js";
|
|
11
11
|
import './MultiSelect.css';/* empty css */
|
|
12
12
|
import { forwardRef, useEffect, useId, useMemo, useRef } from "react";
|
|
13
13
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -125,7 +125,6 @@ var MultiSelect = forwardRef(({ id, options, value, defaultValue, onValueChange,
|
|
|
125
125
|
"aria-haspopup": "listbox",
|
|
126
126
|
"aria-expanded": isOpen,
|
|
127
127
|
"aria-required": required || void 0,
|
|
128
|
-
"aria-controls": isOpen ? listboxId : void 0,
|
|
129
128
|
"aria-describedby": describedBy,
|
|
130
129
|
onClick: () => {
|
|
131
130
|
disclosure.toggle();
|
|
@@ -59,6 +59,45 @@
|
|
|
59
59
|
max-width: none;
|
|
60
60
|
padding: var(--space-3);
|
|
61
61
|
width: 100%;
|
|
62
|
+
animation: pf-notification-in var(--duration-moderate) var(--easing-decelerate);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@keyframes pf-notification-in {
|
|
66
|
+
from {
|
|
67
|
+
opacity: 0;
|
|
68
|
+
transform: translateX(12px);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* Exit: slide off to the right and collapse so stacked siblings reflow. */
|
|
73
|
+
.pf-notification--exiting {
|
|
74
|
+
animation: pf-notification-out var(--duration-moderate) var(--easing-accelerate) forwards;
|
|
75
|
+
overflow: hidden;
|
|
76
|
+
pointer-events: none;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@keyframes pf-notification-out {
|
|
80
|
+
from {
|
|
81
|
+
opacity: 1;
|
|
82
|
+
transform: translateX(0);
|
|
83
|
+
max-height: 480px;
|
|
84
|
+
}
|
|
85
|
+
to {
|
|
86
|
+
opacity: 0;
|
|
87
|
+
transform: translateX(100%);
|
|
88
|
+
max-height: 0;
|
|
89
|
+
margin-top: 0;
|
|
90
|
+
margin-bottom: 0;
|
|
91
|
+
padding-top: 0;
|
|
92
|
+
padding-bottom: 0;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@media (prefers-reduced-motion: reduce) {
|
|
97
|
+
.pf-notification,
|
|
98
|
+
.pf-notification--exiting {
|
|
99
|
+
animation: none;
|
|
100
|
+
}
|
|
62
101
|
}
|
|
63
102
|
|
|
64
103
|
@media (min-width: 768px) {
|
|
@@ -69,22 +108,38 @@
|
|
|
69
108
|
}
|
|
70
109
|
|
|
71
110
|
.pf-notification--info {
|
|
72
|
-
background: color-mix(
|
|
111
|
+
background: color-mix(
|
|
112
|
+
in srgb,
|
|
113
|
+
var(--pf-notification-info-bg) 45%,
|
|
114
|
+
var(--pf-notification-mix-base)
|
|
115
|
+
);
|
|
73
116
|
border-color: var(--pf-notification-info-border);
|
|
74
117
|
}
|
|
75
118
|
|
|
76
119
|
.pf-notification--success {
|
|
77
|
-
background: color-mix(
|
|
120
|
+
background: color-mix(
|
|
121
|
+
in srgb,
|
|
122
|
+
var(--pf-notification-success-bg) 45%,
|
|
123
|
+
var(--pf-notification-mix-base)
|
|
124
|
+
);
|
|
78
125
|
border-color: var(--pf-notification-success-border);
|
|
79
126
|
}
|
|
80
127
|
|
|
81
128
|
.pf-notification--warning {
|
|
82
|
-
background: color-mix(
|
|
129
|
+
background: color-mix(
|
|
130
|
+
in srgb,
|
|
131
|
+
var(--pf-notification-warning-bg) 45%,
|
|
132
|
+
var(--pf-notification-mix-base)
|
|
133
|
+
);
|
|
83
134
|
border-color: var(--pf-notification-warning-border);
|
|
84
135
|
}
|
|
85
136
|
|
|
86
137
|
.pf-notification--danger {
|
|
87
|
-
background: color-mix(
|
|
138
|
+
background: color-mix(
|
|
139
|
+
in srgb,
|
|
140
|
+
var(--pf-notification-danger-bg) 45%,
|
|
141
|
+
var(--pf-notification-mix-base)
|
|
142
|
+
);
|
|
88
143
|
border-color: var(--pf-notification-danger-border);
|
|
89
144
|
}
|
|
90
145
|
|