@capillaryjs/capillary-ui 1.1.0 → 1.3.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/CHANGELOG.md +117 -2
- package/README.md +196 -35
- package/colors/README.md +53 -3
- package/colors/gray/colors.css +4 -2
- package/colors/green/colors.css +4 -2
- package/colors/iceblue/colors.css +4 -2
- package/colors/ocean/colors.css +4 -2
- package/colors/orange/colors.css +4 -2
- package/colors/purple/colors.css +4 -2
- package/colors/red/colors.css +7 -3
- package/colors/yellow/colors.css +8 -4
- package/dist/Components/app/app.d.ts +3 -3
- package/dist/Components/app/app.d.ts.map +1 -1
- package/dist/Components/component.d.ts +24 -3
- package/dist/Components/component.d.ts.map +1 -1
- package/dist/Components/data/descriptionList.d.ts.map +1 -1
- package/dist/Components/data/listview/listview.d.ts.map +1 -1
- package/dist/Components/data/table/DataTable.d.ts +8 -0
- package/dist/Components/data/table/DataTable.d.ts.map +1 -1
- package/dist/Components/data/table/FilterPanel.d.ts.map +1 -1
- package/dist/Components/data/table/TableHeader.d.ts +2 -0
- package/dist/Components/data/table/TableHeader.d.ts.map +1 -1
- package/dist/Components/data/table/TableHeaderCell.d.ts +18 -0
- package/dist/Components/data/table/TableHeaderCell.d.ts.map +1 -1
- package/dist/Components/data/table/tableDataSource.d.ts +6 -0
- package/dist/Components/data/table/tableDataSource.d.ts.map +1 -1
- package/dist/Components/data/treeview/treeview.d.ts.map +1 -1
- package/dist/Components/layout/groupBox.d.ts.map +1 -1
- package/dist/Components/layout/header.d.ts.map +1 -1
- package/dist/Components/layout/layout.d.ts +2 -2
- package/dist/Components/layout/layout.d.ts.map +1 -1
- package/dist/Components/layout/layoutTraits.d.ts +6 -0
- package/dist/Components/layout/layoutTraits.d.ts.map +1 -1
- package/dist/Components/layout/optionGroup.d.ts.map +1 -1
- package/dist/Components/layout/optionsBox.d.ts +2 -1
- package/dist/Components/layout/optionsBox.d.ts.map +1 -1
- package/dist/Components/layout/splitView.d.ts +2 -0
- package/dist/Components/layout/splitView.d.ts.map +1 -1
- package/dist/Components/lineinputs/CheckableControl.d.ts +2 -2
- package/dist/Components/lineinputs/CheckableControl.d.ts.map +1 -1
- package/dist/Components/lineinputs/LabeledInputControl.d.ts +2 -2
- package/dist/Components/lineinputs/LabeledInputControl.d.ts.map +1 -1
- package/dist/Components/lineinputs/LineControl.d.ts +7 -0
- package/dist/Components/lineinputs/LineControl.d.ts.map +1 -0
- package/dist/Components/lineinputs/SelectControl.d.ts.map +1 -1
- package/dist/Components/lineinputs/checkbox/Checkbox.d.ts +9 -3
- package/dist/Components/lineinputs/checkbox/Checkbox.d.ts.map +1 -1
- package/dist/Components/lineinputs/checkbox/QuadCheckbox.d.ts +1 -0
- package/dist/Components/lineinputs/checkbox/QuadCheckbox.d.ts.map +1 -1
- package/dist/Components/lineinputs/checkbox/TriCheckbox.d.ts +1 -0
- package/dist/Components/lineinputs/checkbox/TriCheckbox.d.ts.map +1 -1
- package/dist/Components/lineinputs/datetime/TemporalInput.d.ts.map +1 -1
- package/dist/Components/lineinputs/dropdown.d.ts +4 -2
- package/dist/Components/lineinputs/dropdown.d.ts.map +1 -1
- package/dist/Components/lineinputs/radio.d.ts +9 -4
- package/dist/Components/lineinputs/radio.d.ts.map +1 -1
- package/dist/Components/lineinputs/requiredPresentation.d.ts +21 -0
- package/dist/Components/lineinputs/requiredPresentation.d.ts.map +1 -0
- package/dist/Components/lineinputs/textbox.d.ts.map +1 -1
- package/dist/Components/lineinputs/toggle.d.ts +4 -2
- package/dist/Components/lineinputs/toggle.d.ts.map +1 -1
- package/dist/Components/menu/button.d.ts +2 -2
- package/dist/Components/menu/button.d.ts.map +1 -1
- package/dist/Components/status/progressBar.d.ts +2 -2
- package/dist/Components/status/progressBar.d.ts.map +1 -1
- package/dist/Components/status/statusPresentation.d.ts.map +1 -1
- package/dist/Components/theme/stylesheetPicker.d.ts +2 -1
- package/dist/Components/theme/stylesheetPicker.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2697 -2079
- package/dist/index.js.map +1 -1
- package/dist/jsx-dev-runtime.js +3 -3
- package/dist/jsx-runtime-Ba-uafjl.js +1631 -0
- package/dist/jsx-runtime-Ba-uafjl.js.map +1 -0
- package/dist/jsx-runtime.js +2 -2
- package/dist/localization.d.ts +1 -1
- package/dist/localization.d.ts.map +1 -1
- package/dist/routing/RouteOutlet.d.ts.map +1 -1
- package/dist/runtime.d.ts +4 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/styling/theme.d.ts +1 -1
- package/dist/styling/theme.d.ts.map +1 -1
- package/docs/application-composition-guide.md +22 -5
- package/package.json +3 -3
- package/styles/structural.css +704 -158
- package/themes/README.md +9 -2
- package/themes/base.css +114 -18
- package/themes/capillary/theme.css +300 -0
- package/themes/shiny/theme.css +33 -15
- package/themes/soft/theme.css +37 -0
- package/themes/white/theme.css +52 -0
- package/dist/jsx-dev-runtime-D3UnwrKT.js +0 -1362
- package/dist/jsx-dev-runtime-D3UnwrKT.js.map +0 -1
- package/themes/java/theme.css +0 -21
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,121 @@ Versioning.
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Set the default GroupBox content gap independently from island spacing, using
|
|
12
|
+
a compact 2px rhythm for controls inside a GroupBox.
|
|
13
|
+
|
|
14
|
+
- Render unfilled required controls with a transparent negative ✲ marker:
|
|
15
|
+
inside native input surfaces and beside a pseudo-element checkable outline
|
|
16
|
+
extension that does not change the label's layout width.
|
|
17
|
+
- Place checkbox and radio validation halos around the complete labelled
|
|
18
|
+
choice while retaining the error border on the painted shell.
|
|
19
|
+
- Keep busy buttons visually normal and layer only the working animation over
|
|
20
|
+
their ordinary chrome. Gate ProgressBar's busy animation on an emitter-backed
|
|
21
|
+
`FetchState.Loading` state, applying the working texture to both determinate
|
|
22
|
+
and indeterminate bars so literal indeterminate values remain static.
|
|
23
|
+
- Make ProgressBar fill its available inline width while remaining shrinkable
|
|
24
|
+
inside constrained layouts.
|
|
25
|
+
- Omit island content padding on direct app-root headers, letting their navbar
|
|
26
|
+
and toolbar own spacing. Preserve nested headers, other islands, outer
|
|
27
|
+
gutters, borders, and shadows across themes and managed/legacy layouts.
|
|
28
|
+
- Keep island borders and shadows visible through nested scrollports by using
|
|
29
|
+
existing gutter space inside the clipping boundary. Preserve surface
|
|
30
|
+
alignment, shared gaps, and split resizing without theme clearance tokens.
|
|
31
|
+
Add browser pixel checks for painted borders/shadows and clipping regressions.
|
|
32
|
+
- Publish only the maintained Capillary, Shiny, Soft, White, and Minimal themes.
|
|
33
|
+
The former Glossy, Original, Java, Dark, and Sci-fi assets and picker entries
|
|
34
|
+
are removed from the package and applications.
|
|
35
|
+
- Make named-theme surfaces, text, borders, and fills palette-derived. In
|
|
36
|
+
particular, Shiny progress chrome now follows the muted surface and primary
|
|
37
|
+
ramps instead of fixed Ice blue stops. Neutral black/white gloss and shadow
|
|
38
|
+
overlays remain intentionally literal.
|
|
39
|
+
- Replace hue-named palette status primitives with semantic negative, positive,
|
|
40
|
+
and neutral status colors. Error and success aliases follow the negative and
|
|
41
|
+
positive colors; multi-state checkbox deny, require, and prefer chrome uses
|
|
42
|
+
negative, positive, and neutral respectively.
|
|
43
|
+
- Derive shared chrome backgrounds from muted primary palette tones, so panels,
|
|
44
|
+
table headers, button gradients, and disabled surfaces follow palette changes.
|
|
45
|
+
Ice blue preserves exactly `#f5f7f8`, `#ebeff3`, and `#d7dee3`. The derivation
|
|
46
|
+
uses relative HSL colors and sRGB mixing; existing UI aliases remain overridable.
|
|
47
|
+
- Add palette-level `--palette-primary-surface-saturation`: `0` removes primary
|
|
48
|
+
hue from the three chrome surfaces, `1` retains their calibrated default.
|
|
49
|
+
- Keep unchanged DataTable headers out of row-update renders and avoid redundant
|
|
50
|
+
renderer marker, attribute, dataset, and style writes.
|
|
51
|
+
- Preserve table-part names after minification and identify header cells by column.
|
|
52
|
+
- Preserve table/header/body identities when loading/error messages or captions change.
|
|
53
|
+
|
|
54
|
+
- `DataTable` filterable columns no longer keep a permanent document-level
|
|
55
|
+
click listener: the outside-click listener that closes the filter panel is
|
|
56
|
+
now attached only while the panel is open. Previously every click in the
|
|
57
|
+
document fired it, which also flooded event traces with a
|
|
58
|
+
"Table header cell: click" interaction per click. The listener uses the new
|
|
59
|
+
`Component.listenWhile`, so it stays on the normal traced native-event path
|
|
60
|
+
and coalesces with other listeners observing the same click.
|
|
61
|
+
|
|
62
|
+
### Added
|
|
63
|
+
|
|
64
|
+
- Add a live `readOnly` state to Dropdown, checkbox variants, RadioButton,
|
|
65
|
+
RadioGroup, Toggle, and stylesheet pickers. Read-only value controls stay
|
|
66
|
+
focusable and readable, expose native `readonly` or `aria-readonly` as
|
|
67
|
+
appropriate, and reject attempted user changes without becoming disabled.
|
|
68
|
+
- Add palette-derived base read-only chrome tokens for inputs, dropdowns,
|
|
69
|
+
checkables, and toggles. Themes can override the tokens but no longer need to
|
|
70
|
+
reproduce disabled styling to represent a fixed value.
|
|
71
|
+
- Add inherited `islands` layout mode to `CapillaryUiApp` and `Layout`, with
|
|
72
|
+
native `cap-island-layout` / `cap-island-layout-off` traits. One outer inset
|
|
73
|
+
and shared gutters replace accumulated island margins inside opt-in scopes;
|
|
74
|
+
ordinary island content and legacy layouts keep their existing spacing.
|
|
75
|
+
The `--island-gap` and `--island-inset` tokens support theme/application
|
|
76
|
+
overrides, RouteOutlet carries the mode, and SplitView puts its accessible
|
|
77
|
+
separator in one gutter, including zero-gap and RTL resizing.
|
|
78
|
+
- Add the light `capillary` theme: bright rounded cards, restrained neutral
|
|
79
|
+
elevation, compact controls, and palette-primary selected states.
|
|
80
|
+
- Add an overridable instance diagnostic label and a named table-body consumer.
|
|
81
|
+
Consumer facts report render triggers/passes and own renderer DOM-write counts,
|
|
82
|
+
distinguishing execution from DOM work without changing update scheduling.
|
|
83
|
+
- Add `Component.listenWhile(target, type, listener, options)`: like
|
|
84
|
+
`listen`, but returns a function that detaches the listener, for listeners
|
|
85
|
+
that are only active some of the time. It runs through the same traced
|
|
86
|
+
native-event coalescing as `listen` and is removed on destroy if still
|
|
87
|
+
attached.
|
|
88
|
+
- Add a `filterable` column flag to `DataTable`: a column marked
|
|
89
|
+
`filterable` derives its header filter options from the field's distinct
|
|
90
|
+
values across the source's unfiltered rows, so options stay stable while
|
|
91
|
+
a filter is applied. Explicit `filterOptions` still take precedence.
|
|
92
|
+
Local and caller-query data sources expose their pre-filter rows through
|
|
93
|
+
the new `TableDataSource.sourceRows`; remote sources fall back to the
|
|
94
|
+
displayed rows.
|
|
95
|
+
- Add diagnostic ownership scopes and stable diagnostic labels, automatic
|
|
96
|
+
native interaction roots, component/read/watch and function-consumer facts,
|
|
97
|
+
and reactive child, live-property, and native-binding endpoints. Synchronous
|
|
98
|
+
propagation retains its original interaction through the complete UI chain;
|
|
99
|
+
inspection subtrees can be excluded without hiding application writes.
|
|
100
|
+
|
|
101
|
+
### Changed
|
|
102
|
+
|
|
103
|
+
- Use flexbox for single-axis component stacks and simple centered chrome,
|
|
104
|
+
retaining grid only where its track model is needed. This does not change the
|
|
105
|
+
public DOM or layout contract.
|
|
106
|
+
- Give all single-line controls the same minimum row footprint with symmetric
|
|
107
|
+
breathing room, including checkbox/radio variants, temporal inputs, and
|
|
108
|
+
ProgressBar. Add `--control-row-min-height` and `--control-row-padding-block`
|
|
109
|
+
without changing painted control shapes or Capillary's `6px 5px` padding.
|
|
110
|
+
Only OptionsBox retains compact rows and owns a fixed 2px vertical option
|
|
111
|
+
rhythm across themes; RadioGroup no longer adds a default gap on top of the
|
|
112
|
+
common row spacing elsewhere.
|
|
113
|
+
- Empty required text, temporal, and dropdown controls now have a subtle
|
|
114
|
+
themeable dashed required-value outline. The same outline appears on an
|
|
115
|
+
unchecked two-state `Checkbox`; tri- and quad-state checkboxes intentionally
|
|
116
|
+
do not use native required validity because no single semantic state is the
|
|
117
|
+
required value.
|
|
118
|
+
- Retained `Loading` results in `DataTable`, `ListView`, and `TreeView` now
|
|
119
|
+
show a non-blocking translucent animated working texture while their existing
|
|
120
|
+
rows remain visible.
|
|
121
|
+
|
|
122
|
+
## 1.2.0 - 2026-09-15
|
|
123
|
+
|
|
9
124
|
### Changed
|
|
10
125
|
|
|
11
126
|
- Make DataTable, ListView, and TreeView shrink and own overflow before a
|
|
@@ -34,8 +149,8 @@ Versioning.
|
|
|
34
149
|
`cap-header:has(+ cap-toolbar)` shadow override together with its
|
|
35
150
|
`--section-header-with-toolbar-shadow` variable.
|
|
36
151
|
- Normalize line-control sizing and text centering in structural CSS: 24px
|
|
37
|
-
default textbox, dropdown, toggle, and button bodies at 12px UI text
|
|
38
|
-
|
|
152
|
+
default textbox, dropdown, toggle, and button bodies at 12px UI text.
|
|
153
|
+
Remove Shiny's label/select text offsets and
|
|
39
154
|
prevent toggle border/selection changes from shifting segment text.
|
|
40
155
|
- Refine Shiny's input depth, toolbar/table-header chrome, navigation-to-toolbar
|
|
41
156
|
seam, and loading BlockGraph treatment without moving structural layout
|
package/README.md
CHANGED
|
@@ -149,6 +149,14 @@ A class component has explicit phases:
|
|
|
149
149
|
`onCleanup()` registers listeners or other cleanup functions that Capillary UI invokes
|
|
150
150
|
on destruction.
|
|
151
151
|
|
|
152
|
+
Diagnostic labels default to static `diagnosticLabel`, `hostName`, then the class
|
|
153
|
+
name. Override the instance `diagnosticLabel` getter when instances need distinct
|
|
154
|
+
names; identity labels are captured at first observation. Table diagnostics expose
|
|
155
|
+
`Table header`, column-specific header cells, and `Table body`. Unchanged header
|
|
156
|
+
props skip parent-driven rendering, while sort/filter subscriptions remain active.
|
|
157
|
+
Consumer events distinguish render passes from own renderer DOM writes; see the
|
|
158
|
+
[diagnostics guide](../../docs/diagnostics.md) for the exact counting boundary.
|
|
159
|
+
|
|
152
160
|
```tsx
|
|
153
161
|
class Counter extends Component {
|
|
154
162
|
readonly count = new Emitter(0)
|
|
@@ -197,7 +205,7 @@ class Badge extends Component<BadgeProps> {
|
|
|
197
205
|
static override hostName = 'badge'
|
|
198
206
|
static override css = css`
|
|
199
207
|
& { display: inline-flex; }
|
|
200
|
-
&[data-tone="positive"] { color: var(--palette-
|
|
208
|
+
&[data-tone="positive"] { color: var(--palette-status-positive); }
|
|
201
209
|
`
|
|
202
210
|
}
|
|
203
211
|
```
|
|
@@ -313,11 +321,11 @@ the tables below denotes that TypeScript type parameter.
|
|
|
313
321
|
| `Toolbar` | Named action group | `label`, `orientation` |
|
|
314
322
|
| `Label` | Native label for rich or live text | `text`, `htmlFor`; live: `text` |
|
|
315
323
|
| `Textbox` | Labelled native text input with validation | `label`, `valueEmitter`, `defaultValue`, `type`, `name`, `placeholder`, `disabled`, `required`, `readOnly`, `busy`, `error`, native text constraints, `inputRef`, `onInput`, `onChange`; live: availability, `busy`, and `error` |
|
|
316
|
-
| `Dropdown<T>` | Labelled native select | `options`, `label`, `valueEmitter`, `defaultValue`, `placeholder`, `disabled`, `required`, `busy`, `error`, `onChange`; `options` may be static or a readable emitter whose fetch state supplies loading/error feedback |
|
|
317
|
-
| `RadioButton` | Standalone native radio and label | `label`, `name`, `value`, `checked`, `disabled`, `required`, `busy`, `error`, `onChange`; live: state, availability, `busy`, `error` |
|
|
318
|
-
| `RadioGroup<T>` | Named native-radio fieldset owning one value | `options` as `[value, label]` tuples, `label`, `valueEmitter`, `defaultValue`, `disabled`, `required`, `busy`, `error`, `onChange`; options are ordinary render data |
|
|
319
|
-
| `Toggle<T>` | ARIA radio group rendered as toggle buttons | `options` as `[value, label]` tuples, `label`, `valueEmitter`, `defaultValue`, `disabled`, `required`, `busy`, `error`, `onChange` |
|
|
320
|
-
| `Checkbox<T>` | Configurable keyboard-operable semantic state cycle | `symbols` as `[content, value]` tuples, `label`/`ariaLabel`, `valueEmitter`, `defaultValue`, `disabled`, `required`, `busy`, `error`, `onChange` |
|
|
324
|
+
| `Dropdown<T>` | Labelled native select | `options`, `label`, `valueEmitter`, `defaultValue`, `placeholder`, `disabled`, `required`, `readOnly`, `busy`, `error`, `onChange`; `readOnly` retains focusability and restores the selected value after attempted changes; `options` may be static or a readable emitter whose fetch state supplies loading/error feedback |
|
|
325
|
+
| `RadioButton` | Standalone native radio and label | `label`, `name`, `value`, `checked`, `disabled`, `required`, `readOnly`, `busy`, `error`, `onChange`; live: state, availability, `busy`, `error` |
|
|
326
|
+
| `RadioGroup<T>` | Named native-radio fieldset owning one value | `options` as `[value, label]` tuples, `label`, `valueEmitter`, `defaultValue`, `disabled`, `required`, `readOnly`, `busy`, `error`, `onChange`; options are ordinary render data |
|
|
327
|
+
| `Toggle<T>` | ARIA radio group rendered as toggle buttons | `options` as `[value, label]` tuples, `label`, `valueEmitter`, `defaultValue`, `disabled`, `required`, `readOnly`, `busy`, `error`, `onChange` |
|
|
328
|
+
| `Checkbox<T>` | Configurable keyboard-operable semantic state cycle | `symbols` as `[content, value]` tuples, `label`/`ariaLabel`, `valueEmitter`, `defaultValue`, `disabled`, `required`, `readOnly`, `busy`, `error`, `onChange` |
|
|
321
329
|
| `TriCheckbox` | Neutral/prefer/deny `FilterMode` cycle | Same public props as `Checkbox`, except fixed symbols |
|
|
322
330
|
| `QuadCheckbox` | Neutral/prefer/require/deny `FilterMode` cycle | Same public props as `Checkbox`, except fixed symbols |
|
|
323
331
|
| `DatePicker` (experimental) | Native `<input type="date">` | `CivilDate` value props, `label`/`ariaLabel`, `name`, `autoComplete`, `disabled`, `required`, `readOnly`, `busy`, `error`, `min`/`max`/`step`, `inputRef`, input/change callbacks |
|
|
@@ -330,7 +338,12 @@ the native forward cycle.
|
|
|
330
338
|
|
|
331
339
|
`busy` is presentational state: it sets native/ARIA busy semantics and paints
|
|
332
340
|
the theme's moving working texture without disabling an input or choice.
|
|
333
|
-
`Button` remains the exception: a busy action is unavailable until it settles
|
|
341
|
+
`Button` remains the exception: a busy action is unavailable until it settles,
|
|
342
|
+
but keeps its normal button colors, border, and elevation with the working
|
|
343
|
+
texture layered on top. `ProgressBar` only paints that working texture when it
|
|
344
|
+
has a `valueEmitter` whose fetch state is `Loading`; this applies to both
|
|
345
|
+
determinate and indeterminate bars. A literal `value={null}` is simply an
|
|
346
|
+
unfilled indeterminate bar.
|
|
334
347
|
When `error` is also present, error presentation wins over the animation.
|
|
335
348
|
Every error-bearing control describes its native surface with a focusable
|
|
336
349
|
`role="alert"` overlay. Its icon and initially hidden message are absolutely
|
|
@@ -355,12 +368,12 @@ const view = new Emitter<'list' | 'grid'>('list')
|
|
|
355
368
|
|
|
356
369
|
| Component | Purpose | Key props and state |
|
|
357
370
|
| --- | --- | --- |
|
|
358
|
-
| `CapillaryUiApp` | Fixed `cap-app` application shell and theme-text boundary | `sizing`: `embedded`/viewport axes; `layout`: `horizontal`/`vertical`; `landmark`: `main`/`none`; content or overridden `renderContent()` |
|
|
371
|
+
| `CapillaryUiApp` | Fixed `cap-app` application shell and theme-text boundary | `sizing`: `embedded`/viewport axes; `layout`: `horizontal`/`vertical`; `islands`: inherited surface spacing; `landmark`: `main`/`none`; content or overridden `renderContent()` |
|
|
359
372
|
| `Header` | Styled native heading surface | `level` (1–6), `headingId`, content |
|
|
360
|
-
| `GroupBox` | Labelled group; defaults to a bordered vertical-header group and may be a section or column | required `header`, content; optional `variant`: `section` or `column` |
|
|
361
|
-
| `OptionGroup` | Labelled native fieldset for related controls | `label`/`ariaLabel`, `OptionGroupHeaderEnd` and ordinary content children, `disabled`, `required`, `busy`, `error`; state props are live |
|
|
362
|
-
| `OptionsBox` | GroupBox specialization arranging
|
|
363
|
-
| `Layout` | Presentation-only arrangement of arbitrary children | exactly one of `horizontal`/`vertical`; `allocation`, `scroll`, optional accessible-region configuration |
|
|
373
|
+
| `GroupBox` | Labelled group; defaults to a bordered vertical-header group and may be a section or column | required `header`, direct content arranged vertically (`section` arranges direct content horizontally); optional `variant`: `section` or `column` |
|
|
374
|
+
| `OptionGroup` | Labelled native fieldset for related controls | `label`/`ariaLabel`, `OptionGroupHeaderEnd` and ordinary content children, `disabled`, `required`, `busy`, `error`; state props are live. Use for related direct checkboxes or multiple distinct controls. |
|
|
375
|
+
| `OptionsBox` | GroupBox specialization arranging compact choice groups | required `header`, direct `OptionGroup` and/or `RadioGroup` content |
|
|
376
|
+
| `Layout` | Presentation-only arrangement of arbitrary children | exactly one of `horizontal`/`vertical`; `allocation`, `scroll`, inherited `islands` spacing, optional accessible-region configuration |
|
|
364
377
|
| `Panel` | Optional labelled, themed region composed over a Layout body | `header`, `horizontal`/`vertical`, `allocation`, `scroll`, `disabled`; `PanelToolbar` and ordinary content children; live: `disabled` |
|
|
365
378
|
| `Sidebar` | Labelled complementary region with fixed header/toolbar and scrolling content | `header`, `ariaLabel`; `SidebarToolbar` and ordinary content children |
|
|
366
379
|
| `SplitView` | Resizable two-pane layout | required `SplitPrimary` and `SplitSecondary` Layout panes; `horizontal`/`vertical`, `allocation`, initial/minimum sizes, separator label, `onResize` |
|
|
@@ -475,12 +488,13 @@ range while retaining selections outside that range.
|
|
|
475
488
|
On an initial snapshot, or a loading snapshot with no result, all three
|
|
476
489
|
collection views render deterministic, `aria-hidden` placeholder rows;
|
|
477
490
|
`placeholderCount` selects their count. A loading snapshot with retained rows
|
|
478
|
-
keeps those rows in place
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
491
|
+
keeps those rows in place, marks the collection busy, and displays a thin
|
|
492
|
+
animated translucent working texture, avoiding flicker during sort and filter
|
|
493
|
+
refinements.
|
|
494
|
+
Application renderers never receive dummy values, and refreshes preserve valid
|
|
495
|
+
keyed selections and expansions. Error snapshots retain any available rows,
|
|
496
|
+
add an error edge and overlay detail icon, and stop the loading animation. A
|
|
497
|
+
`DataTable` data source with `retry` also renders its localized retry action.
|
|
484
498
|
|
|
485
499
|
Advanced compositions may use `BaseSelectionHandler`,
|
|
486
500
|
`SingleSelectionHandler`, `MultiSelectionHandler`, and
|
|
@@ -503,13 +517,21 @@ expander needs a reusable presentation trait such as `colored`.
|
|
|
503
517
|
For reusable sources, use `createLocalTableDataSource`,
|
|
504
518
|
`createQueryTableDataSource`, `createHandlerTableDataSource`, or
|
|
505
519
|
`createRestTableDataSource`. Sources expose `query`, `sortEmitter`,
|
|
506
|
-
`filtersEmitter`, optional `retry`, and `dispose()`.
|
|
507
|
-
query-shaped sources pass their rows through an
|
|
508
|
-
view, so their sort and filter state always
|
|
520
|
+
`filtersEmitter`, optional `retry`, optional `sourceRows`, and `dispose()`.
|
|
521
|
+
Both direct data and query-shaped sources pass their rows through an
|
|
522
|
+
emitter-derived local table view, so their sort and filter state always
|
|
523
|
+
changes the rendered rows. `sourceRows` exposes the rows before local
|
|
524
|
+
sort/filter when the source can provide them — local and caller-query
|
|
525
|
+
sources do; remote sources leave it absent because filtering is
|
|
526
|
+
server-side.
|
|
509
527
|
|
|
510
528
|
`TableColumn` definitions own display and local comparison/filter functions.
|
|
511
529
|
When a column's visible `label` is rich content, supply its textual
|
|
512
530
|
`ariaLabel` for Capillary UI-generated sort and filter control names.
|
|
531
|
+
Set a column's `filterable` flag to derive its header filter options from
|
|
532
|
+
the field's distinct values across `sourceRows` (or the displayed rows when
|
|
533
|
+
the source cannot expose them), so the options stay stable while a filter
|
|
534
|
+
is applied. Explicit `filterOptions` take precedence over `filterable`.
|
|
513
535
|
The pure `applyLocalTableState`, `serializeTableQuery`, and related table-query
|
|
514
536
|
helpers keep local behavior and remote encoding explicit. Pagination,
|
|
515
537
|
virtualization, and server-specific wire policy remain application concerns.
|
|
@@ -519,7 +541,7 @@ virtualization, and server-specific wire policy remain application concerns.
|
|
|
519
541
|
| Component | Purpose | Key props and state |
|
|
520
542
|
| --- | --- | --- |
|
|
521
543
|
| `Dialog` | Controlled native modal with focus containment and restoration | `title`, `description`, `DialogActions` and ordinary content children, `valueEmitter`/`defaultValue`, `closeLabel`, `showCloseButton`, `initialFocusRef`, `onClose` |
|
|
522
|
-
| `ProgressBar` | Labelled native progress with visual track | required `label`, `value` or `valueEmitter`, `max`, `valueText`; `null` is indeterminate |
|
|
544
|
+
| `ProgressBar` | Labelled native progress with visual track | required `label`, `value` or `valueEmitter`, `max`, `valueText`; fills its available width; `null` is indeterminate; emitter-backed busy chrome (including determinate bars) requires `FetchState.Loading` |
|
|
523
545
|
| `ThemePicker` | Select and replace a Capillary UI theme link | value props, `options`, `label`/`ariaLabel`, `disabled`, `targetDocument`, `onChange` |
|
|
524
546
|
| `ColorPicker` | Select and replace a Capillary UI color link | same contract as `ThemePicker` |
|
|
525
547
|
|
|
@@ -738,6 +760,14 @@ component selectors. Color files provide anchors and endpoints. Component
|
|
|
738
760
|
`static css` owns selectors, layout, pseudo-elements, native states, and
|
|
739
761
|
interaction mechanics.
|
|
740
762
|
|
|
763
|
+
The three chrome backgrounds (`--ui-primary-bg-color`, `--ui-medium-bg-color`,
|
|
764
|
+
and `--ui-dark-bg-color`) alias muted primary surface tones derived from the
|
|
765
|
+
palette's primary anchor and light endpoint. Ice blue retains the exact legacy
|
|
766
|
+
colors `#f5f7f8`, `#ebeff3`, and `#d7dee3`; other palettes recolor these surfaces.
|
|
767
|
+
See the [palette contract](colors/README.md#muted-primary-surfaces) for the
|
|
768
|
+
relative-HSL/sRGB calibration, including the `0`–`1`
|
|
769
|
+
`--palette-primary-surface-saturation` palette control and override points.
|
|
770
|
+
|
|
741
771
|
Theme files provide intentional overrides. Custom properties are the primary
|
|
742
772
|
instrument and belong on `:root` inside `@layer theme`, with `color-scheme` as
|
|
743
773
|
the only ordinary property in that block. A theme may also write ordinary CSS
|
|
@@ -746,6 +776,11 @@ be placed after the `@layer theme` block: component CSS is injected as an
|
|
|
746
776
|
unlayered `<style>` element prepended to `<head>`, so unlayered theme rules win
|
|
747
777
|
by document order while layered ones would always lose.
|
|
748
778
|
|
|
779
|
+
The built-in theme options are Capillary, Shiny, Soft, White, and Minimal.
|
|
780
|
+
Capillary is a bright, compact card treatment with restrained elevation and
|
|
781
|
+
palette-primary selections. Minimal is adaptive; the other options are fixed
|
|
782
|
+
light treatments.
|
|
783
|
+
|
|
749
784
|
`capillaryUiThemeVariableCatalog` describes the supported palette and semantic
|
|
750
785
|
variable hierarchy. `findCapillaryUiStylesheetOption`, `replaceCapillaryUiStylesheet`,
|
|
751
786
|
`setCapillaryUiAppearance`, and `getCapillaryUiAppearance` support application-controlled
|
|
@@ -753,10 +788,23 @@ runtime selection.
|
|
|
753
788
|
|
|
754
789
|
### Line-control sizing
|
|
755
790
|
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
791
|
+
All single-line controls reserve the same vertical row space: Textbox,
|
|
792
|
+
Dropdown (including theme/color pickers), Toggle, Button, checkbox variants,
|
|
793
|
+
RadioButton, date/time controls, and ProgressBar. Their existing painted
|
|
794
|
+
bodies remain centered within that row; small checkbox/radio shapes do not
|
|
795
|
+
grow to look like text fields.
|
|
796
|
+
|
|
797
|
+
`--control-min-height: 2em` sets the body minimum (24px at the default 12px
|
|
798
|
+
`--ui-font-size`). The row uses the greater of that minimum and
|
|
799
|
+
`--control-row-min-height` (default `0px`), plus
|
|
800
|
+
`--control-row-padding-block: .25em` on each side. Default rows are therefore
|
|
801
|
+
30px with 3px above and below the body. Capillary supplies a `2.75em` row
|
|
802
|
+
floor (39px including padding) to accommodate its roomier chrome and native
|
|
803
|
+
temporal inputs while retaining its `6px 5px` control padding. Additional
|
|
804
|
+
layout `gap` is optional and adds to this built-in breathing room.
|
|
805
|
+
|
|
806
|
+
These are minimum sizes: multiline/rich content can grow without clipping.
|
|
807
|
+
Labels and native controls inherit the font family and share a unitless
|
|
760
808
|
1.2 authored text line height. Native single-line inputs may clamp the used
|
|
761
809
|
line-height to platform font metrics (notably Firefox on Linux); their bodies
|
|
762
810
|
and text remain centered. Larger content can increase the minimum-sized body.
|
|
@@ -765,6 +813,29 @@ minimum-width/shrinking behavior. Field and button inline padding is 5px;
|
|
|
765
813
|
toggle segments use 6px. General `--space-xs`/`--space-sm` no longer determine
|
|
766
814
|
these line controls' padding.
|
|
767
815
|
|
|
816
|
+
`OptionsBox` deliberately keeps compact descendants, including through nested
|
|
817
|
+
`OptionGroup` and `Layout` wrappers: it removes the shared row floor and
|
|
818
|
+
block padding while retaining each control's natural body size. Its checkbox
|
|
819
|
+
and radio rows are normally 1.2em, or the theme's larger painted-shell size.
|
|
820
|
+
OptionsBox owns a fixed 2px vertical option rhythm—between nested groups,
|
|
821
|
+
checkboxes, and radio options—regardless of theme. Ordinary GroupBox and
|
|
822
|
+
Toolbar do not opt into compact spacing. RadioGroup elsewhere adds no
|
|
823
|
+
inter-option gap by default, so the same number of radio and checkbox rows
|
|
824
|
+
occupies the same height (excluding any group legend). Set
|
|
825
|
+
`--radio-group-gap` to add spacing explicitly outside OptionsBox.
|
|
826
|
+
|
|
827
|
+
An `OptionGroup` and a labelled `RadioGroup` both produce a native
|
|
828
|
+
`fieldset`/`legend`. For one mutually exclusive choice, put the `RadioGroup`
|
|
829
|
+
directly in an `OptionsBox` and give it the one visible label. Use an
|
|
830
|
+
`OptionGroup` for a collection of direct checkboxes (or when its legend adds a
|
|
831
|
+
separate, meaningful concept around several controls). Do not wrap a single
|
|
832
|
+
labelled `RadioGroup` in an `OptionGroup` merely for layout; that creates
|
|
833
|
+
redundant legends and nested fieldsets.
|
|
834
|
+
|
|
835
|
+
Maintained themes add chrome without text offsets. Shadows do not participate
|
|
836
|
+
in centering. Toggle borders and selected overlap are painted independently
|
|
837
|
+
of segment layout, so selection does not move text.
|
|
838
|
+
|
|
768
839
|
Horizontal form `GroupBox` children use their natural content size: GroupBox
|
|
769
840
|
does not contribute a synthetic preferred width or an artificial size floor.
|
|
770
841
|
Intrinsic label/body tracks distinguish preferred field widths from the
|
|
@@ -794,14 +865,6 @@ their normal inset. In this composition, omit a `DataTable` `caption`: the
|
|
|
794
865
|
labelled Panel header supplies the surrounding data-region name. Application
|
|
795
866
|
data-surface components can opt in by declaring the same static trait.
|
|
796
867
|
|
|
797
|
-
Checkbox variants and RadioButton retain compact 1.2em label rows with 1em
|
|
798
|
-
squares/circles. They center within stretched horizontal hosts without making
|
|
799
|
-
vertical lists as tall as text fields. Date/time controls consume the same
|
|
800
|
-
shared sizing rules. Themes may deliberately override the minimum (Java does),
|
|
801
|
-
but Shiny uses the structural defaults and adds chrome without text offsets.
|
|
802
|
-
Shadows do not participate in centering. Toggle borders and selected overlap
|
|
803
|
-
are painted independently of segment layout, so selection does not move text.
|
|
804
|
-
|
|
805
868
|
### Root sizing and typography
|
|
806
869
|
|
|
807
870
|
`CapillaryUiApp` is block-level and always applies `--application-background`,
|
|
@@ -837,7 +900,7 @@ semantics.
|
|
|
837
900
|
Applications may explicitly opt native elements into Capillary UI presentation and
|
|
838
901
|
layout contracts by applying public Capillary UI traits such as `island`,
|
|
839
902
|
`cap-layout-horizontal`, `cap-layout-vertical`, `cap-size-natural`,
|
|
840
|
-
`cap-size-flexible`, and `cap-
|
|
903
|
+
`cap-size-flexible`, `cap-scroll`, and `cap-island-layout`. These traits are intentionally
|
|
841
904
|
element-agnostic and may style application-owned native markup as well as
|
|
842
905
|
Capillary UI-owned hosts.
|
|
843
906
|
|
|
@@ -893,6 +956,85 @@ provide breakpoint variants.
|
|
|
893
956
|
native markup. Capillary UI rejects nested component islands; application markup must
|
|
894
957
|
preserve the same one-layer invariant.
|
|
895
958
|
|
|
959
|
+
### Composing islands without margin doubling
|
|
960
|
+
|
|
961
|
+
Enable `islands` once on the app or the Layout that contains the composition:
|
|
962
|
+
|
|
963
|
+
```tsx
|
|
964
|
+
<CapillaryUiApp sizing="viewport" islands>
|
|
965
|
+
<Header island>Application header</Header>
|
|
966
|
+
<Layout horizontal allocation="flexible">
|
|
967
|
+
<Sidebar island header="Navigation">...</Sidebar>
|
|
968
|
+
<Layout vertical allocation="flexible">
|
|
969
|
+
<Panel island header="Overview">...</Panel>
|
|
970
|
+
<Panel island header="Results" allocation="flexible">...</Panel>
|
|
971
|
+
</Layout>
|
|
972
|
+
</Layout>
|
|
973
|
+
<footer className="island cap-size-natural">Status</footer>
|
|
974
|
+
</CapillaryUiApp>
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
`islands` is a **layout mode**; `island` still marks each **surface**. The
|
|
978
|
+
outermost enabled container gets one perimeter inset. Participating layouts
|
|
979
|
+
then place a single shared gutter between their children, with no island
|
|
980
|
+
margins to add up. Nested Layouts inherit the mode automatically, including
|
|
981
|
+
through ordinary wrappers and `RouteOutlet`. Repeating `islands` on an already
|
|
982
|
+
enabled nested Layout does not add another inset. An app with `islands` and no
|
|
983
|
+
explicit `layout` defaults to vertical; Layout still requires an axis.
|
|
984
|
+
|
|
985
|
+
The public `CapillaryUiIslandLayoutProps` contract is static `islands?: boolean`:
|
|
986
|
+
|
|
987
|
+
- `true` enables managed composition;
|
|
988
|
+
- omitted or `undefined` inherits the surrounding mode;
|
|
989
|
+
- `false` stops inheritance and restores legacy spacing in that subtree.
|
|
990
|
+
|
|
991
|
+
Surface boundaries stop managed layout gaps from reaching controls inside
|
|
992
|
+
them. Panel padding, toolbar gaps, and other internal spacing keep their own
|
|
993
|
+
contracts. A later explicit enabled scope below an opt-out starts a fresh
|
|
994
|
+
perimeter inset. Neither this mode nor nested layouts permit nested islands.
|
|
995
|
+
|
|
996
|
+
Use `--island-gap` for gutters and `--island-inset` for the outer inset. Base
|
|
997
|
+
defaults both to `1rem`; White uses zero. Override these on the composition,
|
|
998
|
+
and optionally `--island-gap` on a nested Layout for a local gutter.
|
|
999
|
+
`--island-padding` remains the padding **inside** each surface, except a direct
|
|
1000
|
+
app-root header: `cap-app > header.island` and `cap-app > cap-header.island`
|
|
1001
|
+
have zero padding. These shell headers delegate internal spacing to their
|
|
1002
|
+
navbar, toolbar, and branding rows. Their border, shadow, outer inset, and
|
|
1003
|
+
gutter remain unchanged. Nested headers and non-island headings are unaffected;
|
|
1004
|
+
this rule also applies outside managed island mode. Use a native `<header
|
|
1005
|
+
className="island">` for a shell containing navigation/toolbars; `Header`
|
|
1006
|
+
remains the component for a native heading.
|
|
1007
|
+
|
|
1008
|
+
`SplitView`
|
|
1009
|
+
inherits the mode and places its separator in one shared gutter; a zero gutter
|
|
1010
|
+
retains an overlapping drag target and keyboard resizing.
|
|
1011
|
+
|
|
1012
|
+
Scrolling layouts automatically include surrounding gutter space in their
|
|
1013
|
+
scrollport, so an island's border and shadow can paint there. Equal padding
|
|
1014
|
+
and negative margin extend the clip by half a gutter without moving the
|
|
1015
|
+
surfaces or increasing their separation. Nested scrollports reuse this space;
|
|
1016
|
+
RouteOutlet and SplitView leave clipping to their content/panes. Themes only
|
|
1017
|
+
declare their ordinary borders and shadows: no clearance token is required.
|
|
1018
|
+
Surface contents and opt-outs retain ordinary scrolling behavior. A zero
|
|
1019
|
+
gutter deliberately leaves no paint space between adjacent surfaces.
|
|
1020
|
+
|
|
1021
|
+
Native markup can use `cap-island-layout` and `cap-island-layout-off`. Combine
|
|
1022
|
+
them with a direction trait, or with your own `display: grid` rules. A wrapper
|
|
1023
|
+
around one region needs no new trait. A native wrapper arranging multiple
|
|
1024
|
+
regions must opt into a layout: inheritance does not turn arbitrary elements
|
|
1025
|
+
into flex/grid containers. Axes, dimensions, responsive wrapping, allocation,
|
|
1026
|
+
and scroll ownership remain explicit application choices.
|
|
1027
|
+
|
|
1028
|
+
Migration is opt-in. Existing layouts outside managed scopes keep
|
|
1029
|
+
`--island-margin` and their former behavior. When enabling a scope, remove
|
|
1030
|
+
margin-cancellation selectors and redundant gap rules, and move any intended
|
|
1031
|
+
spacing override to `--island-gap`/`--island-inset` on the layout. A direct CSS
|
|
1032
|
+
`margin` or `gap` override still wins through the normal cascade; the framework
|
|
1033
|
+
does not measure or rewrite application styles. `islands={false}` can isolate
|
|
1034
|
+
a legacy region during incremental migration.
|
|
1035
|
+
|
|
1036
|
+
### Semantic category color
|
|
1037
|
+
|
|
896
1038
|
`colored` consumes an explicit `--c1`, `--c2`, `--c3` triplet for the shared
|
|
897
1039
|
gradient and `--colored-shadow` treatment. It does not choose semantic colors
|
|
898
1040
|
for the application.
|
|
@@ -921,3 +1063,22 @@ legacy browsers, or a concurrent rendering scheduler.
|
|
|
921
1063
|
- [Theme contract](themes/README.md)
|
|
922
1064
|
- [Color palette contract](colors/README.md)
|
|
923
1065
|
- [Release history](CHANGELOG.md)
|
|
1066
|
+
|
|
1067
|
+
## Optional interaction-to-leaf diagnostics
|
|
1068
|
+
|
|
1069
|
+
With a Capillary diagnostic observer attached, native handlers and bindings
|
|
1070
|
+
establish interaction roots. Component reads/watchers, class/function renders,
|
|
1071
|
+
reactive children, and native/live-property bindings report causal consumers.
|
|
1072
|
+
Without an observer these paths do not create diagnostic events.
|
|
1073
|
+
|
|
1074
|
+
Runtime `diagnosticScope` and static component `diagnosticScope` allow tool
|
|
1075
|
+
subtrees to be excluded. Set static `diagnosticLabel` (or function component
|
|
1076
|
+
`diagnosticLabel`) for names that survive minification; built-in hosts already
|
|
1077
|
+
supply readable defaults. Keep the application in its normal runtime and use an
|
|
1078
|
+
excluded runtime for custom inspection controls. Existing application-emitter
|
|
1079
|
+
writes remain observable even if initiated by an excluded control.
|
|
1080
|
+
|
|
1081
|
+
These additive APIs require the diagnostics-enabled Capillary/Capillary UI 1.2
|
|
1082
|
+
lines. See the [diagnostics guide](../../docs/diagnostics.md) and
|
|
1083
|
+
[DevTools package](../capillary-devtools/README.md). Application policy remains
|
|
1084
|
+
outside the UI runtime, and playback never rerenders the inspected application.
|
package/colors/README.md
CHANGED
|
@@ -14,9 +14,13 @@ A palette supplies:
|
|
|
14
14
|
|
|
15
15
|
- `--palette-light` and `--palette-dark` endpoints;
|
|
16
16
|
- `--palette-contrast-light` and `--palette-contrast-dark` foregrounds;
|
|
17
|
-
- `--palette-
|
|
17
|
+
- `--palette-status-negative`, `--palette-status-positive`, and
|
|
18
|
+
`--palette-status-neutral` status primitives. The last is deliberately
|
|
19
|
+
distinct from the `--palette-neutral-*` tonal ramp;
|
|
18
20
|
- `--palette-primary-500`, `--palette-secondary-500`, and
|
|
19
21
|
`--palette-neutral-500` anchors.
|
|
22
|
+
- palette-primary-surface-saturation, a 0–1 multiplier for the three muted
|
|
23
|
+
primary chrome surfaces.
|
|
20
24
|
|
|
21
25
|
`themes/base.css` derives the remaining numeric ramp stops, ordinary
|
|
22
26
|
`primary`/`light`/`dark` aliases, and transparent light variants with
|
|
@@ -31,9 +35,11 @@ ramp intentionally changes hue.
|
|
|
31
35
|
--palette-dark: #111827;
|
|
32
36
|
--palette-contrast-light: #fff;
|
|
33
37
|
--palette-contrast-dark: #111827;
|
|
34
|
-
--palette-
|
|
35
|
-
--palette-
|
|
38
|
+
--palette-status-negative: #c62828;
|
|
39
|
+
--palette-status-positive: #2e7d32;
|
|
40
|
+
--palette-status-neutral: #64748b;
|
|
36
41
|
--palette-primary-500: #2989d8;
|
|
42
|
+
--palette-primary-surface-saturation: 1;
|
|
37
43
|
--palette-secondary-500: #7137a8;
|
|
38
44
|
--palette-neutral-500: #7892aa;
|
|
39
45
|
}
|
|
@@ -44,6 +50,50 @@ Color files must not declare semantic roles such as `--button-*`,
|
|
|
44
50
|
`--input-*`, or `--panel-*`. The base and active theme map derived palette
|
|
45
51
|
values to those roles.
|
|
46
52
|
|
|
53
|
+
## Muted primary surfaces
|
|
54
|
+
|
|
55
|
+
The base also derives `--palette-primary-surface-light`,
|
|
56
|
+
`--palette-primary-surface-medium`, and `--palette-primary-surface-dark` from
|
|
57
|
+
`--palette-primary-500` and `--palette-light`. These are pale, desaturated
|
|
58
|
+
surface tones, separate from the accent ramp: Ice blue's cyan
|
|
59
|
+
`--palette-primary-light-mix` intentionally does not tint these surfaces.
|
|
60
|
+
The existing `--ui-primary-bg-color`, `--ui-medium-bg-color`, and
|
|
61
|
+
`--ui-dark-bg-color` variables alias them, respectively. Shiny panels, table
|
|
62
|
+
headers, button gradients, and other consumers retain their existing wiring.
|
|
63
|
+
|
|
64
|
+
The derivation uses relative HSL to reduce primary saturation and apply a small
|
|
65
|
+
hue offset, followed by `color-mix(in srgb, ..., var(--palette-light))`. Its
|
|
66
|
+
rational coefficients preserve the historical Ice blue colors exactly:
|
|
67
|
+
|
|
68
|
+
| Surface | Ice blue sRGB | Hue offset | Saturation multiplier | Primary tint weight |
|
|
69
|
+
| --- | --- | --- | --- | --- |
|
|
70
|
+
| light | `#f5f7f8` | `-248/35` degrees | `759/2975` | `17/253` |
|
|
71
|
+
| medium | `#ebeff3` | `102/35` degrees | `253/700` | `32/253` |
|
|
72
|
+
| dark | `#d7dee3` | `-73/35` degrees | `759/2975` | `68/253` |
|
|
73
|
+
|
|
74
|
+
These are calibration ratios, not arbitrary rounded percentages: the reference
|
|
75
|
+
primary `#2989d8` has HSL hue `7248/35`, saturation `17500/253` percent, and
|
|
76
|
+
lightness `12850/255` percent. The three legacy targets have different hues
|
|
77
|
+
and saturations, so one white/primary ramp cannot reproduce all three. The
|
|
78
|
+
same calibrated recipe runs for every palette; there is no Ice blue override.
|
|
79
|
+
Changing the primary anchor or light endpoint recomputes all three surfaces.
|
|
80
|
+
Applications may still override the surface tokens or existing UI aliases.
|
|
81
|
+
|
|
82
|
+
`--palette-primary-surface-saturation` controls how much primary hue the three
|
|
83
|
+
surfaces retain. It is a palette number from `0` through `1`: `1` is the
|
|
84
|
+
calibrated default (and preserves Ice blue exactly), `0.5` halves the primary
|
|
85
|
+
saturation, and `0` makes all three surfaces completely neutral. It affects
|
|
86
|
+
only these muted surfaces, never the primary accent ramp or component semantic
|
|
87
|
+
roles that use it.
|
|
88
|
+
|
|
89
|
+
Shiny's chrome and progress-track gradients explicitly interpolate in sRGB,
|
|
90
|
+
preserving their legacy appearance when stops become derived `color()` values.
|
|
91
|
+
Custom gradients that need the same legacy interpolation should likewise declare
|
|
92
|
+
`in srgb` instead of relying on the browser's choice of interpolation space.
|
|
93
|
+
|
|
94
|
+
This derivation requires relative HSL colors and `color-mix()`, verified in
|
|
95
|
+
the package's Chromium, Firefox, and WebKit browser matrix.
|
|
96
|
+
|
|
47
97
|
## Loading and replacement
|
|
48
98
|
|
|
49
99
|
Load one palette after Capillary UI's base and structural CSS and before the active
|
package/colors/gray/colors.css
CHANGED
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
--palette-dark: #111827;
|
|
7
7
|
--palette-contrast-light: var(--palette-light);
|
|
8
8
|
--palette-contrast-dark: var(--palette-dark);
|
|
9
|
-
--palette-
|
|
10
|
-
--palette-
|
|
9
|
+
--palette-status-negative: #b3261e;
|
|
10
|
+
--palette-status-positive: #287a3c;
|
|
11
|
+
--palette-status-neutral: #64748b;
|
|
11
12
|
|
|
12
13
|
--palette-primary-500: #5d6873;
|
|
14
|
+
--palette-primary-surface-saturation: 1;
|
|
13
15
|
--palette-secondary-500: #1769aa;
|
|
14
16
|
--palette-neutral-500: #858d95;
|
|
15
17
|
}
|
package/colors/green/colors.css
CHANGED
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
--palette-dark: #111827;
|
|
7
7
|
--palette-contrast-light: var(--palette-light);
|
|
8
8
|
--palette-contrast-dark: var(--palette-dark);
|
|
9
|
-
--palette-
|
|
10
|
-
--palette-
|
|
9
|
+
--palette-status-negative: #b3261e;
|
|
10
|
+
--palette-status-positive: #287a3c;
|
|
11
|
+
--palette-status-neutral: #64748b;
|
|
11
12
|
|
|
12
13
|
--palette-primary-500: #287a3c;
|
|
14
|
+
--palette-primary-surface-saturation: 1;
|
|
13
15
|
--palette-secondary-500: #087f78;
|
|
14
16
|
--palette-neutral-500: #75947a;
|
|
15
17
|
}
|
|
@@ -6,13 +6,15 @@
|
|
|
6
6
|
--palette-dark: #111827;
|
|
7
7
|
--palette-contrast-light: var(--palette-light);
|
|
8
8
|
--palette-contrast-dark: var(--palette-dark);
|
|
9
|
-
--palette-
|
|
10
|
-
--palette-
|
|
9
|
+
--palette-status-negative: #b3261e;
|
|
10
|
+
--palette-status-positive: #287a3c;
|
|
11
|
+
--palette-status-neutral: #64748b;
|
|
11
12
|
|
|
12
13
|
/* Preserve the legacy Shiny movement from navy through blue to cyan. */
|
|
13
14
|
--palette-primary-light-mix: #00b9e8;
|
|
14
15
|
--palette-primary-dark-mix: #00193f;
|
|
15
16
|
--palette-primary-500: #2989d8;
|
|
17
|
+
--palette-primary-surface-saturation: 1;
|
|
16
18
|
--palette-secondary-500: #7137a8;
|
|
17
19
|
--palette-neutral-500: #7892aa;
|
|
18
20
|
}
|
package/colors/ocean/colors.css
CHANGED
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
--palette-dark: #111827;
|
|
7
7
|
--palette-contrast-light: var(--palette-light);
|
|
8
8
|
--palette-contrast-dark: var(--palette-dark);
|
|
9
|
-
--palette-
|
|
10
|
-
--palette-
|
|
9
|
+
--palette-status-negative: #b3261e;
|
|
10
|
+
--palette-status-positive: #287a3c;
|
|
11
|
+
--palette-status-neutral: #64748b;
|
|
11
12
|
|
|
12
13
|
--palette-primary-500: #087f78;
|
|
14
|
+
--palette-primary-surface-saturation: 1;
|
|
13
15
|
--palette-secondary-500: #1769aa;
|
|
14
16
|
--palette-neutral-500: #668f8a;
|
|
15
17
|
}
|
package/colors/orange/colors.css
CHANGED
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
--palette-dark: #111827;
|
|
7
7
|
--palette-contrast-light: var(--palette-light);
|
|
8
8
|
--palette-contrast-dark: var(--palette-dark);
|
|
9
|
-
--palette-
|
|
10
|
-
--palette-
|
|
9
|
+
--palette-status-negative: #b3261e;
|
|
10
|
+
--palette-status-positive: #287a3c;
|
|
11
|
+
--palette-status-neutral: #64748b;
|
|
11
12
|
|
|
12
13
|
--palette-primary-500: #a94b00;
|
|
14
|
+
--palette-primary-surface-saturation: 1;
|
|
13
15
|
--palette-secondary-500: #7137a8;
|
|
14
16
|
--palette-neutral-500: #a87a56;
|
|
15
17
|
}
|