@starci/grammar 0.12.1 → 0.12.4
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/README.md +119 -35
- package/dist/.build-stamp.json +4 -4
- package/dist/common/components-avatar-group.css +7 -0
- package/dist/common/components-forms.css +12 -74
- package/dist/common/components-list-panel.css +36 -7
- package/dist/common/components-navigation.css +46 -157
- package/dist/common/components-overlays.css +1 -85
- package/dist/common/registry.d.ts +6 -6
- package/dist/common/renderers-navigation.d.ts +6 -5
- package/dist/common/renderers-navigation.d.ts.map +1 -1
- package/dist/common/renderers-navigation.js.map +1 -1
- package/dist/common/renderers.d.ts +5 -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/styles.css +7 -132
- package/dist/core/branch/AlertDialog/index.d.ts.map +1 -1
- package/dist/core/branch/AlertDialog/index.js +4 -1
- package/dist/core/branch/AlertDialog/index.js.map +1 -1
- package/dist/core/branch/DataTable/index.d.ts +0 -2
- package/dist/core/branch/DataTable/index.d.ts.map +1 -1
- package/dist/core/branch/DataTable/index.js +3 -2
- package/dist/core/branch/DataTable/index.js.map +1 -1
- package/dist/core/branch/Dialog/index.d.ts.map +1 -1
- package/dist/core/branch/Dialog/index.js +2 -1
- package/dist/core/branch/Dialog/index.js.map +1 -1
- package/dist/core/branch/DragItem/index.d.ts +2 -1
- package/dist/core/branch/DragItem/index.d.ts.map +1 -1
- package/dist/core/branch/DragItem/index.js +1 -1
- package/dist/core/branch/DragItem/index.js.map +1 -1
- package/dist/core/branch/Drawer/index.d.ts.map +1 -1
- package/dist/core/branch/Drawer/index.js +2 -1
- package/dist/core/branch/Drawer/index.js.map +1 -1
- package/dist/core/branch/DropdownMenu/index.d.ts +5 -2
- package/dist/core/branch/DropdownMenu/index.d.ts.map +1 -1
- package/dist/core/branch/DropdownMenu/index.js +6 -4
- package/dist/core/branch/DropdownMenu/index.js.map +1 -1
- package/dist/core/branch/FlowGraph/index.d.ts +4 -1
- package/dist/core/branch/FlowGraph/index.d.ts.map +1 -1
- package/dist/core/branch/FlowGraph/index.js +1 -1
- package/dist/core/branch/FlowGraph/index.js.map +1 -1
- package/dist/core/branch/ListBox/index.d.ts +22 -3
- package/dist/core/branch/ListBox/index.d.ts.map +1 -1
- package/dist/core/branch/ListBox/index.js +9 -5
- package/dist/core/branch/ListBox/index.js.map +1 -1
- package/dist/core/branch/Rail/index.d.ts.map +1 -1
- package/dist/core/branch/Rail/index.js +2 -4
- package/dist/core/branch/Rail/index.js.map +1 -1
- package/dist/core/branch/Select/index.d.ts +3 -0
- package/dist/core/branch/Select/index.d.ts.map +1 -1
- package/dist/core/branch/Select/index.js +7 -3
- package/dist/core/branch/Select/index.js.map +1 -1
- package/dist/core/branch/SurfaceAccordionCard/classNames.d.ts +1 -1
- package/dist/core/branch/SurfaceAccordionCard/classNames.d.ts.map +1 -1
- package/dist/core/branch/SurfaceAccordionCard/classNames.js +3 -3
- package/dist/core/branch/SurfaceAccordionCard/classNames.js.map +1 -1
- package/dist/core/branch/SurfaceAccordionCard/index.d.ts +2 -2
- package/dist/core/branch/SurfaceAccordionCard/index.d.ts.map +1 -1
- package/dist/core/branch/SurfaceAccordionCard/index.js +10 -9
- package/dist/core/branch/SurfaceAccordionCard/index.js.map +1 -1
- package/dist/core/branch/SurfaceCard/classNames.d.ts +0 -4
- package/dist/core/branch/SurfaceCard/classNames.d.ts.map +1 -1
- package/dist/core/branch/SurfaceCard/classNames.js +0 -4
- package/dist/core/branch/SurfaceCard/classNames.js.map +1 -1
- package/dist/core/branch/SurfaceCard/index.d.ts +0 -3
- package/dist/core/branch/SurfaceCard/index.d.ts.map +1 -1
- package/dist/core/branch/SurfaceCard/index.js +11 -29
- package/dist/core/branch/SurfaceCard/index.js.map +1 -1
- package/dist/core/branch/SurfaceListCard/index.d.ts.map +1 -1
- package/dist/core/branch/SurfaceListCard/index.js +2 -1
- package/dist/core/branch/SurfaceListCard/index.js.map +1 -1
- package/dist/core/branch/Tabs/classNames.d.ts +1 -3
- package/dist/core/branch/Tabs/classNames.d.ts.map +1 -1
- package/dist/core/branch/Tabs/classNames.js +1 -4
- package/dist/core/branch/Tabs/classNames.js.map +1 -1
- package/dist/core/branch/Tabs/index.d.ts +5 -8
- package/dist/core/branch/Tabs/index.d.ts.map +1 -1
- package/dist/core/branch/Tabs/index.js +8 -4
- package/dist/core/branch/Tabs/index.js.map +1 -1
- package/dist/core/branch/Toast/index.js +2 -2
- package/dist/core/branch/Toast/index.js.map +1 -1
- package/dist/core/branch/Tooltip/classNames.d.ts +1 -2
- package/dist/core/branch/Tooltip/classNames.d.ts.map +1 -1
- package/dist/core/branch/Tooltip/classNames.js +1 -2
- package/dist/core/branch/Tooltip/classNames.js.map +1 -1
- package/dist/core/branch/Tooltip/index.d.ts +10 -14
- package/dist/core/branch/Tooltip/index.d.ts.map +1 -1
- package/dist/core/branch/Tooltip/index.js +10 -48
- package/dist/core/branch/Tooltip/index.js.map +1 -1
- package/dist/core/buttonIntent.d.ts +27 -0
- package/dist/core/buttonIntent.d.ts.map +1 -0
- package/dist/core/buttonIntent.js +29 -0
- package/dist/core/buttonIntent.js.map +1 -0
- package/dist/core/collectionItem.d.ts +16 -0
- package/dist/core/collectionItem.d.ts.map +1 -0
- package/dist/core/collectionItem.js +12 -0
- package/dist/core/collectionItem.js.map +1 -0
- package/dist/core/composite/AvatarButton/index.d.ts +5 -4
- package/dist/core/composite/AvatarButton/index.d.ts.map +1 -1
- package/dist/core/composite/AvatarButton/index.js +2 -2
- package/dist/core/composite/AvatarButton/index.js.map +1 -1
- package/dist/core/composite/AvatarGroup/index.d.ts +6 -4
- package/dist/core/composite/AvatarGroup/index.d.ts.map +1 -1
- package/dist/core/composite/AvatarGroup/index.js +4 -3
- package/dist/core/composite/AvatarGroup/index.js.map +1 -1
- package/dist/core/composite/CollectionItem/index.d.ts +8 -0
- package/dist/core/composite/CollectionItem/index.d.ts.map +1 -0
- package/dist/core/composite/CollectionItem/index.js +5 -0
- package/dist/core/composite/CollectionItem/index.js.map +1 -0
- package/dist/core/composite/Fieldset/index.js +2 -2
- package/dist/core/composite/Fieldset/index.js.map +1 -1
- package/dist/core/composite/IdentityLockup/index.d.ts +2 -2
- package/dist/core/composite/IdentityLockup/index.d.ts.map +1 -1
- package/dist/core/composite/IdentityLockup/index.js +1 -1
- package/dist/core/composite/ItemActions/index.d.ts +8 -0
- package/dist/core/composite/ItemActions/index.d.ts.map +1 -0
- package/dist/core/composite/ItemActions/index.js +5 -0
- package/dist/core/composite/ItemActions/index.js.map +1 -0
- package/dist/core/composite/ListRow/index.d.ts.map +1 -1
- package/dist/core/composite/ListRow/index.js +2 -1
- package/dist/core/composite/ListRow/index.js.map +1 -1
- package/dist/core/composite/SegmentedControl/index.d.ts.map +1 -1
- package/dist/core/composite/SegmentedControl/index.js +2 -2
- package/dist/core/composite/SegmentedControl/index.js.map +1 -1
- package/dist/core/composite/TagGroup/index.d.ts +3 -3
- package/dist/core/composite/TagGroup/index.d.ts.map +1 -1
- package/dist/core/composite/TagGroup/index.js +1 -1
- package/dist/core/composite/TagGroup/index.js.map +1 -1
- package/dist/core/composite/ToolbarActions/index.d.ts +8 -0
- package/dist/core/composite/ToolbarActions/index.d.ts.map +1 -0
- package/dist/core/composite/ToolbarActions/index.js +5 -0
- package/dist/core/composite/ToolbarActions/index.js.map +1 -0
- package/dist/core/composition/ChatWorkspace/index.d.ts.map +1 -1
- package/dist/core/composition/ChatWorkspace/index.js +2 -1
- package/dist/core/composition/ChatWorkspace/index.js.map +1 -1
- package/dist/core/composition/NavigationFeatureNav/index.d.ts.map +1 -1
- package/dist/core/composition/NavigationFeatureNav/index.js +3 -1
- package/dist/core/composition/NavigationFeatureNav/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 +10 -4
- package/dist/core/composition/Sidebar/index.js.map +1 -1
- package/dist/core/composition/TopBar/index.d.ts.map +1 -1
- package/dist/core/composition/TopBar/index.js +3 -1
- package/dist/core/composition/TopBar/index.js.map +1 -1
- package/dist/core/composition/WorkspaceShell/index.d.ts.map +1 -1
- package/dist/core/composition/WorkspaceShell/index.js +4 -2
- package/dist/core/composition/WorkspaceShell/index.js.map +1 -1
- package/dist/core/dna.d.ts +63 -2
- package/dist/core/dna.d.ts.map +1 -1
- package/dist/core/dna.js +38 -2
- package/dist/core/dna.js.map +1 -1
- package/dist/core/primitive/Avatar/index.d.ts +32 -24
- package/dist/core/primitive/Avatar/index.d.ts.map +1 -1
- package/dist/core/primitive/Avatar/index.js +57 -30
- package/dist/core/primitive/Avatar/index.js.map +1 -1
- package/dist/core/primitive/Button/index.d.ts +5 -2
- package/dist/core/primitive/Button/index.d.ts.map +1 -1
- package/dist/core/primitive/Button/index.js +6 -3
- package/dist/core/primitive/Button/index.js.map +1 -1
- package/dist/core/primitive/Divider/index.d.ts.map +1 -1
- package/dist/core/primitive/Divider/index.js +3 -4
- package/dist/core/primitive/Divider/index.js.map +1 -1
- package/dist/core/primitive/Field/index.d.ts +10 -1
- package/dist/core/primitive/Field/index.d.ts.map +1 -1
- package/dist/core/primitive/Field/index.js +16 -1
- package/dist/core/primitive/Field/index.js.map +1 -1
- package/dist/core/primitive/FileDropzone/index.d.ts.map +1 -1
- package/dist/core/primitive/FileDropzone/index.js +2 -2
- package/dist/core/primitive/FileDropzone/index.js.map +1 -1
- package/dist/core/primitive/GrammarRoot/index.d.ts.map +1 -1
- package/dist/core/primitive/GrammarRoot/index.js +3 -1
- package/dist/core/primitive/GrammarRoot/index.js.map +1 -1
- package/dist/core/primitive/IconButton/index.d.ts +17 -10
- package/dist/core/primitive/IconButton/index.d.ts.map +1 -1
- package/dist/core/primitive/IconButton/index.js +4 -1
- package/dist/core/primitive/IconButton/index.js.map +1 -1
- package/dist/core/primitive/Input/index.d.ts.map +1 -1
- package/dist/core/primitive/Input/index.js +3 -18
- package/dist/core/primitive/Input/index.js.map +1 -1
- package/dist/core/primitive/ListItem/index.d.ts.map +1 -1
- package/dist/core/primitive/ListItem/index.js +2 -1
- package/dist/core/primitive/ListItem/index.js.map +1 -1
- package/dist/core/primitive/Progress/index.d.ts.map +1 -1
- package/dist/core/primitive/Progress/index.js +1 -1
- package/dist/core/primitive/Progress/index.js.map +1 -1
- package/dist/core/primitive/RelativeTime/index.d.ts +19 -6
- package/dist/core/primitive/RelativeTime/index.d.ts.map +1 -1
- package/dist/core/primitive/RelativeTime/index.js +44 -23
- package/dist/core/primitive/RelativeTime/index.js.map +1 -1
- package/dist/core/primitive/Skeleton/index.js +1 -1
- package/dist/core/primitive/Skeleton/index.js.map +1 -1
- package/dist/core/primitive/Slider/index.d.ts.map +1 -1
- package/dist/core/primitive/Slider/index.js +2 -2
- package/dist/core/primitive/Slider/index.js.map +1 -1
- package/dist/core/primitive/Switch/index.d.ts +3 -6
- package/dist/core/primitive/Switch/index.d.ts.map +1 -1
- package/dist/core/primitive/Switch/index.js +1 -1
- package/dist/core/primitive/Switch/index.js.map +1 -1
- package/dist/core/primitive/Text/index.d.ts +1 -0
- package/dist/core/primitive/Text/index.d.ts.map +1 -1
- package/dist/core/primitive/Text/index.js +1 -2
- package/dist/core/primitive/Text/index.js.map +1 -1
- package/dist/core/primitive/TextAction/index.d.ts +3 -3
- package/dist/core/primitive/TextAction/index.d.ts.map +1 -1
- package/dist/core/primitive/TextAction/index.js +2 -2
- package/dist/core/primitive/TextAction/index.js.map +1 -1
- package/dist/core/styles.css +0 -2
- package/dist/heritage/dna.d.ts +62 -0
- package/dist/heritage/dna.d.ts.map +1 -0
- package/dist/heritage/dna.js +37 -0
- package/dist/heritage/dna.js.map +1 -0
- package/dist/offset-pop/conformance.d.ts +1 -1
- package/dist/offset-pop/conformance.js +1 -1
- package/dist/offset-pop/conformance.js.map +1 -1
- package/dist/offset-pop/dna.d.ts +56 -0
- package/dist/offset-pop/dna.d.ts.map +1 -1
- package/dist/offset-pop/dna.js +31 -0
- package/dist/offset-pop/dna.js.map +1 -1
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -36,6 +36,25 @@ its root from one place. Heritage does not re-export Common. It exports `heritag
|
|
|
36
36
|
|
|
37
37
|
## Usage
|
|
38
38
|
|
|
39
|
+
### Button intent
|
|
40
|
+
|
|
41
|
+
Applications declare `intent` on `Button` and `IconButton`: `commit`, `alternative`, `dismiss`,
|
|
42
|
+
`neutral` or `destructive`. A destructive action may supply `step="entry" | "confirm"`; omitted
|
|
43
|
+
step means entry. The type permits `step` only for destructive intent. The family DNA's `intent`
|
|
44
|
+
mapping derives the variant. Explicit `variant` remains available to Grammar internals and stories.
|
|
45
|
+
The [generated button props catalog](docs/button-intent-props.generated.md) lists the published values.
|
|
46
|
+
|
|
47
|
+
Collection rows supply item placement automatically. Wrap a custom repeated card in
|
|
48
|
+
`CollectionItem`, or its action slot in `ItemActions`; both preserve the existing DOM. A repeated
|
|
49
|
+
next action resolves to secondary. `ToolbarActions` supplies chrome placement for custom persistent
|
|
50
|
+
toolbars without adding markup. Bars and panel headers supply chrome placement; neutral commands
|
|
51
|
+
are ghost there, while navbar icon actions stay tertiary. The default decision placement makes a
|
|
52
|
+
neutral command outline. Dialogs and drawers restore decision placement inside their surfaces.
|
|
53
|
+
|
|
54
|
+
Use a `Button` for final destructive confirmation. `AlertDialog` renders dismiss first, focuses it
|
|
55
|
+
on entry, then renders its destructive confirm last. The `Primitives/Button intent` stories show
|
|
56
|
+
the complete placement mapping in light and dark, including destination, pending and skeleton states.
|
|
57
|
+
|
|
39
58
|
### App shell
|
|
40
59
|
|
|
41
60
|
The [app-shell canon](../../knowledge/ui/composition/app-shell.yaml) owns `FE-APP-SHELL-1` through `FE-APP-SHELL-7`.
|
|
@@ -43,10 +62,31 @@ The `Compositions/App shell` stories show the fixed shell, grouped sidebar, icon
|
|
|
43
62
|
|
|
44
63
|
- `size="control"` is available on `Button`, `IconButton`, `TextAction`, `PlainPressable`, `IdentityLockup`, `Input` and `SearchField`, alongside `Switch`, `Avatar` and `AvatarButton`.
|
|
45
64
|
- `SidebarItem.badge`, `badgeLabel` and `badgeMax` show and announce unread counts in both sidebar presentations. `SidebarGroup.placement="end"` places settings groups after the main groups and pushes them to the bottom.
|
|
46
|
-
- The collapsed Sidebar uses Grammar's internal `AnchoredTooltip` on hover and focus.
|
|
65
|
+
- The collapsed Sidebar uses Grammar's internal `AnchoredTooltip` on hover and focus. HeroUI Tooltip positions the annotation beside the selected collection item and portals it into the same family DOM scope, preserving HeroUI's collection anatomy. `onAction` runs for every activated destination, including the selected item, so a drawer can close consistently.
|
|
47
66
|
- A fixed `WorkspaceShell` frames its `compactHeader` slot as the mobile opener band; pass a client `Drawer` with an ellipsis `IconButton` trigger. The `navigationDrawer` form owns the same band when it supplies the opener.
|
|
48
|
-
- `AvatarButton seed` passes the stable identity id to Grammar's shared `Avatar`, which draws
|
|
49
|
-
- `DropdownMenuItem.mark` accepts a decorative identity mark and is mutually exclusive with `iconSource`. A destructive item uses `tone="danger"
|
|
67
|
+
- `AvatarButton seed` passes the stable identity id to Grammar's shared `Avatar`, which draws local DiceBear initials whenever `src` is absent; an uploaded `src` takes precedence.
|
|
68
|
+
- `DropdownMenuItem.mark` accepts a decorative identity mark and is mutually exclusive with `iconSource`. A destructive item uses `tone="danger"`.
|
|
69
|
+
|
|
70
|
+
Compose the interactive shell in a Client Component, where its glyph functions, callbacks and
|
|
71
|
+
state are created. A server layout can pass its rendered children to that component. Load the
|
|
72
|
+
selected family stylesheet and place the family's root around the layout.
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
// components/WorkspaceFrame.tsx
|
|
76
|
+
"use client"
|
|
77
|
+
|
|
78
|
+
import { Sidebar, WorkspaceShell } from "@starci/grammar/core"
|
|
79
|
+
import { EllipsisHorizontalIcon } from "@heroicons/react/24/outline"
|
|
80
|
+
import type { ReactNode } from "react"
|
|
81
|
+
|
|
82
|
+
const groups = [{ id: "main", items: [{ id: "home", label: "Home" }] }]
|
|
83
|
+
|
|
84
|
+
export default function WorkspaceFrame({ children }: { children: ReactNode }) {
|
|
85
|
+
return <WorkspaceShell primary={children} primaryLabel="Workspace" navigation={<Sidebar label="Workspace" groups={groups} />}
|
|
86
|
+
navigationLabel="Workspace navigation" navigationDrawer={{ title: "Navigation", openLabel: "Open navigation",
|
|
87
|
+
closeLabel: "Close navigation", source: EllipsisHorizontalIcon, content: <Sidebar presentation="drawer" label="Workspace" groups={groups} /> }} />
|
|
88
|
+
}
|
|
89
|
+
```
|
|
50
90
|
|
|
51
91
|
### Common (neutral structure only)
|
|
52
92
|
|
|
@@ -57,7 +97,7 @@ import "@starci/grammar/common/styles.css"
|
|
|
57
97
|
export const App = () => (
|
|
58
98
|
<GrammarRoot theme="system">
|
|
59
99
|
<PageContainer>
|
|
60
|
-
<SurfaceCard label="Welcome"><Button>Start</Button></SurfaceCard>
|
|
100
|
+
<SurfaceCard label="Welcome"><Button intent="commit">Start</Button></SurfaceCard>
|
|
61
101
|
</PageContainer>
|
|
62
102
|
</GrammarRoot>
|
|
63
103
|
)
|
|
@@ -84,6 +124,8 @@ export const ProductSurface = () => (
|
|
|
84
124
|
`STARCI_CORE_DNA` exposes the immutable design values. `STARCI_CORE_SPACING_SCALE` exposes the
|
|
85
125
|
4px spacing steps. `STARCI_CORE_TOKEN_NAMES` lists the CSS variables, and
|
|
86
126
|
`STARCI_CORE_TOKEN_DEFAULTS` / `STARCI_CORE_DARK_TOKEN_DEFAULTS` hold their exact packaged values.
|
|
127
|
+
Core's DNA declares a shadow without a border at top surface depth, and a border without a shadow
|
|
128
|
+
at nested depth.
|
|
87
129
|
|
|
88
130
|
### Heritage
|
|
89
131
|
|
|
@@ -173,32 +215,38 @@ same alignment and icon-size rule. Keep the visible item label as its accessible
|
|
|
173
215
|
the mark without visual slot CSS.
|
|
174
216
|
|
|
175
217
|
`RelativeTime` renders `<time dateTime>` for live relative copy such as "5 minutes ago" and a
|
|
176
|
-
countdown such as "in 5 minutes". Pass `dateTime` as a timezone-qualified
|
|
177
|
-
as the active BCP 47 locale.
|
|
178
|
-
|
|
179
|
-
|
|
218
|
+
countdown such as "in 5 minutes". Pass `dateTime` as a timezone-qualified RFC 3339 string and `locale`
|
|
219
|
+
as the active BCP 47 locale. Fractional seconds and numeric offsets such as `+0000` are accepted.
|
|
220
|
+
`mode="relative"` is the default. `mode="countdown"` rounds up the remaining seconds, chooses a unit,
|
|
221
|
+
then shows its completed count: 25 hours shows "in 1 day", and an expired countdown shows
|
|
222
|
+
"in 0 seconds" in English. `format="digital"` shows `m:ss` or `h:mm:ss`; `template` is serializable
|
|
223
|
+
copy containing `{time}`, and `expiredLabel` replaces that complete copy after expiry.
|
|
224
|
+
`size` (`xs`, `sm`, `md`) and `tone` (`default`, `muted`, `accent`) use Common's text presentation.
|
|
180
225
|
|
|
181
226
|
```tsx
|
|
182
227
|
<RelativeTime dateTime="2026-10-25T09:00:00Z" locale="en" />
|
|
183
228
|
<RelativeTime dateTime="2026-10-25T10:00:00+01:00" locale="en" mode="countdown" />
|
|
229
|
+
<RelativeTime dateTime="2026-10-25T10:00:00+0000" locale="en" mode="countdown"
|
|
230
|
+
format="digital" template="Offer ends in {time}" expiredLabel="Offer ended" fallback="Loading" />
|
|
184
231
|
```
|
|
185
232
|
|
|
186
233
|
The server and initial hydration render show `fallback`, or the canonical ISO instant when it is
|
|
187
234
|
omitted. After hydration, every instance reads the same shared ticker. The first subscriber starts
|
|
188
235
|
it and the last unsubscribe stops it; leaves own no clock or refresh interval. Supply translated
|
|
189
|
-
`fallback` copy when an ISO instant is unsuitable.
|
|
236
|
+
`fallback` copy when an ISO instant is unsuitable. Invalid timestamps render the fallback and warn
|
|
237
|
+
in development. Time changes are not a live announcement, so a
|
|
190
238
|
page of timestamps does not repeatedly interrupt assistive technology. Grammar owns native
|
|
191
239
|
`Intl.RelativeTimeFormat` for this primitive; other application date display follows FE-DATE.
|
|
192
240
|
|
|
193
241
|
**DropdownMenu entries.** `entries` is a list of items and sections; the app writes data and no markup, no separator, no
|
|
194
|
-
className and no size. An item takes `id`, `label`, `description`, `shortcut`, `href`, `isDisabled`, `submenu` and:
|
|
242
|
+
className and no size. An item takes `id`, `label`, `description`, `descriptionLines`, `shortcut`, `href`, `isDisabled`, `submenu` and:
|
|
195
243
|
|
|
196
244
|
- `iconSource`: a glyph component (the app's Heroicons). Grammar draws it in HeroUI's leading position at the canon icon size,
|
|
197
245
|
20px (`size-5`, `Icon` `leading`; the Heroicons rule R93 / FE-ICON). HeroUI's own docs example draws its sample glyph at
|
|
198
246
|
`size-4`, which is example content and not a component default, so 20px is StarCi's icon rule and not a vendor override.
|
|
199
247
|
- `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.
|
|
200
248
|
- `tone: "danger"`: HeroUI's `danger` variant, which colours the label and the glyph. Sign out, delete, remove, leave workspace
|
|
201
|
-
and revoke are destructive; the lint rule `starci-
|
|
249
|
+
and revoke are destructive; the lint rule `starci-grammar/destructive-menu-entry-needs-danger-tone` of `@starci/eslint-grammar-starci` refuses such an entry without it.
|
|
202
250
|
|
|
203
251
|
A section takes `label` and optionally `selection` (`mode: "single" | "multiple"`, `selectedIds`, `onChange`). Between two
|
|
204
252
|
adjacent entries, when either is a section, Grammar always inserts HeroUI's own `Separator`: the app cannot forget one. The selection
|
|
@@ -228,7 +276,7 @@ and `Select` are HeroUI's own list-box items (a `Label`, a `Description`, the it
|
|
|
228
276
|
DescriptionList, Disclosure, ListBox, Pagination, Stepper, Subnav, Tabs, TagGroup, Timeline.
|
|
229
277
|
|
|
230
278
|
`DataTable.getCellInteraction(row, columnId)` optionally supplies `onAction`, `onDragOver`,
|
|
231
|
-
`onDragLeave
|
|
279
|
+
`onDragLeave` and `onDrop`. Cells remain semantic
|
|
232
280
|
table cells under the existing arrow-key navigation. An actionable cell takes focus itself,
|
|
233
281
|
activates once with Enter/Space or a click on its plain content, and leaves nested controls to
|
|
234
282
|
their own actions. Native drag callbacks receive the actual inner content-frame event (`HTMLDivElement`); the caller owns
|
|
@@ -276,21 +324,30 @@ dismissal and focus return.
|
|
|
276
324
|
shape in any state, no hover effect, a zoom-out on press, a focus ring, and no zoom under
|
|
277
325
|
`prefers-reduced-motion`. `AvatarButton` is a circle-only avatar built on it (an account-menu
|
|
278
326
|
trigger) and `IdentityLockup` a mark beside a title and a muted subtitle with no caret (a workspace
|
|
279
|
-
switcher trigger). All three work as the `trigger` of `DropdownMenu` and `Popover`. `IdentityLockup`'s mark
|
|
327
|
+
switcher trigger). All three work as the `trigger` of `DropdownMenu` and `Popover`. `IdentityLockup`'s uploaded mark has a transparent box; without an image it uses Avatar's local DiceBear initials. The mark is an uncropped square by default (`markShape="rounded"` opts in to a
|
|
280
328
|
corner) and `Avatar` takes `shape="square" | "rounded"`.
|
|
281
329
|
|
|
282
|
-
Personal avatars are circles.
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
330
|
+
Personal avatars are circles. `Avatar`, `AvatarButton` and each `AvatarGroup` member render the
|
|
331
|
+
bundled DiceBear `initials` style whenever `src` is absent. Initials use the first and last words
|
|
332
|
+
of `name`: `Tran Minh Khoa` becomes `TK`, and a single word contributes one letter. Pass the user
|
|
333
|
+
or entity id as `seed` for stable colours; otherwise the name determines the colour. Server and
|
|
334
|
+
client render the same local data URI, with no network request. The image follows the requested
|
|
335
|
+
Avatar shape and keeps contrasting text in light and dark themes. Images have `alt=""`; the
|
|
336
|
+
avatar shell carries its name, or `isDecorative` hides it beside a visible name. `AvatarButton`
|
|
337
|
+
names the button and keeps its inner avatar decorative. Apps install and import Grammar; its
|
|
338
|
+
pinned DiceBear runtime dependencies and avatar drawing stay inside the package.
|
|
339
|
+
|
|
340
|
+
`kind="person" | "agent"` defaults to `person` on `Avatar`, `AvatarButton` and `AvatarGroup` items.
|
|
341
|
+
Agent names are free text and use the same first-and-last-word initials: `Thao Van Mkt` becomes
|
|
342
|
+
`TM`. Agents add a bottom-right bot badge through HeroUI's Badge anchor, with a surface-colour
|
|
343
|
+
ring and `AI` in the accessible name. The badge is hidden below 32px, including group grid cells;
|
|
344
|
+
their initials and accessible identity remain available.
|
|
289
345
|
The package requires Node 22 or newer, as does the pinned DiceBear engine.
|
|
290
346
|
|
|
291
347
|
```tsx
|
|
292
348
|
<Avatar name={user.name} seed={user.id} isDecorative />
|
|
293
349
|
<AvatarButton name={user.name} seed={user.id} src={user.avatarUrl} />
|
|
350
|
+
<Avatar name="Thao Van Mkt" seed="agent-1" kind="agent" />
|
|
294
351
|
<AvatarGroup label="Team" items={members.map(user => ({ id: user.id, name: user.name, seed: user.id }))}
|
|
295
352
|
overflowLabel={count => `${count} more members`} />
|
|
296
353
|
```
|
|
@@ -310,39 +367,66 @@ renderers with prop-compatible versions and add extensions whose names don't col
|
|
|
310
367
|
|
|
311
368
|
### Surface controls, panel lists and group identity
|
|
312
369
|
|
|
313
|
-
SurfaceCard
|
|
314
|
-
|
|
370
|
+
SurfaceCard, SurfaceListCard, painted SurfaceAccordionCard, Sidebar and the content of Drawer,
|
|
371
|
+
Dialog, AlertDialog and Popover supply the nesting context of ANATOMY-2. SurfaceCard always paints
|
|
372
|
+
a surface: the top layer is raised and a nested layer is subordinate; never raise both layers.
|
|
373
|
+
Each family's DNA owns the paint. SurfaceCard and bounded
|
|
374
|
+
SurfaceAccordionCard derive their depth from the parent context. SurfaceAccordionCard defaults to
|
|
375
|
+
`frame="bounded"`; `frame="unpainted"` and Rail pass the parent's context through.
|
|
315
376
|
Omit a field's `variant`: Input, SearchField, Textarea, NumberField, DateField, TimeField, Select,
|
|
316
377
|
ComboBox, DatePicker, DateRangePicker, Checkbox, CheckboxGroup, RadioGroup, PressableField and OtpInput use `secondary`
|
|
317
378
|
inside these surfaces and `primary` outside. Overlay triggers keep their surrounding context.
|
|
318
|
-
|
|
319
|
-
`
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
379
|
+
Tabs also default to `secondary` inside a surface and `primary` on the page background. The FE
|
|
380
|
+
canon's `FE_NESTED_VARIANT` rejects static field variants throughout app code and explicit primary
|
|
381
|
+
Tabs inside a painted surface. `FE_GRAMMAR_LAYOUT_ONLY` rejects application paint utilities,
|
|
382
|
+
arbitrary paint properties and inline style paint; application CSS carries layout only.
|
|
383
|
+
|
|
384
|
+
ListBox defaults to `inset="panel"` inside the same context. Its box aligns with the panel's search
|
|
385
|
+
field and tabs boxes without negative margins or application padding wrappers (PADDING-0).
|
|
386
|
+
Content keeps HeroUI's list inset and item padding, rounded hover/pressed/selected backgrounds,
|
|
387
|
+
and selection-indicator space, including inside a scrolling panel. Outside a surface, the vendor list inset stays;
|
|
325
388
|
`inset="panel"` also selects the alignment explicitly. Pass flat `items` or named `sections`
|
|
326
389
|
(`ListBoxSection`), with unique item ids across the whole list. `FE_LIST_PANEL_PADDING` rejects
|
|
327
|
-
horizontal padding wrappers around a list or its section caption
|
|
390
|
+
horizontal padding wrappers around a list or its section caption within the nearest painted Grammar surface.
|
|
391
|
+
Sidebar's expanded and collapsed
|
|
328
392
|
rows also retain HeroUI item padding.
|
|
329
393
|
|
|
394
|
+
A `ListBoxItem` is `label` (a string: the title, accessible name and typeahead text), optional `description`,
|
|
395
|
+
`leading` (a centred node in a fixed column before the copy, such as an avatar), `trailing` (after it, such as a count) and
|
|
396
|
+
`isDisabled`. Descriptions show one line with an ellipsis by default; `descriptionLines?: 1 | 2 | 3`
|
|
397
|
+
selects the visible line limit. The same prop and default apply to `DropdownMenuItem`, `SidebarItem`
|
|
398
|
+
and the `ListOption` descriptions used by Select and ComboBox. The packaged stylesheet clamps the
|
|
399
|
+
vendor `Description` slot; its full text stays available to assistive technology.
|
|
400
|
+
`ListBoxItem.emphasis="unread"` makes both the label and description strong using the active family's
|
|
401
|
+
DNA. Omit it for a read row, which keeps HeroUI's normal label and muted description.
|
|
402
|
+
Optional `labelLeading` puts a decorative glyph in the title line itself, inside HeroUI's `Label` before the
|
|
403
|
+
text and on its baseline, e.g. a status mark beside an item's name. Both glyph slots are
|
|
404
|
+
`aria-hidden` (A11Y-2), so the name stays `label`; pass an `Icon usage="chip"` to keep the title line's height.
|
|
405
|
+
`ListBox size="sm" | "md" | "lg"` defaults to `md` and reserves a leading column of 2rem, 2.5rem
|
|
406
|
+
or 3rem, respectively, so icons, avatars and group grids keep labels in one column. An item's
|
|
407
|
+
`size` overrides the list's size.
|
|
408
|
+
|
|
330
409
|
```tsx
|
|
331
410
|
<SurfaceCard ariaLabel="Conversations">
|
|
332
411
|
<Heading level={2}>Conversations</Heading>
|
|
333
412
|
<SearchField label="Find a conversation" />
|
|
334
413
|
<ListBox label="Conversations" sections={[
|
|
335
|
-
{ id: "recent", label: "Recent", items: [
|
|
414
|
+
{ id: "recent", label: "Recent", items: [
|
|
415
|
+
{ id: "team", label: "Design team", description: "Sam: The draft is ready", emphasis: "unread" },
|
|
416
|
+
] },
|
|
336
417
|
]} />
|
|
337
418
|
</SurfaceCard>
|
|
338
419
|
```
|
|
339
420
|
|
|
340
421
|
For a conversation or group identity, use `AvatarGroup layout="grid"` (COLLECTION-3, the Zalo
|
|
341
422
|
reference). It is one round Avatar-sized mark at `sm`, `md`, `lg` or `control`: two members split
|
|
342
|
-
the circle, three show one above two, and four use a 2 by 2 grid
|
|
343
|
-
members, the fourth cell shows
|
|
344
|
-
|
|
345
|
-
|
|
423
|
+
the circle, three show one above two, and four use a 2 by 2 grid. With five or more
|
|
424
|
+
members, three avatars remain and the fourth cell shows the total member count, such as `5` or `30`.
|
|
425
|
+
Each cell has a ring in the surface colour. Each member uses Avatar's
|
|
426
|
+
uploaded image or bundled DiceBear initials, accepts `seed`, `kind` and a custom uploaded-image `fallback`,
|
|
427
|
+
and the count uses the shared avatar renderer. `overflowLabel` receives the number of hidden members
|
|
428
|
+
in both layouts and names them accessibly; the grid's visible digits show the total. A single
|
|
429
|
+
person uses Avatar. The default `layout="row"` keeps the overlapping member row and its `+N` overflow count.
|
|
346
430
|
|
|
347
431
|
## Theming
|
|
348
432
|
|
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.12.
|
|
4
|
+
"version": "0.12.4",
|
|
5
5
|
"algorithm": "starci/grammar-source-digest@1",
|
|
6
|
-
"sourceDigest": "sha256:
|
|
7
|
-
"distDigest": "sha256:
|
|
8
|
-
"builtAt": "2026-10-
|
|
6
|
+
"sourceDigest": "sha256:ffb4788560df9c19f27b314c79227eb27ffeab503001d9dfcef8412143ea8833",
|
|
7
|
+
"distDigest": "sha256:b3108e47d872028b103de19bdd2249105e1d355a294a22ec845b40e25bec3e70",
|
|
8
|
+
"builtAt": "2026-10-25T17:41:39.782Z"
|
|
9
9
|
}
|
|
@@ -16,6 +16,13 @@
|
|
|
16
16
|
background: var(--surface, Canvas);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/* Each member and the total-count cell retain a surface ring over uploaded or generated images. */
|
|
20
|
+
.starci-core-avatar-group-grid > .starci-core-avatar-group-member,
|
|
21
|
+
.starci-core-avatar-group-grid > .starci-core-avatar-group-count {
|
|
22
|
+
outline: 1px solid var(--surface, Canvas);
|
|
23
|
+
outline-offset: -1px;
|
|
24
|
+
}
|
|
25
|
+
|
|
19
26
|
.starci-core-avatar-group[data-grammar-avatar-cells="1"] > .starci-core-avatar-group-grid {
|
|
20
27
|
grid-template-columns: minmax(0, 1fr);
|
|
21
28
|
grid-template-rows: minmax(0, 1fr);
|
|
@@ -45,8 +45,6 @@
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
.starci-core-field-error {
|
|
48
|
-
margin: 0;
|
|
49
|
-
color: var(--danger, CanvasText);
|
|
50
48
|
font-size: 0.75rem;
|
|
51
49
|
font-weight: 600;
|
|
52
50
|
line-height: 1.4;
|
|
@@ -142,7 +140,6 @@
|
|
|
142
140
|
.starci-core-field-skeleton-control > .starci-core-skeleton {
|
|
143
141
|
block-size: 100%;
|
|
144
142
|
aspect-ratio: auto;
|
|
145
|
-
border-radius: var(--field-radius, calc(var(--radius, 0.5rem) * 1.5));
|
|
146
143
|
}
|
|
147
144
|
|
|
148
145
|
.starci-core-field-skeleton-control:is([data-grammar-field-skeleton="input"]) { block-size: 2.5rem; }
|
|
@@ -160,11 +157,8 @@
|
|
|
160
157
|
|
|
161
158
|
/* A checkbox box and a switch track beside their real labels. */
|
|
162
159
|
.starci-core-field-skeleton-control[data-grammar-field-skeleton="choice"] { flex: none; block-size: 1rem; inline-size: 1rem; }
|
|
163
|
-
.starci-core-field-skeleton-control[data-grammar-field-skeleton="choice"] > .starci-core-skeleton { border-radius: 0.25rem; }
|
|
164
160
|
.starci-core-field-skeleton-control[data-grammar-field-skeleton="switch"] { flex: none; block-size: 1.25rem; inline-size: 2rem; }
|
|
165
|
-
.starci-core-field-skeleton-control[data-grammar-field-skeleton="switch"]
|
|
166
|
-
.starci-core-field-skeleton-control[data-grammar-field-skeleton="switch"][data-grammar-switch-size="lg"] { block-size: 2.25rem; inline-size: 4rem; }
|
|
167
|
-
.starci-core-field-skeleton-control[data-grammar-field-skeleton="switch"][data-grammar-switch-size="control"] { block-size: var(--starci-core-control-min-size, 2.75rem); inline-size: 4.875rem; }
|
|
161
|
+
.starci-core-field-skeleton-control[data-grammar-field-skeleton="switch"][data-grammar-switch-size="lg"] { block-size: 1.5rem; inline-size: 3rem; }
|
|
168
162
|
|
|
169
163
|
.starci-core-field-skeleton-choice-label {
|
|
170
164
|
color: var(--foreground, CanvasText);
|
|
@@ -210,8 +204,16 @@
|
|
|
210
204
|
.starci-core-number-field-group,
|
|
211
205
|
.starci-core-date-group {
|
|
212
206
|
box-sizing: border-box;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.starci-core-input-field,
|
|
210
|
+
.starci-core-combo-box-group {
|
|
211
|
+
min-block-size: var(--starci-core-field-min-height, 2.5rem);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* Owner 2026-10-25: Select has the same 2.5rem field height as Input. */
|
|
215
|
+
.starci-core-select-trigger {
|
|
213
216
|
min-block-size: var(--starci-core-field-min-height, 2.5rem);
|
|
214
|
-
border-radius: var(--field-radius, calc(var(--radius, 0.5rem) * 1.5));
|
|
215
217
|
}
|
|
216
218
|
|
|
217
219
|
/*
|
|
@@ -222,8 +224,7 @@
|
|
|
222
224
|
* are never both outlined. The frame keeps the ring for every way focus arrives (`:focus-within`), so keyboard
|
|
223
225
|
* focus stays visible; forced-colors draws it as a system outline on the same frame.
|
|
224
226
|
*/
|
|
225
|
-
|
|
226
|
-
outline: none;
|
|
227
|
+
.starci-core-combo-box-input:is(:focus, :focus-visible, [data-focused="true"], [data-focus-visible="true"]) {
|
|
227
228
|
box-shadow: none;
|
|
228
229
|
}
|
|
229
230
|
|
|
@@ -245,13 +246,11 @@
|
|
|
245
246
|
box-sizing: border-box;
|
|
246
247
|
flex: 1 1 0;
|
|
247
248
|
border-radius: inherit;
|
|
248
|
-
padding-inline: 0.75rem 1.75rem;
|
|
249
249
|
text-overflow: ellipsis;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
.starci-core-combo-box-trigger {
|
|
253
253
|
inset-inline-end: 0;
|
|
254
|
-
padding-inline-end: 0.5rem;
|
|
255
254
|
}
|
|
256
255
|
|
|
257
256
|
.starci-core-date-input {
|
|
@@ -261,8 +260,6 @@
|
|
|
261
260
|
|
|
262
261
|
.starci-core-date-range-separator {
|
|
263
262
|
flex-shrink: 0;
|
|
264
|
-
padding-inline: 0.25rem;
|
|
265
|
-
color: var(--muted, GrayText);
|
|
266
263
|
}
|
|
267
264
|
|
|
268
265
|
/* --- List popover (Select, ComboBox) ---
|
|
@@ -310,55 +307,7 @@
|
|
|
310
307
|
}
|
|
311
308
|
|
|
312
309
|
/*
|
|
313
|
-
*
|
|
314
|
-
* `lg`: a 4rem by 2.25rem fully round track, a thumb the track height less 0.5rem inset 0.25rem, an optional glyph centred in the
|
|
315
|
-
* thumb. `control`: the same shape at the shared control height (2.75rem), so a theme switch lines up with the IconButtons and the
|
|
316
|
-
* avatar of a bar. Keyed on the stamps the component emits (`data-grammar-switch-size`, `data-grammar-switch-thumb`,
|
|
317
|
-
* `data-grammar-switch-icon`), never on vendor class names. The geometry is `!important` because consumers import this sheet on
|
|
318
|
-
* either side of `@heroui/styles`, so layer rank cannot decide against the vendor `.switch--*` size rules. The on position is a
|
|
319
|
-
* margin (as HeroUI's own thumb), the percentage resolving against the track: 100% - thumb - inset.
|
|
320
|
-
*/
|
|
321
|
-
[data-component="Switch"][data-grammar-switch-size="lg"] {
|
|
322
|
-
--grammar-switch-height: 2.25rem;
|
|
323
|
-
--grammar-switch-width: 4rem;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
[data-component="Switch"][data-grammar-switch-size="control"] {
|
|
327
|
-
--grammar-switch-height: var(--starci-core-control-min-size, 2.75rem);
|
|
328
|
-
--grammar-switch-width: 4.875rem;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
[data-component="Switch"]:is([data-grammar-switch-size="lg"], [data-grammar-switch-size="control"]) {
|
|
332
|
-
--grammar-switch-thumb: calc(var(--grammar-switch-height) - 0.5rem);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
[data-component="Switch"]:is([data-grammar-switch-size="lg"], [data-grammar-switch-size="control"]) [data-grammar-choice-control="switch"] {
|
|
336
|
-
block-size: var(--grammar-switch-height) !important;
|
|
337
|
-
inline-size: var(--grammar-switch-width) !important;
|
|
338
|
-
border-radius: 9999px !important;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
[data-component="Switch"]:is([data-grammar-switch-size="lg"], [data-grammar-switch-size="control"]) [data-grammar-switch-thumb] {
|
|
342
|
-
block-size: var(--grammar-switch-thumb) !important;
|
|
343
|
-
inline-size: var(--grammar-switch-thumb) !important;
|
|
344
|
-
border-radius: 9999px !important;
|
|
345
|
-
margin-inline-start: 0.25rem !important;
|
|
346
|
-
align-items: center;
|
|
347
|
-
justify-content: center;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
[data-component="Switch"]:is([data-grammar-switch-size="lg"], [data-grammar-switch-size="control"]):is([data-selected="true"], [aria-checked="true"]) [data-grammar-switch-thumb] {
|
|
351
|
-
margin-inline-start: calc(100% - var(--grammar-switch-thumb) - 0.25rem) !important;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/* The description and error align under the label, past the wider track. */
|
|
355
|
-
[data-component="Switch"]:is([data-grammar-switch-size="lg"], [data-grammar-switch-size="control"]) > :is([data-slot="description"], [data-slot="field-error"]) {
|
|
356
|
-
padding-inline-start: calc(var(--grammar-switch-width) + 0.75rem);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/*
|
|
360
|
-
* The thumb glyph box is the canon icon size, not whatever the vendor's thumb container leaves: 20px (size-5, `Icon` `leading`) on `lg`
|
|
361
|
-
* and `control`, 16px (`chip`) on `md`, whose thumb is 1rem tall. The glyph fills its box, centred in the thumb.
|
|
310
|
+
* The thumb glyph box is the canon icon size: 20px (size-5, `Icon` `leading`) on `lg`, 16px (`chip`) on `md`. The glyph fills its box, centred in the thumb.
|
|
362
311
|
*/
|
|
363
312
|
.starci-core-switch-icon {
|
|
364
313
|
display: inline-flex;
|
|
@@ -399,8 +348,6 @@
|
|
|
399
348
|
|
|
400
349
|
.starci-core-slider-output {
|
|
401
350
|
color: var(--muted, GrayText);
|
|
402
|
-
font-size: 0.875rem;
|
|
403
|
-
font-variant-numeric: tabular-nums;
|
|
404
351
|
}
|
|
405
352
|
|
|
406
353
|
/* --- SegmentedControl --- */
|
|
@@ -454,10 +401,6 @@
|
|
|
454
401
|
width: 100%;
|
|
455
402
|
margin: 0;
|
|
456
403
|
padding: 0;
|
|
457
|
-
color: var(--foreground, CanvasText);
|
|
458
|
-
font-size: 1rem;
|
|
459
|
-
font-weight: 700;
|
|
460
|
-
line-height: 1.3;
|
|
461
404
|
}
|
|
462
405
|
|
|
463
406
|
.starci-core-fieldset-legend + * {
|
|
@@ -559,11 +502,6 @@
|
|
|
559
502
|
overflow-wrap: anywhere;
|
|
560
503
|
}
|
|
561
504
|
|
|
562
|
-
/* --- Read-only reads as settled, not as unavailable --- */
|
|
563
|
-
[data-grammar-field="true"][data-grammar-readonly="true"] :where(.starci-core-combo-box-group, .starci-core-search-field-group, .starci-core-number-field-group, .starci-core-date-group, .starci-core-textarea-control) {
|
|
564
|
-
background: var(--surface-secondary, var(--field-background, Canvas));
|
|
565
|
-
}
|
|
566
|
-
|
|
567
505
|
/*
|
|
568
506
|
* THE 44px TOUCH FLOOR.
|
|
569
507
|
*
|
|
@@ -1,13 +1,42 @@
|
|
|
1
|
-
/* PADDING-0:
|
|
1
|
+
/* PADDING-0: panel list boxes share the field and tabs edge; HeroUI owns list and item padding. */
|
|
2
2
|
@layer starci-grammar-common {
|
|
3
3
|
.grammar-common-root .starci-core-list-box[data-grammar-list-inset="panel"] {
|
|
4
|
-
|
|
5
|
-
inline
|
|
6
|
-
margin-inline: -0.5rem;
|
|
7
|
-
padding-inline: 0 !important;
|
|
4
|
+
inline-size: 100%;
|
|
5
|
+
margin-inline: 0;
|
|
8
6
|
}
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
/* owner:item-description-one-line: clamp the vendor Description slot, preserving its text and paint. */
|
|
9
|
+
.grammar-common-root [data-slot="description"][data-grammar-item-description="true"] {
|
|
10
|
+
display: -webkit-box;
|
|
11
|
+
-webkit-box-orient: vertical;
|
|
12
|
+
-webkit-line-clamp: 1;
|
|
13
|
+
line-clamp: 1;
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
white-space: normal;
|
|
16
|
+
text-overflow: ellipsis;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.grammar-common-root [data-slot="description"][data-grammar-description-lines="2"] {
|
|
20
|
+
-webkit-line-clamp: 2;
|
|
21
|
+
line-clamp: 2;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.grammar-common-root [data-slot="description"][data-grammar-description-lines="3"] {
|
|
25
|
+
-webkit-line-clamp: 3;
|
|
26
|
+
line-clamp: 3;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.grammar-common-root [data-grammar-sidebar-copy="true"] {
|
|
30
|
+
display: flex;
|
|
31
|
+
flex: 1;
|
|
32
|
+
flex-direction: column;
|
|
33
|
+
min-width: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.grammar-common-root [data-grammar-item-label="true"] {
|
|
37
|
+
max-inline-size: 100%;
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
white-space: nowrap;
|
|
40
|
+
text-overflow: ellipsis;
|
|
12
41
|
}
|
|
13
42
|
}
|