@crewlethq/ui 0.60.0 → 0.62.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 (35) hide show
  1. package/README.md +8 -0
  2. package/dist/Combobox/index.js +1 -1
  3. package/dist/PrincipalPicker/index.js +2 -2
  4. package/dist/Prose/Prose.d.ts +5 -2
  5. package/dist/Prose/index.js +1 -1
  6. package/dist/{Prose-BTXNFT2Q.css → Prose-OMV2T6NT.css} +19 -2
  7. package/dist/RichEditor/index.js +1 -1
  8. package/dist/SendButton/SendButton.d.ts +25 -11
  9. package/dist/SendButton/index.d.ts +1 -0
  10. package/dist/SendButton/index.js +1 -1
  11. package/dist/SendButton-L4UX54XS.css +173 -0
  12. package/dist/ThinkingIndicator/ThinkingIndicator.d.ts +37 -0
  13. package/dist/ThinkingIndicator/index.d.ts +3 -0
  14. package/dist/ThinkingIndicator/index.js +3 -0
  15. package/dist/ThinkingIndicator-QJMX2TXC.css +122 -0
  16. package/dist/ValueField/ValueField.d.ts +117 -0
  17. package/dist/ValueField/index.d.ts +10 -0
  18. package/dist/ValueField/index.js +15 -0
  19. package/dist/ValueField/references.d.ts +66 -0
  20. package/dist/ValueField-EIBD6RYS.css +13 -0
  21. package/dist/{chunk-V57TGM2L.js → chunk-5MN2HISF.js} +1 -1
  22. package/dist/{chunk-JCSA3XVH.js → chunk-DVVP27OD.js} +1 -1
  23. package/dist/chunk-E2MIUNUU.js +19 -0
  24. package/dist/{chunk-RPHQNXE5.js → chunk-IOZFPFQS.js} +1 -1
  25. package/dist/chunk-OD3Z6QKN.js +237 -0
  26. package/dist/chunk-PBR5C5MX.js +33 -0
  27. package/dist/{chunk-VC2M2E7N.js → chunk-PK2P2QH6.js} +4 -3
  28. package/dist/generated/index.d.ts +2 -0
  29. package/dist/generated/index.js +15 -13
  30. package/dist/index.js +15 -13
  31. package/dist/styles.css +337 -3
  32. package/package.json +3 -3
  33. package/dist/chunk-XN5L5E5D.js +0 -27
  34. package/dist/{Editor-EQBOZPXS.js → Editor-DM7X24B7.js} +1 -1
  35. /package/dist/{chunk-DJV2FVD2.js → chunk-UOTNQV6D.js} +0 -0
package/dist/styles.css CHANGED
@@ -25354,7 +25354,7 @@ button.crewlet-presence-stack__member:focus-visible {
25354
25354
  }
25355
25355
 
25356
25356
 
25357
- /* Prose-BTXNFT2Q.css */
25357
+ /* Prose-OMV2T6NT.css */
25358
25358
  /*
25359
25359
  * Natural language: the proportional face, real leading, a bounded measure.
25360
25360
  */
@@ -25418,7 +25418,23 @@ button.crewlet-presence-stack__member:focus-visible {
25418
25418
  transition: color var(--motion-duration-slow) var(--motion-easing-default);
25419
25419
  }
25420
25420
 
25421
- .crewlet-prose--streaming::after {
25421
+ /*
25422
+ * THE CARET ENDS THE LAST LINE OF TEXT, never a line of its own. On a block
25423
+ * that holds rendered Markdown, the block's own ::after came after its last
25424
+ * paragraph or list, so the caret stood alone on a new line; and on a reply
25425
+ * with no words yet it stood alone at the start. So: no caret on an empty
25426
+ * block, none on the block itself when its children are blocks, and the caret
25427
+ * after the last child instead when that child is a paragraph or a heading,
25428
+ * whose last line it then ends. A list, a table or code last draws none: a
25429
+ * caret after its final row reads as a stray mark, not as the end of a line.
25430
+ */
25431
+ .crewlet-prose--streaming:empty::after,
25432
+ .crewlet-prose--streaming:has(> :is(p, div, ul, ol, pre, table, blockquote, h1, h2, h3, h4, h5, h6))::after {
25433
+ content: none;
25434
+ }
25435
+
25436
+ .crewlet-prose--streaming::after,
25437
+ .crewlet-prose--streaming > :is(p, h1, h2, h3, h4, h5, h6):last-child::after {
25422
25438
  content: '';
25423
25439
  display: inline-block;
25424
25440
  width: 2px;
@@ -25450,7 +25466,8 @@ button.crewlet-presence-stack__member:focus-visible {
25450
25466
  transition: none;
25451
25467
  }
25452
25468
 
25453
- .crewlet-prose--streaming::after {
25469
+ .crewlet-prose--streaming::after,
25470
+ .crewlet-prose--streaming > :is(p, h1, h2, h3, h4, h5, h6):last-child::after {
25454
25471
  animation: none;
25455
25472
  }
25456
25473
  }
@@ -27905,6 +27922,182 @@ svg.crewlet-select__chevron {
27905
27922
  }
27906
27923
 
27907
27924
 
27925
+ /* SendButton-L4UX54XS.css */
27926
+ /*
27927
+ * A chat composer's Send, which becomes Stop. See SendButton.tsx for what each
27928
+ * state says. The surfaces, edges and hover and press inks are IconButton's
27929
+ * primary and secondary squares; this sheet adds the glyph cross fade, the
27930
+ * quiet held state, the press and the running arc.
27931
+ */
27932
+
27933
+ /*
27934
+ * THE ARC'S ANGLE, registered so it can turn. An unregistered custom property
27935
+ * animates in one step at the halfway point, which would make the arc jump
27936
+ * between two places rather than travel.
27937
+ */
27938
+ @property --crewlet-send-button-arc {
27939
+ syntax: '<angle>';
27940
+ inherits: false;
27941
+ initial-value: 0deg;
27942
+ }
27943
+
27944
+ .crewlet-send-button {
27945
+ position: relative;
27946
+ transition:
27947
+ background var(--motion-duration-fast) var(--motion-easing-default),
27948
+ border-color var(--motion-duration-fast) var(--motion-easing-default),
27949
+ color var(--motion-duration-fast) var(--motion-easing-default),
27950
+ transform var(--motion-duration-instant) var(--motion-easing-out);
27951
+ }
27952
+
27953
+ /* A press sinks the square a little, so the pointer feels it land. */
27954
+ .crewlet-send-button:active:not([aria-disabled='true']) {
27955
+ transform: scale(0.94);
27956
+ }
27957
+
27958
+ /*
27959
+ * BOTH GLYPHS IN ONE CELL. The one in use stands at full size; the other is
27960
+ * faded and scaled to half, and the two trade places on the base step with
27961
+ * the entering surface's ease, so Send turning into Stop reads as one control
27962
+ * changing its mind rather than as two buttons swapping.
27963
+ */
27964
+ .crewlet-send-button__glyphs {
27965
+ display: grid;
27966
+ place-items: center;
27967
+ }
27968
+
27969
+ .crewlet-send-button__glyph {
27970
+ grid-area: 1 / 1;
27971
+ transition:
27972
+ opacity var(--motion-duration-base) var(--motion-easing-default),
27973
+ transform var(--motion-duration-base) var(--motion-easing-emphasized);
27974
+ }
27975
+
27976
+ .crewlet-send-button--send .crewlet-send-button__glyph--stop,
27977
+ .crewlet-send-button--stop .crewlet-send-button__glyph--send {
27978
+ opacity: 0;
27979
+ transform: scale(0.5);
27980
+ }
27981
+
27982
+ /*
27983
+ * THE STOP SQUARE IS SMALLER THAN THE ARROW: a filled block at the arrow's
27984
+ * 14px was the heaviest mark on the panel. At the 12px step its square is
27985
+ * nine pixels, crisp on the pixel grid and the weight of the arrow's stroke.
27986
+ */
27987
+ .crewlet-send-button.crewlet-icon-btn--md .crewlet-send-button__glyph--stop {
27988
+ width: var(--font-size-xs);
27989
+ height: var(--font-size-xs);
27990
+ }
27991
+
27992
+ /*
27993
+ * HELD, AT FULL OPACITY, with the glyph in the tertiary ink. A faded accent
27994
+ * block read as a muddy, broken button on the dark ground, and the composer's
27995
+ * own fade multiplied it further. Send held is the accent's soft tint, so it
27996
+ * is still the purple control that lights up the moment there is something
27997
+ * to send; Stop held (a stop already under way) is the neutral hover overlay,
27998
+ * since nothing about it is waiting to light up.
27999
+ */
28000
+ .crewlet-send-button.crewlet-icon-btn[aria-disabled='true'] {
28001
+ opacity: 1;
28002
+ border-color: transparent;
28003
+ color: var(--color-text-tertiary);
28004
+ }
28005
+
28006
+ .crewlet-send-button--send.crewlet-icon-btn[aria-disabled='true'] {
28007
+ background: var(--color-brand-accent-soft);
28008
+ }
28009
+
28010
+ .crewlet-send-button--stop.crewlet-icon-btn[aria-disabled='true'] {
28011
+ background: var(--color-surface-hover);
28012
+ }
28013
+
28014
+ /*
28015
+ * THE RUNNING ARC: a band of the accent travelling round Stop's edge, over its
28016
+ * own 1px border, with a tail that fades behind it. The band is a conic
28017
+ * gradient cut to a 2px ring by a mask (a mask reads only alpha, so its black
28018
+ * is opacity rather than a colour), so it follows the rounded corner exactly.
28019
+ * One round is the working ring's sweep period, and it fades in on the
28020
+ * moderate step as Stop arrives.
28021
+ */
28022
+ .crewlet-send-button--stop::before {
28023
+ content: '';
28024
+ position: absolute;
28025
+ inset: -1px;
28026
+ padding: 2px;
28027
+ border-radius: inherit;
28028
+ background: conic-gradient(
28029
+ from var(--crewlet-send-button-arc),
28030
+ transparent 0turn,
28031
+ transparent 0.55turn,
28032
+ var(--color-brand-accent) 1turn
28033
+ );
28034
+ -webkit-mask:
28035
+ linear-gradient(#000 0 0) content-box,
28036
+ linear-gradient(#000 0 0);
28037
+ -webkit-mask-composite: xor;
28038
+ mask:
28039
+ linear-gradient(#000 0 0) content-box exclude,
28040
+ linear-gradient(#000 0 0);
28041
+ /* Paint, never a target. */
28042
+ pointer-events: none;
28043
+ animation:
28044
+ crewlet-send-button-arc var(--motion-duration-sweep) linear infinite,
28045
+ crewlet-send-button-arc-in var(--motion-duration-moderate) var(--motion-easing-out);
28046
+ }
28047
+
28048
+ /* A stop already under way has nothing left to show running. */
28049
+ .crewlet-send-button--stop[aria-disabled='true']::before {
28050
+ display: none;
28051
+ }
28052
+
28053
+ @keyframes crewlet-send-button-arc {
28054
+ to {
28055
+ --crewlet-send-button-arc: 360deg;
28056
+ }
28057
+ }
28058
+
28059
+ @keyframes crewlet-send-button-arc-in {
28060
+ from {
28061
+ opacity: 0;
28062
+ }
28063
+
28064
+ to {
28065
+ opacity: 1;
28066
+ }
28067
+ }
28068
+
28069
+ /*
28070
+ * UNDER REDUCED MOTION nothing travels or scales: the glyphs change in place,
28071
+ * and the arc becomes the whole edge in the accent, still and still saying
28072
+ * that something runs.
28073
+ */
28074
+ @media (prefers-reduced-motion: reduce) {
28075
+ .crewlet-send-button {
28076
+ transition: none;
28077
+ }
28078
+
28079
+ .crewlet-send-button:active:not([aria-disabled='true']) {
28080
+ transform: none;
28081
+ }
28082
+
28083
+ .crewlet-send-button__glyph {
28084
+ transition: none;
28085
+ }
28086
+
28087
+ .crewlet-send-button--stop::before {
28088
+ background: var(--color-brand-accent);
28089
+ animation: none;
28090
+ }
28091
+ }
28092
+
28093
+ /* The system draws its own edge; a masked gradient is not repainted there. */
28094
+ @media (forced-colors: active) {
28095
+ .crewlet-send-button--stop::before {
28096
+ display: none;
28097
+ }
28098
+ }
28099
+
28100
+
27908
28101
  /* SettingsTable-6DUFAFXG.css */
27909
28102
  /*
27910
28103
  * SettingsTable: a read-only table of settings, one row each, on one grid.
@@ -35608,6 +35801,131 @@ b.crewlet-switcher__match {
35608
35801
  }
35609
35802
 
35610
35803
 
35804
+ /* ThinkingIndicator-QJMX2TXC.css */
35805
+ /*
35806
+ * The assistant at work: the Assistant's mark, its blades turning, and a line
35807
+ * of status under a shimmer. See ThinkingIndicator.tsx for why it replaces a
35808
+ * caret and how it is announced.
35809
+ */
35810
+
35811
+ /*
35812
+ * ONE LINE OF PROSE TALL, at every state: the mark alone, the mark with a
35813
+ * status line, and the line changing from one step to the next all keep the
35814
+ * same height, so the thread never moves while the assistant works.
35815
+ */
35816
+ .crewlet-thinking {
35817
+ display: flex;
35818
+ align-items: center;
35819
+ gap: var(--spacing-2);
35820
+ min-width: 0;
35821
+ min-height: calc(var(--font-size-compact) * var(--font-line-height-relaxed));
35822
+ font-family: var(--font-family-sans);
35823
+ font-size: var(--font-size-compact);
35824
+ line-height: var(--font-line-height-relaxed);
35825
+ }
35826
+
35827
+ /*
35828
+ * THE BLADES TURN A QUARTER, THEN REST. The figure is four blades around a
35829
+ * core, the same after a quarter turn, so each round ends where the next
35830
+ * begins and the loop never shows a seam. One round is the breath period
35831
+ * (2.2s): the turn takes its first half on the in-out ease and the second
35832
+ * half is still, which reads as steady thought rather than as a spinner. The
35833
+ * core holds still, as the mark's own description promises.
35834
+ */
35835
+ .crewlet-thinking__mark [data-motion='turn'] {
35836
+ transform-box: view-box;
35837
+ transform-origin: 50% 50%;
35838
+ animation: crewlet-thinking-turn var(--motion-duration-breath) var(--motion-easing-in-out) infinite;
35839
+ }
35840
+
35841
+ @keyframes crewlet-thinking-turn {
35842
+ 0% {
35843
+ transform: rotate(0deg);
35844
+ }
35845
+
35846
+ 50%,
35847
+ 100% {
35848
+ transform: rotate(90deg);
35849
+ }
35850
+ }
35851
+
35852
+ /*
35853
+ * THE SHIMMER IS A LIGHTER BAND CROSSING THE WORDS, the band Skeleton sweeps
35854
+ * across a placeholder, set in ink rather than in surface: the words are the
35855
+ * secondary ink at rest, so they read at every point of the sweep, and the
35856
+ * band is the primary ink. The gradient is clipped to the glyphs and is three
35857
+ * times the line's width, so the band crosses it rather than standing in it.
35858
+ */
35859
+ .crewlet-thinking__status {
35860
+ min-width: 0;
35861
+ overflow: hidden;
35862
+ color: var(--color-text-secondary);
35863
+ text-overflow: ellipsis;
35864
+ white-space: nowrap;
35865
+ animation: crewlet-thinking-enter var(--motion-duration-moderate) var(--motion-easing-out);
35866
+ }
35867
+
35868
+ @supports (background-clip: text) or (-webkit-background-clip: text) {
35869
+ .crewlet-thinking__status {
35870
+ background-image: linear-gradient(
35871
+ 90deg,
35872
+ var(--color-text-secondary) 0%,
35873
+ var(--color-text-secondary) 40%,
35874
+ var(--color-text-primary) 50%,
35875
+ var(--color-text-secondary) 60%,
35876
+ var(--color-text-secondary) 100%
35877
+ );
35878
+ background-size: 300% 100%;
35879
+ -webkit-background-clip: text;
35880
+ background-clip: text;
35881
+ color: transparent;
35882
+ animation:
35883
+ crewlet-thinking-enter var(--motion-duration-moderate) var(--motion-easing-out),
35884
+ crewlet-thinking-shimmer var(--motion-duration-breath) linear infinite;
35885
+ }
35886
+ }
35887
+
35888
+ @keyframes crewlet-thinking-shimmer {
35889
+ from {
35890
+ background-position: 100% 50%;
35891
+ }
35892
+
35893
+ to {
35894
+ background-position: 0 50%;
35895
+ }
35896
+ }
35897
+
35898
+ @keyframes crewlet-thinking-enter {
35899
+ from {
35900
+ opacity: 0;
35901
+ }
35902
+
35903
+ to {
35904
+ opacity: 1;
35905
+ }
35906
+ }
35907
+
35908
+ @media (prefers-reduced-motion: reduce) {
35909
+ .crewlet-thinking__mark [data-motion='turn'] {
35910
+ animation: none;
35911
+ }
35912
+
35913
+ .crewlet-thinking__status {
35914
+ background-image: none;
35915
+ color: var(--color-text-secondary);
35916
+ animation: none;
35917
+ }
35918
+ }
35919
+
35920
+ /* The system's own ink: a gradient clipped to text is dropped there. */
35921
+ @media (forced-colors: active) {
35922
+ .crewlet-thinking__status {
35923
+ background-image: none;
35924
+ color: CanvasText;
35925
+ }
35926
+ }
35927
+
35928
+
35611
35929
  /* TileGrid-UYMVVVJK.css */
35612
35930
  /*
35613
35931
  * TileGrid: tiles on a fixed track count that folds by the grid's own width.
@@ -38249,6 +38567,22 @@ svg.crewlet-time-window__tick {
38249
38567
  }
38250
38568
 
38251
38569
 
38570
+ /* ValueField-EIBD6RYS.css */
38571
+ /*
38572
+ * ValueField: a labelled value with the control its kind needs.
38573
+ *
38574
+ * The row is FormField's and every control is the package's own; what is
38575
+ * drawn here is the mark a label may carry, such as a third party's logo,
38576
+ * set on the label's line ahead of its words.
38577
+ */
38578
+
38579
+ .crewlet-value-field__label {
38580
+ display: inline-flex;
38581
+ align-items: center;
38582
+ gap: var(--spacing-1);
38583
+ }
38584
+
38585
+
38252
38586
  /* VersionCompare-UUZOPTQO.css */
38253
38587
  /* VersionCompare: a head naming the two versions with the lens switch at its
38254
38588
  end, then the changes or the two versions. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewlethq/ui",
3
- "version": "0.60.0",
3
+ "version": "0.62.0",
4
4
  "description": "Crewlet shared React components built on @crewlethq/tokens and @crewlethq/icons.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -42,8 +42,8 @@
42
42
  "clean": "rm -rf dist src/generated"
43
43
  },
44
44
  "dependencies": {
45
- "@crewlethq/icons": "0.60.0",
46
- "@crewlethq/tokens": "0.60.0",
45
+ "@crewlethq/icons": "0.62.0",
46
+ "@crewlethq/tokens": "0.62.0",
47
47
  "prosemirror-commands": "1.7.2",
48
48
  "prosemirror-gapcursor": "1.4.1",
49
49
  "prosemirror-history": "1.5.1",
@@ -1,27 +0,0 @@
1
- import { IconButton } from './chunk-2XWFWNDT.js';
2
- import { cx } from './chunk-ODEQTPFM.js';
3
- import { forwardRef } from 'react';
4
- import { SquareGlyph, ArrowUpGlyph } from '@crewlethq/icons/glyphs';
5
- import { jsx } from 'react/jsx-runtime';
6
-
7
- var SEND_BUTTON_LABELS = { send: "Send", stop: "Stop" };
8
- var SendButton = forwardRef(function SendButton2({ mode, onPress, disabledReason, labels: overrides, className, ...rest }, ref) {
9
- const labels = overrides ? { ...SEND_BUTTON_LABELS, ...overrides } : SEND_BUTTON_LABELS;
10
- const stopping = mode === "stop";
11
- return /* @__PURE__ */ jsx(
12
- IconButton,
13
- {
14
- ...rest,
15
- ref,
16
- size: "md",
17
- variant: stopping ? "secondary" : "primary",
18
- label: stopping ? labels.stop : labels.send,
19
- icon: stopping ? /* @__PURE__ */ jsx(SquareGlyph, { filled: true }) : /* @__PURE__ */ jsx(ArrowUpGlyph, {}),
20
- disabledReason: stopping ? void 0 : disabledReason,
21
- className: cx("crewlet-send-button", `crewlet-send-button--${mode}`, className),
22
- onClick: onPress
23
- }
24
- );
25
- });
26
-
27
- export { SEND_BUTTON_LABELS, SendButton };
@@ -1,5 +1,5 @@
1
- import { schema, readMarkdown, writeMarkdown } from './chunk-QH6VYJ3X.js';
2
1
  import { richEditorLabels } from './chunk-CSQTDGTS.js';
2
+ import { schema, readMarkdown, writeMarkdown } from './chunk-QH6VYJ3X.js';
3
3
  import { safeHref, MARKDOWN_CALLOUT_TONES } from './chunk-BAKPMH3S.js';
4
4
  import { Toolbar } from './chunk-NR4CPM4T.js';
5
5
  import { FormField, Input } from './chunk-TLIJG4TP.js';
File without changes