diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 093d617abac069..9817ebed4d1fc7 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -129,7 +129,6 @@ apps/theming-designer @microsoft/fluentui-react apps/ssr-tests-v9 @microsoft/fluentui-react-build apps/react-18-tests-v8 @microsoft/cxe-red @micahgodbolt apps/react-18-tests-v9 @microsoft/cxe-red @micahgodbolt -apps/recipes-react-components @microsoft/cxe-red @microsoft/fluentui-react @sopranopillow #### Packages packages/azure-themes @Jacqueline-ms @robtaft-ms diff --git a/apps/recipes-react-components/.eslintrc.json b/apps/recipes-react-components/.eslintrc.json deleted file mode 100644 index b9d702c5e755da..00000000000000 --- a/apps/recipes-react-components/.eslintrc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": ["plugin:@fluentui/eslint-plugin/react"], - "root": true, - "rules": { - "@griffel/styles-file": "off", - "@fluentui/no-restricted-imports": "off", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/jsx-no-bind": "off", - "deprecation/deprecation": "off", - "import/no-extraneous-dependencies": ["error", { "packageDir": [".", "../.."] }], - "no-restricted-globals": "off" - } -} diff --git a/apps/recipes-react-components/.storybook/main.js b/apps/recipes-react-components/.storybook/main.js deleted file mode 100644 index 3b1cfc0b06f062..00000000000000 --- a/apps/recipes-react-components/.storybook/main.js +++ /dev/null @@ -1,6 +0,0 @@ -const rootMain = require('../../../.storybook/main'); - -module.exports = /** @type {Omit} */ ({ - ...rootMain, - stories: ['../src/**/*.stories.mdx'], -}); diff --git a/apps/recipes-react-components/.storybook/preview.js b/apps/recipes-react-components/.storybook/preview.js deleted file mode 100644 index cacb8663c76486..00000000000000 --- a/apps/recipes-react-components/.storybook/preview.js +++ /dev/null @@ -1,7 +0,0 @@ -import { FluentDocsContainer } from '../src/DocComponents/FluentDocsContainer.stories'; - -export const parameters = { - docs: { - container: FluentDocsContainer, - }, -}; diff --git a/apps/recipes-react-components/just.config.ts b/apps/recipes-react-components/just.config.ts deleted file mode 100644 index b10db31a6aca51..00000000000000 --- a/apps/recipes-react-components/just.config.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { preset } from '@fluentui/scripts-tasks'; - -preset(); diff --git a/apps/recipes-react-components/package.json b/apps/recipes-react-components/package.json deleted file mode 100644 index 703f2dbf7b010d..00000000000000 --- a/apps/recipes-react-components/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "@fluentui/recipes-react-components", - "version": "9.0.0-alpha.0", - "private": true, - "description": "Recipes for the Fluent UI v9 library", - "scripts": { - "build": "build-storybook -o dist/storybook", - "clean": "just-scripts clean", - "format": "prettier . -w --ignore-path ../../.prettierignore", - "lint": "just-scripts lint", - "start": "start-storybook", - "type-check": "just-scripts type-check" - }, - "devDependencies": { - "@fluentui/eslint-plugin": "*", - "@fluentui/scripts-tasks": "*" - }, - "dependencies": { - "@fluentui/react-components": "*", - "@fluentui/react-icons": "^2.0.239", - "@fluentui/react-theme": "*", - "@fluentui/react-provider": "*", - "@fluentui/react-storybook-addon": "*", - "@fluentui/react-storybook-addon-export-to-sandbox": "*", - "@griffel/react": "^1.5.22", - "react": "17.0.2", - "react-dom": "17.0.2", - "tslib": "^2.1.0" - } -} diff --git a/apps/recipes-react-components/project.json b/apps/recipes-react-components/project.json deleted file mode 100644 index de77688b4e4615..00000000000000 --- a/apps/recipes-react-components/project.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@fluentui/recipes-react-components", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "implicitDependencies": [], - "sourceRoot": "apps/recipes-react-components/src", - "tags": ["vNext"] -} diff --git a/apps/recipes-react-components/src/DocComponents/FluentDocsContainer.stories.tsx b/apps/recipes-react-components/src/DocComponents/FluentDocsContainer.stories.tsx deleted file mode 100644 index bd362d22c04177..00000000000000 --- a/apps/recipes-react-components/src/DocComponents/FluentDocsContainer.stories.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react'; -import { DocsContainer, DocsContextProps } from '@storybook/addon-docs'; -import { FluentStoryContext } from '@fluentui/react-storybook-addon'; -import { webLightTheme, FluentProvider } from '@fluentui/react-components'; - -type FluentDocsContainerProps = { - context: FluentStoryContext & DocsContextProps; -}; - -export const FluentDocsContainer: React.FC = ({ children, context }) => { - return ( - - {children} - - ); -}; diff --git a/apps/recipes-react-components/src/index.ts b/apps/recipes-react-components/src/index.ts deleted file mode 100644 index cb0ff5c3b541f6..00000000000000 --- a/apps/recipes-react-components/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/apps/recipes-react-components/src/recipes/media-object/MediaObject.stories.mdx b/apps/recipes-react-components/src/recipes/media-object/MediaObject.stories.mdx deleted file mode 100644 index 2eeb24eea12eb7..00000000000000 --- a/apps/recipes-react-components/src/recipes/media-object/MediaObject.stories.mdx +++ /dev/null @@ -1,227 +0,0 @@ -import LinkTo from '@storybook/addon-links/react'; -import { Meta } from '@storybook/addon-docs'; -import { TextPositionVariations, TextAlignmentVariations, FlexSkeleton, IconMediaObject } from './code-snippets'; -import { TemplateExample } from '../../templates'; - - - ---- - -# Media Object recipe - -### **Overview** - -A Media Object, is a pattern commonly used to display media content and a description of that content. -A typical example of this patter is displaying an Avatar of a person (the media content) next to their name (the description). Fluent UI's Persona is an example of this pattern. - -This recipe focuses on other uses of this patterns and will show you how to create a Media Object to display images, icons or any other media content you want to add. - -### **Ingredients** - -- @fluentui/react-icons -- @fluentui/react-image -- @fluentui/react-text - -> **\*\*Note:\*\*** This recipe is meant to provide a way to use custom media. If you want to use -> `Avatar` or `PresenceBadge` as media, please refer to our Persona component. - -## **Steps** - -There are two ways to build a Media Object, you can use a grid layout or a flex layout. We will cover both in this -recipe. There are upsides and downsides to both, but the main difference is that grid layout uses less DOM than the -flex option. - -### **Flex Layout** - -The main idea behind the flex layout is to have a container and two children, as shown below. The parent div will -contain the media and another div (text div) that will contain the text content. - - - - - -To achieve this layout, we will follow these steps: - -#### **Step 1: Creating our parent and text container styles.** - -As seen above, we will first need to create our parent div and our text containers. These containers will need to have -the `display: flex` css property and a `row` direction for the parent and a `column` direction for the text container, as shown in the `makeStyles` call below: - -```jsx -const useStyles = makeStyles({ - parent: { - display: 'flex', - flexDirection: 'row', - }, - textContainer: { - display: 'flex', - flexDirection: 'column', - }, -}); -``` - -#### **Step 2: Putting everything together.** - -After we have our styles, we just have to put our styles to work! Since we are using flex box we don't need to worry about dynamically placing items. Do take into account that using this approach will be heavier on the DOM than the grid approach. - -```jsx -import { Text, makeStyles } from '@fluentui/react-components'; - -// Our makeStyles call from above - -const MediaObject: React.FC<{ text?: string }> = ({ children, text }) => { - const styles = useStyles(); - - return ( -
- {children} -
- {text} -
-
- ); -}; -``` - -After these steps you should be able to build something like the example below. - - - - - -### **Grid Layout** - -When using a grid for Media Object, we only need a parent div and we can pass the items directly into it. -As you can tell, the grid layout has one less layer of DOM compared to the flex layout. This is especially important -when the component is going to be used repeatedly in a list or the media or/and text have many layers themselves. - -To get started, we will follow these steps: - -#### **Step 1: Creating our grid.** - -To get the initial layout, we need to add these css properties to our parent div: - -- `display: grid`: This will create our grid layout and allow us to use the grid properties. -- `grid-auto-flow: column`: This will make the grid flow as a column and allow our media to be on the left and our text on the right. - -Resulting in a `makeStyles` call like this: - -```jsx -const useStyles = makeStyles({ - parent: { - display: 'grid', - gridAutoFlow: 'column', - }, -}); -``` - -#### **Step 2: Adding our media styles.** - -Our next step is to add our media styles. Unlike the flex layout, we will need to add some css properties to our media because we are using `grid-auto-flow: column`. To make our media take all the rows on the left, we will need to make our media span the number of rows the text will take. If we have 4 lines of text, we will need to add `grid-row-start: span 4`. While this could be done dynamically using line names, this is the simplest way to achieve a media object with grid. This will give us the following `makeStyles` call: - -```jsx -const useStyles = makeStyles({ - // parent styles - media: { - gridRowStart: 'span 4', - }, -}); -``` - -#### **Step 3: Putting everything together.** - -After these steps we should be able to add our media and text, and get the desired layout shown above. We should have a component that looks like this: - -```jsx -import { Text, makeStyles } from '@fluentui/react-components'; - -// Our makeStyles call from above - -const MediaObject: React.FC<{ text?: string }> = ({ children, text }) => { - const styles = useStyles(); - - return ( -
-
{children}
- {text} -
- ); -}; -``` - -#### **Step 3 (_optional_): Dynamically place media and text.** - -If you want to dynamically place your media and text, you can use `grid-template-columns` to achieve this. For the basic layout, we need to add the css property `grid-template-columns: max-content [middle] auto`. This will create two columns and a line name called middle. The max-content column will be the media which will help only use the space needed for the media and the auto column will be the text so we can wrap it when there is not enough space in our container. This will give us the following `makeStyles` call: - -```jsx -const useStyles = makeStyles({ - parent: { - display: 'grid', - gridTemplateColumns: 'max-content [middle] auto', - }, -}); -``` - -#### **Step 4 (_optional_): Let your media and text know where to start and end.** - -Now that we have our template columns, we need to let our text know where to start and our media where to end. The media must end at the middle line and the text must start at the middle line. This has the pro of not having to know how many rows of text we will have, but the downside is that we have to let the media and text know where to start or end. We should a `makeStyles` call like this: - -```jsx -const useStyles = makeStyles({ - // parent styles - media: { - gridColumnEnd: 'middle', - }, - text: { - gridColumnStart: 'middle', - }, -}); -``` - -#### **Step 5 (_optional_): Putting everything together.** - -After our styles are ready to be used, we can put everything together and get the desired layout shown above. We should have a component that looks like this: - -```jsx -import { Text, makeStyles } from '@fluentui/react-components'; - -// Our makeStyles call from above - -const MediaObject: React.FC<{ text?: string }> = ({ children, text }) => { - const styles = useStyles(); - - return ( -
-
{children}
- {text} -
- ); -}; -``` - -## **Variants** - -There are a few common variants that you might want to use when building a Media Object. These are some of them: - -- ### **Text Alignment Variations** - -There are text alignment variations that might be useful when building an application. These can be ones below where the -first one is after the media, the second one is below, and the last one is before. - - - - - -- ### **Text Vertical Alignment Variations** - -There are also vertical alignment variations, these include start and center as seen below. - - - - - -## **Best practices** - -- The higher up the text line, the more important it is. You should not apply higher weights to the lines underneath. -- When using `grid-template-columns` make sure the DOM makes sense and not differ from how the grid is placing them. Do - not have your DOM be ` ` when the rendered result looks like ` `. diff --git a/apps/recipes-react-components/src/recipes/media-object/code-snippets/MediaObject.tsx b/apps/recipes-react-components/src/recipes/media-object/code-snippets/MediaObject.tsx deleted file mode 100644 index 13b965a31ba541..00000000000000 --- a/apps/recipes-react-components/src/recipes/media-object/code-snippets/MediaObject.tsx +++ /dev/null @@ -1,200 +0,0 @@ -import * as React from 'react'; -import { makeStyles, mergeClasses, shorthands, Text } from '@fluentui/react-components'; -import { Attach24Regular } from '@fluentui/react-icons'; - -const useExampleStyles = makeStyles({ - multiExample: { - display: 'flex', - justifyContent: 'center', - ...shorthands.gap('60px'), - }, -}); - -const useSkeletonStyles = makeStyles({ - blue: { - backgroundColor: '#4f5e8f', - }, - purple: { - backgroundColor: '#e1c7fc', - }, - legendContainer: { - display: 'flex', - flexDirection: 'column-reverse', - ...shorthands.gap('10px'), - ...shorthands.padding('4px'), - }, - legend: { - display: 'flex', - ...shorthands.gap('5px'), - }, - legendColor: { - alignSelf: 'center', - width: '10px', - height: '10px', - }, -}); - -const useMediaObjectStyles = makeStyles({ - main: { - display: 'flex', - flexDirection: 'row', - ...shorthands.gap('4px'), - }, - text: { - display: 'flex', - flexDirection: 'column', - ...shorthands.gap('4px'), - }, - emptyMedia: { - ...shorthands.padding('20px', '20px', '20px', '80px'), - }, - emptyText: { - width: '100px', - height: '50px', - }, - - centerMedia: { - alignItems: 'center', - }, - - verticalMediaObject: { - display: 'flex', - flexDirection: 'column', - ...shorthands.gap('4px'), - alignItems: 'center', - }, - centerTextPosition: { - alignItems: 'center', - }, - beforeTextPosition: { - alignItems: 'flex-end', - }, -}); - -type MediaObjectTypes = { - media?: React.ReactElement; - text?: React.ReactElement; - textPosition?: 'before' | 'below' | 'after'; - textAlignment?: 'start' | 'center'; -}; - -const MediaObject: React.VoidFunctionComponent = ({ - media, - text, - textPosition = 'after', - textAlignment = 'start', -}) => { - const mediaObjectStyles = useMediaObjectStyles(); - - const mainClassName = mergeClasses( - mediaObjectStyles.main, - textPosition === 'below' && mediaObjectStyles.verticalMediaObject, - textAlignment === 'center' && mediaObjectStyles.centerMedia, - ); - - const textClassName = mergeClasses( - mediaObjectStyles.text, - textPosition === 'below' && mediaObjectStyles.centerTextPosition, - textPosition === 'before' && mediaObjectStyles.beforeTextPosition, - ); - - return ( -
- {(textPosition === 'after' || textPosition === 'below') && media} -
{text}
- {textPosition === 'before' && media} -
- ); -}; - -const Legend: React.FC<{ colorClassName: string }> = ({ children, colorClassName }) => { - const skeletonStyles = useSkeletonStyles(); - return ( -
-
- {children} -
- ); -}; - -export const FlexSkeleton = () => { - const exampleStyles = useExampleStyles(); - const skeletonStyles = useSkeletonStyles(); - const mediaObjectStyles = useMediaObjectStyles(); - - return ( -
-
-
-
-
- Parent div - Text div -
-
- ); -}; - -export const IconMediaObject = () => ( - } - text={ - <> - - File.tsx - - 256 Gb - - } - /> -); - -export const TextPositionVariations = () => { - const exampleStyles = useExampleStyles(); - const positions: MediaObjectTypes['textPosition'][] = ['after', 'below', 'before']; - - return ( -
- {positions.map(textPosition => ( - } - key={textPosition} - text={ - <> - - File.tsx - - 256 Gb - - } - /> - ))} -
- ); -}; - -export const TextAlignmentVariations = () => { - const exampleStyles = useExampleStyles(); - const alignments: MediaObjectTypes['textAlignment'][] = ['start', 'center']; - - return ( -
- {alignments.map(alignment => ( - } - text={ - <> - - File.tsx - - 256 Gb - - } - /> - ))} -
- ); -}; diff --git a/apps/recipes-react-components/src/recipes/media-object/code-snippets/index.ts b/apps/recipes-react-components/src/recipes/media-object/code-snippets/index.ts deleted file mode 100644 index d1f240176219dd..00000000000000 --- a/apps/recipes-react-components/src/recipes/media-object/code-snippets/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './MediaObject'; diff --git a/apps/recipes-react-components/src/templates/Example.tsx b/apps/recipes-react-components/src/templates/Example.tsx deleted file mode 100644 index b8d2086fca5f95..00000000000000 --- a/apps/recipes-react-components/src/templates/Example.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import * as React from 'react'; -import { - FluentProvider, - makeStyles, - mergeClasses, - shorthands, - tokens, - webLightTheme, -} from '@fluentui/react-components'; - -const useExampleStyles = makeStyles({ - root: { - ...shorthands.border('1px', 'solid', tokens.colorNeutralStroke1), - ...shorthands.borderRadius('16px'), - ...shorthands.padding('30px'), - ...shorthands.margin('6px'), - }, - innerContainer: { - display: 'flex', - backgroundColor: 'rgb(250, 250, 250)', - ...shorthands.padding('48px', '24px', '48px', '24px'), - }, - centered: { - justifyContent: 'center', - }, -}); - -export const TemplateExample: React.FC<{ centered?: boolean }> = ({ children, centered }) => { - const exampleStyles = useExampleStyles(); - - const innerContainerClassName = mergeClasses(exampleStyles.innerContainer, centered && exampleStyles.centered); - - return ( - -
-
{children}
-
-
- ); -}; diff --git a/apps/recipes-react-components/src/templates/index.ts b/apps/recipes-react-components/src/templates/index.ts deleted file mode 100644 index 99e30127539411..00000000000000 --- a/apps/recipes-react-components/src/templates/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Example'; diff --git a/apps/recipes-react-components/tsconfig.app.json b/apps/recipes-react-components/tsconfig.app.json deleted file mode 100644 index a623085f89633d..00000000000000 --- a/apps/recipes-react-components/tsconfig.app.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "noEmit": true, - "lib": ["ES2019", "dom"], - "types": [] - }, - "include": ["./src/**/*.ts", "./src/**/*.tsx"] -} diff --git a/apps/recipes-react-components/tsconfig.json b/apps/recipes-react-components/tsconfig.json deleted file mode 100644 index fa6520ff6babe8..00000000000000 --- a/apps/recipes-react-components/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "module": "commonjs", - "target": "ES2019", - "noEmit": true, - "isolatedModules": true, - "jsx": "react", - "noUnusedLocals": true, - "preserveConstEnums": true - }, - "include": [], - "files": [], - "references": [ - { - "path": "./tsconfig.app.json" - } - ] -}