@nick-skriabin/glyph 0.1.49 → 0.1.51
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 +61 -1
- package/dist/index.d.ts +55 -1
- package/dist/index.js +18 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ Build real terminal applications with React. Glyph provides a full component mod
|
|
|
40
40
|
| | |
|
|
41
41
|
|---|---|
|
|
42
42
|
| **Flexbox Layout** | Full CSS-like flexbox via Yoga — rows, columns, wrapping, alignment, gaps, padding |
|
|
43
|
-
| **Rich Components** | Box, Text, Input, Button, Checkbox, Radio, Select, ScrollView, List, Menu, Progress, Spinner, Toasts, Dialogs, Portal, JumpNav |
|
|
43
|
+
| **Rich Components** | Box, Text, Input, Button, Checkbox, Radio, Select, ScrollView, List, Menu, Progress, Spinner, Image, Toasts, Dialogs, Portal, JumpNav |
|
|
44
44
|
| **Focus System** | Tab navigation, focus scopes, focus trapping for modals, JumpNav quick-jump hints |
|
|
45
45
|
| **Keyboard Input** | `useInput` hook, declarative `<Keybind>` component, vim-style bindings |
|
|
46
46
|
| **Smart Rendering** | Double-buffered framebuffer with character-level diffing — only changed cells are written |
|
|
@@ -455,6 +455,65 @@ Animated spinner with configurable frames. Cleans up timers on unmount.
|
|
|
455
455
|
<Spinner frames={["|", "/", "-", "\\"]} intervalMs={100} />
|
|
456
456
|
```
|
|
457
457
|
|
|
458
|
+
### `<Image>`
|
|
459
|
+
|
|
460
|
+
Display images in the terminal with inline rendering or OS preview. Supports local files and remote URLs.
|
|
461
|
+
|
|
462
|
+
```tsx
|
|
463
|
+
<Image
|
|
464
|
+
src="./photo.jpg"
|
|
465
|
+
style={{ width: 40, height: 15 }}
|
|
466
|
+
autoLoad
|
|
467
|
+
/>
|
|
468
|
+
|
|
469
|
+
<Image
|
|
470
|
+
src="https://images.unsplash.com/photo-123"
|
|
471
|
+
style={{ flexGrow: 1 }}
|
|
472
|
+
/>
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
**How it works:**
|
|
476
|
+
1. By default, shows a placeholder with the image name
|
|
477
|
+
2. Focus the component and press `Space` to load
|
|
478
|
+
3. Image renders inline (Kitty/iTerm2 protocol) or opens OS preview (Quick Look on macOS)
|
|
479
|
+
4. Press `Escape` to return to placeholder, `R` to reload
|
|
480
|
+
|
|
481
|
+
**Props:**
|
|
482
|
+
|
|
483
|
+
| Prop | Type | Default | Description |
|
|
484
|
+
|------|------|---------|-------------|
|
|
485
|
+
| `src` | `string` | required | Local path or remote URL |
|
|
486
|
+
| `width` | `number` | auto | Fixed width in cells |
|
|
487
|
+
| `height` | `number` | auto | Fixed height in cells |
|
|
488
|
+
| `style` | `Style` | `{}` | Container style (flexbox) |
|
|
489
|
+
| `focusedStyle` | `Style` | `{}` | Style when focused |
|
|
490
|
+
| `inline` | `boolean` | `true` | Allow inline terminal rendering |
|
|
491
|
+
| `autoLoad` | `boolean` | `false` | Load automatically on mount |
|
|
492
|
+
| `focusable` | `boolean` | `true` | Whether the component is focusable |
|
|
493
|
+
| `placeholder` | `string` | filename | Custom placeholder text |
|
|
494
|
+
| `onStateChange` | `(state) => void` | - | Called when state changes |
|
|
495
|
+
| `onError` | `(error) => void` | - | Called on error |
|
|
496
|
+
|
|
497
|
+
**Terminal support:**
|
|
498
|
+
- **Inline rendering:** Kitty, Ghostty, WezTerm, iTerm2 (via Kitty Graphics or iTerm2 protocol)
|
|
499
|
+
- **OS preview fallback:** Quick Look (macOS), xdg-open (Linux), start (Windows)
|
|
500
|
+
|
|
501
|
+
**Remote images** are automatically downloaded and cached. Supported formats: PNG, JPEG, GIF, WebP.
|
|
502
|
+
|
|
503
|
+
```tsx
|
|
504
|
+
// Inline disabled - always use OS preview
|
|
505
|
+
<Image src="./large-photo.jpg" inline={false} />
|
|
506
|
+
|
|
507
|
+
// With state callback
|
|
508
|
+
<Image
|
|
509
|
+
src={imageUrl}
|
|
510
|
+
onStateChange={(state) => {
|
|
511
|
+
// "placeholder" | "loading" | "loaded" | "error" | "preview"
|
|
512
|
+
console.log("Image state:", state);
|
|
513
|
+
}}
|
|
514
|
+
/>
|
|
515
|
+
```
|
|
516
|
+
|
|
458
517
|
### `<ToastHost>` + `useToast()`
|
|
459
518
|
|
|
460
519
|
Lightweight toast notifications rendered via Portal. Wrap your app in `<ToastHost>`, then push toasts from anywhere with `useToast()`.
|
|
@@ -763,6 +822,7 @@ Interactive examples are included in the repo. Each demonstrates different compo
|
|
|
763
822
|
| **dialog-demo** | Alert and Confirm dialogs | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/dialog-demo) |
|
|
764
823
|
| **jump-nav** | Quick navigation with keyboard hints | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/jump-nav) |
|
|
765
824
|
| **ansi-text** | ANSI escape codes and colored output | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/ansi-text) |
|
|
825
|
+
| **image** | Inline images and OS preview | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/image) |
|
|
766
826
|
| **showcase** | Progress bars, Spinners, Toasts | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/showcase) |
|
|
767
827
|
| **dashboard** | Full task manager (all components) | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/dashboard) |
|
|
768
828
|
|
package/dist/index.d.ts
CHANGED
|
@@ -509,6 +509,42 @@ interface JumpNavProps {
|
|
|
509
509
|
*/
|
|
510
510
|
declare function JumpNav({ children, activationKey, hintStyle, hintBg, hintFg, hintChars, enabled, debug, }: JumpNavProps): React.JSX.Element;
|
|
511
511
|
|
|
512
|
+
/**
|
|
513
|
+
* Image component for terminal UIs
|
|
514
|
+
*
|
|
515
|
+
* Supports inline rendering via terminal protocols (Kitty, iTerm2)
|
|
516
|
+
* and OS-level preview (Quick Look on macOS, xdg-open on Linux)
|
|
517
|
+
*/
|
|
518
|
+
|
|
519
|
+
type ImageState = "placeholder" | "loading" | "loaded" | "error" | "preview";
|
|
520
|
+
interface ImageProps {
|
|
521
|
+
/** Image source - local path or remote URL */
|
|
522
|
+
src: string;
|
|
523
|
+
/** Fixed width in cells (optional, uses flexbox if not set) */
|
|
524
|
+
width?: number;
|
|
525
|
+
/** Fixed height in cells (optional, uses flexbox if not set) */
|
|
526
|
+
height?: number;
|
|
527
|
+
/** Container style (flexbox) */
|
|
528
|
+
style?: Style;
|
|
529
|
+
/** Style when focused */
|
|
530
|
+
focusedStyle?: Style;
|
|
531
|
+
/** Style for the placeholder */
|
|
532
|
+
placeholderStyle?: Style;
|
|
533
|
+
/** Whether the component is focusable (default: true) */
|
|
534
|
+
focusable?: boolean;
|
|
535
|
+
/** Allow inline rendering in terminal (default: true) */
|
|
536
|
+
inline?: boolean;
|
|
537
|
+
/** Custom placeholder text (default: image name) */
|
|
538
|
+
placeholder?: string;
|
|
539
|
+
/** Called when image state changes */
|
|
540
|
+
onStateChange?: (state: ImageState) => void;
|
|
541
|
+
/** Called on error */
|
|
542
|
+
onError?: (error: Error) => void;
|
|
543
|
+
/** Auto-load on mount (default: false - user presses space) */
|
|
544
|
+
autoLoad?: boolean;
|
|
545
|
+
}
|
|
546
|
+
declare function Image({ src, width, height, style, focusedStyle, placeholderStyle, focusable, inline, placeholder, onStateChange, onError, autoLoad, }: ImageProps): React.JSX.Element;
|
|
547
|
+
|
|
512
548
|
declare function useInput(handler: (key: Key) => void, deps?: any[]): void;
|
|
513
549
|
|
|
514
550
|
interface UseFocusResult {
|
|
@@ -725,4 +761,22 @@ declare function parseAnsi(input: string): StyledSegment[];
|
|
|
725
761
|
*/
|
|
726
762
|
declare function stripAnsi(input: string): string;
|
|
727
763
|
|
|
728
|
-
|
|
764
|
+
/**
|
|
765
|
+
* Terminal capability detection for image protocols
|
|
766
|
+
*/
|
|
767
|
+
interface TerminalCapabilities {
|
|
768
|
+
name: string;
|
|
769
|
+
supportsKittyGraphics: boolean;
|
|
770
|
+
supportsIterm2Images: boolean;
|
|
771
|
+
supportsSixel: boolean;
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Detect which terminal we're running in and what image protocols it supports
|
|
775
|
+
*/
|
|
776
|
+
declare function detectTerminalCapabilities(debug?: boolean): TerminalCapabilities;
|
|
777
|
+
/**
|
|
778
|
+
* Check if the terminal supports any inline image protocol
|
|
779
|
+
*/
|
|
780
|
+
declare function supportsInlineImages(): boolean;
|
|
781
|
+
|
|
782
|
+
export { type AlertOptions, type AnsiStyle, type AppHandle, type BorderStyle, Box, type BoxProps, Button, type ButtonProps, Checkbox, type CheckboxProps, type Color, type ConfirmOptions, type DialogContextValue, DialogHost, type DialogHostProps, type DimensionValue, type FocusRegistryValue, FocusScope, type FocusScopeProps, type FocusableElement, type HexColor, Image, type ImageProps, type ImageState, Input, type InputProps, type InputType, JumpNav, type JumpNavProps, type Key, Keybind, type KeybindProps, type LayoutRect, List, type ListItemInfo, type ListProps, type MaskOptions, Menu, type MenuItem, type MenuProps, type NamedColor, Portal, type PortalProps, Progress, type ProgressProps, type RGBColor, Radio, type RadioItem, type RadioProps, type RenderOptions, ScrollView, type ScrollViewProps, Select, type SelectItem, type SelectProps, Spacer, type SpacerProps, Spinner, type SpinnerProps, type Style, type StyledSegment, type TerminalCapabilities, Text, type TextAlign, type TextProps, type Toast, ToastHost, type ToastHostProps, type ToastPosition, type ToastVariant, type UseFocusableOptions, type UseFocusableResult, type WrapMode, createMask, detectTerminalCapabilities, masks, parseAnsi, render, stripAnsi, supportsInlineImages, useApp, useDialog, useFocus, useFocusRegistry, useFocusable, useInput, useLayout, useToast };
|