@phuong-tran-redoc/document-engine-angular 0.1.4 → 0.1.5
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 +39 -3
- package/fesm2022/phuong-tran-redoc-document-engine-angular.mjs +342 -248
- package/fesm2022/phuong-tran-redoc-document-engine-angular.mjs.map +1 -1
- package/index.d.ts +44 -3
- package/package.json +5 -2
- package/src/lib/styles/_panel-surface.scss +43 -0
- package/src/lib/styles/document-editor.scss +61 -0
- package/src/lib/styles/index.scss +8 -0
- package/src/lib/styles/tokens.scss +69 -0
package/index.d.ts
CHANGED
|
@@ -746,9 +746,14 @@ declare class TiptapFloatingMenuDirective implements OnInit, OnDestroy {
|
|
|
746
746
|
*
|
|
747
747
|
* Usage:
|
|
748
748
|
* <button #trigger>Open</button>
|
|
749
|
-
* <div [
|
|
749
|
+
* <div [documentEnginePopover]="trigger" [isOpen]="isOpen">
|
|
750
750
|
* Content
|
|
751
751
|
* </div>
|
|
752
|
+
*
|
|
753
|
+
* The host is pinned `position: fixed`, so floating-ui is asked for viewport-
|
|
754
|
+
* relative coordinates (`strategy: 'fixed'`). Omitting the strategy yields
|
|
755
|
+
* offset-parent-relative numbers, which are off by the page's scroll offset
|
|
756
|
+
* once written onto a fixed element.
|
|
752
757
|
*/
|
|
753
758
|
declare class PopoverDirective implements OnChanges, AfterViewInit, OnDestroy {
|
|
754
759
|
private elRef;
|
|
@@ -756,7 +761,16 @@ declare class PopoverDirective implements OnChanges, AfterViewInit, OnDestroy {
|
|
|
756
761
|
/**
|
|
757
762
|
* The trigger element reference (ElementRef or HTMLElement)
|
|
758
763
|
*/
|
|
759
|
-
|
|
764
|
+
documentEnginePopover?: ElementRef<HTMLElement> | HTMLElement;
|
|
765
|
+
/**
|
|
766
|
+
* The trigger element reference (ElementRef or HTMLElement)
|
|
767
|
+
*
|
|
768
|
+
* @deprecated Use `documentEnginePopover`. `[popover]` collides with the
|
|
769
|
+
* native HTML popover attribute and will be removed in the next major.
|
|
770
|
+
*/
|
|
771
|
+
popover?: ElementRef<HTMLElement> | HTMLElement;
|
|
772
|
+
/** The trigger, whichever input supplied it. */
|
|
773
|
+
private get trigger();
|
|
760
774
|
/**
|
|
761
775
|
* Whether the popover is open
|
|
762
776
|
*/
|
|
@@ -784,9 +798,18 @@ declare class PopoverDirective implements OnChanges, AfterViewInit, OnDestroy {
|
|
|
784
798
|
private updateVisibility;
|
|
785
799
|
private setupFloating;
|
|
786
800
|
private _setupFloatingInternal;
|
|
801
|
+
/**
|
|
802
|
+
* Position `dropdownEl` against `triggerEl`.
|
|
803
|
+
*
|
|
804
|
+
* `strategy: 'fixed'` is required: the host binding pins this element to
|
|
805
|
+
* `position: fixed`, so the coordinates must be viewport-relative. Without it
|
|
806
|
+
* floating-ui returns offset-parent-relative numbers and the panel lands the
|
|
807
|
+
* page's scroll offset away from its trigger.
|
|
808
|
+
*/
|
|
809
|
+
private reposition;
|
|
787
810
|
private cleanup;
|
|
788
811
|
static ɵfac: i0.ɵɵFactoryDeclaration<PopoverDirective, never>;
|
|
789
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<PopoverDirective, "[popover]", never, { "popover": { "alias": "popover"; "required": false; }; "isOpen": { "alias": "isOpen"; "required": false; }; "placement": { "alias": "placement"; "required": false; }; "offset": { "alias": "offset"; "required": false; }; "padding": { "alias": "padding"; "required": false; }; }, {}, never, never, true, never>;
|
|
812
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<PopoverDirective, "[documentEnginePopover], [popover]", never, { "documentEnginePopover": { "alias": "documentEnginePopover"; "required": false; }; "popover": { "alias": "popover"; "required": false; }; "isOpen": { "alias": "isOpen"; "required": false; }; "placement": { "alias": "placement"; "required": false; }; "offset": { "alias": "offset"; "required": false; }; "padding": { "alias": "padding"; "required": false; }; }, {}, never, never, true, never>;
|
|
790
813
|
}
|
|
791
814
|
|
|
792
815
|
declare const DocumentEngineKit: Extension<DocumentEngineConfig, any>;
|
|
@@ -1277,6 +1300,7 @@ declare class CheckboxComponent implements ControlValueAccessor {
|
|
|
1277
1300
|
checked: boolean;
|
|
1278
1301
|
checkedChange: EventEmitter<boolean>;
|
|
1279
1302
|
hostClass: boolean;
|
|
1303
|
+
private readonly cdr;
|
|
1280
1304
|
private onChange;
|
|
1281
1305
|
private onTouched;
|
|
1282
1306
|
onCheckboxChange(event: Event): void;
|
|
@@ -1711,6 +1735,8 @@ declare class ToolbarBubbleMenuComponent implements AfterViewInit, OnDestroy {
|
|
|
1711
1735
|
private currentViewRef;
|
|
1712
1736
|
private currentViewId;
|
|
1713
1737
|
private currentAttributes;
|
|
1738
|
+
private cleanupAutoUpdate?;
|
|
1739
|
+
private positionTimeout?;
|
|
1714
1740
|
isVisible: boolean;
|
|
1715
1741
|
ngAfterViewInit(): void;
|
|
1716
1742
|
ngOnDestroy(): void;
|
|
@@ -1733,6 +1759,21 @@ declare class ToolbarBubbleMenuComponent implements AfterViewInit, OnDestroy {
|
|
|
1733
1759
|
private handleNavigateTo;
|
|
1734
1760
|
private handleGoBack;
|
|
1735
1761
|
private findViewConfig;
|
|
1762
|
+
/**
|
|
1763
|
+
* Anchor the bubble to its trigger with floating-ui, matching
|
|
1764
|
+
* `PopoverDirective`.
|
|
1765
|
+
*
|
|
1766
|
+
* The hand-rolled version this replaces measured the trigger exactly once, so
|
|
1767
|
+
* scrolling left the panel welded to the viewport while its target slid away.
|
|
1768
|
+
* It also had no third case: a panel that fit neither below nor above got a
|
|
1769
|
+
* negative `top`, putting its own header off the top edge of the screen.
|
|
1770
|
+
* `flip` handles the second placement and `shift` clamps the panel into the
|
|
1771
|
+
* viewport instead, so there is no unhandled case left.
|
|
1772
|
+
*
|
|
1773
|
+
* `strategy: 'fixed'` matches the `position: fixed` written below — asking for
|
|
1774
|
+
* the default `'absolute'` coordinates would offset the panel by the page's
|
|
1775
|
+
* scroll amount.
|
|
1776
|
+
*/
|
|
1736
1777
|
private positionBubble;
|
|
1737
1778
|
static ɵfac: i0.ɵɵFactoryDeclaration<ToolbarBubbleMenuComponent, never>;
|
|
1738
1779
|
static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarBubbleMenuComponent, "document-engine-toolbar-bubble-menu", never, { "editor": { "alias": "editor"; "required": false; }; "config": { "alias": "config"; "required": false; }; }, {}, never, never, true, never>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phuong-tran-redoc/document-engine-angular",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Realestatedoc (Redoc)",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"tslib": "^2.3.0",
|
|
37
37
|
"@floating-ui/dom": "^1.7.4",
|
|
38
|
-
"@phuong-tran-redoc/document-engine-core": "0.1.
|
|
38
|
+
"@phuong-tran-redoc/document-engine-core": "0.1.5"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"rxjs": "^7.5.0",
|
|
@@ -75,6 +75,9 @@
|
|
|
75
75
|
"./styles": {
|
|
76
76
|
"sass": "./src/lib/styles/index.scss"
|
|
77
77
|
},
|
|
78
|
+
"./styles/tokens": {
|
|
79
|
+
"sass": "./src/lib/styles/tokens.scss"
|
|
80
|
+
},
|
|
78
81
|
"./styles/editor-content": {
|
|
79
82
|
"sass": "./src/lib/styles/editor-content.scss"
|
|
80
83
|
},
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Floating-panel surface — the look every bubble menu / popover panel needs to
|
|
3
|
+
* be legible: an opaque background, a rule, a radius, an elevation and a
|
|
4
|
+
* stacking order.
|
|
5
|
+
*
|
|
6
|
+
* Why this is a mixin and not Tailwind utilities in a template:
|
|
7
|
+
* utilities like `bg-card`, `border-border` or `shadow-elevation-2` only exist
|
|
8
|
+
* if the HOST app's `tailwind.config.js` extends its theme with exactly those
|
|
9
|
+
* keys. The demo app happens to; a consumer with its own theme does not, and
|
|
10
|
+
* there the class names generate no rule at all — the panel then renders as
|
|
11
|
+
* transparent text floating over the page. A component library must not put
|
|
12
|
+
* that requirement on its host, so the panel carries its own surface.
|
|
13
|
+
*
|
|
14
|
+
* Every value resolves from a CSS custom property WITH a fallback, so:
|
|
15
|
+
* - a consumer that remaps the tokens gets its own theme, and
|
|
16
|
+
* - a consumer that remaps nothing still gets a usable, opaque panel.
|
|
17
|
+
*
|
|
18
|
+
* Tokens read here (all optional, all documented in docs/THEMING.md):
|
|
19
|
+
* --popover / --card panel background
|
|
20
|
+
* --popover-foreground / --card-foreground panel text
|
|
21
|
+
* --border panel rule
|
|
22
|
+
* --shadow-elevation-2 panel elevation
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/* Light-mode floors, used only when the consumer defines nothing. */
|
|
26
|
+
$de-fallback-surface: hsl(0 0% 100%) !default;
|
|
27
|
+
$de-fallback-surface-foreground: hsl(222.2 84% 4.9%) !default;
|
|
28
|
+
$de-fallback-border: hsl(214.3 31.8% 91.4%) !default;
|
|
29
|
+
|
|
30
|
+
@mixin panel-surface($z-index: 30, $radius: 0.25rem) {
|
|
31
|
+
box-sizing: border-box;
|
|
32
|
+
z-index: $z-index;
|
|
33
|
+
border-radius: $radius;
|
|
34
|
+
border: 1px solid var(--border, #{$de-fallback-border});
|
|
35
|
+
|
|
36
|
+
/* `--popover` is the semantic token for a floating surface; `--card` is the
|
|
37
|
+
* broader surface token most consumers already define, so it is the second
|
|
38
|
+
* chance before the hardcoded floor. */
|
|
39
|
+
background-color: var(--popover, var(--card, #{$de-fallback-surface}));
|
|
40
|
+
color: var(--popover-foreground, var(--card-foreground, #{$de-fallback-surface-foreground}));
|
|
41
|
+
|
|
42
|
+
box-shadow: var(--shadow-elevation-2, 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1));
|
|
43
|
+
}
|
|
@@ -7,10 +7,31 @@
|
|
|
7
7
|
color: var(--card-foreground, #000);
|
|
8
8
|
box-shadow: none;
|
|
9
9
|
|
|
10
|
+
// Participate in a parent that has a real height (a fixed-height container, a
|
|
11
|
+
// flex/grid cell) instead of only ever sizing to content. `flex: 1 1 auto` is
|
|
12
|
+
// what actually claims that height: without it this box stays content-sized as
|
|
13
|
+
// a flex item of :host, and a fixed-height container is left with a band of
|
|
14
|
+
// dead, unclickable space under the editable.
|
|
15
|
+
//
|
|
16
|
+
// `max-height: 100%` is inert when the parent's height is indefinite (a
|
|
17
|
+
// percentage against an auto height resolves to none), so an unconstrained
|
|
18
|
+
// consumer still gets a box that simply grows.
|
|
19
|
+
flex: 1 1 auto;
|
|
20
|
+
min-height: 0;
|
|
21
|
+
max-height: 100%;
|
|
22
|
+
|
|
10
23
|
&__content {
|
|
11
24
|
padding: 1rem;
|
|
12
25
|
border: 1px solid var(--border, #e5e7eb);
|
|
13
26
|
background-color: var(--card, #fff);
|
|
27
|
+
|
|
28
|
+
// Take the leftover space so the editing surface below can stretch into it.
|
|
29
|
+
// Deliberately no `overflow` here: the panels rendered inside carry selects
|
|
30
|
+
// and colour popovers, and an overflow ancestor can clip them.
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-direction: column;
|
|
33
|
+
flex: 1 1 auto;
|
|
34
|
+
min-height: 0;
|
|
14
35
|
}
|
|
15
36
|
}
|
|
16
37
|
|
|
@@ -18,3 +39,43 @@
|
|
|
18
39
|
// document-engine-toolbar ~ .document-engine-document-editor__content {
|
|
19
40
|
// border-top: 1px solid var(--border, #e5e7eb);
|
|
20
41
|
// }
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Editing-surface sizing.
|
|
45
|
+
*
|
|
46
|
+
* The library used to size the contenteditable to its content and nothing else,
|
|
47
|
+
* so an emptied editor collapsed to a single line. In a fixed-height container
|
|
48
|
+
* that left a ~28px editable inside a ~480px box that plainly looks like a text
|
|
49
|
+
* field, and clicking anywhere but that one line did nothing.
|
|
50
|
+
*
|
|
51
|
+
* Two hooks, one rule:
|
|
52
|
+
* - `--de-editor-min-height` is the floor (default `12rem`). Remap it, or set
|
|
53
|
+
* it to `0` to opt out entirely.
|
|
54
|
+
* - `flex: 1 1 auto` lets an ancestor with a real height drive the surface, so
|
|
55
|
+
* the editable fills a fixed-height container without any magic number.
|
|
56
|
+
*
|
|
57
|
+
* `.tiptap-editor` is the class `TiptapEditorDirective` puts on its host;
|
|
58
|
+
* `.tiptap` / `.ProseMirror` is the contenteditable Tiptap creates inside it.
|
|
59
|
+
*/
|
|
60
|
+
.tiptap-editor {
|
|
61
|
+
display: flex;
|
|
62
|
+
flex-direction: column;
|
|
63
|
+
flex: 1 1 auto;
|
|
64
|
+
min-height: 0;
|
|
65
|
+
|
|
66
|
+
// The editing surface is the scroll container. Without this, `max-height: 100%`
|
|
67
|
+
// above caps the wrapper while nothing scrolls, so a long document paints
|
|
68
|
+
// straight through the bottom of a fixed-height container and over whatever
|
|
69
|
+
// follows it on the page.
|
|
70
|
+
//
|
|
71
|
+
// Safe to put overflow here: the floating panels are rendered inside
|
|
72
|
+
// `document-engine-toolbar`, a sibling of the content box, never a descendant
|
|
73
|
+
// of this element — so there is nothing of theirs for this to clip.
|
|
74
|
+
overflow-y: auto;
|
|
75
|
+
|
|
76
|
+
> .tiptap,
|
|
77
|
+
> .ProseMirror {
|
|
78
|
+
flex: 1 1 auto;
|
|
79
|
+
min-height: var(--de-editor-min-height, 12rem);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -23,8 +23,16 @@
|
|
|
23
23
|
*
|
|
24
24
|
* All styles use class/element selectors and CSS-variable-driven values, so you
|
|
25
25
|
* can also override them with your own CSS without importing these files.
|
|
26
|
+
*
|
|
27
|
+
* Theming: this barrel also ships zero-specificity DEFAULTS for every custom
|
|
28
|
+
* property the library reads (`_tokens.scss`, emitted on `:where(:root)`), so it
|
|
29
|
+
* looks right out of the box and any token you declare yourself wins without a
|
|
30
|
+
* specificity fight. The full list is in `docs/THEMING.md`.
|
|
26
31
|
*/
|
|
27
32
|
|
|
33
|
+
// Token defaults first, so they sit at the top of the emitted sheet.
|
|
34
|
+
@use 'tokens';
|
|
35
|
+
|
|
28
36
|
@forward 'icon';
|
|
29
37
|
@forward 'button';
|
|
30
38
|
@forward 'toolbar';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default values for every CSS custom property the library's CSS reads.
|
|
3
|
+
*
|
|
4
|
+
* The library's stylesheets are token-driven: they paint with `var(--border)`,
|
|
5
|
+
* `var(--popover)`, `var(--foreground)` and friends. Historically the library
|
|
6
|
+
* *consumed* those tokens without ever defining or documenting them, so a
|
|
7
|
+
* consumer that had not happened to declare the same shadcn-style token set got
|
|
8
|
+
* panels with no background and text with no colour.
|
|
9
|
+
*
|
|
10
|
+
* This file closes that hole: it declares a light-mode default for every token,
|
|
11
|
+
* so importing the chrome barrel is enough to get a working look with zero
|
|
12
|
+
* theming. See `docs/THEMING.md` for the full contract.
|
|
13
|
+
*
|
|
14
|
+
* ## Why `:where(:root)`
|
|
15
|
+
*
|
|
16
|
+
* `:where()` contributes **zero specificity**, so ANY declaration a consumer
|
|
17
|
+
* writes — `:root { --border: … }`, `.dark { --border: … }`, an inline style,
|
|
18
|
+
* a `[data-theme]` block — beats these defaults regardless of source order.
|
|
19
|
+
* They are a floor, never a fight.
|
|
20
|
+
*
|
|
21
|
+
* ## Rescoping
|
|
22
|
+
*
|
|
23
|
+
* The defaults are also exposed as a mixin, so you can plant a fresh set on any
|
|
24
|
+
* container — e.g. an embedded editor that must ignore the surrounding theme:
|
|
25
|
+
*
|
|
26
|
+
* @use '@phuong-tran-redoc/document-engine-angular/styles/tokens' as de-tokens;
|
|
27
|
+
* .my-isolated-editor { @include de-tokens.token-defaults; }
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
@mixin token-defaults {
|
|
31
|
+
/* --- Surfaces --- */
|
|
32
|
+
--background: hsl(0 0% 100%);
|
|
33
|
+
--foreground: hsl(222.2 84% 4.9%);
|
|
34
|
+
--card: hsl(0 0% 100%);
|
|
35
|
+
--card-foreground: hsl(222.2 84% 4.9%);
|
|
36
|
+
--popover: hsl(0 0% 100%);
|
|
37
|
+
--popover-foreground: hsl(222.2 84% 4.9%);
|
|
38
|
+
|
|
39
|
+
/* --- Accents & state --- */
|
|
40
|
+
--primary: hsl(222.2 47.4% 11.2%);
|
|
41
|
+
--primary-foreground: hsl(210 40% 98%);
|
|
42
|
+
--secondary: hsl(210 40% 96.1%);
|
|
43
|
+
--secondary-foreground: hsl(222.2 47.4% 11.2%);
|
|
44
|
+
--muted: hsl(210 40% 96.1%);
|
|
45
|
+
--muted-foreground: hsl(215.4 16.3% 46.9%);
|
|
46
|
+
--accent: hsl(210 40% 96.1%);
|
|
47
|
+
--accent-foreground: hsl(222.2 47.4% 11.2%);
|
|
48
|
+
--destructive: hsl(0 84.2% 60.2%);
|
|
49
|
+
--destructive-foreground: hsl(210 40% 98%);
|
|
50
|
+
|
|
51
|
+
/* --- Lines --- */
|
|
52
|
+
--border: hsl(214.3 31.8% 91.4%);
|
|
53
|
+
--input: hsl(214.3 31.8% 91.4%);
|
|
54
|
+
--ring: hsl(222.2 84% 4.9%);
|
|
55
|
+
|
|
56
|
+
/* --- Elevation ---
|
|
57
|
+
* Consumed by panels, dropdowns and inputs. Undefined, `box-shadow: var(…)`
|
|
58
|
+
* resolves to nothing, which is how floating panels lost their elevation. */
|
|
59
|
+
--shadow-elevation-1: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
60
|
+
--shadow-elevation-2: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1);
|
|
61
|
+
--shadow-elevation-3: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
|
|
62
|
+
|
|
63
|
+
/* --- Editing surface sizing (see docs/THEMING.md#sizing) --- */
|
|
64
|
+
--de-editor-min-height: 12rem;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
:where(:root) {
|
|
68
|
+
@include token-defaults;
|
|
69
|
+
}
|