@warmio/ui 1.0.0 → 1.1.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/README.md CHANGED
@@ -4,10 +4,25 @@ Portable React components shared by Warm products. Install this package with the
4
4
  `@warmio/design@1.0.0` CSS contract, import `@warmio/design/globals.css` once, and add the package's
5
5
  compiled files to Tailwind's source detection:
6
6
 
7
+ ## Why these files are separate
8
+
9
+ Independently deployed Warm products cannot import runtime code from the private `warm-app`
10
+ workspace, so `libraries/public-ui/` must be a standalone public package rather than another private
11
+ workspace entry point. `tools/tasks/check-ui-package.mjs` is a dedicated package-boundary check
12
+ because the existing application checks do not build, pack, and inspect a public npm tarball.
13
+ `.github/workflows/publish-ui.yml` is separate from application deployment workflows so npm trusted
14
+ publishing can bind credentials to one reviewable package-release boundary without granting an app
15
+ deployment permission to publish packages.
16
+
7
17
  ```css
8
18
  @import '@warmio/design/globals.css';
9
19
  @source '../node_modules/@warmio/ui/dist';
10
20
  ```
11
21
 
12
- The initial public surface contains the Warm badge, logo, and complete responsive sidebar family.
22
+ The `1.1.0` public surface contains the Warm badge, logo, Button, Text and `StackedDisplay`,
23
+ DropdownMenu, Sheet, and complete responsive Sidebar family including `SidebarBrand` and
24
+ `SidebarAccountTrigger`. Styling is sealed: use documented semantic presentations and layout
25
+ wrappers, never `className` or `style` overrides. DropdownMenu interaction feedback requires the
26
+ exact public peer `cuelume@0.1.0`.
27
+
13
28
  The published artifact is standalone and never imports private `warm-app` workspace packages.
package/dist/button.js ADDED
@@ -0,0 +1,10 @@
1
+ import {
2
+ Button,
3
+ ButtonLink
4
+ } from "./chunks/chunk-KCEDMF2I.js";
5
+ import "./chunks/chunk-T2TXMN3G.js";
6
+ import "./chunks/chunk-VIB7OX7D.js";
7
+ export {
8
+ Button,
9
+ ButtonLink
10
+ };
@@ -0,0 +1,85 @@
1
+ import {
2
+ cn
3
+ } from "./chunk-VIB7OX7D.js";
4
+
5
+ // ../ui/src/warmio/text.tsx
6
+ import * as React from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ var textClassNameByVariant = {
9
+ display: "block text-[1.35rem] font-normal leading-snug tracking-normal [font-family:var(--font-display)] @3xl/main:text-[1.875rem]",
10
+ displayCompact: "block text-xl font-normal leading-snug tracking-normal [font-family:var(--font-display)] @3xl/main:text-2xl",
11
+ overline: "block font-mono text-xs font-bold uppercase tracking-[0.18em]",
12
+ micro: "text-[10px] font-normal leading-tight",
13
+ microStrong: "text-[10px] font-bold leading-tight",
14
+ body: "text-sm",
15
+ caption: "text-xs",
16
+ helper: "text-xs",
17
+ sectionTitle: "text-sm font-bold leading-6"
18
+ };
19
+ var defaultTextElementByVariant = {
20
+ display: "span",
21
+ displayCompact: "span",
22
+ overline: "span",
23
+ micro: "span",
24
+ microStrong: "span",
25
+ body: "p",
26
+ caption: "span",
27
+ helper: "small",
28
+ sectionTitle: "h3"
29
+ };
30
+ var textClassNameByTone = {
31
+ default: "",
32
+ muted: "text-muted-foreground",
33
+ foreground: "text-foreground",
34
+ primary: "text-primary",
35
+ success: "text-success",
36
+ warning: "text-warning"
37
+ };
38
+ var textClassNameByAlign = {
39
+ start: "text-left",
40
+ center: "text-center",
41
+ end: "text-right"
42
+ };
43
+ function Text({
44
+ as,
45
+ variant = "micro",
46
+ tone = "default",
47
+ align,
48
+ numeric = false,
49
+ truncate = false,
50
+ className: _className,
51
+ style: _style,
52
+ ...props
53
+ }) {
54
+ const Component = as ?? defaultTextElementByVariant[variant];
55
+ return React.createElement(Component, {
56
+ ...props,
57
+ className: cn(
58
+ textClassNameByVariant[variant],
59
+ textClassNameByTone[tone],
60
+ align && textClassNameByAlign[align],
61
+ numeric && "tabular-nums",
62
+ truncate && "truncate"
63
+ )
64
+ });
65
+ }
66
+ Text.displayName = "WarmText";
67
+ function StackedDisplay({
68
+ align = "start",
69
+ firstLine,
70
+ presentation = "dashboard",
71
+ secondLine
72
+ }) {
73
+ const firstLineClassName = presentation === "welcome" ? "block text-muted-foreground font-editorial" : "block text-foreground";
74
+ const secondLineClassName = presentation === "welcome" ? "block text-foreground" : "block text-muted-foreground font-editorial";
75
+ return /* @__PURE__ */ jsxs(Text, { as: "span", variant: "displayCompact", align, children: [
76
+ /* @__PURE__ */ jsx("span", { className: firstLineClassName, children: firstLine }),
77
+ /* @__PURE__ */ jsx("span", { className: secondLineClassName, children: secondLine })
78
+ ] });
79
+ }
80
+ StackedDisplay.displayName = "WarmStackedDisplay";
81
+
82
+ export {
83
+ Text,
84
+ StackedDisplay
85
+ };
@@ -0,0 +1,124 @@
1
+ import {
2
+ Button,
3
+ buttonVariants
4
+ } from "./chunk-T2TXMN3G.js";
5
+ import {
6
+ cn
7
+ } from "./chunk-VIB7OX7D.js";
8
+
9
+ // ../ui/src/warmio/button.tsx
10
+ import * as React from "react";
11
+ import { jsx } from "react/jsx-runtime";
12
+ var buttonPresentationSize = {
13
+ assistantIcon: "icon-xs",
14
+ assistantRoundIcon: "icon-round",
15
+ composerIcon: "icon-sm",
16
+ default: "default",
17
+ compact: "sm",
18
+ controlPeer: "default",
19
+ editPill: "sm",
20
+ hero: "lg",
21
+ menuOption: "option",
22
+ promptCategory: "default",
23
+ promptOption: "option",
24
+ sidebarIcon: "icon",
25
+ tableHeader: "default",
26
+ threadMore: "icon-xs",
27
+ threadNew: "sm",
28
+ touch: "default"
29
+ };
30
+ var buttonPresentationClasses = {
31
+ assistantIcon: "size-6 p-1 active:scale-90",
32
+ composerIcon: "size-7 p-1",
33
+ editPill: "rounded-full px-3",
34
+ hero: "h-12 rounded-xl bg-clip-border px-6 py-2 text-base font-bold",
35
+ promptCategory: "h-9 gap-1.5 rounded-full border border-border bg-background px-3.5 text-sm font-normal text-foreground shadow-xs transition-colors hover:bg-muted",
36
+ promptOption: "min-h-16 items-start justify-start gap-2 rounded-xl px-3 py-3 text-sm",
37
+ sidebarIcon: "bg-clip-border text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground dark:hover:bg-white/6 dark:hover:text-sidebar-foreground",
38
+ // Flush with WarmTableHead/Cell edge inset so labels align with row content.
39
+ tableHeader: "h-auto min-h-0 w-full justify-start gap-1 rounded-lg px-0 py-0 font-normal text-muted-foreground hover:bg-transparent hover:text-foreground data-[align=end]:justify-end",
40
+ touch: "min-h-11",
41
+ threadMore: "size-6 p-0",
42
+ threadNew: "h-8 justify-start gap-2 rounded-lg px-2.5 text-sm font-normal hover:bg-muted data-active:bg-muted"
43
+ };
44
+ var buttonVariantBase = {
45
+ apple: "outline",
46
+ default: "default",
47
+ destructive: "destructive",
48
+ ghost: "ghost",
49
+ outline: "outline"
50
+ };
51
+ var buttonVariantClasses = {
52
+ apple: "border-black bg-black text-white hover:bg-black/90 hover:text-white [&_.warm-loader-logo]:invert"
53
+ };
54
+ var buttonInputAlignmentClasses = {
55
+ default: "bg-clip-border py-1"
56
+ };
57
+ function resolveButton(presentation, size, variant) {
58
+ const resolvedSize = size ?? buttonPresentationSize[presentation];
59
+ const presentationClassName = !size && buttonPresentationClasses[presentation] ? buttonPresentationClasses[presentation] : buttonInputAlignmentClasses[resolvedSize];
60
+ return {
61
+ presentationClassName,
62
+ primitiveVariant: buttonVariantBase[variant],
63
+ resolvedSize,
64
+ variantClassName: buttonVariantClasses[variant]
65
+ };
66
+ }
67
+ var Button2 = React.forwardRef(function Button3({
68
+ className: _className,
69
+ presentation = "default",
70
+ size,
71
+ style: _style,
72
+ variant = "default",
73
+ width,
74
+ ...props
75
+ }, ref) {
76
+ const { presentationClassName, primitiveVariant, resolvedSize, variantClassName } = resolveButton(
77
+ presentation,
78
+ size,
79
+ variant
80
+ );
81
+ return /* @__PURE__ */ jsx(
82
+ Button,
83
+ {
84
+ ...props,
85
+ ref,
86
+ variant: primitiveVariant,
87
+ size: resolvedSize,
88
+ "data-variant": variant,
89
+ className: cn(presentationClassName, variantClassName, width === "full" && "w-full")
90
+ }
91
+ );
92
+ });
93
+ Button2.displayName = "WarmButton";
94
+ var ButtonLink = React.forwardRef(function ButtonLink2({ children, presentation = "default", size, variant = "default", width, ...props }, ref) {
95
+ const { presentationClassName, primitiveVariant, resolvedSize, variantClassName } = resolveButton(
96
+ presentation,
97
+ size,
98
+ variant
99
+ );
100
+ return /* @__PURE__ */ jsx(
101
+ "a",
102
+ {
103
+ ...props,
104
+ ref,
105
+ "data-slot": "button",
106
+ "data-variant": variant,
107
+ "data-size": resolvedSize,
108
+ className: cn(
109
+ buttonVariants({ size: resolvedSize, variant: primitiveVariant }),
110
+ presentationClassName,
111
+ variantClassName,
112
+ "focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-ring",
113
+ width === "full" && "w-full"
114
+ ),
115
+ children
116
+ }
117
+ );
118
+ });
119
+ ButtonLink.displayName = "WarmButtonLink";
120
+
121
+ export {
122
+ Button2 as Button,
123
+ ButtonLink
124
+ };
@@ -0,0 +1,135 @@
1
+ import {
2
+ Button
3
+ } from "./chunk-T2TXMN3G.js";
4
+ import {
5
+ cn
6
+ } from "./chunk-VIB7OX7D.js";
7
+
8
+ // ../ui/src/components/sheet.tsx
9
+ import * as React from "react";
10
+ import { Dialog as SheetPrimitive } from "@base-ui/react/dialog";
11
+ import { XIcon } from "lucide-react";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+ function Sheet(props) {
14
+ return /* @__PURE__ */ jsx(SheetPrimitive.Root, { ...props });
15
+ }
16
+ function SheetTrigger({ asChild = false, children, render, ...props }) {
17
+ const resolvedRender = render ?? (asChild && React.isValidElement(children) ? children : void 0);
18
+ return /* @__PURE__ */ jsx(SheetPrimitive.Trigger, { "data-slot": "sheet-trigger", render: resolvedRender, ...props, children: resolvedRender ? void 0 : children });
19
+ }
20
+ function SheetClose({ asChild = false, children, render, ...props }) {
21
+ const resolvedRender = render ?? (asChild && React.isValidElement(children) ? children : void 0);
22
+ return /* @__PURE__ */ jsx(SheetPrimitive.Close, { "data-slot": "sheet-close", render: resolvedRender, ...props, children: resolvedRender ? void 0 : children });
23
+ }
24
+ function SheetPortal({ ...props }) {
25
+ return /* @__PURE__ */ jsx(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
26
+ }
27
+ function SheetOverlay({ className, ...props }) {
28
+ return /* @__PURE__ */ jsx(
29
+ SheetPrimitive.Backdrop,
30
+ {
31
+ "data-slot": "sheet-overlay",
32
+ className: cn(
33
+ "fixed inset-0 z-[var(--z-overlay-backdrop)] bg-black/20 duration-100 supports-backdrop-filter:backdrop-blur data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
34
+ className
35
+ ),
36
+ ...props
37
+ }
38
+ );
39
+ }
40
+ function SheetContent({
41
+ className,
42
+ children,
43
+ side = "right",
44
+ showCloseButton = true,
45
+ overlayClassName,
46
+ ...props
47
+ }) {
48
+ return /* @__PURE__ */ jsxs(SheetPortal, { children: [
49
+ /* @__PURE__ */ jsx(SheetOverlay, { className: overlayClassName }),
50
+ /* @__PURE__ */ jsxs(
51
+ SheetPrimitive.Popup,
52
+ {
53
+ "data-slot": "sheet-content",
54
+ "data-side": side,
55
+ className: cn(
56
+ "fixed z-[calc(var(--z-overlay-backdrop)+1)] flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:max-h-[calc(100dvh-var(--safe-area-inset-top)-var(--safe-area-inset-bottom))] data-[side=bottom]:overflow-y-auto data-[side=bottom]:border-t data-[side=bottom]:pb-[var(--safe-area-inset-bottom)] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:pt-[var(--safe-area-inset-top)] data-[side=left]:pb-[var(--safe-area-inset-bottom)] data-[side=left]:pl-[var(--safe-area-inset-left)] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:pt-[var(--safe-area-inset-top)] data-[side=right]:pr-[var(--safe-area-inset-right)] data-[side=right]:pb-[var(--safe-area-inset-bottom)] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:max-h-[calc(100dvh-var(--safe-area-inset-top)-var(--safe-area-inset-bottom))] data-[side=top]:overflow-y-auto data-[side=top]:border-b data-[side=top]:pt-[var(--safe-area-inset-top)] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10 motion-reduce:animate-none motion-reduce:transition-none",
57
+ className
58
+ ),
59
+ ...props,
60
+ children: [
61
+ children,
62
+ showCloseButton && /* @__PURE__ */ jsxs(
63
+ SheetPrimitive.Close,
64
+ {
65
+ "data-slot": "sheet-close",
66
+ render: /* @__PURE__ */ jsx(
67
+ Button,
68
+ {
69
+ variant: "ghost",
70
+ className: "absolute top-[max(1rem,var(--safe-area-inset-top))] right-[max(1rem,var(--safe-area-inset-right))]",
71
+ size: "icon-sm"
72
+ }
73
+ ),
74
+ children: [
75
+ /* @__PURE__ */ jsx(XIcon, {}),
76
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
77
+ ]
78
+ }
79
+ )
80
+ ]
81
+ }
82
+ )
83
+ ] });
84
+ }
85
+ function SheetHeader({ className, ...props }) {
86
+ return /* @__PURE__ */ jsx(
87
+ "div",
88
+ {
89
+ "data-slot": "sheet-header",
90
+ className: cn("flex flex-col gap-1.5 p-4", className),
91
+ ...props
92
+ }
93
+ );
94
+ }
95
+ function SheetFooter({ className, ...props }) {
96
+ return /* @__PURE__ */ jsx(
97
+ "div",
98
+ {
99
+ "data-slot": "sheet-footer",
100
+ className: cn("mt-auto flex flex-col gap-2 p-4", className),
101
+ ...props
102
+ }
103
+ );
104
+ }
105
+ function SheetTitle({ className, ...props }) {
106
+ return /* @__PURE__ */ jsx(
107
+ SheetPrimitive.Title,
108
+ {
109
+ "data-slot": "sheet-title",
110
+ className: cn("font-heading font-bold text-foreground", className),
111
+ ...props
112
+ }
113
+ );
114
+ }
115
+ function SheetDescription({ className, ...props }) {
116
+ return /* @__PURE__ */ jsx(
117
+ SheetPrimitive.Description,
118
+ {
119
+ "data-slot": "sheet-description",
120
+ className: cn("text-sm text-muted-foreground", className),
121
+ ...props
122
+ }
123
+ );
124
+ }
125
+
126
+ export {
127
+ Sheet,
128
+ SheetTrigger,
129
+ SheetClose,
130
+ SheetContent,
131
+ SheetHeader,
132
+ SheetFooter,
133
+ SheetTitle,
134
+ SheetDescription
135
+ };