@crewlethq/ui 0.6.3 → 0.7.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 (125) hide show
  1. package/README.md +109 -0
  2. package/dist/AddPill/index.js +1 -1
  3. package/dist/{AddPill-IJQYCY6C.css → AddPill-V4TQXJ53.css} +23 -22
  4. package/dist/AppShell/index.js +2 -2
  5. package/dist/{AppShell-XARELGIH.css → AppShell-CEVLW4QG.css} +3 -1
  6. package/dist/Button/index.js +1 -1
  7. package/dist/{Button-EXU36DEH.css → Button-UWKBTKYD.css} +18 -0
  8. package/dist/Canvas/Canvas.d.ts +16 -1
  9. package/dist/Canvas/index.d.ts +1 -1
  10. package/dist/Canvas/index.js +3 -3
  11. package/dist/{Canvas-Q6JETCWR.css → Canvas-YVXHMWLN.css} +13 -0
  12. package/dist/Card/index.js +1 -1
  13. package/dist/{Card-GLP7SUV6.css → Card-KJOYHDTJ.css} +5 -1
  14. package/dist/Checkbox/index.js +1 -1
  15. package/dist/{Checkbox-BOXQ747I.css → Checkbox-UE7TEPAM.css} +9 -1
  16. package/dist/CodeBlock/index.js +4 -4
  17. package/dist/Combobox/index.js +3 -3
  18. package/dist/CommandPalette/index.js +6 -6
  19. package/dist/Copyable/index.js +3 -3
  20. package/dist/DataTable/index.js +6 -6
  21. package/dist/{DataTable-OLHPF7D4.css → DataTable-WZK3V62B.css} +11 -0
  22. package/dist/DataView/index.js +11 -11
  23. package/dist/DateTimePicker/index.js +4 -4
  24. package/dist/{DateTimePicker-22VNXRWC.css → DateTimePicker-4AZBTODT.css} +11 -6
  25. package/dist/ErrorBoundary/index.js +2 -2
  26. package/dist/FilterChip/index.js +1 -1
  27. package/dist/{FilterChip-GTGLLOXE.css → FilterChip-EZ4QMW4E.css} +4 -1
  28. package/dist/IconButton/index.js +1 -1
  29. package/dist/{IconButton-TVEUWK6L.css → IconButton-VYWP6SGW.css} +15 -0
  30. package/dist/ImageUpload/index.js +1 -1
  31. package/dist/{ImageUpload-YCHJMUGX.css → ImageUpload-L2GE4JUM.css} +5 -1
  32. package/dist/Input/index.js +2 -2
  33. package/dist/{Input-2PU5CPKK.css → Input-DRFNI26F.css} +40 -10
  34. package/dist/Kbd/index.js +1 -1
  35. package/dist/{Kbd-JPLDVJIP.css → Kbd-MCWJTRTT.css} +11 -0
  36. package/dist/ListInput/index.js +4 -4
  37. package/dist/Menu/index.js +3 -3
  38. package/dist/Modal/index.js +3 -3
  39. package/dist/NewItemsNotice/index.js +1 -1
  40. package/dist/{NewItemsNotice-T4DSSPVV.css → NewItemsNotice-Q5ED73BQ.css} +3 -1
  41. package/dist/OrgLabel/OrgLabel.d.ts +12 -3
  42. package/dist/OrgLabel/index.js +1 -1
  43. package/dist/{OrgLabel-CR233G34.css → OrgLabel-6WSKJQOT.css} +38 -0
  44. package/dist/OrgNode/OrgNode.d.ts +7 -4
  45. package/dist/OrgNode/index.js +2 -2
  46. package/dist/{OrgNode-BT7T2Q2X.css → OrgNode-TCHJH5FO.css} +89 -45
  47. package/dist/OrgTable/index.js +5 -5
  48. package/dist/{OrgTable-VWMFC3TB.css → OrgTable-JZSYTUIK.css} +28 -4
  49. package/dist/Popover/index.js +1 -1
  50. package/dist/{Popover-WJGCF3ZQ.css → Popover-QCINR7WG.css} +5 -2
  51. package/dist/PricingCard/index.js +2 -2
  52. package/dist/{PricingCard-7EFXRSD2.css → PricingCard-HTAHG4ST.css} +5 -1
  53. package/dist/SearchTrigger/index.js +1 -1
  54. package/dist/{SearchTrigger-Z5D4AAY7.css → SearchTrigger-KIZLWBEH.css} +4 -1
  55. package/dist/SegmentedControl/SegmentedControl.d.ts +19 -1
  56. package/dist/SegmentedControl/index.d.ts +1 -1
  57. package/dist/SegmentedControl/index.js +2 -2
  58. package/dist/SegmentedControl-76HODRBT.css +160 -0
  59. package/dist/Select/index.js +1 -1
  60. package/dist/{Select-E24U5LBC.css → Select-4ANVLHUY.css} +4 -4
  61. package/dist/Switch/index.js +1 -1
  62. package/dist/{Switch-U4OWK4CL.css → Switch-66RAQCRE.css} +8 -5
  63. package/dist/Tabs/index.js +1 -1
  64. package/dist/{Tabs-XCNPHA7B.css → Tabs-BWFQSWY3.css} +12 -0
  65. package/dist/Tag/index.js +1 -1
  66. package/dist/{Tag-4OXGO2DU.css → Tag-4BRQS6GN.css} +28 -1
  67. package/dist/TagGroup/index.js +1 -1
  68. package/dist/{TagGroup-APC2EFH4.css → TagGroup-BCQZD7ZD.css} +4 -1
  69. package/dist/TagsInput/index.js +3 -3
  70. package/dist/{TagsInput-W4P36PRJ.css → TagsInput-P2HS5QL4.css} +2 -2
  71. package/dist/ThemeSwitcher/index.js +3 -3
  72. package/dist/ThemeToggle/index.js +2 -2
  73. package/dist/TimeWindowPicker/index.js +6 -6
  74. package/dist/{TimeWindowPicker-7I7KWCMU.css → TimeWindowPicker-GBF4JDFI.css} +21 -8
  75. package/dist/Tree/layout.d.ts +3 -3
  76. package/dist/TreeCanvas/TreeCanvas.d.ts +7 -5
  77. package/dist/TreeCanvas/index.js +4 -4
  78. package/dist/{TreeCanvas-HVOV4SQN.css → TreeCanvas-L2XYONWL.css} +80 -74
  79. package/dist/TreeGrid/index.js +2 -2
  80. package/dist/{chunk-SVNXOK25.js → chunk-26SCUACK.js} +2 -2
  81. package/dist/{chunk-4UQ7SMPK.js → chunk-4FQT6ZAY.js} +1 -1
  82. package/dist/{chunk-IBYO2IJN.js → chunk-5I56UXBJ.js} +4 -4
  83. package/dist/{chunk-ZFATEERP.js → chunk-5YLON2PW.js} +1 -1
  84. package/dist/{chunk-EFYPAJT3.js → chunk-6DRDCT22.js} +1 -1
  85. package/dist/{chunk-PQNILU27.js → chunk-6HXH57BL.js} +3 -3
  86. package/dist/{chunk-BNCCEER3.js → chunk-6SIG5I72.js} +22 -11
  87. package/dist/{chunk-OM5E3TTK.js → chunk-74WGARJE.js} +5 -2
  88. package/dist/{chunk-EV6IMYJ6.js → chunk-A722MUNR.js} +1 -1
  89. package/dist/{chunk-WOFOMTGB.js → chunk-B47YUQGM.js} +6 -2
  90. package/dist/{chunk-MV2E3QZM.js → chunk-BTHX2FS3.js} +2 -2
  91. package/dist/{chunk-2QLOH454.js → chunk-BXPLX7YU.js} +3 -3
  92. package/dist/{chunk-V34H2YCY.js → chunk-CEOXFO3E.js} +1 -1
  93. package/dist/{chunk-KKLITCMF.js → chunk-CLPDVL46.js} +8 -8
  94. package/dist/{chunk-AGQ3YLA5.js → chunk-CVB7O3SZ.js} +6 -6
  95. package/dist/{chunk-QY7UU5ZB.js → chunk-DRHXRGB6.js} +1 -1
  96. package/dist/{chunk-V2XMNLMS.js → chunk-E6UWRXNM.js} +1 -1
  97. package/dist/{chunk-NQ2HQ6P5.js → chunk-HVPC2GHY.js} +6 -6
  98. package/dist/{chunk-FFKYL7Z3.js → chunk-L7THQMFB.js} +4 -2
  99. package/dist/{chunk-PAWGBSHU.js → chunk-LOECRMHA.js} +1 -1
  100. package/dist/{chunk-LSJZUA5V.js → chunk-LSB3EHBW.js} +2 -2
  101. package/dist/{chunk-ERHSECG2.js → chunk-MORLKUGM.js} +1 -1
  102. package/dist/{chunk-UWQWTGQH.js → chunk-MPXI6FM6.js} +3 -3
  103. package/dist/{chunk-DHPUMOTX.js → chunk-N5KCGFWI.js} +8 -4
  104. package/dist/{chunk-ZAO4HHXI.js → chunk-OG6CL3EB.js} +1 -1
  105. package/dist/{chunk-C5WJUZVR.js → chunk-ORNOOMVY.js} +1 -1
  106. package/dist/{chunk-WUVZDFHS.js → chunk-OVLJEVQS.js} +2 -2
  107. package/dist/{chunk-AUS5FNQE.js → chunk-PDUZO35I.js} +1 -1
  108. package/dist/{chunk-YLYOWZ4V.js → chunk-PXU6HOZB.js} +1 -1
  109. package/dist/{chunk-S7KW47IQ.js → chunk-RHHGLTXJ.js} +1 -1
  110. package/dist/{chunk-SJQ546ID.js → chunk-SEFMO2EV.js} +1 -1
  111. package/dist/{chunk-KJ34ZBBI.js → chunk-SMBKXWML.js} +1 -1
  112. package/dist/{chunk-FIFNP6PL.js → chunk-SX2DFTQV.js} +1 -1
  113. package/dist/{chunk-L6XZOCP4.js → chunk-UCYIRDND.js} +2 -2
  114. package/dist/{chunk-D6EVJUGU.js → chunk-UYK72NOS.js} +1 -1
  115. package/dist/{chunk-TIWAHZZ6.js → chunk-VCOELPCT.js} +2 -2
  116. package/dist/{chunk-2HY7I3NT.js → chunk-VE6LD3KM.js} +5 -3
  117. package/dist/{chunk-CAIHUYXV.js → chunk-W4GQWFRX.js} +1 -1
  118. package/dist/{chunk-BWIPKSWA.js → chunk-XX2VQE55.js} +1 -1
  119. package/dist/{chunk-UA7O3KKJ.js → chunk-YCTMKKRA.js} +1 -1
  120. package/dist/{chunk-DSUY5F4E.js → chunk-ZGX2DP7F.js} +2 -2
  121. package/dist/generated/index.js +41 -41
  122. package/dist/index.js +41 -41
  123. package/dist/styles.css +621 -222
  124. package/package.json +3 -3
  125. package/dist/SegmentedControl-X3BI3XU4.css +0 -68
@@ -1,4 +1,4 @@
1
- export { PricingCard } from '../chunk-L6XZOCP4.js';
2
- import '../chunk-PAWGBSHU.js';
1
+ export { PricingCard } from '../chunk-UCYIRDND.js';
2
+ import '../chunk-LOECRMHA.js';
3
3
  import '../chunk-WIATRXEJ.js';
4
4
  import '../chunk-ODEQTPFM.js';
@@ -64,9 +64,13 @@
64
64
  border-color: var(--color-brand-accent-soft-strong);
65
65
  }
66
66
 
67
+ /* One ring, over the card's own boundary rather than 2px off it, which is two
68
+ edges with a gap between them: the rule every field keeps (see Input.css).
69
+ The chosen plan keeps an accent line inside the ring, since the selection
70
+ ring below is two pixels deep and the focus ring covers one of them. */
67
71
  .crewlet-pricing-card:focus-visible {
68
72
  outline: 2px solid var(--color-focus);
69
- outline-offset: 2px;
73
+ outline-offset: var(--size-focus-ring-inset-offset);
70
74
  }
71
75
 
72
76
  /* The chosen plan takes the selection ring, which is the same inset rule
@@ -1,2 +1,2 @@
1
- export { SearchTrigger } from '../chunk-EFYPAJT3.js';
1
+ export { SearchTrigger } from '../chunk-6DRDCT22.js';
2
2
  import '../chunk-ODEQTPFM.js';
@@ -58,9 +58,12 @@
58
58
  color: var(--color-text-primary);
59
59
  }
60
60
 
61
+ /* One ring, over the trigger's own boundary rather than 2px off it, which is
62
+ two edges with a gap between them: the rule every field keeps (see
63
+ Input.css). */
61
64
  .crewlet-search-trigger:focus-visible {
62
65
  outline: 2px solid var(--color-focus);
63
- outline-offset: 2px;
66
+ outline-offset: var(--size-focus-ring-inset-offset);
64
67
  }
65
68
 
66
69
  .crewlet-search-trigger__icon {
@@ -1,5 +1,7 @@
1
1
  import { type ReactNode } from 'react';
2
2
  export type SegmentedSize = 'sm' | 'md';
3
+ /** How the options are drawn: see [SegmentedControlProps.layout]. */
4
+ export type SegmentedLayout = 'pill' | 'chips';
3
5
  export interface SegmentedOption<T extends string = string> {
4
6
  value: T;
5
7
  /** What is drawn. An empty label makes the option icon-only. */
@@ -27,6 +29,22 @@ interface SegmentedShared<T extends string> {
27
29
  value: T;
28
30
  onValueChange: (value: T) => void;
29
31
  size?: SegmentedSize | undefined;
32
+ /**
33
+ * How the options are drawn. `pill`, the default, is a row of chips in one
34
+ * tinted well, for a lens, a setting or a compact switch. `chips` is a row of
35
+ * SEPARATE chips that wraps, for a setting with more choices than a well
36
+ * holds on one line (a unit's type): each chip a raised ground of its own,
37
+ * the chosen one filled with the accent. A row whose options carry a
38
+ * description is drawn as cards whatever this says.
39
+ */
40
+ layout?: SegmentedLayout | undefined;
41
+ /**
42
+ * Drawn at the end of the row, after the last option and outside the
43
+ * choices themselves: the field that completes the last choice, such as the
44
+ * box a "Custom" chip asks for. It takes no part in the arrow keys, so a
45
+ * caret moves inside it as it does in any field.
46
+ */
47
+ trailing?: ReactNode | undefined;
30
48
  className?: string | undefined;
31
49
  }
32
50
  /**
@@ -97,5 +115,5 @@ export type SegmentedControlProps<T extends string = string> = SegmentedShared<T
97
115
  * look like two different controls depending on which component a screen
98
116
  * reached for.
99
117
  */
100
- export declare function SegmentedControl<T extends string = string>({ label, options, value, onValueChange, size, className, semantics, panelId, activate, activateHint, }: SegmentedControlProps<T>): import("react").JSX.Element;
118
+ export declare function SegmentedControl<T extends string = string>({ label, options, value, onValueChange, size, layout, trailing, className, semantics, panelId, activate, activateHint, }: SegmentedControlProps<T>): import("react").JSX.Element;
101
119
  export {};
@@ -1,4 +1,4 @@
1
1
  import '../Tabs/Tabs.css';
2
2
  import './SegmentedControl.css';
3
3
  export { SegmentedControl } from './SegmentedControl.js';
4
- export type { SegmentedActivation, SegmentedControlProps, SegmentedOption, SegmentedSize, } from './SegmentedControl.js';
4
+ export type { SegmentedActivation, SegmentedControlProps, SegmentedLayout, SegmentedOption, SegmentedSize, } from './SegmentedControl.js';
@@ -1,5 +1,5 @@
1
- export { SegmentedControl } from '../chunk-DHPUMOTX.js';
2
- import '../chunk-QY7UU5ZB.js';
1
+ export { SegmentedControl } from '../chunk-N5KCGFWI.js';
2
+ import '../chunk-DRHXRGB6.js';
3
3
  import '../chunk-BHHIIK3M.js';
4
4
  import '../chunk-BZFWDIV6.js';
5
5
  import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,160 @@
1
+ /*
2
+ * SegmentedControl: the pill row, drawn with the Tabs classes.
3
+ *
4
+ * Only what is its own lives here. The chrome, the sizes and the active chip
5
+ * come from Tabs.css, so a lens row and a setting row look the same whichever
6
+ * component a screen reached for.
7
+ */
8
+
9
+ .crewlet-segmented__text {
10
+ display: inline-flex;
11
+ flex-direction: column;
12
+ align-items: flex-start;
13
+ gap: 1px;
14
+ min-width: 0;
15
+ }
16
+
17
+ /*
18
+ * A choice a reader has to READ before making it is a card row, not a chip:
19
+ * a template with a sentence under its name does not fit in a pill, and
20
+ * squeezing it there is how the sentence ends up truncated to nothing.
21
+ */
22
+ /*
23
+ * TWO CLASSES, so this wins whatever order the stylesheets are bundled in.
24
+ * `.crewlet-tabs` sets the row's own display and alignment, and a rule of
25
+ * equal weight in a file that happens to come later takes them back.
26
+ */
27
+ .crewlet-tabs.crewlet-segmented--cards {
28
+ display: grid;
29
+ gap: var(--spacing-2);
30
+ width: 100%;
31
+ align-items: stretch;
32
+ }
33
+
34
+ /*
35
+ * The same frame a framed Checkbox draws, because it is the same row: a
36
+ * boundary on the body it sits in, and no surface of its own. A choice with a
37
+ * surface inside a panel of the same surface reads as a second panel.
38
+ */
39
+ .crewlet-segmented--cards .crewlet-segmented__option {
40
+ justify-content: flex-start;
41
+ text-align: left;
42
+ /* A sentence under a name is a sentence: it wraps rather than being cut. */
43
+ white-space: normal;
44
+ padding: var(--spacing-3);
45
+ border: 1px solid var(--color-border-default);
46
+ border-radius: var(--radius-lg);
47
+ font-size: var(--font-size-compact);
48
+ }
49
+
50
+ /* One ring, over the card's own boundary rather than 2px off it, which is two
51
+ edges with a gap between them: the rule every field keeps (see Input.css).
52
+ The chosen card still says so under the ring, in its tint and its ink. */
53
+ .crewlet-segmented--cards .crewlet-segmented__option:focus-visible {
54
+ outline-offset: var(--size-focus-ring-inset-offset);
55
+ }
56
+
57
+ /* The one card that is chosen takes the accent, which is what "here, this
58
+ one" means everywhere else in the product. */
59
+ .crewlet-segmented--cards .crewlet-segmented__option.is-active {
60
+ border-color: var(--color-brand-accent);
61
+ background: var(--color-brand-accent-soft);
62
+ color: var(--color-brand-accent-ink);
63
+ }
64
+
65
+ /*
66
+ * A ROW OF SEPARATE CHIPS, for a setting with more choices than a well holds
67
+ * on one line: the console's own row of unit types. It wraps rather than
68
+ * running off the panel it sits in, and each chip stands on the raised ground
69
+ * a chip with no edge of its own takes (held off the card by the palette
70
+ * suite), so no chip draws a frame inside the panel's. Two classes, for the
71
+ * reason the card row gives above.
72
+ */
73
+ .crewlet-tabs.crewlet-segmented--chips {
74
+ /* The chip's own drawing (below) is the --crewlet-segmented-chip-height
75
+ band inside a target-floor box, so it is the same height at every
76
+ density the console's 11px chip is drawn at. */
77
+ --crewlet-segmented-chip-height: calc(var(--size-target-min) - var(--spacing-1));
78
+ display: flex;
79
+ flex-wrap: wrap;
80
+ align-items: center;
81
+ /* No gap between ROWS: each chip's target already overhangs its drawing by
82
+ half a step above and below, so two rows' drawings stand a whole step
83
+ apart while their targets meet. */
84
+ gap: 0 var(--spacing-1);
85
+ }
86
+
87
+ /*
88
+ * SMALL, AS THE CONSOLE'S ARE, AND DRAWN SMALL BUT HIT FULL SIZE, the rule the
89
+ * org chart's own controls keep. A chip is a word in the 11px face with a step
90
+ * of room either side, drawn as a band shorter than the pointer-target floor;
91
+ * the button around it stays at the floor, so the band can be the console's
92
+ * size without being a target a finger misses. At the small control step a
93
+ * row of ten was a second row of buttons under the field's label rather than a
94
+ * row of answers to it.
95
+ *
96
+ * The band is the button's own ::before, behind the label, rather than its
97
+ * background clipped to the content box: a clip takes the corner's curve in by
98
+ * the padding it removes, and a chip this small would lose its radius.
99
+ */
100
+ .crewlet-segmented--chips .crewlet-segmented__option {
101
+ position: relative;
102
+ isolation: isolate;
103
+ min-height: var(--size-target-min);
104
+ padding: 0 var(--spacing-2);
105
+ border-radius: var(--radius-sm);
106
+ background: none;
107
+ color: var(--color-text-secondary);
108
+ font-size: var(--font-size-2xs);
109
+ }
110
+
111
+ .crewlet-segmented--chips .crewlet-segmented__option::before {
112
+ content: '';
113
+ position: absolute;
114
+ inset: calc((var(--size-target-min) - var(--crewlet-segmented-chip-height)) / 2) 0;
115
+ z-index: -1;
116
+ border-radius: var(--radius-sm);
117
+ background: var(--color-surface-elevated);
118
+ pointer-events: none;
119
+ }
120
+
121
+ /* The chosen chip is FILLED with the accent: on a row of up to ten raised
122
+ chips, a fill is the one thing that says "this one" at a glance, as the
123
+ console's row says it. Its ring stands off it, because an edge drawn on an
124
+ accent fill in the focus colour is nearly the fill's own colour. */
125
+ .crewlet-segmented--chips .crewlet-segmented__option.is-active {
126
+ color: var(--color-text-on-accent);
127
+ }
128
+
129
+ .crewlet-segmented--chips .crewlet-segmented__option.is-active::before {
130
+ background: var(--color-brand-accent);
131
+ }
132
+
133
+ /* What completes the last choice sits in the row, at the chips' own height
134
+ and in their face: a field at its own control step stood taller than every
135
+ chip beside it. */
136
+ .crewlet-segmented__trailing {
137
+ display: inline-flex;
138
+ align-items: center;
139
+ min-width: 0;
140
+ }
141
+
142
+ .crewlet-segmented--chips .crewlet-segmented__trailing .crewlet-input {
143
+ min-height: var(--crewlet-segmented-chip-height);
144
+ }
145
+
146
+ .crewlet-segmented--chips .crewlet-segmented__trailing .crewlet-input__control {
147
+ font-size: var(--font-size-2xs);
148
+ }
149
+
150
+ .crewlet-segmented__description {
151
+ font-size: var(--font-size-xs);
152
+ font-weight: var(--font-weight-regular);
153
+ line-height: var(--font-line-height-normal);
154
+ color: var(--color-text-tertiary);
155
+ white-space: normal;
156
+ }
157
+
158
+ .crewlet-segmented--cards .crewlet-segmented__option.is-active .crewlet-segmented__description {
159
+ color: var(--color-brand-accent-ink);
160
+ }
@@ -1,4 +1,4 @@
1
- export { Select } from '../chunk-SJQ546ID.js';
1
+ export { Select } from '../chunk-SEFMO2EV.js';
2
2
  import '../chunk-6MU7HNB4.js';
3
3
  import '../chunk-7RPGY3JE.js';
4
4
  import '../chunk-R25RGPUB.js';
@@ -68,8 +68,8 @@
68
68
  * leave the other bare.
69
69
  */
70
70
  .crewlet-select:focus-within {
71
- outline: 2px solid var(--color-focus);
72
- outline-offset: var(--size-focus-ring-inset-offset);
71
+ outline: 1px solid var(--color-focus);
72
+ outline-offset: -1px;
73
73
  }
74
74
 
75
75
  /*
@@ -347,8 +347,8 @@ svg.crewlet-select__chevron {
347
347
  * outset ring on the input would be cut by the menu's own `overflow: hidden`.
348
348
  */
349
349
  .crewlet-select__search:focus-within {
350
- outline: 2px solid var(--color-focus);
351
- outline-offset: var(--size-focus-ring-inset-offset);
350
+ outline: 1px solid var(--color-focus);
351
+ outline-offset: -1px;
352
352
  }
353
353
 
354
354
  .crewlet-select__search {
@@ -1,2 +1,2 @@
1
- export { Switch } from '../chunk-EV6IMYJ6.js';
1
+ export { Switch } from '../chunk-A722MUNR.js';
2
2
  import '../chunk-ODEQTPFM.js';
@@ -111,14 +111,17 @@
111
111
  * control's own :focus-visible. The track is the same box: the control is
112
112
  * `inset: 0` over it.
113
113
  *
114
- * OUTSET, like a Checkbox's and unlike a text field's. A 20px pill has no
115
- * room to draw a ring inside itself, and there is no boundary to cover out
116
- * there either: the track's own border goes the accent colour of its fill
117
- * when the switch is on, so the ring is the only edge in that space.
114
+ * OUTSIDE THE TRACK, like a Checkbox's and unlike a text field's: a 20px pill
115
+ * has no room to draw a ring inside itself. But AGAINST it, not 2px off it.
116
+ * Off, the track draws a real boundary of its own, and a ring standing off
117
+ * that boundary was two edges with a gap between them, which reads as a
118
+ * second outline rather than as focus. Flush, the ring and the track are one
119
+ * edge in both states, and the ring is still drawn whole on the ground around
120
+ * the pill, where it is measured.
118
121
  */
119
122
  .crewlet-switch__track:has(.crewlet-switch__control:focus-visible) {
120
123
  outline: 2px solid var(--color-focus);
121
- outline-offset: 2px;
124
+ outline-offset: 0;
122
125
  }
123
126
 
124
127
  .crewlet-switch__text {
@@ -1,4 +1,4 @@
1
- export { TabPanel, Tabs, tabId } from '../chunk-QY7UU5ZB.js';
1
+ export { TabPanel, Tabs, tabId } from '../chunk-DRHXRGB6.js';
2
2
  import '../chunk-BHHIIK3M.js';
3
3
  import '../chunk-BZFWDIV6.js';
4
4
  import '../chunk-ODEQTPFM.js';
@@ -288,6 +288,18 @@
288
288
  outline-offset: 2px;
289
289
  }
290
290
 
291
+ /*
292
+ * A CHIP RINGS ON ITS OWN EDGE, flush rather than 2px off it. The chip that
293
+ * is on draws a hairline round itself, and a ring standing off that hairline
294
+ * was two edges with a gap between them, which reads as a second outline
295
+ * rather than as focus. Flush, the ring covers the hairline, and it stays
296
+ * inside the well's 2px inset: two pixels wide, it meets the well's own
297
+ * boundary rather than leaving a sliver of the well between the two.
298
+ */
299
+ .crewlet-tabs--pill .crewlet-tabs__tab:focus-visible {
300
+ outline-offset: 0;
301
+ }
302
+
291
303
  .crewlet-tabs__tab.is-disabled,
292
304
  .crewlet-tabs__tab:disabled {
293
305
  opacity: 0.55;
package/dist/Tag/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { Tag } from '../chunk-PAWGBSHU.js';
1
+ export { Tag } from '../chunk-LOECRMHA.js';
2
2
  import '../chunk-WIATRXEJ.js';
3
3
  import '../chunk-ODEQTPFM.js';
@@ -264,11 +264,38 @@
264
264
  box-shadow: inset 0 0 0 1px var(--crewlet-tag-ink);
265
265
  }
266
266
 
267
+ /*
268
+ * ONE RING, ON THE PILL'S OWN EDGE, never off it. A pill draws a border
269
+ * whenever it is neutral, pointed at or pressed, and a ring standing off that
270
+ * border is two edges with a gap between them, which reads as a second
271
+ * outline rather than as focus. So every control here rings over the pill's
272
+ * border, and the offset that puts it there is each control's own, because
273
+ * the three boxes meet that border in different places:
274
+ *
275
+ * - a whole actionable tag IS the pill, so -1px covers the border and one
276
+ * pixel outside it;
277
+ * - the press half of a split pill stops at the border's inside edge, so 0
278
+ * puts its ring on the same two pixels;
279
+ * - the remove reaches over the border at the top and the bottom (see its
280
+ * rule below), so -1px puts its ring there as well.
281
+ *
282
+ * ONE PIXEL INTO THE PILL AT MOST, not a field's two, because a pressed tag
283
+ * says so in an ink line just inside its border: a ring two pixels deep would
284
+ * cover the one change that pressing it makes.
285
+ */
267
286
  .crewlet-tag--actionable:focus-visible,
268
287
  .crewlet-tag__press:focus-visible,
269
288
  .crewlet-tag__remove:focus-visible {
270
289
  outline: 2px solid var(--color-focus);
271
- outline-offset: 2px;
290
+ }
291
+
292
+ .crewlet-tag--actionable:focus-visible,
293
+ .crewlet-tag__remove:focus-visible {
294
+ outline-offset: -1px;
295
+ }
296
+
297
+ .crewlet-tag__press:focus-visible {
298
+ outline-offset: 0;
272
299
  }
273
300
 
274
301
  /* ── the pill that holds two controls ──────────────────────────────────── */
@@ -1,4 +1,4 @@
1
- export { TagGroup } from '../chunk-V2XMNLMS.js';
1
+ export { TagGroup } from '../chunk-E6UWRXNM.js';
2
2
  import '../chunk-RSAQOKH3.js';
3
3
  import '../chunk-BZFWDIV6.js';
4
4
  import '../chunk-ODEQTPFM.js';
@@ -63,9 +63,12 @@
63
63
  color: var(--color-text-primary);
64
64
  }
65
65
 
66
+ /* One ring, over the dashed boundary rather than 2px off it, which is two
67
+ edges with a gap between them: the rule every field keeps (see Input.css).
68
+ The list above has no edge of its own, so its ring stays outset. */
66
69
  .crewlet-tag-group__more:focus-visible {
67
70
  outline: 2px solid var(--color-focus);
68
- outline-offset: 2px;
71
+ outline-offset: var(--size-focus-ring-inset-offset);
69
72
  }
70
73
 
71
74
  @media (prefers-reduced-motion: reduce) {
@@ -1,10 +1,10 @@
1
- export { TagsInput } from '../chunk-UWQWTGQH.js';
2
- import '../chunk-PAWGBSHU.js';
1
+ export { TagsInput } from '../chunk-MPXI6FM6.js';
2
+ import '../chunk-LOECRMHA.js';
3
3
  import '../chunk-WIATRXEJ.js';
4
4
  import '../chunk-6MU7HNB4.js';
5
5
  import '../chunk-RSAQOKH3.js';
6
6
  import '../chunk-7RPGY3JE.js';
7
7
  import '../chunk-R25RGPUB.js';
8
- import '../chunk-4UQ7SMPK.js';
8
+ import '../chunk-4FQT6ZAY.js';
9
9
  import '../chunk-BZFWDIV6.js';
10
10
  import '../chunk-ODEQTPFM.js';
@@ -72,8 +72,8 @@
72
72
  * the whole reason they sit above the field instead of inside it.
73
73
  */
74
74
  .crewlet-tags-input__box:focus-visible {
75
- outline: 2px solid var(--color-focus);
76
- outline-offset: var(--size-focus-ring-inset-offset);
75
+ outline: 1px solid var(--color-focus);
76
+ outline-offset: -1px;
77
77
  }
78
78
 
79
79
  .crewlet-tags-input.is-disabled {
@@ -1,7 +1,7 @@
1
- export { DensitySwitcher, ThemeSwitcher } from '../chunk-S7KW47IQ.js';
1
+ export { DensitySwitcher, ThemeSwitcher } from '../chunk-RHHGLTXJ.js';
2
2
  export { applyDensity, applyStoredPreferences, applyTheme, resolveTheme, useDensityPreference, useSystemTheme, useThemePreference } from '../chunk-K3OWD7BJ.js';
3
- import '../chunk-DHPUMOTX.js';
4
- import '../chunk-QY7UU5ZB.js';
3
+ import '../chunk-N5KCGFWI.js';
4
+ import '../chunk-DRHXRGB6.js';
5
5
  import '../chunk-BHHIIK3M.js';
6
6
  import '../chunk-BZFWDIV6.js';
7
7
  import '../chunk-ODEQTPFM.js';
@@ -1,5 +1,5 @@
1
- export { ThemeToggle } from '../chunk-C5WJUZVR.js';
1
+ export { ThemeToggle } from '../chunk-ORNOOMVY.js';
2
2
  import '../chunk-K3OWD7BJ.js';
3
- import '../chunk-4UQ7SMPK.js';
3
+ import '../chunk-4FQT6ZAY.js';
4
4
  import '../chunk-BZFWDIV6.js';
5
5
  import '../chunk-ODEQTPFM.js';
@@ -1,13 +1,13 @@
1
- export { DEFAULT_TIME_WINDOW_LABELS, TIME_WINDOW_SPANS, TimeWindowPicker, describeTimeWindow, isTimeWindowSet, parseTimeWindowDuration, resolveTimeWindow, timeWindowMatchesPreset } from '../chunk-NQ2HQ6P5.js';
2
- import '../chunk-SJQ546ID.js';
3
- import '../chunk-AUS5FNQE.js';
1
+ export { DEFAULT_TIME_WINDOW_LABELS, TIME_WINDOW_SPANS, TimeWindowPicker, describeTimeWindow, isTimeWindowSet, parseTimeWindowDuration, resolveTimeWindow, timeWindowMatchesPreset } from '../chunk-HVPC2GHY.js';
2
+ import '../chunk-SEFMO2EV.js';
3
+ import '../chunk-PDUZO35I.js';
4
4
  import '../chunk-GXQ3B46I.js';
5
5
  import '../chunk-6MU7HNB4.js';
6
- import '../chunk-DSUY5F4E.js';
6
+ import '../chunk-ZGX2DP7F.js';
7
7
  import '../chunk-PQADV6P6.js';
8
8
  import '../chunk-7RPGY3JE.js';
9
9
  import '../chunk-R25RGPUB.js';
10
- import '../chunk-4UQ7SMPK.js';
11
- import '../chunk-ZAO4HHXI.js';
10
+ import '../chunk-4FQT6ZAY.js';
11
+ import '../chunk-OG6CL3EB.js';
12
12
  import '../chunk-BZFWDIV6.js';
13
13
  import '../chunk-ODEQTPFM.js';
@@ -37,11 +37,17 @@
37
37
  border-color: var(--color-border-hover);
38
38
  }
39
39
 
40
+ /*
41
+ * ONE RING, OVER THE BOUNDARY, for focus and for open alike. It stood 2px off
42
+ * the box with the border recoloured to the focus colour as well, which is an
43
+ * accent hairline, a gap and an accent band: two rings from one state. On the
44
+ * inset offset the ring covers the border, and the border keeps its own colour
45
+ * under it, the rule every field keeps (see Input.css).
46
+ */
40
47
  .crewlet-time-window:focus-visible,
41
48
  .crewlet-time-window.is-open {
42
- outline: 2px solid var(--color-focus);
43
- outline-offset: 2px;
44
- border-color: var(--color-focus);
49
+ outline: 1px solid var(--color-focus);
50
+ outline-offset: -1px;
45
51
  }
46
52
 
47
53
  .crewlet-time-window.is-disabled,
@@ -301,11 +307,18 @@ svg.crewlet-time-window__tick {
301
307
  transition: border-color var(--motion-duration-fast) var(--motion-easing-default);
302
308
  }
303
309
 
304
- .crewlet-time-window__masked:focus-within {
305
- outline: 2px solid transparent;
306
- outline-offset: 2px;
307
- border-color: var(--color-focus);
308
- box-shadow: var(--shadow-focus);
310
+ /*
311
+ * THE BOX RINGS ONCE, AS A FIELD DOES. It drew the field register's old
312
+ * indicator: the border recoloured to the focus colour AND --shadow-focus,
313
+ * which is itself a ring (a background-coloured gap, then a band), so a
314
+ * focused box showed two accent edges with a gap between them, and the
315
+ * transparent outline under them was a third that forced-colors mode paints.
316
+ * What is left is the field's one outline on the inset offset, over the box's
317
+ * own boundary (see Input.css), keyed on the box's own input.
318
+ */
319
+ .crewlet-time-window__masked:has(.crewlet-time-window__masked-input:focus-visible) {
320
+ outline: 1px solid var(--color-focus);
321
+ outline-offset: -1px;
309
322
  }
310
323
 
311
324
  .crewlet-time-window__masked-input {
@@ -96,9 +96,9 @@ export interface LayoutGaps {
96
96
  *
97
97
  * IT IS PART OF THE LAYOUT rather than padding on whatever draws it, because
98
98
  * the canvas scrolls and CLIPS: a margin drawn as padding is outside the
99
- * scrollable content, so the outermost card's halo, its focus ring and the
100
- * control hanging under it are cut off at the frame at exactly the moment a
101
- * reader has panned to that card. Unset, none.
99
+ * scrollable content, so the control hanging under the outermost card is cut
100
+ * off at the frame at exactly the moment a reader has panned to that card.
101
+ * Unset, none.
102
102
  */
103
103
  margin?: number | undefined;
104
104
  }
@@ -76,7 +76,7 @@
76
76
  * of its suite.
77
77
  */
78
78
  import { type KeyboardEvent, type MouseEvent, type ReactNode, type Ref } from 'react';
79
- import { type CanvasLabels } from '../Canvas/index.js';
79
+ import { type CanvasGround, type CanvasLabels } from '../Canvas/index.js';
80
80
  import { type TreeConnectorShape, type TreeInput, type TreeItemAction, type LayoutRanks, type TreeModel, type TreeViewHandle } from '../Tree/index.js';
81
81
  /** A card of the layout: its id and the cards nested under it. */
82
82
  export interface TreeCardInput {
@@ -93,9 +93,9 @@ export interface TreeCardInput {
93
93
  * with no such choice derives from a stable identity.
94
94
  *
95
95
  * A NAMED SET RATHER THAN A COLOUR. A caller that could hand in any colour
96
- * would hand in a literal, and the fill, the border, the halo and the ink of a
97
- * tinted card are four measured steps of one hue rather than one value with
98
- * three alphas applied by whoever drew it last.
96
+ * would hand in a literal, and the fill, the border and the ink of a tinted
97
+ * card are measured steps of one hue rather than one value with alphas applied
98
+ * by whoever drew it last.
99
99
  */
100
100
  export type TreeCardTone = 'purple' | 'cyan' | 'green' | 'amber' | 'rose' | 'blue';
101
101
  /**
@@ -417,6 +417,8 @@ export interface TreeCanvasProps {
417
417
  * which says WHICH node the surface is about.
418
418
  */
419
419
  dimmed?: boolean | undefined;
420
+ /** What the field under the chart is drawn as: see [CanvasProps.ground]. */
421
+ ground?: CanvasGround | undefined;
420
422
  /**
421
423
  * A node being composed in the chart rather than in a surface over it: see
422
424
  * [TreeComposing]. Null, and the chart is the data and nothing else.
@@ -427,4 +429,4 @@ export interface TreeCanvasProps {
427
429
  ref?: Ref<TreeCanvasHandle> | undefined;
428
430
  className?: string | undefined;
429
431
  }
430
- export declare function TreeCanvas({ label, nodes, cards, cardOf, renderCard, renderUnder, cardTone, appearance, ranks, connector, groups, onNodeKey, onNodeKeyDown, hasNodeMenu, selectedId, onSelect, anchorNode, overlay, controlsPlacement, controlsExtra, controlsBelow, hint, dimmed, composing, labels, ref, className, }: TreeCanvasProps): import("react").JSX.Element;
432
+ export declare function TreeCanvas({ label, nodes, cards, cardOf, renderCard, renderUnder, cardTone, appearance, ranks, connector, groups, onNodeKey, onNodeKeyDown, hasNodeMenu, selectedId, onSelect, anchorNode, overlay, controlsPlacement, controlsExtra, controlsBelow, hint, dimmed, ground, composing, labels, ref, className, }: TreeCanvasProps): import("react").JSX.Element;
@@ -1,10 +1,10 @@
1
- export { TreeCanvas } from '../chunk-FFKYL7Z3.js';
1
+ export { TreeCanvas } from '../chunk-L7THQMFB.js';
2
2
  import '../chunk-S3BCVWTU.js';
3
- import '../chunk-2HY7I3NT.js';
3
+ import '../chunk-VE6LD3KM.js';
4
4
  import '../chunk-53DVJCVW.js';
5
5
  import '../chunk-7RPGY3JE.js';
6
6
  import '../chunk-R25RGPUB.js';
7
- import '../chunk-4UQ7SMPK.js';
8
- import '../chunk-ZAO4HHXI.js';
7
+ import '../chunk-4FQT6ZAY.js';
8
+ import '../chunk-OG6CL3EB.js';
9
9
  import '../chunk-BZFWDIV6.js';
10
10
  import '../chunk-ODEQTPFM.js';