FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat(sanity): align portabletext with react v6.2.0 by osnoser1 · Pull Request #44 · limitless-angular/limitless-angular · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .md  (2) .ts  (20) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
2 changes: 1 addition & 1 deletion packages/sanity/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ We welcome contributions! Check our [Contributing Guide](CONTRIBUTING.md) for de

## Credits

Adapted from [@portabletext/react v3.1.0](https://github.com/portabletext/react-portabletext/blob/main/CHANGELOG.md#310-2024-05-28) which provided the
Adapted from [@portabletext/react v6.2.0](https://github.com/portabletext/react-portabletext/releases/tag/v6.2.0) which provided the
vast majority of node rendering logic.

## License
Expand Down
40 changes: 39 additions & 1 deletion packages/sanity/portabletext/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Render [Portable Text](https://portabletext.org/) with Angular.

Based on [@portabletext/react v3.1.0](https://github.com/portabletext/react-portabletext/blob/main/CHANGELOG.md#310-2024-05-28).
Based on [@portabletext/react v6.2.0](https://github.com/portabletext/react-portabletext/releases/tag/v6.2.0).

## Demo

Expand All @@ -17,6 +17,7 @@ You can also see the example project in the monorepo: [`apps/sanity-example`](/a

- [Installation](#installation)
- [Basic usage](#basic-usage)
- [Inputs](#inputs)
- [Styling](#styling-the-output)
- [Customizing components](#customizing-components)
- [Available components](#available-components)
Expand All @@ -26,6 +27,7 @@ You can also see the example project in the monorepo: [`apps/sanity-example`](/a
- [list](#list)
- [listItem](#listitem)
- [hardBreak](#hardbreak)
- [Fallback components](#fallback-components)
- [Architecture Documentation](./ARCHITECTURE.md)

## Installation
Expand Down Expand Up @@ -57,6 +59,15 @@ export class YourComponent {
}
```

## Inputs

The Angular component follows the `@portabletext/react` prop contract with Angular inputs:

- `value`: a single Portable Text node, an array of nodes, `null`, or `undefined`. `null` and `undefined` render nothing.
- `components`: optional Angular component overrides.
- `onMissingComponent`: warning handler, or `false` to disable warnings.
- `listNestingMode`: optional `ListNestMode` (`html` by default, or `direct`).

## Styling the output

The rendered HTML does not have any styling applied, so you will either render a parent container with a class name you can target in your CSS, or pass [custom components](#customizing-components) if you want to control the direct markup and CSS of each element.
Expand Down Expand Up @@ -715,6 +726,33 @@ Component to use for rendering "hard breaks", eg `\n` inside of text spans.

Will by default render a `<br />`. Pass `false` to render as-is (`\n`)

### Fallback components

You can also override the fallback components used when no renderer is registered:

- `unknownType`
- `unknownMark`
- `unknownBlockStyle`
- `unknownList`
- `unknownListItem`

For example:

```typescript
import { Component } from '@angular/core';
import { PortableTextComponents, PortableTextTypeComponent } from '@limitless-angular/sanity/portabletext';

@Component({
selector: 'div',
template: `Unknown type: {{ value()._type }}`,
})
export class UnknownTypeComponent extends PortableTextTypeComponent {}

export const components: PortableTextComponents = {
unknownType: UnknownTypeComponent,
};
```

## Rendering Plain Text

This module also exports a function (toPlainText()) that will render one or more Portable Text blocks as plain text. This is helpful in cases where formatted text is not supported, or you need to process the raw text value.
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { RenderNode } from '../directives/render-node.directive';
<ng-container
[renderNode]="child"
[isInline]="child.isInline ?? isInline ?? true"
[index]="index"
[index]="child.index ?? index"
/>
}
</ng-template>`,
Expand All @@ -30,7 +30,7 @@ import { RenderNode } from '../directives/render-node.directive';
export class ChildrenComponent {
template = viewChild.required<
TemplateRef<{
children: (TypedObject & { isInline?: boolean })[];
children: (TypedObject & { index?: number; isInline?: boolean })[];
isInline?: boolean;
}>
>(TemplateRef);
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
import { PortableTextComponents } from '../../types';
/* eslint-disable @angular-eslint/component-selector */
/* eslint-disable @angular-eslint/component-class-suffix */
import { Component } from '@angular/core';
import { PortableTextAngularComponents } from '../../types';
import { defaultBlockStyles } from './blocks';
import { defaultLists } from './list';
import { DefaultListItem } from './list';
import { defaultMarks } from './marks';
import {
DefaultUnknownType,
DefaultUnknownMark,
DefaultUnknownBlockStyle,
DefaultUnknownList,
DefaultUnknownListItem,
} from './unknown';
export const defaultComponents: PortableTextComponents = {

@Component({
selector: 'br',
template: '',
})
export class DefaultHardBreak {}

export const defaultComponents: PortableTextAngularComponents = {
types: {},

block: defaultBlockStyles,
marks: defaultMarks,
list: defaultLists,
listItem: DefaultListItem,
hardBreak: DefaultHardBreak,

unknownType: DefaultUnknownType,
unknownMark: DefaultUnknownMark,
unknownList: DefaultUnknownList,
unknownListItem: DefaultUnknownListItem,
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
/* eslint-disable @angular-eslint/component-selector */
/* eslint-disable @angular-eslint/component-class-suffix */
import { Component } from '@angular/core';
import { Component, computed } from '@angular/core';
import {
PortableTextBlockComponent,
PortableTextListComponent,
PortableTextListItemComponent,
PortableTextMarkComponent,
PortableTextTypeComponent,
} from '../../directives/portable-text-directives';
import { unknownTypeWarning } from '../../warnings';

const template = '<ng-container #children />';

@Component({
selector: 'span',
template: `{{ warning() }}`,
host: { '[style.display]': '"none"' },
})
export class DefaultUnknownType extends PortableTextTypeComponent {
protected readonly warning = computed(() =>
unknownTypeWarning(this.value()._type),
);
}

@Component({
selector: 'span,span[data-unknown="true"]',
template,
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import {
} from '@angular/core';
import { NgTemplateOutlet } from '@angular/common';

import { LIST_NEST_MODE_HTML, nestLists } from '@portabletext/toolkit';
import {
LIST_NEST_MODE_HTML,
nestLists,
type ToolkitListNestMode,
} from '@portabletext/toolkit';
import {
ArbitraryTypedObject,
PortableTextBlock,
Expand All @@ -22,6 +26,7 @@ import {

import {
MissingComponentHandler,
PortableTextAngularComponents,
PortableTextComponents,
RenderNodeContext,
} from '../types';
Expand Down Expand Up @@ -66,16 +71,16 @@ import { TextComponent } from './text.component';
}
</ng-template>

<ng-template #unknownTmpl let-node="node" let-isInline="isInline">
<ng-template
#unknownTmpl
let-node="node"
let-isInline="isInline"
let-warning="warning"
>
@if (isInline) {
<span style="display: none" aria-hidden="true">{{
'Unknown block type: ' + node._type
}}</span>
<span style="display: none">{{ warning }}</span>
} @else {
<!-- display: inline -->
<div style="display: none" aria-hidden="true">{{
'Unknown block type: ' + node._type
}}</div>
<div style="display: none">{{ warning }}</div>
}
</ng-template>
`,
Expand All @@ -95,20 +100,26 @@ export class PortableTextComponent<
* The Portable Text content to render.
* Can be a single block or an array of blocks.
*/
value = input.required<B | B[]>();
value = input.required<B | B[] | null | undefined>();

/**
* Custom components to override the default rendering.
* @see PortableTextComponents
*/
componentOverrides = input<Partial<PortableTextComponents>>(
{},
componentOverrides = input<PortableTextComponents<B> | undefined>(
undefined,
// eslint-disable-next-line @angular-eslint/no-input-rename
{ alias: 'components' },
);

/**
* Template reference for rendering nodes
* Determines whether lists are nested inside list items (`html`) or as a
* direct child of another list (`direct`).
*/
listNestingMode = input<ToolkitListNestMode>();

/**
* @internal Template reference for rendering nodes.
*/
renderNode =
viewChild.required<TemplateRef<RenderNodeContext<B>>>('renderNode');
Expand All @@ -126,17 +137,20 @@ export class PortableTextComponent<
/**
* Merged components from default and overrides
*/
availableComponents = computed(() =>
mergeComponents(defaultComponents, this.componentOverrides()),
);
availableComponents = computed<PortableTextAngularComponents<B>>(() => {
const overrides = this.componentOverrides();
return overrides
? mergeComponents(defaultComponents, overrides)
: (defaultComponents as PortableTextAngularComponents<B>);
});

/**
* Template reference for rendering unknown block types
*/
unknownTmpl =
viewChild.required<TemplateRef<{ node: TypedObject; isInline: boolean }>>(
'unknownTmpl',
);
viewChild.required<
TemplateRef<{ node: TypedObject; isInline: boolean; warning: string }>
>('unknownTmpl');

/**
* Creates a template for rendering children
Expand All @@ -160,8 +174,21 @@ export class PortableTextComponent<
* Handles both single blocks and arrays of blocks
*/
nestedBlocks = computed(() => {
const blocks = Array.isArray(this.value()) ? this.value() : [this.value()];
return nestLists(blocks as TypedObject[], LIST_NEST_MODE_HTML);
const input = this.value();
let blocks: B[];

if (Array.isArray(input)) {
blocks = input;
} else if (input == null) {
blocks = [];
} else {
blocks = [input];
}

return nestLists(
blocks as TypedObject[],
this.listNestingMode() || LIST_NEST_MODE_HTML,
);
});

/**
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ import { PortableTextComponents } from '../types';
// prettier-ignore
template: `<ng-template let-node let-components="components">
@if (node.text === '\\n') {
@if (components.hardBreak === undefined) {<br />}
@else if (components.hardBreak === false) {{{ '\\n' }}}
@else {<ng-container *ngComponentOutlet="components.hardBreak" />}
@if (components.hardBreak) {<ng-container *ngComponentOutlet="components.hardBreak" />}
@else {{{ '\\n' }}}
} @else {{{ node.text }}}
</ng-template>`,
changeDetection: ChangeDetectionStrategy.OnPush,
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import { PortableTextComponent } from '../components/portable-text.component';
export class DynamicPortableTextContent<Node extends TypedObject = TypedObject>
implements AfterViewInit
{
children = input.required<(TypedObject & { isInline?: boolean })[]>();
children =
input.required<(TypedObject & { index?: number; isInline?: boolean })[]>();
container = viewChild<ViewContainerRef, ViewContainerRef>('children', {
read: ViewContainerRef,
});
Expand Down Expand Up @@ -93,6 +94,11 @@ export class PortableTextTypeComponent<
> extends DynamicPortableTextContent<T> {
value = input.required<T>();

/**
* Index within its parent.
*/
index = input(0);

/**
* Whether this node is "inline" - ie as a child of a text block,
* alongside text spans, or a block in and of itself.
Expand All @@ -103,16 +109,20 @@ export class PortableTextTypeComponent<
// eslint-disable-next-line @angular-eslint/directive-selector
@Directive({ selector: '[portableTextBlock]' })
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class PortableTextBlockComponent extends PortableTextTypeComponent<PortableTextBlock> {}
export class PortableTextBlockComponent<
T extends TypedObject = PortableTextBlock,
> extends PortableTextTypeComponent<T> {}

// eslint-disable-next-line @angular-eslint/directive-selector
@Directive({ selector: '[portableTextListItem]' })
@Directive({ selector: '[portableTextList]' })
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class PortableTextListComponent extends PortableTextTypeComponent<PortableTextListBlock> {}
export class PortableTextListComponent<
T extends TypedObject = PortableTextListBlock,
> extends PortableTextTypeComponent<T> {}

// eslint-disable-next-line @angular-eslint/directive-selector
@Directive({ selector: '[portableTextListItem]' })
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class PortableTextListItemComponent extends PortableTextTypeComponent<PortableTextListItemBlock> {
index = input.required<number>();
}
export class PortableTextListItemComponent<
T extends TypedObject = PortableTextListItemBlock,
> extends PortableTextTypeComponent<T> {}
31 changes: 29 additions & 2 deletions packages/sanity/portabletext/src/index.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
export { PortableTextComponent } from './components/portable-text.component';
export {
PortableTextComponent,
PortableTextComponent as PortableText,
} from './components/portable-text.component';
export {
PortableTextTypeComponent,
PortableTextMarkComponent,
PortableTextBlockComponent,
PortableTextListItemComponent,
PortableTextListComponent,
} from './directives/portable-text-directives';
export { PortableTextComponents } from './types';
export { defaultComponents } from './components/defaults/default-components';
export { mergeComponents } from './utils/merge';
export type {
AngularPortableTextList,
AngularPortableTextListItem,
DefaultPortableTextBlockStyle,
DefaultPortableTextListItem,
DefaultPortableTextMark,
InferComponents,
InferStrictComponents,
InferValue,
MissingComponentHandler,
NodeType,
PortableTextAngularComponent,
PortableTextAngularComponents,
PortableTextBlockComponentType,
PortableTextComponents,
PortableTextListBlock,
PortableTextListComponentType,
PortableTextListItemComponentType,
PortableTextMarkComponentType,
PortableTextProps,
UnknownNodeType,
} from './types';
export type { ToolkitListNestMode as ListNestMode } from '@portabletext/toolkit';
export { toPlainText } from '@portabletext/toolkit';
export type { PortableTextBlock } from '@portabletext/types';
Loading
Loading

Back | FazBrowse Home | New Git URL