diff --git a/.github/workflows/docsite-publish-ghpages.yml b/.github/workflows/docsite-publish-ghpages.yml index 1d3bdac0e81cb..7e18da844d033 100644 --- a/.github/workflows/docsite-publish-ghpages.yml +++ b/.github/workflows/docsite-publish-ghpages.yml @@ -49,11 +49,12 @@ jobs: if: steps.affected_storybooks_count.outputs.value > 0 run: | rm -rf _pages - mkdir -p _pages/react _pages/charts _pages/web-components + mkdir -p _pages/react _pages/charts _pages/web-components _pages/headless cp -R apps/public-docsite-v9/dist/react/* _pages/react/ cp -R apps/chart-docsite/dist/storybook/* _pages/charts/ cp -R packages/web-components/dist/storybook/* _pages/web-components + cp -R apps/public-docsite-v9-headless/dist/storybook/* _pages/headless/ - name: Upload Pages Artifact if: steps.affected_storybooks_count.outputs.value > 0 diff --git a/apps/pr-deploy-site/just.config.ts b/apps/pr-deploy-site/just.config.ts index 0aac32b650dde..3fa049d438f1a 100644 --- a/apps/pr-deploy-site/just.config.ts +++ b/apps/pr-deploy-site/just.config.ts @@ -33,7 +33,7 @@ const dependencies = [ '@fluentui/public-docsite-v9', '@fluentui/perf-test-react-components', '@fluentui/theme-designer', - '@fluentui/react-headless-components-preview-stories', + '@fluentui/public-docsite-v9-headless', // web-components '@fluentui/web-components', // charting diff --git a/apps/pr-deploy-site/pr-deploy-site.js b/apps/pr-deploy-site/pr-deploy-site.js index 5b19c76188599..eb75f70ce0364 100644 --- a/apps/pr-deploy-site/pr-deploy-site.js +++ b/apps/pr-deploy-site/pr-deploy-site.js @@ -85,10 +85,10 @@ function main() { title: 'Theme Designer v9', }, { - package: '@fluentui/react-headless-components-preview-stories', - link: './react-headless-components-preview-stories/storybook/index.html', + package: '@fluentui/public-docsite-v9-headless', + link: './public-docsite-v9-headless/storybook/index.html', icon: 'Code', - title: '@fluentui/react-headless-components-preview Storybook', + title: 'Headless Components', }, { package: '@fluentui/perf-test', diff --git a/apps/public-docsite-v9-headless/.storybook/main.js b/apps/public-docsite-v9-headless/.storybook/main.js new file mode 100644 index 0000000000000..19e4e2ab01e9c --- /dev/null +++ b/apps/public-docsite-v9-headless/.storybook/main.js @@ -0,0 +1,22 @@ +const rootMain = require('../../../.storybook/main'); + +module.exports = /** @type {Omit} */ ({ + ...rootMain, + stories: [ + ...rootMain.stories, + // docsite stories + '../src/**/*.mdx', + '../src/**/index.stories.@(ts|tsx)', + // headless package stories + '../../../packages/react-components/react-headless-components-preview/stories/src/**/index.stories.@(ts|tsx)', + ], + addons: [...rootMain.addons], + build: { + previewUrl: process.env.DEPLOY_PATH, + }, + webpackFinal: (config, options) => { + const localConfig = /** @type config */ ({ ...rootMain.webpackFinal(config, options) }); + + return localConfig; + }, +}); diff --git a/apps/public-docsite-v9-headless/.storybook/manager.js b/apps/public-docsite-v9-headless/.storybook/manager.js new file mode 100644 index 0000000000000..549d47e694f82 --- /dev/null +++ b/apps/public-docsite-v9-headless/.storybook/manager.js @@ -0,0 +1,10 @@ +import { addons } from 'storybook/manager-api'; + +import fluentStorybookTheme from './theme'; + +addons.setConfig({ + enableShortcuts: false, + theme: fluentStorybookTheme, + showPanel: false, + showToolbar: false, +}); diff --git a/apps/public-docsite-v9-headless/.storybook/preview-head.html b/apps/public-docsite-v9-headless/.storybook/preview-head.html new file mode 100644 index 0000000000000..670a7917313c6 --- /dev/null +++ b/apps/public-docsite-v9-headless/.storybook/preview-head.html @@ -0,0 +1,6 @@ + + diff --git a/apps/public-docsite-v9-headless/.storybook/preview.js b/apps/public-docsite-v9-headless/.storybook/preview.js new file mode 100644 index 0000000000000..0f1ef1a261711 --- /dev/null +++ b/apps/public-docsite-v9-headless/.storybook/preview.js @@ -0,0 +1,20 @@ +import * as rootPreview from '../../../.storybook/preview'; + +/** @type {typeof rootPreview.decorators} */ +export const decorators = [...rootPreview.decorators]; + +/** @type {typeof rootPreview.parameters} */ +export const parameters = { + ...rootPreview.parameters, + docs: { + ...rootPreview.parameters.docs, + }, + options: { + storySort: { + method: 'alphabetical', + order: ['Introduction', 'Headless Components'], + }, + }, +}; + +export const tags = ['autodocs']; diff --git a/apps/public-docsite-v9-headless/.storybook/theme.js b/apps/public-docsite-v9-headless/.storybook/theme.js new file mode 100644 index 0000000000000..4a00dce65f788 --- /dev/null +++ b/apps/public-docsite-v9-headless/.storybook/theme.js @@ -0,0 +1,40 @@ +import { create } from 'storybook/theming'; + +/** + * Theming and branding the storybook to fluent. Taken from https://storybook.js.org/docs/react/configure/theming + */ +const theme = create({ + base: 'light', + + // Storybook-specific color palette + colorPrimary: 'rgba(255, 255, 255, .4)', + colorSecondary: '#0078d4', + + // UI + appBg: '#ffffff', + appContentBg: '#ffffff', + appBorderColor: '#e0e0e0', // use msft gray + appBorderRadius: 4, + + // Fonts + fontBase: + '"Segoe UI", "Segoe UI Web (West European)", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;', + fontCode: 'monospace', + + // Text colors + textColor: '#11100f', + textInverseColor: '#0078d4', // use msft primary blue default + + // Toolbar default and active colors + barSelectedColor: '#0078d4', // use msft primary blue default + + // Form colors + inputBorderRadius: 4, + + // Use the fluent branding for the upper left image + brandTitle: 'Fluent UI Headless Components', + brandUrl: + 'https://github.com/microsoft/fluentui/tree/master/packages/react-components/react-headless-components-preview', +}); + +export default theme; diff --git a/apps/public-docsite-v9-headless/eslint.config.js b/apps/public-docsite-v9-headless/eslint.config.js new file mode 100644 index 0000000000000..c35361afdb4c4 --- /dev/null +++ b/apps/public-docsite-v9-headless/eslint.config.js @@ -0,0 +1,16 @@ +// @ts-check +const fluentPlugin = require('@fluentui/eslint-plugin'); + +/** @type {import("eslint").Linter.Config[]} */ +module.exports = [ + ...fluentPlugin.configs['flat/react'], + { + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/jsx-no-bind': 'off', + '@typescript-eslint/no-deprecated': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + 'import/no-extraneous-dependencies': ['error', { packageDir: ['.', '../..'] }], + }, + }, +]; diff --git a/apps/public-docsite-v9-headless/just.config.ts b/apps/public-docsite-v9-headless/just.config.ts new file mode 100644 index 0000000000000..242d94f1f0210 --- /dev/null +++ b/apps/public-docsite-v9-headless/just.config.ts @@ -0,0 +1,5 @@ +import { preset, task } from '@fluentui/scripts-tasks'; + +preset(); + +task('build', 'build:node-lib').cached!(); diff --git a/apps/public-docsite-v9-headless/package.json b/apps/public-docsite-v9-headless/package.json new file mode 100644 index 0000000000000..cb7e8b05f1b85 --- /dev/null +++ b/apps/public-docsite-v9-headless/package.json @@ -0,0 +1,26 @@ +{ + "name": "@fluentui/public-docsite-v9-headless", + "version": "1.0.0", + "private": true, + "description": "Fluent UI React Headless Components Preview documentation", + "scripts": { + "build-storybook": "storybook build -o ./dist/storybook --docs", + "build-storybook:docsite": "cross-env DEPLOY_PATH=/headless/ storybook build -o ./dist/storybook --docs", + "clean": "just-scripts clean", + "code-style": "just-scripts code-style", + "just": "just-scripts", + "type-check": "just-scripts type-check", + "start": "yarn storybook:docs", + "storybook": "storybook dev --port 3000", + "storybook:docs": "yarn storybook --docs", + "test": "jest --passWithNoTests" + }, + "dependencies": { + "@fluentui/react-headless-components-preview": "*", + "@fluentui/react-storybook-addon": "*", + "@fluentui/react-storybook-addon-export-to-sandbox": "*", + "react": "19.2.0", + "react-dom": "19.2.0", + "tslib": "^2.1.0" + } +} diff --git a/apps/public-docsite-v9-headless/project.json b/apps/public-docsite-v9-headless/project.json new file mode 100644 index 0000000000000..563425b1366d3 --- /dev/null +++ b/apps/public-docsite-v9-headless/project.json @@ -0,0 +1,17 @@ +{ + "name": "public-docsite-v9-headless", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "implicitDependencies": ["react-headless-components-preview-stories"], + "tags": ["platform:web", "vNext"], + "targets": { + "build-storybook": { + "dependsOn": [ + { + "projects": ["react-storybook-addon", "react-storybook-addon-export-to-sandbox"], + "target": "build" + } + ] + } + } +} diff --git a/apps/public-docsite-v9-headless/src/Introduction.mdx b/apps/public-docsite-v9-headless/src/Introduction.mdx new file mode 100644 index 0000000000000..a9ea43fba150f --- /dev/null +++ b/apps/public-docsite-v9-headless/src/Introduction.mdx @@ -0,0 +1,34 @@ +import { Meta } from '@storybook/addon-docs/blocks'; + + + +## Overview + +Fluent UI React Headless Components is a set of unstyled, accessible, and composable React components that implement the Fluent UI design patterns without prescribing any specific styling solution. + +These components provide the behavior, accessibility, and state management while giving you full control over the visual presentation using your preferred styling approach (e.g., Tailwind CSS, CSS Modules, or any other solution). + +## Getting Started + +To get started with the headless components package in your project: + +1. Install the package using `npm` or `yarn`: + + ``` + npm install @fluentui/react-headless-components-preview + ``` + +2. Import and use the components: + + ```tsx + import { + Accordion, + AccordionItem, + AccordionHeader, + AccordionPanel, + } from '@fluentui/react-headless-components-preview'; + ``` + +## Contributing + +Refer to the main FluentUI [wiki](https://github.com/microsoft/fluentui/wiki) for detailed instructions on setup and contributing to the package. diff --git a/apps/public-docsite-v9-headless/tsconfig.app.json b/apps/public-docsite-v9-headless/tsconfig.app.json new file mode 100644 index 0000000000000..3114b73ab654d --- /dev/null +++ b/apps/public-docsite-v9-headless/tsconfig.app.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "ESNext", + "target": "ES2019", + "noEmit": false, + "outDir": "lib", + "jsx": "react", + "sourceMap": true, + "types": ["static-assets", "webpack-env"] + }, + "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx"], + "include": ["src"] +} diff --git a/apps/public-docsite-v9-headless/tsconfig.json b/apps/public-docsite-v9-headless/tsconfig.json new file mode 100644 index 0000000000000..1c0b3afbde8d0 --- /dev/null +++ b/apps/public-docsite-v9-headless/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.base.all.json", + "compilerOptions": { + "module": "ESNext", + "target": "ES2019", + "noEmit": true, + "experimentalDecorators": true, + "noUnusedLocals": true, + "strictNullChecks": true, + "noImplicitAny": true + }, + "include": [], + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + } + ] +} diff --git a/apps/public-docsite-v9/project.json b/apps/public-docsite-v9/project.json index 4118059d01472..5faa045dec2c2 100644 --- a/apps/public-docsite-v9/project.json +++ b/apps/public-docsite-v9/project.json @@ -28,7 +28,7 @@ "build-storybook", "build-storybook:react", { - "projects": ["chart-docsite", "web-components"], + "projects": ["chart-docsite", "web-components", "public-docsite-v9-headless"], "target": "build-storybook:docsite" } ]