@starci/grammar 0.12.14 → 0.14.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/LICENSE +21 -21
- package/README.md +34 -31
- package/dist/.build-stamp.json +4 -4
- package/dist/common/components-forms.css +28 -44
- package/dist/common/components-list-panel.css +8 -0
- package/dist/common/components-navigation.css +163 -6
- package/dist/common/components-overlays.css +41 -2
- package/dist/common/conformance.d.ts +3 -8
- package/dist/common/conformance.d.ts.map +1 -1
- package/dist/common/conformance.js +4 -9
- package/dist/common/conformance.js.map +1 -1
- package/dist/common/registry.d.ts +24 -21
- package/dist/common/registry.d.ts.map +1 -1
- package/dist/common/registry.js +4 -4
- package/dist/common/registry.js.map +1 -1
- package/dist/common/renderers-forms.d.ts +11 -11
- package/dist/common/renderers-navigation.d.ts +5 -5
- package/dist/common/renderers-navigation.d.ts.map +1 -1
- package/dist/common/renderers-navigation.js +1 -1
- package/dist/common/renderers-navigation.js.map +1 -1
- package/dist/common/renderers-overlays.d.ts +2 -2
- package/dist/common/renderers-overlays.d.ts.map +1 -1
- package/dist/common/renderers-overlays.js.map +1 -1
- package/dist/common/renderers.d.ts +4 -1
- package/dist/common/renderers.d.ts.map +1 -1
- package/dist/common/renderers.js +3 -0
- package/dist/common/renderers.js.map +1 -1
- package/dist/common/{rule-catalog.generated.d.ts → rule-catalog.d.ts} +1 -1
- package/dist/common/rule-catalog.d.ts.map +1 -0
- package/dist/common/{rule-catalog.generated.js → rule-catalog.js} +2 -4
- package/dist/common/rule-catalog.js.map +1 -0
- package/dist/common/styles.css +236 -48
- package/dist/core/branch/ComboBox/index.d.ts +5 -5
- package/dist/core/branch/ComboBox/index.d.ts.map +1 -1
- package/dist/core/branch/ComboBox/index.js +9 -2
- package/dist/core/branch/ComboBox/index.js.map +1 -1
- package/dist/core/branch/DataTable/index.d.ts +20 -3
- package/dist/core/branch/DataTable/index.d.ts.map +1 -1
- package/dist/core/branch/DataTable/index.js +45 -8
- package/dist/core/branch/DataTable/index.js.map +1 -1
- package/dist/core/branch/FlowGraph/index.d.ts +26 -7
- package/dist/core/branch/FlowGraph/index.d.ts.map +1 -1
- package/dist/core/branch/FlowGraph/index.js +132 -30
- package/dist/core/branch/FlowGraph/index.js.map +1 -1
- package/dist/core/branch/FlowGraph/layout.d.ts +34 -1
- package/dist/core/branch/FlowGraph/layout.d.ts.map +1 -1
- package/dist/core/branch/FlowGraph/layout.js +82 -0
- package/dist/core/branch/FlowGraph/layout.js.map +1 -1
- package/dist/core/branch/FlowGraph/types.d.ts +13 -1
- package/dist/core/branch/FlowGraph/types.d.ts.map +1 -1
- package/dist/core/branch/ListBox/index.d.ts +4 -2
- package/dist/core/branch/ListBox/index.d.ts.map +1 -1
- package/dist/core/branch/ListBox/index.js +2 -2
- package/dist/core/branch/ListBox/index.js.map +1 -1
- package/dist/core/branch/MarkdownArticle/index.d.ts +7 -1
- package/dist/core/branch/MarkdownArticle/index.d.ts.map +1 -1
- package/dist/core/branch/MarkdownArticle/index.js +5 -2
- package/dist/core/branch/MarkdownArticle/index.js.map +1 -1
- package/dist/core/branch/Select/index.d.ts +6 -8
- package/dist/core/branch/Select/index.d.ts.map +1 -1
- package/dist/core/branch/Select/index.js +9 -5
- package/dist/core/branch/Select/index.js.map +1 -1
- package/dist/core/branch/SurfaceCard/index.d.ts +9 -0
- package/dist/core/branch/SurfaceCard/index.d.ts.map +1 -1
- package/dist/core/branch/SurfaceCard/index.js +3 -2
- package/dist/core/branch/SurfaceCard/index.js.map +1 -1
- package/dist/core/branch/Tabs/index.d.ts.map +1 -1
- package/dist/core/branch/Tabs/index.js +17 -0
- package/dist/core/branch/Tabs/index.js.map +1 -1
- package/dist/core/branch/Tooltip/index.d.ts +9 -1
- package/dist/core/branch/Tooltip/index.d.ts.map +1 -1
- package/dist/core/branch/Tooltip/index.js +2 -2
- package/dist/core/branch/Tooltip/index.js.map +1 -1
- package/dist/core/buttonIntent.d.ts.map +1 -1
- package/dist/core/buttonIntent.js +1 -2
- package/dist/core/buttonIntent.js.map +1 -1
- package/dist/core/collectionItem.d.ts +3 -3
- package/dist/core/collectionItem.d.ts.map +1 -1
- package/dist/core/collectionItem.js +1 -2
- package/dist/core/collectionItem.js.map +1 -1
- package/dist/core/composite/Alert/index.d.ts +5 -0
- package/dist/core/composite/Alert/index.d.ts.map +1 -1
- package/dist/core/composite/Alert/index.js +7 -2
- package/dist/core/composite/Alert/index.js.map +1 -1
- package/dist/core/composite/CheckboxGroup/index.d.ts +6 -5
- package/dist/core/composite/CheckboxGroup/index.d.ts.map +1 -1
- package/dist/core/composite/CheckboxGroup/index.js +10 -3
- package/dist/core/composite/CheckboxGroup/index.js.map +1 -1
- package/dist/core/composite/DescriptionList/index.d.ts +3 -2
- package/dist/core/composite/DescriptionList/index.d.ts.map +1 -1
- package/dist/core/composite/DescriptionList/index.js +5 -4
- package/dist/core/composite/DescriptionList/index.js.map +1 -1
- package/dist/core/composite/RadioGroup/index.d.ts +5 -3
- package/dist/core/composite/RadioGroup/index.d.ts.map +1 -1
- package/dist/core/composite/RadioGroup/index.js +9 -2
- package/dist/core/composite/RadioGroup/index.js.map +1 -1
- package/dist/core/composite/SegmentedControl/index.d.ts +6 -6
- package/dist/core/composite/SegmentedControl/index.d.ts.map +1 -1
- package/dist/core/composite/SegmentedControl/index.js +9 -5
- package/dist/core/composite/SegmentedControl/index.js.map +1 -1
- package/dist/core/composite/TagGroup/index.d.ts +27 -4
- package/dist/core/composite/TagGroup/index.d.ts.map +1 -1
- package/dist/core/composite/TagGroup/index.js +132 -2
- package/dist/core/composite/TagGroup/index.js.map +1 -1
- package/dist/core/composite/Timeline/index.d.ts +5 -0
- package/dist/core/composite/Timeline/index.d.ts.map +1 -1
- package/dist/core/composite/Timeline/index.js +1 -1
- package/dist/core/composite/Timeline/index.js.map +1 -1
- package/dist/core/composition/Sidebar/index.d.ts +4 -0
- package/dist/core/composition/Sidebar/index.d.ts.map +1 -1
- package/dist/core/composition/Sidebar/index.js +4 -2
- package/dist/core/composition/Sidebar/index.js.map +1 -1
- package/dist/core/dna.d.ts +1 -1
- package/dist/core/dna.js +1 -1
- package/dist/core/dna.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/primitive/Avatar/index.d.ts +1 -1
- package/dist/core/primitive/Badge/index.d.ts +8 -5
- package/dist/core/primitive/Badge/index.d.ts.map +1 -1
- package/dist/core/primitive/Badge/index.js +14 -5
- package/dist/core/primitive/Badge/index.js.map +1 -1
- package/dist/core/primitive/Button/index.d.ts +10 -2
- package/dist/core/primitive/Button/index.d.ts.map +1 -1
- package/dist/core/primitive/Button/index.js +15 -4
- package/dist/core/primitive/Button/index.js.map +1 -1
- package/dist/core/primitive/Checkbox/index.d.ts +5 -3
- package/dist/core/primitive/Checkbox/index.d.ts.map +1 -1
- package/dist/core/primitive/Checkbox/index.js +9 -2
- package/dist/core/primitive/Checkbox/index.js.map +1 -1
- package/dist/core/primitive/Code/index.d.ts +10 -0
- package/dist/core/primitive/Code/index.d.ts.map +1 -0
- package/dist/core/primitive/Code/index.js +5 -0
- package/dist/core/primitive/Code/index.js.map +1 -0
- package/dist/core/primitive/Field/index.d.ts +12 -25
- package/dist/core/primitive/Field/index.d.ts.map +1 -1
- package/dist/core/primitive/Field/index.js +13 -14
- package/dist/core/primitive/Field/index.js.map +1 -1
- package/dist/core/primitive/GrammarRoot/index.d.ts +8 -1
- package/dist/core/primitive/GrammarRoot/index.d.ts.map +1 -1
- package/dist/core/primitive/GrammarRoot/index.js +5 -1
- package/dist/core/primitive/GrammarRoot/index.js.map +1 -1
- package/dist/core/primitive/Icon/index.d.ts.map +1 -1
- package/dist/core/primitive/Icon/index.js +3 -2
- package/dist/core/primitive/Icon/index.js.map +1 -1
- package/dist/core/primitive/Input/index.d.ts +9 -4
- package/dist/core/primitive/Input/index.d.ts.map +1 -1
- package/dist/core/primitive/Input/index.js +13 -8
- package/dist/core/primitive/Input/index.js.map +1 -1
- package/dist/core/primitive/Meter/index.d.ts +4 -1
- package/dist/core/primitive/Meter/index.d.ts.map +1 -1
- package/dist/core/primitive/Meter/index.js +3 -3
- package/dist/core/primitive/Meter/index.js.map +1 -1
- package/dist/core/primitive/NumberField/index.d.ts +6 -5
- package/dist/core/primitive/NumberField/index.d.ts.map +1 -1
- package/dist/core/primitive/NumberField/index.js +10 -3
- package/dist/core/primitive/NumberField/index.js.map +1 -1
- package/dist/core/primitive/PinnedActionBar/index.d.ts +25 -6
- package/dist/core/primitive/PinnedActionBar/index.d.ts.map +1 -1
- package/dist/core/primitive/PinnedActionBar/index.js +9 -4
- package/dist/core/primitive/PinnedActionBar/index.js.map +1 -1
- package/dist/core/primitive/SearchField/index.d.ts +6 -5
- package/dist/core/primitive/SearchField/index.d.ts.map +1 -1
- package/dist/core/primitive/SearchField/index.js +10 -3
- package/dist/core/primitive/SearchField/index.js.map +1 -1
- package/dist/core/primitive/SectionHeader/index.d.ts +3 -3
- package/dist/core/primitive/SectionHeader/index.js +2 -2
- package/dist/core/primitive/SectionHeader/index.js.map +1 -1
- package/dist/core/primitive/Skeleton/index.d.ts +11 -0
- package/dist/core/primitive/Skeleton/index.d.ts.map +1 -1
- package/dist/core/primitive/Skeleton/index.js +12 -1
- package/dist/core/primitive/Skeleton/index.js.map +1 -1
- package/dist/core/primitive/StatusDot/index.d.ts +61 -0
- package/dist/core/primitive/StatusDot/index.d.ts.map +1 -0
- package/dist/core/primitive/StatusDot/index.js +55 -0
- package/dist/core/primitive/StatusDot/index.js.map +1 -0
- package/dist/core/primitive/Switch/index.d.ts +4 -3
- package/dist/core/primitive/Switch/index.d.ts.map +1 -1
- package/dist/core/primitive/Switch/index.js +5 -2
- package/dist/core/primitive/Switch/index.js.map +1 -1
- package/dist/core/primitive/Terminal/index.d.ts +20 -0
- package/dist/core/primitive/Terminal/index.d.ts.map +1 -0
- package/dist/core/primitive/Terminal/index.js +29 -0
- package/dist/core/primitive/Terminal/index.js.map +1 -0
- package/dist/core/primitive/Text/index.d.ts +5 -1
- package/dist/core/primitive/Text/index.d.ts.map +1 -1
- package/dist/core/primitive/Text/index.js +12 -7
- package/dist/core/primitive/Text/index.js.map +1 -1
- package/dist/core/primitive/TextAction/index.d.ts.map +1 -1
- package/dist/core/primitive/TextAction/index.js +9 -4
- package/dist/core/primitive/TextAction/index.js.map +1 -1
- package/dist/core/primitive/Textarea/index.d.ts +8 -4
- package/dist/core/primitive/Textarea/index.d.ts.map +1 -1
- package/dist/core/primitive/Textarea/index.js +9 -5
- package/dist/core/primitive/Textarea/index.js.map +1 -1
- package/dist/core/styles.css +18 -6
- package/dist/offset-pop/components-forms.css +0 -17
- package/dist/offset-pop/components-navigation.css +30 -4
- package/dist/offset-pop/components-overlays.css +5 -0
- package/dist/offset-pop/index.d.ts +1 -1
- package/dist/offset-pop/index.d.ts.map +1 -1
- package/dist/offset-pop/styles.css +44 -0
- package/package.json +7 -12
- package/dist/common/rule-catalog.generated.d.ts.map +0 -1
- package/dist/common/rule-catalog.generated.js.map +0 -1
- package/dist/heritage/dna.d.ts +0 -63
- package/dist/heritage/dna.d.ts.map +0 -1
- package/dist/heritage/dna.js +0 -37
- package/dist/heritage/dna.js.map +0 -1
- package/dist/heritage/index.d.ts +0 -27
- package/dist/heritage/index.d.ts.map +0 -1
- package/dist/heritage/index.js +0 -46
- package/dist/heritage/index.js.map +0 -1
- package/dist/heritage/styles.css +0 -187
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 StarCi
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 StarCi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`@starci/grammar` splits a UI kit into one shared contract and several visual families. The
|
|
4
4
|
contract has no business logic. Common owns the typed props, semantics, renderer anatomy, universal
|
|
5
|
-
states and scales, and the family registry. Core
|
|
5
|
+
states and scales, and the family registry. Core and Offset Pop are sibling families.
|
|
6
6
|
Each one implements the same contract with its own scoped visual DNA. The package contains no
|
|
7
7
|
routes, domain entities, product decisions or feature-named shells.
|
|
8
8
|
|
|
@@ -13,8 +13,6 @@ only: props, DOM, ARIA and keyboard behaviour stay the same.
|
|
|
13
13
|
|
|
14
14
|
```sh
|
|
15
15
|
npm install @starci/grammar @heroui/react react react-dom
|
|
16
|
-
# while developing inside this repository:
|
|
17
|
-
npm install ./.claude/packages/grammar
|
|
18
16
|
```
|
|
19
17
|
|
|
20
18
|
The package needs Node.js 22 or newer. Its peer dependencies are React 18+, `@xyflow/react` 12 (for `FlowGraph`) and `@heroui/react`
|
|
@@ -25,14 +23,10 @@ exactly one Grammar family stylesheet. Each family sheet already imports Common
|
|
|
25
23
|
| --- | --- | --- |
|
|
26
24
|
| `@starci/grammar/common` | `GrammarRoot` (neutral) | `@starci/grammar/common/styles.css` (`common.css`) |
|
|
27
25
|
| `@starci/grammar/core` | `CoreGrammarRoot` | `@starci/grammar/core/styles.css` (`core.css`) |
|
|
28
|
-
| `@starci/grammar/heritage` | `HeritageGrammarRoot` | `@starci/grammar/heritage/styles.css` (`heritage.css`) |
|
|
29
26
|
| `@starci/grammar/offset-pop` | `OffsetPopGrammarRoot` | `@starci/grammar/offset-pop/styles.css` (`offset-pop.css`) |
|
|
30
27
|
|
|
31
28
|
The Core and Offset Pop entry points re-export all of Common, so an app imports its components and
|
|
32
|
-
its root from one place.
|
|
33
|
-
`HeritageGrammarRoot`, its `Brand` extension (`HeritageBrand`), the `HeritageButton` and
|
|
34
|
-
`HeritageHeading` aliases and its conformance, so import the other renderers from
|
|
35
|
-
`@starci/grammar/common`.
|
|
29
|
+
its root from one place.
|
|
36
30
|
|
|
37
31
|
## Usage
|
|
38
32
|
|
|
@@ -57,7 +51,7 @@ the complete placement mapping in light and dark, including destination, pending
|
|
|
57
51
|
|
|
58
52
|
### App shell
|
|
59
53
|
|
|
60
|
-
The [app-shell canon](../../
|
|
54
|
+
The [app-shell canon](../../contexts/ui/composition.md) owns `FE-APP-SHELL-1` through `FE-APP-SHELL-7`.
|
|
61
55
|
The `Compositions/App shell` stories show the fixed shell, grouped sidebar, icon rail and mobile drawer.
|
|
62
56
|
|
|
63
57
|
- `size="control"` is available on `Button`, `IconButton`, `TextAction`, `PlainPressable`, `IdentityLockup`, `Input` and `SearchField`, alongside `Switch`, `Avatar` and `AvatarButton`.
|
|
@@ -127,23 +121,6 @@ export const ProductSurface = () => (
|
|
|
127
121
|
Core's DNA declares a shadow without a border at top surface depth, and a border without a shadow
|
|
128
122
|
at nested depth.
|
|
129
123
|
|
|
130
|
-
### Heritage
|
|
131
|
-
|
|
132
|
-
```tsx
|
|
133
|
-
import { TopBar } from "@starci/grammar/common"
|
|
134
|
-
import { HeritageBrand, HeritageGrammarRoot } from "@starci/grammar/heritage"
|
|
135
|
-
import "@starci/grammar/heritage/styles.css"
|
|
136
|
-
|
|
137
|
-
export const Masthead = () => (
|
|
138
|
-
<HeritageGrammarRoot>
|
|
139
|
-
<TopBar brand={<a href="/"><HeritageBrand name="…" descriptor="…" logo={{ src: "/logo.svg", width: 40, height: 40 }} /></a>} />
|
|
140
|
-
</HeritageGrammarRoot>
|
|
141
|
-
)
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
Heritage replaces only the root. It adds one extension, `Brand`, which is non-interactive brand
|
|
145
|
-
content for a destination the consumer owns.
|
|
146
|
-
|
|
147
124
|
### Offset Pop
|
|
148
125
|
|
|
149
126
|
```tsx
|
|
@@ -167,11 +144,37 @@ offset shadow and a pink decision accent. Text that uses the accent is drawn in
|
|
|
167
144
|
`OFFSET_POP_TOKEN_DEFAULTS`, `OFFSET_POP_DARK_TOKEN_DEFAULTS`, `OFFSET_POP_BAND_TOKEN_NAMES`,
|
|
168
145
|
`offsetPopGrammar` and `offsetPopRuleConformance`.
|
|
169
146
|
|
|
147
|
+
## Client-side navigation
|
|
148
|
+
|
|
149
|
+
Every Grammar root (`GrammarRoot`, `CoreGrammarRoot`, `OffsetPopGrammarRoot`) accepts `navigate(path)` and `useHref(href)` and
|
|
150
|
+
mounts react-aria's `RouterProvider`. Pass your router's functions once at the root and every Grammar `Link`, `Button href`,
|
|
151
|
+
`Breadcrumbs` item, `ListBox`/`Menu` item `href` and `FlowGraph` node `href` navigates inside the app without a reload.
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
import { useHref, useNavigate } from "react-router-dom"
|
|
155
|
+
import { CoreGrammarRoot } from "@starci/grammar/core"
|
|
156
|
+
|
|
157
|
+
export const Root = ({ children }: { children: React.ReactNode }) => {
|
|
158
|
+
const navigate = useNavigate()
|
|
159
|
+
return <CoreGrammarRoot navigate={(path) => navigate(path)} useHref={useHref}>{children}</CoreGrammarRoot>
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Mount the root inside the router. Without `navigate` the links behave as plain anchors.
|
|
164
|
+
|
|
165
|
+
### FlowGraph layouts
|
|
166
|
+
|
|
167
|
+
`FlowGraph` places nodes with `layout`: `radial` (the default), `layered` (a DAG in layers) or `manual` (each node's `position`).
|
|
168
|
+
`direction="TB" | "LR"` puts the target handle on the entering side and the source handle on the leaving side so edges run along the
|
|
169
|
+
layout, and selects `layered` when no layout is given. `headers={[{ label, at }]}` draws a column header above each layer for `LR` and
|
|
170
|
+
a lane header beside it for `TB` (`at` is the layer index in `layered`, graph units in `manual`). `height` takes `sm | md | lg`, a number
|
|
171
|
+
(pixels) or any CSS length. A node with `href` is a link through the root's router and one keyboard stop.
|
|
172
|
+
|
|
170
173
|
## Family scope and the overlay portal rule
|
|
171
174
|
|
|
172
175
|
A family paints only inside its root. Each family stylesheet is scoped to
|
|
173
176
|
`.grammar-common-root[data-grammar-family="<id>"]` inside its own cascade layer:
|
|
174
|
-
`starci-grammar-common` comes first, then `-core
|
|
177
|
+
`starci-grammar-common` comes first, then `-core` and `-offset-pop`. No family sheet
|
|
175
178
|
imports a sibling family's sheet. So two families can share a page, each inside its own root, and
|
|
176
179
|
nested roots resolve to the innermost one.
|
|
177
180
|
|
|
@@ -246,7 +249,7 @@ className and no size. An item takes `id`, `label`, `description`, `descriptionL
|
|
|
246
249
|
`size-4`, which is example content and not a component default, so 20px is StarCi's icon rule and not a vendor override.
|
|
247
250
|
- `mark`: a decorative node instead of `iconSource`, e.g. an identity mark (`<Avatar size="sm" shape="rounded" isDecorative />`). The public type rejects both props together.
|
|
248
251
|
- `tone: "danger"`: HeroUI's `danger` variant, which colours the label and the glyph. Sign out, delete, remove, leave workspace
|
|
249
|
-
and revoke are destructive; the lint rule `starci-grammar/destructive-menu-entry-needs-danger-tone` of `@starci/eslint-grammar-
|
|
252
|
+
and revoke are destructive; the lint rule `starci-grammar/destructive-menu-entry-needs-danger-tone` of `@starci/eslint-grammar-core` refuses such an entry without it.
|
|
250
253
|
|
|
251
254
|
A section takes `label` and optionally `selection` (`mode: "single" | "multiple"`, `selectedIds`, `onChange`). Between two
|
|
252
255
|
adjacent entries, when either is a section, Grammar always inserts HeroUI's own `Separator`: the app cannot forget one. The selection
|
|
@@ -267,7 +270,7 @@ an item with a submenu).
|
|
|
267
270
|
```
|
|
268
271
|
|
|
269
272
|
**HeroUI parity.** Grammar is a wrapper of HeroUI, so a wrapper keeps HeroUI's anatomy and defaults. The vendor reference
|
|
270
|
-
(`
|
|
273
|
+
(`contexts/vendor/` of the StarCi harness) is measured from the installed `@heroui/react` and
|
|
271
274
|
`@heroui/styles`; the gate `GRAMMAR_VENDOR_PARITY` fails a wrapper that renders a part HeroUI does not have, omits one it
|
|
272
275
|
requires, restyles what the vendor decides, or replaces a vendor default, unless an owner-pinned override declares it. `ListBox`
|
|
273
276
|
and `Select` are HeroUI's own list-box items (a `Label`, a `Description`, the item indicator at the end of the row).
|
|
@@ -430,8 +433,8 @@ person uses Avatar. The default `layout="row"` keeps the overlapping member row
|
|
|
430
433
|
|
|
431
434
|
## Theming
|
|
432
435
|
|
|
433
|
-
- **Tokens.** Each family writes its DNA as CSS custom properties on its root: `--starci-core
|
|
434
|
-
|
|
436
|
+
- **Tokens.** Each family writes its DNA as CSS custom properties on its root: `--starci-core-*`
|
|
437
|
+
or `--offset-pop-*`. It feeds those into the Common semantic variables that
|
|
435
438
|
renderers read: `--accent`, `--accent-foreground`, `--focus`, `--background`, `--surface`,
|
|
436
439
|
`--surface-secondary`, `--foreground`, `--muted`, `--border`, `--separator`, the status
|
|
437
440
|
colours and their foregrounds, radii and shadow. Core also publishes a tertiary face under its own
|
package/dist/.build-stamp.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "starci/grammar-build-stamp@1",
|
|
3
3
|
"package": "@starci/grammar",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.14.0",
|
|
5
5
|
"algorithm": "starci/grammar-source-digest@1",
|
|
6
|
-
"sourceDigest": "sha256:
|
|
7
|
-
"distDigest": "sha256:
|
|
8
|
-
"builtAt": "2026-10-
|
|
6
|
+
"sourceDigest": "sha256:abe48ef178e3f654d64eda3138e1bbc98b0d48d7f8fd27c09432d9966a6a99ec",
|
|
7
|
+
"distDigest": "sha256:d0879914392be475eacac5872c11615e3528982f7bae31376fc96801d23c97c9",
|
|
8
|
+
"builtAt": "2026-10-27T19:22:38.977Z"
|
|
9
9
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Only structure, rhythm and the touch floor live here. Paint resolves through the semantic
|
|
8
8
|
* variables every family binds (`--field-*`, `--accent`, `--danger`, `--muted`, `--focus`,
|
|
9
|
-
* `--border`), so Core
|
|
9
|
+
* `--border`), so Core and Offset Pop each get their own look without a Common colour.
|
|
10
10
|
* Spacing uses the Common 4px scale (0.25 / 0.5 / 0.75 / 1 / 1.5rem).
|
|
11
11
|
*
|
|
12
12
|
* `!important` appears only on the few declarations the vendor's field roots also set (display and
|
|
@@ -124,58 +124,42 @@
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
/*
|
|
127
|
-
* Loading field (knowledge STATE-8
|
|
128
|
-
*
|
|
129
|
-
*
|
|
127
|
+
* Loading field (knowledge STATE-8) with skeleton parity: the control renders its ready anatomy inside
|
|
128
|
+
* `.starci-core-field-skeleton-scope` (layout-neutral, inert), so label, description and control box keep the ready
|
|
129
|
+
* geometry by construction. Every control box in the scope is painted as a Skeleton (the vendor skeleton tint and
|
|
130
|
+
* shimmer); what it holds - a value, a placeholder, an indicator, a thumb - is not drawn. Its border stays, so a
|
|
131
|
+
* family's outline keeps the field box.
|
|
130
132
|
*/
|
|
131
|
-
|
|
132
|
-
.starci-core-field-skeleton {
|
|
133
|
-
min-width: 0;
|
|
134
|
-
pointer-events: none;
|
|
135
|
-
user-select: none;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.starci-core-field-skeleton-control { display: block; min-width: 0; }
|
|
133
|
+
.starci-core-field-skeleton-scope { display: contents; }
|
|
139
134
|
|
|
140
|
-
.starci-core-field-skeleton-control
|
|
141
|
-
|
|
142
|
-
|
|
135
|
+
.starci-core-field-skeleton-scope :is([data-grammar-field-control="true"]:not(.starci-core-choice-group-options), .starci-core-input-field, [data-grammar-choice-control], [data-grammar-tag-id]) {
|
|
136
|
+
position: relative;
|
|
137
|
+
overflow: hidden;
|
|
138
|
+
background: color-mix(in oklab, var(--surface-tertiary, #e4e4e7) 70%, transparent) !important;
|
|
139
|
+
color: transparent !important;
|
|
140
|
+
user-select: none;
|
|
143
141
|
}
|
|
144
142
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
.starci-core-field-skeleton-control[data-grammar-field-skeleton="select"] { block-size: var(--starci-core-control-min-size, 2.5rem); }
|
|
149
|
-
|
|
150
|
-
/* Joined segments: one block, a segment-width (5rem) per option, never wider than the field; `fill` takes the whole row. */
|
|
151
|
-
.starci-core-field-skeleton-control[data-grammar-field-skeleton="segmented"] {
|
|
152
|
-
block-size: 2.5rem;
|
|
153
|
-
inline-size: min(100%, calc(var(--starci-core-skeleton-segments, 2) * 5rem));
|
|
143
|
+
/* A control box whose rounded part is inside it (a ComboBox or SegmentedControl group, a Field control slot) takes the field radius. */
|
|
144
|
+
.starci-core-field-skeleton-scope [data-grammar-field-control="true"]:is(.starci-core-combo-box-group, .starci-core-segmented-control-group, .starci-core-field-control) {
|
|
145
|
+
border-radius: var(--field-radius, calc(var(--radius, 0.5rem) * 1.5));
|
|
154
146
|
}
|
|
155
147
|
|
|
156
|
-
.starci-core-field-skeleton-
|
|
157
|
-
.starci-core-field-skeleton-
|
|
158
|
-
|
|
159
|
-
/* A checkbox box and a switch track beside their real labels. */
|
|
160
|
-
.starci-core-field-skeleton-control[data-grammar-field-skeleton="choice"] { flex: none; block-size: 1rem; inline-size: 1rem; }
|
|
161
|
-
.starci-core-field-skeleton-control[data-grammar-field-skeleton="switch"] { flex: none; block-size: 1.25rem; inline-size: 2rem; }
|
|
162
|
-
.starci-core-field-skeleton-control[data-grammar-field-skeleton="switch"][data-grammar-switch-size="lg"] { block-size: 1.5rem; inline-size: 3rem; }
|
|
163
|
-
.starci-core-field-skeleton-control[data-grammar-field-skeleton="switch"][data-grammar-switch-size="control"] { block-size: var(--starci-core-control-min-size, 2.5rem); inline-size: 4.5rem; }
|
|
148
|
+
.starci-core-field-skeleton-scope :is([data-grammar-field-control="true"]:not(.starci-core-choice-group-options), [data-grammar-choice-control], [data-grammar-tag-id]) > * { visibility: hidden; }
|
|
149
|
+
.starci-core-field-skeleton-scope :is(input, textarea)::placeholder { color: transparent; }
|
|
164
150
|
|
|
165
|
-
.starci-core-field-skeleton-choice-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
151
|
+
.starci-core-field-skeleton-scope :is([data-grammar-field-control="true"]:not(.starci-core-choice-group-options, textarea), [data-grammar-choice-control], [data-grammar-tag-id])::after {
|
|
152
|
+
content: "";
|
|
153
|
+
position: absolute;
|
|
154
|
+
inset: 0;
|
|
155
|
+
visibility: visible;
|
|
156
|
+
background-image: linear-gradient(to right, transparent, var(--surface-tertiary, #e4e4e7), transparent);
|
|
157
|
+
translate: -100%;
|
|
158
|
+
animation: skeleton 2s linear infinite;
|
|
173
159
|
}
|
|
174
160
|
|
|
175
|
-
@media (
|
|
176
|
-
.starci-core-field-skeleton-
|
|
177
|
-
min-block-size: var(--starci-core-control-min-size, 2.5rem);
|
|
178
|
-
}
|
|
161
|
+
@media (prefers-reduced-motion: reduce) {
|
|
162
|
+
.starci-core-field-skeleton-scope :is([data-grammar-field-control="true"], [data-grammar-choice-control])::after { animation: none; content: none; }
|
|
179
163
|
}
|
|
180
164
|
|
|
181
165
|
.starci-core-combo-box-group,
|
|
@@ -21,6 +21,14 @@
|
|
|
21
21
|
line-clamp: 2;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
.grammar-common-root [data-slot="description"][data-grammar-description-lines="wrap"] {
|
|
25
|
+
display: block;
|
|
26
|
+
-webkit-line-clamp: none;
|
|
27
|
+
line-clamp: none;
|
|
28
|
+
overflow: visible;
|
|
29
|
+
overflow-wrap: anywhere;
|
|
30
|
+
}
|
|
31
|
+
|
|
24
32
|
.grammar-common-root [data-slot="description"][data-grammar-description-lines="3"] {
|
|
25
33
|
-webkit-line-clamp: 3;
|
|
26
34
|
line-clamp: 3;
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
/* A crumb whose label is not known yet (knowledge STATE-8): a short Skeleton text line of the label's size. */
|
|
113
113
|
.starci-core-breadcrumb-skeleton { display: inline-block; inline-size: 6rem; }
|
|
114
114
|
.starci-core-breadcrumb-skeleton > .starci-core-skeleton-group { gap: 0; }
|
|
115
|
-
.starci-core-breadcrumb-skeleton .starci-core-skeleton {
|
|
115
|
+
.starci-core-breadcrumb-skeleton .starci-core-skeleton { --starci-core-skeleton-line: 0.875rem; }
|
|
116
116
|
|
|
117
117
|
@media (max-width: 30rem) {
|
|
118
118
|
.starci-core-breadcrumb-label {
|
|
@@ -269,7 +269,7 @@
|
|
|
269
269
|
.starci-core-step-skeleton-marker { border: 0; background: transparent; }
|
|
270
270
|
.starci-core-step-skeleton-label { display: block; inline-size: 5rem; }
|
|
271
271
|
.starci-core-step-skeleton-label > .starci-core-skeleton-group { gap: 0; }
|
|
272
|
-
.starci-core-step-skeleton-label .starci-core-skeleton {
|
|
272
|
+
.starci-core-step-skeleton-label .starci-core-skeleton { --starci-core-skeleton-line: 0.875rem; }
|
|
273
273
|
|
|
274
274
|
.starci-core-step-copy {
|
|
275
275
|
display: flex;
|
|
@@ -779,6 +779,26 @@
|
|
|
779
779
|
white-space: nowrap;
|
|
780
780
|
}
|
|
781
781
|
|
|
782
|
+
/* The reorder layer's event wrapper takes no box: the TagGroup lays out as if it were not there. */
|
|
783
|
+
.starci-core-tag-group-reorder {
|
|
784
|
+
display: contents;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/* Reorderable tags: the grab cursor, the lifted tag and the tag a drop would replace. */
|
|
788
|
+
.starci-core-tag-group[data-grammar-tag-reorderable="true"] .starci-core-tag[draggable="true"] {
|
|
789
|
+
cursor: grab;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
.starci-core-tag-group[data-grammar-tag-reorderable="true"] .starci-core-tag[data-grammar-tag-dragging="true"] {
|
|
793
|
+
opacity: 0.5;
|
|
794
|
+
cursor: grabbing;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
.starci-core-tag-group[data-grammar-tag-reorderable="true"] .starci-core-tag[data-grammar-tag-drop-target="true"] {
|
|
798
|
+
outline: 2px solid var(--accent, Highlight);
|
|
799
|
+
outline-offset: 2px;
|
|
800
|
+
}
|
|
801
|
+
|
|
782
802
|
/*
|
|
783
803
|
* Selectable chips (0.9.6, selectionMode single or multiple): a group of choices carries a 1px inset ring,
|
|
784
804
|
* --border when unselected and --accent when selected. The chip face, hover and selected paint are HeroUI's own.
|
|
@@ -850,6 +870,15 @@
|
|
|
850
870
|
width: max-content;
|
|
851
871
|
}
|
|
852
872
|
|
|
873
|
+
/*
|
|
874
|
+
* A table that hosts editors, or has folded its low columns for a narrow container, fits the container instead:
|
|
875
|
+
* at max-content an editor's TagGroup never wraps its chips and the folded text never wraps, so the table ran
|
|
876
|
+
* past its container. It still scrolls sideways once its columns cannot shrink further.
|
|
877
|
+
*/
|
|
878
|
+
.starci-core-data-table:is([data-grammar-table-editors="true"], [data-grammar-table-narrow="true"]) .starci-core-data-table-content {
|
|
879
|
+
width: 100%;
|
|
880
|
+
}
|
|
881
|
+
|
|
853
882
|
.starci-core-data-table[data-grammar-table-sticky="true"] .starci-core-data-table-header {
|
|
854
883
|
position: sticky;
|
|
855
884
|
z-index: 1;
|
|
@@ -892,6 +921,65 @@
|
|
|
892
921
|
box-sizing: border-box;
|
|
893
922
|
}
|
|
894
923
|
|
|
924
|
+
/* A whole-row link target reads as one pressable row. */
|
|
925
|
+
.starci-core-data-table-row[data-grammar-table-row-link="true"] {
|
|
926
|
+
cursor: pointer;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/* An editor cell hosts a field; the field keeps its own control height and fills the column, never wider. */
|
|
930
|
+
.starci-core-data-table-editor {
|
|
931
|
+
display: flex;
|
|
932
|
+
min-width: 0;
|
|
933
|
+
max-inline-size: 100%;
|
|
934
|
+
align-items: center;
|
|
935
|
+
white-space: normal;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
.starci-core-data-table-editor > * {
|
|
939
|
+
flex: 1 1 auto;
|
|
940
|
+
min-width: 0;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/*
|
|
944
|
+
* A text input's intrinsic width is its `size` (20 characters, about 11rem), which an auto-layout table takes as the
|
|
945
|
+
* column's minimum: a NumberField editor alone pushed the table past its container, even in narrow mode. In an editor
|
|
946
|
+
* cell the input asks for no width of its own and fills its track through its minimum (a percentage minimum does not
|
|
947
|
+
* count toward the column's intrinsic width), so the column can shrink to the room the table has and the input still
|
|
948
|
+
* fills what it gets, never less than three characters beside its own inline padding.
|
|
949
|
+
*/
|
|
950
|
+
.starci-core-data-table-editor input {
|
|
951
|
+
inline-size: 0;
|
|
952
|
+
min-inline-size: max(calc(3ch + 1.5rem), 100%);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
/* Narrow mode: low-priority columns stack under the first column's content as secondary text. */
|
|
956
|
+
.starci-core-data-table-secondary {
|
|
957
|
+
display: flex;
|
|
958
|
+
flex-direction: column;
|
|
959
|
+
gap: 0.125rem;
|
|
960
|
+
margin-block-start: 0.25rem;
|
|
961
|
+
color: var(--muted, GrayText);
|
|
962
|
+
font-size: 0.875em;
|
|
963
|
+
white-space: normal;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/* A long value (an email, an id) may break anywhere, so the folded text never sets the first column's minimum. */
|
|
967
|
+
.starci-core-data-table-secondary-item {
|
|
968
|
+
display: flex;
|
|
969
|
+
min-width: 0;
|
|
970
|
+
flex-wrap: wrap;
|
|
971
|
+
gap: 0.25rem;
|
|
972
|
+
overflow-wrap: anywhere;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
.starci-core-data-table-secondary-value {
|
|
976
|
+
min-width: 0;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
.starci-core-data-table-secondary-label::after {
|
|
980
|
+
content: ":";
|
|
981
|
+
}
|
|
982
|
+
|
|
895
983
|
.starci-core-drag-item {
|
|
896
984
|
display: flex;
|
|
897
985
|
min-width: 0;
|
|
@@ -1021,6 +1109,9 @@
|
|
|
1021
1109
|
line-height: 1.25rem;
|
|
1022
1110
|
}
|
|
1023
1111
|
|
|
1112
|
+
/* A loading stat keeps its unit's place, unseen (skeleton parity). */
|
|
1113
|
+
.starci-core-description-list[data-loading="true"] .starci-core-description-unit { visibility: hidden; }
|
|
1114
|
+
|
|
1024
1115
|
.starci-core-description-meta {
|
|
1025
1116
|
min-width: 0;
|
|
1026
1117
|
margin: 0;
|
|
@@ -1112,12 +1203,12 @@
|
|
|
1112
1203
|
display: flex;
|
|
1113
1204
|
min-width: 0;
|
|
1114
1205
|
flex-direction: column;
|
|
1206
|
+
gap: 0.25rem;
|
|
1115
1207
|
}
|
|
1116
1208
|
|
|
1117
1209
|
/* Loading options (knowledge STATE-8): a label line and a description line, at the loaded option's height. */
|
|
1118
1210
|
.starci-core-list-box-skeleton-option {
|
|
1119
1211
|
display: flex;
|
|
1120
|
-
min-block-size: 2.25rem;
|
|
1121
1212
|
align-items: center;
|
|
1122
1213
|
padding-inline: 0.5rem;
|
|
1123
1214
|
padding-block: 0.375rem;
|
|
@@ -1128,8 +1219,10 @@
|
|
|
1128
1219
|
.starci-core-list-box-skeleton-option .starci-core-list-box-description { display: block; }
|
|
1129
1220
|
.starci-core-list-box-skeleton-option .starci-core-list-box-label > .starci-core-skeleton-group { inline-size: 55%; }
|
|
1130
1221
|
.starci-core-list-box-skeleton-option .starci-core-list-box-description > .starci-core-skeleton-group { inline-size: 80%; }
|
|
1131
|
-
|
|
1132
|
-
.starci-core-list-box-skeleton-option .starci-core-
|
|
1222
|
+
/* Skeleton parity: each line takes the line box of the vendor label (0.875rem / 1.25rem) and description (0.75rem / 1rem). */
|
|
1223
|
+
.starci-core-list-box-skeleton-option .starci-core-list-box-label { font-size: 0.875rem; line-height: 1.25rem; }
|
|
1224
|
+
.starci-core-list-box-skeleton-option .starci-core-list-box-description { font-size: 0.75rem; line-height: 1rem; }
|
|
1225
|
+
.starci-core-list-box-skeleton-option .starci-core-skeleton-group { gap: 0; }
|
|
1133
1226
|
|
|
1134
1227
|
.starci-core-list-box-empty {
|
|
1135
1228
|
padding: var(--grammar-section-gap, 1rem);
|
|
@@ -1379,6 +1472,34 @@
|
|
|
1379
1472
|
background: currentColor;
|
|
1380
1473
|
}
|
|
1381
1474
|
|
|
1475
|
+
/*
|
|
1476
|
+
* Attention entry: the whole row takes a tone background (the marker alone is too small to catch the eye). The
|
|
1477
|
+
* row grows 0.5rem each side and gives the same back as negative margin, so the markers and the copy keep their
|
|
1478
|
+
* column; the connector moves with the padding and reaches the next entry.
|
|
1479
|
+
*/
|
|
1480
|
+
.starci-core-timeline-item[data-grammar-attention="true"] {
|
|
1481
|
+
--starci-core-timeline-attention-tone: var(--warning, CanvasText);
|
|
1482
|
+
margin-inline: -0.5rem;
|
|
1483
|
+
margin-block-end: 0.5rem;
|
|
1484
|
+
padding: 0.5rem;
|
|
1485
|
+
border-radius: 0.75rem;
|
|
1486
|
+
background: color-mix(in oklab, var(--starci-core-timeline-attention-tone) 14%, transparent);
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
.starci-core-timeline-item[data-grammar-attention="true"][data-grammar-timeline-state="negative"] { --starci-core-timeline-attention-tone: var(--danger, CanvasText); }
|
|
1490
|
+
.starci-core-timeline-item[data-grammar-attention="true"][data-grammar-timeline-state="affirmative"] { --starci-core-timeline-attention-tone: var(--success, CanvasText); }
|
|
1491
|
+
.starci-core-timeline-item[data-grammar-attention="true"][data-grammar-timeline-state="informative"] { --starci-core-timeline-attention-tone: var(--info, CanvasText); }
|
|
1492
|
+
|
|
1493
|
+
.starci-core-timeline-item[data-grammar-attention="true"]:not(:last-child)::before {
|
|
1494
|
+
top: 2rem;
|
|
1495
|
+
bottom: -0.5rem;
|
|
1496
|
+
inset-inline-start: calc(1.25rem - 1px);
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
.starci-core-timeline-item[data-grammar-attention="true"] .starci-core-timeline-marker {
|
|
1500
|
+
background: transparent;
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1382
1503
|
/* Loading timeline (knowledge STATE-8): static mark and connector tint, three Skeleton lines of the entry's rhythm. */
|
|
1383
1504
|
.starci-core-timeline-skeleton-marker > .starci-core-skeleton { inline-size: 1rem; block-size: 1rem; }
|
|
1384
1505
|
.starci-core-timeline[data-loading="true"] .starci-core-timeline-item:not(:last-child)::before { background: color-mix(in srgb, var(--foreground, CanvasText) 9%, transparent); }
|
|
@@ -1386,7 +1507,7 @@
|
|
|
1386
1507
|
.starci-core-timeline-item[data-grammar-skeleton="true"] .starci-core-timeline-time > .starci-core-skeleton-group { inline-size: 25%; }
|
|
1387
1508
|
.starci-core-timeline-item[data-grammar-skeleton="true"] .starci-core-timeline-description > .starci-core-skeleton-group { inline-size: 80%; }
|
|
1388
1509
|
.starci-core-timeline-item[data-grammar-skeleton="true"] .starci-core-skeleton-group { gap: 0; }
|
|
1389
|
-
.starci-core-timeline-item[data-grammar-skeleton="true"] .starci-core-skeleton {
|
|
1510
|
+
.starci-core-timeline-item[data-grammar-skeleton="true"] .starci-core-skeleton { --starci-core-skeleton-line: 0.8125rem; }
|
|
1390
1511
|
|
|
1391
1512
|
.starci-core-timeline-copy {
|
|
1392
1513
|
display: flex;
|
|
@@ -1395,10 +1516,13 @@
|
|
|
1395
1516
|
gap: 0.125rem;
|
|
1396
1517
|
}
|
|
1397
1518
|
|
|
1519
|
+
/* The list title scale (the ListBox and panel row label, text-sm), not whatever size the page body inherits. */
|
|
1398
1520
|
.starci-core-timeline-title {
|
|
1399
1521
|
margin: 0;
|
|
1400
1522
|
overflow-wrap: anywhere;
|
|
1523
|
+
font-size: 0.875rem;
|
|
1401
1524
|
font-weight: 600;
|
|
1525
|
+
line-height: 1.25rem;
|
|
1402
1526
|
}
|
|
1403
1527
|
|
|
1404
1528
|
.starci-core-timeline-time,
|
|
@@ -1479,6 +1603,9 @@
|
|
|
1479
1603
|
|
|
1480
1604
|
.starci-core-flow-graph[data-grammar-flow-height="sm"] .starci-core-flow-graph-canvas { block-size: 16rem; }
|
|
1481
1605
|
.starci-core-flow-graph[data-grammar-flow-height="lg"] .starci-core-flow-graph-canvas { block-size: 32rem; }
|
|
1606
|
+
.starci-core-flow-graph[data-grammar-flow-height="custom"] .starci-core-flow-graph-canvas { block-size: var(--starci-flow-height, 24rem); }
|
|
1607
|
+
/* The readable fit grew the canvas to the graph's aspect at its width rather than shrink the text below 12px. */
|
|
1608
|
+
.starci-core-flow-graph[data-grammar-flow-grown="true"] .starci-core-flow-graph-canvas { block-size: var(--starci-flow-grown-height); }
|
|
1482
1609
|
|
|
1483
1610
|
.starci-core-flow-graph-loading > .starci-core-skeleton { block-size: 100%; aspect-ratio: auto; }
|
|
1484
1611
|
|
|
@@ -1568,6 +1695,36 @@
|
|
|
1568
1695
|
line-height: 1.25;
|
|
1569
1696
|
}
|
|
1570
1697
|
|
|
1698
|
+
.starci-core-flow-graph-link {
|
|
1699
|
+
display: inline-flex;
|
|
1700
|
+
align-items: center;
|
|
1701
|
+
gap: 0.5rem;
|
|
1702
|
+
min-inline-size: 0;
|
|
1703
|
+
border-radius: inherit;
|
|
1704
|
+
color: inherit;
|
|
1705
|
+
text-decoration: none;
|
|
1706
|
+
outline: none;
|
|
1707
|
+
cursor: pointer;
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
.starci-core-flow-graph-node:has(.starci-core-flow-graph-link:focus-visible) {
|
|
1711
|
+
outline: 2px solid var(--focus, var(--starci-core-focus, Highlight));
|
|
1712
|
+
outline-offset: 2px;
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
.starci-core-flow-graph-header {
|
|
1716
|
+
padding: 0.125rem 0.625rem;
|
|
1717
|
+
color: var(--muted, GrayText);
|
|
1718
|
+
font-size: 0.6875rem;
|
|
1719
|
+
font-weight: 600;
|
|
1720
|
+
letter-spacing: 0.04em;
|
|
1721
|
+
text-transform: uppercase;
|
|
1722
|
+
white-space: nowrap;
|
|
1723
|
+
pointer-events: none;
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
.starci-core-flow-graph-header[data-direction="TB"] { text-align: end; }
|
|
1727
|
+
|
|
1571
1728
|
.starci-core-flow-graph-node[data-size="sm"] { padding: 0.25rem 0.625rem; font-size: 0.75rem; }
|
|
1572
1729
|
.starci-core-flow-graph-node[data-size="lg"] { padding: 0.625rem 1.25rem; font-size: 1rem; font-weight: 600; }
|
|
1573
1730
|
.starci-core-flow-graph-node[data-tone="accent"] { --starci-flow-tint: var(--accent-soft, transparent); --starci-flow-ink: var(--accent-soft-foreground, CanvasText); }
|
|
@@ -547,6 +547,14 @@
|
|
|
547
547
|
flex: none;
|
|
548
548
|
}
|
|
549
549
|
|
|
550
|
+
/* A loading Alert (skeleton parity): the glyph keeps its place as a round Skeleton tint. */
|
|
551
|
+
.starci-core-alert[data-loading="true"] .starci-core-alert-indicator {
|
|
552
|
+
border-radius: 999px;
|
|
553
|
+
background: color-mix(in oklab, var(--surface-tertiary, #e4e4e7) 70%, transparent);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
.starci-core-alert[data-loading="true"] .starci-core-alert-indicator > * { visibility: hidden; }
|
|
557
|
+
|
|
550
558
|
.starci-core-alert-title {
|
|
551
559
|
margin: 0;
|
|
552
560
|
}
|
|
@@ -663,11 +671,16 @@
|
|
|
663
671
|
}
|
|
664
672
|
|
|
665
673
|
/* ---------------------------------------------------------------- skeleton */
|
|
674
|
+
/*
|
|
675
|
+
* Skeleton parity: a text skeleton takes the line box of the copy it stands for. Each line occupies exactly `1lh` of
|
|
676
|
+
* the inherited type (the bar, `--starci-core-skeleton-line` tall, is centred in it by its margins), so `lines={n}`
|
|
677
|
+
* is as tall as n lines of that copy. A context sizes the bar through the variable, never the block size.
|
|
678
|
+
*/
|
|
666
679
|
.starci-core-skeleton-group {
|
|
667
680
|
display: flex;
|
|
668
681
|
width: 100%;
|
|
669
682
|
flex-direction: column;
|
|
670
|
-
gap: 0
|
|
683
|
+
gap: 0;
|
|
671
684
|
}
|
|
672
685
|
|
|
673
686
|
.starci-core-skeleton {
|
|
@@ -678,9 +691,32 @@
|
|
|
678
691
|
|
|
679
692
|
.starci-core-skeleton-group > .starci-core-skeleton {
|
|
680
693
|
width: 100%;
|
|
681
|
-
height: 0.875em;
|
|
694
|
+
height: var(--starci-core-skeleton-line, 0.875em);
|
|
695
|
+
margin-block: calc((1lh - var(--starci-core-skeleton-line, 0.875em)) / 2);
|
|
682
696
|
}
|
|
683
697
|
|
|
698
|
+
/*
|
|
699
|
+
* The measured placeholder (internal `SkeletonPlaceholder`): the ready content is laid out unseen and the shimmer
|
|
700
|
+
* paints its box. A text run is an inline block one line box per line (`vertical-align: top` keeps it from growing
|
|
701
|
+
* the line box); a block or circle sizes to its control or mark.
|
|
702
|
+
*/
|
|
703
|
+
.starci-core-skeleton-placeholder {
|
|
704
|
+
display: inline-block;
|
|
705
|
+
max-inline-size: 100%;
|
|
706
|
+
vertical-align: top;
|
|
707
|
+
color: transparent;
|
|
708
|
+
user-select: none;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
.starci-core-skeleton-placeholder > * { visibility: hidden; }
|
|
712
|
+
.starci-core-skeleton-placeholder[data-shape="block"] { display: inline-flex; }
|
|
713
|
+
.starci-core-skeleton-placeholder[data-shape="circle"] { display: inline-flex; border-radius: 999px; }
|
|
714
|
+
.starci-core-skeleton-placeholder[data-shape="region"] { display: block; }
|
|
715
|
+
.starci-core-skeleton-placeholder[data-shape="text"]:empty { inline-size: min(100%, 8rem); block-size: 1lh; }
|
|
716
|
+
|
|
717
|
+
/* A skeleton root that keeps its content as a measured placeholder (Button, Badge, StatusDot) paints none of it. */
|
|
718
|
+
:is(.starci-core-button, [data-component="Badge"], [data-component="StatusDot"])[data-loading="true"] > * { visibility: hidden; }
|
|
719
|
+
|
|
684
720
|
.starci-core-skeleton[data-grammar-skeleton-line="last"] {
|
|
685
721
|
width: 60%;
|
|
686
722
|
}
|
|
@@ -793,6 +829,9 @@
|
|
|
793
829
|
/* Loading meter (knowledge STATE-8, `isSkeleton`): the label stays real, the bar is a static Skeleton bar of the track height. */
|
|
794
830
|
.starci-core-meter-skeleton-bar { display: block; block-size: 0.5rem; overflow: hidden; border-radius: 999px; }
|
|
795
831
|
|
|
832
|
+
/* `size="sm"`: the thin track is HeroUI's own `.meter--sm` (h-1); only the loading bar, which is ours, follows it. */
|
|
833
|
+
.starci-core-meter-skeleton[data-size="sm"] .starci-core-meter-skeleton-bar { block-size: 0.25rem; }
|
|
834
|
+
|
|
796
835
|
.starci-core-meter-skeleton-bar > .starci-core-skeleton {
|
|
797
836
|
block-size: 100%;
|
|
798
837
|
aspect-ratio: auto;
|