@campfire-interactive/ui 0.9.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 +6 -3
- package/dist/index.js +23 -14
- package/package.json +1 -1
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`
|
|
46
|
-
*
|
|
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
|
-
|
|
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(
|
|
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,
|
|
@@ -650,13 +659,13 @@ var Textarea = forwardRef8(function Textarea2({ invalid, className, rows = 3, ..
|
|
|
650
659
|
});
|
|
651
660
|
|
|
652
661
|
// src/Field.tsx
|
|
653
|
-
import { Children, cloneElement, createContext, isValidElement, useContext, useId } from "react";
|
|
662
|
+
import { Children, cloneElement as cloneElement2, createContext, isValidElement as isValidElement2, useContext, useId } from "react";
|
|
654
663
|
|
|
655
664
|
// src/Field.css
|
|
656
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');
|
|
657
666
|
|
|
658
667
|
// src/Field.tsx
|
|
659
|
-
import { Fragment as
|
|
668
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
660
669
|
function Label3({ required, className, children, ...rest }) {
|
|
661
670
|
return /* @__PURE__ */ jsxs10("label", { className: cn("cfi-ui", "cfi-ui-label", className), ...rest, children: [
|
|
662
671
|
children,
|
|
@@ -693,11 +702,11 @@ function Field({
|
|
|
693
702
|
}
|
|
694
703
|
function FieldControl({ children }) {
|
|
695
704
|
const ctx = useContext(FieldContext);
|
|
696
|
-
if (!ctx) return /* @__PURE__ */ jsx10(
|
|
705
|
+
if (!ctx) return /* @__PURE__ */ jsx10(Fragment3, { children });
|
|
697
706
|
const only = Children.count(children) === 1 ? Children.toArray(children)[0] : null;
|
|
698
|
-
if (!only || !
|
|
707
|
+
if (!only || !isValidElement2(only)) return /* @__PURE__ */ jsx10(Fragment3, { children });
|
|
699
708
|
const props = only.props;
|
|
700
|
-
return
|
|
709
|
+
return cloneElement2(only, {
|
|
701
710
|
id: props.id ?? ctx.controlId,
|
|
702
711
|
// A control that already declares its own description keeps it — the
|
|
703
712
|
// field's id is appended rather than replacing it.
|
|
@@ -1078,7 +1087,7 @@ function CreatableSelect({
|
|
|
1078
1087
|
}
|
|
1079
1088
|
|
|
1080
1089
|
// src/Combobox.tsx
|
|
1081
|
-
import { Fragment as
|
|
1090
|
+
import { Fragment as Fragment4, useEffect, useId as useId2, useMemo as useMemo3, useRef, useState as useState3 } from "react";
|
|
1082
1091
|
import { Check as Check4, ChevronDown as ChevronDown3, Search, X as X3 } from "lucide-react";
|
|
1083
1092
|
|
|
1084
1093
|
// src/Combobox.css
|
|
@@ -1302,7 +1311,7 @@ function Combobox({
|
|
|
1302
1311
|
option.value
|
|
1303
1312
|
);
|
|
1304
1313
|
});
|
|
1305
|
-
if (!run.group) return /* @__PURE__ */ jsx15(
|
|
1314
|
+
if (!run.group) return /* @__PURE__ */ jsx15(Fragment4, { children: rows }, `ungrouped-${runIndex}`);
|
|
1306
1315
|
return /* @__PURE__ */ jsxs15("div", { role: "group", "aria-label": run.group, children: [
|
|
1307
1316
|
/* @__PURE__ */ jsx15("p", { className: "cfi-ui-combobox__group-label", "aria-hidden": "true", children: run.group }),
|
|
1308
1317
|
rows
|
|
@@ -1320,7 +1329,7 @@ function Combobox({
|
|
|
1320
1329
|
// src/Tooltip.tsx
|
|
1321
1330
|
import { forwardRef as forwardRef12 } from "react";
|
|
1322
1331
|
import * as RadixTooltip from "@radix-ui/react-tooltip";
|
|
1323
|
-
import { Fragment as
|
|
1332
|
+
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1324
1333
|
var TooltipProvider = RadixTooltip.Provider;
|
|
1325
1334
|
var TooltipRoot = RadixTooltip.Root;
|
|
1326
1335
|
var TooltipTrigger = RadixTooltip.Trigger;
|
|
@@ -1342,7 +1351,7 @@ var TooltipContent = forwardRef12(function TooltipContent2({ className, children
|
|
|
1342
1351
|
) });
|
|
1343
1352
|
});
|
|
1344
1353
|
function Tooltip({ content, side = "top", align = "center", delay = 300, disabled, children }) {
|
|
1345
|
-
if (disabled || content == null || content === "") return /* @__PURE__ */ jsx16(
|
|
1354
|
+
if (disabled || content == null || content === "") return /* @__PURE__ */ jsx16(Fragment5, { children });
|
|
1346
1355
|
return /* @__PURE__ */ jsx16(RadixTooltip.Provider, { delayDuration: delay, children: /* @__PURE__ */ jsxs16(TooltipRoot, { children: [
|
|
1347
1356
|
/* @__PURE__ */ jsx16(TooltipTrigger, { asChild: true, children }),
|
|
1348
1357
|
/* @__PURE__ */ jsx16(TooltipContent, { side, align, children: content })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@campfire-interactive/ui",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Shared UI primitives for the Campfire Suite — Radix behavior, plain CSS styled entirely from the design tokens, no Tailwind required",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|