Merge branch 'master' into master
|
@ -7174,8 +7174,8 @@ xtend@~3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a"
|
||||
|
||||
y18n@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696"
|
||||
|
||||
yallist@^2.0.0:
|
||||
version "2.1.2"
|
||||
|
|
|
@ -9089,8 +9089,8 @@ xtend@~3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a"
|
||||
|
||||
y18n@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696"
|
||||
|
||||
y18n@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
|
|
@ -17546,9 +17546,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
|
|
|
@ -192,9 +192,10 @@
|
|||
},
|
||||
{
|
||||
"gitHubAccount": "mohammadamer",
|
||||
"company": "",
|
||||
"pictureUrl": "https://github.com/mohammadamer.png",
|
||||
"name": "Mohammed Amer"
|
||||
"company": "Atea Global Services",
|
||||
"pictureUrl": "https://avatars.githubusercontent.com/u/19314043?s=460&u=79acb7fd0ad466e1040ddd8a739fa93385018b81&v=4",
|
||||
"name": "Mohammed Amer",
|
||||
"twitter": "Mohammad3mer"
|
||||
}
|
||||
],
|
||||
"references": [
|
||||
|
|
|
@ -176,7 +176,7 @@ export class Event extends React.Component<IEventProps, IEventState> {
|
|||
}
|
||||
else {
|
||||
if (this.state.eventData.EventType == '1') { // recurrence exception
|
||||
eventData.RecurrenceID = eventData.EventDate.toString();
|
||||
eventData.RecurrenceID = eventData.EventDate;
|
||||
eventData.MasterSeriesItemID = eventData.ID.toString();
|
||||
eventData.EventType = "4";
|
||||
eventData.fRecurrence = true;
|
||||
|
|
|
@ -20,6 +20,6 @@ export interface IEventData {
|
|||
fRecurrence?: string | boolean;
|
||||
EventType?: string;
|
||||
UID?: string;
|
||||
RecurrenceID?: string;
|
||||
RecurrenceID?: Date;
|
||||
MasterSeriesItemID?: string;
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ export default class spservices {
|
|||
UID: newEvent.UID,
|
||||
RecurrenceData: newEvent.RecurrenceData ? await this.deCodeHtmlEntities(newEvent.RecurrenceData) : "",
|
||||
MasterSeriesItemID: newEvent.MasterSeriesItemID,
|
||||
RecurrenceID: newEvent.RecurrenceID ? await this.getUtcTime(newEvent.RecurrenceID) : undefined,
|
||||
RecurrenceID: newEvent.RecurrenceID ? newEvent.RecurrenceID : undefined,
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
|
@ -240,7 +240,7 @@ export default class spservices {
|
|||
switch (event.EventType.toString()) {
|
||||
case '4': // Exception Recurrence Event
|
||||
results = await web.lists.getById(listId).items.getById(event.Id).update({
|
||||
Title: `Delete: ${event.title}`,
|
||||
Title: `Deleted: ${event.title}`,
|
||||
EventType: '3',
|
||||
});
|
||||
break;
|
||||
|
@ -251,9 +251,10 @@ export default class spservices {
|
|||
await this.deleteRecurrenceExceptions(event, siteUrl, listId);
|
||||
await web.lists.getById(listId).items.getById(event.Id).delete();
|
||||
} else {
|
||||
// delete a single recurrence Exception. add new entry with eventtype 3
|
||||
|
||||
event.RecurrenceID = event.EventDate.toString();
|
||||
//Applying the Standard funactionality of SharePoint When deleting for deleting one occurrence of recurrent event by
|
||||
// 1) adding prefix "Deleted" to event title 2) Set RecurrenceID to event Date 3) Set MasterSeriesItemID to event ID 4)Set fRecurrence to true 5) Set event type to 3
|
||||
event.title = `Deleted: ${event.title}`;
|
||||
event.RecurrenceID = event.EventDate;
|
||||
event.MasterSeriesItemID = event.ID.toString();
|
||||
event.fRecurrence = true;
|
||||
event.EventType = '3';
|
||||
|
@ -532,7 +533,7 @@ export default class spservices {
|
|||
Duration: event.Duration,
|
||||
RecurrenceData: event.RecurrenceData ? await this.deCodeHtmlEntities(event.RecurrenceData) : "",
|
||||
fRecurrence: event.fRecurrence,
|
||||
RecurrenceID: event.RecurrenceID ? await this.getLocalTime(event.RecurrenceID) : undefined,
|
||||
RecurrenceID: event.RecurrenceID ? event.RecurrenceID : undefined,
|
||||
MasterSeriesItemID: event.MasterSeriesItemID,
|
||||
UID: event.UID.replace("{", "").replace("}", ""),
|
||||
});
|
||||
|
|
|
@ -12571,9 +12571,9 @@
|
|||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
|
||||
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
|
@ -17867,9 +17867,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
[*]
|
||||
|
||||
# change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# we recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[{package,bower}.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
|
@ -0,0 +1,32 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
|
||||
# Build generated files
|
||||
dist
|
||||
lib
|
||||
solution
|
||||
temp
|
||||
*.sppkg
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Visual Studio files
|
||||
.ntvs_analysis.dat
|
||||
.vs
|
||||
bin
|
||||
obj
|
||||
|
||||
# Resx Generated Code
|
||||
*.resx.ts
|
||||
|
||||
# Styles Generated Code
|
||||
*.scss.ts
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"@microsoft/generator-sharepoint": {
|
||||
"isCreatingSolution": true,
|
||||
"environment": "onprem19",
|
||||
"version": "1.11.0",
|
||||
"libraryName": "react-image-editor",
|
||||
"libraryId": "e859f86f-7a12-40e3-94fb-97ee47419aed",
|
||||
"packageManager": "npm",
|
||||
"componentType": "webpart"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
---
|
||||
page_type: sample
|
||||
products:
|
||||
- office-sp
|
||||
languages:
|
||||
- javascript
|
||||
- typescript
|
||||
extensions:
|
||||
contentType: samples
|
||||
technologies:
|
||||
- SharePoint Framework
|
||||
platforms:
|
||||
- React
|
||||
createdDate: 3/17/2021 12:00:00 AM
|
||||
---
|
||||
|
||||
# React Image Editor
|
||||
|
||||
|
||||
## Summary
|
||||
|
||||
This solution contains an SPFx web part that shows an HTML Image Editor based on canvas and [Office UI Fabric](https://developer.microsoft.com/fluentui/).
|
||||
|
||||
Key features of the Editor
|
||||
|
||||
* Resize
|
||||
* Crop
|
||||
* Flip
|
||||
* Rotate
|
||||
* Scale
|
||||
* Filter (Grayscale / Sepia)
|
||||
* Redo / Undo
|
||||
* Histoy of Actions
|
||||
|
||||
The Placeholder and FilePicker are components from the [sp-dev-fx-controls-react ](https://pnp.github.io/sp-dev-fx-controls-react/)
|
||||
|
||||
![react-image-editor in action](assets/react-image-editor.gif)
|
||||
|
||||
|
||||
## Compatibility
|
||||
|
||||
![SPFx 1.4.0](https://img.shields.io/badge/SPFx-1.4.0-green.svg)
|
||||
![Node.js LTS 6.x](https://img.shields.io/badge/Node.js-LTS%206.x-green.svg)
|
||||
![SharePoint 2019 | Online](https://img.shields.io/badge/SharePoint-2019%20%7C%20Online-yellow.svg)
|
||||
![Teams No: Not designed for Microsoft Teams](https://img.shields.io/badge/Teams-No-red.svg "Not designed for Microsoft Teams")
|
||||
![Workbench Local | Hosted](https://img.shields.io/badge/Workbench-Local%20%7C%20Hosted-green.svg)
|
||||
|
||||
References to office-ui-fabric-react version 5.x because of SharePoint 2019 Support
|
||||
|
||||
## Applies to
|
||||
|
||||
- [SharePoint Framework](https://aka.ms/spfx)
|
||||
- [Microsoft 365 tenant](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||
|
||||
> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
> SharePoint Online or SharePoint 2019
|
||||
|
||||
## Solution
|
||||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
react-image-editor | Peter Paul Kirschner ([@petkir_at](https://twitter.com/petkir_at))
|
||||
|
||||
Thanks to [celum](https://www.celum.com/) and [cubido](https://www.cubido.at/) to allow to share this code.
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0.0.0|Mar 17, 2021|Initial release
|
||||
|
||||
## 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.**
|
||||
|
||||
---
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
- Clone this repository
|
||||
- Ensure that you are at the solution folder
|
||||
- in the command-line run:
|
||||
- **npm install**
|
||||
- edit config\serve.json set "initialPage": "https://{tenant}.sharepoint.com/_layouts/15/workbench.aspx"
|
||||
- **gulp serve**
|
||||
|
||||
> Include any additional steps as needed.
|
||||
|
||||
## Usage
|
||||
|
||||
* PNP Placeholder control if not Configured
|
||||
* PNP WebPartTitle control (toggle Show/Hide in property pane)
|
||||
* PNP FilePicker control to pick Images (is mocked on local workbench)
|
||||
* Office UI Fabric
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- [Getting started with SharePoint Framework](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
|
||||
- [Building for Microsoft teams](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/build-for-teams-overview)
|
||||
- [Use Microsoft Graph in your solution](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/using-microsoft-graph-apis)
|
||||
- [Publish SharePoint Framework applications to the Marketplace](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/publish-to-marketplace-overview)
|
||||
- [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - Guidance, tooling, samples and open-source controls for your Microsoft 365 development
|
||||
|
||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-image-editor" />
|
After Width: | Height: | Size: 9.0 MiB |
|
@ -0,0 +1,65 @@
|
|||
[
|
||||
{
|
||||
"name": "pnp-sp-dev-spfx-web-parts-react-image-editor",
|
||||
"source": "pnp",
|
||||
"title": "Image Editor",
|
||||
"shortDescription": "This solution contains an SPFx web part that shows an HTML Image Editor based on canvas and Office UI Fabric",
|
||||
"url": "https://github.com/pnp/sp-dev-fx-webparts/tree/master/samples/react-image-editor",
|
||||
"longDescription": [
|
||||
"This solution contains an SPFx web part that shows an HTML Image Editor based on canvas and Office UI Fabric ",
|
||||
"Key features of the Editor",
|
||||
"* Resize",
|
||||
"* Crop",
|
||||
"* Flip",
|
||||
"* Rotate",
|
||||
"* Scale",
|
||||
"* Filter (Grayscale / Sepia)",
|
||||
"* Redo / Undo",
|
||||
"* Histoy of Actions"
|
||||
],
|
||||
"created": "2021-03-17",
|
||||
"modified": "2021-03-17",
|
||||
"products": [
|
||||
"SharePoint",
|
||||
"Office"
|
||||
],
|
||||
"metadata": [
|
||||
{
|
||||
"key": "CLIENT-SIDE-DEV",
|
||||
"value": "React"
|
||||
},
|
||||
{
|
||||
"key": "SPFX-VERSION",
|
||||
"value": "1.4.0"
|
||||
},
|
||||
{
|
||||
"key": "SPFX-TEAMSTAB",
|
||||
"value": "false"
|
||||
}
|
||||
],
|
||||
"thumbnails": [
|
||||
{
|
||||
"type": "image",
|
||||
"order": 100,
|
||||
"url": "https://github.com/pnp/sp-dev-fx-webparts/raw/master/samples/react-image-editor/assets/react-image-editor.gif",
|
||||
"alt": "React Image Editor Web part"
|
||||
}
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"gitHubAccount": "petkir",
|
||||
"company": "Cubido Business Solutions GmbH",
|
||||
"pictureUrl": "https://github.com/petkir.png",
|
||||
"name": "Peter Paul Kirschner",
|
||||
"twitter": "petkir_at"
|
||||
}
|
||||
],
|
||||
"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/en-us/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||
"version": "2.0",
|
||||
"bundles": {
|
||||
"react-image-editor-web-part": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/webparts/reactImageEditor/ReactImageEditorWebPart.js",
|
||||
"manifest": "./src/webparts/reactImageEditor/ReactImageEditorWebPart.manifest.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"externals": {},
|
||||
"localizedResources": {
|
||||
"ReactImageEditorWebPartStrings": "lib/webparts/reactImageEditor/loc/{locale}.js",
|
||||
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js",
|
||||
"ImageManipulationStrings": "lib/components/ImageManipulation/loc/{locale}.js"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
|
||||
"deployCdnPath": "temp/deploy"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
|
||||
"workingDir": "./temp/deploy/",
|
||||
"account": "<!-- STORAGE ACCOUNT NAME -->",
|
||||
"container": "react-image-editor",
|
||||
"accessKey": "<!-- ACCESS KEY -->"
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "react-image-editor-client-side-solution",
|
||||
"id": "e859f86f-7a12-40e3-94fb-97ee47419aed",
|
||||
"version": "1.0.0.0",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": true
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/react-image-editor.sppkg"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
|
||||
"port": 4321,
|
||||
"https": true,
|
||||
"initialPage": "https://contoso.sharepoint.com/_layouts/15/workbench.aspx",
|
||||
"api": {
|
||||
"port": 5432,
|
||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
|
||||
"cdnBasePath": "<!-- PATH TO CDN -->"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
'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.`);
|
||||
|
||||
build.initialize(require('gulp'));
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"name": "react-image-editor",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"main": "lib/index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
"clean": "gulp clean",
|
||||
"test": "gulp test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/sp-core-library": "~1.4.0",
|
||||
"@microsoft/sp-lodash-subset": "~1.4.0",
|
||||
"@microsoft/sp-office-ui-fabric-core": "~1.4.0",
|
||||
"@microsoft/sp-webpart-base": "~1.4.0",
|
||||
"@pnp/spfx-controls-react": "^1.21.1",
|
||||
"office-ui-fabric-react": "5.131.0",
|
||||
"react": "15.6.2",
|
||||
"react-dom": "15.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "15.6.6",
|
||||
"@types/react-dom": "15.5.6",
|
||||
"@microsoft/sp-build-web": "~1.4.1",
|
||||
"@microsoft/sp-module-interfaces": "~1.4.1",
|
||||
"@microsoft/sp-webpart-workbench": "~1.4.1",
|
||||
"gulp": "~3.9.1",
|
||||
"@types/chai": "3.4.34",
|
||||
"@types/mocha": "2.2.38",
|
||||
"ajv": "~5.2.2",
|
||||
"@types/webpack-env": "1.13.1",
|
||||
"@types/es6-promise": "0.0.33"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import { IImageFilter } from './IImageFilter';
|
||||
|
||||
export class GrayscaleFilter implements IImageFilter {
|
||||
public process(imageData: ImageData, width: number, height: number, nvalue?: number, svalue?: string): ImageData {
|
||||
const data: Uint8ClampedArray = imageData.data;
|
||||
|
||||
// Get length of all pixels in image each pixel made up of
|
||||
// 4 elements for each pixel, one for Red, Green, Blue and Alpha
|
||||
const arraylength: number = width * height * 4;
|
||||
// Common formula for converting to grayscale.
|
||||
// gray = 0.3*R + 0.59*G + 0.11*B
|
||||
for (let i: number = arraylength - 1; i > 0; i -= 4) {
|
||||
// R= i-3, G = i-2 and B = i-1
|
||||
// Get our gray shade using the formula
|
||||
const gray: number = 0.3 * data[i - 3] + 0.59 * data[i - 2] + 0.11 * data[i - 1];
|
||||
data[i - 3] = gray;
|
||||
data[i - 2] = gray;
|
||||
data[i - 1] = gray;
|
||||
}
|
||||
|
||||
return (imageData);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export interface IImageFilter {
|
||||
// describing function,
|
||||
// parameters are in left side parenthesis,
|
||||
// right side 'string' is return type
|
||||
process(imageData: ImageData, width: number, height: number, nvalue?: number, svalue?: string): ImageData;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import { IImageFilter } from './IImageFilter';
|
||||
|
||||
export class SepiaFilter implements IImageFilter {
|
||||
// tslint:disable-next-line: max-line-length
|
||||
private r: number[] = [
|
||||
0, 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 19, 19, 20, 21, 22, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 44, 45, 47, 48, 49, 52, 54, 55, 57, 59, 60, 62, 65, 67, 69, 70, 72, 74, 77, 79, 81, 83, 86, 88, 90, 92, 94, 97, 99, 101, 103, 107, 109, 111, 112, 116, 118, 120, 124, 126, 127, 129, 133, 135, 136, 140, 142, 143, 145, 149, 150, 152, 155, 157, 159, 162, 163, 165, 167, 170, 171, 173, 176, 177, 178, 180, 183, 184, 185, 188, 189, 190, 192, 194, 195, 196, 198, 200, 201, 202, 203, 204, 206, 207, 208, 209, 211, 212, 213, 214, 215, 216, 218, 219, 219, 220, 221, 222, 223, 224, 225, 226, 227, 227, 228, 229, 229, 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 244, 244, 245, 245, 245, 246, 247, 247, 248, 248, 249, 249, 249, 250, 251, 251, 252, 252, 252, 253, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
|
||||
];
|
||||
|
||||
// tslint:disable-next-line: max-line-length
|
||||
private g: number[] = [
|
||||
0, 0, 1, 2, 2, 3, 5, 5, 6, 7, 8, 8, 10, 11, 11, 12, 13, 15, 15, 16, 17, 18, 18, 19, 21, 22, 22, 23, 24, 26, 26, 27, 28, 29, 31, 31, 32, 33, 34, 35, 35, 37, 38, 39, 40, 41, 43, 44, 44, 45, 46, 47, 48, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 83, 84, 85, 86, 88, 89, 90, 92, 93, 94, 95, 96, 97, 100, 101, 102, 103, 105, 106, 107, 108, 109, 111, 113, 114, 115, 117, 118, 119, 120, 122, 123, 124, 126, 127, 128, 129, 131, 132, 133, 135, 136, 137, 138, 140, 141, 142, 144, 145, 146, 148, 149, 150, 151, 153, 154, 155, 157, 158, 159, 160, 162, 163, 164, 166, 167, 168, 169, 171, 172, 173, 174, 175, 176, 177, 178, 179, 181, 182, 183, 184, 186, 186, 187, 188, 189, 190, 192, 193, 194, 195, 195, 196, 197, 199, 200, 201, 202, 202, 203, 204, 205, 206, 207, 208, 208, 209, 210, 211, 212, 213, 214, 214, 215, 216, 217, 218, 219, 219, 220, 221, 222, 223, 223, 224, 225, 226, 226, 227, 228, 228, 229, 230, 231, 232, 232, 232, 233, 234, 235, 235, 236, 236, 237, 238, 238, 239, 239, 240, 240, 241, 242, 242, 242, 243, 244, 245, 245, 246, 246, 247, 247, 248, 249, 249, 249, 250, 251, 251, 252, 252, 252, 253, 254, 255
|
||||
];
|
||||
|
||||
// tslint:disable-next-line: max-line-length
|
||||
private b: number[] = [
|
||||
53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59, 60, 61, 61, 61, 62, 62, 63, 63, 63, 64, 65, 65, 65, 66, 66, 67, 67, 67, 68, 69, 69, 69, 70, 70, 71, 71, 72, 73, 73, 73, 74, 74, 75, 75, 76, 77, 77, 78, 78, 79, 79, 80, 81, 81, 82, 82, 83, 83, 84, 85, 85, 86, 86, 87, 87, 88, 89, 89, 90, 90, 91, 91, 93, 93, 94, 94, 95, 95, 96, 97, 98, 98, 99, 99, 100, 101, 102, 102, 103, 104, 105, 105, 106, 106, 107, 108, 109, 109, 110, 111, 111, 112, 113, 114, 114, 115, 116, 117, 117, 118, 119, 119, 121, 121, 122, 122, 123, 124, 125, 126, 126, 127, 128, 129, 129, 130, 131, 132, 132, 133, 134, 134, 135, 136, 137, 137, 138, 139, 140, 140, 141, 142, 142, 143, 144, 145, 145, 146, 146, 148, 148, 149, 149, 150, 151, 152, 152, 153, 153, 154, 155, 156, 156, 157, 157, 158, 159, 160, 160, 161, 161, 162, 162, 163, 164, 164, 165, 165, 166, 166, 167, 168, 168, 169, 169, 170, 170, 171, 172, 172, 173, 173, 174, 174, 175, 176, 176, 177, 177, 177, 178, 178, 179, 180, 180, 181, 181, 181, 182, 182, 183, 184, 184, 184, 185, 185, 186, 186, 186, 187, 188, 188, 188, 189, 189, 189, 190, 190, 191, 191, 192, 192, 193, 193, 193, 194, 194, 194, 195, 196, 196, 196, 197, 197, 197, 198, 199
|
||||
];
|
||||
private noise: number = 0;
|
||||
public process(imageData: ImageData, _width: number, _height: number, nvalue?: number, _svalue?: string): ImageData {
|
||||
// var data: Uint8ClampedArray = imageData.data;
|
||||
this.noise = nvalue;
|
||||
for (let i: number = 0; i < imageData.data.length; i += 4) {
|
||||
// change image colors
|
||||
imageData.data[i] = this.r[imageData.data[i]];
|
||||
imageData.data[i + 1] = this.g[imageData.data[i + 1]];
|
||||
imageData.data[i + 2] = this.b[imageData.data[i + 2]];
|
||||
|
||||
if (this.noise > 0) {
|
||||
this.noise = Math.round(this.noise - Math.random() * this.noise);
|
||||
for (let j: number = 0; j < 3; j++) {
|
||||
const iPN: number = this.noise + imageData.data[i + j];
|
||||
imageData.data[i + j] = (iPN > 255) ? 255 : iPN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (imageData);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import { Icon } from 'office-ui-fabric-react';
|
||||
import * as React from 'react';
|
||||
import styles from './ImageManipulation.module.scss';
|
||||
|
||||
import {
|
||||
IImageManipulationSettings,
|
||||
manipulationTypeData,
|
||||
IManipulationTypeDataDetails } from './ImageManipulation.types';
|
||||
|
||||
// tslint:disable-next-line: typedef
|
||||
export const historyItem = (item: IImageManipulationSettings, _index: number): JSX.Element => {
|
||||
if (!item) {
|
||||
return undefined;
|
||||
}
|
||||
const data: IManipulationTypeDataDetails = manipulationTypeData[item.type];
|
||||
|
||||
const detailrender: JSX.Element = data.toHTML(item);
|
||||
return (
|
||||
<span className={styles.historyItem}>
|
||||
<span className={styles.historyItemIcon}>{data.svgIcon ?
|
||||
// tslint:disable-next-line: react-a11y-img-has-alt
|
||||
<img className={styles.historyItemSvg} src={data.svgIcon} /> :
|
||||
<Icon iconName={data.iconName} />}</span>
|
||||
<span className={styles.historyItemText}>{data.text}</span>
|
||||
<span className={styles.historyItemDetails}>{detailrender}</span>
|
||||
</span>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,63 @@
|
|||
|
||||
|
||||
.historyItem {
|
||||
.historyItemText,
|
||||
.historyItemIcon{
|
||||
padding-right: 6px;
|
||||
}
|
||||
.historyItemDetails{
|
||||
display: inline;
|
||||
}
|
||||
.historyItemSvg{
|
||||
margin-bottom: -3px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
.svgbuttonPanel {
|
||||
height: 40px;
|
||||
}
|
||||
.buttonHolderPanel {
|
||||
&>button {
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
.imageEditor{
|
||||
width: 100%;
|
||||
position: relative;
|
||||
.commandBar{
|
||||
position: absolute;
|
||||
top:-32px;
|
||||
button {
|
||||
background-color: lightgray;
|
||||
}
|
||||
.svgbutton {
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
.imageplaceholder{
|
||||
position: relative;
|
||||
}
|
||||
.canvasmaxwidth{
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
.iconbtn {
|
||||
min-width: 32px;
|
||||
width: 32px;
|
||||
padding: 10px 2px;
|
||||
margin-right: 3px;
|
||||
height: 50px;
|
||||
&>div{
|
||||
display: inline-block;
|
||||
}
|
||||
.imgtext{
|
||||
display: block;
|
||||
}
|
||||
.imgicon{
|
||||
display: block;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
import * as React from 'react';
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
const colorFilterIcon: any = require('../../svg/colorFilter.svg');
|
||||
// tslint:disable-next-line: no-any
|
||||
const cropIcon: any = require('../../svg/crop.svg');
|
||||
// tslint:disable-next-line: no-any
|
||||
const flipVerticalIcon: any = require('../../svg/flipVertical.svg');
|
||||
// tslint:disable-next-line: no-any
|
||||
const resizeIcon: any = require('../../svg/resize.svg');
|
||||
import * as strings from 'ImageManipulationStrings';
|
||||
|
||||
|
||||
|
||||
export enum SettingPanelType {
|
||||
Closed = 1,
|
||||
Filter = 2,
|
||||
Flip = 3,
|
||||
Rotate = 4,
|
||||
Scale = 5,
|
||||
Crop = 6,
|
||||
Resize = 7,
|
||||
History = 99
|
||||
}
|
||||
|
||||
export enum FilterType {
|
||||
Grayscale,
|
||||
Sepia
|
||||
/*
|
||||
Blur,
|
||||
Emboss,
|
||||
Sepia2,
|
||||
Invert,
|
||||
Sharpen,
|
||||
RemoteWhite,
|
||||
Brightness,
|
||||
Noise,
|
||||
Pixelate,
|
||||
ColorOverLay*/
|
||||
}
|
||||
|
||||
export interface ICrop {
|
||||
sx: number;
|
||||
sy: number;
|
||||
width: number;
|
||||
height: number;
|
||||
aspect?: number;
|
||||
}
|
||||
|
||||
export interface IResize {
|
||||
width: number;
|
||||
height: number;
|
||||
aspect?: number;
|
||||
}
|
||||
|
||||
export enum ManipulationType {
|
||||
Crop,
|
||||
Scale,
|
||||
Rotate,
|
||||
Flip,
|
||||
Filter,
|
||||
Resize
|
||||
}
|
||||
export interface IManipulationBase {
|
||||
type: ManipulationType;
|
||||
}
|
||||
export interface ICropSettings extends IManipulationBase, ICrop {
|
||||
}
|
||||
export interface IFlipSettings extends IManipulationBase {
|
||||
flipX: boolean;
|
||||
flipY: boolean;
|
||||
}
|
||||
export interface IScaleSettings extends IManipulationBase {
|
||||
scale: number;
|
||||
}
|
||||
export interface IRotateSettings extends IManipulationBase {
|
||||
rotate: number;
|
||||
}
|
||||
export interface IFilterSettings extends IManipulationBase {
|
||||
filterType: FilterType;
|
||||
nvalue?: number;
|
||||
svalue?: string;
|
||||
}
|
||||
export interface IResizeSettings extends IManipulationBase, IResize {
|
||||
}
|
||||
export type IImageManipulationSettings = IFilterSettings | IRotateSettings |
|
||||
IScaleSettings | IFlipSettings | ICropSettings | IResizeSettings;
|
||||
|
||||
|
||||
export const filterTypeData: IFilterTypeData = {
|
||||
0: strings.FilterTypeGrayscale,
|
||||
1: strings.FilterTypeSepia
|
||||
};
|
||||
|
||||
export interface IFilterTypeData {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface IManipulationTypeDataBase {
|
||||
text: string;
|
||||
iconName?: string;
|
||||
// tslint:disable-next-line: no-any
|
||||
svgIcon?: any;
|
||||
settingPanelType: SettingPanelType;
|
||||
}
|
||||
|
||||
export interface IManipulationTypeData {
|
||||
[key: string]: IManipulationTypeDataDetails;
|
||||
}
|
||||
|
||||
export interface IManipulationTypeDataDetails extends IManipulationTypeDataBase {
|
||||
toHTML: (item: IImageManipulationSettings) => JSX.Element;
|
||||
}
|
||||
|
||||
export const manipulationTypeData: IManipulationTypeData = {
|
||||
0: {
|
||||
text: strings.ManipulationTypeCrop,
|
||||
svgIcon: cropIcon,
|
||||
toHTML: (item: ICropSettings) => {
|
||||
return (<span></span>);
|
||||
// return (<span>{`X:${item.sx} Y:${item.sy}`}</span>);
|
||||
},
|
||||
settingPanelType: SettingPanelType.Crop
|
||||
},
|
||||
1: {
|
||||
text: strings.ManipulationTypeScale,
|
||||
iconName: 'Zoom',
|
||||
toHTML: (item: IScaleSettings) => { return (<span></span>); },
|
||||
settingPanelType: SettingPanelType.Scale
|
||||
},
|
||||
2: {
|
||||
text: strings.ManipulationTypeRotate,
|
||||
iconName: 'Rotate',
|
||||
toHTML: (item: IRotateSettings) => { return (<span></span>); },
|
||||
settingPanelType: SettingPanelType.Rotate
|
||||
},
|
||||
3: {
|
||||
text: strings.ManipulationTypeFlip,
|
||||
svgIcon: flipVerticalIcon,
|
||||
toHTML: (item: IFlipSettings) => { return (<span></span>); },
|
||||
settingPanelType: SettingPanelType.Flip
|
||||
},
|
||||
4: {
|
||||
text: strings.ManipulationTypeFilter,
|
||||
svgIcon: colorFilterIcon,
|
||||
toHTML: (item: IFilterSettings) => {
|
||||
return (<span>{filterTypeData[item.filterType]}</span>);
|
||||
},
|
||||
settingPanelType: SettingPanelType.Filter
|
||||
},
|
||||
5: {
|
||||
text: strings.ManipulationTypeResize,
|
||||
iconName: 'SizeLegacy',
|
||||
svgIcon: resizeIcon,
|
||||
toHTML: (item: IResizeSettings) => { return (<span></span>); },
|
||||
settingPanelType: SettingPanelType.Resize
|
||||
}
|
||||
};
|
|
@ -0,0 +1,31 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;"></canvas>
|
||||
<script>
|
||||
|
||||
const img= new Image()
|
||||
img.crossOrigin = "Anonymous";
|
||||
img.addEventListener("load", imageReceived, false);
|
||||
img.src = 'https://pnp.github.io/images/hero-parker-p-800.png';
|
||||
|
||||
|
||||
function imageReceived() {
|
||||
const c = document.getElementById("myCanvas");
|
||||
const ctx = c.getContext("2d");
|
||||
c.width = img.width;
|
||||
c.height = img.height;
|
||||
|
||||
ctx.translate(0, c.height);
|
||||
ctx.scale(1, -1);
|
||||
|
||||
ctx.drawImage(img, 0, 0);
|
||||
ctx.font = "30px Arial";
|
||||
ctx.strokeText("Hello PnP-Community",10,50);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
export enum nodePoition {
|
||||
NW,
|
||||
N,
|
||||
NE,
|
||||
E,
|
||||
SE,
|
||||
S,
|
||||
SW,
|
||||
W
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
$drag-handle-width: 10px !default;
|
||||
$drag-handle-height: 10px !default;
|
||||
$drag-bar-size: 6px !default;
|
||||
|
||||
// Query to kick us into "mobile" mode with larger drag handles/bars.
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer
|
||||
$mobile-media-query: '(pointer: coarse)' !default;
|
||||
|
||||
// Mobile handle/bar sizes. Override as above.
|
||||
$drag-handle-mobile-width: 24px !default;
|
||||
$drag-handle-mobile-height: 24px !default;
|
||||
|
||||
// Handle color/border.
|
||||
$drag-handle-background-colour: rgba(0, 0, 0, 0.2) !default;
|
||||
$drag-handle-border: 1px solid rgba(255, 255, 255, 0.7) !default;
|
||||
|
||||
.ImgGridShadowOverlay{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ImgGridVisible {
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
right: 0;
|
||||
bottom:0;
|
||||
cursor: crosshair;
|
||||
touch-action: manipulation;
|
||||
|
||||
.CropContrainer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: translate3d(0, 0, 0);
|
||||
box-sizing: border-box;
|
||||
cursor: move;
|
||||
box-shadow: 0 0 0 9999em rgba(0, 0, 0, 0.5);
|
||||
touch-action: manipulation;
|
||||
border: 1px dashed white;
|
||||
|
||||
.ruleOfThirdsVT,
|
||||
.ruleOfThirdsHZ{
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
background-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
}
|
||||
.ruleOfThirdsVT{
|
||||
&::before,
|
||||
&::after {
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&::before {
|
||||
left: 33.3333%;
|
||||
left: calc(100% / 3);
|
||||
}
|
||||
|
||||
&::after {
|
||||
left: 66.6666%;
|
||||
left: calc(100% / 3 * 2);
|
||||
}
|
||||
}
|
||||
.ruleOfThirdsHZ{
|
||||
&::before,
|
||||
&::after {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
top: 33.3333%;
|
||||
top: calc(100% / 3);
|
||||
}
|
||||
|
||||
&::after {
|
||||
top: 66.6666%;
|
||||
top: calc(100% / 3 * 2);
|
||||
}
|
||||
}
|
||||
|
||||
.dragHandle{
|
||||
position: absolute;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
display: block;
|
||||
width: $drag-handle-width;
|
||||
height: $drag-handle-height;
|
||||
background-color: $drag-handle-background-colour;
|
||||
border: $drag-handle-border;
|
||||
box-sizing: border-box;
|
||||
|
||||
// This stops the borders disappearing when keyboard
|
||||
// nudging.
|
||||
outline: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.nw{
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin-top: -(ceil($drag-handle-height / 2));
|
||||
margin-left: -(ceil($drag-handle-width / 2));
|
||||
cursor: nwse-resize;
|
||||
|
||||
&::after {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
.n {
|
||||
top: 0;
|
||||
left: 50%;
|
||||
margin-top: -(ceil($drag-handle-height / 2));
|
||||
margin-left: -(ceil($drag-handle-width / 2));
|
||||
cursor: ns-resize;
|
||||
|
||||
&::after {
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
.ne {
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin-top: -(ceil($drag-handle-height / 2));
|
||||
margin-right: -(ceil($drag-handle-width / 2));
|
||||
cursor: nesw-resize;
|
||||
|
||||
&::after {
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
.e {
|
||||
top: 50%;
|
||||
right: 0;
|
||||
margin-top: -(ceil($drag-handle-height / 2));
|
||||
margin-right: -(ceil($drag-handle-width / 2));
|
||||
cursor: ew-resize;
|
||||
|
||||
&::after {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
.se {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
margin-bottom: -(ceil($drag-handle-height / 2));
|
||||
margin-right: -(ceil($drag-handle-width / 2));
|
||||
cursor: nwse-resize;
|
||||
|
||||
&::after {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
.s {
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
margin-bottom: -(ceil($drag-handle-height / 2));
|
||||
margin-left: -(ceil($drag-handle-width / 2));
|
||||
cursor: ns-resize;
|
||||
|
||||
&::after {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
.sw {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
margin-bottom: -(ceil($drag-handle-height / 2));
|
||||
margin-left: -(ceil($drag-handle-width / 2));
|
||||
cursor: nesw-resize;
|
||||
|
||||
&::after {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
.w {
|
||||
top: 50%;
|
||||
left: 0;
|
||||
margin-top: -(ceil($drag-handle-height / 2));
|
||||
margin-left: -(ceil($drag-handle-width / 2));
|
||||
cursor: ew-resize;
|
||||
|
||||
&::after {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
.dragBar_n {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: $drag-bar-size;
|
||||
margin-top: -($drag-bar-size / 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.dragBar_e {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: $drag-bar-size;
|
||||
height: 100%;
|
||||
margin-right: -($drag-bar-size / 2);
|
||||
}
|
||||
.dragBar_s {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: $drag-bar-size;
|
||||
margin-bottom: -($drag-bar-size / 2);
|
||||
}
|
||||
.dragBar_w {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: $drag-bar-size;
|
||||
height: 100%;
|
||||
margin-left: -($drag-bar-size / 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,432 @@
|
|||
import * as React from 'react';
|
||||
import { ICrop } from '../ImageManipulation.types';
|
||||
|
||||
import { nodePoition } from './Enums';
|
||||
import styles from './ImageCrop.module.scss';
|
||||
import { ICropData, IMousePosition } from './Interfaces';
|
||||
|
||||
function clamp(num: number, min: number, max: number): number {
|
||||
return Math.min(Math.max(num, min), max);
|
||||
}
|
||||
|
||||
export interface IImageCropProps {
|
||||
crop: ICrop;
|
||||
|
||||
sourceHeight: number;
|
||||
sourceWidth: number;
|
||||
showRuler?: boolean;
|
||||
onDragStart?: (e: MouseEvent) => void;
|
||||
onComplete?: (crop: ICrop) => void;
|
||||
onChange?: (crop: ICrop) => void;
|
||||
// tslint:disable-next-line: no-any
|
||||
onDragEnd?: (e: any) => void;
|
||||
}
|
||||
|
||||
export interface IImageCropState {
|
||||
cropIsActive: boolean;
|
||||
newCropIsBeingDrawn: boolean;
|
||||
reloadtimestamp: string;
|
||||
}
|
||||
|
||||
// Feature detection
|
||||
// tslint:disable-next-line: max-line-length
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Improving_scrolling_performance_with_passive_listeners
|
||||
|
||||
export default class ImageCrop extends
|
||||
React.Component<IImageCropProps, IImageCropState> {
|
||||
|
||||
private controlRef: HTMLDivElement = undefined;
|
||||
|
||||
private dragStarted: boolean = false;
|
||||
private mouseDownOnCrop: boolean = false;
|
||||
private evData: ICropData;
|
||||
|
||||
constructor(props: IImageCropProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
cropIsActive: false,
|
||||
newCropIsBeingDrawn: false,
|
||||
reloadtimestamp: ''
|
||||
};
|
||||
this.onDocMouseTouchMove = this.onDocMouseTouchMove.bind(this);
|
||||
this.onDocMouseTouchEnd = this.onDocMouseTouchEnd.bind(this);
|
||||
this.onCropMouseTouchDown = this.onCropMouseTouchDown.bind(this);
|
||||
this.setControlRef = this.setControlRef.bind(this);
|
||||
this.onMouseTouchDown = this.onMouseTouchDown.bind(this);
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
const { crop } = this.props;
|
||||
if (crop && this.isValid(crop) &&
|
||||
(crop.sx !== 0 || crop.sy !== 0 || crop.width !== 0 && crop.height !== 0)
|
||||
) {
|
||||
this.setState({ cropIsActive: true });
|
||||
} else {
|
||||
// Requireed because first renderer has no ref
|
||||
this.setState({ reloadtimestamp: new Date().getTime().toString() });
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public render(): React.ReactElement<IImageCropProps> {
|
||||
const { crop } = this.props;
|
||||
const cropSelection: JSX.Element = this.isValid(crop) && this.controlRef ? this.createSelectionGrid() : undefined;
|
||||
|
||||
// tslint:disable:react-a11y-event-has-role
|
||||
return (
|
||||
<div ref={this.setControlRef}
|
||||
className={styles.ImgGridShadowOverlay}
|
||||
onMouseMove={this.onDocMouseTouchMove}
|
||||
onTouchMove={this.onDocMouseTouchMove}
|
||||
onMouseUp={this.onDocMouseTouchEnd}
|
||||
onTouchCancel={this.onDocMouseTouchEnd}
|
||||
onTouchEnd={this.onDocMouseTouchEnd}
|
||||
onMouseDown={this.onMouseTouchDown}
|
||||
onTouchStart={this.onMouseTouchDown}
|
||||
>
|
||||
<div className={styles.ImgGridVisible}
|
||||
style={
|
||||
{
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0
|
||||
}
|
||||
}>
|
||||
{cropSelection}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
// tslint:
|
||||
}
|
||||
|
||||
private createSelectionGrid(): JSX.Element {
|
||||
const { showRuler } = this.props;
|
||||
const style: { top: string, left: string, width: string, height: string } = this.getCropStyle();
|
||||
|
||||
// tslint:disable:react-a11y-event-has-role
|
||||
return (
|
||||
<div
|
||||
style={style}
|
||||
className={styles.CropContrainer}
|
||||
onMouseDown={this.onCropMouseTouchDown}
|
||||
onTouchStart={this.onCropMouseTouchDown}
|
||||
>
|
||||
|
||||
<div className={styles.dragBar_n} data-ord={nodePoition.N} />
|
||||
<div className={styles.dragBar_e} data-ord={nodePoition.E} />
|
||||
<div className={styles.dragBar_s} data-ord={nodePoition.S} />
|
||||
<div className={styles.dragBar_w} data-ord={nodePoition.W} />
|
||||
|
||||
<div className={[styles.dragHandle, styles.nw].join(' ')} data-ord={nodePoition.NW} />
|
||||
<div className={[styles.dragHandle, styles.n].join(' ')} data-ord={nodePoition.N} />
|
||||
<div className={[styles.dragHandle, styles.ne].join(' ')} data-ord={nodePoition.NE} />
|
||||
<div className={[styles.dragHandle, styles.e].join(' ')} data-ord={nodePoition.E} />
|
||||
<div className={[styles.dragHandle, styles.se].join(' ')} data-ord={nodePoition.SE} />
|
||||
<div className={[styles.dragHandle, styles.s].join(' ')} data-ord={nodePoition.S} />
|
||||
<div className={[styles.dragHandle, styles.sw].join(' ')} data-ord={nodePoition.SW} />
|
||||
<div className={[styles.dragHandle, styles.w].join(' ')} data-ord={nodePoition.W} />
|
||||
|
||||
{showRuler && (
|
||||
<div>
|
||||
<div className={styles.ruleOfThirdsHZ} />
|
||||
<div className={styles.ruleOfThirdsVT} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
// tslint:enable
|
||||
}
|
||||
|
||||
private makeNewCrop(): ICrop {
|
||||
const crop: ICrop = { ...{ sx: 0, sy: 0, height: 0, width: 0 }, ...this.props.crop };
|
||||
return crop;
|
||||
}
|
||||
|
||||
private getCropStyle(): { top: string, left: string, width: string, height: string } {
|
||||
const crop: ICrop = this.makeNewCrop();
|
||||
const unit: string = 'px';
|
||||
return {
|
||||
top: `${crop.sy}${unit}`,
|
||||
left: `${crop.sx}${unit}`,
|
||||
width: `${crop.width}${unit}`,
|
||||
height: `${crop.height}${unit}`
|
||||
};
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private onDocMouseTouchMove(e: React.MouseEvent<HTMLDivElement> | any): void {
|
||||
const { crop, onChange, onDragStart } = this.props;
|
||||
if (!this.mouseDownOnCrop) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
if (!this.dragStarted) {
|
||||
this.dragStarted = true;
|
||||
if (onDragStart) {
|
||||
// tslint:disable-next-line: no-any
|
||||
onDragStart(e as any);
|
||||
}
|
||||
}
|
||||
|
||||
const clientPos: IMousePosition = this.getClientPos(e);
|
||||
/*
|
||||
if (this.evData.isResize && this.props.aspect && this.evData.cropOffset) {
|
||||
clientPos.y = this.straightenYPath(clientPos.x);
|
||||
}
|
||||
*/
|
||||
|
||||
this.evData.xDiff = clientPos.x - this.evData.clientStartX;
|
||||
this.evData.yDiff = clientPos.y - this.evData.clientStartY;
|
||||
|
||||
let nextCrop: ICrop;
|
||||
|
||||
if (this.evData.isResize) {
|
||||
nextCrop = this.resizeCrop();
|
||||
} else {
|
||||
nextCrop = this.dragCrop();
|
||||
}
|
||||
|
||||
if (nextCrop !== crop) {
|
||||
if (onChange) {
|
||||
onChange(nextCrop);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private dragCrop(): ICrop {
|
||||
|
||||
const { evData } = this;
|
||||
const nextCrop: ICrop = this.makeNewCrop();
|
||||
const width: number = this.controlRef.clientWidth;
|
||||
const height: number = this.controlRef.clientHeight;
|
||||
nextCrop.sx = clamp(evData.cropStartX + evData.xDiff, 0, width - nextCrop.width);
|
||||
nextCrop.sy = clamp(evData.cropStartY + evData.yDiff, 0, height - nextCrop.height);
|
||||
|
||||
return nextCrop;
|
||||
}
|
||||
|
||||
private resizeCrop(): ICrop {
|
||||
const { evData } = this;
|
||||
const nextCrop: ICrop = this.makeNewCrop();
|
||||
const { pos } = evData;
|
||||
|
||||
if (evData.xInversed) {
|
||||
evData.xDiff -= evData.cropStartWidth * 2;
|
||||
|
||||
}
|
||||
if (evData.yInversed) {
|
||||
evData.yDiff -= evData.cropStartHeight * 2;
|
||||
|
||||
}
|
||||
const newSize: { width: number, height: number } = this.getNewSize();
|
||||
|
||||
let newX: number = evData.cropStartX;
|
||||
let newY: number = evData.cropStartY;
|
||||
|
||||
if (evData.xInversed) {
|
||||
newX = nextCrop.sx + (nextCrop.width - newSize.width);
|
||||
}
|
||||
|
||||
if (evData.yInversed) {
|
||||
newY = nextCrop.sy + (nextCrop.height - newSize.height);
|
||||
}
|
||||
|
||||
const containedCrop: ICrop = {
|
||||
sx: newX,
|
||||
sy: newY,
|
||||
width: newSize.width,
|
||||
height: newSize.height,
|
||||
aspect: this.props.crop.aspect
|
||||
};
|
||||
|
||||
if (this.props.crop.aspect
|
||||
|| (pos === nodePoition.NW
|
||||
|| pos === nodePoition.SE
|
||||
|| pos === nodePoition.SW
|
||||
|| pos === nodePoition.NE)) {
|
||||
nextCrop.sx = containedCrop.sx;
|
||||
nextCrop.sy = containedCrop.sy;
|
||||
nextCrop.width = containedCrop.width;
|
||||
nextCrop.height = containedCrop.height;
|
||||
} else if (pos === nodePoition.E || pos === nodePoition.W) {
|
||||
nextCrop.sx = containedCrop.sx;
|
||||
nextCrop.width = containedCrop.width;
|
||||
} else if (pos === nodePoition.N || pos === nodePoition.S) {
|
||||
nextCrop.sy = containedCrop.sy;
|
||||
nextCrop.height = containedCrop.height;
|
||||
}
|
||||
return nextCrop;
|
||||
}
|
||||
|
||||
private getNewSize(): { width: number, height: number } {
|
||||
const { crop, sourceWidth, sourceHeight } = this.props;
|
||||
const { evData } = this;
|
||||
|
||||
let newWidth: number = evData.cropStartWidth + evData.xDiff;
|
||||
|
||||
if (evData.xInversed) {
|
||||
newWidth = Math.abs(newWidth);
|
||||
}
|
||||
|
||||
newWidth = clamp(newWidth, 0, sourceWidth);
|
||||
|
||||
// New height.
|
||||
let newHeight: number;
|
||||
|
||||
if (crop.aspect) {
|
||||
newHeight = newWidth / crop.aspect;
|
||||
} else {
|
||||
newHeight = evData.cropStartHeight + evData.yDiff;
|
||||
}
|
||||
|
||||
if (evData.yInversed) {
|
||||
// Cap if polarity is inversed and the height fills the y space.
|
||||
newHeight = Math.min(Math.abs(newHeight), evData.cropStartY);
|
||||
}
|
||||
|
||||
newHeight = clamp(newHeight, 0, sourceHeight);
|
||||
|
||||
if (crop.aspect) {
|
||||
newWidth = clamp(newHeight * crop.aspect, 0, sourceWidth);
|
||||
}
|
||||
|
||||
return {
|
||||
width: newWidth,
|
||||
height: newHeight
|
||||
};
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private onDocMouseTouchEnd(e: MouseEvent | any): void {
|
||||
const { crop, onDragEnd, onComplete } = this.props;
|
||||
|
||||
if (this.mouseDownOnCrop) {
|
||||
this.mouseDownOnCrop = false;
|
||||
this.dragStarted = false;
|
||||
if (onDragEnd) {
|
||||
onDragEnd(e);
|
||||
}
|
||||
if (onComplete) {
|
||||
onComplete(crop);
|
||||
}
|
||||
this.setState({ cropIsActive: false, newCropIsBeingDrawn: false });
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private onCropMouseTouchDown(e: MouseEvent | any): void {
|
||||
const { crop } = this.props;
|
||||
|
||||
e.preventDefault(); // Stop drag selection.
|
||||
const mousepos: IMousePosition = this.getClientPos(e);
|
||||
const { ord } = e.target.dataset;
|
||||
|
||||
let xInversed: boolean = false;
|
||||
let yInversed: boolean = false;
|
||||
let pos: nodePoition = undefined;
|
||||
if (ord && !isNaN(+ord)) {
|
||||
pos = +ord;
|
||||
xInversed = pos === nodePoition.NW || pos === nodePoition.W || pos === nodePoition.SW;
|
||||
yInversed = pos === nodePoition.NW || pos === nodePoition.N || pos === nodePoition.NE;
|
||||
}
|
||||
|
||||
this.evData = {
|
||||
clientStartX: mousepos.x,
|
||||
clientStartY: mousepos.y,
|
||||
cropStartWidth: crop.width,
|
||||
cropStartHeight: crop.height,
|
||||
cropStartX: xInversed ? crop.sx + crop.width : crop.sx,
|
||||
cropStartY: yInversed ? crop.sy + crop.height : crop.sy,
|
||||
xInversed: xInversed,
|
||||
yInversed: yInversed,
|
||||
isResize: (ord && !isNaN(ord)),
|
||||
pos: pos,
|
||||
xDiff: 0,
|
||||
yDiff: 0
|
||||
};
|
||||
|
||||
this.mouseDownOnCrop = true;
|
||||
this.setState({ cropIsActive: true });
|
||||
}
|
||||
|
||||
private setControlRef(element: HTMLDivElement): void {
|
||||
this.controlRef = element;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private getClientPos(e: MouseEvent | any): IMousePosition {
|
||||
let pageX: number;
|
||||
let pageY: number;
|
||||
|
||||
if (e.touches) {
|
||||
[{ pageX, pageY }] = e.touches;
|
||||
} else {
|
||||
({ pageX, pageY } = e);
|
||||
}
|
||||
|
||||
return {
|
||||
x: pageX,
|
||||
y: pageY
|
||||
};
|
||||
}
|
||||
|
||||
private isValid(crop: ICrop): boolean {
|
||||
return crop && !isNaN(crop.width) && !isNaN(crop.height);
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private onMouseTouchDown(e: MouseEvent | any): void {
|
||||
const { crop, onChange } = this.props;
|
||||
e.preventDefault(); // Stop drag selection.
|
||||
const mousepos: IMousePosition = this.getClientPos(e);
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
const refpos: any = this.controlRef.getBoundingClientRect();
|
||||
const startx: number = mousepos.x - refpos.left;
|
||||
const starty: number = mousepos.y - refpos.top;
|
||||
// is mousePos in current pos
|
||||
if (crop) {
|
||||
if (crop.sx - 5 <= startx && crop.sx + crop.width + 5 >= startx &&
|
||||
crop.sy - 5 <= starty && crop.sy + crop.height + 5 >= starty
|
||||
) {
|
||||
// Position in current crop do Nothing
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const nextCrop: ICrop = {
|
||||
sx: startx,
|
||||
sy: starty,
|
||||
width: 0,
|
||||
height: 0,
|
||||
aspect: crop.aspect
|
||||
};
|
||||
|
||||
this.evData = {
|
||||
clientStartX: mousepos.x,
|
||||
clientStartY: mousepos.y,
|
||||
cropStartWidth: nextCrop.width,
|
||||
cropStartHeight: nextCrop.height,
|
||||
cropStartX: nextCrop.sx,
|
||||
cropStartY: nextCrop.sy,
|
||||
xInversed: false,
|
||||
yInversed: false,
|
||||
isResize: true,
|
||||
xDiff: 0,
|
||||
yDiff: 0,
|
||||
pos: nodePoition.NW
|
||||
};
|
||||
|
||||
this.mouseDownOnCrop = true;
|
||||
|
||||
onChange(nextCrop);
|
||||
|
||||
this.setState({ cropIsActive: true, newCropIsBeingDrawn: true });
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
.ImgGridShadowOverlay{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
//background-color: rgba(0,0,0,0.4);
|
||||
overflow: hidden;
|
||||
}
|
||||
.ImgGridVisible {
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
right: 0;
|
||||
bottom:0;
|
||||
// box-sizing: border-box;
|
||||
// box-shadow:0 0 0 9999em;
|
||||
box-shadow: 0 0 0 9999em rgba(0, 0, 0, 0.5);
|
||||
|
||||
.ImgGridTabel {
|
||||
border:2px solid white;
|
||||
display: table;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
.ImgGridRow {
|
||||
display: table-row;
|
||||
height: 33.33%;
|
||||
|
||||
.ImgGridCell {
|
||||
display: table-cell;
|
||||
width: 33.33%;
|
||||
}
|
||||
.ImgLeftTop{
|
||||
border-right: 1px solid white;
|
||||
border-bottom: 1px solid white;
|
||||
.bubble{
|
||||
cursor:nwse-resize;
|
||||
left: 0;
|
||||
top:0;
|
||||
}
|
||||
}
|
||||
.ImgRightTop{
|
||||
border-left: 1px solid white;
|
||||
border-bottom: 1px solid white;
|
||||
.bubble{
|
||||
cursor:nesw-resize;
|
||||
right: 0;
|
||||
top:0;
|
||||
}
|
||||
}
|
||||
.ImgLeftBottom {
|
||||
border-right: 1px solid white;
|
||||
border-top: 1px solid white;
|
||||
.bubble{
|
||||
cursor:nesw-resize;
|
||||
left: 0;
|
||||
bottom:0;
|
||||
}
|
||||
}
|
||||
.ImgRightBottom {
|
||||
border-left: 1px solid white;
|
||||
border-top: 1px solid white;
|
||||
.bubble{
|
||||
cursor:nwse-resize;
|
||||
right: 0;
|
||||
bottom:0;
|
||||
}
|
||||
}
|
||||
.ImgCenterTop {
|
||||
border-bottom: 1px dashed white;
|
||||
.bubble{
|
||||
cursor:ns-resize;
|
||||
left: 50%;
|
||||
top:0;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
.ImgCenterBottom{
|
||||
border-top: 1px dashed white;
|
||||
.bubble{
|
||||
cursor:ns-resize;
|
||||
left: 50%;
|
||||
bottom:0;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
.ImgLeftCenter{
|
||||
border-right: 1px dashed white;
|
||||
.bubble{
|
||||
cursor:ew-resize;
|
||||
left: 0;
|
||||
top:50%;
|
||||
width: 10px;
|
||||
}
|
||||
}
|
||||
.ImgRightCenter{
|
||||
border-left: 1px dashed white;
|
||||
.bubble{
|
||||
cursor:ew-resize;
|
||||
right: 0;
|
||||
top:50%;
|
||||
width: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bubble{
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
background-color: white;
|
||||
//border-radius: 50%;
|
||||
border:1px solid black;
|
||||
display: block;
|
||||
position:absolute;
|
||||
// margin: -8px 0 0 -8px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
.ImgGridRowTop {
|
||||
.ImgGridCellLeft {}
|
||||
.ImgGridCellCenter {}
|
||||
.ImgGridCellRight {}
|
||||
}
|
||||
.ImgGridRowMiddle {}
|
||||
.ImgGridRowBottom {}
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
import * as React from 'react';
|
||||
import { IResize } from '../ImageManipulation.types';
|
||||
|
||||
import { nodePoition } from './Enums';
|
||||
import styles from './ImageGrid.module.scss';
|
||||
import { IMousePosition } from './Interfaces';
|
||||
|
||||
export interface IImageGridProps {
|
||||
width: number;
|
||||
height: number;
|
||||
aspect?: number;
|
||||
onChange: (size: IResize) => void;
|
||||
onComplete?: (size: IResize) => void;
|
||||
// tslint:disable-next-line: no-any
|
||||
onDragEnd?: (e: MouseEvent | any) => void;
|
||||
// tslint:disable-next-line: no-any
|
||||
onDragStart?: (e: MouseEvent | any) => void;
|
||||
}
|
||||
|
||||
export interface IImageGridState { }
|
||||
|
||||
export interface IResizeData {
|
||||
pos: nodePoition;
|
||||
width: number;
|
||||
height: number;
|
||||
xInverse: boolean;
|
||||
yInverse: boolean;
|
||||
clientStartX: number;
|
||||
clientStartY: number;
|
||||
}
|
||||
|
||||
export default class ImageGrid extends React.Component<IImageGridProps, IImageGridState> {
|
||||
|
||||
private evData: IResizeData = undefined;
|
||||
private dragStarted: boolean = false;
|
||||
constructor(props: IImageGridProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {};
|
||||
|
||||
this.onStartResizing = this.onStartResizing.bind(this);
|
||||
this.onDocMouseTouchMove = this.onDocMouseTouchMove.bind(this);
|
||||
this.onDocMouseTouchEnd = this.onDocMouseTouchEnd.bind(this);
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
window.document.addEventListener('mousemove', this.onDocMouseTouchMove);
|
||||
window.document.addEventListener('touchmove', this.onDocMouseTouchMove);
|
||||
window.document.addEventListener('mouseup', this.onDocMouseTouchEnd);
|
||||
window.document.addEventListener('touchend', this.onDocMouseTouchEnd);
|
||||
window.document.addEventListener('touchcancel', this.onDocMouseTouchEnd);
|
||||
|
||||
}
|
||||
public componentWillUnmount(): void {
|
||||
window.document.removeEventListener('mousemove', this.onDocMouseTouchMove);
|
||||
window.document.removeEventListener('touchmove', this.onDocMouseTouchMove);
|
||||
window.document.removeEventListener('mouseup', this.onDocMouseTouchEnd);
|
||||
window.document.removeEventListener('touchend', this.onDocMouseTouchEnd);
|
||||
window.document.removeEventListener('touchcancel', this.onDocMouseTouchEnd);
|
||||
}
|
||||
|
||||
public render(): React.ReactElement<IImageGridProps> {
|
||||
// tslint:disable:react-a11y-event-has-role
|
||||
return (
|
||||
<div className={styles.ImgGridShadowOverlay}>
|
||||
<div className={styles.ImgGridVisible}
|
||||
style={
|
||||
{
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0
|
||||
}
|
||||
}>
|
||||
<div className={styles.ImgGridTabel}>
|
||||
|
||||
<div className={styles.ImgGridRow}>
|
||||
<div className={styles.ImgLeftTop + ' ' + styles.ImgGridCell}>
|
||||
<div className={styles.bubble}
|
||||
onMouseDown={this.onStartResizing}
|
||||
onTouchStart={this.onStartResizing}
|
||||
data-ord={nodePoition.NW} />
|
||||
</div>
|
||||
<div className={styles.ImgCenterTop + ' ' + styles.ImgGridCell}>
|
||||
<div className={styles.bubble} data-ord={nodePoition.N} onMouseDown={this.onStartResizing} />
|
||||
</div>
|
||||
<div className={styles.ImgRightTop + ' ' + styles.ImgGridCell}>
|
||||
<div className={styles.bubble} data-ord={nodePoition.NE} onMouseDown={this.onStartResizing} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.ImgGridRow}>
|
||||
<div className={styles.ImgLeftCenter + ' ' + styles.ImgGridCell}>
|
||||
<div className={styles.bubble} data-ord={nodePoition.W} onMouseDown={this.onStartResizing} />
|
||||
</div>
|
||||
<div className={styles.ImgGridCell}></div>
|
||||
<div className={styles.ImgRightCenter + ' ' + styles.ImgGridCell}>
|
||||
<div className={styles.bubble} data-ord={nodePoition.E} onMouseDown={this.onStartResizing} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.ImgGridRow}>
|
||||
<div className={styles.ImgLeftBottom + ' ' + styles.ImgGridCell}>
|
||||
<div className={styles.bubble} data-ord={nodePoition.SW} onMouseDown={this.onStartResizing} />
|
||||
</div>
|
||||
<div className={styles.ImgCenterBottom + ' ' + styles.ImgGridCell}>
|
||||
<div className={styles.bubble} data-ord={nodePoition.S} onMouseDown={this.onStartResizing} />
|
||||
</div>
|
||||
<div className={styles.ImgRightBottom + ' ' + styles.ImgGridCell}>
|
||||
<div className={styles.bubble} data-ord={nodePoition.SE} onMouseDown={this.onStartResizing} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
// tslint:enable
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private onStartResizing(e: MouseEvent | any): void {
|
||||
const mousePos: IMousePosition = this.getClientPos(e);
|
||||
let xInversed: boolean = false;
|
||||
let yInversed: boolean = false;
|
||||
const { ord } = e.target.dataset;
|
||||
let pos: nodePoition = undefined;
|
||||
if (ord && !isNaN(+ord)) {
|
||||
pos = +ord;
|
||||
xInversed = pos === nodePoition.NW || pos === nodePoition.W || pos === nodePoition.SW;
|
||||
yInversed = pos === nodePoition.NW || pos === nodePoition.N || pos === nodePoition.NE;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
this.dragStarted = true;
|
||||
if (this.props.onDragStart) {
|
||||
this.props.onDragStart(e);
|
||||
}
|
||||
this.evData = {
|
||||
clientStartX: mousePos.x,
|
||||
clientStartY: mousePos.y,
|
||||
xInverse: xInversed,
|
||||
yInverse: yInversed,
|
||||
pos: pos,
|
||||
width: this.props.width,
|
||||
height: this.props.height
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private onDocMouseTouchMove(e: React.MouseEvent<HTMLDivElement> | any): void {
|
||||
const { aspect, onChange } = this.props;
|
||||
if (!this.dragStarted) {
|
||||
return;
|
||||
}
|
||||
if (!this.evData) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
const mousePos: IMousePosition = this.getClientPos(e);
|
||||
|
||||
let xDiff: number = 0;
|
||||
let yDiff: number = 0;
|
||||
|
||||
if (this.evData.pos === nodePoition.E
|
||||
|| this.evData.pos === nodePoition.SE
|
||||
|| this.evData.pos === nodePoition.NE) {
|
||||
xDiff = mousePos.x - this.evData.clientStartX;
|
||||
} else if (this.evData.pos === nodePoition.W
|
||||
|| this.evData.pos === nodePoition.SW
|
||||
|| this.evData.pos === nodePoition.NW) {
|
||||
xDiff = this.evData.clientStartX - mousePos.x;
|
||||
}
|
||||
|
||||
if (this.evData.pos === nodePoition.N || this.evData.pos === nodePoition.NW || this.evData.pos === nodePoition.NE) {
|
||||
yDiff = this.evData.clientStartY - mousePos.y;
|
||||
} else if (this.evData.pos === nodePoition.S
|
||||
|| this.evData.pos === nodePoition.SW
|
||||
|| this.evData.pos === nodePoition.SE) {
|
||||
yDiff = mousePos.y - this.evData.clientStartY;
|
||||
}
|
||||
|
||||
const nextsize: IResize = {
|
||||
width: this.evData.width + xDiff,
|
||||
height: this.evData.height + yDiff
|
||||
};
|
||||
if (aspect) {
|
||||
if (this.evData.pos !== nodePoition.N && this.evData.pos !== nodePoition.S) {
|
||||
nextsize.height = nextsize.width / aspect;
|
||||
} else {
|
||||
nextsize.width = nextsize.height * aspect;
|
||||
}
|
||||
}
|
||||
if (onChange) {
|
||||
onChange(nextsize);
|
||||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private onDocMouseTouchEnd(e: MouseEvent | any): void {
|
||||
const { width, height, onDragEnd, onComplete } = this.props;
|
||||
if (this.dragStarted) {
|
||||
this.dragStarted = false;
|
||||
if (onDragEnd) {
|
||||
onDragEnd(e);
|
||||
}
|
||||
this.evData = undefined;
|
||||
if (onComplete) {
|
||||
onComplete({ width: width, height: height });
|
||||
this.setState({ cropIsActive: false, newCropIsBeingDrawn: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private getClientPos(e: MouseEvent | any): IMousePosition {
|
||||
let pageX: number;
|
||||
let pageY: number;
|
||||
|
||||
if (e.touches) {
|
||||
[{ pageX, pageY }] = e.touches;
|
||||
} else {
|
||||
({ pageX, pageY } = e);
|
||||
}
|
||||
|
||||
return {
|
||||
x: pageX,
|
||||
y: pageY
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import { nodePoition } from './Enums';
|
||||
|
||||
export interface IMousePosition {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
export interface ICropData {
|
||||
clientStartX: number;
|
||||
clientStartY: number;
|
||||
cropStartWidth: number;
|
||||
cropStartHeight: number;
|
||||
cropStartX: number;
|
||||
cropStartY: number;
|
||||
xInversed: boolean;
|
||||
yInversed: boolean;
|
||||
isResize: boolean;
|
||||
pos?: nodePoition;
|
||||
xDiff: number;
|
||||
yDiff: number;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
$ms-color-themePrimary: '[theme:themePrimary, default:#0078d7]';
|
||||
$ms-color-neutralLight: '[theme:neutralLight, default:#eaeaea]';
|
||||
$ms-color-neutralLighter: '[theme:neutralLighter, default:#f4f4f4]';
|
||||
$ms-color-neutralTertiary: '[theme:neutralTertiary, default:#a6a6a6]';
|
||||
$ms-color-white: '[theme:white, default:#ffffff]';
|
||||
|
||||
|
||||
.propertyFieldOrder {
|
||||
margin-bottom: 2px;
|
||||
|
||||
ul {
|
||||
padding: 0.5px;
|
||||
margin: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
|
||||
li {
|
||||
color: $ms-color-neutralTertiary;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
background-color: $ms-color-white;
|
||||
border: 0.5px solid;
|
||||
border-color: $ms-color-neutralLight;
|
||||
outline: 0.5px solid;
|
||||
outline-color: $ms-color-neutralLight;
|
||||
|
||||
.enabled & :hover {
|
||||
background-color: $ms-color-neutralLighter;
|
||||
}
|
||||
|
||||
& > div {
|
||||
padding: 3px 6px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.itemBox {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.dragEnter {
|
||||
background-color: $ms-color-neutralLight;
|
||||
border-top: 2px dashed;
|
||||
border-top-color: $ms-color-themePrimary;
|
||||
}
|
||||
|
||||
.dragLast {
|
||||
background-color: $ms-color-neutralLight;
|
||||
border-bottom: 2px dashed;
|
||||
border-bottom-color: $ms-color-themePrimary;
|
||||
}
|
||||
|
||||
.lastBox {
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,303 @@
|
|||
import { isEqual } from '@microsoft/sp-lodash-subset';
|
||||
import { EventGroup, IButtonStyles, IconButton, ISelection, Label } from 'office-ui-fabric-react';
|
||||
import { DragDropHelper, IDragDropContext } from 'office-ui-fabric-react/lib-es2015/utilities/dragdrop';
|
||||
import * as React from 'react';
|
||||
import styles from './ItemOrder.module.scss';
|
||||
|
||||
export interface IItemOrderProps {
|
||||
label: string;
|
||||
disabled: boolean;
|
||||
// tslint:disable-next-line: no-any
|
||||
items: Array<any>;
|
||||
textProperty?: string;
|
||||
moveUpIconName: string;
|
||||
moveDownIconName: string;
|
||||
disableDragAndDrop: boolean;
|
||||
removeArrows: boolean;
|
||||
maxHeight?: number;
|
||||
// tslint:disable-next-line: no-any
|
||||
valueChanged: (newValue: Array<any>) => void;
|
||||
// tslint:disable-next-line: no-any
|
||||
onRenderItem?: (item: any, index: number) => JSX.Element;
|
||||
}
|
||||
|
||||
export interface IItemOrderState {
|
||||
// tslint:disable-next-line: no-any
|
||||
items: Array<any>;
|
||||
}
|
||||
|
||||
export default class ItemOrder extends React.Component<IItemOrderProps, IItemOrderState> {
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private _draggedItem: any;
|
||||
private _selection: ISelection;
|
||||
private _ddHelper: DragDropHelper;
|
||||
private _refs: Array<HTMLElement>;
|
||||
// tslint:disable-next-line: no-any
|
||||
private _ddSubs: Array<any>;
|
||||
private _lastBox: HTMLElement;
|
||||
|
||||
constructor(props: IItemOrderProps) {
|
||||
super(props);
|
||||
|
||||
this._selection = undefined;
|
||||
this._ddHelper = new DragDropHelper({
|
||||
selection: this._selection
|
||||
});
|
||||
|
||||
this._refs = new Array<HTMLElement>();
|
||||
// tslint:disable-next-line: no-any
|
||||
this._ddSubs = new Array<any>();
|
||||
|
||||
this._draggedItem = undefined;
|
||||
|
||||
this.state = {
|
||||
items: []
|
||||
};
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
const {
|
||||
items
|
||||
} = this.state;
|
||||
return (
|
||||
<div className={styles.propertyFieldOrder}>
|
||||
{this.props.label && <Label>{this.props.label}</Label>}
|
||||
<ul
|
||||
style={{ maxHeight: this.props.maxHeight ? this.props.maxHeight + 'px' : '100%' }}
|
||||
className={!this.props.disabled ? styles.enabled : styles.disabled}>
|
||||
{
|
||||
(items && items.length > 0) && (
|
||||
// tslint:disable-next-line: no-any
|
||||
items.map((value: any, index: number) => {
|
||||
return (
|
||||
<li
|
||||
ref={this.registerRef}
|
||||
key={index}
|
||||
draggable={!this.props.disableDragAndDrop && !this.props.disabled}
|
||||
style={{ cursor: !this.props.disableDragAndDrop && !this.props.disabled ? 'pointer' : 'default' }}
|
||||
>{this.renderItem(value, index)}</li>
|
||||
);
|
||||
})
|
||||
)
|
||||
}
|
||||
{
|
||||
(items && items.length > 0) && <div
|
||||
className={styles.lastBox}
|
||||
ref={(ref: HTMLElement) => { this._lastBox = ref; }} />
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public componentWillMount(): void {
|
||||
this.setState({
|
||||
items: this.props.items || []
|
||||
});
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
this.setupSubscriptions();
|
||||
}
|
||||
|
||||
public componentWillUpdate(nextProps: IItemOrderProps): void {
|
||||
// Check if the provided items are still the same
|
||||
if (!isEqual(nextProps.items, this.state.items)) {
|
||||
this.setState({
|
||||
items: this.props.items || []
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public componentDidUpdate(): void {
|
||||
this.cleanupSubscriptions();
|
||||
this.setupSubscriptions();
|
||||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
this.cleanupSubscriptions();
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private renderItem(item: any, index: number): JSX.Element {
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.itemBox}>
|
||||
{this.renderDisplayValue(item, index)}
|
||||
</div>
|
||||
{!this.props.removeArrows &&
|
||||
<div>{this.renderArrows(index)}</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private renderDisplayValue(item: any, index: number): JSX.Element {
|
||||
if (typeof this.props.onRenderItem === 'function') {
|
||||
return this.props.onRenderItem(item, index);
|
||||
} else {
|
||||
return (
|
||||
<span>{this.props.textProperty ? item[this.props.textProperty] : item.toString()}</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private renderArrows(index: number): JSX.Element {
|
||||
const arrowButtonStyles: Partial<IButtonStyles> = {
|
||||
root: {
|
||||
width: '14px',
|
||||
height: '100%',
|
||||
display: 'inline-block !important'
|
||||
},
|
||||
rootDisabled: {
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
icon: {
|
||||
fontSize: '10px'
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<IconButton
|
||||
disabled={this.props.disabled || index === 0}
|
||||
iconProps={{ iconName: this.props.moveUpIconName }}
|
||||
onClick={() => { this.onMoveUpClick(index); }}
|
||||
styles={arrowButtonStyles}
|
||||
/>
|
||||
<IconButton
|
||||
disabled={this.props.disabled || index === this.props.items.length - 1}
|
||||
iconProps={{ iconName: this.props.moveDownIconName }}
|
||||
onClick={() => { this.onMoveDownClick(index); }}
|
||||
styles={arrowButtonStyles}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private registerRef = (ref: HTMLElement): void => {
|
||||
this._refs.push(ref);
|
||||
}
|
||||
|
||||
private setupSubscriptions = (): void => {
|
||||
if (!this.props.disableDragAndDrop && !this.props.disabled) {
|
||||
this._refs.forEach((value: HTMLElement, index: number) => {
|
||||
this._ddSubs.push(this._ddHelper.subscribe(value, new EventGroup(value), {
|
||||
eventMap: [
|
||||
{
|
||||
// tslint:disable-next-line: no-any
|
||||
callback: (context: IDragDropContext, _event?: any) => {
|
||||
this._draggedItem = context.data;
|
||||
},
|
||||
eventName: 'dragstart'
|
||||
}
|
||||
],
|
||||
selectionIndex: index,
|
||||
context: { data: this.state.items[index], index: index },
|
||||
updateDropState: (isDropping: boolean, _event: DragEvent) => {
|
||||
if (isDropping) {
|
||||
value.classList.add(styles.dragEnter);
|
||||
} else {
|
||||
value.classList.remove(styles.dragEnter);
|
||||
}
|
||||
},
|
||||
canDrop: (_dropContext?: IDragDropContext, _dragContext?: IDragDropContext) => {
|
||||
return true;
|
||||
},
|
||||
// tslint:disable-next-line: no-any
|
||||
canDrag: (_item?: any) => {
|
||||
return true;
|
||||
},
|
||||
// tslint:disable-next-line: no-any
|
||||
onDrop: (item?: any, _event?: DragEvent) => {
|
||||
if (this._draggedItem) {
|
||||
this.insertBeforeItem(item);
|
||||
}
|
||||
},
|
||||
/*onDragStart: (item?: any, itemIndex?: number, selectedItems?: any[], event?: MouseEvent) => {
|
||||
//Never called for some reason, so using eventMap above
|
||||
this._draggedItem = item;
|
||||
},*/
|
||||
// tslint:disable-next-line: no-any
|
||||
onDragEnd: (_item?: any, _event?: DragEvent) => {
|
||||
this._draggedItem = undefined;
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
// Create droppable area below list to allow items to be dragged to the bottom
|
||||
if (this._refs.length && typeof this._lastBox !== 'undefined') {
|
||||
this._ddSubs.push(this._ddHelper.subscribe(this._lastBox, new EventGroup(this._lastBox), {
|
||||
selectionIndex: this._refs.length,
|
||||
context: { data: {}, index: this._refs.length },
|
||||
updateDropState: (isDropping: boolean, event: DragEvent) => {
|
||||
if (isDropping) {
|
||||
this._refs[this._refs.length - 1].classList.add(styles.dragLast);
|
||||
} else {
|
||||
this._refs[this._refs.length - 1].classList.remove(styles.dragLast);
|
||||
}
|
||||
},
|
||||
canDrop: (_dropContext?: IDragDropContext, _dragContext?: IDragDropContext) => {
|
||||
return true;
|
||||
},
|
||||
// tslint:disable-next-line: no-any
|
||||
onDrop: (_item?: any, _event?: DragEvent) => {
|
||||
if (this._draggedItem) {
|
||||
const itemIndex: number = this.state.items.indexOf(this._draggedItem);
|
||||
this.moveItemAtIndexToTargetIndex(itemIndex, this.state.items.length - 1);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private cleanupSubscriptions = (): void => {
|
||||
while (this._ddSubs.length) {
|
||||
// tslint:disable-next-line: no-any
|
||||
const sub: any = this._ddSubs.pop();
|
||||
sub.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
private insertBeforeItem = (item: any) => {
|
||||
const itemIndex: number = this.state.items.indexOf(this._draggedItem);
|
||||
let targetIndex: number = this.state.items.indexOf(item);
|
||||
if (itemIndex < targetIndex) {
|
||||
targetIndex -= 1;
|
||||
}
|
||||
this.moveItemAtIndexToTargetIndex(itemIndex, targetIndex);
|
||||
}
|
||||
|
||||
private onMoveUpClick = (itemIndex: number): void => {
|
||||
if (itemIndex > 0) {
|
||||
this.moveItemAtIndexToTargetIndex(itemIndex, itemIndex - 1);
|
||||
}
|
||||
}
|
||||
|
||||
private onMoveDownClick = (itemIndex: number): void => {
|
||||
if (itemIndex < this.state.items.length - 1) {
|
||||
this.moveItemAtIndexToTargetIndex(itemIndex, itemIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private moveItemAtIndexToTargetIndex = (itemIndex: number, targetIndex: number): void => {
|
||||
if (itemIndex !== targetIndex
|
||||
&& itemIndex > -1 && targetIndex > -1
|
||||
&& itemIndex < this.state.items.length
|
||||
&& targetIndex < this.state.items.length) {
|
||||
// tslint:disable-next-line: no-any
|
||||
const items: Array<any> = this.state.items;
|
||||
items.splice(targetIndex, 0, ...items.splice(itemIndex, 1)[0]);
|
||||
|
||||
this.setState({
|
||||
items: items
|
||||
});
|
||||
|
||||
this.props.valueChanged(items);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
|
||||
export { ImageManipulation, IImageManipulationConfig } from './ImageManipulation';
|
||||
|
||||
export {
|
||||
IImageManipulationSettings, IManipulationBase,
|
||||
IFilterSettings, IRotateSettings, IScaleSettings, IFlipSettings, ICropSettings, IResizeSettings,
|
||||
FilterType
|
||||
} from './ImageManipulation.types';
|
|
@ -0,0 +1,24 @@
|
|||
define([], function () {
|
||||
return {
|
||||
"ManipulationTypeFilter": "Filter",
|
||||
"ManipulationTypeFlip": "Spiegeln",
|
||||
"ManipulationTypeRotate": "Drehen",
|
||||
"ManipulationTypeScale": "Skalieren",
|
||||
"ManipulationTypeCrop": "Zuschneiden",
|
||||
"ManipulationTypeResize": "Größe ändern",
|
||||
"FilterTypeGrayscale": "Graustufen",
|
||||
"FilterTypeSepia": "Sepia",
|
||||
"SettingPanelClose": "Schließen",
|
||||
"SettingPanelHistory": "Verlauf",
|
||||
"CommandBarRedo": "Erneut ausführen",
|
||||
"CommandBarUndo": "Rückgängig machen",
|
||||
"CommandBarReset": "Zurücksetzen",
|
||||
"FlipVertical": "Vertikal",
|
||||
"FlipHorizontal": "Horizontal",
|
||||
"LockAspect": "Verhältnis sperren",
|
||||
"Width": "Breite",
|
||||
"Height": "Höhe",
|
||||
"SourceX": "SourceX",
|
||||
"SourceY": "SourceY",
|
||||
}
|
||||
});
|
|
@ -0,0 +1,24 @@
|
|||
define([], function () {
|
||||
return {
|
||||
"ManipulationTypeFilter": "Filter",
|
||||
"ManipulationTypeFlip": "Flip",
|
||||
"ManipulationTypeRotate": "Rotate",
|
||||
"ManipulationTypeScale": "Scale",
|
||||
"ManipulationTypeCrop": "Crop",
|
||||
"ManipulationTypeResize": "Resize",
|
||||
"FilterTypeGrayscale": "Grayscale",
|
||||
"FilterTypeSepia": "Sepia",
|
||||
"SettingPanelClose": "Close",
|
||||
"SettingPanelHistory": "History",
|
||||
"CommandBarRedo": "Redo",
|
||||
"CommandBarUndo": "Undo",
|
||||
"CommandBarReset": "Reset",
|
||||
"FlipVertical": "Vertical",
|
||||
"FlipHorizontal": "Horizontal",
|
||||
"LockAspect": "Lock aspect",
|
||||
"Width": "Width",
|
||||
"Height": "Height",
|
||||
"SourceX": "SourceX",
|
||||
"SourceY": "SourceY",
|
||||
}
|
||||
});
|
34
samples/react-image-editor/src/components/ImageManipulation/loc/mystrings.d.ts
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
declare interface IImageManipulationStrings {
|
||||
|
||||
ManipulationTypeFilter: string;
|
||||
ManipulationTypeFlip: string;
|
||||
ManipulationTypeRotate: string;
|
||||
ManipulationTypeScale: string;
|
||||
ManipulationTypeCrop: string;
|
||||
ManipulationTypeResize: string;
|
||||
|
||||
FilterTypeGrayscale: string;
|
||||
FilterTypeSepia: string;
|
||||
|
||||
SettingPanelClose: string;
|
||||
SettingPanelHistory: string;
|
||||
|
||||
CommandBarRedo: string;
|
||||
CommandBarUndo: string;
|
||||
CommandBarReset: string;
|
||||
|
||||
FlipVertical: string;
|
||||
FlipHorizontal: string;
|
||||
|
||||
LockAspect: string;
|
||||
Width: string;
|
||||
Height: string;
|
||||
SourceX: string;
|
||||
SourceY: string;
|
||||
|
||||
}
|
||||
|
||||
declare module 'ImageManipulationStrings' {
|
||||
const strings: IImageManipulationStrings;
|
||||
export = strings;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './ImageManipulation';
|
|
@ -0,0 +1 @@
|
|||
// A file is required to be in the root of the /src directory by the TypeScript compiler
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M 16 4 C 11.593564 4 8 7.5935677 8 12 C 8 12.195683 8.0153666 12.387845 8.0292969 12.580078 C 5.0876831 13.764072 3 16.643186 3 20 C 3 24.406432 6.5935644 28 11 28 C 12.890388 28 14.628379 27.335631 16 26.232422 C 17.371621 27.335631 19.109612 28 21 28 C 25.406436 28 29 24.406432 29 20 C 29 16.643186 26.912317 13.764072 23.970703 12.580078 C 23.984633 12.387845 24 12.195683 24 12 C 24 7.5935677 20.406436 4 16 4 z M 16 6 C 19.325556 6 22 8.674446 22 12 C 22 12.023102 21.996351 12.045321 21.996094 12.068359 C 21.669097 12.027374 21.337804 12 21 12 C 19.109612 12 17.371621 12.664369 16 13.767578 C 14.628379 12.664369 12.890388 12 11 12 C 10.662196 12 10.330903 12.027374 10.003906 12.068359 C 10.003649 12.045321 10 12.023102 10 12 C 10 8.674446 12.674444 6 16 6 z M 11 14 C 12.360072 14 13.607475 14.45273 14.611328 15.208984 C 14.110052 15.875191 13.710721 16.618398 13.435547 17.421875 C 12.008277 16.748871 10.896895 15.533946 10.359375 14.035156 C 10.569969 14.013008 10.783318 14 11 14 z M 21 14 C 21.216682 14 21.430031 14.013008 21.640625 14.035156 C 21.103105 15.533946 19.991723 16.748871 18.564453 17.421875 C 18.289279 16.618398 17.889948 15.875191 17.388672 15.208984 C 18.392525 14.45273 19.639928 14 21 14 z M 8.4355469 14.578125 C 9.1903993 16.782207 10.878414 18.554196 13.029297 19.419922 C 13.015367 19.612155 13 19.804317 13 20 C 13 21.797096 13.604527 23.452954 14.611328 24.791016 C 13.607475 25.54727 12.360072 26 11 26 C 7.6744439 26 5 23.325554 5 20 C 5 17.594646 6.4028703 15.536599 8.4355469 14.578125 z M 23.564453 14.578125 C 25.59713 15.536599 27 17.594646 27 20 C 27 23.325554 24.325556 26 21 26 C 19.639928 26 18.392525 25.54727 17.388672 24.791016 C 18.395473 23.452954 19 21.797096 19 20 C 19 19.804317 18.984633 19.612155 18.970703 19.419922 C 21.121586 18.554196 22.809601 16.782207 23.564453 14.578125 z M 16 16.675781 C 16.264346 17.073691 16.476452 17.507074 16.640625 17.964844 C 16.430031 17.986992 16.216682 18 16 18 C 15.783318 18 15.569969 17.986992 15.359375 17.964844 C 15.523548 17.507074 15.735654 17.073691 16 16.675781 z M 15.003906 19.931641 C 15.330903 19.972626 15.662196 20 16 20 C 16.337804 20 16.669097 19.972626 16.996094 19.931641 C 16.996351 19.954679 17 19.976898 17 20 C 17 21.232254 16.631467 22.373698 16 23.324219 C 15.368533 22.373698 15 21.232254 15 20 C 15 19.976898 15.003649 19.954679 15.003906 19.931641 z"></path></svg>
|
After Width: | Height: | Size: 2.4 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M 8 4 L 8 8 L 4 8 L 4 10 L 8 10 L 8 24 L 22 24 L 22 28 L 24 28 L 24 24 L 28 24 L 28 22 L 11.4375 22 L 22 11.4375 L 22 21 L 24 21 L 24 9.4375 L 27.71875 5.71875 L 26.28125 4.28125 L 22.5625 8 L 11 8 L 11 10 L 20.5625 10 L 10 20.5625 L 10 4 Z"></path></svg>
|
After Width: | Height: | Size: 325 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M 26 3.3125 L 4.5 15 L 26 15 Z M 4.46875 17 L 7.9375 18.875 L 24.53125 27.875 L 26 28.6875 L 26 17 Z M 12.34375 19 L 24 19 L 24 25.34375 Z"></path></svg>
|
After Width: | Height: | Size: 223 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M 15 4.46875 L 13.125 7.9375 L 4.125 24.53125 L 3.3125 26 L 15 26 Z M 17 4.5 L 17 26 L 28.6875 26 Z M 13 12.34375 L 13 24 L 6.65625 24 Z"></path></svg>
|
After Width: | Height: | Size: 221 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"><path d="M 46.0625 1.9375 C 45.976563 1.949219 45.894531 1.96875 45.8125 2 C 45.726563 2.019531 45.640625 2.050781 45.5625 2.09375 L 1.5625 24.09375 C 1.210938 24.257813 0.984375 24.613281 0.984375 25 C 0.984375 25.386719 1.210938 25.742188 1.5625 25.90625 L 45.5625 47.90625 C 46.0625 48.148438 46.664063 47.9375 46.90625 47.4375 C 47.148438 46.9375 46.9375 46.335938 46.4375 46.09375 L 39.40625 42.5625 C 41.109375 39.992188 45 33.238281 45 25 C 45 16.761719 41.109375 10.007813 39.40625 7.4375 L 46.4375 3.90625 C 46.960938 3.78125 47.292969 3.269531 47.191406 2.742188 C 47.089844 2.214844 46.59375 1.859375 46.0625 1.9375 Z M 35.75 9.25 C 36.667969 10.550781 41 17.03125 41 25 C 41 32.96875 36.667969 39.449219 35.75 40.75 L 26.59375 36.1875 C 28.097656 34.328125 31 30.078125 31 25 C 31 19.921875 28.097656 15.671875 26.59375 13.8125 Z M 21.6875 16.28125 C 20.347656 18.484375 19 21.542969 19 25 C 19 28.457031 20.347656 31.515625 21.6875 33.71875 L 4.25 25 Z"></path></svg>
|
After Width: | Height: | Size: 1.0 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M 5 5 L 5 7 L 7 7 L 7 5 Z M 9 5 L 9 7 L 11 7 L 11 5 Z M 13 5 L 13 7 L 15 7 L 15 5 Z M 17 5 L 17 7 L 19 7 L 19 5 Z M 21 5 L 21 7 L 23 7 L 23 5 Z M 25 5 L 25 7 L 27 7 L 27 5 Z M 5 9 L 5 11 L 7 11 L 7 9 Z M 25 9 L 25 11 L 27 11 L 27 9 Z M 14 11 L 14 13 L 17.5625 13 L 13.5625 17 L 5 17 L 5 27 L 15 27 L 15 18.4375 L 19 14.4375 L 19 18 L 21 18 L 21 11 Z M 5 13 L 5 15 L 7 15 L 7 13 Z M 25 13 L 25 15 L 27 15 L 27 13 Z M 25 17 L 25 19 L 27 19 L 27 17 Z M 7 19 L 13 19 L 13 25 L 7 25 Z M 25 21 L 25 23 L 27 23 L 27 21 Z M 17 25 L 17 27 L 19 27 L 19 25 Z M 21 25 L 21 27 L 23 27 L 23 25 Z M 25 25 L 25 27 L 27 27 L 27 25 Z"></path></svg>
|
After Width: | Height: | Size: 700 B |
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||
"id": "51c2d476-67e1-453f-888c-ae193bad7bc6",
|
||||
"alias": "ReactImageEditorWebPart",
|
||||
"componentType": "WebPart",
|
||||
|
||||
"version": "*",
|
||||
"manifestVersion": 2,
|
||||
|
||||
"requiresCustomScript": false,
|
||||
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70",
|
||||
"group": { "default": "Other" },
|
||||
"title": { "default": "react-image-editor" },
|
||||
"description": { "default": "react-image-editor description" },
|
||||
"officeFabricIconFontName": "Page",
|
||||
"properties": {
|
||||
"title": "react-image-editor Sample",
|
||||
"showTitle":true,
|
||||
"settings":[],
|
||||
"url":""
|
||||
}
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
import * as React from 'react';
|
||||
import * as ReactDom from 'react-dom';
|
||||
import { Version } from '@microsoft/sp-core-library';
|
||||
import {
|
||||
BaseClientSideWebPart,
|
||||
IPropertyPaneConfiguration,
|
||||
PropertyPaneToggle
|
||||
} from '@microsoft/sp-webpart-base';
|
||||
|
||||
import * as strings from 'ReactImageEditorWebPartStrings';
|
||||
import ReactImageEditor, { IReactImageEditorBaseProps, IReactImageEditorProps } from './components/ReactImageEditor';
|
||||
import { IImageManipulationSettings } from '../../components';
|
||||
|
||||
export interface IReactImageEditorWebPartProps extends IReactImageEditorBaseProps {
|
||||
|
||||
}
|
||||
|
||||
export default class ReactImageEditorWebPart extends BaseClientSideWebPart<IReactImageEditorWebPartProps> {
|
||||
|
||||
public render(): void {
|
||||
const element: React.ReactElement<IReactImageEditorProps> = React.createElement(
|
||||
ReactImageEditor,
|
||||
{
|
||||
context: this.context,
|
||||
displayMode: this.displayMode,
|
||||
|
||||
showTitle: this.properties.showTitle,
|
||||
title: this.properties.title,
|
||||
url: this.properties.url,
|
||||
settings: this.properties.settings,
|
||||
|
||||
updateTitleProperty: (value: string) => { this.properties.title = value; },
|
||||
updateUrlProperty: (value: string) => {
|
||||
// tslint:disable-next-line: curly
|
||||
if (this.properties.url !== value)
|
||||
this.properties.url = value;
|
||||
this.properties.settings = [];
|
||||
this.render();
|
||||
},
|
||||
updateManipulationSettingsProperty: (value: IImageManipulationSettings[]) => {
|
||||
this.properties.settings = value;
|
||||
this.render();
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
ReactDom.render(element, this.domElement);
|
||||
}
|
||||
|
||||
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: [
|
||||
PropertyPaneToggle('showTitle', {
|
||||
label: strings.ShowTitleFieldLabel
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
|
||||
|
||||
.reactImageEditor {
|
||||
display: block;
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
import * as React from 'react';
|
||||
import styles from './ReactImageEditor.module.scss';
|
||||
import { WebPartTitle } from '@pnp/spfx-controls-react/lib/WebPartTitle';
|
||||
import { DisplayMode, Environment, EnvironmentType } from '@microsoft/sp-core-library';
|
||||
import { Placeholder } from '@pnp/spfx-controls-react/lib/Placeholder';
|
||||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { FilePicker, IFilePickerResult } from '@pnp/spfx-controls-react/lib/FilePicker';
|
||||
import { ImageManipulation, IImageManipulationSettings } from '../../../components/ImageManipulation';
|
||||
|
||||
export interface IReactImageEditorBaseProps {
|
||||
showTitle: boolean;
|
||||
title: string;
|
||||
url?: string;
|
||||
settings?: IImageManipulationSettings[];
|
||||
|
||||
}
|
||||
|
||||
export interface IReactImageEditorProps extends IReactImageEditorBaseProps {
|
||||
displayMode: DisplayMode;
|
||||
context: WebPartContext;
|
||||
updateTitleProperty: (value: string) => void;
|
||||
updateUrlProperty: (value: string) => void;
|
||||
updateManipulationSettingsProperty: (value: IImageManipulationSettings[]) => void;
|
||||
}
|
||||
|
||||
export interface IReactImageEditorState {
|
||||
isFilePickerOpen: boolean;
|
||||
statekey: string;
|
||||
}
|
||||
|
||||
export default class ReactImageEditor extends React.Component<IReactImageEditorProps, IReactImageEditorState> {
|
||||
constructor(props: IReactImageEditorProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isFilePickerOpen: false,
|
||||
statekey: 'init'
|
||||
};
|
||||
this._onConfigure = this._onConfigure.bind(this);
|
||||
this._onUrlChanged = this._onUrlChanged.bind(this);
|
||||
this._onSettingsChanged = this._onSettingsChanged.bind(this);
|
||||
}
|
||||
public render(): React.ReactElement<IReactImageEditorProps> {
|
||||
const { url, settings } = this.props;
|
||||
const { isFilePickerOpen } = this.state;
|
||||
const isConfigured: boolean = !!url && url.length > 0;
|
||||
return (
|
||||
|
||||
<div className={styles.reactImageEditor}>
|
||||
<WebPartTitle displayMode={this.props.displayMode}
|
||||
title={this.props.title}
|
||||
updateProperty={this.props.updateTitleProperty} />
|
||||
{(isFilePickerOpen || isConfigured) && Environment.type !== EnvironmentType.Local &&
|
||||
<FilePicker
|
||||
isPanelOpen={isFilePickerOpen}
|
||||
accepts={['.gif', '.jpg', '.jpeg', '.png']}
|
||||
buttonIcon='FileImage'
|
||||
onSave={(filePickerResult: IFilePickerResult) => {
|
||||
this.setState({ isFilePickerOpen: false }, () => this._onUrlChanged(filePickerResult.fileAbsoluteUrl));
|
||||
}}
|
||||
onCancel={() => {
|
||||
this.setState({ isFilePickerOpen: false });
|
||||
}}
|
||||
onChanged={(filePickerResult: IFilePickerResult) => {
|
||||
this.setState({ isFilePickerOpen: false }, () => this._onUrlChanged(filePickerResult.fileAbsoluteUrl));
|
||||
|
||||
}}
|
||||
context={this.props.context}
|
||||
/>}
|
||||
|
||||
{!isConfigured ? (<Placeholder iconName='Edit'
|
||||
iconText='Configure your web part'
|
||||
description='Please configure the web part.'
|
||||
buttonLabel='Configure'
|
||||
onConfigure={this._onConfigure} />) :
|
||||
(
|
||||
<ImageManipulation
|
||||
settings={this.props.settings}
|
||||
configSettings={{
|
||||
rotateButtons: [-90, -45, -30, 0, 30, 45, 90]
|
||||
}
|
||||
}
|
||||
displayMode={this.props.displayMode}
|
||||
settingsChanged={this._onSettingsChanged}
|
||||
src={this.props.url}
|
||||
/>
|
||||
)}
|
||||
|
||||
</div >
|
||||
);
|
||||
}
|
||||
|
||||
private _onConfigure = () => {
|
||||
if (Environment.type === EnvironmentType.Local) {
|
||||
this.setState({ isFilePickerOpen: false }, () => {
|
||||
this._onUrlChanged(
|
||||
'https://media.gettyimages.com/photos/'
|
||||
+ 'whitewater-paddlers-descend-vertical-waterfall-in-kayak-picture-id1256321293?s=2048x2048'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
this.setState({ isFilePickerOpen: true });
|
||||
}
|
||||
}
|
||||
private _onUrlChanged = (url: string) => {
|
||||
this.props.updateUrlProperty(url);
|
||||
}
|
||||
private _onSettingsChanged = (settings: IImageManipulationSettings[]) => {
|
||||
this.props.updateManipulationSettingsProperty(settings);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
define([], function() {
|
||||
return {
|
||||
"PropertyPaneDescription": "Description",
|
||||
"BasicGroupName": "Group Name",
|
||||
"ShowTitleFieldLabel": "Show webpart title"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
declare interface IReactImageEditorWebPartStrings {
|
||||
PropertyPaneDescription: string;
|
||||
BasicGroupName: string;
|
||||
ShowTitleFieldLabel: string;
|
||||
}
|
||||
|
||||
declare module 'ReactImageEditorWebPartStrings' {
|
||||
const strings: IReactImageEditorWebPartStrings;
|
||||
export = strings;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"skipLibCheck": true,
|
||||
"typeRoots": [
|
||||
"./node_modules/@types",
|
||||
"./node_modules/@microsoft"
|
||||
],
|
||||
"types": [
|
||||
"es6-promise",
|
||||
"webpack-env"
|
||||
],
|
||||
"lib": [
|
||||
"es5",
|
||||
"dom",
|
||||
"es2015.collection"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"extends": "@microsoft/sp-tslint-rules/base-tslint.json",
|
||||
"rules": {
|
||||
"class-name": false,
|
||||
"export-name": false,
|
||||
"forin": false,
|
||||
"label-position": false,
|
||||
"member-access": true,
|
||||
"no-arg": false,
|
||||
"no-console": false,
|
||||
"no-construct": false,
|
||||
"no-duplicate-variable": true,
|
||||
"no-eval": false,
|
||||
"no-function-expression": true,
|
||||
"no-internal-module": true,
|
||||
"no-shadowed-variable": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-unnecessary-semicolons": true,
|
||||
"no-unused-expression": true,
|
||||
"no-use-before-declare": true,
|
||||
"no-with-statement": true,
|
||||
"semicolon": true,
|
||||
"trailing-comma": false,
|
||||
"typedef": false,
|
||||
"typedef-whitespace": false,
|
||||
"use-named-parameter": true,
|
||||
"variable-name": false,
|
||||
"whitespace": false,
|
||||
"react-a11y-event-has-role": true
|
||||
}
|
||||
}
|
|
@ -856,6 +856,12 @@
|
|||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
|
||||
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1746,6 +1752,12 @@
|
|||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
|
||||
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1985,6 +1997,12 @@
|
|||
"yargs": "^8.0.2"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
|
||||
|
@ -9283,12 +9301,6 @@
|
|||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "15.3.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
|
||||
|
@ -10910,6 +10922,12 @@
|
|||
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz",
|
||||
|
@ -11749,6 +11767,12 @@
|
|||
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz",
|
||||
|
@ -17044,6 +17068,12 @@
|
|||
"integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
|
||||
|
@ -18774,6 +18804,12 @@
|
|||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz",
|
||||
|
@ -19605,6 +19641,12 @@
|
|||
"has-flag": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
|
||||
|
@ -19858,9 +19900,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
|
||||
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
|
@ -19935,6 +19977,12 @@
|
|||
"strip-ansi": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
|
||||
|
|
|
@ -10170,8 +10170,8 @@ xmlbuilder@0.4.3:
|
|||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
|
||||
|
||||
y18n@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696"
|
||||
|
||||
y18n@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
|
|
@ -4445,9 +4445,9 @@
|
|||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
|
||||
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
|
@ -17519,9 +17519,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
|
|
|
@ -12768,9 +12768,9 @@
|
|||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
|
||||
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
|
@ -16311,9 +16311,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
|
|
|
@ -8138,8 +8138,8 @@ xtend@~3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a"
|
||||
|
||||
y18n@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696"
|
||||
|
||||
y18n@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
|
|
@ -6,9 +6,15 @@ This is an application that supports Questions & Answers through a web part that
|
|||
|
||||
![Questions and Answers](./assets/QuestionsAndAnswers.gif)
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
|
||||
![1.11.0](https://img.shields.io/badge/version-1.11.0-green.svg)
|
||||
## Compatibility
|
||||
|
||||
![SPFx 1.11](https://img.shields.io/badge/SPFx-1.11.0-green.svg)
|
||||
![Node.js LTS 10.x](https://img.shields.io/badge/Node.js-LTS%2010.x-green.svg)
|
||||
![SharePoint Online](https://img.shields.io/badge/SharePoint-Online-yellow.svg)
|
||||
![Teams Yes: Designed for Microsoft Teams](https://img.shields.io/badge/Teams-Yes-green.svg "Designed for Microsoft Teams")
|
||||
![Workbench Hosted: Does not work with local workbench](https://img.shields.io/badge/Workbench-Hosted-yellow.svg "Does not work with local workbench")
|
||||
|
||||
|
||||
## Applies to
|
||||
|
||||
|
@ -24,13 +30,14 @@ This is an application that supports Questions & Answers through a web part that
|
|||
|
||||
Solution|Author(s)
|
||||
--------|---------
|
||||
react-questions-and-answers | Bo George ([@bo_george](https://twitter.com/bo_george))
|
||||
react-questions-and-answers | Bo George ([@bo_george](https://twitter.com/bo_george)), Mike Homol ([@homol](https://twitter.com/homol))
|
||||
|
||||
## Version history
|
||||
|
||||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|September 13, 2020|Initial release
|
||||
2.0|March, 22, 2021|Version 2.0 with new features and new editor based on TinyMCE.<br />This change has new list schema dependencies so you will need remove and re-add the app if you installed version 1.0. See below for more on what's new in 2.o
|
||||
|
||||
## Disclaimer
|
||||
|
||||
|
@ -61,7 +68,7 @@ Version|Date|Comments
|
|||
* If you deployed a shippable (SharePoint Online) version you don't need to do anything else
|
||||
* If you deployed a debug (http://localhost:4321) version you'll need to ensure gulp serve is running
|
||||
|
||||
## Features
|
||||
## Features in Version 1
|
||||
|
||||
Below is intended to provide “notable” details on different features. Notable meaning, they may be different than a typical expectation or require clarification. For all features see “Features based Questions Role” to understand if they are available for a specific role.
|
||||
|
||||
|
@ -133,4 +140,19 @@ Mark/Unmark a Reply as Helpful|Yes|Yes|No
|
|||
Mark/Unmark a Reply as Correct Answer - Question entered by me|Yes|Yes|No
|
||||
Mark/Unmark a Reply as Correct Answer - Question entered by others|Yes|No|No
|
||||
|
||||
## Summary of Features added in Version 2
|
||||
|
||||
* Upgraded editor to support:
|
||||
* use TinyMCE standalone as a replacement for primereact
|
||||
* embedding of images in questions, conversations and replies
|
||||
* at mention users within editor
|
||||
* Introduced "Conversations" which are behave like Questions without the ability to:
|
||||
* Mark a reply as Helpful
|
||||
* Mark a reply as the correct answer
|
||||
* Add ability to categorize questions which:
|
||||
* allows a single site to have questions on many different topics and filter them as necessary
|
||||
* Make the Questions list visible and searchable
|
||||
* added extension which intercepts list item url and redirects to the appropriate questions or conversations page with threaded replies
|
||||
* Bug fixes with dates
|
||||
|
||||
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-questions-and-answers" />
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
"longDescription": [
|
||||
"This is an application that supports Questions \u0026 Answers through a web part that can be used directly on a Modern SharePoint Site without the need for Yammer or a backing Microsoft Team site. It relies on a backing SharePoint list that is hidden and a provisioned Site Page that hosts a pre-configured version of the questions web part."
|
||||
],
|
||||
"created": "2020-10-01",
|
||||
"modified": "2020-10-01",
|
||||
"created": "2021-03-22",
|
||||
"modified": "2021-03-22",
|
||||
"products": [
|
||||
"SharePoint",
|
||||
"Office"
|
||||
|
@ -67,4 +67,4 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
@ -9,11 +9,20 @@
|
|||
"manifest": "./src/webparts/questions/QuestionsWebPart.manifest.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"questions-list-manager": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/extensions/questionsListManager/QuestionsListManagerApplicationCustomizer.js",
|
||||
"manifest": "./src/extensions/questionsListManager/QuestionsListManagerApplicationCustomizer.manifest.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"externals": {},
|
||||
"externals": {
|
||||
},
|
||||
"localizedResources": {
|
||||
"QuestionsWebPartStrings": "lib/webparts/questions/loc/{locale}.js",
|
||||
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +1,57 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "Questions and Answers",
|
||||
"id": "6feb4c2f-341b-499c-998c-9b2ebd95435c",
|
||||
"version": "1.0.1.0",
|
||||
"skipFeatureDeployment": false,
|
||||
"iconPath": "images/Feedback_Icon.png",
|
||||
"includeClientSideAssets": true,
|
||||
"features": [
|
||||
{
|
||||
"id": "2088baa5-aab6-43ec-907b-147a786c2b36",
|
||||
"title": "Questions Assets",
|
||||
"description": "Provides assets to support Questions webpart. This includes schema elements such as content types, site columns and list instance as well as the Questions application page.",
|
||||
"version": "1.0.2.0",
|
||||
"assets": {
|
||||
"elementManifests": [
|
||||
"elements.xml"
|
||||
],
|
||||
"elementFiles": [
|
||||
"schema.xml",
|
||||
"QuestionsSitePage.aspx"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"developer": {
|
||||
"name": "Bo George",
|
||||
"websiteUrl": "https://threewill.com/team/bo-george/",
|
||||
"privacyUrl": "",
|
||||
"termsOfUseUrl": "",
|
||||
"mpnId": "m365pnp"
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/react-questions-and-answers.sppkg"
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
|
||||
"solution": {
|
||||
"name": "Questions and Answers",
|
||||
"id": "6feb4c2f-341b-499c-998c-9b2ebd95435c",
|
||||
"version": "2.0.1.15",
|
||||
"skipFeatureDeployment": false,
|
||||
"iconPath": "images/Feedback_Icon.png",
|
||||
"includeClientSideAssets": true,
|
||||
"features": [
|
||||
{
|
||||
"id": "2088baa5-aab6-43ec-907b-147a786c2b36",
|
||||
"title": "Questions Assets",
|
||||
"description": "Provides assets to support Questions webpart. This includes schema elements such as content types, site columns and list instance as well as the Questions application page.",
|
||||
"version": "2.0.1.15",
|
||||
"assets": {
|
||||
"elementManifests": [
|
||||
"elements.xml"
|
||||
],
|
||||
"elementFiles": [
|
||||
"schema.xml",
|
||||
"QuestionsSitePage.aspx",
|
||||
"ConversationsSitePage.aspx"
|
||||
]
|
||||
},
|
||||
"componentIds": [
|
||||
"761fbf9d-6ef9-4099-8488-02d5e2826f36"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "bf9284ec-1ca1-43bc-b277-daf358bdf250",
|
||||
"title": "Question List Manager",
|
||||
"description": "Enables the Question List Manager Application Extension",
|
||||
"version": "2.0.1.15",
|
||||
"assets": {
|
||||
"elementManifests": [
|
||||
"elements2.xml",
|
||||
"ClientSideInstance.xml"
|
||||
]
|
||||
},
|
||||
"componentIds": [
|
||||
"aefe4f31-4914-4dcb-be8c-f24bf52f7719"
|
||||
]
|
||||
}
|
||||
],
|
||||
"developer": {
|
||||
"name": "Bo George",
|
||||
"websiteUrl": "https://threewill.com/team/bo-george/",
|
||||
"privacyUrl": "",
|
||||
"termsOfUseUrl": "",
|
||||
"mpnId": ""
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/react-questions-and-answers.sppkg"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
|
||||
<title>ic_fluent_arrow_redo_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-System-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_arrow_redo_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M19.25,1.99981721 C18.8703042,1.99981721 18.556509,2.28197109 18.5068466,2.64804665 L18.5,2.74981721 L18.5,8.43981721 L13.9256607,3.87995431 C11.483715,1.43800869 7.56154453,1.37844904 5.04739282,3.70127537 L4.8615166,3.87995431 C2.35852234,6.38294858 2.35852234,10.4411041 4.8615166,12.9440984 L13.7066528,21.7832698 L13.7066528,21.7832698 C13.9996749,22.0760341 14.4744198,22.0756964 14.767313,21.7828032 C15.0602061,21.48991 15.0598683,21.0149074 14.7668462,20.7221431 L5.92217677,11.8834382 L5.92217677,11.8834382 C4.00496895,9.96623037 4.00496895,6.85782231 5.92217677,4.94061449 C7.78128739,3.08150387 10.7604981,3.02516718 12.6881921,4.77230194 L12.8657665,4.94137945 L17.438,9.49981721 L11.75,9.5 C11.3703042,9.5 11.056509,9.78215388 11.0068466,10.1482294 L11,10.25 C11,10.6296958 11.2821539,10.943491 11.6482294,10.9931534 L11.75,11 L19.25,11 C19.6296958,11 19.943491,10.7178461 19.9931534,10.3517706 L20,10.25 L20,2.74981721 C20,2.33560365 19.6642136,1.99981721 19.25,1.99981721 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
|
||||
<title>ic_fluent_arrow_undo_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-System-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_arrow_undo_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M4.75,1.99981721 C5.12969577,1.99981721 5.44349096,2.28197109 5.49315338,2.64804665 L5.5,2.74981721 L5.5,8.43981721 L10.0743393,3.87995431 C12.516285,1.43800869 16.4384555,1.37844904 18.9526072,3.70127537 L19.1384834,3.87995431 C21.6414777,6.38294858 21.6414777,10.4411041 19.1384834,12.9440984 L10.2933472,21.7832698 L10.2933472,21.7832698 C10.0003251,22.0760341 9.52558023,22.0756964 9.23268704,21.7828032 C8.93979385,21.48991 8.9401317,21.0149074 9.23315376,20.7221431 L18.0778232,11.8834382 L18.0778232,11.8834382 C19.9950311,9.96623037 19.9950311,6.85782231 18.0778232,4.94061449 C16.2187126,3.08150387 13.2395019,3.02516718 11.3118079,4.77230194 L11.1342335,4.94137945 L6.562,9.49981721 L12.25,9.5 C12.6296958,9.5 12.943491,9.78215388 12.9931534,10.1482294 L13,10.25 C13,10.6296958 12.7178461,10.943491 12.3517706,10.9931534 L12.25,11 L4.75,11 C4.37030423,11 4.05650904,10.7178461 4.00684662,10.3517706 L4,10.25 L4,2.74981721 C4,2.33560365 4.33578644,1.99981721 4.75,1.99981721 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>ic_fluent_color_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_color_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M3.83904058,5.85749561 C6.78004581,1.94188971 12.8686707,0.802505202 17.2029394,3.497377 C21.4827525,6.15839057 23.0567972,11.2744655 21.303866,16.0747407 C19.648689,20.6073231 15.2875295,22.403209 12.1442101,20.1231428 C10.9667425,19.2690444 10.5102901,18.1984035 10.2896576,16.4593132 L10.1842745,15.4713913 L10.1388589,15.073954 C10.0162342,14.1399065 9.82780748,13.7214296 9.43453605,13.5022264 C8.89894535,13.2036966 8.54231757,13.1967226 7.83905282,13.4692784 L7.48794193,13.6148779 L7.30920754,13.6928218 C6.29543196,14.1331038 5.62104161,14.2877923 4.76804588,14.1090543 L4.56779442,14.0618665 L4.40426138,14.0152691 C1.61529547,13.1510586 1.20220653,9.36813303 3.83904058,5.85749561 Z M4.8232597,12.5739125 L4.94616428,12.610372 L5.080113,12.6412161 C5.51918878,12.7281665 5.89444039,12.6556749 6.51713486,12.3993955 L7.11930681,12.1421347 C8.32144994,11.6492191 9.1045463,11.6010233 10.1648305,12.1920088 C11.0824191,12.7034581 11.4400583,13.4895978 11.62247,14.8516511 L11.6756637,15.310802 L11.729873,15.8425189 L11.7770095,16.2649431 C11.9490842,17.6262078 12.2619162,18.3554553 13.024955,18.90894 C15.3002886,20.5593963 18.5593937,19.2173263 19.8948725,15.5602143 C21.411142,11.4080201 20.0689941,7.04567303 16.4109117,4.77122636 C12.736718,2.48676231 7.51248742,3.46438986 5.03840796,6.75833849 C2.96361994,9.52067707 3.21809532,12.0378944 4.8232597,12.5739125 Z M16.0477462,10.5795744 C15.8690689,9.91274179 16.264797,9.2273206 16.9316297,9.04864333 C17.5984623,8.86996607 18.2838835,9.26569418 18.4625608,9.93252681 C18.641238,10.5993594 18.2455099,11.2847806 17.5786773,11.4634579 C16.9118447,11.6421352 16.2264235,11.2464071 16.0477462,10.5795744 Z M16.5423361,14.0682389 C16.3636589,13.4014063 16.759387,12.7159851 17.4262196,12.5373078 C18.0930522,12.3586306 18.7784734,12.7543587 18.9571507,13.4211913 C19.135828,14.0880239 18.7400999,14.7734451 18.0732672,14.9521224 C17.4064346,15.1307997 16.7210134,14.7350716 16.5423361,14.0682389 Z M14.0692386,7.57689062 C13.8905613,6.91005799 14.2862894,6.2246368 14.9531221,6.04595953 C15.6199547,5.86728227 16.3053759,6.26301038 16.4840531,6.92984301 C16.6627304,7.59667564 16.2670023,8.28209683 15.6001697,8.4607741 C14.933337,8.63945136 14.2479158,8.24372325 14.0692386,7.57689062 Z M14.0407569,16.5752747 C13.8620796,15.9084421 14.2578077,15.2230209 14.9246403,15.0443437 C15.591473,14.8656664 16.2768942,15.2613945 16.4555714,15.9282271 C16.6342487,16.5950598 16.2385206,17.280481 15.571688,17.4591582 C14.9048553,17.6378355 14.2194341,17.2421074 14.0407569,16.5752747 Z M10.5438339,6.60529725 C10.3651566,5.93846462 10.7608847,5.25304343 11.4277174,5.07436616 C12.09455,4.8956889 12.7799712,5.29141701 12.9586484,5.95824964 C13.1373257,6.62508227 12.7415976,7.31050346 12.074765,7.48918073 C11.4079323,7.66785799 10.7225111,7.27212988 10.5438339,6.60529725 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>ic_fluent_copy_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_copy_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M5.50280381,4.62704038 L5.5,6.75 L5.5,17.2542087 C5.5,19.0491342 6.95507456,20.5042087 8.75,20.5042087 L17.3662868,20.5044622 C17.057338,21.3782241 16.2239751,22.0042087 15.2444057,22.0042087 L8.75,22.0042087 C6.12664744,22.0042087 4,19.8775613 4,17.2542087 L4,6.75 C4,5.76928848 4.62744523,4.93512464 5.50280381,4.62704038 Z M17.75,2 C18.9926407,2 20,3.00735931 20,4.25 L20,17.25 C20,18.4926407 18.9926407,19.5 17.75,19.5 L8.75,19.5 C7.50735931,19.5 6.5,18.4926407 6.5,17.25 L6.5,4.25 C6.5,3.00735931 7.50735931,2 8.75,2 L17.75,2 Z M17.75,3.5 L8.75,3.5 C8.33578644,3.5 8,3.83578644 8,4.25 L8,17.25 C8,17.6642136 8.33578644,18 8.75,18 L17.75,18 C18.1642136,18 18.5,17.6642136 18.5,17.25 L18.5,4.25 C18.5,3.83578644 18.1642136,3.5 17.75,3.5 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.1409 9.34138L12.14 9.34274L7.37017 2.32828C7.13725 1.98575 6.67077 1.8969 6.32824 2.12982C5.98572 2.36273 5.89687 2.82922 6.12978 3.17174L11.2606 10.7169L8.86478 14.4604C8.30797 14.1664 7.67342 14 7 14C4.79086 14 3 15.7909 3 18C3 20.2091 4.79086 22 7 22C9.20914 22 11 20.2091 11 18C11 17.0088 10.6395 16.1018 10.0424 15.403L12.178 12.0661L14.2426 15.1023C13.4771 15.8309 13 16.8597 13 18C13 20.2091 14.7909 22 17 22C19.2091 22 21 20.2091 21 18C21 15.7909 19.2091 14 17 14C16.471 14 15.9659 14.1027 15.5037 14.2893L13.0575 10.6919L13.0588 10.6899L12.1409 9.34138ZM4.5 18C4.5 16.6193 5.61929 15.5 7 15.5C8.38071 15.5 9.5 16.6193 9.5 18C9.5 19.3807 8.38071 20.5 7 20.5C5.61929 20.5 4.5 19.3807 4.5 18ZM14.5 18C14.5 16.6193 15.6193 15.5 17 15.5C18.3807 15.5 19.5 16.6193 19.5 18C19.5 19.3807 18.3807 20.5 17 20.5C15.6193 20.5 14.5 19.3807 14.5 18Z" fill="#212121"/>
|
||||
<path d="M13.9381 9.31594L17.8815 3.15426C18.1048 2.80538 18.003 2.34155 17.6541 2.11827C17.3053 1.89498 16.8414 1.9968 16.6181 2.34568L13.0202 7.96744L13.9381 9.31594Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>ic_fluent_dismiss_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_dismiss_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M4.39705176,4.55378835 L4.46966991,4.46966991 C4.73593648,4.20340335 5.15260016,4.1791973 5.44621165,4.39705176 L5.53033009,4.46966991 L12,10.939 L18.4696699,4.46966991 C18.7625631,4.1767767 19.2374369,4.1767767 19.5303301,4.46966991 C19.8232233,4.76256313 19.8232233,5.23743687 19.5303301,5.53033009 L13.061,12 L19.5303301,18.4696699 C19.7965966,18.7359365 19.8208027,19.1526002 19.6029482,19.4462117 L19.5303301,19.5303301 C19.2640635,19.7965966 18.8473998,19.8208027 18.5537883,19.6029482 L18.4696699,19.5303301 L12,13.061 L5.53033009,19.5303301 C5.23743687,19.8232233 4.76256313,19.8232233 4.46966991,19.5303301 C4.1767767,19.2374369 4.1767767,18.7625631 4.46966991,18.4696699 L10.939,12 L4.46966991,5.53033009 C4.20340335,5.26406352 4.1791973,4.84739984 4.39705176,4.55378835 L4.46966991,4.46966991 L4.39705176,4.55378835 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>ic_fluent_highlight_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_highlight_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M20.2585648,2.00438474 C20.6382605,2.00472706 20.9518016,2.28716326 21.0011348,2.65328337 L21.0078899,2.75506004 L21.0038407,7.25276883 C21.0009137,8.40908568 20.1270954,9.36072944 19.0029371,9.48671858 L19.0024932,11.7464847 C19.0024932,12.9373487 18.0773316,13.9121296 16.906542,13.9912939 L16.7524932,13.9964847 L16.501,13.9963847 L16.5017549,16.7881212 C16.5017549,17.6030744 16.0616895,18.349347 15.3600767,18.7462439 L15.2057929,18.8258433 L8.57108142,21.9321389 C8.10484975,22.1504232 7.57411944,21.8450614 7.50959937,21.3535767 L7.50306874,21.2528982 L7.503,13.9963847 L7.25,13.9964847 C6.05913601,13.9964847 5.08435508,13.0713231 5.00519081,11.9005335 L5,11.7464847 L5.00043957,9.4871861 C3.92882124,9.36893736 3.08392302,8.49812196 3.0058865,7.41488149 L3,7.25086975 L3,2.75438506 C3,2.3401715 3.33578644,2.00438474 3.75,2.00438474 C4.12969577,2.00438474 4.44349096,2.28653894 4.49315338,2.6526145 L4.5,2.75438506 L4.5,7.25086975 C4.5,7.63056552 4.78215388,7.94436071 5.14822944,7.99402313 L5.25,8.00086975 L18.7512697,8.00087075 C19.1315998,8.00025031 19.4461483,7.71759877 19.4967392,7.3518545 L19.5038434,7.25019537 L19.5078902,2.75371008 C19.508263,2.33949668 19.8443515,2.00401258 20.2585648,2.00438474 Z M15.001,13.9963847 L9.003,13.9963847 L9.00306874,20.0736262 L14.5697676,17.4673619 C14.8004131,17.3593763 14.9581692,17.1431606 14.9940044,16.89581 L15.0017549,16.7881212 L15.001,13.9963847 Z M17.502,9.50038474 L6.5,9.50038474 L6.5,11.7464847 C6.5,12.1261805 6.78215388,12.4399757 7.14822944,12.4896381 L7.25,12.4964847 L16.7524932,12.4964847 C17.1321889,12.4964847 17.4459841,12.2143308 17.4956465,11.8482552 L17.5024932,11.7464847 L17.502,9.50038474 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>ic_fluent_image_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_image_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M17.75,3 C19.5449254,3 21,4.45507456 21,6.25 L21,17.75 C21,19.5449254 19.5449254,21 17.75,21 L6.25,21 C4.45507456,21 3,19.5449254 3,17.75 L3,6.25 C3,4.45507456 4.45507456,3 6.25,3 L17.75,3 Z M18.330538,19.401407 L12.5246673,13.7148182 C12.259617,13.4552555 11.8501251,13.4316429 11.558795,13.6439914 L11.4752034,13.7147748 L5.66845098,19.4010512 C5.85040089,19.4651384 6.04612926,19.5 6.25,19.5 L17.75,19.5 C17.9534932,19.5 18.1488742,19.4652674 18.330538,19.401407 L12.5246673,13.7148182 L18.330538,19.401407 Z M17.75,4.5 L6.25,4.5 C5.28350169,4.5 4.5,5.28350169 4.5,6.25 L4.5,17.75 C4.5,17.9584012 4.53642824,18.1582941 4.60326447,18.3436585 L10.4257839,12.6429919 C11.2588664,11.8272921 12.5674613,11.7885018 13.4457696,12.5265833 L13.5741754,12.6431221 L19.396372,18.3446658 C19.4634397,18.1590183 19.5,17.9587787 19.5,17.75 L19.5,6.25 C19.5,5.28350169 18.7164983,4.5 17.75,4.5 Z M15.252115,6.5 C16.4959237,6.5 17.50423,7.50830622 17.50423,8.75211499 C17.50423,9.99592375 16.4959237,11.00423 15.252115,11.00423 C14.0083062,11.00423 13,9.99592375 13,8.75211499 C13,7.50830622 14.0083062,6.5 15.252115,6.5 Z M15.252115,8 C14.8367333,8 14.5,8.33673335 14.5,8.75211499 C14.5,9.16749662 14.8367333,9.50422997 15.252115,9.50422997 C15.6674966,9.50422997 16.00423,9.16749662 16.00423,8.75211499 C16.00423,8.33673335 15.6674966,8 15.252115,8 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>ic_fluent_link_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_link_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M9.25,7 C9.66421356,7 10,7.33578644 10,7.75 C10,8.12655778 9.72249055,8.43829976 9.3608295,8.49186807 L9.25,8.5 L7,8.5 C5.06700338,8.5 3.5,10.0670034 3.5,12 C3.5,13.863961 4.95707329,15.3876044 6.79434841,15.4940585 L7,15.5 L9.25,15.5 C9.66421356,15.5 10,15.8357864 10,16.25 C10,16.6265578 9.72249055,16.9382998 9.3608295,16.9918681 L9.25,17 L7,17 C4.23857625,17 2,14.7614237 2,12 C2,9.32225576 4.10496059,7.13615141 6.75044957,7.00611913 L7,7 L9.25,7 Z M17,7 C19.7614237,7 22,9.23857625 22,12 C22,14.6777442 19.8950394,16.8638486 17.2495504,16.9938809 L17,17 L14.75,17 C14.3357864,17 14,16.6642136 14,16.25 C14,15.8734422 14.2775095,15.5617002 14.6391705,15.5081319 L14.75,15.5 L17,15.5 C18.9329966,15.5 20.5,13.9329966 20.5,12 C20.5,10.136039 19.0429267,8.61239564 17.2056516,8.50594148 L17,8.5 L14.75,8.5 C14.3357864,8.5 14,8.16421356 14,7.75 C14,7.37344222 14.2775095,7.06170024 14.6391705,7.00813193 L14.75,7 L17,7 Z M7,11.25 L17,11.25 C17.4142136,11.25 17.75,11.5857864 17.75,12 C17.75,12.3796958 17.4678461,12.693491 17.1017706,12.7431534 L17,12.75 L7,12.75 C6.58578644,12.75 6.25,12.4142136 6.25,12 C6.25,11.6203042 6.53215388,11.306509 6.89822944,11.2568466 L7,11.25 L17,11.25 L7,11.25 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1,6 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.25 5C9.66421 5 10 5.33579 10 5.75C10 6.12656 9.72249 6.4383 9.36083 6.49187L9.25 6.5H7C5.067 6.5 3.5 8.067 3.5 10C3.5 11.864 4.95707 13.3876 6.79435 13.4941L7 13.5H9.25C9.66421 13.5 10 13.8358 10 14.25C10 14.6266 9.72249 14.9383 9.36083 14.9919L9.25 15H7C4.23858 15 2 12.7614 2 10C2 7.32226 4.10496 5.13615 6.75045 5.00612L7 5H9.25Z" fill="#212121"/>
|
||||
<path d="M17 5C19.7614 5 22 7.23858 22 10C22 10.2921 21.975 10.5783 21.9269 10.8566C21.5089 10.4752 21.0162 10.2212 20.4987 10.0945C20.4996 10.0631 20.5 10.0316 20.5 10C20.5 8.13604 19.0429 6.6124 17.2057 6.50594L17 6.5H14.75C14.3358 6.5 14 6.16421 14 5.75C14 5.37344 14.2775 5.0617 14.6392 5.00813L14.75 5H17Z" fill="#212121"/>
|
||||
<path d="M7 9.25H17C17.4142 9.25 17.75 9.58579 17.75 10C17.75 10.3797 17.4678 10.6935 17.1018 10.7432L17 10.75H7C6.58579 10.75 6.25 10.4142 6.25 10C6.25 9.6203 6.53215 9.30651 6.89823 9.25685L7 9.25Z" fill="#212121"/>
|
||||
<path d="M12.1957 17.5719L18.0981 11.6695C18.9908 10.7768 20.438 10.7768 21.3306 11.6695C22.2232 12.5621 22.2232 14.0093 21.3306 14.9019L15.4282 20.8043C15.084 21.1485 14.6528 21.3926 14.1807 21.5106L12.35 21.9683C11.5538 22.1674 10.8327 21.4462 11.0317 20.6501L11.4894 18.8194C11.6075 18.3472 11.8516 17.916 12.1957 17.5719ZM19.1588 12.7301L13.2564 18.6325C13.1045 18.7844 12.9967 18.9748 12.9446 19.1832L12.6539 20.3462L13.8169 20.0554C14.0253 20.0033 14.2156 19.8956 14.3675 19.7437L20.2699 13.8412C20.5768 13.5344 20.5768 13.0369 20.2699 12.7301C19.9631 12.4233 19.4656 12.4233 19.1588 12.7301Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
|
||||
<title>ic_fluent_link_remove_20_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-System-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_link_remove_20_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M14.5,10 C16.9853,10 19,12.0147 19,14.5 C19,16.9853 16.9853,19 14.5,19 C12.0147,19 10,16.9853 10,14.5 C10,12.0147 12.0147,10 14.5,10 Z M12.7322,12.7322 C12.537,12.9275 12.537,13.2441 12.7322,13.4393 L13.7929,14.5 L12.7322,15.5607 C12.537,15.7559 12.537,16.0725 12.7322,16.2678 C12.9275,16.463 13.2441,16.463 13.4393,16.2678 L14.5,15.2071 L15.5607,16.2678 C15.7559,16.463 16.0725,16.463 16.2678,16.2678 C16.463,16.0725 16.463,15.7559 16.2678,15.5607 L15.2071,14.5 L16.2678,13.4393 C16.463,13.2441 16.463,12.9275 16.2678,12.7322 C16.0725,12.537 15.7559,12.537 15.5607,12.7322 L14.5,13.7929 L13.4393,12.7322 C13.2441,12.537 12.9275,12.537 12.7322,12.7322 Z M8,4 C8.27614,4 8.5,4.22386 8.5,4.5 C8.5,4.74546 8.32312,4.94961 8.08988,4.99194 L8,5 L6,5 C4.34315,5 3,6.34315 3,8 C3,9.59058 4.23784,10.892 5.80275,10.9936 L6,11 L8,11 C8.27614,11 8.5,11.2239 8.5,11.5 C8.5,11.7455 8.32312,11.9496 8.08988,11.9919 L8,12 L6,12 C3.79086,12 2,10.2091 2,8 C2,5.8645 3.67346,4.11986 5.78053,4.00592 L6,4 L8,4 Z M14,4 C16.2091,4 18,5.79086 18,8 C18,8.68859 17.826,9.33654 17.5196,9.90229 C17.242,9.71965 16.947,9.56146 16.6375,9.43079 C16.8687,9.00552 17,8.5181 17,8 C17,6.40942 15.7622,5.10795 14.1973,5.00638 L14,5 L12,5 C11.7239,5 11.5,4.77614 11.5,4.5 C11.5,4.25454 11.6769,4.05039 11.9101,4.00806 L12,4 L14,4 Z M14,7.5 C14.2761,7.5 14.5,7.72386 14.5,8 C14.5,8.24546 14.3231,8.44961 14.0899,8.49194 L14,8.5 L6,8.5 C5.72386,8.5 5.5,8.27614 5.5,8 C5.5,7.75454 5.67688,7.55039 5.91012,7.50806 L6,7.5 L14,7.5 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>ic_fluent_lock_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_lock_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M12,2 C14.209139,2 16,3.790861 16,6 L16,8 L17.75,8 C18.9926407,8 20,9.00735931 20,10.25 L20,19.75 C20,20.9926407 18.9926407,22 17.75,22 L6.25,22 C5.00735931,22 4,20.9926407 4,19.75 L4,10.25 C4,9.00735931 5.00735931,8 6.25,8 L8,8 L8,6 C8,3.790861 9.790861,2 12,2 Z M17.75,9.5 L6.25,9.5 C5.83578644,9.5 5.5,9.83578644 5.5,10.25 L5.5,19.75 C5.5,20.1642136 5.83578644,20.5 6.25,20.5 L17.75,20.5 C18.1642136,20.5 18.5,20.1642136 18.5,19.75 L18.5,10.25 C18.5,9.83578644 18.1642136,9.5 17.75,9.5 Z M12.000125,13.5 C12.8285521,13.5 13.500125,14.1715729 13.500125,15 C13.500125,15.8284271 12.8285521,16.5 12.000125,16.5 C11.1716979,16.5 10.500125,15.8284271 10.500125,15 C10.500125,14.1715729 11.1716979,13.5 12.000125,13.5 Z M12,3.5 C10.6192881,3.5 9.5,4.61928813 9.5,6 L9.5,8 L14.5,8 L14.5,6 C14.5,4.61928813 13.3807119,3.5 12,3.5 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>ic_fluent_open_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_open_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M7.25008054,4.49999913 L10.7494682,4.49999913 C11.1636818,4.49999913 11.4994682,4.83578644 11.4994682,5.25 C11.4994682,5.62969577 11.2173143,5.94349023 10.8512388,5.99315253 L10.7494682,5.99999913 L7.24972349,5.99999913 C6.07077742,5.99943864 5.10347879,6.90639393 5.00784424,8.06094921 L5.00026803,8.21986131 L5.00310465,16.7504962 C5.00341779,17.9413602 5.92883567,18.9158978 7.09964605,18.9947542 L7.25369622,18.9999045 L15.751762,18.9882338 C16.9414684,18.9865998 17.9144722,18.0618298 17.9934904,16.8921377 L17.9986716,16.738236 L17.9986716,13.2319436 C17.9986716,12.81773 18.334458,12.4819436 18.7486716,12.4819436 C19.1283674,12.4819436 19.4421626,12.7640975 19.491825,13.130173 L19.4986716,13.2319436 L19.4986716,16.738236 C19.4986716,18.7405488 17.9292489,20.3767194 15.9527826,20.4827708 L15.7538222,20.4882324 L7.25825518,20.499901 L7.05493071,20.4947588 C5.14237343,20.3951844 3.60893529,18.8625525 3.50835508,16.9500479 L3.5031047,16.7508907 L3.50087004,8.2525319 L3.50527942,8.05003289 C3.60537339,6.13731798 5.13865446,4.60431851 7.05094826,4.50510482 L7.25008054,4.49999913 L10.7494682,4.49999913 L7.25008054,4.49999913 Z M13.748109,3.00129623 L20.3017795,3.0018036 L20.4013609,3.01557712 L20.4013609,3.01557712 L20.5021655,3.04376069 L20.5021655,3.04376069 L20.5589882,3.06786568 L20.5589882,3.06786568 C20.6122302,3.09104804 20.6633548,3.12146211 20.7110467,3.15867802 L20.7803898,3.22139044 L20.7803898,3.22139044 L20.8641342,3.31997258 L20.8641342,3.31997258 L20.9183108,3.41008637 L20.9183108,3.41008637 L20.9570021,3.50039784 L20.9570021,3.50039784 L20.9762122,3.56459327 L20.9762122,3.56459327 L20.9897783,3.62845344 L20.9897783,3.62845344 L20.9991402,3.72265407 L20.9991402,3.72265407 L20.9996358,10.2551867 C20.9996358,10.6694002 20.6638494,11.0051867 20.2496358,11.0051867 C19.86994,11.0051867 19.5561448,10.7230328 19.5064824,10.3569572 L19.4996358,10.2551867 L19.49887,5.56129623 L12.2796385,12.7845179 C12.0134324,13.0508449 11.5967743,13.0751456 11.3031133,12.8573578 L11.2189784,12.7847587 C10.9526514,12.5185526 10.9283507,12.1018944 11.1461385,11.8082335 L11.2187376,11.7240986 L18.43687,4.50129623 L13.748109,4.50129623 C13.3684132,4.50129623 13.054618,4.21914235 13.0049556,3.85306678 L12.998109,3.75129623 C12.998109,3.37160046 13.2802629,3.05780527 13.6463384,3.00814284 L13.748109,3.00129623 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
|
||||
<title>ic_fluent_table_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-System-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_table_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M17.75,3 C19.5449,3 21,4.45507 21,6.25 L21,17.75 C21,19.5449 19.5449,21 17.75,21 L6.25,21 C4.45507,21 3,19.5449 3,17.75 L3,6.25 C3,4.45507 4.45507,3 6.25,3 L17.75,3 Z M14,15.5 L10,15.5 L10,19.5 L14,19.5 L14,15.5 Z M19.5,15.5 L15.5,15.5 L15.5,19.5 L17.75,19.5 C18.7165,19.5 19.5,18.7165 19.5,17.75 L19.5,17.75 L19.5,15.5 Z M8.5,15.5 L4.5,15.5 L4.5,17.75 C4.5,18.7165 5.2835,19.5 6.25,19.5 L6.25,19.5 L8.5,19.5 L8.5,15.5 Z M8.5,10 L4.5,10 L4.5,14 L8.5,14 L8.5,10 Z M14,10 L10,10 L10,14 L14,14 L14,10 Z M19.5,10 L15.5,10 L15.5,14 L19.5,14 L19.5,10 Z M8.5,4.5 L6.25,4.5 C5.2835,4.5 4.5,5.2835 4.5,6.25 L4.5,8.5 L8.5,8.5 L8.5,4.5 Z M17.75,4.5 L15.5,4.5 L15.5,8.5 L19.5,8.5 L19.5,6.25 C19.5,5.2835 18.7165,4.5 17.75,4.5 L17.75,4.5 Z M14,4.5 L10,4.5 L10,8.5 L14,8.5 L14,4.5 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.25 3C4.45507 3 3 4.45507 3 6.25V17.75C3 19.5449 4.45507 21 6.25 21H17.75C19.5449 21 21 19.5449 21 17.75V6.25C21 4.45507 19.5449 3 17.75 3H6.25ZM4.5 6.25C4.5 5.2835 5.2835 4.5 6.25 4.5H11V7.5H4.5V6.25ZM12.5 16.5H19.5V17.75C19.5 18.7165 18.7165 19.5 17.75 19.5H12.5V16.5ZM19.5 7.5H12.5V4.5H17.75C18.7165 4.5 19.5 5.2835 19.5 6.25V7.5ZM11 16.5V19.5H6.25C5.2835 19.5 4.5 18.7165 4.5 17.75V16.5H11ZM4.5 9H19.5V15H4.5V9Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 548 B |
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.5 10H11V14H12.5V10Z" fill="#212121"/>
|
||||
<path d="M3 6.25C3 4.45507 4.45507 3 6.25 3H17.75C19.5449 3 21 4.45507 21 6.25V17.75C21 19.5449 19.5449 21 17.75 21H6.25C4.45507 21 3 19.5449 3 17.75V6.25ZM6.25 4.5C5.2835 4.5 4.5 5.2835 4.5 6.25V7.5H11V4.5H6.25ZM19.5 16.5H12.5V19.5H17.75C18.7165 19.5 19.5 18.7165 19.5 17.75V16.5ZM19.5 6.25C19.5 5.2835 18.7165 4.5 17.75 4.5H12.5V7.5H19.5V6.25ZM4.5 16.5V17.75C4.5 18.7165 5.2835 19.5 6.25 19.5H11V16.5H4.5ZM4.5 15H19.5V9H4.5V15Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 602 B |
|
@ -0,0 +1,7 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22 3.75C22 3.33579 21.6642 3 21.25 3L20.25 3C18.4551 3 17 4.45508 17 6.25V17.75C17 19.5449 18.4551 21 20.25 21H21.25C21.6642 21 22 20.6642 22 20.25C22 19.8358 21.6642 19.5 21.25 19.5H20.25C19.2835 19.5 18.5 18.7165 18.5 17.75V15.5H21.25C21.6642 15.5 22 15.1642 22 14.75C22 14.3358 21.6642 14 21.25 14H18.5V10H21.25C21.6642 10 22 9.66421 22 9.25C22 8.83579 21.6642 8.5 21.25 8.5H18.5V6.25C18.5 5.2835 19.2835 4.5 20.25 4.5H21.25C21.6642 4.5 22 4.16421 22 3.75Z" fill="#212121"/>
|
||||
<path d="M2 3.75C2 3.33579 2.33579 3 2.75 3L3.75 3C5.54493 3 7 4.45507 7 6.25L7 17.75C7 19.5449 5.54493 21 3.75 21H2.75C2.33579 21 2 20.6642 2 20.25C2 19.8358 2.33579 19.5 2.75 19.5H3.75C4.7165 19.5 5.5 18.7165 5.5 17.75L5.5 15.5H2.75C2.33579 15.5 2 15.1642 2 14.75C2 14.3358 2.33579 14 2.75 14H5.5L5.5 10H2.75C2.33579 10 2 9.66421 2 9.25C2 8.83579 2.33579 8.5 2.75 8.5H5.5L5.5 6.25C5.5 5.2835 4.7165 4.5 3.75 4.5H2.75C2.33579 4.5 2 4.16421 2 3.75Z" fill="#212121"/>
|
||||
<path d="M10.9393 12L9.46967 13.4697C9.17678 13.7626 9.17678 14.2374 9.46967 14.5303C9.76256 14.8232 10.2374 14.8232 10.5303 14.5303L12 13.0607L13.4697 14.5303C13.7626 14.8232 14.2374 14.8232 14.5303 14.5303C14.8232 14.2374 14.8232 13.7626 14.5303 13.4697L13.0607 12L14.5303 10.5303C14.8232 10.2374 14.8232 9.76256 14.5303 9.46967C14.2374 9.17678 13.7626 9.17678 13.4697 9.46967L12 10.9393L10.5303 9.46967C10.2374 9.17678 9.76256 9.17678 9.46967 9.46967C9.17678 9.76256 9.17678 10.2374 9.46967 10.5303L10.9393 12Z" fill="#212121"/>
|
||||
<path d="M11.25 8.72739C11.2758 8.75048 11.3011 8.77441 11.3258 8.79918L12 9.47335L12.6742 8.79917C12.6989 8.77441 12.7242 8.75048 12.75 8.72739V2.75C12.75 2.33579 12.4142 2 12 2C11.5858 2 11.25 2.33579 11.25 2.75L11.25 8.72739Z" fill="#212121"/>
|
||||
<path d="M11.25 15.5226V21.25C11.25 21.6642 11.5858 22 12 22C12.4142 22 12.75 21.6642 12.75 21.25V15.5226C12.7242 15.4995 12.6989 15.4756 12.6742 15.4508L12 14.7767L11.3258 15.4508C11.3011 15.4756 11.2758 15.4995 11.25 15.5226Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
|
||||
<title>ic_fluent_table_delete_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-System-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_table_delete_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M17.5,12 C20.5376,12 23,14.4624 23,17.5 C23,20.5376 20.5376,23 17.5,23 C14.4624,23 12,20.5376 12,17.5 C12,14.4624 14.4624,12 17.5,12 Z M17.75,3 C19.5449,3 21,4.45507 21,6.25 L21,12.0218 C20.5368,11.7253 20.0335,11.4858 19.5,11.3135 L19.5,10 L15.5,10 L15.5,11.3135 C14.9665,11.4858 14.4632,11.7253 14,12.0218 L14,10 L10,10 L10,14 L12.0218,14 C11.7253,14.4632 11.4858,14.9665 11.3135,15.5 L10,15.5 L10,19.5 L11.3135,19.5 C11.4858,20.0335 11.7253,20.5368 12.0218,21 L6.25,21 C4.45507,21 3,19.5449 3,17.75 L3,6.25 C3,4.45507 4.45507,3 6.25,3 L17.75,3 Z M15.1464,15.1464 C14.9512,15.3417 14.9512,15.6583 15.1464,15.8536 L16.7929,17.5 L15.1464,19.1464 C14.9512,19.3417 14.9512,19.6583 15.1464,19.8536 C15.3417,20.0488 15.6583,20.0488 15.8536,19.8536 L17.5,18.2071 L19.1464,19.8536 C19.3417,20.0488 19.6583,20.0488 19.8536,19.8536 C20.0488,19.6583 20.0488,19.3417 19.8536,19.1464 L18.2071,17.5 L19.8536,15.8536 C20.0488,15.6583 20.0488,15.3417 19.8536,15.1464 C19.6583,14.9512 19.3417,14.9512 19.1464,15.1464 L17.5,16.7929 L15.8536,15.1464 C15.6583,14.9512 15.3417,14.9512 15.1464,15.1464 Z M8.5,15.5 L4.5,15.5 L4.5,17.75 C4.5,18.668175 5.20710875,19.4211925 6.10647256,19.4941988 L6.25,19.5 L8.5,19.5 L8.5,15.5 Z M8.5,10 L4.5,10 L4.5,14 L8.5,14 L8.5,10 Z M8.5,4.5 L6.25,4.5 C5.2835,4.5 4.5,5.2835 4.5,6.25 L4.5,8.5 L8.5,8.5 L8.5,4.5 Z M17.75,4.5 L15.5,4.5 L15.5,8.5 L19.5,8.5 L19.5,6.25 C19.5,5.331825 18.7928913,4.5788075 17.8935274,4.50580119 L17.75,4.5 Z M14,4.5 L10,4.5 L10,8.5 L14,8.5 L14,4.5 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.75 15.5C3.33579 15.5 3 15.1642 3 14.75V6.25C3 4.45508 4.45507 3 6.25 3H17.75C19.5449 3 21 4.45508 21 6.25V14.75C21 15.1642 20.6642 15.5 20.25 15.5L3.75 15.5ZM10 14H14V10L10 10V14ZM10 8.5L14 8.5V4.5L10 4.5V8.5ZM15.5 14H19.5V10H15.5V14ZM15.5 8.5H19.5V6.25C19.5 5.2835 18.7165 4.5 17.75 4.5L15.5 4.5V8.5ZM8.5 4.5L6.25 4.5C5.2835 4.5 4.5 5.2835 4.5 6.25L4.5 8.5H8.5V4.5ZM4.5 14H8.5V10H4.5L4.5 14Z" fill="#212121"/>
|
||||
<path d="M3.75 19.5C3.33579 19.5 3 19.8358 3 20.25C3 20.6642 3.33579 21 3.75 21H20.25C20.6642 21 21 20.6642 21 20.25C21 19.8358 20.6642 19.5 20.25 19.5H3.75Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 702 B |
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.5 3.75C4.5 3.33579 4.16421 3 3.75 3C3.33579 3 3 3.33579 3 3.75V20.25C3 20.6642 3.33579 21 3.75 21C4.16421 21 4.5 20.6642 4.5 20.25L4.5 3.75Z" fill="#212121"/>
|
||||
<path d="M8.5 3.75C8.5 3.33579 8.83579 3 9.25 3H17.75C19.5449 3 21 4.45507 21 6.25V17.75C21 19.5449 19.5449 21 17.75 21H9.25C8.83579 21 8.5 20.6642 8.5 20.25V3.75ZM10 10V14H14V10H10ZM10 15.5V19.5H14V15.5H10ZM15.5 15.5V19.5H17.75C18.7165 19.5 19.5 18.7165 19.5 17.75V15.5H15.5ZM15.5 10V14H19.5V10H15.5ZM19.5 8.5V6.25C19.5 5.2835 18.7165 4.5 17.75 4.5H15.5V8.5H19.5ZM10 4.5V8.5H14V4.5H10Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 679 B |
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.5 3.75C15.5 3.33579 15.1642 3 14.75 3H6.25C4.45508 3 3 4.45507 3 6.25V17.75C3 19.5449 4.45508 21 6.25 21H14.75C15.1642 21 15.5 20.6642 15.5 20.25V3.75ZM14 10V14H10V10H14ZM4.5 14V10H8.5V14H4.5ZM14 8.5H10V4.5H14V8.5ZM8.5 8.5H4.5V6.25C4.5 5.2835 5.2835 4.5 6.25 4.5H8.5V8.5ZM8.5 19.5H6.25C5.2835 19.5 4.5 18.7165 4.5 17.75V15.5H8.5V19.5ZM10 15.5H14V19.5H10V15.5Z" fill="#212121"/>
|
||||
<path d="M19.5 3.75C19.5 3.33579 19.8358 3 20.25 3C20.6642 3 21 3.33579 21 3.75V20.25C21 20.6642 20.6642 21 20.25 21C19.8358 21 19.5 20.6642 19.5 20.25V3.75Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 670 B |
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20.25 4.5C20.6642 4.5 21 4.16421 21 3.75C21 3.33579 20.6642 3 20.25 3H3.75C3.33579 3 3 3.33579 3 3.75C3 4.16421 3.33579 4.5 3.75 4.5L20.25 4.5Z" fill="#212121"/>
|
||||
<path d="M20.25 8.5C20.6642 8.5 21 8.83579 21 9.25V17.75C21 19.5449 19.5449 21 17.75 21L6.25 21C4.45507 21 3 19.5449 3 17.75V9.25C3 8.83579 3.33579 8.5 3.75 8.5L20.25 8.5ZM14 10H10V14L14 14V10ZM8.5 10L4.5 10L4.5 14H8.5V10ZM8.5 15.5H4.5L4.5 17.75C4.5 18.7165 5.2835 19.5 6.25 19.5H8.5V15.5ZM14 15.5L10 15.5V19.5L14 19.5V15.5ZM15.5 19.5H17.75C18.7165 19.5 19.5 18.7165 19.5 17.75V15.5H15.5V19.5ZM19.5 10H15.5V14H19.5V10Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 712 B |
|
@ -0,0 +1,5 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.75 15.5C3.33579 15.5 3 15.1642 3 14.75V6.25C3 4.45508 4.45507 3 6.25 3H17.75C19.5449 3 21 4.45508 21 6.25V14.75C21 15.1642 20.6642 15.5 20.25 15.5H15.9821C16.0529 15.0075 15.9144 14.4883 15.558 14.0874C15.1525 13.6312 14.562 13.4372 14 13.5178V10L10 10V13.5178C9.43797 13.4372 8.8475 13.6312 8.44205 14.0874C8.08563 14.4883 7.9471 15.0075 8.01793 15.5H3.75ZM10 8.5L14 8.5V4.5L10 4.5V8.5ZM19.5 14V10H15.5V14H19.5ZM15.5 8.5H19.5V6.25C19.5 5.2835 18.7165 4.5 17.75 4.5L15.5 4.5V8.5ZM8.5 4.5L6.25 4.5C5.2835 4.5 4.5 5.2835 4.5 6.25L4.5 8.5H8.5V4.5ZM4.5 14H8.5V10H4.5L4.5 14Z" fill="#212121"/>
|
||||
<path d="M3.75 19.5C3.33579 19.5 3 19.8358 3 20.25C3 20.6642 3.33579 21 3.75 21H20.25C20.6642 21 21 20.6642 21 20.25C21 19.8358 20.6642 19.5 20.25 19.5H3.75Z" fill="#212121"/>
|
||||
<path d="M9.18945 14.7517C9.46464 14.4421 9.93869 14.4143 10.2483 14.6894L11.25 15.5799V12.75C11.25 12.3358 11.5858 12 12 12C12.4142 12 12.75 12.3358 12.75 12.75V15.5799L13.7517 14.6894C14.0613 14.4143 14.5354 14.4421 14.8106 14.7517C15.0858 15.0613 15.0579 15.5354 14.7483 15.8106L12.4983 17.8106C12.2141 18.0631 11.7859 18.0631 11.5017 17.8106L9.25174 15.8106C8.94215 15.5354 8.91426 15.0613 9.18945 14.7517Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,5 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20.25 4.5C20.6642 4.5 21 4.16421 21 3.75C21 3.33579 20.6642 3 20.25 3H3.75C3.33579 3 3 3.33578 3 3.75C3 4.16421 3.33579 4.5 3.75 4.5L20.25 4.5Z" fill="#212121"/>
|
||||
<path d="M20.25 8.5C20.6642 8.5 21 8.83579 21 9.25V17.75C21 19.5449 19.5449 21 17.75 21L6.25 21C4.45507 21 3 19.5449 3 17.75V9.25C3 8.83579 3.33579 8.5 3.75 8.5L8.01789 8.5C7.94707 8.99246 8.0856 9.51167 8.44202 9.91264C8.84748 10.3688 9.43795 10.5628 10 10.4822V14L14 14V10.4822C14.562 10.5628 15.1525 10.3688 15.5579 9.91264C15.9144 9.51167 16.0529 8.99246 15.9821 8.5L20.25 8.5ZM8.5 10L4.5 10L4.5 14H8.5V10ZM8.5 15.5H4.5L4.5 17.75C4.5 18.7165 5.2835 19.5 6.25 19.5H8.5V15.5ZM14 19.5V15.5L10 15.5V19.5L14 19.5ZM15.5 19.5H17.75C18.7165 19.5 19.5 18.7165 19.5 17.75V15.5H15.5V19.5ZM15.5 10V14H19.5V10H15.5Z" fill="#212121"/>
|
||||
<path d="M14.8105 9.24827C14.5354 9.55786 14.0613 9.58574 13.7517 9.31056L12.75 8.42014V11.25C12.75 11.6642 12.4142 12 12 12C11.5858 12 11.25 11.6642 11.25 11.25V8.42013L10.2483 9.31056C9.93868 9.58574 9.46462 9.55786 9.18944 9.24827C8.91425 8.93869 8.94213 8.46463 9.25172 8.18944L11.5017 6.18944C11.7859 5.93685 12.2141 5.93685 12.4983 6.18944L14.7483 8.18944C15.0579 8.46463 15.0857 8.93869 14.8105 9.24827Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,7 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.75 2C3.33579 2 3 2.33579 3 2.75L3 3.75C3 5.54493 4.45508 7 6.25 7L17.75 7C19.5449 7 21 5.54493 21 3.75V2.75C21 2.33579 20.6642 2 20.25 2C19.8358 2 19.5 2.33579 19.5 2.75V3.75C19.5 4.7165 18.7165 5.5 17.75 5.5H15.5V2.75C15.5 2.33579 15.1642 2 14.75 2C14.3358 2 14 2.33579 14 2.75V5.5L10 5.5V2.75C10 2.33579 9.66421 2 9.25 2C8.83579 2 8.5 2.33579 8.5 2.75V5.5H6.25C5.2835 5.5 4.5 4.7165 4.5 3.75V2.75C4.5 2.33579 4.16421 2 3.75 2Z" fill="#212121"/>
|
||||
<path d="M3.75 22C3.33579 22 3 21.6642 3 21.25V20.25C3 18.4551 4.45507 17 6.25 17L17.75 17C19.5449 17 21 18.4551 21 20.25V21.25C21 21.6642 20.6642 22 20.25 22C19.8358 22 19.5 21.6642 19.5 21.25V20.25C19.5 19.2835 18.7165 18.5 17.75 18.5H15.5V21.25C15.5 21.6642 15.1642 22 14.75 22C14.3358 22 14 21.6642 14 21.25V18.5H10V21.25C10 21.6642 9.66421 22 9.25 22C8.83579 22 8.5 21.6642 8.5 21.25V18.5H6.25C5.2835 18.5 4.5 19.2835 4.5 20.25V21.25C4.5 21.6642 4.16421 22 3.75 22Z" fill="#212121"/>
|
||||
<path d="M12 13.0607L13.4697 14.5303C13.7626 14.8232 14.2374 14.8232 14.5303 14.5303C14.8232 14.2374 14.8232 13.7626 14.5303 13.4697L13.0607 12L14.5303 10.5303C14.8232 10.2374 14.8232 9.76256 14.5303 9.46967C14.2374 9.17678 13.7626 9.17678 13.4697 9.46967L12 10.9393L10.5303 9.46967C10.2374 9.17678 9.76256 9.17678 9.46967 9.46967C9.17678 9.76256 9.17678 10.2374 9.46967 10.5303L10.9393 12L9.46967 13.4697C9.17678 13.7626 9.17678 14.2374 9.46967 14.5303C9.76256 14.8232 10.2374 14.8232 10.5303 14.5303L12 13.0607Z" fill="#212121"/>
|
||||
<path d="M8.72739 12.75C8.75048 12.7242 8.77441 12.6989 8.79918 12.6742L9.47335 12L8.79917 11.3258C8.77441 11.3011 8.75048 11.2758 8.72739 11.25H2.75C2.33579 11.25 2 11.5858 2 12C2 12.4142 2.33579 12.75 2.75 12.75L8.72739 12.75Z" fill="#212121"/>
|
||||
<path d="M15.5226 12.75H21.25C21.6642 12.75 22 12.4142 22 12C22 11.5858 21.6642 11.25 21.25 11.25H15.5226C15.4995 11.2758 15.4756 11.3011 15.4508 11.3258L14.7767 12L15.4508 12.6742C15.4756 12.6989 15.4995 12.7242 15.5226 12.75Z" fill="#212121"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
|
||||
<title>ic_fluent_table_settings_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-System-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_table_settings_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M17.5001,12 C17.6956333,12 17.8886778,12.0109333 18.0787296,12.032237 L18.3615,12.0719 L18.5342,12.7878 C18.7908348,13.8518348 19.849775,14.5028684 20.9017658,14.2736562 L21.0451,14.2369 L21.647,14.0591 C21.9488333,14.4480167 22.2005972,14.8803361 22.3922222,15.3455259 L22.4999,15.6285 L22.0526,16.0588 C21.275785,16.80626 21.2369442,18.024825 21.9360777,18.8193955 L22.0526,18.9412 L22.4999,19.3715 C22.3327333,19.8494167 22.1034139,20.2965694 21.8220111,20.7024259 L21.647,20.9409 L21.0451,20.7631 C19.995413,20.4529 18.9019922,21.0441843 18.5740926,22.0697082 L18.5342,22.2122 L18.3615,22.9281 C18.0811,22.9754 17.7934,23 17.5001,23 C17.3045667,23 17.1114778,22.9890667 16.9213963,22.967763 L16.6386,22.9281 L16.4659,22.2122 C16.2092652,21.1481652 15.150325,20.4971316 14.0983342,20.7263438 L13.955,20.7631 L13.3531,20.9409 C13.0512667,20.5519833 12.7995028,20.1196639 12.6078778,19.6544741 L12.5002,19.3715 L12.9475,18.9412 C13.724315,18.19374 13.7631557,16.975175 13.0640222,16.1806045 L12.9475,16.0588 L12.5002,15.6285 C12.6673667,15.1505833 12.8966861,14.7034306 13.1780889,14.2975741 L13.3531,14.0591 L13.955,14.2369 C15.004687,14.5471 16.0981078,13.9558157 16.4260074,12.9302918 L16.4659,12.7878 L16.6386,12.0719 C16.919,12.0246 17.2068,12 17.5001,12 Z M17.75,3 C19.5449,3 21,4.45507 21,6.25 L21,12.0218 C20.5368,11.7253 20.0335,11.4858 19.5,11.3135 L19.5,10 L15.5,10 L15.5,11.3135 C14.9665,11.4858 14.4632,11.7253 14,12.0218 L14,10 L10,10 L10,14 L12.0218,14 C11.7253,14.4632 11.4858,14.9665 11.3135,15.5 L10,15.5 L10,19.5 L11.3135,19.5 C11.4858,20.0335 11.7253,20.5368 12.0218,21 L6.25,21 C4.45507,21 3,19.5449 3,17.75 L3,6.25 C3,4.45507 4.45507,3 6.25,3 L17.75,3 Z M8.5,15.5 L4.5,15.5 L4.5,17.75 C4.5,18.668175 5.20710875,19.4211925 6.10647256,19.4941988 L6.25,19.5 L8.5,19.5 L8.5,15.5 Z M17.5001,16 C16.6994,16 16.0504,16.6716 16.0504,17.5 C16.0504,18.3284 16.6994,19 17.5001,19 C18.3007,19 18.9497,18.3284 18.9497,17.5 C18.9497,16.6716 18.3007,16 17.5001,16 Z M8.5,10 L4.5,10 L4.5,14 L8.5,14 L8.5,10 Z M8.5,4.5 L6.25,4.5 C5.2835,4.5 4.5,5.2835 4.5,6.25 L4.5,8.5 L8.5,8.5 L8.5,4.5 Z M17.75,4.5 L15.5,4.5 L15.5,8.5 L19.5,8.5 L19.5,6.25 C19.5,5.331825 18.7928913,4.5788075 17.8935274,4.50580119 L17.75,4.5 Z M14,4.5 L10,4.5 L10,8.5 L14,8.5 L14,4.5 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
|
||||
<title>ic_fluent_text_align_center_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-System-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_text_align_center_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M17.25,18 C17.6642,18 18,18.3358 18,18.75 C18,19.1642 17.6642,19.5 17.25,19.5 L6.75,19.5 C6.33579,19.5 6,19.1642 6,18.75 C6,18.3358 6.33579,18 6.75,18 L17.25,18 Z M21.25,11.5 C21.6642,11.5 22,11.8358 22,12.25 C22,12.6296833 21.7178347,12.9434889 21.3517677,12.9931531 L21.25,13 L2.75,13 C2.33579,13 2,12.6642 2,12.25 C2,11.8703167 2.28215688,11.5565111 2.64823019,11.5068469 L2.75,11.5 L21.25,11.5 Z M19.25,5 C19.6642,5 20,5.33579 20,5.75 C20,6.16421 19.6642,6.5 19.25,6.5 L4.75,6.5 C4.33579,6.5 4,6.16421 4,5.75 C4,5.33579 4.33579,5 4.75,5 L19.25,5 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
|
||||
<title>ic_fluent_text_align_justify_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-System-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_text_align_justify_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M21.25,18 C21.6642,18 22,18.3358 22,18.75 C22,19.1642 21.6642,19.5 21.25,19.5 L2.75,19.5 C2.33579,19.5 2,19.1642 2,18.75 C2,18.3358 2.33579,18 2.75,18 L21.25,18 Z M21.25,11.5 C21.6642,11.5 22,11.8358 22,12.25 C22,12.6296833 21.7178347,12.9434889 21.3517677,12.9931531 L21.25,13 L2.75,13 C2.33579,13 2,12.6642 2,12.25 C2,11.8703167 2.28215688,11.5565111 2.64823019,11.5068469 L2.75,11.5 L21.25,11.5 Z M21.25,5 C21.6642,5 22,5.33579 22,5.75 C22,6.16421 21.6642,6.5 21.25,6.5 L2.75,6.5 C2.33579,6.5 2,6.16421 2,5.75 C2,5.33579 2.33579,5 2.75,5 L21.25,5 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
|
||||
<title>ic_fluent_text_align_left_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-System-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_text_align_left_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M13.25,18 C13.6642,18 14,18.3358 14,18.75 C14,19.1642 13.6642,19.5 13.25,19.5 L2.75,19.5 C2.33579,19.5 2,19.1642 2,18.75 C2,18.3358 2.33579,18 2.75,18 L13.25,18 Z M21.25,11.5 C21.6642,11.5 22,11.8358 22,12.25 C22,12.6296833 21.7178347,12.9434889 21.3517677,12.9931531 L21.25,13 L2.75,13 C2.33579,13 2,12.6642 2,12.25 C2,11.8703167 2.28215688,11.5565111 2.64823019,11.5068469 L2.75,11.5 L21.25,11.5 Z M18.25,5 C18.6642,5 19,5.33579 19,5.75 C19,6.16421 18.6642,6.5 18.25,6.5 L2.75,6.5 C2.33579,6.5 2,6.16421 2,5.75 C2,5.33579 2.33579,5 2.75,5 L18.25,5 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
|
||||
<title>ic_fluent_text_align_right_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-System-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_text_align_right_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M21.25,18 C21.6642,18 22,18.3358 22,18.75 C22,19.1642 21.6642,19.5 21.25,19.5 L10.75,19.5 C10.3358,19.5 10,19.1642 10,18.75 C10,18.3358 10.3358,18 10.75,18 L21.25,18 Z M21.25,11.5 C21.6642,11.5 22,11.8358 22,12.25 C22,12.6296833 21.7178347,12.9434889 21.3517677,12.9931531 L21.25,13 L2.75,13 C2.33579,13 2,12.6642 2,12.25 C2,11.8703167 2.28215688,11.5565111 2.64823019,11.5068469 L2.75,11.5 L21.25,11.5 Z M21.25,5 C21.6642,5 22,5.33579 22,5.75 C22,6.16421 21.6642,6.5 21.25,6.5 L5.75,6.5 C5.33579,6.5 5,6.16421 5,5.75 C5,5.33579 5.33579,5 5.75,5 L21.25,5 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
|
||||
<title>ic_fluent_text_bold_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-System-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_text_bold_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M12.38,4.00006 C15.0166,4.00006 17,6.18217 17,8.62546 C17,9.6021 16.6833,10.5368 16.1346,11.307 C17.2115,12.1341 18,13.4275 18,15.1201 C18,18.2315 15.3015,20.0001 13.12,20.0001 L8,20.0001 C7.17157,20.0001 6.5,19.3285 6.5,18.5001 L6.49658977,5.50088 C6.49637,5.10291 6.65431,4.72117 6.93564,4.43969 C7.21697,4.15821 7.59862,4.00006 7.99658977,4.00006 L12.38,4.00006 Z M13.12,13.25 L9.5,13.25 L9.5,17.0001 L13.12,17.0001 C13.9931,17.0001 15,16.2465 15,15.1201 C15,13.9902 14.0253,13.25 13.12,13.25 L13.12,13.25 Z M12.38,7.00006 L9.49741,7.00006 L9.49918,10.25 L12.38,10.25 C13.2829,10.25 14,9.49057 14,8.62546 C14,7.76006 13.2819,7.00006 12.38,7.00006 Z" id="Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59.1 (86144) - https://sketch.com -->
|
||||
<title>ic_fluent_text_bullet_list_24_regular</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_text_bullet_list_24_regular" fill="#212121" fill-rule="nonzero">
|
||||
<path d="M3.24928905,16 C3.93925235,16 4.49857811,16.5593258 4.49857811,17.2492891 C4.49857811,17.9392523 3.93925235,18.4985781 3.24928905,18.4985781 C2.55932576,18.4985781 2,17.9392523 2,17.2492891 C2,16.5593258 2.55932576,16 3.24928905,16 Z M6.75,16.5 L21.25,16.5 C21.6642136,16.5 22,16.8357864 22,17.25 C22,17.6296958 21.7178461,17.943491 21.3517706,17.9931534 L21.25,18 L6.75,18 C6.33578644,18 6,17.6642136 6,17.25 C6,16.8703042 6.28215388,16.556509 6.64822944,16.5068466 L6.75,16.5 L21.25,16.5 L6.75,16.5 Z M3.24928905,11 C3.93925235,11 4.49857811,11.5593258 4.49857811,12.2492891 C4.49857811,12.9392523 3.93925235,13.4985781 3.24928905,13.4985781 C2.55932576,13.4985781 2,12.9392523 2,12.2492891 C2,11.5593258 2.55932576,11 3.24928905,11 Z M6.75,11.5 L21.25,11.5 C21.6642136,11.5 22,11.8357864 22,12.25 C22,12.6296958 21.7178461,12.943491 21.3517706,12.9931534 L21.25,13 L6.75,13 C6.33578644,13 6,12.6642136 6,12.25 C6,11.8703042 6.28215388,11.556509 6.64822944,11.5068466 L6.75,11.5 L21.25,11.5 L6.75,11.5 Z M3.24928905,6 C3.93925235,6 4.49857811,6.55932576 4.49857811,7.24928905 C4.49857811,7.93925235 3.93925235,8.49857811 3.24928905,8.49857811 C2.55932576,8.49857811 2,7.93925235 2,7.24928905 C2,6.55932576 2.55932576,6 3.24928905,6 Z M6.75,6.5 L21.25,6.5 C21.6642136,6.5 22,6.83578644 22,7.25 C22,7.62969577 21.7178461,7.94349096 21.3517706,7.99315338 L21.25,8 L6.75,8 C6.33578644,8 6,7.66421356 6,7.25 C6,6.87030423 6.28215388,6.55650904 6.64822944,6.50684662 L6.75,6.5 L21.25,6.5 L6.75,6.5 Z" id="🎨-Color"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |