* Remove all docs content from fluentui-react-native

* add headline links to documentation

* update yarn.lock

* update yarn.lock for merge

* re-add images to new assets dir for repo readmes to reference

* refresh yarn.lock

* refresh yarn.lock cleanly after mege

* update yarn.lock

Co-authored-by: Chris Hogan <chrishog@microsoft.com>
This commit is contained in:
Patrick Boyd 2020-04-22 17:04:27 -07:00 коммит произвёл GitHub
Родитель b94dc570ad
Коммит b1ec056884
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
139 изменённых файлов: 930 добавлений и 18647 удалений

Просмотреть файл

@ -8,8 +8,8 @@ If you have an existing React Native project, it's easy to begin using FluentUI
### Prerequisites
* [Standard React Native dependencies](http://facebook.github.io/react-native/docs/getting-started.html#node-python2-jdk)
* [Node.js](https://nodejs.org/en/download/)
- [Standard React Native dependencies](http://facebook.github.io/react-native/docs/getting-started.html#node-python2-jdk)
- [Node.js](https://nodejs.org/en/download/)
### Install FluentUI React Native into an existing project
@ -25,7 +25,25 @@ After successful installation, you can test the package by importing components
import { Checkbox } from '@fluentui/react-native';
```
Once you have the package installed, check out our [Hello World Fluent page](./docs/pages/HELLO_WORLD.md) to start writing code (Coming Soon).
Once you have the package installed, check out our [Hello World Fluent page](https://github.com/microsoft/fluent-site/blob/master/packages/fluent-website/docs/windows/get-started/Hello-World.mdx) to start writing code (Coming Soon).
## Documentation
### Components and Controls
Our component documentation is hosted in a separate repository, [Microsoft FluentUI Site](https://github.com/Microsoft/fluent-site) that will be published to its own website (Coming Soon).
### Theming framework
Our FluentUI framework documentation is found in this repository alongside the implementation.
- [Theming Overview](./packages/framework/theming-react-native/README.md)
- [StyleSheets](./packages/framework/themed-stylesheet/README.md)
- [Customizing Theme Settings](./packages/framework/themed-settings/README.md)
- [Theme Registry](./packages/framework/theme-registry/README.md)
- [Tokens](./packages/framework/foundation-tokens/README.md)
- [Settings and Slots](./packages/framework/foundation-settings/README.md)
- [Compose](./packages/framework/foundation-compose/README.md) and [Composable](./packages/framework/foundation-composable/README.md)
## Developing in the repo
@ -45,7 +63,9 @@ To start developing in the repository you can:
After a successful yarn build, you can explore FluentUI Tester, our demo application to play with each of the controls. To run FluentUI Tester, please follow instructions in the [FluentUI Tester readme](./apps/fluent-tester/README.md).
### Beachball
This repo manages semantic versioning and publishing using [Beachball](https://github.com/microsoft/beachball). When contributing, make sure to run the following before making a pull request:
1. `yarn change` will take you through a command line wizard to generate change files
2. Make sure to commit and push the newly generated change file

Просмотреть файл

@ -21,9 +21,10 @@
```
yarn run-win32
```
5. You will see FluentUI Tester show up in a new window.
![ReactTest image debug menu location](./../../docs/pages/images/fluent_tester_radiogroup.png)
![ReactTest image debug menu location](./../../assets/fluent_tester_radiogroup.png)
## Debug `FluentUI Tester` app with direct debugging
@ -46,11 +47,11 @@ Note: we recommend using [Visual Studio Code](https://code.visualstudio.com/down
5. Inside ReactTest, open the debug option menu and select the checkbox `Use Direct Debugger`
![ReactTest image debug menu location](./../../docs/pages/images/fluent_tester_debug_menu.png)
![ReactTest image debug menu location](./../../assets/fluent_tester_debug_menu.png)
6. In Visual Studio Code, open the debug pane and select `Debug Fabric Tester` option from the "Run And Debug" dropdown.
![ReactTest image debug menu location](./../../docs/pages/images/fluent_tester_vscode_debug.png)
![ReactTest image debug menu location](./../../assets/fluent_tester_vscode_debug.png)
7. At this time, VS Code will attach to the JS runtime and you can start debugging. For more information on debugging in VS Code, please see [Visual Studio Code documentation](https://code.visualstudio.com/docs/editor/debugging).

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 14 KiB

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 14 KiB

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 11 KiB

После

Ширина:  |  Высота:  |  Размер: 11 KiB

Просмотреть файл

@ -1,110 +0,0 @@
{
"name": "fluent-rn-website",
"entries": [
{
"date": "Fri, 17 Apr 2020 22:36:03 GMT",
"tag": "fluent-rn-website_v0.3.0",
"version": "0.3.0",
"comments": {
"minor": [
{
"comment": "yarn.lock",
"author": "warleu@microsoft.com",
"commit": "205e7b7e88151a17f2560ecdaec1c6e13c5825b7",
"package": "fluent-rn-website"
}
]
}
},
{
"date": "Fri, 17 Apr 2020 16:48:18 GMT",
"tag": "fluent-rn-website_v0.2.2",
"version": "0.2.2",
"comments": {
"patch": [
{
"comment": "Revert \"Merge pull request #136 from ksiler/fluent-variant-support\"",
"author": "krsiler@microsoft.com",
"commit": "302097d2dc2dc50680be2ff3747b9c244501d7d5",
"package": "fluent-rn-website"
}
]
}
},
{
"date": "Tue, 14 Apr 2020 05:14:46 GMT",
"tag": "fluent-rn-website_v0.2.0",
"version": "0.2.0",
"comments": {
"minor": [
{
"comment": "add accessibility documentation",
"author": "krsiler@microsoft.com",
"commit": "232a97794dc044cec9671e5cca4cf204d881f614",
"package": "fluent-rn-website"
}
]
}
},
{
"date": "Mon, 13 Apr 2020 22:48:23 GMT",
"tag": "fluent-rn-website_v0.1.0",
"version": "0.1.0",
"comments": {
"minor": [
{
"comment": "add docs for text",
"author": "krsiler@microsoft.com",
"commit": "232a97794dc044cec9671e5cca4cf204d881f614",
"package": "fluent-rn-website"
}
]
}
},
{
"date": "Thu, 09 Apr 2020 18:39:15 GMT",
"tag": "fluent-rn-website_v0.0.4",
"version": "0.0.4",
"comments": {
"patch": [
{
"comment": "merge conflicts",
"author": "ppatboyd@outlook.com",
"commit": "232a97794dc044cec9671e5cca4cf204d881f614",
"package": "fluent-rn-website"
}
]
}
},
{
"date": "Thu, 09 Apr 2020 17:35:20 GMT",
"tag": "fluent-rn-website_v0.0.3",
"version": "0.0.3",
"comments": {
"patch": [
{
"comment": "add some dependencies",
"author": "mgodbolt@microsoft.com",
"commit": "232a97794dc044cec9671e5cca4cf204d881f614",
"package": "fluent-rn-website"
}
]
}
},
{
"date": "Wed, 08 Apr 2020 21:26:12 GMT",
"tag": "fluent-rn-website_v0.0.2",
"version": "0.0.2",
"comments": {
"patch": [
{
"comment": "update package name",
"author": "mgodbolt@microsoft.com",
"commit": "232a97794dc044cec9671e5cca4cf204d881f614",
"package": "fluent-rn-website"
}
]
}
}
]
}

Просмотреть файл

@ -1,54 +0,0 @@
# Change Log - fluent-rn-website
This log was last generated on Fri, 17 Apr 2020 22:36:03 GMT and should not be manually modified.
<!-- Start content -->
## 0.3.0
Fri, 17 Apr 2020 22:36:03 GMT
### Minor changes
- yarn.lock (warleu@microsoft.com)
## 0.2.2
Fri, 17 Apr 2020 16:48:18 GMT
### Patches
- Revert "Merge pull request #136 from ksiler/fluent-variant-support" (krsiler@microsoft.com)
## 0.2.0
Tue, 14 Apr 2020 05:14:46 GMT
### Minor changes
- add accessibility documentation (krsiler@microsoft.com)
## 0.1.0
Mon, 13 Apr 2020 22:48:23 GMT
### Minor changes
- add docs for text (krsiler@microsoft.com)
## 0.0.4
Thu, 09 Apr 2020 18:39:15 GMT
### Patches
- merge conflicts (ppatboyd@outlook.com)
## 0.0.3
Thu, 09 Apr 2020 17:35:20 GMT
### Patches
- add some dependencies (mgodbolt@microsoft.com)
## 0.0.2
Wed, 08 Apr 2020 21:26:12 GMT
### Patches
- update package name (mgodbolt@microsoft.com)

Просмотреть файл

@ -1,106 +0,0 @@
# Fluent Website Content
__Key Concepts:__
1. [Folder path === URL](#adding-new-content)
2. [Left hand navigation defined per folder/folder tree](#creating-navigation)
3. [Built with MD, MDX or TSX](#supported-page-formats)
4. [Host your content anywhere](#hosting-your-content)
## Adding new content
Files in the `docs` folders are built to a page with the same URL as the relative directory. `index` files will be rendered as the folder's root page.
`docs/components/button.mdx` will be built to `example.com/components/button.html`. `docs/styles/index.tsx` will be built to `example.com/styles/index.html`
## Creating navigation
The vertical navigation of each page is written in a `toc.yml` file that includes `name`, `link` and any children `items`.
- `name` is the link text
- `link` is the full url to the page
- `items` is an array of name/link pairs and can be further nested
```yml
- name: Components
items:
- name: Button
link: components/button
- name: Toggle
link: components/toggle
```
### Unique navigation for sub controls
Often you'll want a subsection of the site to have its own navigation. The navigation of each page is based off of the closest `toc.yml` file to the page.
```md
docs/
styles.mdx
toc.yml
components/
button.mdx
toc.yml
foo/
bar.mdx
```
The `styles` page will have the navigation from `docs/toc.yml` and `button` page will use the navigation found in `docs/components/toc.yml`.
`docs/foo` does not contain a `toc.yml` so `docs/toc.yml` will be used for `bar.mdx`.
## Supported page formats
The Fluid UI Site supports multiple page formats.
### MDX
[MDX](https://mdxjs.com/) is a superset of markdown that adds the power of JSX to the file.
This means you can import JSX directly into your markdown content.
#### Importing JSX into MDX
```md
import {Button} from 'office-ui-fabric-react'
## This is a Fabric button
<Button primary={true}> Click Me </Button>
```
#### Importing MD into MDX
Another great feature of MDX is the ability to import other MD or MDX files into a single file.
This is a great way to split content out into multiple files and combine/reuse it.
```md
import Stuff from './somestuff.md'
Hello, this is my <Stuff />
```
### TSX Files
TSX files can be used when you need complete control over the page contents. No assumptions will be made about the page contents, styles or meta information (other than URL).
#### Leveraging site templates
Unless your page is meant to be a standalone app, we recommend using the built in `PageTemplate` to render the default page shell.
```tsx
import React from 'react';
import PageTemplate from 'gatsby-theme-fluent-site/src/templates/PageTemplate'
import
export default () => {
return <PageTemplate>Page Content</PageTemplate>
}
```
## Hosting your content
Gatsby can source pages from multiple locations. Content added to this repo under `docs/ios` could easily be moved to another repo under `fluentui-docs/ios` and produce the exact same page content. This workflow is not yet fully implemented, but it is a core tenent and fully supported by our tech choices.

Просмотреть файл

@ -1,2 +0,0 @@
- name: Windows
link: /windows

Просмотреть файл

@ -1,100 +0,0 @@
---
titleCategory: Design & developer
title: Callout
---
import { Usage, Example } from 'gatsby-theme-fluent-site/src/components/Usage';
import { NYI } from 'gatsby-theme-fluent-site/src/components/NYI';
import { Playground } from 'gatsby-theme-fluent-site/src/components/Playground';
<style>{`
.fakefocus {
outline: 2px solid black;
outline-offset: 2px;
}
`}</style>
## Overview
Callouts are a powerful way to simplify a user interface. They host tips and other information users need when they need it, with minimal effort on their part. Callouts can help you use screen space more effectively and reduce screen clutter. However, poorly designed Callouts can be annoying, distracting, unhelpful, overwhelming, or in the way.
Use a Callout for displaying additional contextual information about an item on the screen. Callouts also have a tail that identifies their source. A common use for Callout is the introduction of a new feature or capability of an app or site. Alternate usages include pairing the Callout with a button or clickable element for on-demand presentation of additional or supporting content.
By default, Callouts that do not contain focusable elements (links, buttons etc) cannot gain focus when opened. For proper screen reader support, follow the non-focusable callout example, which treats the callout content like a status message.
[Design spec]() |
[GitHub](https://github.com/microsoft/fluentui-react-native/tree/master/packages/components/Callout)
export const themes = ['Light', 'Dark'];
export const examples = [
{
title: 'Simple Callout',
description: "We don't have FluentUI working in the examples yet.",
source: 'export default () => <Callout><Text>React Native Callout control</Text></Callout>'
}
];
<Playground themes={themes} examples={examples} />
## Best practices
<NYI>Content needed: best practices</NYI>
### Usage
<NYI>Content needed: usage examples</NYI>
### Layout
<NYI>Content needed: positioning, anchoring</NYI>
### Accessibility
<NYI>Content needed: explain specifics of ARIA properties; mind 'announce' in particular</NYI>
### Globalization
<NYI>Content needed: any int'l concerns</NYI>
## How to customize
<NYI>Content needed: add a customization example</NYI>
You can customize the appearance of this and other controls by overriding its _design tokens_. Controls in your UI should be consistent in appearance, so most changes to a control's appearance should affect _all_ controls of the same type in your app. If you need a one-off style, however, you can override the design tokens for a single instance of a control.
- [Overview: How to use design tokens](/web/styles)
Each control uses many different design tokens. To explore the design tokens that affect this control, select "Design tokens" in the the playground at the top of this page. <NYI />
## Related components
<NYI>Content needed</NYI>
## In-depth examples
<NYI>Content needed</NYI>
### Additional examples
<NYI>Content needed</NYI>
<NYI>Explain the actual process of overriding design tokens (which doesn't exist yet)</NYI>
## Implementation status
This control is **unfinished**. The table below shows the current status of the implementation.
&#x2713; Design specifications and UI kits
&#x2713; Theming and spacing
&#x2713; Motion
&#x2713; Design tokens
&#x2713; Responsive
### Issues
#### Is this page helpful?
&#x1f44d;&nbsp;Yes &#x1f44e;&nbsp;No

Просмотреть файл

@ -1,59 +0,0 @@
# Component Name: Checkbox
## Purpose:
The goal of this Checkbox component is to allows users to switch between two mutually exclusive options (checked or unchecked,
on or off) through a single click or tap. It can also be used to indicate a subordinate setting or preference when paired with another control.
## Do's:
- Allow users to choose any combination of options when several Checkboxes are grouped together.
## Don't:
- Don't use a Checkbox as an on/off control. Instead use a toggle switch.
- Dont use a Checkbox when the user can choose only one option from the group, use radio buttons instead.
- Don't put two groups of Checkboxes next to each other. Separate the two groups with labels.
## Sample Code:
```
<Checkbox label="This is the label (uncontrolled)" onChange={onChange} defaultChecked={false} />
<Checkbox label="This is a controlled Checkbox" onChange={onChangeControlled1} checked={isCheckedControlled1} />
```
## Tokens:
Checkbox supports the following tokens:
1. checkboxBackgroundColor – This changes the background color of the Checkbox.
2. checkboxBorderColor – This changes the border color of the Checkbox.
3. checkmarkColor – This changes the color of Checkmark.
4. borderRadius - This changes the border radius of the Checkbox (use this to create a circular checkbox)
## Token Usage Example:
Circular Checkbox: We use "borderRadius=7" right now because we currently don't support % for borderRadius. The checkbox
size is currently 14x14, so 7 is 50%. We have a task to allow for %'s.
```
const CircularCheckbox = Checkbox.customize({ tokens: { borderRadius: 7 } });
```
Checkbox with white background (when unchecked):
```
const WhiteCheckbox = Checkbox.customize({ tokens: { backgroundColor: 'white' } });
```
Circular Color-Customized Checkbox - (Green background + green border + white checkmark) when Checked.
```
const CircleColorCheckbox = Checkbox.customize({
tokens: { borderRadius: 7 },
_overrides: {
checked: {
tokens: {
checkboxBackgroundColor: 'green',
checkboxBorderColor: 'green',
checkmarkColor: 'white'
}
},
focused: { tokens: { checkboxBackgroundColor: 'menuItemBackgroundHovered' } },
hovered: { tokens: { checkboxBackgroundColor: 'menuItemBackgroundHovered' } },
pressed: { tokens: { checkboxBackgroundColor: 'menuItemBackgroundPressed' } }
}
});
```

Просмотреть файл

@ -1,20 +0,0 @@
# Button Documentation
## Example
```
import * as React from 'react';
import { Button, View } from '@fluentui/react-native';
export const ButtonExample: React.FunctionComponent<{}> = props => {
return (
<View>
<Button content="Save" onClick={_alertClicked} />
</View>
);
};
function _alertClicked(): void {
alert('Clicked');
}
```

Просмотреть файл

@ -1,4 +0,0 @@
---
title: Components
---

Просмотреть файл

@ -1,24 +0,0 @@
# Link
## Example
```
import * as React from 'react';
import * as ReactNative from 'react-native';
import { Stack } from '../components';
import { Link } from '../components/Link/Link.win32';
import { stackStyle } from './TesterStyles';
export const LinkTest: React.FunctionComponent<{}> = () => {
const doPress = () => {
ReactNative.Alert.alert('Alert.', 'You have been alerted.');
};
return (
<Stack style={stackStyle}>
<Link url="https://www.bing.com/" content="Click to open the URL." />
<Link onPress={doPress} content="Click to activate the onPress event." />
<Link url="https://www.google.com/" content="This link is disabled." disabled />
</Stack>
);
};
```

Просмотреть файл

@ -1,39 +0,0 @@
# Component Name: RadioGroup
## Purpose
The goal of this RadioGroup component is to let users select one option from two or more choices. Each option is represented by one RadioButton component, and the group of RadioButtons is represented by a RadioGroup component. A user can only select one RadioButton in a RadioGroup.
## Do's:
- Use when there are 2-7 options, if you have enough screen space and the options are important enough to be a good use of that screen space. Otherwise, use a Checkbox or Dropdown list.
- Use on wizard pages to make the alternatives clear, even if a Checkbox is otherwise acceptable.
- List the options in a logical order, such as most likely to be selected least, simplest operation to most complex, or least risk to most. Alphabetical ordering is not recommended because it is language dependent and therefore not localizable.
- If none of the options is a valid choice, add another option to reflect this choice, such as “None” or “Does not apply”.
- Select the safest (to prevent loss of data or system access) and most secure and private option as the default. If safety and security arent factors, select the most likely or convenient option.
- Align radio buttons vertically instead of horizontally, if possible. Horizontal alignment is harder to read and localize.
## Don't:
- Use when the options are numbers that have fixed steps, like 10, 20, 30. Use a slider component instead.
- Use if there are more than 7 options, use a Dropdown instead.
- Nest with other RadioGroup or Checkboxes. If possible, keep all the options at the same level.
## Sample Code:
```jsx
<RadioGroup label="This is a test RadioGroup" defaultSelectedKey="A">
<RadioButton content="Option A" buttonKey="A" />
<RadioButton content="Option B" buttonKey="B" />
<RadioButton content="Option C" buttonKey="C" disabled={true} />
<RadioButton content="Option D" buttonKey="D" />
</RadioGroup>
```
## Tokens:
RadioButton supports the following tokens:
1. borderColor – This changes the border color of the RadioButton.
2. backgroundColor – This changes the background color of the inner circle of the RadioButton.
3. color – This changes the text color of the label associated with the RadioButton.
RadioGroup supports the following tokens:
1. fontFamily - Changes the font family of the label associated with the RadioGroup.
2. fontSize - Changes the font size of the label associated with the RadioGroup.
3. fontWeight - Changes the font weight of the label associated with the RadioGroup.
4. color - This changes the text color of the label associated with the RadioGroup.

Просмотреть файл

@ -1,46 +0,0 @@
# Separator
## Horizontal Example
```
import { ISeparator, Separator, Stack, Text } from '@fluentui/react-native';
const stackStyle: IStackProps['style'] = {
borderWidth: 1,
borderColor: '#bdbdbd',
padding: 8,
margin: 8
};
export const SeparatorExample: React.FunctionComponent<{}> = props => {
return (
<Stack style={ stackStyle } gap={ 5 }>
<Text>This is a text element</Text>
<Separator />
<Text>This is a longer text element</Text>
</Stack>
);
};
```
## Vertical Example
```
import { ISeparator, Separator, Stack } from '@fluentui/react-native';
const separatorStackStyle: IStackProps['style'] = {
height: 200,
flexDirection: 'row',
justifyContent: 'space-evenly'
};
export const SeparatorExample: React.FunctionComponent<{}> = props => {
return (
<Stack gap={ 4 } style={ separatorStackStyle }>
<Text>Text 1</Text>
<Separator color="blue" vertical />
<Text>Text 2</Text>
<Separator color="red" vertical />
<Text>Text 3</Text>
</Stack>
);
};
```

Просмотреть файл

@ -1,3 +0,0 @@
# Text
### Not Yet Implemented

Просмотреть файл

@ -1,22 +0,0 @@
- name: Components
items:
- name: Button
link: windows/components/button
- name: Checkbox
link: windows/components/checkbox
- name: Link
link: windows/components/link
- name: RadioGroup
link: windows/components/radiogroup
- name: Separator
link: windows/components/separator
- name: Text
link: windows/components/text
- name: Utilities
items:
- name: FocusTrapZone
link: windows/components/utilities/focustrapzone
- name: Pressable
link: windows/components/utilities/pressable
- name: Stack
link: windows/components/utilities/stack

Просмотреть файл

@ -1,24 +0,0 @@
# FocusTrapZone Documentation
## Example
```
import { IFocusTrapZoneProps, FocusTrapZone, Button } from '@fluentui/react-native';
const activeTrapZoneStyle: IFocusTrapZoneProps['style'] = {
borderWidth: 2,
borderColor: '#ababab',
borderStyle: 'solid',
padding: 10
}
export const FocusTrapZoneExample: React.FunctionComponent<{}> = props => {
return (
<FocusTrapZone style={activeTrapZoneStyle}>
<Button content="Button 1" />
<Button content="Button 2" />
<Button content="Button 3" />
</FocusTrapZone>
);
};
```

Просмотреть файл

@ -1,3 +0,0 @@
# Pressable
### Not Yet Implemented

Просмотреть файл

@ -1,3 +0,0 @@
# Stack
### Not Yet Implemented

Просмотреть файл

@ -1,15 +0,0 @@
import React, { useState } from 'react';
export const Counter = function() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
};
export default Counter;

Просмотреть файл

@ -1,3 +0,0 @@
---
title: Experiences
---

Просмотреть файл

@ -1,2 +0,0 @@
- name: Example
link: windows

Просмотреть файл

@ -1,5 +0,0 @@
---
title: Get started
---
#

Просмотреть файл

@ -1,2 +0,0 @@
- name: Example
link: windows

Просмотреть файл

@ -1,50 +0,0 @@
import Counter from './counter.jsx';
# JDX in MDX
You can import React components in an `.mdx` file. Like this:
> ```jsx
> import Counter from './counter.jsx';
> <Counter />;
> ```
<Counter />
# FluentUI Docs
## Components
- [Button](/windows/components/button)
- [Link](/windows/components/link)
- [Separator](/windows/components/separator)
- [Text](/windows/components/text)
## Utilities
- [FocusTrapZone](/windows/components/utilities/focustrapzone)
- [Pressable](/windows/components/utilities/pressable)
- [Stack](/windows/components/utilities/stack)
## Contributing Docs
- Follow and maintain the template below
- Run the local dev server with:
> ```
> cd fluentui-react-native
> yarn
> cd Docs
> yarn dev
> ```
## Template
> ```
> # Component Name
>
> ## Purpose
>
> ## Do's and Don'ts
>
> ## Sample Code
> ```

Просмотреть файл

@ -1,5 +0,0 @@
---
title: Styles
---
styles

Просмотреть файл

@ -1,2 +0,0 @@
- name: Example
link: windows

Просмотреть файл

@ -1,16 +0,0 @@
module.exports = {
siteMetadata: {
siteURL: 'https://fluentui.z5.web.core.windows.net/',
},
plugins: [
`gatsby-plugin-typescript`,
`gatsby-plugin-sharp`,
'gatsby-transformer-sharp',
{
resolve: `gatsby-theme-fluent-site`,
options: {
contentPath: `./content`,
},
},
],
};

Просмотреть файл

@ -1,72 +0,0 @@
{
"name": "fluent-rn-website",
"version": "0.3.5",
"description": "Fluent website content",
"repository": {
"type": "git",
"url": "https://github.com/microsoft/fluent-site"
},
"license": "MIT",
"scripts": {
"clean": "gatsby clean",
"build": "gatsby build --prefix-paths",
"develop": "gatsby clean && gatsby develop --port 3000",
"serve": "gatsby serve",
"start": "npm run develop"
},
"devDependencies": {
"gatsby-theme-fluent-site": "^0.2.0",
"gatsby-plugin-sharp": "^2.3.13",
"gatsby-transformer-sharp": "^2.3.12"
},
"dependencies": {
"@babel/core": "^7.8.3",
"@mdx-js/mdx": "^1.1.0",
"@mdx-js/react": "^1.0.27",
"@storybook/addon-actions": "^5.3.4",
"@storybook/addon-links": "^5.3.4",
"@storybook/addons": "^5.3.4",
"@storybook/react": "^5.3.4",
"@types/graphql": "^14.2.0",
"@types/node": "^11.13.13",
"@types/react": "^16.8.19",
"@types/react-dom": "^16.8.4",
"@types/react-helmet": "^5.0.8",
"babel-loader": "^8.0.6",
"gatsby-image": "^2.2.38",
"gatsby-link": "^2.2.2",
"gatsby-plugin-docs-creator": "^2.2.0",
"gatsby-plugin-manifest": "^2.2.20",
"gatsby-plugin-mdx": "^1.0.67",
"gatsby-plugin-netlify-cms": "^4.2.2",
"gatsby-plugin-offline": "^3.0.32",
"gatsby-plugin-react-helmet": "^3.1.21",
"gatsby-plugin-sharp": "^2.3.13",
"gatsby-remark-copy-linked-files": "^2.1.36",
"gatsby-remark-images": "^3.1.42",
"gatsby-remark-prismjs": "^3.3.30",
"gatsby-source-filesystem": "^2.1.46",
"gatsby-source-git": "^1.0.2",
"gatsby-transformer-remark": "^2.6.48",
"gatsby-transformer-sharp": "^2.3.12",
"gatsby-transformer-yaml": "^2.2.24",
"monaco-editor-webpack-plugin": "^1.9.0",
"netlify-cms-app": "^2.12.2",
"office-ui-fabric-react": "^7.92.0",
"prism-react-renderer": "^1.0.1",
"react-helmet": "^5.2.1",
"react-live": "^2.1.2",
"react-monaco-editor": "^0.34.0",
"remark-parse": "^7.0.0",
"remark-react": "^6.0.0",
"unified": "^8.3.2",
"gatsby-plugin-typescript": "^2.1.26",
"typescript": "^3.5.1",
"gatsby": "^2.19.27",
"gatsby-plugin-emotion": "^4.1.23",
"react": "^16.13.0",
"react-dom": "^16.13.0",
"@fluentui/react-native": "^0.15.5",
"@mdx-js/loader": "^1.5.5"
}
}

Просмотреть файл

@ -1,26 +0,0 @@
# Hello World Fluent
Now that you have the FluentUI React Native package installed, we will add components from the library to a new React Native project.
```
// In App.js in a new project
import React from 'react';
import { View, Text } from 'react-native';
import { Checkbox } from '@fluentui/react-native';
function HelloWorldApp() {
return (
<View
style={{ }}
flex: 1,
justifyContent: "center",
alignItems: "center"
}}>
<Text>Hello, world!</Text>
<Checkbox label="Hello World Checkbox"/>
</View>
)
}
export default HelloWorldApp;
```

Просмотреть файл

@ -1,204 +0,0 @@
# Accessibility
Accessibility means designing and creating UI that's accessible to all users, including those with disabilities.
It's important to create accessible UI so that assitive technology, like screen readers, can access information users
need to interact with your controls. Here you can find a guide to get started as well as tools to help you test your UI
for accessibility.
## Our Approach
FluentUI React Native enables developers to create accessible UI by providing APIs that are complimentary to Microsoft
UI Automation (UIA), an accessibility framework for Windows. Our API surface is heavily inspired by Accessible Internet Rich
Applications (ARIA), an accessibility framework for the web. We chose to align with ARIA to provide a "web first"
development experience. ARIA also provides a lot of guidelines and best practices for creating accessible content.
## Making UI accessible
FluentUI React Native components are accessible by default meaning you only need to provide minimal customizations to make
your UI accessible. Here you will find information on the folowing components: Properties, Roles, States, and Actions.
### Properties
#### accessible
When `true`, indicates that the view is an accessible element meaning it receives accessibility focus. By default, all
controls are accessible.
```tsx
<Text accessible={true}>first</Text>
<Text accessible={false}>second</Text>
```
In the above example, 'first' recieves accessiblity focus but 'second' does not.
#### accessibilityLabel
When something is accessible, it's good practice to set an `accessiblityLabel` so the user knows what element has focus. Narrator will read out this string when the user places focus on the control.
To use, set the `accessibilityLabel` property to a custom string:
```tsx
<Button content="Click me" accessibilityLabel="Press me" />
```
In the above example, Narrator will read "Press me" instead of "Click me".
#### accessibilityHint
An accessibility hint helps users understand what will happen when they preform an action on the accessibility element when
the result isn't clear from the accessibility label.
To use, set the `accessibilityHint` property to a custom string:
```tsx
<Button content="Back" accessibilityLabel="Go Back" accessibilityHint="Navigates to the previous screen" />
```
In the above example, Narrator will read the hint after the label.
#### acceptsKeyboardFocus
When `true`, this enables the component to accept keyboard focus.
#### accessibilityLevel, accessibiiltyPositionInSet, accessibilitySetSize
These properties are used together to define a set of items.
- ```accessibilityLevel``` defines the level of the set
- ```accessibilityPositionInSet``` defines the position of the item in a set
- ```accessibilitySetSize``` defines the number of items in a set
```tsx
<View>
<Button content="One" accessibilityLevel={1} accessibiltyPositionInSet={1} accessibilitySetSize={2}/>
<Button content="Two" accessibilityLevel={1} accessibiltyPositionInSet={2} accessibilitySetSize={2}/>
<View>
<Button content="Three" accessibilityLevel={2} accessibiltyPositionInSet={1} accessibilitySetSize={3} />
<Button content="Four" accessibilityLevel={2} accessibiltyPositionInSet={2} accessibilitySetSize={3} />
<Button content="Five" accessibilityLevel={2} accessibiltyPositionInSet={3} accessibilitySetSize={3} />
</View>
</View>
```
In the above example, Narrator will read the first button as "One, 1 of 2, level 1" and the second button as "Two, 2 of
2, level 1" and so on.
### Roles
`accessibilityRole` communicates the purpose of a component to the user.
`accessibilityRole` can be one of the following:
- **adjustable** Used when an element can be "adjusted" (e.g. a slider).
- **alert** Used when an element contains important text to be presented to the user. (note: maps to UIA Group control type)
- **alertdialog** Used to represent a dialog that contains an alert message. (note: maps to UIA Pane control type)
- **application** Used to represent a structure containing one or more focusable elements requiring user input such as keyboard or gesture events. (note: maps to UIA Pane control type)
- **button** Used when the element should be treated as a button.
- **checkbox** Used when an element represents a checkbox which can be checked, unchecked, or have mixed checked state.
- **combobox** Used when an element represents a combo box, which allows the user to select among several choices.
- **dialog** Used to represent a descendant window of a primary window of an application. (note: maps to UIA Pane control type)
- **group** Used to represent a set of user interface objects.
- **header** Used when an element acts as a header for a content section (e.g. the title of a navigation bar) (note: maps to UIA Text control type)
- **image** Used when the element should be treated as an image.
- **imagebutton** Used when the element should be treated as a button and is also an image. (note: maps to UIA Button control type)
- **keyboardkey** Used when the element acts as a keyboard key. (note: maps to UIA Button control type)
- **link** Used when the element should be treated as a link.
- **menu** Used when the component is a menu of choices.
- **menubar** Used when a component is a container of multiple menus.
- **menuitem** Used to represent an item within a menu.
- **none** Used when the element has no role. (note: maps to UIA Group control type and is removed from the control tree)
- **progressbar** Used to represent a component which indicates progress of a task.
- **presentation** Used to represent an element whose implicit native role semantics will not be mapped to the accessibility API. Synonymn is none. (note: maps to UIA Group control type and is removed from the control tree)
- **radio** Used to represent a radio button.
- **radiogroup** Used to represent a group of radio buttons. (note: maps to UIA List control type)
- **scrollbar** Used to represent a scroll bar.
- **search** Used when the text field element should also be treated as a search field (note: maps to UIA Group control type)
- **spinbutton** Used to represent a button which opens a list of choices. (note: maps to UIA Spinner control type)
- **summary** Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches. (note: maps to UIA Text control type)
- **switch** Used to represent a switch which can be turned on and off. (note: maps to UIA Button control type)
- **tab** Used to represent a tab. (note: maps to UIA Tabitem control type)
- **tablist** Used to represent a list of tabs. (note: maps to UIA Tab control type)
- **tabpanel** Used to represent a container for the resources associated with a tab, where each tab is contained in a tablist. (note: maps to UIA Pane contorl type)
- **text** Used when the element should be treated as static text that cannot change.
- **textbox** Used whent the element should be treated as a type of input that allows free-form text as its value. (note: maps to UIA Edit control type)
- **timer** Used to represent a timer. (note: maps to UIA Group control type)
- **toolbar** Used to represent a tool bar (a container of action buttons or components).
- **tree** Used to represent a list that contains sub-level nested groups that can be collapsed and expanded.
- **treeitem** Used to represent an option item in a tree that may be expanded or collapsed if it contains a sub-level group of tree item elements.
### States
`accessibilityStates` is an array of values, and may include any of the following:
- **disabled** Used when the element is disabled and cannot be interacted with.
- **checked** Used to indicate that a checkable element is currently checked.
- **unchecked** Used to indicate that a checkable element is not currently checked.
- **mixed** Used to indicate that a checkable element is in a mixed state.
- **expanded** Used to indicate that an expandable element is currently expanded.
- **selected** Used when the element is in a selected state.
- **required** Used to indicate that selection is required for a group of elements.
- **multiselectable** Used to indicate that multiple items can be selected from a group.
To use, set the `accessibilityStates` to an array containing the list of current states.
### Actions
Accessibility actions allow an assistive technology to programmatically invoke the actions of a component. In order to support accessibility actions, a component must do two things:
- Define the list of actions it supports via the `accessibilityActions` property.
- Implement an `onAccessibilityAction` function to handle action requests.
The `accessibilityActions` property should contain a list of action objects. Each action object should contain the following fields:
| Name | Type | Required |
| ----- | ------ | -------- |
| name | string | Yes |
| label | string | No |
Actions either represent standard actions, such as clicking a button or adjusting a slider, or custom actions specific to a given component such as deleting an email message. The `name` field is required for both standard and custom actions, but `label` is optional for standard actions.
When adding support for standard actions, `name` must be one of the following:
- `'Expand'` - Displays all child nodes, controls, or content of the control.
- `'Collapse'` - Hides all child nodes, controls, or content of this element.
- `'Select'` - Deselects any selected items and then selects the current element.
- `'AddToSelection'` - Adds the current element to the collection of selected items.
- `'RemoveFromSelection'` - Removes the current element from the collection of selected items.
- `'Toggle'` - Cycles through the toggle states of a control.
Note: These are the only standard actions we have support for at this time. When new actions are added, they will be updated here.
The `label` field is optional for standard actions, and is often unused by assistive technologies. For custom actions, it is a localized string containing a description of the action to be presented to the user.
To handle action requests, a component must implement an `onAccessibilityAction` function. The only argument to this function is an event containing the name of the action to perform. The below example shows how to use standard actions.
```tsx
<View
accessible={true}
accessibilityActions={[
{name: 'Expand'},
{name: 'Collapse'},
]}
onAccessibilityAction={(event) => {
switch (event.nativeEvent.actionName) {
case 'Expand':
Alert.alert('Alert', 'Expand action success');
break;
case 'Collapse':
Alert.alert('Alert', 'Collapse action success');
break;
}}
/>
```
## Testing
To test your application with Narrator, visit the complete guide to Narrator: https://support.microsoft.com/en-us/help/22798/windows-10-complete-guide-to-narrator
To test your application wiht Accessibility Insights, visit Accessibility Insights for Windows: https://accessibilityinsights.io/docs/en/windows/overview
## Checklist
- Is the control marked as accessible?
- Does the control acceptKeyboardFocus?
- Does the control have the correct accessibilityRole set?
- Does the control have the correct acccessibilityStates set?
- Does the control have the correct accessibilityActions set?
- Does the control include appropriate customizations (accessibilityLabel, accessibilityHint, etc.)?
- Try testing it with Narrator. Does narrator annouce the control correctly? When interacting with it, does it have the correct behavior?
- Try testing it with AccessibilityInsights. Does the control expose the correct UIA patterns? Does the control reflect the right properties, role, states and actions?

Просмотреть файл

@ -1,18 +0,0 @@
{
"include": ["./src/**/*"],
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"lib": ["dom", "es2017"],
// "allowJs": true,
// "checkJs": true,
"jsx": "react",
"strict": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"noEmit": true,
"skipLibCheck": true,
"noImplicitAny": false
}
}

Просмотреть файл

@ -1,30 +0,0 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
decls
dist

Просмотреть файл

@ -1,34 +0,0 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
*.un~
yarn.lock
src
flow-typed
coverage
decls
examples

Просмотреть файл

@ -1,50 +0,0 @@
{
"name": "gatsby-plugin-docs-creator",
"entries": [
{
"date": "Fri, 17 Apr 2020 22:36:03 GMT",
"tag": "gatsby-plugin-docs-creator_v2.2.0",
"version": "2.2.0",
"comments": {
"minor": [
{
"comment": "yarn.lock",
"author": "warleu@microsoft.com",
"commit": "205e7b7e88151a17f2560ecdaec1c6e13c5825b7",
"package": "gatsby-plugin-docs-creator"
}
]
}
},
{
"date": "Thu, 09 Apr 2020 18:39:15 GMT",
"tag": "gatsby-plugin-docs-creator_v2.1.42",
"version": "2.1.42",
"comments": {
"patch": [
{
"comment": "merge conflicts",
"author": "ppatboyd@outlook.com",
"commit": "232a97794dc044cec9671e5cca4cf204d881f614",
"package": "gatsby-plugin-docs-creator"
}
]
}
},
{
"date": "Wed, 08 Apr 2020 21:26:12 GMT",
"tag": "gatsby-plugin-docs-creator_v2.1.41",
"version": "2.1.41",
"comments": {
"patch": [
{
"comment": "update package name",
"author": "mgodbolt@microsoft.com",
"commit": "232a97794dc044cec9671e5cca4cf204d881f614",
"package": "gatsby-plugin-docs-creator"
}
]
}
}
]
}

Просмотреть файл

@ -1,26 +0,0 @@
# Change Log - gatsby-plugin-docs-creator
This log was last generated on Fri, 17 Apr 2020 22:36:03 GMT and should not be manually modified.
<!-- Start content -->
## 2.2.0
Fri, 17 Apr 2020 22:36:03 GMT
### Minor changes
- yarn.lock (warleu@microsoft.com)
## 2.1.42
Thu, 09 Apr 2020 18:39:15 GMT
### Patches
- merge conflicts (ppatboyd@outlook.com)
## 2.1.41
Wed, 08 Apr 2020 21:26:12 GMT
### Patches
- update package name (mgodbolt@microsoft.com)

Просмотреть файл

@ -1,104 +0,0 @@
# gatsby-plugin-docs-creator
Gatsby plugin that automatically creates pages from React components in specified directories. Gatsby
includes this plugin automatically in all sites for creating pages from components in `src/pages`.
You may include another instance of this plugin if you'd like to create additional "pages" directories.
With this plugin, _any_ file that lives in the specified pages folder (e.g. the default `src/pages`) or subfolders will be expected to export a React Component to generate a Page. The following files are automatically excluded:
- `template-*`
- `__tests__/*`
- `*.test.jsx?`
- `*.spec.jsx?`
- `*.d.tsx?`
- `*.json`
- `*.yaml`
- `_*`
- `.*`
To exclude custom patterns, see [Ignoring Specific Files](#ignoring-specific-files)
## Install
`npm install --save gatsby-plugin-docs-creator`
## How to use
```javascript
// gatsby-config.js
module.exports = {
plugins: [
// You can have multiple instances of this plugin
// to create pages from React components in different directories.
//
// The following sets up the pattern of having multiple
// "pages" directories in your project
{
resolve: `gatsby-plugin-docs-creator`,
options: {
path: `${__dirname}/src/account/pages`,
},
},
{
resolve: `gatsby-plugin-docs-creator`,
options: {
path: `${__dirname}/src/settings/pages`,
},
},
],
}
```
### Ignoring Specific Files
#### Shorthand
```javascript
// The following example will disable the `/blog` index page
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-docs-creator`,
options: {
path: `${__dirname}/src/indexes/pages`,
ignore: [`blog.(js|ts)?(x)`],
// See pattern syntax recognized by micromatch
// https://www.npmjs.com/package/micromatch#matching-features
},
},
],
}
```
**NOTE**: The above code snippet will only stop the creation of the `/blog` page, which is defined as a React component.
This plugin does not affect programmatically generated pages from the [createPagesAPI](https://www.gatsbyjs.org/docs/node-apis/#createPages).
#### Ignore Options
```javascript
// The following example will ignore pages using case-insensitive matching
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-docs-creator`,
options: {
path: `${__dirname}/src/examples/pages`,
ignore: {
// Example: Ignore `file.example.js`, `dir/s/file.example.tsx`
patterns: [`**/*.example.(js|ts)?(x)`],
// Example: Match both `file.example.js` and `file.EXAMPLE.js`
options: { nocase: true },
// See all available micromatch options
// https://www.npmjs.com/package/micromatch#optionsnocase
},
},
},
],
}
```

Просмотреть файл

@ -1,9 +0,0 @@
export declare const createPagesStatefully: ({ store, actions, reporter }: {
store: any;
actions: any;
reporter: any;
}, { path: pagesPath, pathCheck, ignore }: {
path: any;
pathCheck?: boolean | undefined;
ignore: any;
}, doneCb: any) => Promise<void>;

Просмотреть файл

@ -1,149 +0,0 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var tslib_1 = require('tslib');
var lodash_1 = tslib_1.__importDefault(require('lodash'));
var js_yaml_1 = tslib_1.__importDefault(require('js-yaml'));
var gatsby_page_utils_1 = require('gatsby-page-utils');
var BBPromise = require('bluebird');
var existsSync = require('fs-exists-cached').sync;
var systemPath = require('path');
var readFileSync = require('fs').readFileSync;
var globCB = require('glob');
var glob = BBPromise.promisify(globCB);
// Path creator.
// Auto-create pages.
// algorithm is glob /pages directory for js/jsx/cjsx files *not*
// underscored. Then create url w/ our path algorithm *unless* user
// takes control of that page component in gatsby-node.
exports.createPagesStatefully = function(_a, _b, doneCb) {
var store = _a.store,
actions = _a.actions,
reporter = _a.reporter;
var pagesPath = _b.path,
_c = _b.pathCheck,
pathCheck = _c === void 0 ? true : _c,
ignore = _b.ignore;
return tslib_1.__awaiter(void 0, void 0, void 0, function() {
var createPage, deletePage, program, exts, findNearestFile, pagesDirectory, pagesGlob, tocGlob, files, tocs;
return tslib_1.__generator(this, function(_d) {
switch (_d.label) {
case 0:
(createPage = actions.createPage), (deletePage = actions.deletePage);
program = store.getState().program;
exts = program.extensions
.map(function(e) {
return '' + e.slice(1);
})
.join(',');
if (!pagesPath) {
reporter.panic(
'\n "path" is a required option for gatsby-plugin-page-creator\n\n See docs here - https://www.gatsbyjs.org/plugins/gatsby-plugin-page-creator/\n '
);
}
// Validate that the path exists.
if (pathCheck && !existsSync(pagesPath)) {
reporter.panic(
'\n The path passed to gatsby-plugin-page-creator does not exist on your file system:\n\n ' +
pagesPath +
'\n\n Please pick a path to an existing directory.\n '
);
}
findNearestFile = function(matchPath, filePaths) {
if (filePaths === undefined) {
return undefined;
}
var matchParts = matchPath.split('/');
do {
var match = filePaths.find(function(filePath) {
var fileRelPath = systemPath.dirname(filePath);
var matchRelPath = systemPath.dirname(matchParts.join('/'));
return fileRelPath === matchRelPath;
});
if (match !== undefined) {
return match;
} else {
matchParts.splice(-1, 1);
}
} while (matchParts.length > -1);
return undefined;
};
pagesDirectory = systemPath.resolve(process.cwd(), pagesPath);
pagesGlob = '**/*.{' + exts + '}';
tocGlob = '**/toc.yml';
return [4 /*yield*/, glob(pagesGlob, { cwd: pagesPath })];
case 1:
files = _d.sent();
return [4 /*yield*/, glob(tocGlob, { cwd: pagesPath })];
case 2:
tocs = _d.sent();
files.forEach(function(file) {
var tocPath = findNearestFile(file, tocs);
_createPage(file, pagesDirectory, createPage, ignore, tocPath);
});
gatsby_page_utils_1
.watchDirectory(
pagesPath,
pagesGlob,
function(addedPath) {
if (!lodash_1.default.includes(files, addedPath)) {
var tocPath = findNearestFile(addedPath, tocs);
_createPage(addedPath, pagesDirectory, createPage, ignore, tocPath);
files.push(addedPath);
}
},
function(removedPath) {
// Delete the page for the now deleted component.
var componentPath = systemPath.join(pagesDirectory, removedPath);
store.getState().pages.forEach(function(page) {
if (page.component === componentPath) {
deletePage({
path: gatsby_page_utils_1.createPath(removedPath),
component: componentPath
});
}
});
files = files.filter(function(f) {
return f !== removedPath;
});
}
)
.then(function() {
return doneCb();
});
return [2 /*return*/];
}
});
});
};
var _createPage = function(filePath, pagesDirectory, createPage, ignore, tocPath) {
// Filter out special components that shouldn't be made into
// pages.
if (!gatsby_page_utils_1.validatePath(filePath)) {
return;
}
// Filter out anything matching the given ignore patterns and options
if (gatsby_page_utils_1.ignorePath(filePath, ignore)) {
return;
}
var toc = undefined;
if (tocPath !== undefined) {
try {
toc = js_yaml_1.default.safeLoad(readFileSync(systemPath.join(pagesDirectory, tocPath), 'utf8'));
} catch (e) {
console.log(e);
}
}
// Create page object
var createdPath = gatsby_page_utils_1.createPath(filePath);
var page = {
path: createdPath,
component: systemPath.join(pagesDirectory, filePath),
context: {
toc: toc,
rootPath: filePath.substring(0, filePath.indexOf('/'))
}
};
// Add page
createPage(page);
};
//# sourceMappingURL=gatsby-node.js.map

Просмотреть файл

@ -1 +0,0 @@
{"version":3,"file":"gatsby-node.js","sourceRoot":"","sources":["../src/gatsby-node.ts"],"names":[],"mappings":";;;AAAA,0DAAuB;AACvB,4DAA2B;AAC3B,uDAAyF;AAEzF,IAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,IAAM,UAAU,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC;AACpD,IAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC3B,IAAA,yCAAY,CAAmB;AACvC,IAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC/B,IAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAEzC,gBAAgB;AAChB,qBAAqB;AACrB,iEAAiE;AACjE,mEAAmE;AACnE,uDAAuD;AAC1C,QAAA,qBAAqB,GAAG,UAAO,EAA4B,EAAE,EAA6C,EAAE,MAAM;QAAjF,gBAAK,EAAE,oBAAO,EAAE,sBAAQ;QAAM,mBAAe,EAAE,iBAAgB,EAAhB,qCAAgB,EAAE,kBAAM;;;;;;oBAC3G,UAAU,GAAiB,OAAO,WAAxB,EAAE,UAAU,GAAK,OAAO,WAAZ,CAAa;oBACrC,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC;oBACnC,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,KAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAG,EAAf,CAAe,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAEpE,IAAI,CAAC,SAAS,EAAE;wBACd,QAAQ,CAAC,KAAK,CACZ,oKAIC,CACF,CAAC;qBACH;oBAED,iCAAiC;oBACjC,IAAI,SAAS,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;wBACvC,QAAQ,CAAC,KAAK,CACZ,wGAGE,SAAS,mEAGV,CACF,CAAC;qBACH;oBAEK,eAAe,GAAG,UAAC,SAAiB,EAAE,SAAmB;wBAC7D,IAAI,SAAS,KAAK,SAAS,EAAE;4BAC3B,OAAO,SAAS,CAAC;yBAClB;wBACD,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;wBAClC,IAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;wBACnD,GAAG;4BACD,IAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,UAAA,QAAQ;gCACnC,IAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gCACjD,IAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;gCAC/E,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;gCACvC,OAAO,WAAW,KAAK,YAAY,CAAC;4BACtC,CAAC,CAAC,CAAC;4BACH,IAAI,KAAK,KAAK,SAAS,EAAE;gCACvB,OAAO,KAAK,CAAC;6BACd;;gCAAM,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;yBACjC,QAAQ,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;wBAEjC,OAAO,SAAS,CAAC;oBACnB,CAAC,CAAC;oBAEI,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;oBAC9D,SAAS,GAAG,WAAS,IAAI,MAAG,CAAC;oBAC7B,OAAO,GAAG,YAAY,CAAC;oBAGjB,qBAAM,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,EAAA;;oBAAjD,KAAK,GAAG,SAAyC;oBACxC,qBAAM,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,EAAA;;oBAA9C,IAAI,GAAG,SAAuC;oBAEpD,KAAK,CAAC,OAAO,CAAC,UAAA,IAAI;wBAChB,IAAM,OAAO,GAAG,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;wBAC5C,WAAW,CAAC,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;oBACjE,CAAC,CAAC,CAAC;oBAEH,kCAAc,CACZ,SAAS,EACT,SAAS,EACT,UAAA,SAAS;wBACP,IAAI,CAAC,gBAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE;4BACjC,IAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;4BACjD,WAAW,CAAC,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;4BACpE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;yBACvB;oBACH,CAAC,EACD,UAAA,WAAW;wBACT,iDAAiD;wBACjD,IAAM,aAAa,GAAG,UAAU,CAAC,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;wBACnE,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAA,IAAI;4BACjC,IAAI,IAAI,CAAC,SAAS,KAAK,aAAa,EAAE;gCACpC,UAAU,CAAC;oCACT,IAAI,EAAE,8BAAU,CAAC,WAAW,CAAC;oCAC7B,SAAS,EAAE,aAAa;iCACzB,CAAC,CAAC;6BACJ;wBACH,CAAC,CAAC,CAAC;wBACH,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,KAAK,WAAW,EAAjB,CAAiB,CAAC,CAAC;oBAC/C,CAAC,CACF,CAAC,IAAI,CAAC,cAAM,OAAA,MAAM,EAAE,EAAR,CAAQ,CAAC,CAAC;;;;;CACxB,CAAC;AACF,IAAM,WAAW,GAAG,UAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO;IACxE,4DAA4D;IAC5D,SAAS;IACT,IAAI,CAAC,gCAAY,CAAC,QAAQ,CAAC,EAAE;QAC3B,OAAO;KACR;IAED,qEAAqE;IACrE,IAAI,8BAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE;QAChC,OAAO;KACR;IAED,IAAI,GAAG,GAAG,SAAS,CAAC;IACpB,IAAI,OAAO,KAAK,SAAS,EAAE;QACzB,IAAI;YACF,GAAG,GAAG,iBAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;SACrF;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAChB;KACF;IAED,qBAAqB;IACrB,IAAM,WAAW,GAAG,8BAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAM,IAAI,GAAG;QACX,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,UAAU,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC;QACpD,OAAO,EAAE;YACP,GAAG,EAAE,GAAG;YACR,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;SACvD;KACF,CAAC;IAEF,WAAW;IACX,UAAU,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC,CAAC"}

Просмотреть файл

@ -1 +0,0 @@
module.exports = require('./dist/gatsby-node')

Просмотреть файл

@ -1,50 +0,0 @@
{
"name": "gatsby-plugin-docs-creator",
"version": "2.2.0",
"description": "Gatsby plugin that automatically creates pages from React components in specified directories with additional docs related data",
"main": "dist/gatsby-node.js",
"scripts": {
"build": "echo 'build'",
"start": "yarn watch",
"watch": "tsc -w --preserveWatchOutput",
"prepare": "cross-env NODE_ENV=production npm run build"
},
"keywords": [
"gatsby",
"gatsby-plugin"
],
"author": "Micah Godbolt <mgodbolt@microsoft.com>",
"contributors": [
"Steven Natera <tektekpush@gmail.com> (https://twitter.com/stevennatera)",
"Kyle Mathews <mathews.kyle@gmail.com>"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/microsoft/fluent-site.git",
"directory": "packages/gatsby-plugin-docs-creator"
},
"dependencies": {
"@types/bluebird": "^3.5.29",
"@types/js-yaml": "^3.12.2",
"@types/lodash": "^4.14.149",
"@types/node": "^13.7.4",
"bluebird": "^3.7.2",
"fs-exists-cached": "^1.0.0",
"gatsby-page-utils": "^0.0.39",
"glob": "^7.1.6",
"js-yaml": "^3.13.1",
"lodash": "^4.17.15",
"micromatch": "^3.1.10"
},
"devDependencies": {
"cross-env": "^5.2.1",
"tslib": "^1.10.0"
},
"peerDependencies": {
"gatsby": "^2.0.0"
},
"engines": {
"node": ">=8.0.0"
}
}

Просмотреть файл

@ -1,136 +0,0 @@
import _ from 'lodash';
import yaml from 'js-yaml';
import { createPath, validatePath, ignorePath, watchDirectory } from 'gatsby-page-utils';
const BBPromise = require('bluebird');
const existsSync = require(`fs-exists-cached`).sync;
const systemPath = require(`path`);
const { readFileSync } = require(`fs`);
const globCB = require(`glob`);
const glob = BBPromise.promisify(globCB);
// Path creator.
// Auto-create pages.
// algorithm is glob /pages directory for js/jsx/cjsx files *not*
// underscored. Then create url w/ our path algorithm *unless* user
// takes control of that page component in gatsby-node.
export const createPagesStatefully = async ({ store, actions, reporter }, { path: pagesPath, pathCheck = true, ignore }, doneCb) => {
const { createPage, deletePage } = actions;
const program = store.getState().program;
const exts = program.extensions.map(e => `${e.slice(1)}`).join(`,`);
if (!pagesPath) {
reporter.panic(
`
"path" is a required option for gatsby-plugin-page-creator
See docs here - https://www.gatsbyjs.org/plugins/gatsby-plugin-page-creator/
`
);
}
// Validate that the path exists.
if (pathCheck && !existsSync(pagesPath)) {
reporter.panic(
`
The path passed to gatsby-plugin-page-creator does not exist on your file system:
${pagesPath}
Please pick a path to an existing directory.
`
);
}
const findNearestFile = (matchPath: string, filePaths: string[]): string | undefined => {
if (filePaths === undefined) {
return undefined;
}
const matchParts = matchPath.split('/');
do {
const match = filePaths.find(filePath => {
const fileRelPath = systemPath.dirname(filePath);
const matchRelPath = systemPath.dirname(matchParts.join('/'));
return fileRelPath === matchRelPath;
});
if (match !== undefined) {
return match;
} else matchParts.splice(-1, 1);
} while (matchParts.length > 0);
return undefined;
};
const pagesDirectory = systemPath.resolve(process.cwd(), pagesPath);
const pagesGlob = `**/*.{${exts}}`;
const tocGlob = '**/toc.yml';
// Get initial list of files.
let files = await glob(pagesGlob, { cwd: pagesPath });
const tocs = await glob(tocGlob, { cwd: pagesPath });
files.forEach(file => {
const tocPath = findNearestFile(file, tocs);
_createPage(file, pagesDirectory, createPage, ignore, tocPath);
});
watchDirectory(
pagesPath,
pagesGlob,
addedPath => {
if (!_.includes(files, addedPath)) {
const tocPath = findNearestFile(addedPath, tocs);
_createPage(addedPath, pagesDirectory, createPage, ignore, tocPath);
files.push(addedPath);
}
},
removedPath => {
// Delete the page for the now deleted component.
const componentPath = systemPath.join(pagesDirectory, removedPath);
store.getState().pages.forEach(page => {
if (page.component === componentPath) {
deletePage({
path: createPath(removedPath),
component: componentPath
});
}
});
files = files.filter(f => f !== removedPath);
}
).then(() => doneCb());
};
const _createPage = (filePath, pagesDirectory, createPage, ignore, tocPath) => {
// Filter out special components that shouldn't be made into
// pages.
if (!validatePath(filePath)) {
return;
}
// Filter out anything matching the given ignore patterns and options
if (ignorePath(filePath, ignore)) {
return;
}
let toc = undefined;
if (tocPath !== undefined) {
try {
toc = yaml.safeLoad(readFileSync(systemPath.join(pagesDirectory, tocPath), 'utf8'));
} catch (e) {
console.log(e);
}
}
// Create page object
const createdPath = createPath(filePath);
const page = {
path: createdPath,
component: systemPath.join(pagesDirectory, filePath),
context: {
toc: toc,
rootPath: filePath.substring(0, filePath.indexOf('/'))
}
};
// Add page
createPage(page);
};

Просмотреть файл

@ -1,23 +0,0 @@
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"target": "es5",
"module": "commonjs",
"jsx": "react",
"declaration": true,
"sourceMap": true,
"experimentalDecorators": true,
"importHelpers": true,
"noUnusedLocals": true,
"forceConsistentCasingInFileNames": true,
"strictNullChecks": true,
"noImplicitAny": false,
"moduleResolution": "node",
"preserveConstEnums": true,
"lib": ["es5", "dom"],
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"include": ["src"]
}

Просмотреть файл

@ -1,12 +0,0 @@
{
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"semi": "off"
}
}

Просмотреть файл

@ -1,23 +0,0 @@
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
module.exports = {
stories: ['../src/**/*.story.tsx'],
addons: ['@storybook/addon-actions', '@storybook/addon-links'],
webpackFinal: async config => {
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
presets: [['react-app', { flow: false, typescript: true }]],
},
})
config.plugins.push(
new MonacoWebpackPlugin({
languages: ['typescript'],
})
)
config.resolve.extensions.push('.ts', '.tsx')
return config
},
}

Просмотреть файл

@ -1,96 +0,0 @@
# Application Insights README
Fluent website telementry information
**Table of Contents**
<!-- TOC -->
- [Application Insights README](#application-insights-readme)
- [Description](#description)
- [Usage](#usage)
- [IMPORTANT! Build notes](#important-build-notes)
- [NPM Packages](#npm-packages)
- [Resources](#resources)
<!-- /TOC -->
## Description
The Application Insights interface has be designed as a client side only react component. It hooks into the equivelent of
onComponentDidMount event (via hooks) and runs once per instantiation.
## Usage
*PageView*
```typescript
import { usePageViewTelemetry } from '../components/ApplicationInsights'
...
let pathName = "Home" // if pathName is null, it will use the window.location.pathName value
const [pageView, setPageView] = usePageViewTelemetry({ name: props.path })
// since the call is made immediately, you can just do the following if you are not updating the value
usePageViewTelemetry({ name: props.path })
```
*EventView*
```jsx
import { useEventTelemetry } from '../components/ApplicationInsights'
...
const [myEvent, invokeMyEventTelemetry] = useEventTelemetry({ name: 'MyEvent' })
const buttonClick = () => {
invokeMyEventTelemetry();
}
return (
<button onClick={buttonClick}>Click Here!</button>
)
```
*EventView With Name/Value Property*
```jsx
import { useEventTelemetry } from '../components/ApplicationInsights'
...
const [myEvent, invokeMyEventTelemetry] = useEventTelemetry({ name: 'MyEvent' })
const sendEvent = (buttonId:number) => {
myEvent.properties = myEvent.properties ? myEvent.properties : []
myEvent.properties["Button_Clicked"] = buttonId
// this call will send the update and send the telementry data
invokeMyEventTelemetry(myEvent)
}
return (
<button onClick={() => {sendEvent(1)}}>Button 1</button>
<button onClick={() => {sendEvent(2)}}>Button 2</button>
)
```
## IMPORTANT! Build notes
*NOTE
For production builds you need to set GATBSY_APPLICATIONINSIGHTS_KEY to the value of the production key *prior* to
a production build. This can be done as an evironment variable or in the .env.production file under src/website.
The key is retrieved from the Application Insights app on https://portal.azure.com
For development/test builds, modify the .env.developement file.
## NPM Packages
NPM package(s):
@microsoft/applicationinsights-web
@microsoft/applicationinsights-react-js
## Resources
[Azure Portal Resource](https://ms.portal.azure.com/#@microsoft.onmicrosoft.com/resource/subscriptions/9ccbac18-03d3-485b-a43e-87dc09014817/resourcegroups/OXOSharedRG/providers/microsoft.insights/components/FluentUI-Website/overview)
[Javascript NPM Setup](https://docs.microsoft.com/en-us/azure/azure-monitor/app/javascript#npm-based-setup)
[Application Insights React](https://github.com/microsoft/ApplicationInsights-JS/blob/17ef50442f73fd02a758fbd74134933d92607ecf/extensions/applicationinsights-react-js/README.md)

Просмотреть файл

@ -1,69 +0,0 @@
{
"name": "gatsby-theme-fluent-site",
"entries": [
{
"date": "Fri, 17 Apr 2020 22:36:03 GMT",
"tag": "gatsby-theme-fluent-site_v0.2.0",
"version": "0.2.0",
"comments": {
"minor": [
{
"comment": "yarn.lock",
"author": "warleu@microsoft.com",
"commit": "205e7b7e88151a17f2560ecdaec1c6e13c5825b7",
"package": "gatsby-theme-fluent-site"
}
]
}
},
{
"date": "Thu, 09 Apr 2020 18:39:15 GMT",
"tag": "gatsby-theme-fluent-site_v0.1.3",
"version": "0.1.3",
"comments": {
"patch": [
{
"comment": "merge conflicts",
"author": "ppatboyd@outlook.com",
"commit": "232a97794dc044cec9671e5cca4cf204d881f614",
"package": "gatsby-theme-fluent-site"
}
]
}
},
{
"date": "Wed, 08 Apr 2020 21:26:12 GMT",
"tag": "gatsby-theme-fluent-site_v0.1.2",
"version": "0.1.2",
"comments": {
"patch": [
{
"comment": "update package name",
"author": "mgodbolt@microsoft.com",
"commit": "232a97794dc044cec9671e5cca4cf204d881f614",
"package": "gatsby-theme-fluent-site"
}
]
}
},
{
"date": "Sat, 27 Jul 2019 05:29:12 GMT",
"tag": "gatsby-starter-uifabric-doc_v0.1.1",
"version": "0.1.1",
"comments": {
"patch": [
{
"comment": "initial publish",
"author": "kchau@microsoft.com",
"commit": "d5ff88bc7ddf21d5e9035f4a95503df50709f55c"
},
{
"comment": "initial release",
"author": "kchau@microsoft.com",
"commit": "e9f0dccdd68a5890a3a063b79314d3ea446a95da"
}
]
}
}
]
}

Просмотреть файл

@ -1,33 +0,0 @@
# Change Log - gatsby-theme-fluent-site
This log was last generated on Fri, 17 Apr 2020 22:36:03 GMT and should not be manually modified.
<!-- Start content -->
## 0.2.0
Fri, 17 Apr 2020 22:36:03 GMT
### Minor changes
- yarn.lock (warleu@microsoft.com)
## 0.1.3
Thu, 09 Apr 2020 18:39:15 GMT
### Patches
- merge conflicts (ppatboyd@outlook.com)
## 0.1.2
Wed, 08 Apr 2020 21:26:12 GMT
### Patches
- update package name (mgodbolt@microsoft.com)
## 0.1.1
Sat, 27 Jul 2019 05:29:12 GMT
### Patches
- initial publish (kchau@microsoft.com)
,- initial release (kchau@microsoft.com)

Просмотреть файл

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018 gatsbyjs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Просмотреть файл

@ -1,86 +0,0 @@
## 🚀 Quick start
1. **Start developing.**
```sh
yarn
yarn start
```
1. **Open the source code and start editing!**
Your site is now running at `http://localhost:3000`!
_Note: You'll also see a second link: _`http://localhost:3000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.org/tutorial/part-five/#introducing-graphiql)._
1. Working with [NetlifyCMS](https://www.netlifycms.org/)
NetlifyCMS is a React application that sites on top of the markdown content in git and provides a user friendly interface for creating, editing, and reviewing proposed content changes.
To develop new collections and work within NetlifyCMS's `static/admin/config.yml` file, you can now run a local server and allow the CMS to create and edit your local files
```sh
npx netlify-cms-proxy-server
# while server is running, in a seperate terminal run
yarn start
```
Now when you navigate to `http://localhost:3000/admin/` you will be allowed to log in without authentication, and any file change will only change your local data. No git involved.
## 🧐 What's inside?
A quick look at the top-level files and directories you'll see in a the Website package.
.
├── src
├── gatsby-browser.js
├── gatsby-config.js
├── gatsby-node.js
├── gatsby-ssr.js
├── LICENSE
├── package-lock.json
├── package.json
└── README.md
2. **`/src`**: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. `src` is a convention for “source code”.
5. **`gatsby-browser.js`**: This file is where Gatsby expects to find any usage of the [Gatsby browser APIs](https://www.gatsbyjs.org/docs/browser-apis/) (if any). These allow customization/extension of default Gatsby settings affecting the browser.
6. **`gatsby-config.js`**: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins youd like to include, etc. (Check out the [config docs](https://www.gatsbyjs.org/docs/gatsby-config/) for more detail).
7. **`gatsby-node.js`**: This file is where Gatsby expects to find any usage of the [Gatsby Node APIs](https://www.gatsbyjs.org/docs/node-apis/) (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process.
8. **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.org/docs/ssr-apis/) (if any). These allow customization of default Gatsby settings affecting server-side rendering.
9. **`LICENSE`**: Gatsby is licensed under the MIT license.
11. **`package.json`**: A manifest file for Node.js projects, which includes things like metadata (the projects name, author, etc). This manifest is how npm knows which packages to install for your project.
12. **`README.md`**: A text file containing useful reference information about your project.
## 🎓 Learning Gatsby
Looking for more guidance? Full documentation for Gatsby lives [on the website](https://www.gatsbyjs.org/). Here are some places to start:
- **For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby](https://www.gatsbyjs.org/tutorial/).** It starts with zero assumptions about your level of ability and walks through every step of the process.
- **To dive straight into code samples, head [to our documentation](https://www.gatsbyjs.org/docs/).** In particular, check out the _Guides_, _API Reference_, and _Advanced Tutorials_ sections in the sidebar.
## 💫 Deploy
[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/gatsbyjs/gatsby-starter-hello-world)
<!-- AUTO-GENERATED-CONTENT:END -->
## Developing Components
Check out [README](./src/components/CONTRIBUTING.md) in the components directory.
## Storybook
A playground for developing components in isolation [README](./src/components/STORYBOOK.md)

Просмотреть файл

@ -1,145 +0,0 @@
require('dotenv').config({
path: `.env.${process.env.NODE_ENV}`,
})
module.exports = themeOptions => {
const { contentPath, pathPrefix } = themeOptions
return {
pathPrefix: pathPrefix || '',
siteMetadata: {
title: 'Microsoft Design - Fluent',
description:
'Fluent brings the fundamentals of principled design, innovation in technology, and customer needs together as one. Its a collective approach to creating simplicity and coherence through a shared, open design system across platforms.',
siteURL: 'https://fluentui.z5.web.core.windows.net/',
headerLinks: [
{
name: 'Fundamentals',
link: '/fundamentals',
headerOnly: true,
},
{
name: 'Web',
link: '/web',
},
{
name: 'Windows',
link: '/windows',
},
{
name: 'iOS',
link: '/ios',
},
{
name: 'Android',
link: '/android',
},
{
name: 'Mac',
link: '/mac',
},
],
topLinks: [
{ name: 'Get started', link: 'get-started' },
{ name: 'Styles & Theming', link: 'styles' },
{ name: 'Experiences', link: 'experiences' },
{ name: 'Components', link: 'components' },
],
footerLinks: [
{
name: 'Resources',
link: '/resources',
ariaLabel: 'This link will take you to the Resources page',
},
{
name: "What's new",
link: '/whatsnew',
ariaLabel: "This link will take you to the What's new page",
},
{
name: 'GitHub',
link: 'https://github.com/microsoft/fluent-site',
target: '_blank',
ariaLabel: 'This link will take you to the Microsoft Fluent UI GitHub site in a new window.',
},
{
name: 'Privacy & cookies',
link: 'https://privacy.microsoft.com/en-us/privacystatement',
ariaLabel: 'This link will take you to the Microsoft privacy statement.',
},
],
homePageData: {
news: [
{
title: 'Lorem ipsum dolor sit amet, consectet adipiscing elit. Vivamus ut max velit, ut iaculis est. Nullam tincidunt.',
link: '#',
},
{
title: 'Lorem ipsum dolor sit amet, consectet adipiscing elit. Vivamus ut max velit, ut iaculis est. Nullam tincidunt.',
link: '#',
},
{
title: 'Lorem ipsum dolor sit amet, consectet adipiscing elit. Vivamus ut max velit, ut iaculis est. Nullam tincidunt.',
link: '#',
},
{
title: 'Lorem ipsum dolor sit amet, consectet adipiscing elit. Vivamus ut max velit, ut iaculis est. Nullam tincidunt.',
link: '#',
},
],
},
},
plugins: [
`gatsby-plugin-emotion`,
`gatsby-transformer-yaml`,
`gatsby-plugin-react-helmet`,
`gatsby-plugin-typescript`,
'gatsby-plugin-sharp',
'gatsby-transformer-sharp',
`gatsby-plugin-offline`,
{
resolve: `gatsby-plugin-netlify-cms`,
options: {
modulePath: `${__dirname}/src/cms/cms.js`,
},
},
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `Fabric Website 2.0`,
short_name: `fabricwebsite`,
start_url: `/`,
background_color: `#f7f0eb`,
theme_color: `#a2466c`,
display: `standalone`,
},
},
{
resolve: `gatsby-plugin-mdx`,
options: {
defaultLayouts: {
default: require.resolve('./src/templates/MDXTemplate.tsx'),
},
gatsbyRemarkPlugins: [
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 400,
withWebp: true,
tracedSVG: true,
linkImagesToOriginal: false,
},
},
{
resolve: `gatsby-remark-copy-linked-files`,
},
],
},
},
{
resolve: `gatsby-plugin-docs-creator`,
options: {
path: contentPath,
},
},
],
}
}

Просмотреть файл

@ -1,29 +0,0 @@
const path = require('path')
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
exports.onCreatePage = ({ page, actions }) => {
const { createPage, deletePage } = actions
}
exports.createPages = async ({ actions, graphql }) => {
const { createPage } = actions
}
exports.onCreateWebpackConfig = ({ stage, actions }) => {
if (stage.startsWith('develop')) {
actions.setWebpackConfig({
resolve: {
alias: {
'react-dom': '@hot-loader/react-dom',
},
},
})
}
actions.setWebpackConfig({
plugins: [
new MonacoWebpackPlugin({
languages: ['typescript'],
}),
],
})
}

Просмотреть файл

@ -1,20 +0,0 @@
import { Stylesheet, InjectionMode } from '@uifabric/merge-styles'
import { renderStatic } from '@uifabric/merge-styles/lib/server'
import { renderToString } from 'react-dom/server'
import React from 'react'
const config = require('./gatsby-config')
export const replaceRenderer = ({ bodyComponent, replaceBodyHTMLString, setHeadComponents }) => {
const { html, css } = renderStatic(() => {
return renderToString(bodyComponent)
})
replaceBodyHTMLString(html)
setHeadComponents([<style dangerouslySetInnerHTML={{ __html: css }} />])
}
export const onRenderBody = ({ pathname, setHeadComponents }) => {
setHeadComponents([<link rel="canonical" href={`${config.siteMetadata ? config.siteMetadata.siteUrl : '/'}${pathname}`} />])
}

Просмотреть файл

@ -1,79 +0,0 @@
{
"name": "gatsby-theme-fluent-site",
"version": "0.2.0",
"main": "index.js",
"description": "A Fluent theme for GatsbyJS",
"repository": {
"type": "git",
"url": "https://github.com/microsoft/fluent-site"
},
"license": "MIT",
"scripts": {
"clean": "gatsby clean",
"build": "echo 'building'",
"start": "echo 'starting'",
"test": "echo \"Write tests! -> https://gatsby.app/unit-testing\"",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"devDependencies": {
"@babel/core": "^7.8.3",
"@mdx-js/mdx": "^1.1.0",
"@mdx-js/react": "^1.0.27",
"@storybook/addon-actions": "^5.3.4",
"@storybook/addon-links": "^5.3.4",
"@storybook/addons": "^5.3.4",
"@storybook/react": "^5.3.4",
"@types/graphql": "^14.2.0",
"@types/node": "^11.13.13",
"@types/react": "^16.8.19",
"@types/react-dom": "^16.8.4",
"@types/react-helmet": "^5.0.8",
"babel-loader": "^8.0.6",
"gatsby": "^2.20.10",
"gatsby-image": "^2.2.38",
"gatsby-link": "^2.2.2",
"gatsby-plugin-docs-creator": "^2.2.0",
"gatsby-plugin-manifest": "^2.2.20",
"gatsby-plugin-mdx": "^1.0.67",
"gatsby-plugin-netlify-cms": "^4.2.2",
"gatsby-plugin-offline": "^3.0.32",
"gatsby-plugin-react-helmet": "^3.1.21",
"gatsby-plugin-sharp": "^2.3.13",
"gatsby-plugin-typescript": "^2.1.26",
"gatsby-remark-copy-linked-files": "^2.1.36",
"gatsby-remark-images": "^3.1.42",
"gatsby-remark-prismjs": "^3.3.30",
"gatsby-source-filesystem": "^2.1.46",
"gatsby-source-git": "^1.0.2",
"gatsby-transformer-remark": "^2.6.48",
"gatsby-transformer-sharp": "^2.3.12",
"gatsby-transformer-yaml": "^2.2.24",
"monaco-editor-webpack-plugin": "^1.9.0",
"netlify-cms-app": "^2.12.2",
"office-ui-fabric-react": "^7.92.0",
"prism-react-renderer": "^1.0.1",
"react": "^16.13.0",
"react-dom": "^16.13.0",
"react-helmet": "^5.2.1",
"react-live": "^2.1.2",
"react-monaco-editor": "^0.34.0",
"remark-parse": "^7.0.0",
"remark-react": "^6.0.0",
"unified": "^8.3.2"
},
"dependencies": {
"@emotion/core": "^10.0.27",
"@emotion/styled": "^10.0.27",
"@hot-loader/react-dom": "^16.12.0",
"@loadable/component": "^5.12.0",
"@microsoft/applicationinsights-react-js": "^2.4.4",
"@microsoft/applicationinsights-web": "^2.4.4",
"@uifabric/api-docs": "^7.2.13",
"@uifabric/example-app-base": "^7.11.16",
"fuse.js": "^3.4.6",
"gatsby-plugin-emotion": "^4.1.22",
"monaco-editor": "^0.20.0",
"typescript": "^3.5.1"
}
}

Просмотреть файл

@ -1,6 +0,0 @@
/**
* The default export of `netlify-cms-app` is an object with all of the Netlify CMS
* extension registration methods, such as `registerWidget` and
* `registerPreviewTemplate`.
*/
import CMS from 'netlify-cms-app'

Просмотреть файл

@ -1,65 +0,0 @@
import React, { useEffect } from 'react'
import { ApplicationInsights } from '@microsoft/applicationinsights-web'
import styled from '@emotion/styled'
declare global {
interface Window {
appInsights: ApplicationInsights
}
}
const StyledAppInsights = styled.div`
display: none;
`
export interface IAppInsightsPageViewProps {
path: string | null
}
export interface IAppInsightsEventViewProps {
eventName: string
eventPropertyName?: string
eventPropertyValue?: any
}
const AppInsightsLoadable = (props: IAppInsightsPageViewProps | IAppInsightsEventViewProps) => {
useEffect(() => {
if (window.appInsights === undefined) {
/* TODO: The key needs to be injected for production vs development */
window.appInsights = new ApplicationInsights({
config: {
instrumentationKey: `${process.env.GATSBY_APPLICATIONINSIGHTS_KEY}`,
enableAutoRouteTracking: true,
/* ...Other Configuration Options... */
},
})
window.appInsights.loadAppInsights()
}
let eventProps = props as IAppInsightsEventViewProps
if (eventProps.eventName !== undefined) {
if (eventProps.eventPropertyName !== undefined) {
window.appInsights.trackEvent({
name: eventProps.eventName,
properties: [eventProps.eventPropertyName] = eventProps.eventPropertyValue,
})
} else {
window.appInsights.trackEvent({ name: eventProps.eventName })
}
} else {
let pageViewProps = props as IAppInsightsPageViewProps
let path = pageViewProps.path ? pageViewProps.path : window.location.pathname
if (path === '/') {
path = document.title
} else {
path = path.replace(/^\//, '')
}
if (path) {
window.appInsights.trackPageView({ name: path })
}
}
}, [])
return <StyledAppInsights />
}
export default AppInsightsLoadable

Просмотреть файл

@ -1,36 +0,0 @@
import { ApplicationInsights, IEventTelemetry } from '@microsoft/applicationinsights-web'
import React from 'react'
interface AppInsightsWrapper {
appInsights: ApplicationInsights
}
declare global {
interface Window {
appInsights: ApplicationInsights
}
}
/**
* Returns an instance of the Application Insights object, undefined, or false(during SSR)
**/
export default function InitAppInsights(): ApplicationInsights | undefined {
const windowGlobal = (typeof window !== 'undefined' && window) as Window
const key = `${process.env.GATSBY_APPLICATIONINSIGHTS_KEY}`
if (windowGlobal && key !== undefined && key !== '') {
if (windowGlobal.appInsights === undefined) {
/* TODO: The key needs to be injected for production vs development */
windowGlobal.appInsights = new ApplicationInsights({
config: {
instrumentationKey: key,
enableAutoRouteTracking: true,
/* ...Other Configuration Options... */
},
})
windowGlobal.appInsights.loadAppInsights()
}
return windowGlobal.appInsights
}
return undefined
}

Просмотреть файл

@ -1,3 +0,0 @@
import useEventTelemetry from './useEventTelemetry'
import usePageViewTelemetry from './usePageViewTelemetry'
export { useEventTelemetry, usePageViewTelemetry }

Просмотреть файл

@ -1,33 +0,0 @@
import { useState, useEffect, Dispatch, SetStateAction } from 'react'
import { IEventTelemetry } from '@microsoft/applicationinsights-web'
import InitAppInsights from './InitAppInsights'
//#region IEventTelemetry Hook
/**
* Returns a stateful value of a IEventTelemetry object and a function to invoke the telemetry call
* @param {IEventTelemetry} data IEventTelemetry Object
* @returns [IEventTelemetry, Function to invoke the call]
**/
export default function usePageViewTelemetry(
data: IEventTelemetry | undefined
): [IEventTelemetry, Dispatch<SetStateAction<IEventTelemetry | undefined>>] {
data = data || ({} as IEventTelemetry)
const [telementryData, setTelementryData] = useState(data)
const invoke = (newData: IEventTelemetry | undefined) => {
if (newData !== undefined) {
setTelementryData(newData)
}
newData = newData || telementryData
if (newData !== undefined) {
let appInsights = InitAppInsights()
if (appInsights) {
appInsights.trackEvent(newData)
}
}
}
return [telementryData, invoke]
}
//#endregion

Просмотреть файл

@ -1,41 +0,0 @@
import { useState, useEffect, Dispatch, SetStateAction } from 'react'
import { IPageViewTelemetry } from '@microsoft/applicationinsights-web'
import InitAppInsights from './InitAppInsights'
//#region usePageViewTelemetry Hook
/**
* Returns a stateful value of a IPageViewTelemetry object and a function to update the telemetry value
* @param {IPageViewTelemetry} data IPageViewTelemetry Object
* @returns [IPageViewTelemetry, Function to update]
**/
export default function usePageViewTelemetry(
data: IPageViewTelemetry | undefined
): [IPageViewTelemetry | undefined, Dispatch<SetStateAction<IPageViewTelemetry | undefined>>] {
// Send the data immediately (OnComponentMount) if instantiated with data
const [telementryData, setTelementryData] = useState(data)
useEffect(() => {
if (typeof window !== undefined && window && telementryData !== undefined) {
let appInsights = InitAppInsights()
if (appInsights !== undefined) {
let path = telementryData.name
if (path === undefined) {
path = window.location.pathname
if (path === '/') {
path = document.title
} else {
path = path.replace(/^\//, '')
}
telementryData.name = path
setTelementryData(telementryData)
}
appInsights.trackPageView(telementryData)
}
}
}, [])
return [telementryData, setTelementryData]
}
//#endregion

Просмотреть файл

@ -1,38 +0,0 @@
# A WIP guide to contributing components
> Just gathering some thoughts and notes. These are not final, may change with additional clarity, and are open for discussion. - Scott
## Notes for components:
1. The UI for the docs site should be built using Fluent UI. Seems like table stakes.
2. Initially, we will need to scaffold out the site using components built with JSX tags.
3. Some level of run-time theming will need to be supported.
4. Theming should leverage the same Fluent UI base styles.
- Possible themes include high contrast, dark mode, etc.
## Component questions / thoughts:
1. Can we use the Fluent UI components directly in code or do we need a proxy component to make global changes easier?
> I am leaning on using the Fluent UI components directly since we will be custom-building a version of it for the docs site. - Scott
2. Does overall site theming affect the theme that is shown on any given component?
3. Is global / local theming a setting somewhere?
4. How are design-time customizations exposed for use in the site?
---
## Notes for CSS variables:
- There seems to be a logical divide between theme styles that are static and dynamic.
- Some properties need to be changed at runtime. This includes color themes, density, and others.
- Some properties only need to be changed at design time. This includes most other aspects of the design system: ramps (type, spacing, color), elevation, etc.
- Fallback values will need to provided in a way that allows legacy browser to style things correctly.
- Fallbacks can use the `var(--bg-color, white)` syntax.
- Or they can be made more robust w/ graceful degredation by declaring legacy properties alongside variable properties.
- When leveraging CSS variables, media queries are used to change the value of custom properties.
- This separates out the styling blocks from the layout logic.
- It might make sense to use special casing for global CSS variables, e.g. `--PAGE-BG-COLOR` to more easily differentiate them from local variables.
## CSS variables questions / thoughts:
1. How do we reconcile runtime styling and design time styling?
- The site will need some flexibility that the compiled library wont need. For example, the theme editor with need to change design-time properties on the fly, but implementations of Fluent UI will not introduce these aspects as runtime properties.

Просмотреть файл

@ -1,13 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
export const PageInnerContent = props => {
return <StyledContent>{props.children}</StyledContent>
}
const StyledContent = styled.main`
border-left: 1px solid #eee;
padding: 40px;
overflow-y: auto;
flex-grow: 1;
`

Просмотреть файл

@ -1 +0,0 @@
export { PageInnerContent } from './PageInnerContent'

Просмотреть файл

@ -1,37 +0,0 @@
import * as React from 'react'
import { useStaticQuery, graphql } from 'gatsby'
import styled from '@emotion/styled'
import { FooterMenuItems } from './FooterMenuItems'
export const Footer = props => {
const data = useStaticQuery(graphql`
query FooterMenuQuery {
site {
siteMetadata {
footerLinks {
name
link
target
ariaLabel
}
}
}
}
`)
const {
site: { siteMetadata },
} = data
return (
<StyledFooter>
<FooterMenuItems {...siteMetadata} />
</StyledFooter>
)
}
const StyledFooter = styled.div`
display: flex;
margin: 0 auto;
padding: 40px 40px 40px 20px;
border-top: 1px solid #eee;
`

Просмотреть файл

@ -1,62 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
import { Link } from 'gatsby'
export const FooterMenuItems = props => {
return (
<StyledMenuItems>
{props.footerLinks.map((link, idx) => (
<MenuItem {...link} key={'footerItem_' + idx} />
))}
</StyledMenuItems>
)
}
const MenuItem = props => {
return (
<StyledMenuItem key={props.name}>
{props.link.startsWith('http') ? (
<a
href={props.link}
target={props.target !== undefined ? props.target : undefined}
{...{ 'aria-label': props.ariaLabel ? props.ariaLabel : undefined }}
>
{props.name}
</a>
) : (
<Link
activeClassName="Link-IsActive"
to={props.link}
target={props.target ? props.target : undefined}
{...{ 'aria-label': props.ariaLabel ? props.ariaLabel : undefined }}
>
{props.name}
</Link>
)}
</StyledMenuItem>
)
}
const StyledMenuItems = styled.ul`
display: flex;
padding: 0;
`
const StyledMenuItem = styled.li`
list-style: none;
margin: auto 10px;
a {
color: #000;
opacity: 0.7;
padding: 0 2px;
text-decoration: none;
&.Link-IsActive {
border-bottom: 3px solid #000;
padding-bottom: 20px;
font-weight: 600;
opacity: 1;
}
}
`

Просмотреть файл

@ -1 +0,0 @@
export { Footer } from './Footer'

Просмотреть файл

@ -1,85 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
import { useStaticQuery, graphql, Link } from 'gatsby'
import { HeaderMenuItems } from '.'
import { Search } from '../Search'
import { SubNav } from './SubNav'
import { usePageContext } from '../Provider'
export const Header = props => {
const pageContext = usePageContext()
const data = useStaticQuery(graphql`
query MainMenuQuery {
site {
siteMetadata {
title
headerLinks {
name
link
}
topLinks {
link
name
}
}
}
}
`)
const {
pathContext: { rootPath },
location: { pathname },
} = pageContext
const {
site: { siteMetadata },
} = data
const topLinks = siteMetadata.topLinks.map(item => {
return {
name: item.name,
link: '/' + rootPath + '/' + item.link,
}
})
return (
<StyledHeader>
<Nav>
<Logo to="/">
<img src={require('gatsby-theme-fluent-site/static/images/microsoft.svg')} alt="Microsoft Logo" />
<p>Fluent</p>
</Logo>
<HeaderMenuItems {...siteMetadata} />
<Search />
</Nav>
{rootPath && rootPath !== 'fundamentals' && <SubNav topLinks={topLinks} />}
</StyledHeader>
)
}
const StyledHeader = styled.div``
const Nav = styled.header`
width: 100%;
padding: 20px 40px;
display: flex;
justify-content: space-between;
border-bottom: 1px solid #eee;
`
const Logo = styled(Link)`
display: flex;
color: #000;
text-decoration: none;
img {
width: 22px;
}
p {
margin: 12px;
font-weight: 600;
}
`

Просмотреть файл

@ -1,63 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
import { Link } from 'gatsby'
const MenuItem = props => {
return (
<StyledMenuItem key={props.name}>
<Link activeClassName="Link-IsActive" to={props.link}>
{props.name}
</Link>
</StyledMenuItem>
)
}
export const HeaderMenuItems = props => {
return (
<StyledMenuItems>
{props.headerLinks.map((link, i) => (
<MenuItem key={i} {...link} />
))}
</StyledMenuItems>
)
}
const StyledMenuItems = styled.ul`
display: flex;
padding: 0;
`
const StyledMenuItem = styled.li`
list-style: none;
margin: auto 10px;
&:first-of-type {
border-right: 1px solid #eee;
padding-right: 20px;
}
a {
color: #666;
padding: 0 2px;
font-weight: 500;
text-decoration: none;
&.Link-IsActive {
color: #000;
font-weight: 500;
position: relative;
&:after {
content: '';
position: absolute;
bottom: -35px;
left: calc(50% - 10px);
width: 0;
height: 0;
border-style: solid;
border-width: 0 10px 10px 10px;
border-color: transparent transparent #eeeeee transparent;
}
}
}
`

Просмотреть файл

@ -1,54 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
import { Link } from 'gatsby'
export const SubNav = props => {
const menuItems = props.topLinks.map((item, index) => {
return (
<li key={index}>
<Link partiallyActive={true} activeClassName="Link-IsActive" to={item.link}>
{item.name}
</Link>
</li>
)
})
return (
<StyledSubNav>
<StyledList>{menuItems}</StyledList>
</StyledSubNav>
)
}
const StyledSubNav = styled.div`
background-color: #eee;
margin: 0px;
p {
margin: 0;
padding: 40px;
opacity: 0.4;
}
`
const StyledList = styled.ul`
display: flex;
padding: 30px 30px 30px 20px;
max-width: 600px;
list-style: none;
li {
list-style: none;
margin: 0 20px;
a {
color: #666;
font-weight: 500;
text-decoration: none;
&.Link-IsActive {
color: #000;
}
}
}
`

Просмотреть файл

@ -1,2 +0,0 @@
export { Header } from './Header'
export { HeaderMenuItems } from './HeaderMenuItems'

Просмотреть файл

@ -1,21 +0,0 @@
import * as React from 'react'
import Highlight, { defaultProps } from 'prism-react-renderer'
import darkTheme from 'prism-react-renderer/themes/nightOwl'
export const HighlightHOC = p => {
return (
<Highlight {...defaultProps} theme={darkTheme} code={p.children} language="jsx">
{({ className, style, tokens, getLineProps, getTokenProps }) => (
<div className={className} style={style}>
{tokens.map((line, i) => (
<div {...getLineProps({ line, key: i })}>
{line.map((token, key) => (
<span {...getTokenProps({ token, key })} />
))}
</div>
))}
</div>
)}
</Highlight>
)
}

Просмотреть файл

@ -1,21 +0,0 @@
import * as React from 'react'
import Highlight, { defaultProps } from 'prism-react-renderer'
import darkTheme from 'prism-react-renderer/themes/nightOwl'
export const HighlightInlineHOC = p => {
return (
<Highlight {...defaultProps} theme={darkTheme} code={p.children} language="jsx">
{({ className, style, tokens, getLineProps, getTokenProps }) => (
<code className={className} style={style}>
{tokens.map((line, i) => (
<span {...getLineProps({ line, key: i })}>
{line.map((token, key) => (
<span {...getTokenProps({ token, key })} />
))}
</span>
))}
</code>
)}
</Highlight>
)
}

Просмотреть файл

@ -1,2 +0,0 @@
export { HighlightInlineHOC as HighlightInline } from './HighlightInline'
export { HighlightHOC as Highlight } from './Highlight'

Просмотреть файл

@ -1,42 +0,0 @@
import * as React from 'react'
import { css } from '@emotion/core'
interface NYIProps {
children?: React.ReactNode
}
export const NYI = (props: NYIProps) => (
<>
<abbr
css={css`
display: inline-block;
background-color: lightyellow;
padding: 1px 8px 1px 8px;
border: 1px solid orange;
border-radius: 2px;
color: black;
font-size: 11px;
font-weight: 600;
text-decoration: none;
cursor: default;
user-select: none;
`}
title="Not Yet Implemented"
>
NYI
</abbr>
{props.children && (
<span
css={css`
color: gray;
font-style: italic;
`}
>
{props.children}
</span>
)}
</>
)

Просмотреть файл

@ -1,28 +0,0 @@
import * as React from 'react'
import { css } from '@emotion/core'
interface PlaceholderProps {
children?: React.ReactNode
}
export const Placeholder = (props: PlaceholderProps) => (
<div
css={css`
display: flex;
position: relative;
height: 360px;
color: #808080;
background-color: #f3f2f1;
`}
>
<div
css={css`
display: block;
margin: auto;
`}
>
{props.children}
</div>
</div>
)

Просмотреть файл

@ -1,2 +0,0 @@
export { NYI } from './NYI'
export { Placeholder } from './Placeholder'

Просмотреть файл

@ -1,14 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
export const Persona = () => {
return <StyledPersona>{/* Beep boop */}</StyledPersona>
}
const StyledPersona = styled.div`
width: 32px;
height: 32px;
margin: 8px;
background: #ccc;
border-radius: 100%;
`

Просмотреть файл

Просмотреть файл

@ -1,120 +0,0 @@
import * as React from 'react'
import { IFrameRenderer } from './IFrameRenderer'
import { usePlayground, IExample } from './context'
export const ExamplePreview = ({ example }: { example: IExample }) => {
const [Component, error] = useTranspiledComponent(example.source)
const [playground] = usePlayground()
return (
<IFrameRenderer>
{ctx => {
if (error) return null // TODO: better UX
if (!Component) return null
return (
<ExampleRenderer>
<Component document={ctx.document} theme={playground.currentTheme} rtl={playground.rtl} />
</ExampleRenderer>
)
}}
</IFrameRenderer>
)
}
const ExampleRenderer = ({ children }) => {
const [playground] = usePlayground()
const style: any = {
direction: playground.rtl ? 'rtl' : 'ltr',
zoom: playground.zoomLevel,
}
if (playground.resolution !== 'Responsive') {
style.width = playground.resolution
}
return (
<div
style={{
maxWidth: '100%',
maxHeight: '100%',
overflow: 'auto',
}}
>
<div style={style}>{children}</div>
</div>
)
}
/**
* Transpiles source code into a React component. Expects the source code to
* expose the component as a default export.
*
* @example
* ```tsx
* const Component = useTranspiledComponent(`
* import * as React from "react"
*
* export default () => {
* return <h1>Hello World</h1>
* }
* `)
*
* // Component = () => React.createElement("h1", null, "Hello World")
* ```
*/
function useTranspiledComponent(source: string): [React.ComponentType<any> | undefined, Error | undefined] {
const ts = useLazyTypeScript()
// TypeScript has not loaded, do nothing.
if (!ts) return [undefined, undefined]
// TODO: proper import handling... Consider TS VFS.
source = source.replace('import * as React from "react"', '')
source = source.replace('export default', 'return')
try {
source = ts.transpileModule(source, {
compilerOptions: {
module: 'none',
jsx: 'react',
},
}).outputText
// TODO: should this be sandboxed in some way?
window.React = React // TODO: properly bind React into component scope.
const Component = new Function(source)()
return [
// Dumb wrapper around user-defined component to handle errors/undefined return value.
// TODO: proper UX for errors
props => {
try {
return Component(props) || null
} catch (e) {
return null
}
},
undefined,
]
} catch (e) {
return [undefined, e]
}
}
/**
* Lazy loads TypeScript for in-browser transpilation
*/
function useLazyTypeScript() {
const [ts, setTS] = React.useState()
React.useEffect(() => {
let cancelled = false
import('typescript').then(res => {
if (!cancelled) {
setTS(res.default)
}
})
return () => {
cancelled = true
}
}, [])
return ts
}

Просмотреть файл

@ -1,217 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
import CodeEditor from './plugins/CodeEditor'
import ThemeEditor from './plugins/ThemeEditor'
import { usePlayground } from './context'
const PLUGINS = [CodeEditor, ThemeEditor]
export const Footer = () => {
return (
<StyledFooter>
<StyledFooterBanner>
<PluginList />
<StyledGrid>
<RTLToggle />
<ThemeSelector />
</StyledGrid>
</StyledFooterBanner>
<ActivePluginOutlet />
</StyledFooter>
)
}
const PluginList = () => {
const [playground, dispatch] = usePlayground()
return (
<StyledPluginList>
{PLUGINS.map(plugin => {
const active = plugin === playground.currentPlugin
return (
<li
key={plugin.label}
data-is-active={active}
onClick={() => {
dispatch({ type: 'TOGGLE_PLUGIN', payload: plugin })
}}
>
{plugin.icon}
{plugin.label}
</li>
)
})}
</StyledPluginList>
)
}
const RTLToggle = () => {
const [playground, dispatch] = usePlayground()
return (
<StyledInputLabel htmlFor="rtl">
<span className="label">RTL</span>
<StyledToggleSlider>
<input
id="rtl"
type="checkbox"
checked={playground.rtl}
onChange={() => {
dispatch({ type: 'TOGGLE_RTL' })
}}
/>
<span className="slider" />
</StyledToggleSlider>
</StyledInputLabel>
)
}
const ThemeSelector = () => {
const [playground, dispatch] = usePlayground()
return (
<StyledInputLabel htmlFor="theme">
<span className="label">Theme</span>
<StyledSelect
id="theme"
value={playground.currentTheme}
onChange={e => {
dispatch({ type: 'CHANGE_THEME', payload: e.target.value })
}}
>
{playground.themes.map(theme => {
return (
<option key={theme} value={theme}>
{theme}
</option>
)
})}
</StyledSelect>
</StyledInputLabel>
)
}
const ActivePluginOutlet = () => {
const [playground] = usePlayground()
const plugin = playground.currentPlugin
if (!plugin) return null
return <StyledPluginOutlet>{plugin.render()}</StyledPluginOutlet>
}
const StyledFooter = styled.footer``
const StyledFooterBanner = styled.div`
display: flex;
justify-content: space-between;
padding: 0.75rem 1rem;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
`
const StyledGrid = styled.div`
display: grid;
grid-auto-flow: column;
grid-auto-columns: min-content;
align-items: center;
grid-gap: 1rem;
`
const StyledSelect = styled.select`
padding: 0;
line-height: inherit;
color: inherit;
`
const StyledPluginList = styled.ol`
list-style: none;
padding: 0;
display: grid;
grid-auto-flow: column;
grid-auto-columns: min-content;
align-items: center;
grid-gap: 1rem;
> li {
display: flex;
position: relative;
align-items: center;
white-space: nowrap;
border-bottom: 2px solid transparent;
svg {
margin-right: 0.5rem;
}
&:hover,
&:focus,
&[data-is-active='true'] {
cursor: pointer;
color: rgba(62, 66, 192, 1);
&::after {
content: '';
position: absolute;
width: 100%;
bottom: -19px;
left: 0;
height: 2px;
background: rgba(62, 66, 192, 1);
box-shadow: inset 0 0 1px 0 rgb(62, 66, 192), 0 0 1px 0 rgba(62, 66, 192, 0.1), 0 0 15px 0 rgba(128, 131, 216, 0.4),
0 2px 6px 0 rgba(111, 115, 247, 0.5), 0 2px 2px 0 rgba(104, 68, 207, 0.2);
}
}
}
`
const StyledPluginOutlet = styled.div`
padding: 1rem;
`
const StyledInputLabel = styled.label`
display: flex;
align-items: center;
cursor: pointer;
> .label {
margin-right: 0.5rem;
}
`
const StyledToggleSlider = styled.span`
position: relative;
height: 18px;
width: 40px;
input {
display: none;
&:checked + .slider {
background: #66bb6a;
}
&:checked + .slider::before {
transform: translateX(21px);
}
}
.slider {
position: absolute;
background-color: #ccc;
bottom: 0;
left: 0;
right: 0;
top: 0;
transition: 200ms;
border-radius: 1rem;
&::before {
background-color: #fff;
bottom: 0px;
content: '';
height: 16px;
width: 16px;
left: 1px;
position: absolute;
transition: 200ms;
border: 1px solid #bbb;
border-radius: 100%;
}
}
`

Просмотреть файл

@ -1,102 +0,0 @@
import * as React from 'react'
import * as ReactDOM from 'react-dom'
/**
* Renders React children into an iframe.
*
* TODO: convert to hooks.
*/
export class IFrameRenderer extends React.Component {
node: any
_setInitialContent = false
_mounted = false
_rendered = false
componentDidMount() {
this._mounted = true
const doc = this.getDoc()
if (doc && doc.readyState === 'complete') {
this.forceUpdate()
} else {
this.node.addEventListener('load', this.handleLoad)
}
}
componentWillUnmount() {
this._mounted = false
this.node.removeEventListener('load', this.handleLoad)
}
getDoc() {
return this.node && this.node.contentDocument
}
getMountTarget() {
const doc = this.getDoc()
return doc.getElementById('frame-root')
}
handleLoad = () => {
this.forceUpdate()
}
renderIFrameContents() {
if (!this._mounted) {
return null
}
const doc = this.getDoc()
if (!doc) {
return null
}
if (!this._setInitialContent) {
const styles = `
html, body, #frame-root {
margin: 0;
height: 100vh;
width: 100%;
}
#frame-root {
display: flex;
align-items: center;
justify-content: center;
}
`
doc.write(`<!DOCTYPE html><html><head><style>${styles}</style></head><body><div id="frame-root"></div></body></html>`)
doc.close()
this._setInitialContent = true
}
const mountTarget = this.getMountTarget()
const win = doc.defaultView || doc.parentView
// Do not allow elements to be focused within the iframe
win.HTMLElement.prototype.focus = () => {}
const ctx = { window: win, document: doc }
const content = this.props.children(ctx) || null
return ReactDOM.createPortal(content, mountTarget)
}
render() {
const { children, ...rest } = this.props
return (
<iframe
title="Example Renderer"
seamless
ref={node => (this.node = node)}
style={{
height: '100%',
width: '100%',
border: 'none',
}}
{...rest}
>
{this.renderIFrameContents()}
</iframe>
)
}
}

Просмотреть файл

@ -1,89 +0,0 @@
import React from 'react'
import { Playground } from '.'
import { Global, css } from '@emotion/core'
export default {
title: 'Playground',
component: Playground,
}
// TODO: should share this with the main app and other stories.
const GlobalStyles = () => (
<Global
styles={css`
body {
font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol';
}
`}
/>
)
export const ToStorybook = () => {
const examples = [
{
title: 'Hello World',
description: 'Description for the first example',
source: `import * as React from "react"
export default () => <h1>Hello World!</h1>`,
},
{
title: 'Goodbye World',
description: 'Description for the second example',
source: `import * as React from "react"
export default () => <h1>Goodbye World?</h1>`,
},
{
title: 'RTL Example',
description: 'Description for the third example',
source: `import * as React from "react"
export default () => (
<div style={{
display: "grid",
gridAutoFlow: "column",
gridAutoColumns: "min-content",
gridGap: "1rem",
}}>
<button style={{ padding: "1rem", fontWeight: 800, background: "red", color: "#fff" }}>Cancel</button>
<button style={{ padding: "1rem", fontWeight: 800, background: "blue", color: "#fff" }}>Confirm</button>
</div>
)`,
},
{
title: 'Theme Example',
description: 'Description for the third example',
source: `import * as React from "react"
export default ({ theme }) => {
const style = {
padding: "1rem"
}
switch (theme) {
case "Dark":
style.background = "#333"
style.color = "#eee"
break
case "High Contrast":
style.background = "#000"
style.color = "#fff"
break
}
return <h1 style={style}>Current theme: {theme}</h1>
}`,
},
]
const themes = ['Light', 'Dark', 'High Contrast']
return (
<>
<GlobalStyles />
<Playground themes={themes} examples={examples} />
</>
)
}
ToStorybook.story = {
name: 'Basic',
}

Просмотреть файл

@ -1,66 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
import { PlaygroundProvider, IPlayground, IExample } from './context'
import { Sidebar } from './Sidebar'
import { Viewport } from './Viewport'
import { Footer } from './Footer'
function handleAction(state: IPlayground, action: any): IPlayground {
switch (action.type) {
case 'TOGGLE_RTL':
return { ...state, rtl: !state.rtl }
case 'CHANGE_THEME':
return { ...state, currentTheme: action.payload }
case 'CHANGE_EXAMPLE':
return { ...state, currentExample: action.payload }
case 'CHANGE_RESOLUTION':
return { ...state, resolution: action.payload }
case 'CHANGE_ZOOM_LEVEL':
return { ...state, zoomLevel: action.payload }
case 'CHANGE_CURRENT_EXAMPLE_SOURCE':
return { ...state, currentExample: { ...state.currentExample, source: action.payload } }
case 'TOGGLE_PLUGIN':
return { ...state, currentPlugin: state.currentPlugin === action.payload ? null : action.payload }
default:
console.warn('Missing handler for action: %s', action.type)
return state
}
}
export const Playground = ({ examples = [], themes = [] }: { examples: IExample[]; themes: string[] }) => {
// TODO: ensure state stays in sync with changes to examples/themes props.
const playground = React.useReducer(handleAction, {
examples,
themes,
rtl: false,
zoomLevel: 1,
resolution: 'Responsive',
currentExample: examples[0],
currentTheme: themes[0],
currentPlugin: null,
})
return (
<PlaygroundProvider value={playground}>
<StyledPlayground>
<StyledPlaygroundBody>
<Viewport />
<Sidebar />
</StyledPlaygroundBody>
<Footer />
</StyledPlayground>
</PlaygroundProvider>
)
}
const StyledPlayground = styled.div`
border: 1px solid #eee;
border-radius: 3px;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
`
const StyledPlaygroundBody = styled.div`
position: relative;
display: flex;
overflow: hidden;
`

Просмотреть файл

@ -1,129 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
import { usePlayground } from './context'
export const Sidebar = () => {
const [show, setShow] = React.useState(true)
return (
<>
<StyledSidebar show={show}>
<ExampleList />
</StyledSidebar>
<ToggleSidebar onToggle={() => setShow(!show)} />
</>
)
}
const ExampleList = () => {
const [playground, dispatch] = usePlayground()
return (
<SidebarPanel header="Examples">
<StyledExampleList>
{playground.examples.map(example => {
const active = example.title === playground.currentExample.title
// TODO: should probably render an actual button or anchor inside of li
return (
<StyledExampleListItem
key={example.title}
active={active}
onClick={() => {
dispatch({ type: 'CHANGE_EXAMPLE', payload: example })
}}
>
{example.title}
</StyledExampleListItem>
)
})}
</StyledExampleList>
</SidebarPanel>
)
}
const ToggleSidebar = ({ onToggle }) => {
return (
<StyledToggleButton title="Toggle sidebar" onClick={onToggle}>
<HamburgerIcon />
</StyledToggleButton>
)
}
const StyledExampleList = styled.ul`
margin: 0;
padding: 0;
list-style: none;
`
const StyledExampleListItem = styled.li<{ active: boolean }>`
padding: 0.5rem;
cursor: pointer;
border: 1px solid transparent;
border-bottom-color: #eee;
font-size: 0.9rem;
&:hover,
&:focus {
border-color: rgb(62, 66, 192);
}
${props =>
props.active && {
background: 'rgba(62, 66, 192, 0.035)',
color: 'rgba(62, 66, 192, 1)',
borderColor: 'rgba(62, 66, 192, 1)',
}}
`
const StyledSidebar = styled.aside<{ show: boolean }>`
display: flex;
flex-direction: column;
width: 225px;
margin-left: ${props => (props.show ? 0 : '-226px')};
border-left: 1px solid #eee;
background: #fff;
transition: margin 150ms ease 0s;
`
export const SidebarPanel = ({ header, children }: { children: React.ReactNode; header: React.ReactNode }) => {
const [show, setShow] = React.useState(true)
return (
<StyledSidebarPanel>
<StyledSidebarPanelHeader onClick={() => setShow(!show)}>{header}</StyledSidebarPanelHeader>
{show && <StyledSidebarPanelContent>{children}</StyledSidebarPanelContent>}
</StyledSidebarPanel>
)
}
const StyledSidebarPanel = styled.section``
const StyledSidebarPanelHeader = styled.header`
padding: 0.75rem;
border-bottom: 1px solid #eee;
cursor: pointer;
font-weight: 600;
`
const StyledSidebarPanelContent = styled.div`
background: rgb(249, 249, 249);
`
const HamburgerIcon = () => (
<span role="img" aria-hidden="true">
<svg role="presentation" focusable="false" height="16" width="16" viewBox="8 8 16 16">
<path d="M22.49 10.47c0 .14-.05.25-.14.35s-.21.14-.35.14H9c-.14 0-.25-.05-.35-.14s-.14-.21-.14-.35.05-.25.14-.35.21-.14.35-.14h13c.14 0 .25.05.35.14s.14.21.14.35zm0 5c0 .14-.05.25-.14.35s-.21.14-.35.14H9c-.14 0-.25-.05-.35-.14s-.14-.21-.14-.35.05-.25.14-.35.21-.14.35-.14h13c.14 0 .25.05.35.14s.14.21.14.35zm0 5c0 .14-.05.25-.14.35s-.21.14-.35.14H9c-.14 0-.25-.05-.35-.14s-.14-.21-.14-.35.05-.25.14-.35.21-.14.35-.14h13c.14 0 .25.05.35.14s.14.21.14.35z"></path>
<path d="M9 11h13c.6 0 1-.4 1-1s-.4-1-1-1H9c-.6 0-1 .4-1 1s.4 1 1 1zm13 8H9c-.6 0-1 .4-1 1s.4 1 1 1h13c.6 0 1-.4 1-1s-.4-1-1-1zm0-5H9c-.6 0-1 .4-1 1s.4 1 1 1h13c.6 0 1-.4 1-1s-.4-1-1-1z"></path>
</svg>
</span>
)
const StyledToggleButton = styled.button`
position: absolute;
top: 0;
right: 0;
margin: 15px 15px 0 0;
padding: 0;
background: none;
border: none;
outline: none;
cursor: pointer;
z-index: 2;
`

Просмотреть файл

@ -1,116 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
import { usePlayground } from './context'
import { ExamplePreview } from './ExamplePreview'
const RESOLUTIONS = [
{ label: 'Responsive', value: 'Responsive' },
{ label: '320', value: 320 },
{ label: '640', value: 640 },
{ label: '1024', value: 1024 },
]
const ZOOM_LEVELS = [
{ label: '25%', value: 0.25 },
{ label: '50%', value: 0.5 },
{ label: '75%', value: 0.75 },
{ label: '100%', value: 1 },
{ label: '200%', value: 2 },
{ label: '300%', value: 3 },
]
export const Viewport = () => {
const [playground, dispatch] = usePlayground()
return (
<StyledViewport>
<Grid style={{ zIndex: 1, padding: '1rem' }}>
<Select
label="Resolution"
options={RESOLUTIONS}
value={playground.resolution}
onChange={(value: any) => dispatch({ type: 'CHANGE_RESOLUTION', payload: value })}
/>
<Select
label="Zoom Level"
options={ZOOM_LEVELS}
value={playground.zoomLevel}
onChange={(value: any) => dispatch({ type: 'CHANGE_ZOOM_LEVEL', payload: value })}
/>
</Grid>
<StyledExamplePreviewContainer>
<ExamplePreview example={playground.currentExample} />
</StyledExamplePreviewContainer>
{playground.currentExample && (
<div style={{ position: 'relative', padding: '1rem' }}>
<StyledExampleTitle>{playground.currentExample.title}</StyledExampleTitle>
<StyledExampleDescription>{playground.currentExample.description}</StyledExampleDescription>
</div>
)}
</StyledViewport>
)
}
const Select = ({ label, options, value, onChange }) => {
const selected = options.find(opt => opt.value === value)
return (
<label htmlFor={label} style={{ display: 'flex', alignItems: 'center' }}>
<StyledSelect
id={label}
value={selected.label}
onChange={e => {
const option = options.find(opt => opt.label === e.target.value)!
onChange(option.value)
}}
>
{options.map(opt => {
return (
<option key={opt.label} value={opt.label}>
{opt.label}
</option>
)
})}
</StyledSelect>
</label>
)
}
const StyledViewport = styled.div`
position: relative;
display: flex;
flex: 1 1 0%;
flex-direction: column;
justify-content: space-between;
min-height: 375px;
background: rgb(249, 249, 249);
`
const StyledSelect = styled.select`
padding: 0;
line-height: inherit;
color: inherit;
`
// NOTE: this must take up 100% of the viewport height, since the example
// may render with a custom background. In that case, that background should
// appear behind the viewport's header and footer.
const StyledExamplePreviewContainer = styled.div`
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
`
const StyledExampleTitle = styled.h3`
margin: 0;
`
const StyledExampleDescription = styled.p`
margin: 0.5rem 0;
`
const Grid = styled.div`
display: grid;
grid-auto-flow: column;
grid-auto-columns: min-content;
align-items: center;
grid-gap: 7.5px;
`

Просмотреть файл

@ -1,24 +0,0 @@
import * as React from 'react'
const PlaygroundContext = React.createContext<IPlaygroundContext>(null as any)
PlaygroundContext.displayName = 'PlaygroundContext'
export const PlaygroundProvider = PlaygroundContext.Provider
export const usePlayground = () => React.useContext(PlaygroundContext)
export type IPlaygroundContext = [IPlayground, React.Dispatch<any>]
export interface IPlayground {
examples: IExample[]
themes: string[]
currentTheme: string
currentExample: IExample
currentPlugin: any
rtl: boolean
zoomLevel: number
resolution: number | 'Responsive'
}
export interface IExample {
title: string
description: string
source: string
}

Просмотреть файл

@ -1 +0,0 @@
export { Playground } from './Playground'

Просмотреть файл

@ -1,63 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
import { usePlayground } from '../context'
// TODO: monaco is throwing errors on source change. Dig into
// react-monaco-editor; potentially fork (it's a very slim wrapper)
const CodeEditor = () => {
const MonacoEditor = useLazyMonacoEditor()
const [playground, dispatch] = usePlayground()
if (!MonacoEditor) {
return <span>Loading...</span>
}
const example = playground.currentExample
return (
<MonacoEditor
language="typescript"
value={example.source}
height={300}
onChange={(value: string) => {
dispatch({ type: 'CHANGE_CURRENT_EXAMPLE_SOURCE', payload: value })
}}
/>
)
}
function useLazyMonacoEditor() {
const [monaco, setMonaco] = React.useState()
React.useEffect(() => {
let cancelled = false
Promise.all([import('monaco-editor'), import('react-monaco-editor')]).then(([monaco, MonacoEditor]) => {
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
jsx: monaco.languages.typescript.JsxEmit.React,
})
if (!cancelled) {
setMonaco(() => MonacoEditor.default)
}
})
return () => {
cancelled = true
}
}, [])
return monaco
}
const StyledSVG = styled.svg`
fill: currentColor;
height: 16px;
width: 16px;
`
export default {
label: 'Code Editor',
icon: (
<StyledSVG role="presentation" focusable="false" viewBox="8 8 16 16">
<path d="M20 20.5a.993.993 0 0 1-.65-.241.997.997 0 0 1-.108-1.409L21.683 16l-2.441-2.849a.999.999 0 1 1 1.517-1.302l3 3.5a1 1 0 0 1 0 1.301l-3 3.5a.993.993 0 0 1-.759.35zM12 20.5a.995.995 0 0 1-.76-.35l-3-3.5a1 1 0 0 1 0-1.301l3-3.5a1 1 0 0 1 1.518 1.302L10.317 16l2.442 2.85A1 1 0 0 1 12 20.5zM14.251 23.5a.5.5 0 0 1-.482-.638l4-14a.499.499 0 1 1 .961.274l-4 14a.498.498 0 0 1-.479.364z"></path>
</StyledSVG>
),
render(props: any) {
return <CodeEditor {...props} />
},
}

Просмотреть файл

@ -1,24 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
const ThemeEditor = () => {
return <p>Placeholder</p>
}
const StyledSVG = styled.svg`
fill: currentColor;
height: 16px;
width: 16px;
`
export default {
label: 'Theme Editor',
icon: (
<StyledSVG role="presentation" focusable="false" viewBox="8 8 16 16">
<path d="M23.5,9C23.2239,9,23,9.2236,23,9.5v2c0,0.2759-0.2244,0.5-0.5,0.5H20h-8H9.5C9.2244,12,9,11.7759,9,11.5v-2 C9,9.2236,8.7761,9,8.5,9S8,9.2236,8,9.5v2C8,12.3271,8.6729,13,9.5,13H11v3.5c0,0.8271,0.6729,1.5,1.5,1.5H13v5.5 c0,0.1802,0.0969,0.3462,0.2537,0.4351C13.3301,23.9785,13.415,24,13.5,24c0.0891,0,0.1782-0.0239,0.2573-0.0713l5-3 C18.908,20.8384,19,20.6758,19,20.5V18h0.5c0.8271,0,1.5-0.6729,1.5-1.5V13h1.5c0.8271,0,1.5-0.6729,1.5-1.5v-2 C24,9.2236,23.7761,9,23.5,9z M20,16.5c0,0.2759-0.2244,0.5-0.5,0.5h-7c-0.2756,0-0.5-0.2241-0.5-0.5V13h8V16.5z"></path>
</StyledSVG>
),
render() {
return <ThemeEditor />
},
}

Просмотреть файл

@ -1,4 +0,0 @@
import * as React from 'react'
export const PageContext = React.createContext<any>({})
export const usePageContext = () => React.useContext(PageContext)

Просмотреть файл

@ -1,63 +0,0 @@
import * as React from 'react'
import { MDXProvider } from '@mdx-js/react'
import { Highlight, HighlightInline } from '../Highlight'
import { Global, css } from '@emotion/core'
export const Provider = props => (
<MDXProvider
components={{
code: Highlight,
inlineCode: HighlightInline,
}}
>
<Global
styles={css`
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body,
#gatsby-focus-wrapper,
#___gatsby {
height: 100%;
min-height: 100%;
font-family: 'Segoe UI';
}
body,
ul[class],
ol[class],
li,
figure,
figcaption,
blockquote,
dl,
dd {
margin: 0;
}
input,
button,
textarea,
select {
font: inherit;
}
img {
max-width: 100%;
display: block;
}
body {
font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol';
background: #fff;
}
h1,
h2,
h3 {
font-weight: 600;
}
`}
/>
{props.children}
</MDXProvider>
)

Просмотреть файл

@ -1 +0,0 @@
export * from './PageContext'

Просмотреть файл

@ -1,38 +0,0 @@
# Storybook
Building isolated, reusable components is one of our project goals. If you are starting work on a new feature or want to isolate a component for development / debugging, it is recommended to use [Storybook][storybook].
## Running Storybook
```sh
yarn storybook
```
## Adding a story
To add a story to Storybook, place a `<Component>.story.tsx` (Example: Button.story.tsx) file in your component directory and `yarn storybook` from the command line.
## Writing a story
You can reference the [Storybook documentation][storybookdocs] for an introduction on “Writing Stories”.
You can find examples of stories in this repository by searching for `.story.tsx` files.
```jsx
import React from 'react'
import { BasicPlayground } from '.'
export default {
title: 'Playground',
component: Playground,
}
export const ToStorybook = () => <BasicPlayground />
ToStorybook.story = {
name: 'Basic Playground',
}
```
[storybook]: https://storybook.js.org/
[storybookdocs]: https://storybook.js.org/basics/writing-stories/

Просмотреть файл

@ -1,303 +0,0 @@
import * as React from 'react'
import styled from '@emotion/styled'
import Fuse from 'fuse.js'
import { useKeyPress } from '../../hooks'
const dummyData = [
{
title: "Old Man's War",
author: {
firstName: 'John',
lastName: 'Scalzi',
},
},
{
title: 'The Lock Artist',
author: {
firstName: 'Steve',
lastName: 'Hamilton',
},
},
{
title: 'HTML5',
author: {
firstName: 'Remy',
lastName: 'Sharp',
},
},
{
title: 'Right Ho Jeeves',
author: {
firstName: 'P.D',
lastName: 'Woodhouse',
},
},
{
title: 'The Code of the Wooster',
author: {
firstName: 'P.D',
lastName: 'Woodhouse',
},
},
{
title: 'Thank You Jeeves',
author: {
firstName: 'P.D',
lastName: 'Woodhouse',
},
},
{
title: 'The DaVinci Code',
author: {
firstName: 'Dan',
lastName: 'Brown',
},
},
{
title: 'Angels & Demons',
author: {
firstName: 'Dan',
lastName: 'Brown',
},
},
{
title: 'The Silmarillion',
author: {
firstName: 'J.R.R',
lastName: 'Tolkien',
},
},
{
title: 'Syrup',
author: {
firstName: 'Max',
lastName: 'Barry',
},
},
{
title: 'The Lost Symbol',
author: {
firstName: 'Dan',
lastName: 'Brown',
},
},
{
title: 'The Book of Lies',
author: {
firstName: 'Brad',
lastName: 'Meltzer',
},
},
{
title: 'Lamb',
author: {
firstName: 'Christopher',
lastName: 'Moore',
},
},
{
title: 'Fool',
author: {
firstName: 'Christopher',
lastName: 'Moore',
},
},
{
title: 'Incompetence',
author: {
firstName: 'Rob',
lastName: 'Grant',
},
},
{
title: 'Fat',
author: {
firstName: 'Rob',
lastName: 'Grant',
},
},
{
title: 'Colony',
author: {
firstName: 'Rob',
lastName: 'Grant',
},
},
{
title: 'Backwards, Red Dwarf',
author: {
firstName: 'Rob',
lastName: 'Grant',
},
},
{
title: 'The Grand Design',
author: {
firstName: 'Stephen',
lastName: 'Hawking',
},
},
{
title: 'The Book of Samson',
author: {
firstName: 'David',
lastName: 'Maine',
},
},
{
title: 'The Preservationist',
author: {
firstName: 'David',
lastName: 'Maine',
},
},
{
title: 'Fallen',
author: {
firstName: 'David',
lastName: 'Maine',
},
},
{
title: 'Monster 1959',
author: {
firstName: 'David',
lastName: 'Maine',
},
},
]
const options = {
shouldSort: true,
threshold: 0.6,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 1,
keys: ['title', 'author.firstName'],
}
const fuse = new Fuse(dummyData, options)
export const Search = () => {
const [query, setQuery] = React.useState('')
const [results, setResults] = React.useState()
const [isEmpty, setEmpty] = React.useState(true)
const [isFocused, setFocus] = React.useState(false)
const inputRef = React.useRef<any>()
const handleChange = event => {
const value = event.target.value
setQuery(value)
const results = fuse.search(value)
setResults(results)
results && results.length > 0 ? setEmpty(false) : setEmpty(true)
}
const handleOnFocus = () => {
setFocus(true)
}
const handleOnBlur = () => {
setFocus(false)
}
const invokeSearch = useKeyPress('/')
React.useEffect(() => {
invokeSearch && inputRef.current.focus()
}, [invokeSearch])
return (
<StyledSearch>
<Input
ref={inputRef}
placeholder={isFocused ? '' : 'Search the docs ("/" to focus)'}
value={query}
onChange={handleChange}
onBlur={handleOnBlur}
onFocus={handleOnFocus}
/>
{isFocused && (
<PopOver>
{isEmpty ? (
<ResultsViews>
{query.length > 0 ? (
<div className="ResultsViews-Empty">Empty state</div>
) : (
<div className="ResultsViews-ZeroQuery">Zero query</div>
)}
</ResultsViews>
) : (
<Results>
<ResultsList>
{results.map((result: any) => (
<ResultsItem>{result.title}</ResultsItem>
))}
</ResultsList>
</Results>
)}
</PopOver>
)}
</StyledSearch>
)
}
const StyledSearch = styled.div`
position: relative;
width: 260px;
`
const Input = styled.input`
padding: 10px;
margin: 8px 0px 0px;
height: 32px;
width: 100%;
border: 0px none;
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.05);
-moz-appearance: none;
overflow: hidden;
font-size: 14px;
`
const PopOver = styled.div`
position: absolute;
top: 60px;
left: 0px;
padding: 20px;
height: 300px;
width: 100%;
overflow: scroll;
background-color: #fff;
border: 1px solid #eee;
border-radius: 5px;
box-shadow: 0 20px 30px rgba(100, 100, 100, 0.2);
`
const Results = styled.div`
display: flex;
`
const ResultsList = styled.ul`
margin: 0px;
padding: 0px;
`
const ResultsItem = styled.li`
padding: 0px;
margin: 0px 0px 12px;
list-style: none;
`
const ResultsViews = styled.div`
display: flex;
opacity: 0.5;
.EmptyState-None {
margin: auto;
}
`

Просмотреть файл

@ -1 +0,0 @@
export { Search } from './Search'

Просмотреть файл

@ -1,64 +0,0 @@
import * as React from 'react';
import styled from '@emotion/styled';
import { Link } from 'gatsby';
import { usePageContext } from '../Provider';
const Menu = props => {
const { items, level = 0 } = props;
const menuItems = items.map((item, index) => {
if (!item.link && !item.items) {
return;
}
if (item.link && item.link.charAt(0) !== '/') {
item.link = '/' + item.link;
}
return (
<li key={index} style={{ marginLeft: 16 * level + 'px', marginBottom: 4 }}>
{item.link ? <Link to={item.link}>{item.name}</Link> : <span> {item.name}</span>}
{item.items && <Menu items={item.items} level={level + 1} />}
</li>
);
});
return <StyledList>{menuItems}</StyledList>;
};
export const Sidebar = props => {
const {
pathContext: { toc = [] }
} = usePageContext();
return (
<StyledSidebar>
<Menu items={toc} />
</StyledSidebar>
);
};
const HeaderHeight = 69;
const FooterHeight = 162;
const StyledSidebar = styled.div`
width: 300px;
padding: 40px;
background-color: rgba(0, 0, 0, 0.01);
height: calc(100vh - ${HeaderHeight}px - ${FooterHeight}px);
flex: none;
`;
const StyledList = styled.ul`
margin: 0px;
padding: 0px;
li {
margin: 0px 0px 20px;
padding: 0px;
list-style: none;
a {
color: #323130;
font-weight: 500;
text-decoration: none;
}
}
`;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше