@borisj74/bv-ds 0.1.3 → 0.1.5

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.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as React28 from 'react';
2
2
  import React28__default, { forwardRef, isValidElement, cloneElement, Children, useContext, useMemo, createContext, Fragment, useState, PureComponent, createElement, Component, useRef, useEffect, useCallback, useId, useImperativeHandle } from 'react';
3
3
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
4
+ import { LogOut01, ChevronSelectorVertical, ChevronDown as ChevronDown$1, XClose as XClose$1, Menu02 } from '@borisj74/bv-ds-icons';
4
5
 
5
6
  var __create = Object.create;
6
7
  var __defProp = Object.defineProperty;
@@ -6096,6 +6097,97 @@ function ButtonUtility({
6096
6097
  ) : null
6097
6098
  ] });
6098
6099
  }
6100
+ var dotClasses = {
6101
+ neutral: "bg-utility-neutral-500",
6102
+ brand: "bg-utility-brand-500",
6103
+ emerald: "bg-utility-emerald-500",
6104
+ blue: "bg-utility-blue-500",
6105
+ indigo: "bg-utility-indigo-500",
6106
+ purple: "bg-utility-purple-500",
6107
+ pink: "bg-utility-pink-500",
6108
+ orange: "bg-utility-orange-500",
6109
+ amber: "bg-utility-amber-500"
6110
+ };
6111
+ var filledClasses = {
6112
+ neutral: "bg-utility-neutral-50 border-utility-neutral-200 text-utility-neutral-700",
6113
+ brand: "bg-utility-brand-50 border-utility-brand-200 text-utility-brand-700",
6114
+ emerald: "bg-utility-emerald-50 border-utility-emerald-200 text-utility-emerald-700",
6115
+ blue: "bg-utility-blue-50 border-utility-blue-200 text-utility-blue-700",
6116
+ indigo: "bg-utility-indigo-50 border-utility-indigo-200 text-utility-indigo-700",
6117
+ purple: "bg-utility-purple-50 border-utility-purple-200 text-utility-purple-700",
6118
+ pink: "bg-utility-pink-50 border-utility-pink-200 text-utility-pink-700",
6119
+ orange: "bg-utility-orange-50 border-utility-orange-200 text-utility-orange-700",
6120
+ amber: "bg-utility-amber-50 border-utility-amber-200 text-utility-amber-700"
6121
+ };
6122
+ var filledHoverClasses = {
6123
+ neutral: "bg-utility-neutral-100",
6124
+ brand: "bg-utility-brand-100",
6125
+ emerald: "bg-utility-emerald-100",
6126
+ blue: "bg-utility-blue-100",
6127
+ indigo: "bg-utility-indigo-100",
6128
+ purple: "bg-utility-purple-100",
6129
+ pink: "bg-utility-pink-100",
6130
+ orange: "bg-utility-orange-100",
6131
+ amber: "bg-utility-amber-100"
6132
+ };
6133
+ var timeClasses = {
6134
+ neutral: "text-utility-neutral-600",
6135
+ brand: "text-utility-brand-600",
6136
+ emerald: "text-utility-emerald-600",
6137
+ blue: "text-utility-blue-600",
6138
+ indigo: "text-utility-indigo-600",
6139
+ purple: "text-utility-purple-600",
6140
+ pink: "text-utility-pink-600",
6141
+ orange: "text-utility-orange-600",
6142
+ amber: "text-utility-amber-600"
6143
+ };
6144
+ function CalendarEvent({
6145
+ title,
6146
+ time: time2,
6147
+ color: color2 = "neutral",
6148
+ filled = false,
6149
+ breakpoint = "desktop",
6150
+ state = "default",
6151
+ className
6152
+ }) {
6153
+ if (breakpoint === "mobile") {
6154
+ return /* @__PURE__ */ jsx(
6155
+ "span",
6156
+ {
6157
+ className: clsx_default("inline-block size-2 rounded-full", dotClasses[color2], className),
6158
+ role: "img",
6159
+ "aria-label": time2 ? `${title}, ${time2}` : title
6160
+ }
6161
+ );
6162
+ }
6163
+ return /* @__PURE__ */ jsxs(
6164
+ "div",
6165
+ {
6166
+ className: clsx_default(
6167
+ "flex w-full items-center gap-md rounded-sm border px-md py-xs font-body text-xs",
6168
+ filled ? clsx_default(filledClasses[color2], state === "hover" && filledHoverClasses[color2]) : clsx_default(
6169
+ "border-border-secondary bg-bg-primary text-text-secondary",
6170
+ state === "hover" && "bg-bg-primary-hover"
6171
+ ),
6172
+ className
6173
+ ),
6174
+ children: [
6175
+ /* @__PURE__ */ jsx("span", { className: clsx_default("size-2 shrink-0 rounded-full", dotClasses[color2]), "aria-hidden": true }),
6176
+ /* @__PURE__ */ jsx("span", { className: "truncate font-semibold", children: title }),
6177
+ time2 ? /* @__PURE__ */ jsx(
6178
+ "span",
6179
+ {
6180
+ className: clsx_default(
6181
+ "ml-auto shrink-0 font-normal",
6182
+ filled ? timeClasses[color2] : "text-text-tertiary"
6183
+ ),
6184
+ children: time2
6185
+ }
6186
+ ) : null
6187
+ ]
6188
+ }
6189
+ );
6190
+ }
6099
6191
  function PlusIcon2() {
6100
6192
  return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 20 20", fill: "none", className: "size-4", "aria-hidden": true, children: /* @__PURE__ */ jsx(
6101
6193
  "path",
@@ -6110,19 +6202,26 @@ function PlusIcon2() {
6110
6202
  }
6111
6203
  function CalendarCell({
6112
6204
  date: date2,
6205
+ events,
6113
6206
  children,
6114
6207
  moreCount,
6115
- muted = false,
6208
+ isToday,
6209
+ isSelected = false,
6210
+ isDisabled,
6116
6211
  current = false,
6212
+ muted = false,
6213
+ breakpoint = "desktop",
6117
6214
  onAdd,
6118
6215
  className
6119
6216
  }) {
6217
+ const today = isToday ?? current;
6218
+ const disabled = isDisabled ?? muted;
6120
6219
  return /* @__PURE__ */ jsxs(
6121
6220
  "div",
6122
6221
  {
6123
6222
  className: clsx_default(
6124
6223
  "group relative flex min-h-[120px] flex-col gap-xs bg-bg-primary p-md font-body",
6125
- muted && "bg-bg-secondary",
6224
+ disabled && "bg-bg-secondary",
6126
6225
  className
6127
6226
  ),
6128
6227
  children: [
@@ -6130,12 +6229,31 @@ function CalendarCell({
6130
6229
  "span",
6131
6230
  {
6132
6231
  className: clsx_default(
6133
- "text-xs font-semibold",
6134
- current ? "text-text-brand-secondary" : muted ? "text-text-quaternary" : "text-text-secondary"
6232
+ "flex size-6 items-center justify-center text-xs font-semibold",
6233
+ today ? "rounded-full bg-bg-brand-solid text-white" : isSelected ? "rounded-full bg-bg-secondary text-text-secondary" : disabled ? "text-text-quaternary" : "text-text-secondary"
6135
6234
  ),
6136
6235
  children: date2
6137
6236
  }
6138
6237
  ),
6238
+ events && events.length > 0 ? /* @__PURE__ */ jsx(
6239
+ "div",
6240
+ {
6241
+ className: clsx_default(
6242
+ breakpoint === "mobile" ? "flex flex-row flex-wrap gap-xxs" : "flex flex-col gap-xs"
6243
+ ),
6244
+ children: events.map((ev, i) => /* @__PURE__ */ jsx(
6245
+ CalendarEvent,
6246
+ {
6247
+ title: ev.title,
6248
+ time: ev.time,
6249
+ color: ev.color,
6250
+ filled: true,
6251
+ breakpoint
6252
+ },
6253
+ i
6254
+ ))
6255
+ }
6256
+ ) : null,
6139
6257
  children ? /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-xs", children }) : null,
6140
6258
  moreCount && moreCount > 0 ? /* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-text-tertiary", children: [
6141
6259
  moreCount,
@@ -6155,6 +6273,13 @@ function CalendarCell({
6155
6273
  }
6156
6274
  );
6157
6275
  }
6276
+ var heightClasses = {
6277
+ empty: "h-[48px]",
6278
+ "30min": "h-[48px]",
6279
+ "60min": "h-[96px]",
6280
+ "90min": "h-[144px]",
6281
+ "120min": "h-[192px]"
6282
+ };
6158
6283
  function PlusIcon3() {
6159
6284
  return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 20 20", fill: "none", className: "size-4", "aria-hidden": true, children: /* @__PURE__ */ jsx(
6160
6285
  "path",
@@ -6168,6 +6293,8 @@ function PlusIcon3() {
6168
6293
  ) });
6169
6294
  }
6170
6295
  function CalendarCellDayWeekView({
6296
+ type,
6297
+ state = "default",
6171
6298
  children,
6172
6299
  onAdd,
6173
6300
  muted = false,
@@ -6177,8 +6304,9 @@ function CalendarCellDayWeekView({
6177
6304
  "div",
6178
6305
  {
6179
6306
  className: clsx_default(
6180
- "group relative min-h-[64px] border-b border-border-secondary p-xs font-body",
6181
- muted ? "bg-bg-secondary" : "bg-bg-primary",
6307
+ "group relative border-b border-border-secondary p-xs font-body transition-colors hover:bg-bg-secondary",
6308
+ type ? heightClasses[type] : "min-h-[64px]",
6309
+ muted ? "bg-bg-secondary" : state === "hover" ? "bg-bg-secondary" : "bg-bg-primary",
6182
6310
  className
6183
6311
  ),
6184
6312
  children: [
@@ -6200,16 +6328,20 @@ function CalendarCellDayWeekView({
6200
6328
  function CalendarColumnHeader({
6201
6329
  weekday,
6202
6330
  date: date2,
6331
+ type,
6203
6332
  current = false,
6204
6333
  orientation = "vertical",
6334
+ breakpoint = "desktop",
6205
6335
  className
6206
6336
  }) {
6337
+ const state = type ?? (current ? "selected" : "default");
6207
6338
  return /* @__PURE__ */ jsxs(
6208
6339
  "div",
6209
6340
  {
6210
6341
  className: clsx_default(
6211
6342
  "flex items-center justify-center gap-md py-md font-body",
6212
6343
  orientation === "vertical" && "flex-col gap-xs",
6344
+ breakpoint === "desktop" && "w-[160px]",
6213
6345
  className
6214
6346
  ),
6215
6347
  children: [
@@ -6219,9 +6351,11 @@ function CalendarColumnHeader({
6219
6351
  {
6220
6352
  className: clsx_default(
6221
6353
  "flex items-center justify-center text-xs font-semibold",
6222
- current ? "size-6 rounded-full bg-bg-brand-solid text-white" : "text-text-secondary"
6354
+ state === "selected" && "size-6 rounded-full bg-bg-brand-solid text-white",
6355
+ state === "today" && "border-b-2 border-border-brand pb-xxs text-text-brand-secondary",
6356
+ state === "default" && "text-text-secondary"
6223
6357
  ),
6224
- "aria-current": current ? "date" : void 0,
6358
+ "aria-current": state !== "default" ? "date" : void 0,
6225
6359
  children: date2
6226
6360
  }
6227
6361
  )
@@ -6244,51 +6378,6 @@ function CalendarDateIcon({ month, day, className }) {
6244
6378
  }
6245
6379
  );
6246
6380
  }
6247
- var dotClasses = {
6248
- neutral: "bg-utility-neutral-500",
6249
- brand: "bg-utility-brand-500",
6250
- emerald: "bg-utility-emerald-500",
6251
- blue: "bg-utility-blue-500",
6252
- indigo: "bg-utility-indigo-500",
6253
- purple: "bg-utility-purple-500",
6254
- pink: "bg-utility-pink-500",
6255
- orange: "bg-utility-orange-500",
6256
- amber: "bg-utility-amber-500"
6257
- };
6258
- var filledClasses = {
6259
- neutral: "bg-utility-neutral-100 text-utility-neutral-700",
6260
- brand: "bg-utility-brand-100 text-utility-brand-700",
6261
- emerald: "bg-utility-emerald-100 text-utility-emerald-700",
6262
- blue: "bg-utility-blue-100 text-utility-blue-700",
6263
- indigo: "bg-utility-indigo-100 text-utility-indigo-700",
6264
- purple: "bg-utility-purple-100 text-utility-purple-700",
6265
- pink: "bg-utility-pink-100 text-utility-pink-700",
6266
- orange: "bg-utility-orange-100 text-utility-orange-700",
6267
- amber: "bg-utility-amber-100 text-utility-amber-700"
6268
- };
6269
- function CalendarEvent({
6270
- title,
6271
- time: time2,
6272
- color: color2 = "neutral",
6273
- filled = false,
6274
- className
6275
- }) {
6276
- return /* @__PURE__ */ jsxs(
6277
- "div",
6278
- {
6279
- className: clsx_default(
6280
- "flex w-full items-center gap-md rounded-sm px-md py-xs font-body text-xs",
6281
- filled ? filledClasses[color2] : "border border-border-secondary bg-bg-primary text-text-secondary",
6282
- className
6283
- ),
6284
- children: [
6285
- /* @__PURE__ */ jsx("span", { className: clsx_default("size-2 shrink-0 rounded-full", dotClasses[color2]), "aria-hidden": true }),
6286
- /* @__PURE__ */ jsx("span", { className: "truncate font-semibold", children: title }),
6287
- time2 ? /* @__PURE__ */ jsx("span", { className: clsx_default("ml-auto shrink-0 font-normal", !filled && "text-text-tertiary"), children: time2 }) : null
6288
- ]
6289
- }
6290
- );
6291
- }
6292
6381
  var accentClasses = {
6293
6382
  neutral: "border-l-utility-neutral-500",
6294
6383
  brand: "border-l-utility-brand-500",
@@ -6355,11 +6444,13 @@ function CalendarEventDayWeekView({
6355
6444
  function CalendarHeader({
6356
6445
  title,
6357
6446
  range: range6,
6447
+ supportingText,
6358
6448
  badge,
6359
6449
  dateIcon,
6360
6450
  actions,
6361
6451
  className
6362
6452
  }) {
6453
+ const subtitle = range6 ?? supportingText;
6363
6454
  return /* @__PURE__ */ jsxs(
6364
6455
  "div",
6365
6456
  {
@@ -6375,7 +6466,7 @@ function CalendarHeader({
6375
6466
  /* @__PURE__ */ jsx("h2", { className: "text-lg font-bold text-text-primary", children: title }),
6376
6467
  badge
6377
6468
  ] }),
6378
- range6 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-text-tertiary", children: range6 }) : null
6469
+ subtitle ? /* @__PURE__ */ jsx("p", { className: "text-sm text-text-tertiary", children: subtitle }) : null
6379
6470
  ] })
6380
6471
  ] }),
6381
6472
  actions ? /* @__PURE__ */ jsx("div", { className: "flex items-center gap-md", children: actions }) : null
@@ -6383,7 +6474,7 @@ function CalendarHeader({
6383
6474
  }
6384
6475
  );
6385
6476
  }
6386
- function CalendarRowLabel({ label, className }) {
6477
+ function CalendarRowLabel({ label, time: time2, className }) {
6387
6478
  return /* @__PURE__ */ jsx(
6388
6479
  "div",
6389
6480
  {
@@ -6391,7 +6482,7 @@ function CalendarRowLabel({ label, className }) {
6391
6482
  "pr-md text-right text-xs font-medium text-text-quaternary font-body",
6392
6483
  className
6393
6484
  ),
6394
- children: label
6485
+ children: time2 ?? label
6395
6486
  }
6396
6487
  );
6397
6488
  }
@@ -6401,15 +6492,17 @@ var Label = ({ time: time2 }) => /* @__PURE__ */ jsx("span", { className: "shrin
6401
6492
  function CalendarTimemarker({
6402
6493
  time: time2,
6403
6494
  align = "left",
6495
+ breakpoint = "desktop",
6404
6496
  className
6405
6497
  }) {
6498
+ const showLabel = breakpoint === "desktop";
6406
6499
  return /* @__PURE__ */ jsx("div", { className: clsx_default("flex w-full items-center gap-xs font-body", className), children: align === "center" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
6407
6500
  /* @__PURE__ */ jsx(Dot, {}),
6408
6501
  /* @__PURE__ */ jsx(Line, {}),
6409
- /* @__PURE__ */ jsx(Label, { time: time2 }),
6502
+ showLabel ? /* @__PURE__ */ jsx(Label, { time: time2 }) : null,
6410
6503
  /* @__PURE__ */ jsx(Line, {})
6411
6504
  ] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
6412
- /* @__PURE__ */ jsx(Label, { time: time2 }),
6505
+ showLabel ? /* @__PURE__ */ jsx(Label, { time: time2 }) : null,
6413
6506
  /* @__PURE__ */ jsx(Dot, {}),
6414
6507
  /* @__PURE__ */ jsx(Line, {})
6415
6508
  ] }) });
@@ -6434,10 +6527,19 @@ function Chevron2() {
6434
6527
  function CalendarViewDropdown({
6435
6528
  value,
6436
6529
  onChange,
6530
+ onSelect,
6531
+ open: openProp,
6532
+ onOpenChange,
6437
6533
  options = DEFAULT_OPTIONS,
6438
6534
  className
6439
6535
  }) {
6440
- const [open, setOpen] = useState(false);
6536
+ const [internalOpen, setInternalOpen] = useState(false);
6537
+ const isControlled = openProp !== void 0;
6538
+ const open = isControlled ? openProp : internalOpen;
6539
+ const setOpen = (next) => {
6540
+ if (!isControlled) setInternalOpen(next);
6541
+ onOpenChange?.(next);
6542
+ };
6441
6543
  const selected = options.find((o) => o.value === value) ?? options[0];
6442
6544
  return /* @__PURE__ */ jsxs("div", { className: clsx_default("relative inline-block font-body", className), children: [
6443
6545
  /* @__PURE__ */ jsxs(
@@ -6446,7 +6548,7 @@ function CalendarViewDropdown({
6446
6548
  type: "button",
6447
6549
  "aria-haspopup": "listbox",
6448
6550
  "aria-expanded": open,
6449
- onClick: () => setOpen((v) => !v),
6551
+ onClick: () => setOpen(!open),
6450
6552
  className: "inline-flex items-center gap-md rounded-md border border-border-primary bg-bg-primary px-lg py-md text-sm font-semibold text-text-secondary shadow-skeuomorphic transition-colors hover:bg-bg-primary-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-brand focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
6451
6553
  children: [
6452
6554
  selected.label,
@@ -6467,6 +6569,7 @@ function CalendarViewDropdown({
6467
6569
  type: "button",
6468
6570
  onClick: () => {
6469
6571
  onChange?.(opt.value);
6572
+ onSelect?.(opt.value);
6470
6573
  setOpen(false);
6471
6574
  },
6472
6575
  className: "flex w-full items-center gap-md rounded-sm px-md py-xs text-sm font-medium text-text-secondary transition-colors hover:bg-bg-primary-hover",
@@ -31833,17 +31936,7 @@ function MultiSelect({
31833
31936
  hint && /* @__PURE__ */ jsx("span", { className: clsx_default("text-sm", invalid ? "text-text-error-primary" : "text-text-tertiary"), children: hint })
31834
31937
  ] });
31835
31938
  }
31836
- var ChevronSelector = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", className: "size-4", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M5 6l3-3 3 3M5 10l3 3 3-3", stroke: "currentColor", strokeWidth: "1.33", strokeLinecap: "round", strokeLinejoin: "round" }) });
31837
- var LogOut = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", className: "size-4", "aria-hidden": true, children: /* @__PURE__ */ jsx(
31838
- "path",
31839
- {
31840
- d: "M10.67 11.33 14 8m0 0-3.33-3.33M14 8H6M6 2H4.67c-.93 0-1.4 0-1.76.18-.31.16-.57.42-.73.73C2 3.27 2 3.73 2 4.67v6.66c0 .94 0 1.4.18 1.76.16.31.42.57.73.73.36.18.83.18 1.76.18H6",
31841
- stroke: "currentColor",
31842
- strokeWidth: "1.33",
31843
- strokeLinecap: "round",
31844
- strokeLinejoin: "round"
31845
- }
31846
- ) });
31939
+ var IconBox16 = ({ children }) => /* @__PURE__ */ jsx("span", { className: "overflow-clip relative shrink-0 size-[16px] flex items-center justify-center", children });
31847
31940
  var LayeredAvatar = ({ src, online }) => /* @__PURE__ */ jsxs("span", { className: "relative inline-flex size-10 shrink-0 rounded-full border-[0.75px] border-border-secondary-alt bg-bg-primary p-[1px] shadow-xs", children: [
31848
31941
  /* @__PURE__ */ jsx("span", { className: "flex size-full overflow-hidden rounded-full border-[0.5px] border-[rgba(0,0,0,0.16)]", children: /* @__PURE__ */ jsx("img", { src, alt: "", className: "size-full rounded-full object-cover" }) }),
31849
31942
  online !== void 0 && /* @__PURE__ */ jsx(
@@ -31899,7 +31992,7 @@ function NavAccountCard({
31899
31992
  onClick: onSignOut,
31900
31993
  "aria-label": "Sign out",
31901
31994
  className: "absolute right-0 top-[15px] flex items-center justify-center rounded-sm p-sm text-fg-quaternary transition-colors hover:text-fg-quaternary-hover",
31902
- children: /* @__PURE__ */ jsx(LogOut, {})
31995
+ children: /* @__PURE__ */ jsx(IconBox16, { children: /* @__PURE__ */ jsx(LogOut01, { className: "w-full h-full" }) })
31903
31996
  }
31904
31997
  )
31905
31998
  ]
@@ -31922,7 +32015,7 @@ function NavAccountCard({
31922
32015
  "absolute right-[7px] top-[7px] flex items-center justify-center rounded-sm p-sm text-fg-quaternary",
31923
32016
  open && "bg-bg-primary-hover"
31924
32017
  ),
31925
- children: /* @__PURE__ */ jsx(ChevronSelector, {})
32018
+ children: /* @__PURE__ */ jsx(IconBox16, { children: /* @__PURE__ */ jsx(ChevronSelectorVertical, { className: "w-full h-full" }) })
31926
32019
  }
31927
32020
  )
31928
32021
  ]
@@ -32063,7 +32156,6 @@ function NavFeaturedCard({
32063
32156
  }
32064
32157
  );
32065
32158
  }
32066
- var ChevronDown2 = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", className: "size-4", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.33", strokeLinecap: "round", strokeLinejoin: "round" }) });
32067
32159
  function NavItemBase({
32068
32160
  current = false,
32069
32161
  icon,
@@ -32098,14 +32190,13 @@ function NavItemBase({
32098
32190
  /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left text-sm font-semibold text-text-secondary", children: label })
32099
32191
  ] }),
32100
32192
  badge != null && /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded-full border border-utility-neutral-200 bg-utility-neutral-50 px-md py-xxs text-xs font-medium text-utility-neutral-700", children: badge }),
32101
- trailingChevron && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-fg-quaternary", children: /* @__PURE__ */ jsx(ChevronDown2, {}) })
32193
+ trailingChevron && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-fg-quaternary", children: /* @__PURE__ */ jsx("span", { className: "overflow-clip relative shrink-0 size-[16px] flex items-center justify-center", children: /* @__PURE__ */ jsx(ChevronDown$1, { className: "w-full h-full" }) }) })
32102
32194
  ]
32103
32195
  }
32104
32196
  )
32105
32197
  }
32106
32198
  );
32107
32199
  }
32108
- var Chevron5 = ({ up }) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", className: "size-4", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: up ? "M4 10l4-4 4 4" : "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.33", strokeLinecap: "round", strokeLinejoin: "round" }) });
32109
32200
  function NavItemDropdownBase({
32110
32201
  current = false,
32111
32202
  open = false,
@@ -32137,7 +32228,12 @@ function NavItemDropdownBase({
32137
32228
  icon && /* @__PURE__ */ jsx("span", { className: "flex size-5 shrink-0 items-center justify-center text-fg-quaternary [&>svg]:size-5", children: icon }),
32138
32229
  /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left text-sm font-semibold text-text-secondary", children: label })
32139
32230
  ] }),
32140
- /* @__PURE__ */ jsx("span", { className: "shrink-0 text-fg-quaternary", children: /* @__PURE__ */ jsx(Chevron5, { up: open }) })
32231
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-fg-quaternary", children: /* @__PURE__ */ jsx("span", { className: "overflow-clip relative shrink-0 size-[16px] flex items-center justify-center", children: /* @__PURE__ */ jsx(
32232
+ ChevronDown$1,
32233
+ {
32234
+ className: clsx_default("w-full h-full transition-transform", open && "rotate-180")
32235
+ }
32236
+ ) }) })
32141
32237
  ]
32142
32238
  }
32143
32239
  )
@@ -32146,8 +32242,7 @@ function NavItemDropdownBase({
32146
32242
  open && /* @__PURE__ */ jsx("div", { className: "flex flex-col pb-xs", children })
32147
32243
  ] });
32148
32244
  }
32149
- var Menu = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 20 20", fill: "none", className: "size-5", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2.5 10h15M2.5 5h15M2.5 15h15", stroke: "currentColor", strokeWidth: "1.67", strokeLinecap: "round", strokeLinejoin: "round" }) });
32150
- var XClose4 = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 20 20", fill: "none", className: "size-5", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M15 5 5 15M5 5l10 10", stroke: "currentColor", strokeWidth: "1.67", strokeLinecap: "round", strokeLinejoin: "round" }) });
32245
+ var IconBox = ({ children }) => /* @__PURE__ */ jsx("span", { className: "overflow-clip relative shrink-0 size-[20px] flex items-center justify-center", children });
32151
32246
  function NavMenuButton({
32152
32247
  opened = false,
32153
32248
  className,
@@ -32166,7 +32261,7 @@ function NavMenuButton({
32166
32261
  className
32167
32262
  ),
32168
32263
  ...rest,
32169
- children: opened ? /* @__PURE__ */ jsx("span", { className: "opacity-70", children: /* @__PURE__ */ jsx(XClose4, {}) }) : /* @__PURE__ */ jsx(Menu, {})
32264
+ children: opened ? /* @__PURE__ */ jsx("span", { className: "opacity-70", children: /* @__PURE__ */ jsx(IconBox, { children: /* @__PURE__ */ jsx(XClose$1, { className: "w-full h-full" }) }) }) : /* @__PURE__ */ jsx(IconBox, { children: /* @__PURE__ */ jsx(Menu02, { className: "w-full h-full" }) })
32170
32265
  }
32171
32266
  );
32172
32267
  }
@@ -32254,7 +32349,7 @@ function NumberInput({
32254
32349
  const inc = () => set2(value + step);
32255
32350
  const Minus = /* @__PURE__ */ jsx("svg", { viewBox: "0 0 20 20", fill: "none", className: "size-5", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M4.167 10h11.666", stroke: "currentColor", strokeWidth: "1.67", strokeLinecap: "round" }) });
32256
32351
  const Plus = /* @__PURE__ */ jsx("svg", { viewBox: "0 0 20 20", fill: "none", className: "size-5", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M10 4.167v11.666M4.167 10h11.666", stroke: "currentColor", strokeWidth: "1.67", strokeLinecap: "round" }) });
32257
- const Chevron6 = ({ up }) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", fill: "none", className: clsx_default("size-3", up && "rotate-180"), "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M3 4.5 6 7.5 9 4.5", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" }) });
32352
+ const Chevron5 = ({ up }) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", fill: "none", className: clsx_default("size-3", up && "rotate-180"), "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M3 4.5 6 7.5 9 4.5", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" }) });
32258
32353
  const numberEl = /* @__PURE__ */ jsx(
32259
32354
  "input",
32260
32355
  {
@@ -32280,9 +32375,9 @@ function NumberInput({
32280
32375
  ] }) : /* @__PURE__ */ jsxs("div", { className: clsx_default(boxClasses(destructive), "gap-0 overflow-hidden p-0"), children: [
32281
32376
  numberEl,
32282
32377
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col self-stretch border-l border-border-primary", children: [
32283
- /* @__PURE__ */ jsx("button", { type: "button", onClick: inc, disabled, "aria-label": "Increase", className: "flex flex-1 items-center justify-center px-md text-fg-quaternary hover:bg-bg-primary-hover disabled:opacity-60", children: /* @__PURE__ */ jsx(Chevron6, { up: true }) }),
32378
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: inc, disabled, "aria-label": "Increase", className: "flex flex-1 items-center justify-center px-md text-fg-quaternary hover:bg-bg-primary-hover disabled:opacity-60", children: /* @__PURE__ */ jsx(Chevron5, { up: true }) }),
32284
32379
  /* @__PURE__ */ jsx("span", { className: "h-px w-full bg-border-primary" }),
32285
- /* @__PURE__ */ jsx("button", { type: "button", onClick: dec, disabled, "aria-label": "Decrease", className: "flex flex-1 items-center justify-center px-md text-fg-quaternary hover:bg-bg-primary-hover disabled:opacity-60", children: /* @__PURE__ */ jsx(Chevron6, { up: false }) })
32380
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: dec, disabled, "aria-label": "Decrease", className: "flex flex-1 items-center justify-center px-md text-fg-quaternary hover:bg-bg-primary-hover disabled:opacity-60", children: /* @__PURE__ */ jsx(Chevron5, { up: false }) })
32286
32381
  ] })
32287
32382
  ] });
32288
32383
  return /* @__PURE__ */ jsx(FieldWrapper, { label, required, hint, destructive, className, children: box });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@borisj74/bv-ds",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "bv-ds — React component library synced from Figma (Untitled UI v8.0), built on Tailwind CSS",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -35,7 +35,8 @@
35
35
  },
36
36
  "peerDependencies": {
37
37
  "react": ">=18.0.0",
38
- "react-dom": ">=18.0.0"
38
+ "react-dom": ">=18.0.0",
39
+ "@borisj74/bv-ds-icons": ">=0.1.0"
39
40
  },
40
41
  "devDependencies": {
41
42
  "@borisj74/bv-ds-icons": "^0.1.0",
@@ -1,17 +1,40 @@
1
1
  import type { ReactNode } from "react";
2
2
  import clsx from "clsx";
3
+ import { CalendarEvent, type CalendarEventColor } from "../CalendarEvent";
4
+
5
+ export type CalendarCellBreakpoint = "desktop" | "mobile";
6
+
7
+ export interface CalendarCellEvent {
8
+ title: string;
9
+ time?: string;
10
+ color?: CalendarEventColor;
11
+ }
3
12
 
4
13
  export interface CalendarCellProps {
5
14
  /** Day-of-month number. */
6
15
  date: string | number;
16
+ /**
17
+ * Declarative events for this day — rendered as filled `CalendarEvent`
18
+ * chips (collapsed to dots on mobile). Use `children` instead for full
19
+ * control over each chip.
20
+ */
21
+ events?: CalendarCellEvent[];
7
22
  /** Event chips for this day — typically `CalendarEvent` instances. */
8
23
  children?: ReactNode;
9
24
  /** "+N more" overflow count shown beneath the events. */
10
25
  moreCount?: number;
26
+ /** Today — date number in a brand-solid circle. */
27
+ isToday?: boolean;
28
+ /** Selected day — date number in a secondary-fill circle. */
29
+ isSelected?: boolean;
11
30
  /** Other-month / disabled styling. */
12
- muted?: boolean;
13
- /** Marks today (date number in brand). */
31
+ isDisabled?: boolean;
32
+ /** Legacy alias for `isToday`. */
14
33
  current?: boolean;
34
+ /** Legacy alias for `isDisabled`. */
35
+ muted?: boolean;
36
+ /** Desktop renders full chips; mobile collapses chips to dots. */
37
+ breakpoint?: CalendarCellBreakpoint;
15
38
  /** Renders a hover "+" add button bottom-right. */
16
39
  onAdd?: () => void;
17
40
  className?: string;
@@ -34,33 +57,63 @@ function PlusIcon() {
34
57
  /** A single day cell in the month grid. Composes CalendarEvent chips. */
35
58
  export function CalendarCell({
36
59
  date,
60
+ events,
37
61
  children,
38
62
  moreCount,
39
- muted = false,
63
+ isToday,
64
+ isSelected = false,
65
+ isDisabled,
40
66
  current = false,
67
+ muted = false,
68
+ breakpoint = "desktop",
41
69
  onAdd,
42
70
  className,
43
71
  }: CalendarCellProps) {
72
+ const today = isToday ?? current;
73
+ const disabled = isDisabled ?? muted;
74
+
44
75
  return (
45
76
  <div
46
77
  className={clsx(
47
78
  "group relative flex min-h-[120px] flex-col gap-xs bg-bg-primary p-md font-body",
48
- muted && "bg-bg-secondary",
79
+ disabled && "bg-bg-secondary",
49
80
  className,
50
81
  )}
51
82
  >
52
83
  <span
53
84
  className={clsx(
54
- "text-xs font-semibold",
55
- current
56
- ? "text-text-brand-secondary"
57
- : muted
58
- ? "text-text-quaternary"
59
- : "text-text-secondary",
85
+ "flex size-6 items-center justify-center text-xs font-semibold",
86
+ today
87
+ ? "rounded-full bg-bg-brand-solid text-white"
88
+ : isSelected
89
+ ? "rounded-full bg-bg-secondary text-text-secondary"
90
+ : disabled
91
+ ? "text-text-quaternary"
92
+ : "text-text-secondary",
60
93
  )}
61
94
  >
62
95
  {date}
63
96
  </span>
97
+ {events && events.length > 0 ? (
98
+ <div
99
+ className={clsx(
100
+ breakpoint === "mobile"
101
+ ? "flex flex-row flex-wrap gap-xxs"
102
+ : "flex flex-col gap-xs",
103
+ )}
104
+ >
105
+ {events.map((ev, i) => (
106
+ <CalendarEvent
107
+ key={i}
108
+ title={ev.title}
109
+ time={ev.time}
110
+ color={ev.color}
111
+ filled
112
+ breakpoint={breakpoint}
113
+ />
114
+ ))}
115
+ </div>
116
+ ) : null}
64
117
  {children ? <div className="flex flex-col gap-xs">{children}</div> : null}
65
118
  {moreCount && moreCount > 0 ? (
66
119
  <span className="text-xs font-medium text-text-tertiary">
@@ -1,2 +1,6 @@
1
1
  export { CalendarCell } from "./CalendarCell";
2
- export type { CalendarCellProps } from "./CalendarCell";
2
+ export type {
3
+ CalendarCellProps,
4
+ CalendarCellEvent,
5
+ CalendarCellBreakpoint,
6
+ } from "./CalendarCell";