microsoft / angular-react Goto Github PK
View Code? Open in Web Editor NEWUse React components inside Angular
Home Page: https://microsoft.github.io/angular-react/
License: MIT License
Use React components inside Angular
Home Page: https://microsoft.github.io/angular-react/
License: MIT License
Hi,
Thanks for the repository that allows my angular app to use fabric components in react :). Most of components work very well in my project except the issue below:
I followed the same set up from demo app, and put following component into my app component
<fab-dropdown
contentStyle="width: 300px;"
[placeholder]="'Select one'"
[defaultSelectedKey]="'A'"
(onChange)="logEvent('dropdown change', $event)"
>
<options>
<fab-dropdown-option optionKey="A" text="See option A"></fab-dropdown-option>
<fab-dropdown-option optionKey="B" text="See option B"></fab-dropdown-option>
</options>
</fab-dropdown>
However, what I got is a dropdown list that occupies the majority of the page:
And when I inspected the dropdown list dom and compared it with the correct dropdown in demo app, the difference is:
In my project, parent div is
<div role="dialog" aria-modal="true" class="hiddenPanel-71" style="outline: none;">
However in demo app it renders as:
<div class="ms-Callout-container container-288">
This issue happens when load the app into outlook add-in. Dropdown list in the same code works very well in web page.
I don't see a main or module key in package.json or any reference to js in the package.json file. my build tools are not able to resolve the JS for this version. Going to have to move back to an older version for now...
For component that accept <ng-content>
, when running in production (ng build --prod
), the content doesn't show up.
Seems to be related to having buildOptimizer: true
in angular.json
, running with --aot
(but without --prod
) works fine.
Reproduction steps:
npm install
ng serve --prod
Issue seems to be related to the cause of #8 - where the Angular CLI/WebPack's tree shaking removes actual code that's being executed.
I am using the fab-people-picker component and have attached a callback to resolveSuggestions. When the callback is invoked, the this
pointer points to the fab-people-picker component instead of pointing to the container (i.e.. my component where the fab-people-picker is added).
This is a screenshot of the this
pointer when resolveSuggestions callback is invoked.
Same's the case with any callback that is provided as an input to the component, e.g.. selectedItems callback
I tried to get around this by binding my method to (onResolveSuggestions)="AuthorPickerInputChanged($event)"
however as expected, the $event is empty, however the this
variable is correct and points to my component.
I need this
to point to my component so that I can use the injected services to actually resolve the suggestions.
Any suggestions on how I can get this to work?
Hi,
I'm using a fab-details-list with groups items and I need to select an item programmatically and also to show it (scroll to selected item) and to expand the group that contains the selected item.
is it possible ? if yes .... how can do it ?
Thanks.
The issue, for office-ui-fabric-react, is documented here: [https://github.com/microsoft/fluentui/issues/7225]. I reproduced the problem with this code:
<fab-panel [hasCloseButton]='false' [isBlocking]='true' [isOpen]='true'>
<fab-default-button text='close' (onClick)='Visible = true'></fab-default-button>
</fab-panel>
<fab-dialog [hidden]='!Visible'>
<div>Are you sure ?</div>
<fab-dialog-footer>
<fab-default-button text='yes'></fab-default-button>
<fab-primary-button text='no'></fab-primary-button>
</fab-dialog-footer>
</fab-dialog>
although isBlocking = true
if you click outside the panel, the panel closes.
To resolve the problem, I added this line to the template of fab-panel
(onOuterClick)='undefined'
obviously it's possible to define another event handler:
(onOuterClick)='onOuterClick.emit($event)'
Explore the option of creating a simple generic wrapper components, similar in nature to what projects like react2angular
offer (but for Angular 2+), to allow easier usage of React components within Angular. These components would not enjoy the benefit of having a more Angular-y API when exposed to apps, but may be sufficient for some use-cases.
@angular-react/core
- or possibly creating a new package for this - @angular-react/generic
?Hi,
I want to create a fab-details-list by passing in colums: IDetailsListColumnOptions[]
. I want to do this to simplify column sorting, amongst other things, i.e. specify columns and manipulate meta-data via typescript in a similar way to the Fabric UI React documentation/examples
I am trying to specify renderers for some columns, but am not having any luck creating InputRendererOptions<>
. Could you please provide an example of how I can specify a simple renderer. Obviously, what I have below doesn't work.
columns: IDetailsListColumnOptions[] = [
{
key:'name',
name:'Name',
minWidth: 100,
// ....
render: (ctx: IDetailsListColumnOptionsRenderContext) => {
return `<strong>how do I do this? or how to {{ ctx.item }} or ` +ctx.item + `</strong>`
}
},
]
It would be great to be able to reference an <ng-template>
or similar, within the component, but I can't utilise the columns > fab-details-list-column > render
tag/directive, as doing so means I have to define (and maintain) the columns in the template.
The React method for specifying a renderer is very straight forward, using JSX:
onRender: (item: IDocument) => {
return <img src={item.iconName} className={classNames.fileIconImg} alt={item.fileType + ' file icon'} />;
}
Sorry for asking a question as an issue, but the lack of documentation and community support leads me here.
When rendering a react-wrapper component (e.g. <fab-default-button>
) as a render prop in another react component, the inner component is not re-rendered on changes.
More comprehensive example:
// app.component.html
<fab-command-bar>
<items>
<fab-command-bar-item key="custom">
<render>
<ng-template let-item="item">
<counter></counter>
</ng-template>
</render>
</items>
</fab-command-bar>
// counter.component.ts
@Component({
selector: 'counter',
template: `
<fab-default-button [text]="count + '+'" (onClick)="onClick()"></fab-default-button>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CounterComponent {
count = 0;
constructor(private readonly cd: ChangeDetectorRef) {}
onClick() {
this.count++;
this.cd.detectChanges();
}
}
When clicking the button, the text is not changed.
https://microsoft.github.io/angular-react/
Just loads a white page... where are the docs hosted?
gh-pages job on circleCi seems like it has been failing since 9 months
ago (https://circleci.com/gh/microsoft/angular-react/138)
Is there a timeline for upgrading this project to use office-ui-fabric-react v7?
We're starting a new add-in based on an Angular project - and we'd like to start with 'the latest'.
Should we start with the current release in hopes that v7 will come soon or?
Other alternatives we should be looking at?
Thanks, Chad
Virtual + real dom having issue which is difficult to debug.
Some components in Fabric lose styling when served/built using tree shaking (ng build|serve --prod
).
These components are at least:
DatePicker
(fab-date-picker
)
Calendar
within it is unstyled.Panel
(fab-panel
)These seem to happen due to these components using plain Sass and not CSS-in-JS like most of the office-ui-fabric-react
lib uses.
Components that use CSS-in-JS are not affected (for example, the text field and the icon in the DatePicker
appear fine in a prod build, the calendar inside the popup does not).
The way office-ui-fabric-react
works for plain CSS-styled components is that they have an original *.scss file, that's compiled down to a *.js file in the following format (unminified & shorten below for readability):
import { loadStyles } from '@microsoft/load-themed-styles';
loadStyles([
{
rawString:
".root_c754aea6{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:none;box-shadow:none;margin:0;padding:0}.root_c754aea6 *::-moz-focus-inner{border:0}.root_c754aea6 *{outline:transparent}.root_c754aea6 *{position:relative}.ms-Fabric--isFocusVisible .root_c754aea6 *:focus:after{content:'';position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;border:1px solid ",
},
{ theme: 'neutralSecondary', defaultValue: '#666666' },
...
]);
export var root = 'root_c754aea6';
...
It seems like the Angular CLI prod build removes the call to loadStyles
in the code, since I can import these files in the app and access the values of the exported variables (root
above, though there are others, depending on the file).
This package seemingly only supports css-in-javascript styling for the react elements. Are there any plans to change that?
Does this work with React hooks? Is it possible to provide and example?
The current v4 is working with Angular 11, any plans for upgrading the library for angular 12 support?
From @bengry on July 22, 2018 7:57
When having the following structure: React -> (via ReactContent) Angular -> React
,
the inner React component is attached to the root of the VDOM:
Instead of being nested under the ReactContent
(seen above under the div
with key="run"
), it's nested as a root node in the VDOM.
These nodes are also kept in the VDOM after the DOM element has been removed.
A workaround for this (but not a solution) by @xjerwa - in AngularReactRendererFactory
:
end() {
if (DEBUG) { console.log('RootRenderer > end > isRenderPending:', this.isRenderPending, 'reactRootNodes:', this.reactRootNodes); }
// Flush any pending React element render updates. This cannot be done
// earlier (as is done for DOM elements) because React element props
// are ReadOnly.
// Potential fix: manually unmount ReactNodes that don't correspond to a DOM element
for (let i = 0; i < this.reactRootNodes.length; i++) {
const node = this.reactRootNodes[i] as any;
if (!document.contains(node._parent) && ReactDOM.unmountComponentAtNode(node._parent)) {
this.reactRootNodes.splice(i--, 1);
}
}
// End potential fix
if (this.isRenderPending) {
// Remove root nodes that are pending destroy after render.
this.reactRootNodes = this.reactRootNodes.filter(node => !node.render().destroyPending);
this.isRenderPending = false;
}
}
Copied from original issue: benfeely/angular-react#13
Hello Team - We are using this library successfully in our project which is using Angular8. Now we have a need to migrate to Angular10 because we want to leverage some other nugget packages that require Angular10 as minimum.
Unfortunately I could not get this library to work with Angular10 and I am battling this for quite a few days. Here is the relevant package.json file configuration.
"dependencies": {
"@angular-react/core": "3.0.0",
"@angular-react/fabric": "3.0.0",
"@angular/animations": "^10.2.5",
"@angular/cdk": "^7.3.7",
"@angular/common": "10.2.5",
"@angular/compiler": "10.2.5",
"@angular/core": "10.2.5",
"@angular/forms": "10.2.5",
"@angular/material": "^7.3.7",
"@angular/platform-browser": "10.2.5",
"@angular/platform-browser-dynamic": "10.2.5",
"@angular/router": "10.2.5",
"@angular/upgrade": "10.2.5",
"@microsoft/applicationinsights-web": "^2.5.4",
"@ng-select/ng-select": "^5.0.15",
"@types/highcharts": "^7.0.0",
"@types/react": "~16.8.6",
"@types/react-dom": "^16.8.6",
"@uifabric/azure-themes": "7.3.0",
"adal-angular4": "^3.0.16",
"admin-lte": "^2.4.3",
"angular-split-ng6": "^1.0.0-rc.5",
"bootstrap": "^3.4.1",
"classnames": "^2.3.1",
"copy-html-to-clipboard": "^4.0.1",
"core-js": "^3.6.5",
"css-to-style": "^1.4.0",
"font-awesome": "^4.7.0",
"hammerjs": "^2.0.8",
"highcharts": "^8.1.2",
"highcharts-angular": "^2.4.0",
"highcharts-custom-events": "^3.0.9",
"ie-shim": "^0.1.0",
"jquery": "^3.4.1",
"moment": "^2.22.1",
"monaco-languageclient": "^0.13.0",
"office-ui-fabric-core": "11.0.0",
"office-ui-fabric-react": "7.132.0",
"pdfmake": "^0.1.72",
"react": "^16.8.0",
"react-dom": "^16.8.0",
"reconnecting-websocket": "^4.4.0",
"reflect-metadata": "^0.1.3",
"rxjs": "6.6.7",
"rxjs-compat": "6.2.2",
"sass": "^1.54.4",
"stylenames": "^1.1.6",
"tslib": "^2.0.0",
"ua-parser-js": "^0.7.19",
"vis": "^4.21.0",
"vscode-ws-jsonrpc": "^0.2.0",
"web-animations-js": "^2.3.2",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-builders/custom-webpack": "8.0.2",
"@angular-devkit/build-angular": "~0.1002.4",
"@angular-devkit/build-ng-packagr": "~0.1002.4",
"@angular-devkit/build-optimizer": "~0.800.3",
"@angular/cli": "10.2.4",
"@angular/compiler-cli": "10.2.5",
"@angular/language-service": "^10.2.5",
"@types/jasmine": "~2.8.3",
"@types/jasminewd2": "~2.0.2",
"@types/node": "^12.11.1",
"@types/ua-parser-js": "^0.7.32",
"@types/vscode": "1.67.0",
"awesome-typescript-loader": "^2.2.1",
"codelyzer": "^5.1.2",
"concurrently": "^4.1.0",
"jasmine": "^3.0.0",
"jasmine-core": "~3.5.0",
"karma": "~5.0.0",
"karma-chrome-launcher": "~3.1.0",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"ng-packagr": "^10.1.0",
"protractor": "~7.0.0",
"rxjs-tslint": "^0.1.3",
"selfsigned": "^1.10.2",
"ts-node": "~4.1.0",
"tslint": "~6.1.0",
"typescript": "~4.0.8",
"webpack-bundle-analyzer": "^3.6.0"
}
May I know the right combination of the libraries to use to make it work with Angular10?
This is the error I get when I try to run with Angular10
TypeError: Cannot read properties of undefined (reading 'nativeElement')
at FabPrimaryButtonComponent.set (https://localhost:3000/vendor.js:240061:41)
at Object.ngOnChangesSetInput [as setInput] (https://localhost:3000/vendor.js:116112:25)
at setInputsFromAttrs (https://localhost:3000/vendor.js:123461:13)
at instantiateAllDirectives (https://localhost:3000/vendor.js:123199:7)
at createDirectivesInstances (https://localhost:3000/vendor.js:122484:3)
at Module.ɵɵelementStart (https://localhost:3000/vendor.js:131388:5)
at FabricFeedbackComponent_Template (https://localhost:3000/main.js:75213:73)
at executeTemplate (https://localhost:3000/vendor.js:122452:5)
at renderView (https://localhost:3000/vendor.js:122189:7)
at renderComponent (https://localhost:3000/vendor.js:123684:3)
at renderChildComponents (https://localhost:3000/vendor.js:122043:5)
at renderView (https://localhost:3000/vendor.js:122223:7)
at renderComponent (https://localhost:3000/vendor.js:123684:3)
at renderChildComponents (https://localhost:3000/vendor.js:122043:5)
at renderView (https://localhost:3000/vendor.js:122223:7)]
This is the line of code from the browser tools window.
From @bengry on July 13, 2018 14:36
When passing a ComponentRef
as a RenderInput
to a component, after a change detection is triggered the component is removed from the DOM.
This doesn't happen when passing a TemplateRef
or a () => HTMLElement
.
Repro code:
Template
<fab-command-bar [items]="commandBarItems">
</fab-command-bar>
<button (click)="toggleRun()">Toggle change detection</button>
Component
private _customCbItemRef: ComponentRef<any>; // initialized via a `ComponentFactoryResolver`.
commandBarItems: ICommandBarItemOptions[] = [
{
key: 'run',
text: 'Run',
iconProps: {
iconName: 'CaretRight',
},
disabled: true,
},
{
key: 'custom-element',
render: this._customCbItemRef
},
];
toggleRun() {
// Triggers change detection - `FabCommandBar` is defined as `OnPush`
this.commandBarItems = this.commandBarItems.map(item => item.key === 'run' ? { ...item, disabled: !item.disabled } : item);
}
Expected result:
Actual result:
run
command bar item changes the disabled state.custom-element
command bar item disappears.Copied from original issue: benfeely/angular-react#12
Hi,
I'm trying to achieve 2 way data binding to a property. Similar to in this example where the React prop doesn't meet the naming conventions for the Angular banana box syntax.
However I get a warning from React
Warning: React does not recognize the `queryChange` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `querychange` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
My prop is called query
, the React prop is called onEditQuery
(which I bind as [EditQuery]), so I've made a queryChange
EventEmitter, then emit an event in the EditQuery
handler function.
Is there any workaround for this? It still all works, I just don't like the errors in the console.
Thanks!
I try to apply Fluent theme as in the Fabric repo said in
https://github.com/OfficeDev/office-ui-fabric-react/wiki/Fluent-theme-in-Fabric-6
however as they mention they are using Customizer as Context provider to provide the setting of Fluent to the React tree.
Is it possible to apply Fluent with Angular-react?
At present none of the input components support using ngModel to allow support for two way data binding and usage in forms within Angular applications. The proposal below attempts to address that:
I propose a simple abstract base class that all input components can derive from. It should provide the necessary plumbing to support NG_VALUE_ACCESSOR
for individual input components, but should also allow sufficient amount of flexibility for individual input components to implement support for it. The proposed base class should be named FabInputComponent
which inherits from ReactWrapperComponent
The abstract base class will define 2 abstract methods: onModelValueChanged
and onViewValueChanged
which will allow inherited input component to react and respond to framework events pertaining to ngModel bindings. The input components will then implement their own logic to handle those events. For e.g. FabDropdownComponent
will use these events to set it's internal selectedKey
property as well as use the onViewValueChanged
to provide feedback to the framework when a drop down option is selected by the user.
I have a blueprint of this implementation working in one of my fork branches. There is a case for this to be reviewed by the community since these are fundamental changes to some of the widely used components in the library.
I found that amazing library and I'd like to use it, but documentation isn't good enough.
The links in READMEs such as Documentation, quick start, and guides
go to page that contains some performance tests, components presentations etc., but there is no any documentation, quick start and guides.
And my question is: Could you add these resources?
Hello,
I am trying to implement this library in a project. However, when using the 0.5.11 version of @angular-react/fabric, components do not render. I can render them but using the 0.1.6 version as it is done here: https://stackblitz.com/edit/angular-react. I cloned this same project and updated everything to the latest version and it stopped working. (I did update it locally)
Any clue?
Hi,
I have an angular project which hosts a sub-directory with several components.
I want to migrate the sub-project to react and embed it in the angular.
But, I don't want to bundle the react migrated folder as an NPM package.
Is it possible to embed the react folder (source code)? if not, is there a simpler solution rather then bundling a react NPM package?
Thanks
Hi there, I want to use angular-react with Fabric, but it doesn't work.
Whenever I import a module and run ng serve
, it throws some errors.
ERROR in node_modules/@angular-react/fabric/src/lib/components/callout/callout.component.d.ts(7,34): error TS2339: Property 'componentRef' does not exist on type 'ICalloutProps'.
node_modules/@angular-react/fabric/src/lib/components/image/image.component.d.ts(5,32): error TS2339: Property 'componentRef' does not exist on type 'IImageProps'.
I'm using following package versions:
Running on Ubuntu 18.04 on Windows 10.
Depending on which versions of the packages I use, there are different errors.
Any ideas on how to fix this are very appreciated. Thanks!
We have a React based library, which contains a 'button group toggle' component - a wrapper to a group of Button(s) components (handled to it as children), which modifies them lightly (after checking that they are of the right type) to add a click event handler and attaching an 'active' prop based on the wrapper state.
In React, the code works fine.
However, in Angular using angular-react, it doesn't work as expected: first, the children of the wrapper component are not the buttons themselves but rather the ReactContent element. Next, the even if taking the ReactContent children (this.props.children[0].props['children-to-append']
) they are the buttons but their type is not the same type as seen by the code in when we use the library in React directly: the angular type instead of the React type. This causes React to shout when we attempt to modify the children (as mentioned above).
This is how we render the children in the wrapper component:
<ButtonGroupToggle
#reactNode
[fill]="fill"
[minimal]="minimal"
[large]="large"
[vertical]="vertical"
[defaultActive]="defaultActive"
(onActiveChange)="handleActiveChange($event)">
<ReactContent>
<ng-content></ng-content>
</ReactContent>
</ButtonGroupToggle>
I suspect this is a usage issue more than a bug... .
Any help will be appreciated. TIA!
Hi!
I'm trying to create a wrapper around a React component to use within Angular. I haven't done much with React before, so that side of things is quite new to me.
I'm getting an error that a prop is required, but I am supplying that prop.
I had a look and the component is expecting a prop to be set when it is created. However it appears that in Angular-React, the property is supplied later.
The component still works, but it logs a whole lot of errors before it starts working.
The error is like this:
ERROR TypeError: MyReactComponent requires a fetch function.
at new MyReactComponent (MyReactComponent.js:114)
The code that is throwing the error is this:
if (typeof props.fetch !== 'function') {
throw new TypeError('MyReactComponent requires a fetch function.');
}
In my template I have (This is slightly simplified, there are multiple related components in there)
<div #reactNode className="myreactcomponent-container">
<MyReactComponent [fetch]="fetch"></MyReactComponent>
</div>
And fetch is a function in the class (and it is being called)
So I am just wondering if I am doing anything incorrectly, or is there a way I can supply the fetch prop earlier on to avoid the error?
Thanks!
Ryan
From @benfeely on July 12, 2018 18:20
The initial effort to create wrappers for Fabric components is targeted at closely following the React Fabric API. This means implementing a largely imperative pattern, particularly for scenarios such as defining "items" within a "CommandBar". Following the react pattern, these items are defined by passing in an object as a property. Although this is a valid pattern, the Angular community tends to lean more towards a declarative model...
This is the initial implementation which follows the React Fabric API for the component closely.
Component
commandBarItems: ICommandBarItemOptions[] = [
{
key: 'run',
text: 'Run',
iconProps: {
iconName: 'CaretRight',
},
disabled: true,
},
{
key: 'custom-element',
onClick: () => {
console.log('custom element clicked');
},
render: this._customCbItemRef/* this.customCbItemTemplate */,
},
];
Template
<fab-command-bar #commandBar [items]="commandBarItems" [farItems]="commandBarFarItems">
</fab-command-bar>
This is the proposed implementation to add to the extend the API and allow for declarative syntax (preferred by many Angular teams).
<fab-command-bar #commandBar [items]="commandBarItems" [farItems]="commandBarFarItems">
<items>
<fab-action-button [iconProps]="{ iconName: 'AddFriend' }" text="Compound" [secondaryText]="'Loren ipsum dolor sit amet'" (onClick)="onActionButtonClicked($event)"></fab-action-button>
<fab-compound-button [iconProps]="{ iconName: 'AddFriend' }" [secondaryText]="'Loren ipsum dolor sit amet'" (onClick)="onCompoundButtonClicked($event)" text="Compound"></fab-compound-button>
<items>
<far-items>
...
<far-items>
</fab-command-bar>
Note: This proposal is based on Commercial Store's implementation of BSX-List (which is patterned after the Angular Material list and other components). Please see BSX-List source for implementation examples.
Copied from original issue: benfeely/angular-react#11
Inside _passAttributesAsProps()
there is a check to ensure that the DOM node that is being updated does not have style
, class
or key
attributes. This code will throw if any of these attributes are found.
This assumes that the application is the only code that is writing to the DOM. In practice, many browser extensions will also mutate the DOM. This will cause angular-react to throw and break the application.
This check should be, at most, a warning in production code.
Run this code in console.
Array.from(document.querySelectorAll('body *')).forEach(n => n.setAttribute('style', n.getAttribute('style') || 'zoom: 1'))
The next time that the Angular component is re-rendered, it will throw and break the application.
Currently creating @angular-react
components is done manually, specially in @angular-react/fabric
(but the same holds true for any library implementation).
This is fine for a few components, and didn't prove to be worth the effort of creating such a tool, but as the library grows, and more components are added - this seems like it would simplify the long-term maintenance, especially in regards to upgrading the underlying React UI framework (e.g. office-ui-fabric-react
, Semantic-UI-React
).
There are a number of ways to go about this, but the most likely is to use Angular Schematics to generate components, which as part of the inputs will take some sort of identifier for a *Props
interface (e.g. ICheckboxProps
), and together with the TypeScript compiler API (or any of its wrappers) and add the relevant Input
s and Output
s for the component, as well as bindings for the template etc.:
string | number | boolean | object
should be added as-is. e.g: componentRef?: IRefObject<ICheckbox>
-> @Input() componentRef?: ICheckboxProps['componentRef']
(...args: any[]) => void
should be added as @Output
s, with the arguments added as an object with properties the same name as the function parameters. e.g.: onChange?: (ev?: React.FormEvent<HTMLElement | HTMLInputElement>, checked?: boolean) => void
-> @Output() readonly onChange = new EventEmitter<{ ev?: Event, checked?: boolean }>()
.(...args: any[]) => *non-void*
should be added as-is (see 1. above), also as @Input
s.IRenderFunction<T>
should be added as InputRendererOptions<T>
. If the prop name is prefixed with an on
, omit it (the Angular doesn't let Input
s be prefixed with on
), and camel-cased. e.g.:onRenderNavigation?: IRenderFunction<IPanelProps>
-> @Input() renderNavigation?: InputRendererOptions<IPanelProps>
.office-ui-fabric-react
, as this is the only actively-maintained package wrapper - I think this is enough to support automating it, for the moment at least.@angular-react/fabric
can be used as reference.I'm trying to wrap a slate editor by following the fabric examples. I can't seem to get a basic example working. I've set up a module like:
import { registerElement } from '@angular-react/core'
import { CommonModule } from '@angular/common'
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'
import { Editor } from 'slate-react'
import { SlateEditorComponent } from './slate-editor/slate-editor.component'
@NgModule({
declarations: [SlateEditorComponent],
imports: [CommonModule],
exports: [SlateEditorComponent],
schemas: [NO_ERRORS_SCHEMA],
})
export class SlateModule {
constructor() {
registerElement('Editor', () => Editor)
}
}
and a simple component:
import { Value } from 'slate'
import { EditorProps } from 'slate-react'
@Component({
selector: 'app-slate-editor',
template: `
<Editor #reactNode [value]="value" [Change]="onChange"></Editor>
`,
styles: ['react-renderer'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SlateEditorComponent extends ReactWrapperComponent<EditorProps> {
@ViewChild('reactNode', { static: true }) protected reactNodeRef: ElementRef
@Input() value: EditorProps['value'] = Value.fromJSON({
document: {
nodes: [
{
object: 'block',
type: 'paragraph',
nodes: [
{
object: 'text',
text: 'A line of text in a paragraph.',
},
],
},
],
},
})
@Input() onChange: EditorProps['onChange'] = ({ value }) => console.log(value)
constructor(elementRef: ElementRef, changeDetectorRef: ChangeDetectorRef, renderer: Renderer2) {
super(elementRef, changeDetectorRef, renderer)
}
}
I've installed the following dependencies:
"dependencies": {
"@angular-react/core": "^1.0.1",
"@angular/animations": "~8.0.3",
"@angular/cdk": "^8.0.1",
"@angular/common": "~8.0.3",
"@angular/compiler": "~8.0.3",
"@angular/core": "~8.0.3",
"@angular/forms": "~8.0.3",
"@angular/material-moment-adapter": "^8.0.1",
"@angular/platform-browser": "~8.0.3",
"@angular/platform-browser-dynamic": "~8.0.3",
"@angular/router": "~8.0.3",
"@types/slate-react": "^0.22.6",
"@types/stylenames": "^1.1.0",
"immutable": "^4.0.0-rc.12",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"rxjs": "~6.5.2",
"slate": "^0.47.8",
"slate-react": "^0.22.9",
"tslib": "^1.9.0",
"zone.js": "~0.9.1"
},
I'm at a bit of a loss and would appreciate any guidance on what I'm doing wrong here.
Hi, I'm working with fab-defails-list and I would customize the header and the rows passing custom styles (IDetailsHeaderStyles / IDetailsRowStyle) or overriding the default styles. I try to understand the code behind renderDetailsReader and renderRow but I don't understand if it's possibile and how to call the defaultRenderer passing a modified props parameters. Can you help me ? Thanks
Hello, and great library by the way! I've successfully created wrappers for my react components, but now I'm trying to generate a list of components with *ngFor which I can't seem to get working. If needed, I can make a plunker or other sample app; just let me know, thanks.
Example from /angular-react/blob/master/apps/demo/src/app/app.component.html
This doesn't work:
<fab-pivot>
<fab-pivot-item *ngFor="let item of items" headerText="item.name">
<div>{{item.content}}</div>
</fab-pivot-item>
</fab-pivot>
This doesn't work:
<fab-pivot>
<div *ngFor="let item of items">
<fab-pivot-item headerText="item.name"> <div>{{item.content}}</div> </fab-pivot-item>
</div>
</fab-pivot>
This works:
<fab-pivot>
<fab-pivot-item headerText="Tab 1"> <div>Tab 1's content</div> </fab-pivot-item>
<fab-pivot-item headerText="Tab 2"> <div>Tab 2's content</div> </fab-pivot-item>
<fab-pivot-item headerText="Tab 3"> <div>Tab 3's content</div> </fab-pivot-item>
</fab-pivot>
Does @angular-react/fabric
work with Angular 9?
Playing around, and it appears children aren't working with the new version. I get an empty react-content element where I'd expect child elements to display.
Hey Fellas - I just was curios to know if you have ported the Label component from Fluent UI - https://developer.microsoft.com/en-us/fluentui#/controls/web/label
I wanted to reuse that component and I was hoping to avoid doing it manually.
Wrapper components currently either have the default display
(inline
), or when using setHostDisplay: true
, have it be set to whatever the root element is.
This is done because support for display: contents
is partial at the moment, with Edge and IE not supporting it at all, and Safari and all Chromium-based browsers having accessibility issues.
This should be further explored, and use CSS.supports()
to do use display: contents
when available if possible.
Currently when working on the @angular-react/fabric
package (and also on the core one, but less-so), we constantly change the AppComponent
in the demo app.
Ideally, we'd have some sort of playground for these sort of these (as a separate app or otherwise), and all components, with all usages would be available in a kitchen sink app, probably under the docs
app.
This would allow easier testing of components, showcasing various things that they offer, in different syntaxes sometimes (e.g. the FabCommandBarComponent
's both imperative and declarative syntax options for items
(and farItems
and overflowItems
).
Hi, I've an issue using renderFooterContent
in a fab-panel
. This is the template to reproduce the problem.
<fab-panel [isOpen]='true' headerText='Test' [renderFooterContent]='TEMPLATE'>
<render>
Content
<button (click)='IncCounter()'>Change</button>
</render>
</fab-panel>
<ng-template #TEMPLATE>
{{Counter}}
</ng-template>
I had this exception
ERROR TypeError: Cannot convert undefined or null to object
at Function.assign ()
at ReactTemplate.push../src/@angular-react/core/src/lib/renderer/react-template.ts.ReactTemplate.componentDidUpdate (react-template.ts:66)
at commitLifeCycles (react-dom.development.js:16242)
at commitAllLifeCycles (react-dom.development.js:17592)
at HTMLUnknownElement.callCallback (react-dom.development.js:149)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:17280)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:498)
I tried to patch the code of react-template in this way (obviously it's only a temporary workaround).
componentDidUpdate() {
// Context has changes, trigger change detection after pushing the new context in
try {
Object.assign(this._embeddedViewRef.context, this.props.context);
} catch {
console.info('ReactTemplate invalid context');
}
this._embeddedViewRef.detectChanges();
}
Naturally it seems to work, but when I click on the button the counter in the footer changes only if there is an event on the page (mouse move o click another time on the button).
It sounds like the componentDidUpdate
method is called outsize the Angular Zone.
Another strange thing is that if I set the renderHeader
with TEMPLATE
, after rollback the workaround (try ... catch), it doesn't throw the previous exception but I've the same problem about the counter updating.
Thanks
Hi all,
I'm trying to learn how to use the angular-react through the examples in the wiki. Not sure if this is the correct place to ask, please tell me otherwise.
I've successfully achieved the use of already provided fab elements (fab-calendar, fab-dialog or fab-primary-button) and setting their properties successfully
I've successfully created a React JS library (packed and deployed) and used in React Applications
import React, { Component } from 'react'
import PropTypes from 'prop-types'import styles from './styles.css'
export default class ExampleComponent extends Component {
constructor(props) {
super(props);
}static propTypes = {
name: PropTypes.string
}render() {
return ( <div className={styles.test}> Hello {this.props.name} {this.props.lastname} </div> )
}
}
Module specification is quite straightforward, but I'm stuck with component definition. I've tried looking at how it was made for Fabric e.g. Dialog => React and Component Wrapper but these are bit complex to follow.
One of the requirements of ReactWrapperComponent is to place a <TProps extends {}> which for Fabric element is made through Typescript Interface definitions e.g. export class FabDialogComponent extends ReactWrapperComponent, but as I'm using React in JS and not Typescript, It's not clear to me, what to put in ReactWrapperComponent<> and how to access my react Props (i.e. name & lastname).
Thanks in advance and sorry for the dumminess,
Gorka
Hello,
I'm getting warning messages indicating that the components are using deprecated lifecycles. The primary ones I've noticed so far have been componentWillReceiveProps, componentWillMount, and componentWillUpdate. The message indicates these should be replaced with componentDidUpdate and componentDidMount. Appreciate the help.
Many thanks,
Stacy
Hello there! The page https://microsoft.github.io/angular-react/docs doesn't have any documentation now.
Does the documentation exist at all? And if no, do you planning to add it in future?
In the Architecture page Architecture:-High-level.md
twice an incorrect link is used.
Line 19: [more on that here](https://TODO)
Line 25: [caveats](https://TODO)
I got this problem when I try to compile my angular app (angular 13) I have the following error.
node_modules/@angular-react/core/src/lib/components/wrapper-component.d.ts:1:23 - error TS2688: Cannot find type definition file for 'libs/core/src/lib/@types/geteventlisteners'.
1 /// <reference types="libs/core/src/lib/@types/geteventlisteners" />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When I look into the libray downloaded by npm https://registry.npmjs.org/@angular-react/core/-/core-4.1.0.tgz I don't found the folder types in core. Moreover the path seems wrong in lib and not in the code
d.ts
files are not embedded during compilation process.
So I forked the project to propose you an update of the lib to have the right compilation and avoid to have this error.
Any ideas on how I would configure karma to not have to skip all my tests?
Hi,
can you support React Portals?
Thank you
There are important files that Microsoft projects should all have that are not present in this repository. A pull request has been opened to add the missing file(s). When the pr is merged this issue will be closed automatically.
Microsoft teams can learn more about this effort and share feedback within the open source guidance available internally.
Hi,
Would it be handy if input fields support form controls from Angular reactive form?
Thank you!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.