@refraction-ui/react 0.15.0 → 0.16.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/index.cjs +558 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +547 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/kanban-board/index.d.ts +98 -0
- package/dist/internal/react-kanban-board/index.d.ts +71 -0
- package/dist/internal/react-slot-picker/index.d.ts +31 -0
- package/dist/internal/react-sortable-list/index.d.ts +35 -0
- package/dist/internal/slot-picker/index.d.ts +77 -0
- package/package.json +4 -1
package/dist/index.cjs
CHANGED
|
@@ -28,8 +28,13 @@ var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
|
|
|
28
28
|
|
|
29
29
|
var __defProp = Object.defineProperty;
|
|
30
30
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
31
|
-
var __esm = (fn2, res) => function __init() {
|
|
32
|
-
|
|
31
|
+
var __esm = (fn2, res, err) => function __init() {
|
|
32
|
+
if (err) throw err[0];
|
|
33
|
+
try {
|
|
34
|
+
return fn2 && (res = (0, fn2[__getOwnPropNames(fn2)[0]])(fn2 = 0)), res;
|
|
35
|
+
} catch (e2) {
|
|
36
|
+
throw err = [e2], e2;
|
|
37
|
+
}
|
|
33
38
|
};
|
|
34
39
|
var __export = (target, all) => {
|
|
35
40
|
for (var name in all)
|
|
@@ -51926,6 +51931,552 @@ var AudienceFeatureCard = React11__namespace.forwardRef(({ kicker, title, body,
|
|
|
51926
51931
|
);
|
|
51927
51932
|
});
|
|
51928
51933
|
AudienceFeatureCard.displayName = "AudienceFeatureCard";
|
|
51934
|
+
|
|
51935
|
+
// ../sortable-list/dist/index.js
|
|
51936
|
+
function reorder(items, from, to2) {
|
|
51937
|
+
const len = items.length;
|
|
51938
|
+
if (len === 0 || from < 0 || from >= len || to2 < 0 || to2 >= len || from === to2) {
|
|
51939
|
+
return [...items];
|
|
51940
|
+
}
|
|
51941
|
+
const result = [...items];
|
|
51942
|
+
const [moved] = result.splice(from, 1);
|
|
51943
|
+
result.splice(to2, 0, moved);
|
|
51944
|
+
return result;
|
|
51945
|
+
}
|
|
51946
|
+
function getNextOrderIndex(current, key, count) {
|
|
51947
|
+
if (count <= 0) return current;
|
|
51948
|
+
const clamped = Math.max(0, Math.min(current, count - 1));
|
|
51949
|
+
switch (key) {
|
|
51950
|
+
case "ArrowUp":
|
|
51951
|
+
case "ArrowLeft":
|
|
51952
|
+
return Math.max(0, clamped - 1);
|
|
51953
|
+
case "ArrowDown":
|
|
51954
|
+
case "ArrowRight":
|
|
51955
|
+
return Math.min(count - 1, clamped + 1);
|
|
51956
|
+
case "Home":
|
|
51957
|
+
return 0;
|
|
51958
|
+
case "End":
|
|
51959
|
+
return count - 1;
|
|
51960
|
+
default:
|
|
51961
|
+
return clamped;
|
|
51962
|
+
}
|
|
51963
|
+
}
|
|
51964
|
+
function createSortableList() {
|
|
51965
|
+
return {
|
|
51966
|
+
ariaProps: {
|
|
51967
|
+
role: "list"
|
|
51968
|
+
},
|
|
51969
|
+
dataAttributes: {
|
|
51970
|
+
"data-component": "sortable-list"
|
|
51971
|
+
}
|
|
51972
|
+
};
|
|
51973
|
+
}
|
|
51974
|
+
var sortableListVariants = cva({
|
|
51975
|
+
base: "flex flex-col gap-1 w-full",
|
|
51976
|
+
variants: {
|
|
51977
|
+
disabled: {
|
|
51978
|
+
true: "opacity-50 pointer-events-none",
|
|
51979
|
+
false: ""
|
|
51980
|
+
}
|
|
51981
|
+
},
|
|
51982
|
+
defaultVariants: {
|
|
51983
|
+
disabled: "false"
|
|
51984
|
+
}
|
|
51985
|
+
});
|
|
51986
|
+
var sortableListRowVariants = cva({
|
|
51987
|
+
base: [
|
|
51988
|
+
"flex items-center gap-3 rounded-md border border-border bg-card px-3 py-2",
|
|
51989
|
+
"transition-opacity"
|
|
51990
|
+
].join(" "),
|
|
51991
|
+
variants: {
|
|
51992
|
+
dragging: {
|
|
51993
|
+
true: "opacity-50 ring-2 ring-ring",
|
|
51994
|
+
false: ""
|
|
51995
|
+
}
|
|
51996
|
+
},
|
|
51997
|
+
defaultVariants: {
|
|
51998
|
+
dragging: "false"
|
|
51999
|
+
}
|
|
52000
|
+
});
|
|
52001
|
+
var sortableListGripClass = "cursor-grab text-muted-foreground shrink-0 flex items-center focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background rounded";
|
|
52002
|
+
var sortableListContentClass = "flex-1 min-w-0";
|
|
52003
|
+
function SortableListInner({
|
|
52004
|
+
items,
|
|
52005
|
+
getKey,
|
|
52006
|
+
renderItem,
|
|
52007
|
+
onReorder,
|
|
52008
|
+
disabled = false,
|
|
52009
|
+
className,
|
|
52010
|
+
...props
|
|
52011
|
+
}, ref) {
|
|
52012
|
+
const dragFromRef = React11__namespace.useRef(null);
|
|
52013
|
+
const [draggingIndex, setDraggingIndex] = React11__namespace.useState(null);
|
|
52014
|
+
const { ariaProps, dataAttributes } = createSortableList();
|
|
52015
|
+
const handleDragStart = (index) => (event) => {
|
|
52016
|
+
if (disabled) {
|
|
52017
|
+
event.preventDefault();
|
|
52018
|
+
return;
|
|
52019
|
+
}
|
|
52020
|
+
dragFromRef.current = index;
|
|
52021
|
+
setDraggingIndex(index);
|
|
52022
|
+
event.dataTransfer.effectAllowed = "move";
|
|
52023
|
+
event.dataTransfer.setData("text/plain", String(index));
|
|
52024
|
+
};
|
|
52025
|
+
const handleDragOver = (event) => {
|
|
52026
|
+
event.preventDefault();
|
|
52027
|
+
event.dataTransfer.dropEffect = "move";
|
|
52028
|
+
};
|
|
52029
|
+
const handleDragEnter = (toIndex) => (event) => {
|
|
52030
|
+
event.preventDefault();
|
|
52031
|
+
if (disabled || dragFromRef.current === null || dragFromRef.current === toIndex) return;
|
|
52032
|
+
const next = reorder(items, dragFromRef.current, toIndex);
|
|
52033
|
+
dragFromRef.current = toIndex;
|
|
52034
|
+
setDraggingIndex(toIndex);
|
|
52035
|
+
onReorder?.(next);
|
|
52036
|
+
};
|
|
52037
|
+
const handleDrop = (event) => {
|
|
52038
|
+
event.preventDefault();
|
|
52039
|
+
};
|
|
52040
|
+
const handleDragEnd = () => {
|
|
52041
|
+
dragFromRef.current = null;
|
|
52042
|
+
setDraggingIndex(null);
|
|
52043
|
+
};
|
|
52044
|
+
const handleGripKeyDown = (index) => (event) => {
|
|
52045
|
+
if (disabled) return;
|
|
52046
|
+
const next = getNextOrderIndex(index, event.key, items.length);
|
|
52047
|
+
if (next !== index) {
|
|
52048
|
+
event.preventDefault();
|
|
52049
|
+
onReorder?.(reorder(items, index, next));
|
|
52050
|
+
}
|
|
52051
|
+
};
|
|
52052
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
52053
|
+
"div",
|
|
52054
|
+
{
|
|
52055
|
+
ref,
|
|
52056
|
+
className: cn(sortableListVariants({ disabled: disabled ? "true" : "false" }), className),
|
|
52057
|
+
...ariaProps,
|
|
52058
|
+
...dataAttributes,
|
|
52059
|
+
...props,
|
|
52060
|
+
children: items.map((item, index) => {
|
|
52061
|
+
const key = getKey(item, index);
|
|
52062
|
+
const isDragging = draggingIndex === index;
|
|
52063
|
+
const dragHandleProps = {
|
|
52064
|
+
"aria-label": "Reorder item",
|
|
52065
|
+
role: "button",
|
|
52066
|
+
tabIndex: 0,
|
|
52067
|
+
onKeyDown: handleGripKeyDown(index),
|
|
52068
|
+
onDragStart: handleDragStart(index)
|
|
52069
|
+
};
|
|
52070
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
52071
|
+
"div",
|
|
52072
|
+
{
|
|
52073
|
+
role: "listitem",
|
|
52074
|
+
draggable: !disabled,
|
|
52075
|
+
className: sortableListRowVariants({ dragging: isDragging ? "true" : "false" }),
|
|
52076
|
+
onDragOver: handleDragOver,
|
|
52077
|
+
onDragEnter: handleDragEnter(index),
|
|
52078
|
+
onDrop: handleDrop,
|
|
52079
|
+
onDragEnd: handleDragEnd,
|
|
52080
|
+
children: [
|
|
52081
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
52082
|
+
"button",
|
|
52083
|
+
{
|
|
52084
|
+
type: "button",
|
|
52085
|
+
"aria-label": dragHandleProps["aria-label"],
|
|
52086
|
+
role: dragHandleProps.role,
|
|
52087
|
+
tabIndex: dragHandleProps.tabIndex,
|
|
52088
|
+
onKeyDown: dragHandleProps.onKeyDown,
|
|
52089
|
+
onDragStart: dragHandleProps.onDragStart,
|
|
52090
|
+
className: sortableListGripClass,
|
|
52091
|
+
draggable: !disabled,
|
|
52092
|
+
disabled,
|
|
52093
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
52094
|
+
"svg",
|
|
52095
|
+
{
|
|
52096
|
+
width: "16",
|
|
52097
|
+
height: "16",
|
|
52098
|
+
viewBox: "0 0 16 16",
|
|
52099
|
+
fill: "none",
|
|
52100
|
+
"aria-hidden": "true",
|
|
52101
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
52102
|
+
"path",
|
|
52103
|
+
{
|
|
52104
|
+
d: `M2 4h12M2 8h12M2 12h12`,
|
|
52105
|
+
stroke: "currentColor",
|
|
52106
|
+
strokeWidth: "1.5",
|
|
52107
|
+
strokeLinecap: "round"
|
|
52108
|
+
}
|
|
52109
|
+
)
|
|
52110
|
+
}
|
|
52111
|
+
)
|
|
52112
|
+
}
|
|
52113
|
+
),
|
|
52114
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: sortableListContentClass, children: renderItem(item, { index, dragHandleProps }) })
|
|
52115
|
+
]
|
|
52116
|
+
},
|
|
52117
|
+
key
|
|
52118
|
+
);
|
|
52119
|
+
})
|
|
52120
|
+
}
|
|
52121
|
+
);
|
|
52122
|
+
}
|
|
52123
|
+
var SortableList = React11__namespace.forwardRef(SortableListInner);
|
|
52124
|
+
SortableList.displayName = "SortableList";
|
|
52125
|
+
|
|
52126
|
+
// ../kanban-board/dist/index.js
|
|
52127
|
+
function createKanbanBoard() {
|
|
52128
|
+
return {
|
|
52129
|
+
ariaProps: {
|
|
52130
|
+
role: "group",
|
|
52131
|
+
"aria-label": "Board"
|
|
52132
|
+
},
|
|
52133
|
+
dataAttributes: {
|
|
52134
|
+
"data-component": "kanban-board"
|
|
52135
|
+
}
|
|
52136
|
+
};
|
|
52137
|
+
}
|
|
52138
|
+
function cardsByColumn(cards, getColumnId, columns) {
|
|
52139
|
+
const map = /* @__PURE__ */ new Map();
|
|
52140
|
+
for (const col of columns) {
|
|
52141
|
+
map.set(col.id, []);
|
|
52142
|
+
}
|
|
52143
|
+
for (const card of cards) {
|
|
52144
|
+
const colId = getColumnId(card);
|
|
52145
|
+
const bucket = map.get(colId);
|
|
52146
|
+
if (bucket !== void 0) {
|
|
52147
|
+
bucket.push(card);
|
|
52148
|
+
}
|
|
52149
|
+
}
|
|
52150
|
+
return map;
|
|
52151
|
+
}
|
|
52152
|
+
function visibleAndOverflow(cards, cap = 5) {
|
|
52153
|
+
if (cards.length <= cap) {
|
|
52154
|
+
return { visible: cards, overflow: 0 };
|
|
52155
|
+
}
|
|
52156
|
+
return { visible: cards.slice(0, cap), overflow: cards.length - cap };
|
|
52157
|
+
}
|
|
52158
|
+
var kanbanBoardVariants = cva({
|
|
52159
|
+
base: "flex flex-row gap-4 overflow-x-auto pb-4",
|
|
52160
|
+
variants: {},
|
|
52161
|
+
defaultVariants: {}
|
|
52162
|
+
});
|
|
52163
|
+
var kanbanColumnVariants = cva({
|
|
52164
|
+
base: "flex flex-col min-w-[260px] max-w-[300px] flex-shrink-0 rounded-xl bg-muted/40",
|
|
52165
|
+
variants: {},
|
|
52166
|
+
defaultVariants: {}
|
|
52167
|
+
});
|
|
52168
|
+
var kanbanColumnHeaderClass = "flex items-center gap-2 px-4 pt-4 pb-2";
|
|
52169
|
+
var kanbanColumnTitleClass = "flex-1 text-sm font-semibold text-foreground truncate";
|
|
52170
|
+
var kanbanColumnCountClass = "ml-auto inline-flex items-center justify-center rounded-full bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground";
|
|
52171
|
+
var kanbanAccentBarClass = "h-0.5 w-full";
|
|
52172
|
+
var kanbanNoteBarClass = "mx-4 mb-2 rounded-md bg-muted px-3 py-1.5 text-xs text-muted-foreground";
|
|
52173
|
+
var kanbanColumnBodyClass = "flex flex-col gap-2 px-3 pb-3";
|
|
52174
|
+
var kanbanOverflowButtonClass = [
|
|
52175
|
+
"mt-1 w-full rounded-lg border border-dashed border-border",
|
|
52176
|
+
"py-1.5 text-center text-xs text-muted-foreground",
|
|
52177
|
+
"transition-colors hover:bg-muted hover:text-foreground",
|
|
52178
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
|
52179
|
+
].join(" ");
|
|
52180
|
+
var kanbanCardVariants = cva({
|
|
52181
|
+
base: "rounded-lg border border-border bg-card p-3 text-sm text-foreground",
|
|
52182
|
+
variants: {
|
|
52183
|
+
clickable: {
|
|
52184
|
+
true: "cursor-pointer transition-colors hover:bg-muted/60",
|
|
52185
|
+
false: ""
|
|
52186
|
+
}
|
|
52187
|
+
},
|
|
52188
|
+
defaultVariants: {
|
|
52189
|
+
clickable: "false"
|
|
52190
|
+
}
|
|
52191
|
+
});
|
|
52192
|
+
var KanbanCard = React11__namespace.forwardRef(
|
|
52193
|
+
({ accent, clickable = false, className, style, children, ...props }, ref) => {
|
|
52194
|
+
const accentStyle = accent ? { borderTopColor: accent, borderTopWidth: "2px", ...style } : style ?? {};
|
|
52195
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
52196
|
+
"div",
|
|
52197
|
+
{
|
|
52198
|
+
ref,
|
|
52199
|
+
className: cn(
|
|
52200
|
+
kanbanCardVariants({ clickable: clickable ? "true" : "false" }),
|
|
52201
|
+
className
|
|
52202
|
+
),
|
|
52203
|
+
style: accentStyle,
|
|
52204
|
+
...props,
|
|
52205
|
+
children
|
|
52206
|
+
}
|
|
52207
|
+
);
|
|
52208
|
+
}
|
|
52209
|
+
);
|
|
52210
|
+
KanbanCard.displayName = "KanbanCard";
|
|
52211
|
+
var KanbanColumn = React11__namespace.forwardRef(
|
|
52212
|
+
({ def, count, className, children, style, ...props }, ref) => {
|
|
52213
|
+
const derivedCount = count !== void 0 ? count : React11__namespace.Children.count(children);
|
|
52214
|
+
const colStyle = def.accent ? { "--kanban-accent": def.accent, ...style } : style ?? {};
|
|
52215
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
52216
|
+
"div",
|
|
52217
|
+
{
|
|
52218
|
+
ref,
|
|
52219
|
+
className: cn(kanbanColumnVariants(), className),
|
|
52220
|
+
style: colStyle,
|
|
52221
|
+
...props,
|
|
52222
|
+
children: [
|
|
52223
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: kanbanColumnHeaderClass, children: [
|
|
52224
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: kanbanColumnTitleClass, children: def.title }),
|
|
52225
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: kanbanColumnCountClass, children: derivedCount })
|
|
52226
|
+
] }),
|
|
52227
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
52228
|
+
"div",
|
|
52229
|
+
{
|
|
52230
|
+
className: kanbanAccentBarClass,
|
|
52231
|
+
style: def.accent ? { backgroundColor: "var(--kanban-accent)" } : { backgroundColor: "transparent" },
|
|
52232
|
+
"aria-hidden": "true"
|
|
52233
|
+
}
|
|
52234
|
+
),
|
|
52235
|
+
def.note && /* @__PURE__ */ jsxRuntime.jsx("p", { className: kanbanNoteBarClass, children: def.note }),
|
|
52236
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: kanbanColumnBodyClass, children })
|
|
52237
|
+
]
|
|
52238
|
+
}
|
|
52239
|
+
);
|
|
52240
|
+
}
|
|
52241
|
+
);
|
|
52242
|
+
KanbanColumn.displayName = "KanbanColumn";
|
|
52243
|
+
function KanbanBoard({
|
|
52244
|
+
columns,
|
|
52245
|
+
cards,
|
|
52246
|
+
getCardColumnId,
|
|
52247
|
+
getCardKey,
|
|
52248
|
+
renderCard,
|
|
52249
|
+
cardCap = 5,
|
|
52250
|
+
onCardClick: _onCardClick,
|
|
52251
|
+
columnHeader,
|
|
52252
|
+
onShowMore,
|
|
52253
|
+
className,
|
|
52254
|
+
...props
|
|
52255
|
+
}) {
|
|
52256
|
+
const { ariaProps, dataAttributes } = createKanbanBoard();
|
|
52257
|
+
const buckets = cardsByColumn(cards, getCardColumnId, columns);
|
|
52258
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
52259
|
+
"div",
|
|
52260
|
+
{
|
|
52261
|
+
className: cn(kanbanBoardVariants(), className),
|
|
52262
|
+
...ariaProps,
|
|
52263
|
+
...dataAttributes,
|
|
52264
|
+
...props,
|
|
52265
|
+
children: columns.map((def) => {
|
|
52266
|
+
const colCards = buckets.get(def.id) ?? [];
|
|
52267
|
+
const { visible, overflow } = visibleAndOverflow(colCards, cardCap);
|
|
52268
|
+
const count = colCards.length;
|
|
52269
|
+
const header = columnHeader ? columnHeader(def, count) : null;
|
|
52270
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
52271
|
+
"div",
|
|
52272
|
+
{
|
|
52273
|
+
className: kanbanColumnVariants(),
|
|
52274
|
+
style: def.accent ? { "--kanban-accent": def.accent } : void 0,
|
|
52275
|
+
children: [
|
|
52276
|
+
header ?? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: kanbanColumnHeaderClass, children: [
|
|
52277
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: kanbanColumnTitleClass, children: def.title }),
|
|
52278
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: kanbanColumnCountClass, children: count })
|
|
52279
|
+
] }),
|
|
52280
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
52281
|
+
"div",
|
|
52282
|
+
{
|
|
52283
|
+
className: kanbanAccentBarClass,
|
|
52284
|
+
style: def.accent ? { backgroundColor: "var(--kanban-accent)" } : { backgroundColor: "transparent" },
|
|
52285
|
+
"aria-hidden": "true"
|
|
52286
|
+
}
|
|
52287
|
+
),
|
|
52288
|
+
def.note && /* @__PURE__ */ jsxRuntime.jsx("p", { className: kanbanNoteBarClass, children: def.note }),
|
|
52289
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: kanbanColumnBodyClass, children: [
|
|
52290
|
+
visible.map((card) => /* @__PURE__ */ jsxRuntime.jsx(React11__namespace.Fragment, { children: renderCard(card, def) }, getCardKey(card))),
|
|
52291
|
+
overflow > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
52292
|
+
"button",
|
|
52293
|
+
{
|
|
52294
|
+
type: "button",
|
|
52295
|
+
className: kanbanOverflowButtonClass,
|
|
52296
|
+
onClick: () => onShowMore?.(def.id),
|
|
52297
|
+
children: `+${overflow} more`
|
|
52298
|
+
}
|
|
52299
|
+
)
|
|
52300
|
+
] })
|
|
52301
|
+
]
|
|
52302
|
+
},
|
|
52303
|
+
def.id
|
|
52304
|
+
);
|
|
52305
|
+
})
|
|
52306
|
+
}
|
|
52307
|
+
);
|
|
52308
|
+
}
|
|
52309
|
+
|
|
52310
|
+
// ../slot-picker/dist/index.js
|
|
52311
|
+
function slotsForDay(slotsByDay, dayId) {
|
|
52312
|
+
return slotsByDay[dayId] ?? [];
|
|
52313
|
+
}
|
|
52314
|
+
function isSlotSelected(value, dayId, slot) {
|
|
52315
|
+
return value?.dayId === dayId && value?.slot === slot;
|
|
52316
|
+
}
|
|
52317
|
+
function createSlotPicker() {
|
|
52318
|
+
return {
|
|
52319
|
+
ariaProps: {
|
|
52320
|
+
role: "group",
|
|
52321
|
+
"aria-label": "Pick a time"
|
|
52322
|
+
},
|
|
52323
|
+
dataAttributes: {
|
|
52324
|
+
"data-component": "slot-picker"
|
|
52325
|
+
}
|
|
52326
|
+
};
|
|
52327
|
+
}
|
|
52328
|
+
var slotPickerVariants = cva({
|
|
52329
|
+
base: "flex flex-col gap-4",
|
|
52330
|
+
variants: {},
|
|
52331
|
+
defaultVariants: {}
|
|
52332
|
+
});
|
|
52333
|
+
var slotPickerDayRowClass = "flex items-center gap-2 overflow-x-auto pb-1";
|
|
52334
|
+
var slotPickerDayVariants = cva({
|
|
52335
|
+
base: [
|
|
52336
|
+
"inline-flex flex-col items-center justify-center rounded-lg px-3 py-2 min-w-[3.5rem]",
|
|
52337
|
+
"text-sm font-medium cursor-pointer transition-colors",
|
|
52338
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
52339
|
+
"disabled:pointer-events-none disabled:opacity-50"
|
|
52340
|
+
].join(" "),
|
|
52341
|
+
variants: {
|
|
52342
|
+
selected: {
|
|
52343
|
+
true: "bg-primary text-primary-foreground",
|
|
52344
|
+
false: "bg-card border border-input text-foreground hover:bg-muted"
|
|
52345
|
+
}
|
|
52346
|
+
},
|
|
52347
|
+
defaultVariants: {
|
|
52348
|
+
selected: "false"
|
|
52349
|
+
}
|
|
52350
|
+
});
|
|
52351
|
+
var slotPickerGridClass = "grid grid-cols-3 gap-2 sm:grid-cols-4";
|
|
52352
|
+
var slotPickerSlotVariants = cva({
|
|
52353
|
+
base: [
|
|
52354
|
+
"inline-flex items-center justify-center rounded-md border px-3 py-2 text-sm font-medium",
|
|
52355
|
+
"transition-colors cursor-pointer",
|
|
52356
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
|
|
52357
|
+
].join(" "),
|
|
52358
|
+
variants: {
|
|
52359
|
+
selected: {
|
|
52360
|
+
true: "bg-primary text-primary-foreground border-primary",
|
|
52361
|
+
false: "bg-card border-input text-foreground hover:bg-muted"
|
|
52362
|
+
},
|
|
52363
|
+
disabled: {
|
|
52364
|
+
true: "opacity-40 pointer-events-none",
|
|
52365
|
+
false: ""
|
|
52366
|
+
}
|
|
52367
|
+
},
|
|
52368
|
+
defaultVariants: {
|
|
52369
|
+
selected: "false",
|
|
52370
|
+
disabled: "false"
|
|
52371
|
+
}
|
|
52372
|
+
});
|
|
52373
|
+
var slotPickerSectionLabelClass = "text-sm font-semibold text-foreground";
|
|
52374
|
+
var slotPickerTimezoneClass = "text-xs text-muted-foreground ml-2";
|
|
52375
|
+
var SlotPicker = React11__namespace.forwardRef(
|
|
52376
|
+
({
|
|
52377
|
+
days,
|
|
52378
|
+
slotsByDay,
|
|
52379
|
+
value: valueProp,
|
|
52380
|
+
defaultValue,
|
|
52381
|
+
onChange,
|
|
52382
|
+
timezoneLabel,
|
|
52383
|
+
disabledSlots = [],
|
|
52384
|
+
className,
|
|
52385
|
+
...props
|
|
52386
|
+
}, ref) => {
|
|
52387
|
+
const isControlled = valueProp !== void 0;
|
|
52388
|
+
const [internal, setInternal] = React11__namespace.useState(
|
|
52389
|
+
defaultValue
|
|
52390
|
+
);
|
|
52391
|
+
const value = isControlled ? valueProp : internal;
|
|
52392
|
+
const selectedDayId = value?.dayId;
|
|
52393
|
+
const handleDaySelect = React11__namespace.useCallback(
|
|
52394
|
+
(dayId) => {
|
|
52395
|
+
const slots = slotsForDay(slotsByDay, dayId);
|
|
52396
|
+
const keepSlot = value?.slot && slots.includes(value.slot) ? value.slot : void 0;
|
|
52397
|
+
const next = keepSlot ? { dayId, slot: keepSlot } : void 0;
|
|
52398
|
+
if (!isControlled) setInternal(next);
|
|
52399
|
+
if (next) onChange?.(next);
|
|
52400
|
+
},
|
|
52401
|
+
[isControlled, onChange, slotsByDay, value]
|
|
52402
|
+
);
|
|
52403
|
+
const handleSlotSelect = React11__namespace.useCallback(
|
|
52404
|
+
(slot) => {
|
|
52405
|
+
if (!selectedDayId) return;
|
|
52406
|
+
const next = { dayId: selectedDayId, slot };
|
|
52407
|
+
if (!isControlled) setInternal(next);
|
|
52408
|
+
onChange?.(next);
|
|
52409
|
+
},
|
|
52410
|
+
[isControlled, onChange, selectedDayId]
|
|
52411
|
+
);
|
|
52412
|
+
const api = createSlotPicker();
|
|
52413
|
+
const currentSlots = selectedDayId ? slotsForDay(slotsByDay, selectedDayId) : [];
|
|
52414
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
52415
|
+
"div",
|
|
52416
|
+
{
|
|
52417
|
+
ref,
|
|
52418
|
+
className: cn(slotPickerVariants(), className),
|
|
52419
|
+
...api.ariaProps,
|
|
52420
|
+
...api.dataAttributes,
|
|
52421
|
+
...props,
|
|
52422
|
+
children: [
|
|
52423
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
52424
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: slotPickerSectionLabelClass, children: "Pick a day" }),
|
|
52425
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { role: "radiogroup", "aria-label": "Pick a day", className: cn(slotPickerDayRowClass, "mt-2"), children: days.map((day) => {
|
|
52426
|
+
const isSelected = selectedDayId === day.id;
|
|
52427
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
52428
|
+
"button",
|
|
52429
|
+
{
|
|
52430
|
+
type: "button",
|
|
52431
|
+
role: "radio",
|
|
52432
|
+
"aria-checked": isSelected,
|
|
52433
|
+
"data-state": isSelected ? "checked" : "unchecked",
|
|
52434
|
+
className: slotPickerDayVariants({
|
|
52435
|
+
selected: isSelected ? "true" : "false"
|
|
52436
|
+
}),
|
|
52437
|
+
onClick: () => handleDaySelect(day.id),
|
|
52438
|
+
children: [
|
|
52439
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", children: day.weekday }),
|
|
52440
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-bold leading-none", children: day.dayNum })
|
|
52441
|
+
]
|
|
52442
|
+
},
|
|
52443
|
+
day.id
|
|
52444
|
+
);
|
|
52445
|
+
}) })
|
|
52446
|
+
] }),
|
|
52447
|
+
selectedDayId && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
52448
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: slotPickerSectionLabelClass, children: [
|
|
52449
|
+
"Pick a time",
|
|
52450
|
+
timezoneLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: slotPickerTimezoneClass, children: timezoneLabel })
|
|
52451
|
+
] }),
|
|
52452
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { role: "radiogroup", "aria-label": "Pick a time", className: cn(slotPickerGridClass, "mt-2"), children: currentSlots.map((slot) => {
|
|
52453
|
+
const isSelected = isSlotSelected(value, selectedDayId, slot);
|
|
52454
|
+
const isDisabled = disabledSlots.includes(slot);
|
|
52455
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
52456
|
+
"button",
|
|
52457
|
+
{
|
|
52458
|
+
type: "button",
|
|
52459
|
+
role: "radio",
|
|
52460
|
+
"aria-checked": isSelected,
|
|
52461
|
+
"aria-disabled": isDisabled || void 0,
|
|
52462
|
+
"data-state": isSelected ? "checked" : "unchecked",
|
|
52463
|
+
className: slotPickerSlotVariants({
|
|
52464
|
+
selected: isSelected ? "true" : "false",
|
|
52465
|
+
disabled: isDisabled ? "true" : "false"
|
|
52466
|
+
}),
|
|
52467
|
+
onClick: () => !isDisabled && handleSlotSelect(slot),
|
|
52468
|
+
children: slot
|
|
52469
|
+
},
|
|
52470
|
+
slot
|
|
52471
|
+
);
|
|
52472
|
+
}) })
|
|
52473
|
+
] })
|
|
52474
|
+
]
|
|
52475
|
+
}
|
|
52476
|
+
);
|
|
52477
|
+
}
|
|
52478
|
+
);
|
|
52479
|
+
SlotPicker.displayName = "SlotPicker";
|
|
51929
52480
|
/*! Bundled license information:
|
|
51930
52481
|
|
|
51931
52482
|
@nevware21/ts-utils/dist/es5/mod/ts-utils.js:
|
|
@@ -52063,6 +52614,9 @@ exports.InputGroupAddon = InputGroupAddon;
|
|
|
52063
52614
|
exports.InputGroupButton = InputGroupButton;
|
|
52064
52615
|
exports.InputGroupText = InputGroupText;
|
|
52065
52616
|
exports.InstallPrompt = InstallPrompt;
|
|
52617
|
+
exports.KanbanBoard = KanbanBoard;
|
|
52618
|
+
exports.KanbanCard = KanbanCard;
|
|
52619
|
+
exports.KanbanColumn = KanbanColumn;
|
|
52066
52620
|
exports.KeyboardShortcut = KeyboardShortcut;
|
|
52067
52621
|
exports.LanguageSelector = LanguageSelector;
|
|
52068
52622
|
exports.LinkCard = LinkCard;
|
|
@@ -52136,8 +52690,10 @@ exports.Skeleton = Skeleton;
|
|
|
52136
52690
|
exports.SkeletonText = SkeletonText;
|
|
52137
52691
|
exports.SkipToContent = SkipToContent;
|
|
52138
52692
|
exports.SlideViewer = SlideViewer;
|
|
52693
|
+
exports.SlotPicker = SlotPicker;
|
|
52139
52694
|
exports.SocialAuthButton = SocialAuthButton;
|
|
52140
52695
|
exports.SocialAuthRow = SocialAuthRow;
|
|
52696
|
+
exports.SortableList = SortableList;
|
|
52141
52697
|
exports.SpeakingOrb = SpeakingOrb;
|
|
52142
52698
|
exports.StatGrid = StatGrid;
|
|
52143
52699
|
exports.StatsGrid = StatsGrid;
|