@cosxai/ui 0.25.0 → 1.0.0-alpha.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.
Files changed (133) hide show
  1. package/CHANGELOG.md +577 -0
  2. package/NOTICE +11 -0
  3. package/README.md +52 -0
  4. package/package.json +33 -7
  5. package/src/fonts.css +20 -0
  6. package/src/index.ts +8 -25
  7. package/src/lib/cn.ts +23 -6
  8. package/src/styles.css +17 -0
  9. package/src/theme.css +132 -0
  10. package/src/tokens/colors.css +112 -0
  11. package/src/tokens/compat.css +36 -0
  12. package/src/tokens/elevation.css +14 -0
  13. package/src/tokens/motion.css +42 -0
  14. package/src/tokens/spacing.css +55 -0
  15. package/src/tokens/typography-cjk.css +42 -0
  16. package/src/tokens/typography.css +81 -0
  17. package/src/actionbar/ActionBar.tsx +0 -837
  18. package/src/actionbar/ActionBarButton.tsx +0 -111
  19. package/src/actionbar/ActionBarMenuGroup.tsx +0 -116
  20. package/src/actionbar/ActionBarModeHandle.tsx +0 -171
  21. package/src/actionbar/ActionBarProvider.tsx +0 -91
  22. package/src/actionbar/actionbar-context.ts +0 -45
  23. package/src/actionbar/index.ts +0 -28
  24. package/src/actionbar/types.ts +0 -147
  25. package/src/actionbar/useActionBarItems.ts +0 -60
  26. package/src/actionbar/useActionBarMode.ts +0 -144
  27. package/src/actionbar/useActionBarPanel.ts +0 -56
  28. package/src/actionbar/useActionBarStatusDot.ts +0 -49
  29. package/src/actionbar/useActionBarToast.ts +0 -33
  30. package/src/ambient/AmbientBackdrop.tsx +0 -74
  31. package/src/ambient/CommandInput.tsx +0 -107
  32. package/src/ambient/SuperbarStrip.tsx +0 -36
  33. package/src/ambient/index.ts +0 -6
  34. package/src/bento/BentoCell.tsx +0 -66
  35. package/src/bento/BentoGrid.tsx +0 -42
  36. package/src/bento/index.ts +0 -2
  37. package/src/command/CommandPalette.tsx +0 -329
  38. package/src/command/CommandProvider.tsx +0 -57
  39. package/src/command/command-context.ts +0 -12
  40. package/src/command/index.ts +0 -6
  41. package/src/command/rank.ts +0 -50
  42. package/src/command/types.ts +0 -37
  43. package/src/command/useCommandSource.ts +0 -37
  44. package/src/dialogs/DialogsProvider.tsx +0 -216
  45. package/src/dialogs/Modal.tsx +0 -260
  46. package/src/dialogs/Toast.tsx +0 -85
  47. package/src/dialogs/dialogs-context.ts +0 -6
  48. package/src/dialogs/index.ts +0 -10
  49. package/src/dialogs/types.ts +0 -37
  50. package/src/dialogs/useDialogs.ts +0 -8
  51. package/src/editorial/EditorialSpotlight.tsx +0 -63
  52. package/src/editorial/Folio.tsx +0 -52
  53. package/src/editorial/PlateMarker.tsx +0 -33
  54. package/src/editorial/RomanSection.tsx +0 -65
  55. package/src/editorial/RunningMarginalia.tsx +0 -65
  56. package/src/editorial/index.ts +0 -10
  57. package/src/hooks/index.ts +0 -5
  58. package/src/hooks/useKeyboardHotkey.ts +0 -93
  59. package/src/hooks/useReducedMotion.ts +0 -20
  60. package/src/hooks/useViewport.ts +0 -61
  61. package/src/layout/Breadcrumb.tsx +0 -74
  62. package/src/layout/LeftNavRail.tsx +0 -139
  63. package/src/layout/MobileTabBar.tsx +0 -101
  64. package/src/layout/NavItem.tsx +0 -128
  65. package/src/layout/NavSearchTrigger.tsx +0 -88
  66. package/src/layout/NavSection.tsx +0 -40
  67. package/src/layout/RightSidebarPanel.tsx +0 -111
  68. package/src/layout/Shell.tsx +0 -91
  69. package/src/layout/SidePanel.tsx +0 -316
  70. package/src/layout/StickyBanner.tsx +0 -83
  71. package/src/layout/Topbar.tsx +0 -68
  72. package/src/layout/index.ts +0 -24
  73. package/src/layout/useNavRailState.ts +0 -69
  74. package/src/lib/time-utils.ts +0 -44
  75. package/src/neobrutalism/Marquee.tsx +0 -81
  76. package/src/neobrutalism/Sticker.tsx +0 -71
  77. package/src/neobrutalism/index.ts +0 -4
  78. package/src/primitives/Avatar.tsx +0 -53
  79. package/src/primitives/Button.tsx +0 -67
  80. package/src/primitives/Card.tsx +0 -41
  81. package/src/primitives/Checkbox.tsx +0 -87
  82. package/src/primitives/Chip.tsx +0 -191
  83. package/src/primitives/Combobox.tsx +0 -507
  84. package/src/primitives/CopyField.tsx +0 -139
  85. package/src/primitives/CountBadge.tsx +0 -50
  86. package/src/primitives/Input.tsx +0 -204
  87. package/src/primitives/Kbd.tsx +0 -45
  88. package/src/primitives/MentionCombobox.tsx +0 -612
  89. package/src/primitives/MultiCombobox.tsx +0 -327
  90. package/src/primitives/PageHeader.tsx +0 -77
  91. package/src/primitives/Radio.tsx +0 -131
  92. package/src/primitives/SegmentedControl.tsx +0 -135
  93. package/src/primitives/Select.tsx +0 -779
  94. package/src/primitives/SignaturePad.tsx +0 -461
  95. package/src/primitives/Tag.tsx +0 -56
  96. package/src/primitives/Textarea.tsx +0 -62
  97. package/src/primitives/ToggleSwitch.tsx +0 -79
  98. package/src/primitives/Tooltip.tsx +0 -213
  99. package/src/primitives/index.ts +0 -53
  100. package/src/pwa/InstallPromptBanner.tsx +0 -132
  101. package/src/pwa/index.ts +0 -4
  102. package/src/pwa/manifest.template.json +0 -20
  103. package/src/pwa/registerSW.ts +0 -55
  104. package/src/riso/Halftone.tsx +0 -85
  105. package/src/riso/Misregister.tsx +0 -63
  106. package/src/riso/RisoStamp.tsx +0 -76
  107. package/src/riso/index.ts +0 -3
  108. package/src/sketch/HandUnderline.tsx +0 -53
  109. package/src/sketch/RoughArrow.tsx +0 -91
  110. package/src/sketch/RoughBox.tsx +0 -73
  111. package/src/sketch/StickyNote.tsx +0 -56
  112. package/src/sketch/index.ts +0 -4
  113. package/src/styles/base.css +0 -186
  114. package/src/styles/chrome-ambient.css +0 -235
  115. package/src/styles/chrome-bento.css +0 -192
  116. package/src/styles/chrome-editorial.css +0 -168
  117. package/src/styles/chrome-neobrutalism.css +0 -326
  118. package/src/styles/chrome-riso.css +0 -339
  119. package/src/styles/chrome-sketch.css +0 -362
  120. package/src/styles/chrome-swiss.css +0 -265
  121. package/src/styles/chrome-terminal.css +0 -272
  122. package/src/styles/fonts.css +0 -1034
  123. package/src/styles/index.css +0 -343
  124. package/src/styles/tokens.css +0 -941
  125. package/src/terminal/AsciiBox.tsx +0 -65
  126. package/src/terminal/BrailleSpinner.tsx +0 -46
  127. package/src/terminal/index.ts +0 -4
  128. package/src/theme/ThemeProvider.tsx +0 -99
  129. package/src/theme/index.ts +0 -6
  130. package/src/theme/inline-script.ts +0 -40
  131. package/src/theme/theme-context.ts +0 -7
  132. package/src/theme/types.ts +0 -39
  133. package/src/theme/useTheme.ts +0 -8
@@ -1,204 +0,0 @@
1
- import { forwardRef, useId, type InputHTMLAttributes, type ReactNode } from "react";
2
- import { cn } from "../lib/cn";
3
-
4
- // Styled text input with optional label + error + helper text.
5
- // Three states: idle / focused / invalid. Focus ring + invalid border
6
- // both via :focus-visible / aria-invalid CSS — no JS branching.
7
- //
8
- // Optional `prefix` / `suffix` slots render INSIDE the bordered
9
- // field, separated from the input by a subtle hairline divider.
10
- // Common patterns:
11
- // <Input prefix="https://" …/> → `https://[ acme ]`
12
- // <Input suffix=".cosx.dev" …/> → `[ acme ].cosx.dev`
13
- // Both can be set together. Prefer plain strings; ReactNode is
14
- // supported (e.g. icons) but inherits the muted helper colour.
15
-
16
- // We Omit "size" (HTMLInputElement's number-of-visible-chars attr;
17
- // conflicts with our absent layout-size prop and is rarely needed in
18
- // CSS-styled inputs) AND "prefix" (HTML's RDFa metadata attr —
19
- // taking that prop name here lets us expose an addon slot with the
20
- // most intuitive name; consumers needing the rare RDFa attr can
21
- // drop down to a native <input>).
22
- export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "prefix"> {
23
- label?: ReactNode;
24
- helper?: ReactNode;
25
- // Validation error message. When set, the input renders an
26
- // invalid border + colour and the helper slot is replaced by
27
- // the error text.
28
- error?: string | null;
29
- // Width preset — full, fixed, or auto (default full).
30
- fit?: "full" | "auto";
31
- // Inline addons rendered inside the bordered field. Use for
32
- // protocol prefixes ("https://"), domain suffixes (".cosx.dev"),
33
- // currency symbols, unit labels, search icons, etc.
34
- prefix?: ReactNode;
35
- suffix?: ReactNode;
36
- // Bare mode: render ONLY the <input> — no wrapper, label, helper,
37
- // error text, or field chrome (border / background / height). For
38
- // hosts that draw the field themselves (MultiCombobox's inline
39
- // layout, where chips and the input share one frame). `label`,
40
- // `helper`, `error` text, `prefix`, `suffix` and `fit` are ignored;
41
- // `aria-invalid` is still set from `error` so the host can react.
42
- // Default false.
43
- bare?: boolean;
44
- }
45
-
46
- const ADDON_STYLE = {
47
- display: "inline-flex",
48
- alignItems: "center",
49
- padding: "0 12px",
50
- font: "400 13px/1 var(--ck-font-mono, var(--ck-font-sans))",
51
- color: "var(--ck-text-secondary)",
52
- // `--ck-bg-muted` is the canonical "slightly recessed slab"
53
- // background — gives the addon visible separation from the input
54
- // (`--ck-bg-surface`) without needing a hard divider line. The
55
- // bg shift carries across all chromes; tokens.css defines a
56
- // muted tone per chrome (light + dark).
57
- background: "var(--ck-bg-muted)",
58
- whiteSpace: "nowrap" as const,
59
- userSelect: "none" as const,
60
- };
61
-
62
- export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
63
- { label, helper, error, fit = "full", prefix, suffix, bare = false, className, id, style, ...rest },
64
- ref,
65
- ) {
66
- const autoId = useId();
67
- const inputId = id ?? autoId;
68
- const hasAddon = !bare && (prefix != null || suffix != null);
69
- // `...rest` is spread FIRST so the `error`-derived aria-invalid (and,
70
- // non-bare, the helper/error text association) stays authoritative;
71
- // a consumer aria-describedby is merged with ours, not replaced.
72
- const ownDescribedBy = !bare && (helper || error) ? `${inputId}-helper` : undefined;
73
- const describedBy =
74
- [rest["aria-describedby"], ownDescribedBy].filter(Boolean).join(" ") || undefined;
75
-
76
- if (bare) {
77
- // Chrome presets restyle .ck-input with !important; the matching
78
- // .ck-input--bare rule in styles/index.css strips that again.
79
- return (
80
- <input
81
- ref={ref}
82
- id={inputId}
83
- {...rest}
84
- aria-invalid={error ? true : undefined}
85
- aria-describedby={describedBy}
86
- className={cn("ck-input", "ck-input--bare", className)}
87
- style={{
88
- minWidth: 0,
89
- width: "100%",
90
- height: 28,
91
- padding: "0 4px",
92
- font: "400 13px/1 var(--ck-font-sans)",
93
- background: "transparent",
94
- color: "var(--ck-text-primary)",
95
- border: "none",
96
- borderRadius: 0,
97
- boxShadow: "none",
98
- outline: "none",
99
- ...(style ?? {}),
100
- }}
101
- />
102
- );
103
- }
104
-
105
- // Border / radius live on the WRAPPER when there's an addon so the
106
- // addon + input share one continuous frame. Otherwise the input
107
- // itself carries the border (preserves the prior visual contract).
108
- const fieldBorder = `1px solid ${error ? "var(--ck-critical)" : "var(--ck-border-strong)"}`;
109
- const fieldRadius = "var(--ck-radius-sm)";
110
-
111
- const inputEl = (
112
- <input
113
- ref={ref}
114
- id={inputId}
115
- {...rest}
116
- aria-invalid={error ? true : undefined}
117
- aria-describedby={describedBy}
118
- className={cn("ck-input", hasAddon ? "ck-input--with-addon" : undefined)}
119
- style={{
120
- flex: hasAddon ? "1 1 auto" : undefined,
121
- minWidth: 0,
122
- height: hasAddon ? "100%" : 36,
123
- padding: "0 12px",
124
- font: "400 13px/1 var(--ck-font-sans)",
125
- background: "var(--ck-bg-surface)",
126
- color: "var(--ck-text-primary)",
127
- border: hasAddon ? "none" : fieldBorder,
128
- borderRadius: hasAddon ? 0 : fieldRadius,
129
- outline: "none",
130
- transition: "border-color var(--ck-dur-fast) var(--ck-ease)",
131
- ...(style ?? {}),
132
- }}
133
- />
134
- );
135
-
136
- return (
137
- <div
138
- className={cn("ck-input-field", className)}
139
- style={{
140
- display: "flex",
141
- flexDirection: "column",
142
- gap: 6,
143
- width: fit === "full" ? "100%" : undefined,
144
- // minWidth: 0 lets a parent flex container shrink this
145
- // wrapper past the inner addon-wrap's nowrap suffix content.
146
- // Without it, a long suffix (e.g. ".meta.test.cosx.dev")
147
- // sets a min-content floor that pushes the form wider than
148
- // its mobile viewport. Per-page CSS workarounds in consumer
149
- // apps only cover their own scope; fixing it at the primitive
150
- // catches every page.
151
- minWidth: 0,
152
- }}
153
- >
154
- {label && (
155
- <label
156
- htmlFor={inputId}
157
- className="ck-eyebrow"
158
- style={{ color: "var(--ck-text-secondary)" }}
159
- >
160
- {label}
161
- </label>
162
- )}
163
- {hasAddon ? (
164
- <div
165
- className="ck-input-addon-wrap"
166
- style={{
167
- display: "flex",
168
- alignItems: "stretch",
169
- height: 36,
170
- background: "var(--ck-bg-surface)",
171
- border: fieldBorder,
172
- borderRadius: fieldRadius,
173
- overflow: "hidden",
174
- }}
175
- >
176
- {prefix != null && (
177
- <span className="ck-input-addon ck-input-addon--prefix" style={ADDON_STYLE}>
178
- {prefix}
179
- </span>
180
- )}
181
- {inputEl}
182
- {suffix != null && (
183
- <span className="ck-input-addon ck-input-addon--suffix" style={ADDON_STYLE}>
184
- {suffix}
185
- </span>
186
- )}
187
- </div>
188
- ) : (
189
- inputEl
190
- )}
191
- {(helper || error) && (
192
- <div
193
- id={`${inputId}-helper`}
194
- style={{
195
- font: "400 11px/1.4 var(--ck-font-sans)",
196
- color: error ? "var(--ck-critical)" : "var(--ck-text-tertiary)",
197
- }}
198
- >
199
- {error ?? helper}
200
- </div>
201
- )}
202
- </div>
203
- );
204
- });
@@ -1,45 +0,0 @@
1
- import type { ReactNode } from "react";
2
- import { cn } from "../lib/cn";
3
-
4
- // Keyboard hint pill — ⌘K, ⌃K, Shift, etc. Auto-translates "Mod"
5
- // to ⌘ on Mac and Ctrl elsewhere so docs strings can stay portable.
6
-
7
- export interface KbdProps {
8
- // "Mod" is replaced by ⌘ on Mac, Ctrl elsewhere. Otherwise rendered
9
- // verbatim — pass "Shift", "Enter", "↑", "K", etc.
10
- children: ReactNode;
11
- className?: string;
12
- }
13
-
14
- const isMac =
15
- typeof navigator !== "undefined" &&
16
- /Mac|iPhone|iPad|iPod/.test(navigator.platform);
17
-
18
- function renderChild(c: ReactNode): ReactNode {
19
- if (typeof c !== "string") return c;
20
- if (c === "Mod") return isMac ? "⌘" : "Ctrl";
21
- return c;
22
- }
23
-
24
- export function Kbd({ children, className }: KbdProps) {
25
- return (
26
- <kbd
27
- className={cn("ck-kbd", className)}
28
- style={{
29
- display: "inline-flex",
30
- alignItems: "center",
31
- justifyContent: "center",
32
- minWidth: 18,
33
- height: 18,
34
- padding: "0 5px",
35
- background: "var(--ck-bg-muted)",
36
- border: "1px solid var(--ck-border-subtle)",
37
- color: "var(--ck-text-secondary)",
38
- font: "500 11px/1 var(--ck-font-mono)",
39
- borderRadius: "var(--ck-radius-xs)",
40
- }}
41
- >
42
- {renderChild(children)}
43
- </kbd>
44
- );
45
- }