Merge pull request #4095 from AriGunawan/feature/add_spfx_tailwindcss3
This commit is contained in:
commit
7615c206b1
|
@ -0,0 +1,39 @@
|
|||
// For more information on how to run this SPFx project in a VS Code Remote Container, please visit https://aka.ms/spfx-devcontainer
|
||||
{
|
||||
"name": "SPFx 1.18.0",
|
||||
"image": "docker.io/m365pnp/spfx:1.18.0",
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {},
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"editorconfig.editorconfig",
|
||||
"dbaeumer.vscode-eslint"
|
||||
],
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
"forwardPorts": [
|
||||
4321,
|
||||
35729
|
||||
],
|
||||
"portsAttributes": {
|
||||
"4321": {
|
||||
"protocol": "https",
|
||||
"label": "Manifest",
|
||||
"onAutoForward": "silent",
|
||||
"requireLocalPort": true
|
||||
},
|
||||
// Not needed for SPFx>= 1.12.1
|
||||
// "5432": {
|
||||
// "protocol": "https",
|
||||
// "label": "Workbench",
|
||||
// "onAutoForward": "silent"
|
||||
// },
|
||||
"35729": {
|
||||
"protocol": "https",
|
||||
"label": "LiveReload",
|
||||
"onAutoForward": "silent",
|
||||
"requireLocalPort": true
|
||||
}
|
||||
},
|
||||
"postCreateCommand": "bash .devcontainer/spfx-startup.sh",
|
||||
"remoteUser": "node"
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
echo
|
||||
echo -e "\e[1;94mInstalling Node dependencies\e[0m"
|
||||
npm install
|
||||
|
||||
## commands to create dev certificate and copy it to the root folder of the project
|
||||
echo
|
||||
echo -e "\e[1;94mGenerating dev certificate\e[0m"
|
||||
gulp trust-dev-cert
|
||||
|
||||
# Convert the generated PEM certificate to a CER certificate
|
||||
openssl x509 -inform PEM -in ~/.rushstack/rushstack-serve.pem -outform DER -out ./spfx-dev-cert.cer
|
||||
|
||||
# Copy the PEM ecrtificate for non-Windows hosts
|
||||
cp ~/.rushstack/rushstack-serve.pem ./spfx-dev-cert.pem
|
||||
|
||||
## add *.cer to .gitignore to prevent certificates from being saved in repo
|
||||
if ! grep -Fxq '*.cer' ./.gitignore
|
||||
then
|
||||
echo "# .CER Certificates" >> .gitignore
|
||||
echo "*.cer" >> .gitignore
|
||||
fi
|
||||
|
||||
## add *.pem to .gitignore to prevent certificates from being saved in repo
|
||||
if ! grep -Fxq '*.pem' ./.gitignore
|
||||
then
|
||||
echo "# .PEM Certificates" >> .gitignore
|
||||
echo "*.pem" >> .gitignore
|
||||
fi
|
||||
|
||||
echo
|
||||
echo -e "\e[1;92mReady!\e[0m"
|
||||
|
||||
echo -e "\n\e[1;94m**********\nOptional: if you plan on using gulp serve, don't forget to add the container certificate to your local machine. Please visit https://aka.ms/spfx-devcontainer for more information\n**********"
|
|
@ -0,0 +1 @@
|
|||
v18.18.2
|
|
@ -0,0 +1,90 @@
|
|||
# Tailwind 3
|
||||
|
||||
## Summary
|
||||
|
||||
This project showcases an integration of Tailwind CSS into an SPFx project. It offers a sample implementation, facilitating straightforward setup and utilization of Tailwind CSS for enhanced styling and design in SharePoint Framework projects.
|
||||
|
||||
Here is an illustration of the styling outcome achieved with Tailwind, along with the corresponding code.
|
||||
|
||||
![Result](assets/example.png)
|
||||
![Code](assets/code.png)
|
||||
|
||||
To setup Tailwind on your existing project, proceed with the following steps:
|
||||
|
||||
1. Execute the following commands:
|
||||
- `npm i -D react-tailwindcss postcss autoprefixer gulp-postcss`
|
||||
- `npx react-tailwindcss init`
|
||||
2. Add the following files:
|
||||
- /assets/tailwind.css
|
||||
- postcss.config.js
|
||||
- tailwind.config.js
|
||||
3. Update the following files:
|
||||
- gulpfile.js
|
||||
- Check the changes in this project
|
||||
- entry/main component file (e.g. /src/webparts/HelloTailwind/HelloTailwindWebPart.ts)
|
||||
- Add `import '../../../assets/dist/tailwind.css`
|
||||
|
||||
## Compatibility
|
||||
|
||||
| :warning: Important |
|
||||
|:---------------------------|
|
||||
| Every SPFx version is optimally compatible with specific versions of Node.js. In order to be able to build this sample, you need to ensure that the version of Node on your workstation matches one of the versions listed in this section. This sample will not work on a different version of Node.|
|
||||
|Refer to <https://aka.ms/spfx-matrix> for more information on SPFx compatibility. |
|
||||
|
||||
This sample is optimally compatible with the following environment configuration:
|
||||
|
||||
![SPFx 1.18.0](https://img.shields.io/badge/SPFx-1.18.0-green.svg)
|
||||
![Node.js v18.18](https://img.shields.io/badge/Node.js-v18.18+-green.svg)
|
||||
![Compatible with SharePoint Online](https://img.shields.io/badge/SharePoint%20Online-Compatible-green.svg)
|
||||
![Local Workbench Unsupported](https://img.shields.io/badge/Local%20Workbench-Unsupported-red.svg "Local workbench is no longer available as of SPFx 1.13 and above")
|
||||
![Hosted Workbench Compatible](https://img.shields.io/badge/Hosted%20Workbench-Compatible-green.svg)
|
||||
![Compatible with Remote Containers](https://img.shields.io/badge/Remote%20Containers-Compatible-green.svg)
|
||||
|
||||
## Applies to
|
||||
|
||||
- [SharePoint Framework](https://learn.microsoft.com/sharepoint/dev/spfx/sharepoint-framework-overview)
|
||||
- [Microsoft 365 tenant](https://learn.microsoft.com/sharepoint/dev/spfx/set-up-your-development-environment)
|
||||
|
||||
> Get your own free development tenant by subscribing to [Microsoft 365 developer program](https://aka.ms/m365devprogram)
|
||||
|
||||
## Contributors
|
||||
|
||||
- [Ari Gunawan](https://github.com/AriGunawan)
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|October 7, 2023|Initial release
|
||||
|
||||
## Minimal path to awesome
|
||||
|
||||
- Clone this repository (or [download this solution as a .ZIP file](https://pnp.github.io/download-partial/?url=https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-tailwindcss3) then unzip it)
|
||||
- From your command line, change your current directory to the directory containing this sample (`react-tailwindcss3`, located under `samples`)
|
||||
- in the command line run:
|
||||
- `npm install`
|
||||
- `gulp serve`
|
||||
|
||||
> This sample can also be opened with [VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview). Visit <https://aka.ms/spfx-devcontainer> for further instructions.
|
||||
|
||||
## Help
|
||||
|
||||
We do not support samples, but this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
|
||||
|
||||
If you're having issues building the solution, please run [spfx doctor](https://pnp.github.io/cli-microsoft365/cmd/spfx/spfx-doctor/) from within the solution folder to diagnose incompatibility issues with your environment.
|
||||
|
||||
You can try looking at [issues related to this sample](https://github.com/pnp/sp-dev-fx-webparts/issues?q=label%3A%22sample%3A%20react-tailwindcss3%22) to see if anybody else is having the same issues.
|
||||
|
||||
You can also try looking at [discussions related to this sample](https://github.com/pnp/sp-dev-fx-webparts/discussions?discussions_q=react-tailwindcss3) and see what the community is saying.
|
||||
|
||||
If you encounter any issues using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected%2Csample%3A%20react-tailwindcss3&template=bug-report.yml&sample=react-tailwindcss3&authors=@AriGunawan&title=react-tailwindcss3%20-%20).
|
||||
|
||||
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Aquestion%2Csample%3A%20react-tailwindcss3&template=question.yml&sample=react-tailwindcss3&authors=@AriGunawan&title=react-tailwindcss3%20-%20).
|
||||
|
||||
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Aenhancement%2Csample%3A%20react-tailwindcss3&template=suggestion.yml&sample=react-tailwindcss3&authors=@AriGunawan&title=react-tailwindcss3%20-%20).
|
||||
|
||||
## Disclaimer
|
||||
|
||||
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||
|
||||
<img src="https://m365-visitor-stats.azurewebsites.net/sp-dev-fx-webparts/samples/react-tailwindcss3" />
|
Binary file not shown.
After Width: | Height: | Size: 615 KiB |
Binary file not shown.
After Width: | Height: | Size: 249 KiB |
|
@ -0,0 +1,50 @@
|
|||
[
|
||||
{
|
||||
"name": "pnp-sp-dev-spfx-web-parts-react-tailwindcss",
|
||||
"source": "pnp",
|
||||
"title": "Tailwind 3",
|
||||
"shortDescription": "This project showcases an integration of Tailwind CSS into an SPFx project.",
|
||||
"url": "https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-tailwindcss",
|
||||
"downloadUrl": "https://pnp.github.io/download-partial/?url=https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-tailwindcss",
|
||||
"longDescription": [
|
||||
"This project showcases an integration of Tailwind CSS into an SPFx project. It offers a sample implementation, facilitating straightforward setup and utilization of Tailwind CSS for enhanced styling and design in SharePoint Framework projects."
|
||||
],
|
||||
"creationDateTime": "2023-10-07",
|
||||
"updateDateTime": "2023-10-07",
|
||||
"products": [
|
||||
"SharePoint"
|
||||
],
|
||||
"metadata": [
|
||||
{
|
||||
"key": "CLIENT-SIDE-DEV",
|
||||
"value": "React"
|
||||
},
|
||||
{
|
||||
"key": "SPFX-VERSION",
|
||||
"value": "1.18.0"
|
||||
}
|
||||
],
|
||||
"thumbnails": [
|
||||
{
|
||||
"type": "image",
|
||||
"order": 100,
|
||||
"url": "https://github.com/pnp/sp-dev-fx-webparts/raw/main/samples/react-tailwindcss/assets/example.png",
|
||||
"alt": "Web Part Preview"
|
||||
}
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"gitHubAccount": "AriGunawan",
|
||||
"pictureUrl": "https://github.com/AriGunawan.png",
|
||||
"name": "Ari Gunawan"
|
||||
}
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"name": "Build your first SharePoint client-side web part",
|
||||
"description": "Client-side web parts are client-side components that run in the context of a SharePoint page. Client-side web parts can be deployed to SharePoint environments that support the SharePoint Framework. You can also use modern JavaScript web frameworks, tools, and libraries to build them.",
|
||||
"url": "https://docs.microsoft.com/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,3 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||
"version": "2.0",
|
||||
"bundles": {
|
||||
"hello-tailwind-web-part": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/webparts/helloTailwind/HelloTailwindWebPart.js",
|
||||
"manifest": "./src/webparts/helloTailwind/HelloTailwindWebPart.manifest.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"HelloTailwindWebPartStrings": "lib/webparts/helloTailwind/loc/{locale}.js"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||
"workingDir": "./release/assets/",
|
||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||
"container": "spfx-tailwind",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "SPFx Tailwind",
|
||||
"id": "9c2d370c-9957-4e3f-b322-6b2cbd458c69",
|
||||
"version": "1.0.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": true,
|
||||
"isDomainIsolated": false,
|
||||
"developer": {
|
||||
"name": "",
|
||||
"websiteUrl": "",
|
||||
"privacyUrl": "",
|
||||
"termsOfUseUrl": "",
|
||||
"mpnId": "Undefined-1.18.0"
|
||||
},
|
||||
"metadata": {
|
||||
"shortDescription": {
|
||||
"default": "spfx-tailwind description"
|
||||
},
|
||||
"longDescription": {
|
||||
"default": "spfx-tailwind description"
|
||||
},
|
||||
"screenshotPaths": [],
|
||||
"videoUrl": "",
|
||||
"categories": []
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"title": "spfx-tailwind Feature",
|
||||
"description": "The feature that activates elements of the spfx-tailwind solution.",
|
||||
"id": "57651270-7533-41c5-bbc9-88bc9494876c",
|
||||
"version": "1.0.0.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/SPFx Tailwind.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/sass.schema.json"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/spfx-serve.schema.json",
|
||||
"port": 4321,
|
||||
"https": true,
|
||||
"initialPage": "https://yourdomain.sharepoint.com/_layouts/workbench.aspx"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
|
||||
"cdnBasePath": "<!-- PATH TO CDN -->"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"$schema": "https://raw.githubusercontent.com/s-KaiNet/spfx-fast-serve/master/schema/config.latest.schema.json",
|
||||
"cli": {
|
||||
"isLibraryComponent": false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* User webpack settings file. You can add your own settings here.
|
||||
* Changes from this file will be merged into the base webpack configuration file.
|
||||
* This file will not be overwritten by the subsequent spfx-fast-serve calls.
|
||||
*/
|
||||
|
||||
/**
|
||||
* you can add your project related webpack configuration here, it will be merged using webpack-merge module
|
||||
* i.e. plugins: [new webpack.Plugin()]
|
||||
*/
|
||||
const webpackConfig = {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* For even more fine-grained control, you can apply custom webpack settings using below function
|
||||
* @param {object} initialWebpackConfig - initial webpack config object
|
||||
* @param {object} webpack - webpack object, used by SPFx pipeline
|
||||
* @returns webpack config object
|
||||
*/
|
||||
const transformConfig = function (initialWebpackConfig, webpack) {
|
||||
// transform the initial webpack config here, i.e.
|
||||
// initialWebpackConfig.plugins.push(new webpack.Plugin()); etc.
|
||||
|
||||
return initialWebpackConfig;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
webpackConfig,
|
||||
transformConfig
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
'use strict';
|
||||
|
||||
const build = require('@microsoft/sp-build-web');
|
||||
|
||||
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
|
||||
|
||||
var getTasks = build.rig.getTasks;
|
||||
build.rig.getTasks = function () {
|
||||
var result = getTasks.call(build.rig);
|
||||
|
||||
result.set('serve', result.get('serve-deprecated'));
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/* tailwind */
|
||||
const postcss = require("gulp-postcss");
|
||||
const tailwind = require("tailwindcss");
|
||||
|
||||
const tailwindcss = build.subTask(
|
||||
"tailwindcss",
|
||||
function (gulp, buildOptions, done) {
|
||||
gulp
|
||||
.src("assets/tailwind.css")
|
||||
.pipe(
|
||||
postcss([
|
||||
tailwind("./tailwind.config.js"),
|
||||
])
|
||||
)
|
||||
.pipe(gulp.dest("assets/dist"));
|
||||
done();
|
||||
}
|
||||
);
|
||||
build.rig.addPreBuildTask(tailwindcss);
|
||||
/* end of tailwind */
|
||||
|
||||
/* fast-serve */
|
||||
const { addFastServe } = require("spfx-fast-serve-helpers");
|
||||
addFastServe(build);
|
||||
/* end of fast-serve */
|
||||
|
||||
build.initialize(require('gulp'));
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
"name": "spfx-tailwind",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=16.13.0 <17.0.0 || >=18.17.1 <19.0.0"
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"test": "gulp test",
|
||||
"serve": "gulp bundle --custom-serve --max_old_space_size=4096 && fast-serve"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluentui/react": "^8.106.4",
|
||||
"@microsoft/sp-component-base": "1.18.0",
|
||||
"@microsoft/sp-core-library": "1.18.0",
|
||||
"@microsoft/sp-lodash-subset": "1.18.0",
|
||||
"@microsoft/sp-office-ui-fabric-core": "1.18.0",
|
||||
"@microsoft/sp-property-pane": "1.18.0",
|
||||
"@microsoft/sp-webpart-base": "1.18.0",
|
||||
"react": "17.0.1",
|
||||
"react-dom": "17.0.1",
|
||||
"tslib": "2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/eslint-config-spfx": "1.18.0",
|
||||
"@microsoft/eslint-plugin-spfx": "1.18.0",
|
||||
"@microsoft/rush-stack-compiler-4.7": "0.1.0",
|
||||
"@microsoft/sp-build-web": "1.18.0",
|
||||
"@microsoft/sp-module-interfaces": "1.18.0",
|
||||
"@rushstack/eslint-config": "2.5.1",
|
||||
"@types/react": "17.0.45",
|
||||
"@types/react-dom": "17.0.17",
|
||||
"@types/webpack-env": "~1.15.2",
|
||||
"ajv": "^6.12.5",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"eslint": "8.7.0",
|
||||
"eslint-plugin-react-hooks": "4.3.0",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-postcss": "^9.0.1",
|
||||
"postcss": "^8.4.31",
|
||||
"spfx-fast-serve-helpers": "~1.18.0",
|
||||
"tailwindcss": "^3.3.3",
|
||||
"typescript": "4.7.4"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||
"id": "32d20565-ce71-49e4-ac49-ec8dd74a44fa",
|
||||
"alias": "HelloTailwindWebPart",
|
||||
"componentType": "WebPart",
|
||||
|
||||
// The "*" signifies that the version should be taken from the package.json
|
||||
"version": "*",
|
||||
"manifestVersion": 2,
|
||||
|
||||
// If true, the component can only be installed on sites where Custom Script is allowed.
|
||||
// Components that allow authors to embed arbitrary script code should set this to true.
|
||||
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
|
||||
"requiresCustomScript": false,
|
||||
"supportedHosts": ["SharePointWebPart", "TeamsPersonalApp", "TeamsTab", "SharePointFullPage"],
|
||||
"supportsThemeVariants": true,
|
||||
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Advanced
|
||||
"group": { "default": "Advanced" },
|
||||
"title": { "default": "Hello Tailwind" },
|
||||
"description": { "default": "HelloTailwind description" },
|
||||
"officeFabricIconFontName": "Color",
|
||||
"properties": {
|
||||
"description": "HelloTailwind"
|
||||
}
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
import * as React from 'react';
|
||||
import * as ReactDom from 'react-dom';
|
||||
import { Version } from '@microsoft/sp-core-library';
|
||||
import {
|
||||
type IPropertyPaneConfiguration,
|
||||
PropertyPaneTextField
|
||||
} from '@microsoft/sp-property-pane';
|
||||
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
|
||||
import { IReadonlyTheme } from '@microsoft/sp-component-base';
|
||||
|
||||
import * as strings from 'HelloTailwindWebPartStrings';
|
||||
import HelloTailwind from './components/HelloTailwind';
|
||||
import { IHelloTailwindProps } from './components/IHelloTailwindProps';
|
||||
|
||||
import '../../../assets/dist/tailwind.css';
|
||||
|
||||
export interface IHelloTailwindWebPartProps {
|
||||
description: string;
|
||||
}
|
||||
|
||||
export default class HelloTailwindWebPart extends BaseClientSideWebPart<IHelloTailwindWebPartProps> {
|
||||
|
||||
private _isDarkTheme: boolean = false;
|
||||
private _environmentMessage: string = '';
|
||||
|
||||
public render(): void {
|
||||
const element: React.ReactElement<IHelloTailwindProps> = React.createElement(
|
||||
HelloTailwind,
|
||||
{
|
||||
description: this.properties.description,
|
||||
isDarkTheme: this._isDarkTheme,
|
||||
environmentMessage: this._environmentMessage,
|
||||
hasTeamsContext: !!this.context.sdks.microsoftTeams,
|
||||
userDisplayName: this.context.pageContext.user.displayName
|
||||
}
|
||||
);
|
||||
|
||||
ReactDom.render(element, this.domElement);
|
||||
}
|
||||
|
||||
protected onInit(): Promise<void> {
|
||||
return this._getEnvironmentMessage().then(message => {
|
||||
this._environmentMessage = message;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private _getEnvironmentMessage(): Promise<string> {
|
||||
if (!!this.context.sdks.microsoftTeams) { // running in Teams, office.com or Outlook
|
||||
return this.context.sdks.microsoftTeams.teamsJs.app.getContext()
|
||||
.then(context => {
|
||||
let environmentMessage: string = '';
|
||||
switch (context.app.host.name) {
|
||||
case 'Office': // running in Office
|
||||
environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOffice : strings.AppOfficeEnvironment;
|
||||
break;
|
||||
case 'Outlook': // running in Outlook
|
||||
environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOutlook : strings.AppOutlookEnvironment;
|
||||
break;
|
||||
case 'Teams': // running in Teams
|
||||
case 'TeamsModern':
|
||||
environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentTeams : strings.AppTeamsTabEnvironment;
|
||||
break;
|
||||
default:
|
||||
environmentMessage = strings.UnknownEnvironment;
|
||||
}
|
||||
|
||||
return environmentMessage;
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve(this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentSharePoint : strings.AppSharePointEnvironment);
|
||||
}
|
||||
|
||||
protected onThemeChanged(currentTheme: IReadonlyTheme | undefined): void {
|
||||
if (!currentTheme) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isDarkTheme = !!currentTheme.isInverted;
|
||||
const {
|
||||
semanticColors
|
||||
} = currentTheme;
|
||||
|
||||
if (semanticColors) {
|
||||
this.domElement.style.setProperty('--bodyText', semanticColors.bodyText || null);
|
||||
this.domElement.style.setProperty('--link', semanticColors.link || null);
|
||||
this.domElement.style.setProperty('--linkHovered', semanticColors.linkHovered || null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected onDispose(): void {
|
||||
ReactDom.unmountComponentAtNode(this.domElement);
|
||||
}
|
||||
|
||||
protected get dataVersion(): Version {
|
||||
return Version.parse('1.0');
|
||||
}
|
||||
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
header: {
|
||||
description: strings.PropertyPaneDescription
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
groupName: strings.BasicGroupName,
|
||||
groupFields: [
|
||||
PropertyPaneTextField('description', {
|
||||
label: strings.DescriptionFieldLabel
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,41 @@
|
|||
import * as React from 'react';
|
||||
import type { IHelloTailwindProps } from './IHelloTailwindProps';
|
||||
import { escape } from '@microsoft/sp-lodash-subset';
|
||||
|
||||
export default class HelloTailwind extends React.Component<IHelloTailwindProps, {}> {
|
||||
public render(): React.ReactElement<IHelloTailwindProps> {
|
||||
const {
|
||||
description,
|
||||
isDarkTheme,
|
||||
environmentMessage,
|
||||
userDisplayName
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<section className='tw-overflow-hidden tw-p-4 tw-text-black'>
|
||||
<div className='tw-text-center'>
|
||||
<img alt="" src={isDarkTheme ? require('../assets/welcome-dark.png') : require('../assets/welcome-light.png')} className='tw-m-auto tw-w-full tw-max-w-[420px]' />
|
||||
<h2 className='tw-text-2xl'>Well done, {escape(userDisplayName)}!</h2>
|
||||
<div>{environmentMessage}</div>
|
||||
<div>Web part property value: <strong>{escape(description)}</strong></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className='tw-text-xl tw-text-red-600 tw-mb-2'>Welcome to SharePoint Framework!</h3>
|
||||
<p>
|
||||
The SharePoint Framework (SPFx) is a extensibility model for Microsoft Viva, Microsoft Teams and SharePoint. It's the easiest way to extend Microsoft 365 with automatic Single Sign On, automatic hosting and industry standard tooling.
|
||||
</p>
|
||||
<h4 className='tw-text-lg tw-mt-2'>Learn more about SPFx development:</h4>
|
||||
<ul className='[&_a]:tw-underline [&_a]:tw-text-blue-600'>
|
||||
<li><a href="https://aka.ms/spfx" target="_blank" rel="noreferrer">SharePoint Framework Overview</a></li>
|
||||
<li><a href="https://aka.ms/spfx-yeoman-graph" target="_blank" rel="noreferrer">Use Microsoft Graph in your solution</a></li>
|
||||
<li><a href="https://aka.ms/spfx-yeoman-teams" target="_blank" rel="noreferrer">Build for Microsoft Teams using SharePoint Framework</a></li>
|
||||
<li><a href="https://aka.ms/spfx-yeoman-viva" target="_blank" rel="noreferrer">Build for Microsoft Viva Connections using SharePoint Framework</a></li>
|
||||
<li><a href="https://aka.ms/spfx-yeoman-store" target="_blank" rel="noreferrer">Publish SharePoint Framework applications to the marketplace</a></li>
|
||||
<li><a href="https://aka.ms/spfx-yeoman-api" target="_blank" rel="noreferrer">SharePoint Framework API reference</a></li>
|
||||
<li><a href="https://aka.ms/m365pnp" target="_blank" rel="noreferrer">Microsoft 365 Developer Community</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export interface IHelloTailwindProps {
|
||||
description: string;
|
||||
isDarkTheme: boolean;
|
||||
environmentMessage: string;
|
||||
hasTeamsContext: boolean;
|
||||
userDisplayName: string;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Description",
|
||||
"BasicGroupName": "Group Name",
|
||||
"DescriptionFieldLabel": "Description Field",
|
||||
"AppLocalEnvironmentSharePoint": "The app is running on your local environment as SharePoint web part",
|
||||
"AppLocalEnvironmentTeams": "The app is running on your local environment as Microsoft Teams app",
|
||||
"AppLocalEnvironmentOffice": "The app is running on your local environment in office.com",
|
||||
"AppLocalEnvironmentOutlook": "The app is running on your local environment in Outlook",
|
||||
"AppSharePointEnvironment": "The app is running on SharePoint page",
|
||||
"AppTeamsTabEnvironment": "The app is running in Microsoft Teams",
|
||||
"AppOfficeEnvironment": "The app is running in office.com",
|
||||
"AppOutlookEnvironment": "The app is running in Outlook",
|
||||
"UnknownEnvironment": "The app is running in an unknown environment"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,19 @@
|
|||
declare interface IHelloTailwindWebPartStrings {
|
||||
PropertyPaneDescription: string;
|
||||
BasicGroupName: string;
|
||||
DescriptionFieldLabel: string;
|
||||
AppLocalEnvironmentSharePoint: string;
|
||||
AppLocalEnvironmentTeams: string;
|
||||
AppLocalEnvironmentOffice: string;
|
||||
AppLocalEnvironmentOutlook: string;
|
||||
AppSharePointEnvironment: string;
|
||||
AppTeamsTabEnvironment: string;
|
||||
AppOfficeEnvironment: string;
|
||||
AppOutlookEnvironment: string;
|
||||
UnknownEnvironment: string;
|
||||
}
|
||||
|
||||
declare module 'HelloTailwindWebPartStrings' {
|
||||
const strings: IHelloTailwindWebPartStrings;
|
||||
export = strings;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
prefix: 'tw-',
|
||||
content: ["./src/**/*.{html,js,tsx}"],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
After Width: | Height: | Size: 249 B |
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"extends": "./node_modules/@microsoft/rush-stack-compiler-4.7/includes/tsconfig-web.json",
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "lib",
|
||||
"inlineSources": false,
|
||||
"noImplicitAny": true,
|
||||
|
||||
"typeRoots": [
|
||||
"./node_modules/@types",
|
||||
"./node_modules/@microsoft"
|
||||
],
|
||||
"types": [
|
||||
"webpack-env"
|
||||
],
|
||||
"lib": [
|
||||
"es5",
|
||||
"dom",
|
||||
"es2015.collection",
|
||||
"es2015.promise"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue