@campfire-interactive/ui 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -41,9 +41,12 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
41
41
  * ones mostly chose styling. This is the spelling the fleet's vendored
42
42
  * shadcn buttons already use, so it needs no explaining at a call site.
43
43
  *
44
- * The child must be a single element that accepts a ref. `leadingIcon`,
45
- * `trailingIcon` and `loading` are ignored, because the child owns its own
46
- * content — put the icon inside it.
44
+ * The child must be a single element that accepts a ref. `leadingIcon` and
45
+ * `trailingIcon` work here and render inside the child, same as on a real
46
+ * button — they used to be silently dropped, which took the icon off every
47
+ * link-button in the fleet while the plain buttons beside them kept theirs.
48
+ * `loading` is still ignored: a spinner belongs on a control that is doing
49
+ * something, and a link navigates.
47
50
  */
48
51
  asChild?: boolean;
49
52
  /**
package/dist/index.js CHANGED
@@ -39,14 +39,14 @@ function cn(...values) {
39
39
  }
40
40
 
41
41
  // src/Button.tsx
42
- import { forwardRef } from "react";
42
+ import { cloneElement, forwardRef, isValidElement } from "react";
43
43
  import { Slot } from "@radix-ui/react-slot";
44
44
 
45
45
  // src/Button.css
46
46
  styleInject("@layer components {\n :where(.cfi-ui-btn) {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--cfi-ui-space-sm);\n height: 2rem;\n padding-inline: 0.75rem;\n border: 1px solid transparent;\n border-radius: var(--cfi-ui-radius-md);\n background: transparent;\n color: inherit;\n font-family: inherit;\n font-size: var(--cfi-ui-text-xs);\n font-weight: var(--cfi-ui-weight-medium);\n line-height: normal;\n white-space: nowrap;\n cursor: pointer;\n transition:\n background-color var(--cfi-ui-transition-fast),\n border-color var(--cfi-ui-transition-fast),\n color var(--cfi-ui-transition-fast);\n font-variant-numeric: tabular-nums;\n }\n a.cfi-ui-btn,\n a.cfi-ui-btn:hover,\n a.cfi-ui-btn:visited {\n text-decoration: none;\n color: inherit;\n }\n .cfi-ui-btn:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n }\n .cfi-ui-btn[data-loading] {\n cursor: progress;\n opacity: 1;\n }\n .cfi-ui-btn--full {\n width: 100%;\n }\n .cfi-ui-btn[data-size=sm] {\n height: 1.75rem;\n padding-inline: 0.5rem;\n gap: var(--cfi-ui-space-xs);\n }\n .cfi-ui-btn[data-size=lg] {\n height: var(--cfi-ui-control-height-md);\n padding-inline: 1rem;\n font-size: var(--cfi-ui-text-sm);\n }\n .cfi-ui-btn[data-size=icon] {\n width: var(--cfi-ui-control-height-md);\n padding-inline: 0;\n }\n .cfi-ui-btn--icon[data-size=icon] {\n aspect-ratio: 1;\n }\n .cfi-ui-btn[data-variant=primary] {\n background: var(--cfi-ui-accent);\n color: var(--cfi-ui-accent-fg);\n }\n .cfi-ui-btn[data-variant=primary]:hover:not(:disabled) {\n background: var(--cfi-ui-accent-hover);\n }\n .cfi-ui-btn[data-variant=secondary] {\n background: var(--cfi-ui-surface);\n border-color: var(--cfi-ui-border-strong);\n color: var(--cfi-ui-content);\n }\n .cfi-ui-btn[data-variant=secondary]:hover:not(:disabled) {\n background: var(--cfi-ui-surface-hover);\n }\n .cfi-ui-btn[data-variant=ghost] {\n color: var(--cfi-ui-content);\n }\n .cfi-ui-btn[data-variant=ghost]:hover:not(:disabled) {\n background: var(--cfi-ui-surface-active);\n }\n .cfi-ui-btn[data-variant=danger] {\n background: var(--cfi-ui-error-strong);\n color: var(--cfi-ui-content-inverse);\n }\n .cfi-ui-btn[data-variant=danger]:hover:not(:disabled) {\n background: linear-gradient(rgb(0 0 0 / 0.14), rgb(0 0 0 / 0.14)), var(--cfi-ui-error-strong);\n }\n .cfi-ui-btn[data-variant=link] {\n color: var(--cfi-ui-accent);\n text-decoration: underline;\n text-underline-offset: 4px;\n }\n .cfi-ui-btn[data-variant=link]:hover:not(:disabled) {\n text-decoration-thickness: 2px;\n }\n .cfi-ui-btn__icon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n }\n .cfi-ui-btn__icon > svg {\n width: 1em;\n height: 1em;\n display: block;\n }\n .cfi-ui-btn[data-size=lg] .cfi-ui-btn__icon > svg {\n width: 1.15em;\n height: 1.15em;\n }\n .cfi-ui-btn__label {\n display: inline-flex;\n align-items: center;\n gap: var(--cfi-ui-space-sm);\n min-width: 0;\n }\n .cfi-ui-btn[data-size=sm] .cfi-ui-btn__label {\n gap: var(--cfi-ui-space-xs);\n }\n .cfi-ui-btn__label > svg,\n .cfi-ui-btn > svg {\n width: 1em;\n height: 1em;\n flex: none;\n display: block;\n }\n .cfi-ui-btn__spinner {\n flex: none;\n width: 1em;\n height: 1em;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: var(--cfi-ui-radius-full);\n animation: cfi-ui-spin 620ms linear infinite;\n }\n :where(.cfi-ui-btn-group) {\n display: flex;\n align-items: center;\n gap: var(--cfi-ui-space-sm);\n flex-wrap: wrap;\n }\n .cfi-ui-btn-group[data-align=start] {\n justify-content: flex-start;\n }\n .cfi-ui-btn-group[data-align=end] {\n justify-content: flex-end;\n }\n .cfi-ui-btn-group[data-align=between] {\n justify-content: space-between;\n width: 100%;\n }\n}\n");
47
47
 
48
48
  // src/Button.tsx
49
- import { jsx, jsxs } from "react/jsx-runtime";
49
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
50
50
  var Button = forwardRef(function Button2({
51
51
  variant = "secondary",
52
52
  size = "md",
@@ -67,7 +67,16 @@ var Button = forwardRef(function Button2({
67
67
  className: cn("cfi-ui", "cfi-ui-btn", fullWidth && "cfi-ui-btn--full", className)
68
68
  };
69
69
  if (asChild) {
70
- return /* @__PURE__ */ jsx(Slot, { ref, ...styling, ...rest, children });
70
+ const slotted = isValidElement(children) ? cloneElement(
71
+ children,
72
+ void 0,
73
+ /* @__PURE__ */ jsxs(Fragment, { children: [
74
+ leadingIcon && /* @__PURE__ */ jsx("span", { className: "cfi-ui-btn__icon", children: leadingIcon }),
75
+ /* @__PURE__ */ jsx("span", { className: "cfi-ui-btn__label", children: children.props.children }),
76
+ trailingIcon && /* @__PURE__ */ jsx("span", { className: "cfi-ui-btn__icon", children: trailingIcon })
77
+ ] })
78
+ ) : children;
79
+ return /* @__PURE__ */ jsx(Slot, { ref, ...styling, ...rest, children: slotted });
71
80
  }
72
81
  return /* @__PURE__ */ jsxs(
73
82
  "button",
@@ -110,7 +119,7 @@ import { forwardRef as forwardRef3 } from "react";
110
119
  import { ChevronDown } from "lucide-react";
111
120
 
112
121
  // src/Menu.tsx
113
- import { Fragment, forwardRef as forwardRef2 } from "react";
122
+ import { Fragment as Fragment2, forwardRef as forwardRef2 } from "react";
114
123
  import * as RadixMenu from "@radix-ui/react-dropdown-menu";
115
124
  import { Check } from "lucide-react";
116
125
 
@@ -193,7 +202,7 @@ var MenuSubContent = forwardRef2(function MenuSubContent2({ className, ...rest }
193
202
  function Menu({ trigger, items, align = "end", side = "bottom", className }) {
194
203
  return /* @__PURE__ */ jsxs2(MenuRoot, { children: [
195
204
  /* @__PURE__ */ jsx2(MenuTrigger, { asChild: true, children: trigger }),
196
- /* @__PURE__ */ jsx2(MenuContent, { align, side, className, children: items.map((item) => /* @__PURE__ */ jsxs2(Fragment, { children: [
205
+ /* @__PURE__ */ jsx2(MenuContent, { align, side, className, children: items.map((item) => /* @__PURE__ */ jsxs2(Fragment2, { children: [
197
206
  item.separatorBefore && /* @__PURE__ */ jsx2(MenuSeparator, {}),
198
207
  /* @__PURE__ */ jsx2(
199
208
  MenuItem,
@@ -405,6 +414,9 @@ function SelectSeparator({
405
414
  }) {
406
415
  return /* @__PURE__ */ jsx6(RadixSelect.Separator, { className: cn("cfi-ui-menu__separator", className), ...rest });
407
416
  }
417
+ var EMPTY_VALUE = "__cfi_ui_empty__";
418
+ var toRadix = (v) => v === "" ? EMPTY_VALUE : v;
419
+ var fromRadix = (v) => v === EMPTY_VALUE ? "" : v;
408
420
  function Select({
409
421
  options,
410
422
  value,
@@ -433,9 +445,9 @@ function Select({
433
445
  return /* @__PURE__ */ jsxs6(
434
446
  SelectRoot,
435
447
  {
436
- value,
437
- onValueChange,
438
- defaultValue,
448
+ value: toRadix(value),
449
+ onValueChange: onValueChange ? (v) => onValueChange(fromRadix(v)) : void 0,
450
+ defaultValue: toRadix(defaultValue),
439
451
  disabled,
440
452
  required,
441
453
  name,
@@ -458,8 +470,8 @@ function Select({
458
470
  (group, i) => group.name ? /* @__PURE__ */ jsxs6(SelectGroup, { children: [
459
471
  i > 0 && /* @__PURE__ */ jsx6(SelectSeparator, {}),
460
472
  /* @__PURE__ */ jsx6(SelectLabel, { children: group.name }),
461
- group.options.map((o) => /* @__PURE__ */ jsx6(SelectItem, { value: o.value, disabled: o.disabled, children: o.label }, o.value))
462
- ] }, group.name) : group.options.map((o) => /* @__PURE__ */ jsx6(SelectItem, { value: o.value, disabled: o.disabled, children: o.label }, o.value))
473
+ group.options.map((o) => /* @__PURE__ */ jsx6(SelectItem, { value: toRadix(o.value), disabled: o.disabled, children: o.label }, o.value))
474
+ ] }, group.name) : group.options.map((o) => /* @__PURE__ */ jsx6(SelectItem, { value: toRadix(o.value), disabled: o.disabled, children: o.label }, o.value))
463
475
  ),
464
476
  options.length === 0 && /* @__PURE__ */ jsx6("p", { className: "cfi-ui-select-empty", children: emptyLabel })
465
477
  ] })
@@ -647,13 +659,13 @@ var Textarea = forwardRef8(function Textarea2({ invalid, className, rows = 3, ..
647
659
  });
648
660
 
649
661
  // src/Field.tsx
650
- import { Children, cloneElement, createContext, isValidElement, useContext, useId } from "react";
662
+ import { Children, cloneElement as cloneElement2, createContext, isValidElement as isValidElement2, useContext, useId } from "react";
651
663
 
652
664
  // src/Field.css
653
665
  styleInject('@layer components {\n .cfi-ui-label {\n display: inline-flex;\n align-items: center;\n gap: var(--cfi-ui-space-3xs);\n font-size: var(--cfi-ui-text-sm);\n font-weight: var(--cfi-ui-weight-medium);\n color: var(--cfi-ui-content);\n line-height: var(--cfi-ui-leading-normal);\n }\n .cfi-ui-label__required {\n color: var(--cfi-ui-error);\n font-weight: var(--cfi-ui-weight-semibold);\n }\n .cfi-ui-field {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: var(--cfi-ui-space-xs);\n }\n .cfi-ui-field__label {\n justify-self: start;\n }\n .cfi-ui-field__body {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: var(--cfi-ui-space-xs);\n min-width: 0;\n }\n .cfi-ui-field__hint,\n .cfi-ui-field__error {\n margin: 0;\n font-size: var(--cfi-ui-text-xs);\n line-height: var(--cfi-ui-leading-normal);\n }\n .cfi-ui-field__hint {\n color: var(--cfi-ui-content-muted);\n }\n .cfi-ui-field__error {\n color: var(--cfi-ui-error-text);\n font-weight: var(--cfi-ui-weight-medium);\n }\n .cfi-ui-field[data-orientation=horizontal] {\n grid-template-columns: minmax(8rem, 12rem) 1fr;\n align-items: start;\n gap: var(--cfi-ui-space-md);\n }\n .cfi-ui-field[data-orientation=horizontal] .cfi-ui-field__label {\n padding-top: 0.4375rem;\n }\n @media (max-width: 640px) {\n .cfi-ui-field[data-orientation=horizontal] {\n grid-template-columns: 1fr;\n gap: var(--cfi-ui-space-xs);\n }\n .cfi-ui-field[data-orientation=horizontal] .cfi-ui-field__label {\n padding-top: 0;\n }\n }\n .cfi-ui-fieldset {\n min-width: 0;\n margin: 0;\n padding: 0;\n border: 0;\n }\n .cfi-ui-fieldset__legend {\n padding: 0 0 var(--cfi-ui-space-sm);\n font-size: var(--cfi-ui-text-xs);\n font-weight: var(--cfi-ui-weight-semibold);\n letter-spacing: var(--cfi-ui-tracking-caps);\n text-transform: uppercase;\n color: var(--cfi-ui-content-muted);\n }\n .cfi-ui-fieldset__body {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: var(--cfi-ui-space-md);\n }\n .cfi-ui-fieldset[data-columns="2"] .cfi-ui-fieldset__body {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n .cfi-ui-fieldset[data-columns="3"] .cfi-ui-fieldset__body {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n }\n @media (max-width: 720px) {\n .cfi-ui-fieldset[data-columns="2"] .cfi-ui-fieldset__body,\n .cfi-ui-fieldset[data-columns="3"] .cfi-ui-fieldset__body {\n grid-template-columns: 1fr;\n }\n }\n}\n');
654
666
 
655
667
  // src/Field.tsx
656
- import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
668
+ import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
657
669
  function Label3({ required, className, children, ...rest }) {
658
670
  return /* @__PURE__ */ jsxs10("label", { className: cn("cfi-ui", "cfi-ui-label", className), ...rest, children: [
659
671
  children,
@@ -690,11 +702,11 @@ function Field({
690
702
  }
691
703
  function FieldControl({ children }) {
692
704
  const ctx = useContext(FieldContext);
693
- if (!ctx) return /* @__PURE__ */ jsx10(Fragment2, { children });
705
+ if (!ctx) return /* @__PURE__ */ jsx10(Fragment3, { children });
694
706
  const only = Children.count(children) === 1 ? Children.toArray(children)[0] : null;
695
- if (!only || !isValidElement(only)) return /* @__PURE__ */ jsx10(Fragment2, { children });
707
+ if (!only || !isValidElement2(only)) return /* @__PURE__ */ jsx10(Fragment3, { children });
696
708
  const props = only.props;
697
- return cloneElement(only, {
709
+ return cloneElement2(only, {
698
710
  id: props.id ?? ctx.controlId,
699
711
  // A control that already declares its own description keeps it — the
700
712
  // field's id is appended rather than replacing it.
@@ -775,7 +787,7 @@ import * as RadixDialog from "@radix-ui/react-dialog";
775
787
  import { X as X2 } from "lucide-react";
776
788
 
777
789
  // src/Dialog.css
778
- styleInject("@layer components {\n .cfi-ui-dialog__overlay {\n position: fixed;\n inset: 0;\n z-index: var(--cfi-ui-z-overlay);\n background: var(--cfi-ui-overlay);\n animation: cfi-ui-fade-in var(--cfi-ui-transition-base);\n }\n .cfi-ui-dialog {\n position: fixed;\n z-index: var(--cfi-ui-z-modal);\n display: flex;\n flex-direction: column;\n background: var(--cfi-ui-surface);\n color: var(--cfi-ui-content);\n border: 1px solid var(--cfi-ui-border);\n box-shadow: var(--cfi-ui-shadow-lg);\n font-family: var(--cfi-ui-font);\n font-size: var(--cfi-ui-text-sm);\n }\n .cfi-ui-dialog[data-side=center] {\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: calc(100vw - 2 * var(--cfi-ui-space-md));\n max-height: calc(100vh - 2 * var(--cfi-ui-space-xl));\n border-radius: var(--cfi-ui-radius-lg);\n animation: cfi-ui-zoom-in var(--cfi-ui-transition-base);\n }\n .cfi-ui-dialog[data-side=center][data-size=sm] {\n max-width: 26rem;\n }\n .cfi-ui-dialog[data-side=center][data-size=md] {\n max-width: 34rem;\n }\n .cfi-ui-dialog[data-side=center][data-size=lg] {\n max-width: 48rem;\n }\n .cfi-ui-dialog[data-side=center][data-size=xl] {\n max-width: 64rem;\n }\n .cfi-ui-dialog[data-side=center][data-size=full] {\n max-width: none;\n width: calc(100vw - 2 * var(--cfi-ui-space-xl));\n height: calc(100vh - 2 * var(--cfi-ui-space-xl));\n max-height: none;\n }\n .cfi-ui-dialog[data-side=right],\n .cfi-ui-dialog[data-side=left] {\n top: 0;\n bottom: 0;\n height: 100vh;\n max-height: 100vh;\n width: calc(100vw - var(--cfi-ui-space-xl));\n border-radius: 0;\n border: 0;\n }\n .cfi-ui-dialog[data-side=right] {\n right: 0;\n border-right: 0;\n animation: cfi-ui-slide-in-right var(--cfi-ui-transition-base);\n }\n .cfi-ui-dialog[data-side=left] {\n left: 0;\n border-left: 0;\n animation: cfi-ui-slide-in-left var(--cfi-ui-transition-base);\n }\n .cfi-ui-dialog[data-side=right][data-size=sm],\n .cfi-ui-dialog[data-side=left][data-size=sm] {\n max-width: 22rem;\n }\n .cfi-ui-dialog[data-side=right][data-size=md],\n .cfi-ui-dialog[data-side=left][data-size=md] {\n max-width: 24rem;\n }\n .cfi-ui-dialog[data-side=right][data-size=lg],\n .cfi-ui-dialog[data-side=left][data-size=lg] {\n max-width: 42rem;\n }\n .cfi-ui-dialog[data-side=right][data-size=xl],\n .cfi-ui-dialog[data-side=left][data-size=xl] {\n max-width: 56rem;\n }\n .cfi-ui-dialog[data-side=right][data-size=full],\n .cfi-ui-dialog[data-side=left][data-size=full] {\n max-width: none;\n }\n .cfi-ui-dialog__header {\n flex: none;\n display: grid;\n gap: var(--cfi-ui-space-xs);\n padding: var(--cfi-ui-space-md) 3rem var(--cfi-ui-space-md) var(--cfi-ui-space-md);\n border-bottom: 1px solid var(--cfi-ui-border);\n }\n .cfi-ui-dialog__title {\n margin: 0;\n font-size: var(--cfi-ui-text-lg);\n font-weight: var(--cfi-ui-weight-semibold);\n line-height: var(--cfi-ui-leading-tight);\n letter-spacing: var(--cfi-letter-spacing-tight, -0.015em);\n color: var(--cfi-ui-content);\n text-wrap: balance;\n }\n .cfi-ui-sheet__title {\n font-size: var(--cfi-ui-text-base);\n }\n .cfi-ui-dialog__description {\n margin: 0;\n font-size: var(--cfi-ui-text-sm);\n line-height: var(--cfi-ui-leading-normal);\n color: var(--cfi-ui-content-muted);\n }\n :where(.cfi-ui-dialog__body) {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n padding: var(--cfi-ui-space-md);\n }\n .cfi-ui-dialog__footer {\n flex: none;\n padding: var(--cfi-ui-space-md);\n border-top: 1px solid var(--cfi-ui-border);\n background: var(--cfi-ui-surface-sunken);\n }\n .cfi-ui-dialog[data-side=center] .cfi-ui-dialog__footer {\n border-bottom-left-radius: var(--cfi-ui-radius-lg);\n border-bottom-right-radius: var(--cfi-ui-radius-lg);\n }\n .cfi-ui-dialog__close {\n position: absolute;\n top: var(--cfi-ui-space-sm);\n right: var(--cfi-ui-space-sm);\n }\n .cfi-ui-dialog:not(:has(.cfi-ui-dialog__header)) .cfi-ui-dialog__body {\n padding-right: 3rem;\n }\n}\n");
790
+ styleInject("@layer components {\n .cfi-ui-dialog__overlay {\n position: fixed;\n inset: 0;\n z-index: var(--cfi-ui-z-overlay);\n background: var(--cfi-ui-overlay);\n animation: cfi-ui-fade-in var(--cfi-ui-transition-base);\n }\n .cfi-ui-dialog {\n position: fixed;\n z-index: var(--cfi-ui-z-modal);\n display: flex;\n flex-direction: column;\n background: var(--cfi-ui-surface);\n color: var(--cfi-ui-content);\n border: 1px solid var(--cfi-ui-border);\n box-shadow: var(--cfi-ui-shadow-lg);\n font-family: var(--cfi-ui-font);\n font-size: var(--cfi-ui-text-sm);\n }\n .cfi-ui-dialog[data-side=center] {\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: calc(100vw - 2 * var(--cfi-ui-space-md));\n max-height: calc(100vh - 2 * var(--cfi-ui-space-xl));\n border-radius: var(--cfi-ui-radius-lg);\n animation: cfi-ui-zoom-in var(--cfi-ui-transition-base);\n }\n .cfi-ui-dialog[data-side=center][data-size=sm] {\n max-width: 26rem;\n }\n .cfi-ui-dialog[data-side=center][data-size=md] {\n max-width: 34rem;\n }\n .cfi-ui-dialog[data-side=center][data-size=lg] {\n max-width: 48rem;\n }\n .cfi-ui-dialog[data-side=center][data-size=xl] {\n max-width: 64rem;\n }\n .cfi-ui-dialog[data-side=center][data-size=full] {\n max-width: none;\n width: calc(100vw - 2 * var(--cfi-ui-space-xl));\n height: calc(100vh - 2 * var(--cfi-ui-space-xl));\n max-height: none;\n }\n .cfi-ui-dialog[data-side=right],\n .cfi-ui-dialog[data-side=left] {\n top: 0;\n bottom: 0;\n height: 100vh;\n max-height: 100vh;\n width: calc(100vw - var(--cfi-ui-space-xl));\n border-radius: 0;\n border: 0;\n }\n .cfi-ui-dialog[data-side=right] {\n right: 0;\n border-right: 0;\n animation: cfi-ui-slide-in-right var(--cfi-ui-transition-base);\n }\n .cfi-ui-dialog[data-side=left] {\n left: 0;\n border-left: 0;\n animation: cfi-ui-slide-in-left var(--cfi-ui-transition-base);\n }\n .cfi-ui-dialog[data-side=right][data-size=sm],\n .cfi-ui-dialog[data-side=left][data-size=sm] {\n max-width: 22rem;\n }\n .cfi-ui-dialog[data-side=right][data-size=md],\n .cfi-ui-dialog[data-side=left][data-size=md] {\n max-width: 24rem;\n }\n .cfi-ui-dialog[data-side=right][data-size=lg],\n .cfi-ui-dialog[data-side=left][data-size=lg] {\n max-width: 42rem;\n }\n .cfi-ui-dialog[data-side=right][data-size=xl],\n .cfi-ui-dialog[data-side=left][data-size=xl] {\n max-width: 56rem;\n }\n .cfi-ui-dialog[data-side=right][data-size=full],\n .cfi-ui-dialog[data-side=left][data-size=full] {\n max-width: none;\n }\n .cfi-ui-dialog__header {\n flex: none;\n display: grid;\n gap: var(--cfi-ui-space-xs);\n padding: var(--cfi-ui-space-md) 3rem var(--cfi-ui-space-md) var(--cfi-ui-space-md);\n border-bottom: 1px solid var(--cfi-ui-border);\n }\n .cfi-ui-dialog__title {\n margin: 0;\n font-size: var(--cfi-ui-text-lg);\n font-weight: var(--cfi-ui-weight-semibold);\n line-height: var(--cfi-ui-leading-tight);\n letter-spacing: var(--cfi-letter-spacing-tight, -0.015em);\n color: var(--cfi-ui-content);\n text-wrap: balance;\n }\n .cfi-ui-sheet__title {\n font-size: var(--cfi-ui-text-base);\n }\n .cfi-ui-dialog__description {\n margin: 0;\n font-size: var(--cfi-ui-text-sm);\n line-height: var(--cfi-ui-leading-normal);\n color: var(--cfi-ui-content-muted);\n }\n :where(.cfi-ui-dialog__body) {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n padding: var(--cfi-ui-space-md);\n }\n .cfi-ui-dialog__footer {\n flex: none;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n gap: var(--cfi-ui-space-sm);\n padding: var(--cfi-ui-space-md);\n border-top: 1px solid var(--cfi-ui-border);\n background: var(--cfi-ui-surface-sunken);\n }\n .cfi-ui-dialog[data-side=center] .cfi-ui-dialog__footer {\n border-bottom-left-radius: var(--cfi-ui-radius-lg);\n border-bottom-right-radius: var(--cfi-ui-radius-lg);\n }\n .cfi-ui-dialog__close {\n position: absolute;\n top: var(--cfi-ui-space-sm);\n right: var(--cfi-ui-space-sm);\n }\n .cfi-ui-dialog:not(:has(.cfi-ui-dialog__header)) .cfi-ui-dialog__body {\n padding-right: 3rem;\n }\n}\n");
779
791
 
780
792
  // src/Dialog.tsx
781
793
  import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
@@ -1075,7 +1087,7 @@ function CreatableSelect({
1075
1087
  }
1076
1088
 
1077
1089
  // src/Combobox.tsx
1078
- import { Fragment as Fragment3, useEffect, useId as useId2, useMemo as useMemo3, useRef, useState as useState3 } from "react";
1090
+ import { Fragment as Fragment4, useEffect, useId as useId2, useMemo as useMemo3, useRef, useState as useState3 } from "react";
1079
1091
  import { Check as Check4, ChevronDown as ChevronDown3, Search, X as X3 } from "lucide-react";
1080
1092
 
1081
1093
  // src/Combobox.css
@@ -1299,7 +1311,7 @@ function Combobox({
1299
1311
  option.value
1300
1312
  );
1301
1313
  });
1302
- if (!run.group) return /* @__PURE__ */ jsx15(Fragment3, { children: rows }, `ungrouped-${runIndex}`);
1314
+ if (!run.group) return /* @__PURE__ */ jsx15(Fragment4, { children: rows }, `ungrouped-${runIndex}`);
1303
1315
  return /* @__PURE__ */ jsxs15("div", { role: "group", "aria-label": run.group, children: [
1304
1316
  /* @__PURE__ */ jsx15("p", { className: "cfi-ui-combobox__group-label", "aria-hidden": "true", children: run.group }),
1305
1317
  rows
@@ -1317,7 +1329,7 @@ function Combobox({
1317
1329
  // src/Tooltip.tsx
1318
1330
  import { forwardRef as forwardRef12 } from "react";
1319
1331
  import * as RadixTooltip from "@radix-ui/react-tooltip";
1320
- import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
1332
+ import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
1321
1333
  var TooltipProvider = RadixTooltip.Provider;
1322
1334
  var TooltipRoot = RadixTooltip.Root;
1323
1335
  var TooltipTrigger = RadixTooltip.Trigger;
@@ -1339,7 +1351,7 @@ var TooltipContent = forwardRef12(function TooltipContent2({ className, children
1339
1351
  ) });
1340
1352
  });
1341
1353
  function Tooltip({ content, side = "top", align = "center", delay = 300, disabled, children }) {
1342
- if (disabled || content == null || content === "") return /* @__PURE__ */ jsx16(Fragment4, { children });
1354
+ if (disabled || content == null || content === "") return /* @__PURE__ */ jsx16(Fragment5, { children });
1343
1355
  return /* @__PURE__ */ jsx16(RadixTooltip.Provider, { delayDuration: delay, children: /* @__PURE__ */ jsxs16(TooltipRoot, { children: [
1344
1356
  /* @__PURE__ */ jsx16(TooltipTrigger, { asChild: true, children }),
1345
1357
  /* @__PURE__ */ jsx16(TooltipContent, { side, align, children: content })
@@ -2200,7 +2212,7 @@ function Pagination({
2200
2212
  }
2201
2213
 
2202
2214
  // src/ListToolbar.css
2203
- styleInject("@layer components {\n :where(.cfi-ui-list-toolbar) {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--cfi-ui-space-sm);\n min-width: 0;\n }\n .cfi-ui-list-toolbar__search {\n flex: 1 1 14rem;\n min-width: 0;\n max-width: 22rem;\n }\n .cfi-ui-list-toolbar__filters {\n display: flex;\n align-items: center;\n min-width: 0;\n flex: 0 1 auto;\n }\n .cfi-ui-list-toolbar__actions {\n display: flex;\n align-items: center;\n gap: var(--cfi-ui-space-xs);\n margin-inline-start: auto;\n }\n @media (max-width: 40rem) {\n .cfi-ui-list-toolbar__search,\n .cfi-ui-list-toolbar__filters,\n .cfi-ui-list-toolbar__actions {\n flex: 1 1 100%;\n max-width: none;\n margin-inline-start: 0;\n }\n }\n}\n");
2215
+ styleInject("@layer components {\n :where(.cfi-ui-list-toolbar) {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--cfi-ui-space-md);\n min-width: 0;\n }\n .cfi-ui-list-toolbar__search {\n flex: 1 1 14rem;\n min-width: 0;\n max-width: 22rem;\n }\n .cfi-ui-list-toolbar__filters {\n display: flex;\n align-items: center;\n gap: var(--cfi-ui-space-sm);\n min-width: 0;\n flex: 0 1 auto;\n }\n .cfi-ui-list-toolbar__actions {\n display: flex;\n align-items: center;\n gap: var(--cfi-ui-space-xs);\n margin-inline-start: auto;\n }\n @media (max-width: 40rem) {\n .cfi-ui-list-toolbar__search,\n .cfi-ui-list-toolbar__filters,\n .cfi-ui-list-toolbar__actions {\n flex: 1 1 100%;\n max-width: none;\n margin-inline-start: 0;\n }\n }\n}\n");
2204
2216
 
2205
2217
  // src/ListToolbar.tsx
2206
2218
  import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
package/package.json CHANGED
@@ -1,56 +1,56 @@
1
- {
2
- "name": "@campfire-interactive/ui",
3
- "version": "0.8.0",
4
- "description": "Shared UI primitives for the Campfire Suite — Radix behavior, plain CSS styled entirely from the design tokens, no Tailwind required",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
12
- }
13
- },
14
- "files": [
15
- "dist"
16
- ],
17
- "scripts": {
18
- "build": "tsup",
19
- "prepublishOnly": "npm run build",
20
- "dev": "tsup --watch",
21
- "test": "vitest run",
22
- "typecheck": "tsc --noEmit"
23
- },
24
- "peerDependencies": {
25
- "react": "^18.0.0 || ^19.0.0",
26
- "react-dom": "^18.0.0 || ^19.0.0"
27
- },
28
- "dependencies": {
29
- "@campfire-interactive/design-tokens": "*",
30
- "@radix-ui/react-accordion": "^1.2.12",
31
- "@radix-ui/react-checkbox": "^1.3.3",
32
- "@radix-ui/react-dialog": "^1.1.15",
33
- "@radix-ui/react-dropdown-menu": "^2.1.16",
34
- "@radix-ui/react-popover": "^1.1.15",
35
- "@radix-ui/react-select": "^2.2.6",
36
- "@radix-ui/react-slider": "^1.3.6",
37
- "@radix-ui/react-slot": "^1.2.3",
38
- "@radix-ui/react-switch": "^1.2.6",
39
- "@radix-ui/react-tabs": "^1.1.13",
40
- "@radix-ui/react-toggle-group": "^1.1.11",
41
- "@radix-ui/react-tooltip": "^1.2.8",
42
- "lucide-react": "^0.487.0"
43
- },
44
- "devDependencies": {
45
- "@types/react": "^19.0.0",
46
- "@types/react-dom": "^19.0.0",
47
- "react": "^19.0.0",
48
- "react-dom": "^19.0.0",
49
- "tsup": "^8.0.0",
50
- "typescript": "^5.3.3"
51
- },
52
- "publishConfig": {
53
- "registry": "https://registry.npmjs.org",
54
- "access": "public"
55
- }
56
- }
1
+ {
2
+ "name": "@campfire-interactive/ui",
3
+ "version": "0.9.1",
4
+ "description": "Shared UI primitives for the Campfire Suite — Radix behavior, plain CSS styled entirely from the design tokens, no Tailwind required",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsup",
19
+ "prepublishOnly": "npm run build",
20
+ "dev": "tsup --watch",
21
+ "test": "vitest run",
22
+ "typecheck": "tsc --noEmit"
23
+ },
24
+ "peerDependencies": {
25
+ "react": "^18.0.0 || ^19.0.0",
26
+ "react-dom": "^18.0.0 || ^19.0.0"
27
+ },
28
+ "dependencies": {
29
+ "@campfire-interactive/design-tokens": "*",
30
+ "@radix-ui/react-accordion": "^1.2.12",
31
+ "@radix-ui/react-checkbox": "^1.3.3",
32
+ "@radix-ui/react-dialog": "^1.1.15",
33
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
34
+ "@radix-ui/react-popover": "^1.1.15",
35
+ "@radix-ui/react-select": "^2.2.6",
36
+ "@radix-ui/react-slider": "^1.3.6",
37
+ "@radix-ui/react-slot": "^1.2.3",
38
+ "@radix-ui/react-switch": "^1.2.6",
39
+ "@radix-ui/react-tabs": "^1.1.13",
40
+ "@radix-ui/react-toggle-group": "^1.1.11",
41
+ "@radix-ui/react-tooltip": "^1.2.8",
42
+ "lucide-react": "^0.487.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/react": "^19.0.0",
46
+ "@types/react-dom": "^19.0.0",
47
+ "react": "^19.0.0",
48
+ "react-dom": "^19.0.0",
49
+ "tsup": "^8.0.0",
50
+ "typescript": "^5.3.3"
51
+ },
52
+ "publishConfig": {
53
+ "registry": "https://registry.npmjs.org",
54
+ "access": "public"
55
+ }
56
+ }