@solidrt/components 0.0.61 → 0.0.62
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/AGENTS.md +1 -1
- package/README.md +1 -1
- package/docs/nav-shell.md +1 -1
- package/package.json +2 -2
- package/src/editor-field.tsx +20 -7
package/AGENTS.md
CHANGED
|
@@ -99,7 +99,7 @@ One bullet per module, generated from the first paragraph of its docs/ file.
|
|
|
99
99
|
- `Select` - A single-choice picker whose presentation forks on the interaction policy: `desktop`/`hybrid` opens an anchored dropdown under the trigger (flipping above when there is no room), `touch` opens a bottom sheet over a scrim. Same contract either way: `options` is an `Option[]` (`{ value, label }`), controlled via `value`/`onChange` or uncontrolled via `defaultValue`; pressing outside closes without a change. `placeholder` shows in the trigger while nothing is selected. Both presentations fade in and out, and the trigger's chevron flips while open. The option list is not scrollable yet, so keep it short. The chevron is the `theme.icons.chevronDown` slot when a theme sets one.
|
|
100
100
|
- `SegmentedControl` - A single-choice row of equal-width segments joined flush: only the control's outermost corners are rounded, hairline dividers separate the segments, and the active segment is one `primary` indicator that springs between segments on a selection change - the `indicator` transition entry retimes it. Hovered segments tint with the theme `overlayHover` under non-touch interaction policies. `options` is an `Option[]`; controlled via `value`/`onChange`, or uncontrolled via `defaultValue`. Override the inactive fill via `style.backgroundColor` and the outer radius via `style.borderRadius`.
|
|
101
101
|
- `ContextMenu` - Secondary actions on the wrapped content. The opening gesture follows the physical pointer: right-click for a mouse, long-press (500 ms, cancelled by finger travel; core's long-press recognizer) for touch and pen. The long-press wins the finger at its timer: a pressable inside retracts and does not fire on the lift, and a scroll that started first keeps the finger. The presentation forks on the interaction policy: `touch` gets a bottom sheet over a scrim, `desktop`/`hybrid` an anchored menu at the pointer that flips up near the bottom edge. Both presentations fade in and out. `items` is a `ContextMenuItem[]` (`{ label, onSelect?, disabled? }`); pressing outside closes without selecting.
|
|
102
|
-
- `NavShell` - An app shell that arranges primary navigation around the content per `policy.navigation`: bottom tabs under it (`bottomTabs`), a narrow rail (`rail`), or a wide sidebar (`sidebar`) beside it. The content is a single stable node; switching arrangement only flips the shell's flex direction and remounts the stateless nav strip, so page state survives a resize across a breakpoint. `items` is a `NavItem[]` (`{ value, label, icon? }`; the icon renders above the label in tabs/rail, beside it in the sidebar); controlled via `value`/`onChange`, or uncontrolled via `defaultValue`. Safe areas are the caller's concern: wrap the shell in `SafeArea`.
|
|
102
|
+
- `NavShell` - An app shell that arranges primary navigation around the content per `policy.navigation`: bottom tabs under it (`bottomTabs`), a narrow rail (`rail`), or a wide sidebar (`sidebar`) beside it. The content is a single stable node; switching arrangement only flips the shell's flex direction and remounts the stateless nav strip, so page state survives a resize across a breakpoint. `items` is a `NavItem[]` (`{ value, label, icon? }`; the icon renders above the label in tabs/rail, beside it in the sidebar); controlled via `value`/`onChange`, or uncontrolled via `defaultValue`. Safe areas are the caller's concern: wrap the shell in `SafeArea`. With `@solidrt/router` the shell is the tabs route's component, `value`/`onChange` wired to `useTabs()` (`active()`/`select(path)`) and `<Outlet />` as the content; the router then keeps a stack per tab and the tabs mounted.
|
|
103
103
|
- `SplitView` - A list-detail container driven by `policy.layout`: `twoPane` shows the `list` pane (width `listWidth`, default `theme.size.splitViewList`) beside the `detail` pane, `singlePane` shows one at a time per `showDetail`. Keep pane state (selection, scroll) in the app, not in the panes: crossing a breakpoint re-arranges and can remount them. It draws no chrome and adds no padding; a back affordance in the single-pane detail is the app's to render (fork on `policy.layout`).
|
|
104
104
|
- `QrCode` - Renders a QR code for `data` out of primitives: same-color modules in a row collapse into one box, drawn on a light quiet-zone panel; the grid recomputes only when `data` or `level` changes. It paints black on white by default (not the theme) so it stays scannable through a theme switch; override `color`/`background` only if the contrast still holds. `moduleSize` (default 6) is pixels per module, `margin` (default 16) the quiet zone (keep it non-zero), `level` the error correction (`L`/`M`/`Q`/`H`, default `M`: higher tolerates more damage but caps data length sooner), `radius` the panel's corner radius.
|
|
105
105
|
- `Icon` - A thin themed wrapper over the core `parseSvg` primitive. `src` is a whole SVG document as a string; the component parses it once (memoized), maps the draws to `<d-path>` in a square `designSize`-fitted box (`size`, default 24) and, for monochrome icons that stroke/fill with `currentColor`, recolors it via `color` (default the theme text color). It carries no icon set and no name registry, so any `currentColor` SVG works (Lucide, Feather, Heroicons, ...) and only the icons you import are bundled. Multi-color documents keep their own fills. For a non-square box, use `parseSvg` directly.
|
package/README.md
CHANGED
|
@@ -738,7 +738,7 @@ API: `ContextMenu`, `ContextMenuProps`, `ContextMenuItem` - typed and commented
|
|
|
738
738
|
|
|
739
739
|
### NavShell
|
|
740
740
|
|
|
741
|
-
An app shell that arranges primary navigation around the content per `policy.navigation`: bottom tabs under it (`bottomTabs`), a narrow rail (`rail`), or a wide sidebar (`sidebar`) beside it. The content is a single stable node; switching arrangement only flips the shell's flex direction and remounts the stateless nav strip, so page state survives a resize across a breakpoint. `items` is a `NavItem[]` (`{ value, label, icon? }`; the icon renders above the label in tabs/rail, beside it in the sidebar); controlled via `value`/`onChange`, or uncontrolled via `defaultValue`. Safe areas are the caller's concern: wrap the shell in `SafeArea`.
|
|
741
|
+
An app shell that arranges primary navigation around the content per `policy.navigation`: bottom tabs under it (`bottomTabs`), a narrow rail (`rail`), or a wide sidebar (`sidebar`) beside it. The content is a single stable node; switching arrangement only flips the shell's flex direction and remounts the stateless nav strip, so page state survives a resize across a breakpoint. `items` is a `NavItem[]` (`{ value, label, icon? }`; the icon renders above the label in tabs/rail, beside it in the sidebar); controlled via `value`/`onChange`, or uncontrolled via `defaultValue`. Safe areas are the caller's concern: wrap the shell in `SafeArea`. With `@solidrt/router` the shell is the tabs route's component, `value`/`onChange` wired to `useTabs()` (`active()`/`select(path)`) and `<Outlet />` as the content; the router then keeps a stack per tab and the tabs mounted.
|
|
742
742
|
|
|
743
743
|
```jsx
|
|
744
744
|
import { NavShell, Icon } from "@solidrt/components"
|
package/docs/nav-shell.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# NavShell
|
|
2
2
|
|
|
3
|
-
An app shell that arranges primary navigation around the content per `policy.navigation`: bottom tabs under it (`bottomTabs`), a narrow rail (`rail`), or a wide sidebar (`sidebar`) beside it. The content is a single stable node; switching arrangement only flips the shell's flex direction and remounts the stateless nav strip, so page state survives a resize across a breakpoint. `items` is a `NavItem[]` (`{ value, label, icon? }`; the icon renders above the label in tabs/rail, beside it in the sidebar); controlled via `value`/`onChange`, or uncontrolled via `defaultValue`. Safe areas are the caller's concern: wrap the shell in `SafeArea`.
|
|
3
|
+
An app shell that arranges primary navigation around the content per `policy.navigation`: bottom tabs under it (`bottomTabs`), a narrow rail (`rail`), or a wide sidebar (`sidebar`) beside it. The content is a single stable node; switching arrangement only flips the shell's flex direction and remounts the stateless nav strip, so page state survives a resize across a breakpoint. `items` is a `NavItem[]` (`{ value, label, icon? }`; the icon renders above the label in tabs/rail, beside it in the sidebar); controlled via `value`/`onChange`, or uncontrolled via `defaultValue`. Safe areas are the caller's concern: wrap the shell in `SafeArea`. With `@solidrt/router` the shell is the tabs route's component, `value`/`onChange` wired to `useTabs()` (`active()`/`select(path)`) and `<Outlet />` as the content; the router then keeps a stack per tab and the tabs mounted.
|
|
4
4
|
|
|
5
5
|
```jsx
|
|
6
6
|
import { NavShell, Icon } from "@solidrt/components"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidrt/components",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.62",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"funding": "https://github.com/sponsors/wellawaretech",
|
|
6
6
|
"author": "Antoine van Wel",
|
|
@@ -21,6 +21,6 @@
|
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"@solidjs/signals": "2.0.0-rc.9",
|
|
24
|
-
"@solidrt/core": "0.0.
|
|
24
|
+
"@solidrt/core": "0.0.62"
|
|
25
25
|
}
|
|
26
26
|
}
|
package/src/editor-field.tsx
CHANGED
|
@@ -92,6 +92,13 @@ export interface EditorFieldProps extends TransitionProps {
|
|
|
92
92
|
// navigator.clipboard (copy and cut need a range; single-line paste flattens
|
|
93
93
|
// line breaks). A tap outside the field blurs it (core's outside-tap blur in
|
|
94
94
|
// window.ts), as does Escape.
|
|
95
|
+
// Font options compared field by field: the same keys with the same values.
|
|
96
|
+
function sameFont(a: MeasureTextOptions, b: MeasureTextOptions): boolean {
|
|
97
|
+
let ka = Object.keys(a) as (keyof MeasureTextOptions)[]
|
|
98
|
+
let kb = Object.keys(b) as (keyof MeasureTextOptions)[]
|
|
99
|
+
return ka.length === kb.length && ka.every((k) => a[k] === b[k])
|
|
100
|
+
}
|
|
101
|
+
|
|
95
102
|
export function EditorField(props: EditorFieldProps) {
|
|
96
103
|
let [caretOn, setCaretOn] = createSignal(true)
|
|
97
104
|
|
|
@@ -403,13 +410,19 @@ export function EditorField(props: EditorFieldProps) {
|
|
|
403
410
|
let layoutFont = () => layout().text as EditorLayoutProps
|
|
404
411
|
let fontSize = () => (layoutFont().fontSize ?? theme.text.body.size) * policy.textScale
|
|
405
412
|
let lineHeight = () => layoutFont().lineHeight ?? theme.text.body.lineHeight
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
+
// A memo, equal by field: the editor layout reads the font on every
|
|
414
|
+
// caret, text or size change, and rebuilding it (theme, policy and the
|
|
415
|
+
// weight compensation) per read cost more than the geometry it fed.
|
|
416
|
+
let font = createMemo(
|
|
417
|
+
(): MeasureTextOptions => ({
|
|
418
|
+
fontFamily: layoutFont().fontFamily ?? theme.text.fontFamily,
|
|
419
|
+
fontSize: fontSize(),
|
|
420
|
+
lineHeight: lineHeight(),
|
|
421
|
+
fontStyle: layoutFont().fontStyle,
|
|
422
|
+
fontWeight: typeWeight(layoutFont().fontWeight ?? theme.text.body.weight, fontSize()),
|
|
423
|
+
}),
|
|
424
|
+
{ equals: sameFont },
|
|
425
|
+
)
|
|
413
426
|
let rowHeight = () => Math.round(fontSize() * lineHeight())
|
|
414
427
|
let editor = createTextEditorLayout(
|
|
415
428
|
() => viewport,
|