@surrealdb/ui 1.2.12 → 1.2.13

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.
Files changed (93) hide show
  1. package/.claude/launch.json +17 -0
  2. package/.oxfmtrc.json +27 -0
  3. package/.oxlintrc.json +23 -0
  4. package/.zed/settings.json +34 -34
  5. package/AGENTS.md +21 -19
  6. package/README.md +15 -10
  7. package/dist/ui.css +1 -1
  8. package/dist/ui.d.ts +234 -1
  9. package/dist/ui.js +8217 -7329
  10. package/dist/ui.js.map +1 -1
  11. package/doc/code-style.md +264 -0
  12. package/doc/stacker-plan.md +219 -0
  13. package/package.json +119 -116
  14. package/res/_mixins.scss +15 -11
  15. package/tests/_setup/e2e-helpers.tsx +85 -85
  16. package/tests/_setup/portable-stories.ts +11 -10
  17. package/tests/e2e/MarkdownEditor/content-blocks.test.tsx +140 -139
  18. package/tests/e2e/MarkdownEditor/edits.test.tsx +101 -100
  19. package/tests/e2e/MarkdownEditor/heading-fold.test.tsx +35 -34
  20. package/tests/e2e/MarkdownEditor/hybrid-widgets.test.tsx +178 -177
  21. package/tests/e2e/MarkdownEditor/image-on-image.test.tsx +50 -49
  22. package/tests/e2e/MarkdownEditor/jsx-block-content.test.tsx +195 -194
  23. package/tests/e2e/MarkdownEditor/jsx-highlight.test.tsx +47 -46
  24. package/tests/e2e/MarkdownEditor/jsx-inline-badges.test.tsx +35 -34
  25. package/tests/e2e/MarkdownEditor/jsx-inline-click.test.tsx +39 -38
  26. package/tests/e2e/MarkdownEditor/jsx-selection.test.tsx +28 -27
  27. package/tests/e2e/MarkdownEditor/link-placeholder.test.tsx +49 -48
  28. package/tests/e2e/MarkdownEditor/media-align.test.tsx +40 -39
  29. package/tests/e2e/MarkdownEditor/media-edit.test.tsx +49 -48
  30. package/tests/e2e/MarkdownEditor/media-sizing.test.tsx +108 -107
  31. package/tests/e2e/MarkdownEditor/modes.test.tsx +79 -78
  32. package/tests/e2e/MarkdownEditor/onimage-parity.test.tsx +29 -28
  33. package/tests/e2e/MarkdownEditor/regressions.test.tsx +194 -193
  34. package/tests/e2e/MarkdownEditor/slash-commands.test.tsx +81 -80
  35. package/tests/e2e/MarkdownEditor/table-click.test.tsx +36 -35
  36. package/tests/e2e/MarkdownEditor/table-controls.test.tsx +44 -43
  37. package/tests/e2e/MarkdownEditor/table-format.test.tsx +28 -27
  38. package/tests/e2e/MarkdownEditor/undo-redo.test.tsx +22 -21
  39. package/tests/e2e/MarkdownViewer/parity.test.tsx +144 -143
  40. package/tests/e2e/MarkdownViewer/render.test.tsx +20 -19
  41. package/tests/e2e/Stacker/stacker.test.tsx +304 -0
  42. package/tests/unit/Editor/helpers.test.ts +26 -26
  43. package/tests/unit/MarkdownConformance/error-isolation.test.tsx +26 -25
  44. package/tests/unit/MarkdownConformance/indentation.test.tsx +20 -19
  45. package/tests/unit/MarkdownConformance/inline-code-fuzz.test.tsx +255 -0
  46. package/tests/unit/MarkdownConformance/jsx-attributes.test.tsx +39 -38
  47. package/tests/unit/MarkdownConformance/jsx-fuzz.test.tsx +122 -122
  48. package/tests/unit/MarkdownConformance/links.test.tsx +78 -54
  49. package/tests/unit/MarkdownConformance/render-helpers.tsx +60 -60
  50. package/tests/unit/MarkdownEditor/code-info.test.ts +58 -58
  51. package/tests/unit/MarkdownEditor/decorations.test.ts +423 -421
  52. package/tests/unit/MarkdownEditor/editor-ready.test.ts +22 -22
  53. package/tests/unit/MarkdownEditor/html-descriptors.test.ts +70 -70
  54. package/tests/unit/MarkdownEditor/indented-fence.test.ts +80 -80
  55. package/tests/unit/MarkdownEditor/jsx-attr-scan.test.ts +87 -87
  56. package/tests/unit/MarkdownEditor/jsx-block-widget.test.ts +51 -51
  57. package/tests/unit/MarkdownEditor/jsx-tag-grammar.test.ts +63 -63
  58. package/tests/unit/MarkdownEditor/list-indent.test.ts +67 -67
  59. package/tests/unit/MarkdownEditor/slash-commands.test.ts +150 -150
  60. package/tests/unit/MarkdownEditor/table-format.test.ts +67 -67
  61. package/tests/unit/MarkdownEditor/table.test.ts +96 -96
  62. package/tests/unit/MarkdownEditor/triggers.test.ts +167 -167
  63. package/tests/unit/MarkdownEditor/widget-store.test.ts +90 -90
  64. package/tests/unit/MarkdownViewer/callout.test.tsx +42 -42
  65. package/tests/unit/MarkdownViewer/code-highlight.test.tsx +41 -41
  66. package/tests/unit/MarkdownViewer/code-title.test.tsx +45 -45
  67. package/tests/unit/MarkdownViewer/features.test.tsx +129 -129
  68. package/tests/unit/MarkdownViewer/headings.test.tsx +28 -28
  69. package/tests/unit/MarkdownViewer/indented-jsx-children.test.tsx +53 -53
  70. package/tests/unit/MarkdownViewer/jsx-block-nesting.test.tsx +137 -137
  71. package/tests/unit/MarkdownViewer/jsx.test.tsx +188 -188
  72. package/tests/unit/MarkdownViewer/list-bullets.test.tsx +31 -31
  73. package/tests/unit/MarkdownViewer/list-code.test.tsx +45 -45
  74. package/tests/unit/MarkdownViewer/preserve-newlines.test.tsx +109 -109
  75. package/tests/unit/MarkdownViewer/read-time.test.ts +13 -13
  76. package/tests/unit/MarkdownViewer/renderers.test.tsx +75 -75
  77. package/tests/unit/MarkdownViewer/runnable.test.tsx +51 -51
  78. package/tests/unit/MarkdownViewer/ssr.test.tsx +56 -55
  79. package/tests/unit/MarkdownViewer/syntax-highlighting.test.tsx +43 -42
  80. package/tests/unit/MarkdownViewer/tabs-fenced-code.test.tsx +120 -120
  81. package/tests/unit/MarkdownViewer/tabs.test.tsx +83 -82
  82. package/tests/unit/Stacker/drag.test.ts +21 -0
  83. package/tests/unit/Stacker/helpers.test.ts +105 -0
  84. package/tests/unit/Stacker/reducer.test.ts +107 -0
  85. package/tools/duplicate-vector-mappings.json +141 -141
  86. package/tools/glass-export-overrides.json +6 -6
  87. package/tools/icon-parser.ts +41 -40
  88. package/tools/integration-gradient-exports.json +55 -55
  89. package/tools/picto-compare.ts +32 -32
  90. package/tools/picto-merge-urls.ts +19 -19
  91. package/tools/picto-sync.ts +543 -543
  92. package/tools/picto-verify-gradients.ts +50 -50
  93. package/tools/vector-export-nodes.json +975 -975
package/dist/ui.d.ts CHANGED
@@ -6,6 +6,7 @@ import { ButtonProps } from '@mantine/core';
6
6
  import { CodeProps } from '@mantine/core';
7
7
  import { Command } from '@codemirror/view';
8
8
  import { ComponentType } from 'react';
9
+ import { CSSProperties } from 'react';
9
10
  import { default as default_2 } from 'github-slugger';
10
11
  import { EditorSelection } from '@codemirror/state';
11
12
  import { EditorState } from '@codemirror/state';
@@ -24,8 +25,10 @@ import { MantineColor } from '@mantine/core';
24
25
  import { MantineColorScheme } from '@mantine/core';
25
26
  import { MantineFontSize } from '@mantine/core';
26
27
  import { MantineSize } from '@mantine/core';
28
+ import { MantineSpacing } from '@mantine/core';
27
29
  import { MantineThemeOverride } from '@mantine/core';
28
30
  import { PaperProps } from '@mantine/core';
31
+ import * as portals from 'react-reverse-portal';
29
32
  import { PropsWithChildren } from 'react';
30
33
  import { ReactElement } from 'react';
31
34
  import { ReactNode } from 'react';
@@ -413,7 +416,6 @@ export declare interface CodeEditorProps extends BoxProps {
413
416
  autoFocus?: boolean;
414
417
  innerProps?: BoxProps;
415
418
  withPadding?: boolean;
416
- ref?: RefObject<EditorView>;
417
419
  }
418
420
 
419
421
  /** React component keyed by lower-cased fenced-code info string. */
@@ -464,6 +466,12 @@ export declare interface ConfirmOptions<T> {
464
466
  onConfirm: (value: T) => void;
465
467
  }
466
468
 
469
+ /**
470
+ * Open ephemeral overlays that would be covered by `topId` — they should close
471
+ * instead of staying mounted behind the new top.
472
+ */
473
+ export declare function coveredEphemeral(items: StackerItem[], topId: string): StackerItem[];
474
+
467
475
  /**
468
476
  * Get a cached style highlighter for the given color scheme
469
477
  */
@@ -533,6 +541,77 @@ export declare interface DiagramNode {
533
541
  children: RailroadNode[];
534
542
  }
535
543
 
544
+ export declare const Drawer: DrawerCompound;
545
+
546
+ declare function DrawerBody({ lane, children, className, ...rest }: DrawerBodyProps): ReactNode;
547
+
548
+ export declare interface DrawerBodyProps extends Omit<BoxProps, "children"> {
549
+ lane: string;
550
+ children: ReactNode;
551
+ }
552
+
553
+ export declare interface DrawerCompound {
554
+ (props: DrawerProps): ReactNode;
555
+ Lanes: typeof DrawerLanes;
556
+ Lane: typeof DrawerLane;
557
+ Body: typeof DrawerBody;
558
+ }
559
+
560
+ export declare interface DrawerConfig {
561
+ lanes: string[];
562
+ defaultCurrentLane: string;
563
+ pinnedLane?: string;
564
+ }
565
+
566
+ /**
567
+ * Depth transform for a drawer sheet covered by `depth` sheets above it. The
568
+ * transform-origin sits at the free edge and the sheet is pushed outward, so
569
+ * scaling never eats the peek strip and lower sheets stick out from behind.
570
+ */
571
+ export declare function drawerDepthStyle(side: StackerSide, depth: number): CSSProperties;
572
+
573
+ declare function DrawerLane({ lane, label, icon, className, ...rest }: DrawerLaneProps): ReactNode;
574
+
575
+ export declare interface DrawerLaneProps extends Omit<BoxProps, "children"> {
576
+ lane: string;
577
+ label: string;
578
+ icon: string;
579
+ children?: ReactNode;
580
+ }
581
+
582
+ declare function DrawerLanes({ children, className, ...rest }: DrawerLanesProps): ReactNode;
583
+
584
+ export declare interface DrawerLanesProps extends Omit<BoxProps, "children"> {
585
+ children: ReactNode;
586
+ }
587
+
588
+ export declare interface DrawerProps {
589
+ children: ReactNode;
590
+ }
591
+
592
+ export declare function DrawerProvider({ children, state }: DrawerProviderProps): ReactNode;
593
+
594
+ export declare interface DrawerProviderProps {
595
+ children: ReactNode;
596
+ state: DrawerState;
597
+ }
598
+
599
+ export declare interface DrawerState {
600
+ open: boolean;
601
+ currentLane: string;
602
+ activeLane: string;
603
+ progress: number;
604
+ dragging: boolean;
605
+ translate: number;
606
+ expandedHeight: number;
607
+ maxTranslate: number;
608
+ config: DrawerConfig;
609
+ dragRef: (node: HTMLDivElement | null) => void;
610
+ selectLane: (lane: string) => void;
611
+ collapse: () => void;
612
+ portal: portals.HtmlPortalNode;
613
+ }
614
+
536
615
  declare type DynamicNode<T> = ReactNode | ((value: T) => ReactNode);
537
616
 
538
617
  export declare interface EditorController {
@@ -2658,6 +2737,19 @@ export declare function resolveHeadingId(node: SyntaxNode, source: MarkdownSourc
2658
2737
  */
2659
2738
  export declare function resolveImageDescriptor(url: string, alt: string, title?: string, onResolveMedia?: (node: MediaDescriptor) => MediaDescriptor): MediaDescriptor;
2660
2739
 
2740
+ /**
2741
+ * Resolve overlay kind from an explicit variant hint or the viewport.
2742
+ */
2743
+ export declare function resolveKind(variant: StackerKind | undefined, isMobile: boolean): StackerKind;
2744
+
2745
+ /**
2746
+ * Live render kind for the current stack. Empty stacks render nothing. Otherwise:
2747
+ * stack-level `forcedKind` (from the founding overlay's `variant`) → first item's
2748
+ * `variant` → viewport. `forcedKind` keeps a forced kind after the founding
2749
+ * overlay is removed (e.g. ephemeral covered by a push).
2750
+ */
2751
+ export declare function resolveLiveKind(items: StackerItem[], isMobile: boolean, forcedKind?: StackerKind | null): StackerKind | null;
2752
+
2661
2753
  /** Normalise a component registration into its `{ component, block, preserveNewlines }` form. */
2662
2754
  export declare function resolveMarkdownComponent(def: MarkdownComponentDef | undefined): MarkdownComponentConfig | undefined;
2663
2755
 
@@ -2998,6 +3090,12 @@ export declare const setMarkdownEditorReady: StateEffectType<boolean>;
2998
3090
  */
2999
3091
  export declare const setMarkdownMode: StateEffectType<MarkdownEditMode>;
3000
3092
 
3093
+ /**
3094
+ * Decide whether a released drag should dismiss the drawer: either a fast flick
3095
+ * towards the edge, or dragged past halfway.
3096
+ */
3097
+ export declare function shouldDismiss(closeAmount: number, extent: number, towardsVelocity: number): boolean;
3098
+
3001
3099
  export declare function Since({ v, prefix, ...props }: SinceProps): ReactNode;
3002
3100
 
3003
3101
  export declare interface SinceProps extends Omit<BadgeProps, "children"> {
@@ -3116,6 +3214,128 @@ export declare interface SpinnerProps extends BoxProps {
3116
3214
  title?: string;
3117
3215
  }
3118
3216
 
3217
+ export declare const STACKER_INITIAL_STATE: StackerState;
3218
+
3219
+ export declare type StackerAction = {
3220
+ type: "OPEN";
3221
+ item: StackerItem;
3222
+ } | {
3223
+ type: "CLOSE";
3224
+ id: string;
3225
+ } | {
3226
+ type: "CLOSE_ALL";
3227
+ } | {
3228
+ type: "REMOVE";
3229
+ id: string;
3230
+ } | {
3231
+ type: "UPDATE";
3232
+ id: string;
3233
+ patch: Partial<StackerSettings>;
3234
+ };
3235
+
3236
+ /** Value exposed by {@link useStacker}. */
3237
+ export declare interface StackerContextValue {
3238
+ /** Push an overlay onto the stack. Returns the overlay id. */
3239
+ open: (settings?: StackerSettings) => string;
3240
+ /** Close an overlay by id, or the top overlay when the id is omitted. */
3241
+ close: (id?: string) => void;
3242
+ /** Close every open overlay. */
3243
+ closeAll: () => void;
3244
+ /** Merge new settings into an overlay on the stack. */
3245
+ update: (id: string, patch: Partial<StackerSettings>) => void;
3246
+ /** Current stack, ordered bottom-to-top. */
3247
+ stack: StackerItem[];
3248
+ /** Live render kind from the viewport and first stack item, or null when empty. */
3249
+ kind: StackerKind | null;
3250
+ }
3251
+
3252
+ /** A single entry on the stack. */
3253
+ export declare interface StackerItem {
3254
+ id: string;
3255
+ /** False while the overlay plays its exit transition before removal. */
3256
+ opened: boolean;
3257
+ settings: StackerSettings;
3258
+ }
3259
+
3260
+ /** How an overlay is rendered: a centered modal or an edge-anchored drawer. */
3261
+ export declare type StackerKind = "modal" | "drawer";
3262
+
3263
+ /**
3264
+ * Provides {@link useStacker}. Overlays render as modals on desktop and drawers
3265
+ * on mobile (or the forced `variant`), stack like Mantine's modal manager, and
3266
+ * the page content scales back slightly while a drawer stack is open.
3267
+ */
3268
+ export declare function StackerProvider({ children, mobileQuery, zIndex, }: StackerProviderProps): ReactNode;
3269
+
3270
+ export declare interface StackerProviderProps {
3271
+ children?: ReactNode;
3272
+ /** Viewport query selecting the drawer kind. @default "(max-width: 48em)" */
3273
+ mobileQuery?: string;
3274
+ /** Base z-index for the stack. @default 200 */
3275
+ zIndex?: number;
3276
+ }
3277
+
3278
+ /**
3279
+ * Pure state transitions for the stack. Closing an overlay flips its `opened`
3280
+ * flag (so it can play an exit transition); a later `REMOVE` drops it once the
3281
+ * transition finishes.
3282
+ */
3283
+ export declare function stackerReducer(state: StackerState, action: StackerAction): StackerState;
3284
+
3285
+ /** Options accepted by {@link StackerContextValue.open}. */
3286
+ export declare interface StackerSettings {
3287
+ /** Explicit id. Defaults to a random id. Opening an id already on the stack is a no-op. */
3288
+ id?: string;
3289
+ /** Heading rendered in the overlay header. */
3290
+ title?: ReactNode;
3291
+ /** Secondary text rendered underneath the title. */
3292
+ subtitle?: ReactNode;
3293
+ /** Overlay body content. */
3294
+ children?: ReactNode;
3295
+ /**
3296
+ * Force this overlay kind instead of choosing from the viewport. When set on
3297
+ * the founding overlay of a stack, the kind is remembered for the whole stack
3298
+ * even if that overlay is later removed (e.g. ephemeral). Later items' hints
3299
+ * are ignored while the stack is non-empty.
3300
+ */
3301
+ variant?: StackerKind;
3302
+ /** Edge the drawer is anchored to. Ignored for modals. @default "right" */
3303
+ side?: StackerSide;
3304
+ /** Allow dragging the drawer towards its edge to dismiss it. Ignored for modals. @default false */
3305
+ draggable?: boolean;
3306
+ /** Content area size — modal width or drawer extent. Defaults: modal `"lg"`, drawer `"md"`. */
3307
+ size?: MantineSize | (string & {}) | number;
3308
+ /** Header/body padding. @default "xl" */
3309
+ padding?: MantineSpacing;
3310
+ /** Render the header close button. @default true */
3311
+ withCloseButton?: boolean;
3312
+ /** Close this overlay with Escape while it is on top. @default true */
3313
+ closeOnEscape?: boolean;
3314
+ /** Close this overlay by clicking the scrim while it is on top. @default true */
3315
+ closeOnClickOutside?: boolean;
3316
+ /**
3317
+ * When true, this overlay is closed (and removed after its exit) as soon as
3318
+ * another overlay is pushed on top of it — it never stays covered/peeking.
3319
+ * @default false
3320
+ */
3321
+ ephemeral?: boolean;
3322
+ /** Called when the overlay begins closing. */
3323
+ onClose?: () => void;
3324
+ }
3325
+
3326
+ /** Edge a drawer is anchored to. */
3327
+ export declare type StackerSide = "left" | "right" | "top" | "bottom";
3328
+
3329
+ export declare interface StackerState {
3330
+ /**
3331
+ * Forced kind from the stack-founding overlay's `variant`. Survives removal of
3332
+ * that overlay (e.g. ephemeral covered) until the stack is empty.
3333
+ */
3334
+ forcedKind: StackerKind | null;
3335
+ /** Stack entries, ordered bottom-to-top. `opened: false` = playing exit. */
3336
+ items: StackerItem[];
3337
+ }
3338
+
3119
3339
  export declare type StateFields = {
3120
3340
  [prop: string]: StateField<any>;
3121
3341
  };
@@ -3221,6 +3441,9 @@ export declare interface ThemedImageProps extends ImageProps {
3221
3441
  darkSrc?: string;
3222
3442
  }
3223
3443
 
3444
+ /** The top-most open item, or undefined when nothing is open. */
3445
+ export declare function topOpened(items: StackerItem[]): StackerItem | undefined;
3446
+
3224
3447
  /** Trim `{#id}` from the end of a heading source range (returns new exclusive `titleTo`). */
3225
3448
  export declare function trimCustomHeadingIdFromRange(source: {
3226
3449
  slice(from: number, to: number): string;
@@ -3234,6 +3457,10 @@ export declare function trimCustomHeadingIdFromRange(source: {
3234
3457
  */
3235
3458
  export declare function useConfirmation<T = void>(options: ConfirmOptions<T>): (value?: T) => void;
3236
3459
 
3460
+ export declare function useDrawer(config: DrawerConfig): DrawerState;
3461
+
3462
+ export declare function useDrawerState(): DrawerState;
3463
+
3237
3464
  export declare function useEditor(options?: EditorOptions): EditorController;
3238
3465
 
3239
3466
  /**
@@ -3285,6 +3512,12 @@ export declare function useSort<T = DefaultSort>(options?: SortOptions<T>): Sort
3285
3512
  */
3286
3513
  export declare function useStable<T extends AnyFn>(callback: T): T;
3287
3514
 
3515
+ /**
3516
+ * Access the nearest {@link StackerProvider}. Multiple providers can be nested;
3517
+ * each hook call resolves to the closest one.
3518
+ */
3519
+ export declare function useStacker(): StackerContextValue;
3520
+
3288
3521
  /**
3289
3522
  * A state used to track an active/inactive switch state (boolean)
3290
3523
  *